WordPress.org

Make WordPress Core

Ticket #30634: 30634.diff

File 30634.diff, 55.3 KB (added by bor0, 3 years ago)
  • trunk/wp-includes/js/imgareaselect/jquery.imgareaselect.js

     
    11/*
    22 * imgAreaSelect jQuery plugin
    3  * version 0.9.10-monkey
     3 * version 1.0.0-rc.1
    44 *
    55 * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net)
    66 *
    7  * Dual licensed under the MIT (MIT-LICENSE.txt)
    8  * and GPL (GPL-LICENSE.txt) licenses.
     7 * Dual licensed under the MIT (http://opensource.org/licenses/MIT)
     8 * and GPL (http://opensource.org/licenses/GPL-2.0) licenses.
    99 *
    1010 * http://odyniec.net/projects/imgareaselect/
    1111 *
     
    1616/*
    1717 * Math functions will be used extensively, so it's convenient to make a few
    1818 * shortcuts
    19  */
     19 */   
    2020var abs = Math.abs,
    2121    max = Math.max,
    2222    min = Math.min,
     
    2424
    2525/**
    2626 * Create a new HTML div element
    27  *
     27 * 
    2828 * @return A jQuery object representing the new element
    2929 */
    3030function div() {
     
    3333
    3434/**
    3535 * imgAreaSelect initialization
    36  *
     36 * 
    3737 * @param img
    3838 *            A HTML image element to attach the plugin to
    3939 * @param options
     
    4040 *            An options object
    4141 */
    4242$.imgAreaSelect = function (img, options) {
    43     var
    44         /* jQuery object representing the image */
     43    var 
     44        /* jQuery object representing the image */ 
    4545        $img = $(img),
    46 
     46       
    4747        /* Has the image finished loading? */
    4848        imgLoaded,
    49 
     49       
    5050        /* Plugin elements */
    51 
     51       
    5252        /* Container box */
    5353        $box = div(),
    5454        /* Selection area */
     
    5555        $area = div(),
    5656        /* Border (four divs) */
    5757        $border = div().add(div()).add(div()).add(div()),
    58         /* Outer area (four divs) */
    59         $outer = div().add(div()).add(div()).add(div()),
     58        /* Outer area */
     59        $outer = div(),
    6060        /* Handles (empty by default, initialized in setOptions()) */
    6161        $handles = $([]),
    62 
    63         /*
    64          * Additional element to work around a cursor problem in Opera
    65          * (explained later)
    66          */
    67         $areaOpera,
    68 
     62       
    6963        /* Image position (relative to viewport) */
    7064        left, top,
    71 
     65       
    7266        /* Image offset (as returned by .offset()) */
    7367        imgOfs = { left: 0, top: 0 },
    74 
     68       
    7569        /* Image dimensions (as returned by .width() and .height()) */
    7670        imgWidth, imgHeight,
    77 
     71       
    7872        /*
    7973         * jQuery object representing the parent element that the plugin
    8074         * elements are appended to
    8175         */
    8276        $parent,
    83 
     77       
    8478        /* Parent element offset (as returned by .offset()) */
    8579        parOfs = { left: 0, top: 0 },
    86 
     80       
    8781        /* Base z-index for plugin elements */
    8882        zIndex = 0,
    89 
     83               
    9084        /* Plugin elements position */
    9185        position = 'absolute',
    92 
    93         /* X/Y coordinates of the starting point for move/resize operations */
     86       
     87        /* X/Y coordinates of the starting point for move/resize operations */ 
    9488        startX, startY,
    9589
     90        /*
     91         * Distance between the mouse cursor (or touch point) and selection area
     92         * edges (when resizing)
     93         */
     94        edgeX, edgeY,
     95       
    9696        /* Horizontal and vertical scaling factors */
    9797        scaleX, scaleY,
    9898
     
    114114        /* Current selection (relative to scaled image) */
    115115        selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 },
    116116
    117         /* Document element */
    118         docElem = document.documentElement,
    119 
    120117        /* User agent */
    121118        ua = navigator.userAgent,
     119       
     120        /* Is the user performing a touch action? */
     121        touch,
    122122
    123         /* Various helper variables used throughout the code */
     123        /* Various helper variables used throughout the code */ 
    124124        $p, d, i, o, w, h, adjusted;
    125125
    126126    /*
     
    127127     * Translate selection coordinates (relative to scaled image) to viewport
    128128     * coordinates (relative to parent element)
    129129     */
    130 
     130   
    131131    /**
    132132     * Translate selection X to viewport X
    133      *
     133     * 
    134134     * @param x
    135135     *            Selection X
    136136     * @return Viewport X
     
    141141
    142142    /**
    143143     * Translate selection Y to viewport Y
    144      *
     144     * 
    145145     * @param y
    146146     *            Selection Y
    147147     * @return Viewport Y
     
    153153    /*
    154154     * Translate viewport coordinates to selection coordinates
    155155     */
    156 
     156   
    157157    /**
    158158     * Translate viewport X to selection X
    159      *
     159     * 
    160160     * @param x
    161161     *            Viewport X
    162162     * @return Selection X
     
    167167
    168168    /**
    169169     * Translate viewport Y to selection Y
    170      *
     170     * 
    171171     * @param y
    172172     *            Viewport Y
    173173     * @return Selection Y
     
    175175    function selY(y) {
    176176        return y - imgOfs.top + parOfs.top;
    177177    }
    178 
     178   
    179179    /*
    180180     * Translate event coordinates (relative to document) to viewport
    181181     * coordinates
    182182     */
    183 
     183   
    184184    /**
    185185     * Get event X and translate it to viewport X
    186      *
     186     * 
    187187     * @param event
    188188     *            The event object
    189189     * @return Viewport X
    190190     */
    191191    function evX(event) {
    192         return max(event.pageX || 0, touchCoords(event).x) - parOfs.left;
     192        var coords = touchCoords(event) || event, x;
     193
     194        if (x = parseInt(coords.pageX))
     195            return x - parOfs.left;
    193196    }
    194197
    195198    /**
    196199     * Get event Y and translate it to viewport Y
    197      *
     200     * 
    198201     * @param event
    199202     *            The event object
    200203     * @return Viewport Y
    201204     */
    202205    function evY(event) {
    203         return max(event.pageY || 0, touchCoords(event).y) - parOfs.top;
     206        var coords = touchCoords(event) || event, y;
     207
     208        if (y = parseInt(coords.pageY))
     209            return y - parOfs.top;
    204210    }
    205 
     211   
    206212    /**
    207      * Get X and Y coordinates of a touch event
     213     * Get the first touch object in an event
    208214     *
    209215     * @param event
    210216     *            The event object
    211      * @return Coordinates object
     217     * @return The first touch object found in the event object, or false if
     218     *         none are found
    212219     */
    213220    function touchCoords(event) {
    214221        var oev = event.originalEvent || {};
    215 
    216         if (oev.touches && oev.touches.length)
    217             return { x: oev.touches[0].pageX, y: oev.touches[0].pageY };
    218         else
    219             return { x: 0, y: 0 };
     222       
     223        return oev.touches && oev.touches.length ? oev.touches[0] : false;
    220224    }
    221225
    222226    /**
    223227     * Get the current selection
    224      *
     228     * 
    225229     * @param noScale
    226230     *            If set to <code>true</code>, scaling is not applied to the
    227231     *            returned selection
     
    229233     */
    230234    function getSelection(noScale) {
    231235        var sx = noScale || scaleX, sy = noScale || scaleY;
    232 
     236       
    233237        return { x1: round(selection.x1 * sx),
    234238            y1: round(selection.y1 * sy),
    235             x2: round(selection.x2 * sx),
    236             y2: round(selection.y2 * sy),
     239            x2: round(selection.x2 * sx) - 1,
     240            y2: round(selection.y2 * sy) - 1,
    237241            width: round(selection.x2 * sx) - round(selection.x1 * sx),
    238242            height: round(selection.y2 * sy) - round(selection.y1 * sy) };
    239243    }
    240 
     244   
    241245    /**
    242246     * Set the current selection
    243      *
     247     * 
    244248     * @param x1
    245249     *            X coordinate of the upper left corner of the selection area
    246250     * @param y1
     
    255259     */
    256260    function setSelection(x1, y1, x2, y2, noScale) {
    257261        var sx = noScale || scaleX, sy = noScale || scaleY;
    258 
     262       
    259263        selection = {
    260264            x1: round(x1 / sx || 0),
    261265            y1: round(y1 / sy || 0),
    262             x2: round(x2 / sx || 0),
    263             y2: round(y2 / sy || 0)
     266            x2: round(++x2 / sx || 0),
     267            y2: round(++y2 / sy || 0)
    264268        };
    265 
     269       
    266270        selection.width = selection.x2 - selection.x1;
    267271        selection.height = selection.y2 - selection.y1;
    268272    }
     
    278282         */
    279283        if (!imgLoaded || !$img.width())
    280284            return;
    281 
     285       
    282286        /*
    283287         * Get image offset. The .offset() method returns float values, so they
    284288         * need to be rounded.
    285289         */
    286290        imgOfs = { left: round($img.offset().left), top: round($img.offset().top) };
    287 
     291       
    288292        /* Get image dimensions */
    289293        imgWidth = $img.innerWidth();
    290294        imgHeight = $img.innerHeight();
    291 
     295       
    292296        imgOfs.top += ($img.outerHeight() - imgHeight) >> 1;
    293297        imgOfs.left += ($img.outerWidth() - imgWidth) >> 1;
    294298
     
    297301        minHeight = round(options.minHeight / scaleY) || 0;
    298302        maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth));
    299303        maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight));
     304       
     305        /* Determine parent element offset */
     306        parOfs = position == 'fixed' ?
     307            /* Plugin elements position set to fixed */
     308            { left: $(document).scrollLeft(), top: $(document).scrollTop() } :
     309            /* Check parent element position */
     310            /static|^$/.test($parent.css('position')) ?
     311                /* Static */
     312                { left: 0, top: 0 } :
     313                /* Absolute or relative */
     314                { left: round($parent.offset().left) - $parent.scrollLeft(),
     315                    top: round($parent.offset().top) - $parent.scrollTop() };
    300316
    301         /*
    302          * Workaround for jQuery 1.3.2 incorrect offset calculation, originally
    303          * observed in Safari 3. Firefox 2 is also affected.
    304          */
    305         if ($().jquery == '1.3.2' && position == 'fixed' &&
    306             !docElem['getBoundingClientRect'])
    307         {
    308             imgOfs.top += max(document.body.scrollTop, docElem.scrollTop);
    309             imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft);
    310         }
    311 
    312         /* Determine parent element offset */
    313         parOfs = /absolute|relative/.test($parent.css('position')) ?
    314             { left: round($parent.offset().left) - $parent.scrollLeft(),
    315                 top: round($parent.offset().top) - $parent.scrollTop() } :
    316             position == 'fixed' ?
    317                 { left: $(document).scrollLeft(), top: $(document).scrollTop() } :
    318                 { left: 0, top: 0 };
    319 
    320317        left = viewX(0);
    321318        top = viewY(0);
    322 
     319       
    323320        /*
    324321         * Check if selection area is within image boundaries, adjust if
    325322         * necessary
    326323         */
    327324        if (selection.x2 > imgWidth || selection.y2 > imgHeight)
    328             doResize();
     325            fixAreaCoords();
    329326    }
    330327
    331328    /**
    332329     * Update plugin elements
    333      *
     330     * 
    334331     * @param resetKeyPress
    335332     *            If set to <code>false</code>, this instance's keypress
    336333     *            event handler is not activated
     
    349346        /*
    350347         * Reset the position of selection area, borders, and handles (IE6/IE7
    351348         * position them incorrectly if we don't do this)
    352          */
     349         */ 
    353350        $area.add($border).add($handles).css({ left: 0, top: 0 });
    354351
    355352        /* Set border dimensions */
    356         $border
     353        $border.add($outer)
    357354            .width(max(w - $border.outerWidth() + $border.innerWidth(), 0))
    358355            .height(max(h - $border.outerHeight() + $border.innerHeight(), 0));
    359356
    360         /* Arrange the outer area elements */
    361         $($outer[0]).css({ left: left, top: top,
    362             width: selection.x1, height: imgHeight });
    363         $($outer[1]).css({ left: left + selection.x1, top: top,
    364             width: w, height: selection.y1 });
    365         $($outer[2]).css({ left: left + selection.x2, top: top,
    366             width: imgWidth - selection.x2, height: imgHeight });
    367         $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2,
    368             width: w, height: imgHeight - selection.y2 });
     357        /* Set the dimensions and border styles of the outer area */
     358        $outer.css({
     359            left: left,
     360            top: top,
     361            width: w,
     362            height: h,
     363            borderStyle: 'solid',
     364            borderWidth: selection.y1 + 'px ' +
     365                (imgWidth - selection.x2) + 'px ' + (imgHeight - selection.y2) +
     366                'px ' + selection.x1 + 'px'
     367        });
    369368
    370369        w -= $handles.outerWidth();
    371370        h -= $handles.outerHeight();
    372 
     371       
    373372        /* Arrange handles */
    374373        switch ($handles.length) {
    375374        case 8:
     
    387386             * Need to reset the document keypress event handler -- unbind the
    388387             * current handler
    389388             */
    390             if ($.imgAreaSelect.onKeyPress != docKeyPress)
     389            if ($.imgAreaSelect.keyPress != docKeyPress)
    391390                $(document).unbind($.imgAreaSelect.keyPress,
    392391                    $.imgAreaSelect.onKeyPress);
    393392
     
    399398                $(document)[$.imgAreaSelect.keyPress](
    400399                    $.imgAreaSelect.onKeyPress = docKeyPress);
    401400        }
    402 
    403         /*
    404          * Internet Explorer displays 1px-wide dashed borders incorrectly by
    405          * filling the spaces between dashes with white. Toggling the margin
    406          * property between 0 and "auto" fixes this in IE6 and IE7 (IE8 is still
    407          * broken). This workaround is not perfect, as it requires setTimeout()
    408          * and thus causes the border to flicker a bit, but I haven't found a
    409          * better solution.
    410          *
    411          * Note: This only happens with CSS borders, set with the borderWidth,
    412          * borderOpacity, borderColor1, and borderColor2 options (which are now
    413          * deprecated). Borders created with GIF background images are fine.
    414          */
    415         if (msie && $border.outerWidth() - $border.innerWidth() == 2) {
    416             $border.css('margin', 0);
    417             setTimeout(function () { $border.css('margin', 'auto'); }, 0);
    418         }
    419401    }
    420 
     402   
    421403    /**
    422404     * Do the complete update sequence: recalculate offsets, update the
    423405     * elements, and set the correct values of x1, y1, x2, and y2.
    424      *
     406     * 
    425407     * @param resetKeyPress
    426408     *            If set to <code>false</code>, this instance's keypress
    427409     *            event handler is not activated
     
    432414        x1 = viewX(selection.x1); y1 = viewY(selection.y1);
    433415        x2 = viewX(selection.x2); y2 = viewY(selection.y2);
    434416    }
    435 
     417   
    436418    /**
    437419     * Hide or fade out an element (or multiple elements)
    438      *
     420     * 
    439421     * @param $elem
    440422     *            A jQuery object containing the element(s) to hide/fade out
    441423     * @param fn
     
    442424     *            Callback function to be called when fadeOut() completes
    443425     */
    444426    function hide($elem, fn) {
    445         options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide();
     427        options.fadeDuration ? $elem.fadeOut(options.fadeDuration, fn) : $elem.hide();
    446428    }
    447429
    448430    /**
    449      * Selection area mousemove event handler
     431     * Check if a touch event is expected and if the passed event object really
     432     * is a touch event
    450433     *
    451434     * @param event
    452435     *            The event object
     436     * @return True if the event handler should be interrupted
    453437     */
    454     function areaMouseMove(event) {
     438    function breakWhenNoTouch(event) {
     439        return touch && !/^touch/.test(event.type);
     440    }
     441
     442    /**
     443     * Check event coordinates to determine if the selection area should be
     444     * resized or moved
     445     *
     446     * @param event
     447     *            The event object
     448     */
     449    function checkResize(event) {
    455450        var x = selX(evX(event)) - selection.x1,
    456451            y = selY(evY(event)) - selection.y1;
    457452
    458         if (!adjusted) {
    459             adjust();
    460             adjusted = true;
    461 
    462             $box.one('mouseout', function () { adjusted = false; });
    463         }
    464 
    465453        /* Clear the resize mode */
    466454        resize = '';
    467455
     
    482470
    483471        $box.css('cursor', resize ? resize + '-resize' :
    484472            options.movable ? 'move' : '');
    485         if ($areaOpera)
    486             $areaOpera.toggle();
    487473    }
    488474
    489475    /**
     476     * Selection area mousemove event handler
     477     *
     478     * @param event
     479     *            The event object
     480     */
     481    function areaMouseMove(event) {
     482        if (breakWhenNoTouch(event))
     483            return;
     484
     485        if (!adjusted) {
     486            adjust();
     487            adjusted = true;
     488
     489            $box.one('mouseout', function () { adjusted = false; });
     490        }
     491
     492        checkResize(event);
     493    }
     494
     495    /**
    490496     * Document mouseup event handler
    491      *
     497     * 
    492498     * @param event
    493499     *            The event object
    494500     */
    495501    function docMouseUp(event) {
     502        /* Reset touch action flag */
     503        touch = false;
    496504        /* Set back the default cursor */
    497505        $('body').css('cursor', '');
    498506        /*
     
    504512
    505513        $(document).off('mousemove touchmove', selectingMouseMove);
    506514        $box.on('mousemove touchmove', areaMouseMove);
    507 
    508         options.onSelectEnd(img, getSelection());
     515       
     516        /*
     517         * If docMouseUp() is called by areaMouseDown() to work around the issue
     518         * with Android Chrome, there is no event object, and we don't want to
     519         * run the onSelectEnd callback function.
     520         */
     521        if (event)
     522            options.onSelectEnd(img, getSelection());
    509523    }
    510524
    511525    /**
    512526     * Selection area mousedown event handler
    513      *
     527     * 
    514528     * @param event
    515529     *            The event object
    516530     * @return false
     
    517531     */
    518532    function areaMouseDown(event) {
    519533        if (event.type == 'mousedown' && event.which != 1) return false;
     534       
     535        if (event.type == 'touchstart') {
     536            /*
     537             * Android Chrome often does not produce a touchend event
     538             * (https://code.google.com/p/chromium/issues/detail?id=152913), so
     539             * if it appears that the touch flag is still set, we call the
     540             * mouseup/touchend event handler to clean up after the previous
     541             * touch action.
     542             */
     543            if (touch)
     544                docMouseUp();
    520545
    521         /*
    522          * With mobile browsers, there is no "moving the pointer over" action,
    523          * so we need to simulate one mousemove event happening prior to
    524          * mousedown/touchstart.
    525          */
    526         areaMouseMove(event);
     546            /* This is a start of a touch action */
     547            touch = true;
    527548
    528         adjust();
     549            /*
     550             * Normally, checkResize() is called by the mousemove event handler
     551             * triggered just before mousedown, but with a touch action there
     552             * is no mousemove, so we need to call it explicitly.
     553             */
     554            checkResize(event);
     555        }
     556        else
     557            adjust();
    529558
    530559        if (resize) {
    531560            /* Resize mode is in effect */
    532             $('body').css('cursor', resize + '-resize');
    533561
    534             x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']);
    535             y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']);
     562            /*
     563             * Set (x1, y1) to the fixed corner of the selection area, and (x2,
     564             * y2) to the corner that's being moved.
     565             */
     566            x1 = viewX(selection['x' + (1 + /w/.test(resize))]);
     567            y1 = viewY(selection['y' + (1 + /n/.test(resize))]);
     568            x2 = viewX(selection['x' + (1 + !/w/.test(resize))]);
     569            y2 = viewY(selection['y' + (1 + !/n/.test(resize))]);
    536570
     571            edgeX = x2 - evX(event);
     572            edgeY = y2 - evY(event);
     573
    537574            $(document).on('mousemove touchmove', selectingMouseMove)
    538575                .one('mouseup touchend', docMouseUp);
    539576            $box.off('mousemove touchmove', areaMouseMove);
     
    546583
    547584            $(document).on('mousemove touchmove', movingMouseMove)
    548585                .one('mouseup touchend', function () {
     586                    touch = false;
    549587                    options.onSelectEnd(img, getSelection());
    550588
    551589                    $(document).off('mousemove touchmove', movingMouseMove);
     
    560598
    561599    /**
    562600     * Adjust the x2/y2 coordinates to maintain aspect ratio (if defined)
    563      *
     601     * 
    564602     * @param xFirst
    565603     *            If set to <code>true</code>, calculate x2 first. Otherwise,
    566604     *            calculate y2 first.
     
    569607        if (aspectRatio)
    570608            if (xFirst) {
    571609                x2 = max(left, min(left + imgWidth,
    572                     x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)));
     610                    x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)));   
    573611                y2 = round(max(top, min(top + imgHeight,
    574612                    y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))));
    575613                x2 = round(x2);
     
    584622    }
    585623
    586624    /**
    587      * Resize the selection area respecting the minimum/maximum dimensions and
    588      * aspect ratio
     625     * Check if the coordinates of the selection area are within the required
     626     * limits and conform to the aspect ratio; adjust if necessary
    589627     */
    590     function doResize() {
     628    function fixAreaCoords() {
    591629        /*
    592630         * Make sure the top left corner of the selection area stays within
    593631         * image boundaries (it might not if the image source was dynamically
     
    595633         */
    596634        x1 = min(x1, left + imgWidth);
    597635        y1 = min(y1, top + imgHeight);
    598 
     636       
    599637        if (abs(x2 - x1) < minWidth) {
    600638            /* Selection width is smaller than minWidth */
    601639            x2 = x1 - minWidth * (x2 < x1 || -1);
     
    618656
    619657        x2 = max(left, min(x2, left + imgWidth));
    620658        y2 = max(top, min(y2, top + imgHeight));
    621 
     659       
    622660        fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio);
    623661
    624662        if (abs(x2 - x1) > maxWidth) {
     
    636674        selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)),
    637675            y1: selY(min(y1, y2)), y2: selY(max(y1, y2)),
    638676            width: abs(x2 - x1), height: abs(y2 - y1) };
     677    }
    639678
     679    /**
     680     * Resize the selection area respecting the minimum/maximum dimensions and
     681     * aspect ratio
     682     */
     683    function doResize() {
     684        fixAreaCoords();
     685
    640686        update();
    641687
    642688        options.onSelectChange(img, getSelection());
     
    644690
    645691    /**
    646692     * Mousemove event handler triggered when the user is selecting an area
    647      *
     693     * 
    648694     * @param event
    649695     *            The event object
    650696     * @return false
    651697     */
    652698    function selectingMouseMove(event) {
    653         x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2);
    654         y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2);
     699        if (breakWhenNoTouch(event))
     700            return;
     701       
     702        fixAreaCoords();
    655703
     704        x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) + edgeX : viewX(selection.x2);
     705        y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) + edgeY : viewY(selection.y2);
     706
    656707        doResize();
    657708
    658         return false;
     709        return false;       
    659710    }
    660711
    661712    /**
    662713     * Move the selection area
    663      *
     714     * 
    664715     * @param newX1
    665716     *            New viewport X1
    666717     * @param newY1
     
    680731
    681732    /**
    682733     * Mousemove event handler triggered when the selection area is being moved
    683      *
     734     * 
    684735     * @param event
    685736     *            The event object
    686737     * @return false
    687738     */
    688739    function movingMouseMove(event) {
     740        if (breakWhenNoTouch(event))
     741            return;
     742
    689743        x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width));
    690744        y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height));
    691745
    692746        doMove(x1, y1);
    693747
    694         event.preventDefault();
     748        event.preventDefault();     
    695749        return false;
    696750    }
    697751
     
    703757        adjust();
    704758
    705759        x2 = x1;
    706         y2 = y1;
     760        y2 = y1;       
    707761        doResize();
    708762
    709763        resize = '';
     
    710764
    711765        if (!$outer.is(':visible'))
    712766            /* Show the plugin elements */
    713             $box.add($outer).hide().fadeIn(options.fadeSpeed||0);
     767            $box.add($outer).hide().fadeIn(options.fadeDuration||0)
    714768
    715769        shown = true;
    716770
     
    729783        $(document).off('mousemove touchmove', startSelection)
    730784            .off('mouseup touchend', cancelSelection);
    731785        hide($box.add($outer));
    732 
     786       
    733787        setSelection(selX(x1), selY(y1), selX(x1), selY(y1));
    734 
     788       
    735789        /* If this is an API call, callback functions should not be triggered */
    736790        if (!(this instanceof $.imgAreaSelect)) {
    737791            options.onSelectChange(img, getSelection());
     
    741795
    742796    /**
    743797     * Image mousedown event handler
    744      *
     798     * 
    745799     * @param event
    746800     *            The event object
    747801     * @return false
     
    748802     */
    749803    function imgMouseDown(event) {
    750804        /* Ignore the event if animation is in progress */
    751         if (event.which != 1 || $outer.is(':animated')) return false;
     805        if (event.type == 'mousedown' && event.which != 1 ||
     806                $outer.is(':animated'))
     807            return false;
    752808
     809        /* If it's a touch action, set the touch flag */
     810        touch = event.type == 'touchstart';
     811
    753812        adjust();
    754813        startX = x1 = evX(event);
    755814        startY = y1 = evY(event);
     815        edgeX = edgeY = 0;
    756816
    757817        /* Selection will start when the mouse is moved */
    758818        $(document).on({ 'mousemove touchmove': startSelection,
     
    760820
    761821        return false;
    762822    }
    763 
     823   
    764824    /**
    765825     * Window resize event handler
    766826     */
     
    788848            onSelectEnd: function () {}
    789849        }, options));
    790850
    791         $box.add($outer).css({ visibility: '' });
    792 
    793851        if (options.show) {
    794852            shown = true;
    795853            adjust();
    796854            update();
    797             $box.add($outer).hide().fadeIn(options.fadeSpeed||0);
     855            $box.add($outer).hide().fadeIn(options.fadeDuration||0)
    798856        }
    799857
    800858        /*
     
    807865
    808866    /**
    809867     * Document keypress event handler
    810      *
     868     * 
    811869     * @param event
    812870     *            The event object
    813871     * @return false
     
    814872     */
    815873    var docKeyPress = function(event) {
    816874        var k = options.keys, d, t, key = event.keyCode;
    817 
     875       
    818876        d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt :
    819877            !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl :
    820878            !isNaN(k.shift) && event.shiftKey ? k.shift :
     
    825883            (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey)))
    826884        {
    827885            /* Resize selection */
    828 
     886           
    829887            switch (key) {
    830888            case 37:
    831889                /* Left */
     
    855913        }
    856914        else {
    857915            /* Move selection */
    858 
     916           
    859917            x1 = min(x1, x2);
    860918            y1 = min(y1, y2);
    861919
     
    885943    };
    886944
    887945    /**
    888      * Apply style options to plugin element (or multiple elements)
    889      *
    890      * @param $elem
    891      *            A jQuery object representing the element(s) to style
    892      * @param props
    893      *            An object that maps option names to corresponding CSS
    894      *            properties
    895      */
    896     function styleOptions($elem, props) {
    897         for (var option in props)
    898             if (options[option] !== undefined)
    899                 $elem.css(props[option], options[option]);
    900     }
    901 
    902     /**
    903946     * Set plugin options
    904      *
     947     * 
    905948     * @param newOptions
    906949     *            The new options object
    907950     */
    908951    function setOptions(newOptions) {
    909952        if (newOptions.parent)
    910             ($parent = $(newOptions.parent)).append($box.add($outer));
    911 
     953            ($parent = $(newOptions.parent)).append($box).append($outer);
     954       
    912955        /* Merge the new options with the existing ones */
    913956        $.extend(options, newOptions);
    914957
     
    923966
    924967            while (i--)
    925968                $handles = $handles.add(div());
    926 
     969           
    927970            /* Add a class to handles and set the CSS properties */
    928971            $handles.addClass(options.classPrefix + '-handle').css({
    929972                position: 'absolute',
     
    934977                fontSize: 0,
    935978                zIndex: zIndex + 1 || 1
    936979            });
    937 
     980           
    938981            /*
    939982             * If handle width/height has not been set with CSS rules, set the
    940983             * default 5px
     
    941984             */
    942985            if (!parseInt($handles.css('width')) >= 0)
    943986                $handles.width(5).height(5);
    944 
    945             /*
    946              * If the borderWidth option is in use, add a solid border to
    947              * handles
    948              */
    949             if (o = options.borderWidth)
    950                 $handles.css({ borderWidth: o, borderStyle: 'solid' });
    951 
    952             /* Apply other style options */
    953             styleOptions($handles, { borderColor1: 'border-color',
    954                 borderColor2: 'background-color',
    955                 borderOpacity: 'opacity' });
    956987        }
    957988
    958989        /* Calculate scale factors */
     
    9771008        for (i = 0; i++ < 4;)
    9781009            $($border[i-1]).addClass(options.classPrefix + '-border' + i);
    9791010
    980         /* Apply style options */
    981         styleOptions($area, { selectionColor: 'background-color',
    982             selectionOpacity: 'opacity' });
    983         styleOptions($border, { borderOpacity: 'opacity',
    984             borderWidth: 'border-width' });
    985         styleOptions($outer, { outerColor: 'background-color',
    986             outerOpacity: 'opacity' });
    987         if (o = options.borderColor1)
    988             $($border[0]).css({ borderStyle: 'solid', borderColor: o });
    989         if (o = options.borderColor2)
    990             $($border[1]).css({ borderStyle: 'dashed', borderColor: o });
    991 
    9921011        /* Append all the selection area elements to the container box */
    993         $box.append($area.add($border).add($areaOpera)).append($handles);
     1012        $box.append($area.add($border)).append($handles);
    9941013
    9951014        if (msie) {
    9961015            if (o = ($outer.css('filter')||'').match(/opacity=(\d+)/))
     
    9981017            if (o = ($border.css('filter')||'').match(/opacity=(\d+)/))
    9991018                $border.css('opacity', o[1]/100);
    10001019        }
    1001 
     1020       
    10021021        if (newOptions.hide)
    10031022            hide($box.add($outer));
    10041023        else if (newOptions.show && imgLoaded) {
    10051024            shown = true;
    1006             $box.add($outer).fadeIn(options.fadeSpeed||0);
     1025            $box.add($outer).fadeIn(options.fadeDuration||0)
    10071026            doUpdate();
    10081027        }
    10091028
     
    10101029        /* Calculate the aspect ratio factor */
    10111030        aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1];
    10121031
    1013         $img.add($outer).unbind('mousedown', imgMouseDown);
    1014 
     1032        $img.add($outer).off('mousedown touchstart', imgMouseDown);
     1033       
    10151034        if (options.disable || options.enable === false) {
    10161035            /* Disable the plugin */
    10171036            $box.off({ 'mousemove touchmove': areaMouseMove,
     
    10241043                if (options.resizable || options.movable)
    10251044                    $box.on({ 'mousemove touchmove': areaMouseMove,
    10261045                        'mousedown touchstart': areaMouseDown });
    1027 
     1046   
    10281047                $(window).resize(windowResize);
    10291048            }
    10301049
     
    10311050            if (!options.persistent)
    10321051                $img.add($outer).on('mousedown touchstart', imgMouseDown);
    10331052        }
    1034 
     1053       
    10351054        options.enable = options.disable = undefined;
    10361055    }
    1037 
     1056   
    10381057    /**
    10391058     * Remove plugin completely
    10401059     */
     
    10451064        setOptions({ disable: true });
    10461065        $box.add($outer).remove();
    10471066    };
    1048 
     1067   
    10491068    /*
    10501069     * Public API
    10511070     */
    1052 
     1071   
    10531072    /**
    10541073     * Get current options
    1055      *
     1074     * 
    10561075     * @return An object containing the set of options currently in use
    10571076     */
    10581077    this.getOptions = function () { return options; };
    1059 
     1078   
    10601079    /**
    10611080     * Set plugin options
    1062      *
     1081     * 
    10631082     * @param newOptions
    10641083     *            The new options object
    10651084     */
    10661085    this.setOptions = setOptions;
    1067 
     1086   
    10681087    /**
    10691088     * Get the current selection
    1070      *
     1089     * 
    10711090     * @param noScale
    10721091     *            If set to <code>true</code>, scaling is not applied to the
    10731092     *            returned selection
     
    10741093     * @return Selection object
    10751094     */
    10761095    this.getSelection = getSelection;
    1077 
     1096   
    10781097    /**
    10791098     * Set the current selection
    1080      *
     1099     * 
    10811100     * @param x1
    10821101     *            X coordinate of the upper left corner of the selection area
    10831102     * @param y1
     
    10911110     *            new selection
    10921111     */
    10931112    this.setSelection = setSelection;
    1094 
     1113   
    10951114    /**
    10961115     * Cancel selection
    10971116     */
    10981117    this.cancelSelection = cancelSelection;
    1099 
     1118   
    11001119    /**
    11011120     * Update plugin elements
    1102      *
     1121     * 
    11031122     * @param resetKeyPress
    11041123     *            If set to <code>false</code>, this instance's keypress
    11051124     *            event handler is not activated
     
    11081127
    11091128    /* Do the dreaded browser detection */
    11101129    var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1],
    1111         opera = /opera/i.test(ua),
    11121130        safari = /webkit/i.test(ua) && !/chrome/i.test(ua);
    11131131
    1114     /*
     1132    /* 
    11151133     * Traverse the image's parent elements (up to <body>) and find the
    11161134     * highest z-index
    11171135     */
     
    11201138    while ($p.length) {
    11211139        zIndex = max(zIndex,
    11221140            !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex);
    1123         /* Also check if any of the ancestor elements has fixed position */
    1124         if ($p.css('position') == 'fixed')
     1141        /*
     1142         * If the parent element is not set explicitly, check if any of the
     1143         * ancestor elements has fixed position
     1144         */
     1145        if (!options.parent && $p.css('position') == 'fixed')
    11251146            position = 'fixed';
    11261147
    11271148        $p = $p.parent(':not(body)');
     
    11331154     */
    11341155    zIndex = options.zIndex || zIndex;
    11351156
    1136     if (msie)
    1137         $img.attr('unselectable', 'on');
    1138 
    11391157    /*
    11401158     * In MSIE and WebKit, we need to use the keydown event instead of keypress
    11411159     */
    11421160    $.imgAreaSelect.keyPress = msie || safari ? 'keydown' : 'keypress';
    11431161
    1144     /*
    1145      * There is a bug affecting the CSS cursor property in Opera (observed in
    1146      * versions up to 10.00) that prevents the cursor from being updated unless
    1147      * the mouse leaves and enters the element again. To trigger the mouseover
    1148      * event, we're adding an additional div to $box and we're going to toggle
    1149      * it when mouse moves inside the selection area.
    1150      */
    1151     if (opera)
    1152         $areaOpera = div().css({ width: '100%', height: '100%',
    1153             position: 'absolute', zIndex: zIndex + 2 || 2 });
    1154 
    1155     /*
    1156      * We initially set visibility to "hidden" as a workaround for a weird
    1157      * behaviour observed in Google Chrome 1.0.154.53 (on Windows XP). Normally
    1158      * we would just set display to "none", but, for some reason, if we do so
    1159      * then Chrome refuses to later display the element with .show() or
    1160      * .fadeIn().
    1161      */
    1162     $box.add($outer).css({ visibility: 'hidden', position: position,
    1163         overflow: 'hidden', zIndex: zIndex || '0' });
     1162    $box.add($outer).hide().css({ position: position, overflow: 'hidden',
     1163        zIndex: zIndex || '0' });
    11641164    $box.css({ zIndex: zIndex + 2 || 2 });
    11651165    $area.add($border).css({ position: 'absolute', fontSize: 0 });
    1166 
     1166   
    11671167    /*
    11681168     * If the image has been fully loaded, or if it is not really an image (eg.
    11691169     * a div), call imgLoad() immediately; otherwise, bind it to be called once
     
    11721172    img.complete || img.readyState == 'complete' || !$img.is('img') ?
    11731173        imgLoad() : $img.one('load', imgLoad);
    11741174
    1175     /*
     1175    /* 
    11761176     * MSIE 9.0 doesn't always fire the image load event -- resetting the src
    11771177     * attribute seems to trigger it. The check is for version 7 and above to
    11781178     * accommodate for MSIE 9 running in compatibility mode.
     
    11831183
    11841184/**
    11851185 * Invoke imgAreaSelect on a jQuery object containing the image(s)
    1186  *
     1186 * 
    11871187 * @param options
    11881188 *            Options object
    11891189 * @return The jQuery object or a reference to imgAreaSelect instance (if the
     
    12071207        }
    12081208        else if (!options.remove) {
    12091209            /* No exising instance -- create a new one */
    1210 
     1210           
    12111211            /*
    12121212             * If neither the "enable" nor the "disable" option is present, add
    12131213             * "enable" as the default
    1214              */
     1214             */ 
    12151215            if (options.enable === undefined && options.disable === undefined)
    12161216                options.enable = true;
    12171217
     
    12181218            $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options));
    12191219        }
    12201220    });
    1221 
     1221   
    12221222    if (options.instance)
    12231223        /*
    12241224         * Return the imgAreaSelect instance bound to the first element in the
  • trunk/wp-includes/js/imgareaselect/jquery.imgareaselect.min.js

     
    1 !function(e){function t(){return e("<div/>")}var o=Math.abs,i=Math.max,s=Math.min,n=Math.round;e.imgAreaSelect=function(r,c){function d(e){return e+gt.left-vt.left}function a(e){return e+gt.top-vt.top}function u(e){return e-gt.left+vt.left}function l(e){return e-gt.top+vt.top}function h(e){return i(e.pageX||0,m(e).x)-vt.left}function f(e){return i(e.pageY||0,m(e).y)-vt.top}function m(e){var t=e.originalEvent||{};return t.touches&&t.touches.length?{x:t.touches[0].pageX,y:t.touches[0].pageY}:{x:0,y:0}}function p(e){var t=e||B,o=e||Q;return{x1:n(wt.x1*t),y1:n(wt.y1*o),x2:n(wt.x2*t),y2:n(wt.y2*o),width:n(wt.x2*t)-n(wt.x1*t),height:n(wt.y2*o)-n(wt.y1*o)}}function y(e,t,o,i,s){var r=s||B,c=s||Q;wt={x1:n(e/r||0),y1:n(t/c||0),x2:n(o/r||0),y2:n(i/c||0)},wt.width=wt.x2-wt.x1,wt.height=wt.y2-wt.y1}function g(){T&&lt.width()&&(gt={left:n(lt.offset().left),top:n(lt.offset().top)},R=lt.innerWidth(),X=lt.innerHeight(),gt.top+=lt.outerHeight()-X>>1,gt.left+=lt.outerWidth()-R>>1,G=n(c.minWidth/B)||0,J=n(c.minHeight/Q)||0,U=n(s(c.maxWidth/B||1<<24,R)),V=n(s(c.maxHeight/Q||1<<24,X)),"1.3.2"!=e().jquery||"fixed"!=xt||St.getBoundingClientRect||(gt.top+=i(document.body.scrollTop,St.scrollTop),gt.left+=i(document.body.scrollLeft,St.scrollLeft)),vt=/absolute|relative/.test(Y.css("position"))?{left:n(Y.offset().left)-Y.scrollLeft(),top:n(Y.offset().top)-Y.scrollTop()}:"fixed"==xt?{left:e(document).scrollLeft(),top:e(document).scrollTop()}:{left:0,top:0},j=d(0),D=a(0),(wt.x2>R||wt.y2>X)&&C())}function v(t){if(_){switch(ht.css({left:d(wt.x1),top:a(wt.y1)}).add(ft).width(dt=wt.width).height(at=wt.height),ft.add(mt).add(yt).css({left:0,top:0}),mt.width(i(dt-mt.outerWidth()+mt.innerWidth(),0)).height(i(at-mt.outerHeight()+mt.innerHeight(),0)),e(pt[0]).css({left:j,top:D,width:wt.x1,height:X}),e(pt[1]).css({left:j+wt.x1,top:D,width:dt,height:wt.y1}),e(pt[2]).css({left:j+wt.x2,top:D,width:R-wt.x2,height:X}),e(pt[3]).css({left:j+wt.x1,top:D+wt.y2,width:dt,height:X-wt.y2}),dt-=yt.outerWidth(),at-=yt.outerHeight(),yt.length){case 8:e(yt[4]).css({left:dt>>1}),e(yt[5]).css({left:dt,top:at>>1}),e(yt[6]).css({left:dt>>1,top:at}),e(yt[7]).css({top:at>>1});case 4:yt.slice(1,3).css({left:dt}),yt.slice(2,4).css({top:at})}t!==!1&&(e.imgAreaSelect.onKeyPress!=kt&&e(document).unbind(e.imgAreaSelect.keyPress,e.imgAreaSelect.onKeyPress),c.keys&&e(document)[e.imgAreaSelect.keyPress](e.imgAreaSelect.onKeyPress=kt)),Ct&&mt.outerWidth()-mt.innerWidth()==2&&(mt.css("margin",0),setTimeout(function(){mt.css("margin","auto")},0))}}function b(e){g(),v(e),et=d(wt.x1),tt=a(wt.y1),ot=d(wt.x2),it=a(wt.y2)}function x(e,t){c.fadeSpeed?e.fadeOut(c.fadeSpeed,t):e.hide()}function w(e){var t=u(h(e))-wt.x1,o=l(f(e))-wt.y1;ut||(g(),ut=!0,ht.one("mouseout",function(){ut=!1})),F="",c.resizable&&(o<=c.resizeMargin?F="n":o>=wt.height-c.resizeMargin&&(F="s"),t<=c.resizeMargin?F+="w":t>=wt.width-c.resizeMargin&&(F+="e")),ht.css("cursor",F?F+"-resize":c.movable?"move":""),L&&L.toggle()}function S(){e("body").css("cursor",""),(c.autoHide||wt.width*wt.height==0)&&x(ht.add(pt),function(){e(this).hide()}),e(document).off("mousemove touchmove",A),ht.on("mousemove touchmove",w),c.onSelectEnd(r,p())}function z(t){return"mousedown"==t.type&&1!=t.which?!1:(w(t),g(),F?(e("body").css("cursor",F+"-resize"),et=d(wt[/w/.test(F)?"x2":"x1"]),tt=a(wt[/n/.test(F)?"y2":"y1"]),e(document).on("mousemove touchmove",A).one("mouseup touchend",S),ht.off("mousemove touchmove",w)):c.movable?($=j+wt.x1-h(t),q=D+wt.y1-f(t),ht.off("mousemove touchmove",w),e(document).on("mousemove touchmove",I).one("mouseup touchend",function(){c.onSelectEnd(r,p()),e(document).off("mousemove touchmove",I),ht.on("mousemove touchmove",w)})):lt.mousedown(t),!1)}function k(e){Z&&(e?(ot=i(j,s(j+R,et+o(it-tt)*Z*(ot>et||-1))),it=n(i(D,s(D+X,tt+o(ot-et)/Z*(it>tt||-1)))),ot=n(ot)):(it=i(D,s(D+X,tt+o(ot-et)/Z*(it>tt||-1))),ot=n(i(j,s(j+R,et+o(it-tt)*Z*(ot>et||-1)))),it=n(it)))}function C(){et=s(et,j+R),tt=s(tt,D+X),o(ot-et)<G&&(ot=et-G*(et>ot||-1),j>ot?et=j+G:ot>j+R&&(et=j+R-G)),o(it-tt)<J&&(it=tt-J*(tt>it||-1),D>it?tt=D+J:it>D+X&&(tt=D+X-J)),ot=i(j,s(ot,j+R)),it=i(D,s(it,D+X)),k(o(ot-et)<o(it-tt)*Z),o(ot-et)>U&&(ot=et-U*(et>ot||-1),k()),o(it-tt)>V&&(it=tt-V*(tt>it||-1),k(!0)),wt={x1:u(s(et,ot)),x2:u(i(et,ot)),y1:l(s(tt,it)),y2:l(i(tt,it)),width:o(ot-et),height:o(it-tt)},v(),c.onSelectChange(r,p())}function A(e){return ot=/w|e|^$/.test(F)||Z?h(e):d(wt.x2),it=/n|s|^$/.test(F)||Z?f(e):a(wt.y2),C(),!1}function W(t,o){ot=(et=t)+wt.width,it=(tt=o)+wt.height,e.extend(wt,{x1:u(et),y1:l(tt),x2:u(ot),y2:l(it)}),v(),c.onSelectChange(r,p())}function I(e){return et=i(j,s($+h(e),j+R-wt.width)),tt=i(D,s(q+f(e),D+X-wt.height)),W(et,tt),e.preventDefault(),!1}function K(){e(document).off("mousemove touchmove",K),g(),ot=et,it=tt,C(),F="",pt.is(":visible")||ht.add(pt).hide().fadeIn(c.fadeSpeed||0),_=!0,e(document).off("mouseup touchend",P).on("mousemove touchmove",A).one("mouseup touchend",S),ht.off("mousemove touchmove",w),c.onSelectStart(r,p())}function P(){e(document).off("mousemove touchmove",K).off("mouseup touchend",P),x(ht.add(pt)),y(u(et),l(tt),u(et),l(tt)),this instanceof e.imgAreaSelect||(c.onSelectChange(r,p()),c.onSelectEnd(r,p()))}function N(t){return 1!=t.which||pt.is(":animated")?!1:(g(),$=et=h(t),q=tt=f(t),e(document).on({"mousemove touchmove":K,"mouseup touchend":P}),!1)}function H(){b(!1)}function M(){T=!0,O(c=e.extend({classPrefix:"imgareaselect",movable:!0,parent:"body",resizable:!0,resizeMargin:10,onInit:function(){},onSelectStart:function(){},onSelectChange:function(){},onSelectEnd:function(){}},c)),ht.add(pt).css({visibility:""}),c.show&&(_=!0,g(),v(),ht.add(pt).hide().fadeIn(c.fadeSpeed||0)),setTimeout(function(){c.onInit(r,p())},0)}function E(e,t){for(var o in t)void 0!==c[o]&&e.css(t[o],c[o])}function O(o){if(o.parent&&(Y=e(o.parent)).append(ht.add(pt)),e.extend(c,o),g(),null!=o.handles){for(yt.remove(),yt=e([]),rt=o.handles?"corners"==o.handles?4:8:0;rt--;)yt=yt.add(t());yt.addClass(c.classPrefix+"-handle").css({position:"absolute",fontSize:0,zIndex:bt+1||1}),!parseInt(yt.css("width"))>=0&&yt.width(5).height(5),(ct=c.borderWidth)&&yt.css({borderWidth:ct,borderStyle:"solid"}),E(yt,{borderColor1:"border-color",borderColor2:"background-color",borderOpacity:"opacity"})}for(B=c.imageWidth/R||1,Q=c.imageHeight/X||1,null!=o.x1&&(y(o.x1,o.y1,o.x2,o.y2),o.show=!o.hide),o.keys&&(c.keys=e.extend({shift:1,ctrl:"resize"},o.keys)),pt.addClass(c.classPrefix+"-outer"),ft.addClass(c.classPrefix+"-selection"),rt=0;rt++<4;)e(mt[rt-1]).addClass(c.classPrefix+"-border"+rt);E(ft,{selectionColor:"background-color",selectionOpacity:"opacity"}),E(mt,{borderOpacity:"opacity",borderWidth:"border-width"}),E(pt,{outerColor:"background-color",outerOpacity:"opacity"}),(ct=c.borderColor1)&&e(mt[0]).css({borderStyle:"solid",borderColor:ct}),(ct=c.borderColor2)&&e(mt[1]).css({borderStyle:"dashed",borderColor:ct}),ht.append(ft.add(mt).add(L)).append(yt),Ct&&((ct=(pt.css("filter")||"").match(/opacity=(\d+)/))&&pt.css("opacity",ct[1]/100),(ct=(mt.css("filter")||"").match(/opacity=(\d+)/))&&mt.css("opacity",ct[1]/100)),o.hide?x(ht.add(pt)):o.show&&T&&(_=!0,ht.add(pt).fadeIn(c.fadeSpeed||0),b()),Z=(nt=(c.aspectRatio||"").split(/:/))[0]/nt[1],lt.add(pt).unbind("mousedown",N),c.disable||c.enable===!1?(ht.off({"mousemove touchmove":w,"mousedown touchstart":z}),e(window).off("resize",H)):((c.enable||c.disable===!1)&&((c.resizable||c.movable)&&ht.on({"mousemove touchmove":w,"mousedown touchstart":z}),e(window).resize(H)),c.persistent||lt.add(pt).on("mousedown touchstart",N)),c.enable=c.disable=void 0}var T,L,j,D,R,X,Y,$,q,B,Q,F,G,J,U,V,Z,_,et,tt,ot,it,st,nt,rt,ct,dt,at,ut,lt=e(r),ht=t(),ft=t(),mt=t().add(t()).add(t()).add(t()),pt=t().add(t()).add(t()).add(t()),yt=e([]),gt={left:0,top:0},vt={left:0,top:0},bt=0,xt="absolute",wt={x1:0,y1:0,x2:0,y2:0,width:0,height:0},St=document.documentElement,zt=navigator.userAgent,kt=function(e){var t,o,n=c.keys,r=e.keyCode;if(t=isNaN(n.alt)||!e.altKey&&!e.originalEvent.altKey?!isNaN(n.ctrl)&&e.ctrlKey?n.ctrl:!isNaN(n.shift)&&e.shiftKey?n.shift:isNaN(n.arrows)?10:n.arrows:n.alt,"resize"==n.arrows||"resize"==n.shift&&e.shiftKey||"resize"==n.ctrl&&e.ctrlKey||"resize"==n.alt&&(e.altKey||e.originalEvent.altKey)){switch(r){case 37:t=-t;case 39:o=i(et,ot),et=s(et,ot),ot=i(o+t,et),k();break;case 38:t=-t;case 40:o=i(tt,it),tt=s(tt,it),it=i(o+t,tt),k(!0);break;default:return}C()}else switch(et=s(et,ot),tt=s(tt,it),r){case 37:W(i(et-t,j),tt);break;case 38:W(et,i(tt-t,D));break;case 39:W(et+s(t,R-u(ot)),tt);break;case 40:W(et,tt+s(t,X-l(it)));break;default:return}return!1};this.remove=function(){O({disable:!0}),ht.add(pt).remove()},this.getOptions=function(){return c},this.setOptions=O,this.getSelection=p,this.setSelection=y,this.cancelSelection=P,this.update=b;var Ct=(/msie ([\w.]+)/i.exec(zt)||[])[1],At=/opera/i.test(zt),Wt=/webkit/i.test(zt)&&!/chrome/i.test(zt);for(st=lt;st.length;)bt=i(bt,isNaN(st.css("z-index"))?bt:st.css("z-index")),"fixed"==st.css("position")&&(xt="fixed"),st=st.parent(":not(body)");bt=c.zIndex||bt,Ct&&lt.attr("unselectable","on"),e.imgAreaSelect.keyPress=Ct||Wt?"keydown":"keypress",At&&(L=t().css({width:"100%",height:"100%",position:"absolute",zIndex:bt+2||2})),ht.add(pt).css({visibility:"hidden",position:xt,overflow:"hidden",zIndex:bt||"0"}),ht.css({zIndex:bt+2||2}),ft.add(mt).css({position:"absolute",fontSize:0}),r.complete||"complete"==r.readyState||!lt.is("img")?M():lt.one("load",M),!T&&Ct&&Ct>=7&&(r.src=r.src)},e.fn.imgAreaSelect=function(t){return t=t||{},this.each(function(){e(this).data("imgAreaSelect")?t.remove?(e(this).data("imgAreaSelect").remove(),e(this).removeData("imgAreaSelect")):e(this).data("imgAreaSelect").setOptions(t):t.remove||(void 0===t.enable&&void 0===t.disable&&(t.enable=!0),e(this).data("imgAreaSelect",new e.imgAreaSelect(this,t)))}),t.instance?e(this).data("imgAreaSelect"):this}}(jQuery);
    2  No newline at end of file
     1/*! imgareaselect 1.0.0-rc.1 */ (function(e){function t(){return e("<div/>")}var o=Math.abs,n=Math.max,i=Math.min,s=Math.round;e.imgAreaSelect=function(a,c){function r(e){return e+bt.left-St.left}function d(e){return e+bt.top-St.top}function u(e){return e-bt.left+St.left}function h(e){return e-bt.top+St.top}function f(e){var t,o=m(e)||e;return(t=parseInt(o.pageX))?t-St.left:void 0}function l(e){var t,o=m(e)||e;return(t=parseInt(o.pageY))?t-St.top:void 0}function m(e){var t=e.originalEvent||{};return t.touches&&t.touches.length?t.touches[0]:!1}function p(e){var t=e||G,o=e||J;return{x1:s(At.x1*t),y1:s(At.y1*o),x2:s(At.x2*t)-1,y2:s(At.y2*o)-1,width:s(At.x2*t)-s(At.x1*t),height:s(At.y2*o)-s(At.y1*o)}}function v(e,t,o,n,i){var a=i||G,c=i||J;At={x1:s(e/a||0),y1:s(t/c||0),x2:s(++o/a||0),y2:s(++n/c||0)},At.width=At.x2-At.x1,At.height=At.y2-At.y1}function y(){$&&pt.width()&&(bt={left:s(pt.offset().left),top:s(pt.offset().top)},Q=pt.innerWidth(),R=pt.innerHeight(),bt.top+=pt.outerHeight()-R>>1,bt.left+=pt.outerWidth()-Q>>1,V=s(c.minWidth/G)||0,Z=s(c.minHeight/J)||0,_=s(i(c.maxWidth/G||1<<24,Q)),et=s(i(c.maxHeight/J||1<<24,R)),St="fixed"==kt?{left:e(document).scrollLeft(),top:e(document).scrollTop()}:/static|^$/.test(X.css("position"))?{left:0,top:0}:{left:s(X.offset().left)-X.scrollLeft(),top:s(X.offset().top)-X.scrollTop()},L=r(0),j=d(0),(At.x2>Q||At.y2>R)&&P())}function g(t){if(ot){switch(vt.css({left:r(At.x1),top:d(At.y1)}).add(yt).width(ft=At.width).height(lt=At.height),yt.add(gt).add(wt).css({left:0,top:0}),gt.add(xt).width(n(ft-gt.outerWidth()+gt.innerWidth(),0)).height(n(lt-gt.outerHeight()+gt.innerHeight(),0)),xt.css({left:L,top:j,width:ft,height:lt,borderStyle:"solid",borderWidth:At.y1+"px "+(Q-At.x2)+"px "+(R-At.y2)+"px "+At.x1+"px"}),ft-=wt.outerWidth(),lt-=wt.outerHeight(),wt.length){case 8:e(wt[4]).css({left:ft>>1}),e(wt[5]).css({left:ft,top:lt>>1}),e(wt[6]).css({left:ft>>1,top:lt}),e(wt[7]).css({top:lt>>1});case 4:wt.slice(1,3).css({left:ft}),wt.slice(2,4).css({top:lt})}t!==!1&&(e.imgAreaSelect.keyPress!=Pt&&e(document).unbind(e.imgAreaSelect.keyPress,e.imgAreaSelect.onKeyPress),c.keys&&e(document)[e.imgAreaSelect.keyPress](e.imgAreaSelect.onKeyPress=Pt))}}function x(e){y(),g(e),nt=r(At.x1),it=d(At.y1),st=r(At.x2),at=d(At.y2)}function w(e,t){c.fadeDuration?e.fadeOut(c.fadeDuration,t):e.hide()}function b(e){return ct&&!/^touch/.test(e.type)}function S(e){var t=u(f(e))-At.x1,o=h(l(e))-At.y1;U="",c.resizable&&(c.resizeMargin>=o?U="n":o>=At.height-c.resizeMargin&&(U="s"),c.resizeMargin>=t?U+="w":t>=At.width-c.resizeMargin&&(U+="e")),vt.css("cursor",U?U+"-resize":c.movable?"move":"")}function z(e){b(e)||(mt||(y(),mt=!0,vt.one("mouseout",function(){mt=!1})),S(e))}function k(t){ct=!1,e("body").css("cursor",""),(c.autoHide||0==At.width*At.height)&&w(vt.add(xt),function(){e(this).hide()}),e(document).off("mousemove touchmove",N),vt.on("mousemove touchmove",z),t&&c.onSelectEnd(a,p())}function A(t){return"mousedown"==t.type&&1!=t.which?!1:("touchstart"==t.type?(ct&&k(),ct=!0,S(t)):y(),U?(nt=r(At["x"+(1+/w/.test(U))]),it=d(At["y"+(1+/n/.test(U))]),st=r(At["x"+(1+!/w/.test(U))]),at=d(At["y"+(1+!/n/.test(U))]),B=st-f(t),F=at-l(t),e(document).on("mousemove touchmove",N).one("mouseup touchend",k),vt.off("mousemove touchmove",z)):c.movable?(Y=L+At.x1-f(t),q=j+At.y1-l(t),vt.off("mousemove touchmove",z),e(document).on("mousemove touchmove",H).one("mouseup touchend",function(){ct=!1,c.onSelectEnd(a,p()),e(document).off("mousemove touchmove",H),vt.on("mousemove touchmove",z)})):pt.mousedown(t),!1)}function I(e){tt&&(e?(st=n(L,i(L+Q,nt+o(at-it)*tt*(st>nt||-1))),at=s(n(j,i(j+R,it+o(st-nt)/tt*(at>it||-1)))),st=s(st)):(at=n(j,i(j+R,it+o(st-nt)/tt*(at>it||-1))),st=s(n(L,i(L+Q,nt+o(at-it)*tt*(st>nt||-1)))),at=s(at)))}function P(){nt=i(nt,L+Q),it=i(it,j+R),V>o(st-nt)&&(st=nt-V*(nt>st||-1),L>st?nt=L+V:st>L+Q&&(nt=L+Q-V)),Z>o(at-it)&&(at=it-Z*(it>at||-1),j>at?it=j+Z:at>j+R&&(it=j+R-Z)),st=n(L,i(st,L+Q)),at=n(j,i(at,j+R)),I(o(st-nt)<o(at-it)*tt),o(st-nt)>_&&(st=nt-_*(nt>st||-1),I()),o(at-it)>et&&(at=it-et*(it>at||-1),I(!0)),At={x1:u(i(nt,st)),x2:u(n(nt,st)),y1:h(i(it,at)),y2:h(n(it,at)),width:o(st-nt),height:o(at-it)}}function K(){P(),g(),c.onSelectChange(a,p())}function N(e){return b(e)?void 0:(P(),st=/w|e|^$/.test(U)||tt?f(e)+B:r(At.x2),at=/n|s|^$/.test(U)||tt?l(e)+F:d(At.y2),K(),!1)}function C(t,o){st=(nt=t)+At.width,at=(it=o)+At.height,e.extend(At,{x1:u(nt),y1:h(it),x2:u(st),y2:h(at)}),g(),c.onSelectChange(a,p())}function H(e){return b(e)?void 0:(nt=n(L,i(Y+f(e),L+Q-At.width)),it=n(j,i(q+l(e),j+R-At.height)),C(nt,it),e.preventDefault(),!1)}function M(){e(document).off("mousemove touchmove",M),y(),st=nt,at=it,K(),U="",xt.is(":visible")||vt.add(xt).hide().fadeIn(c.fadeDuration||0),ot=!0,e(document).off("mouseup touchend",W).on("mousemove touchmove",N).one("mouseup touchend",k),vt.off("mousemove touchmove",z),c.onSelectStart(a,p())}function W(){e(document).off("mousemove touchmove",M).off("mouseup touchend",W),w(vt.add(xt)),v(u(nt),h(it),u(nt),h(it)),this instanceof e.imgAreaSelect||(c.onSelectChange(a,p()),c.onSelectEnd(a,p()))}function D(t){return"mousedown"==t.type&&1!=t.which||xt.is(":animated")?!1:(ct="touchstart"==t.type,y(),Y=nt=f(t),q=it=l(t),B=F=0,e(document).on({"mousemove touchmove":M,"mouseup touchend":W}),!1)}function E(){x(!1)}function O(){$=!0,T(c=e.extend({classPrefix:"imgareaselect",movable:!0,parent:"body",resizable:!0,resizeMargin:10,onInit:function(){},onSelectStart:function(){},onSelectChange:function(){},onSelectEnd:function(){}},c)),c.show&&(ot=!0,y(),g(),vt.add(xt).hide().fadeIn(c.fadeDuration||0)),setTimeout(function(){c.onInit(a,p())},0)}function T(o){if(o.parent&&(X=e(o.parent)).append(vt).append(xt),e.extend(c,o),y(),null!=o.handles){for(wt.remove(),wt=e([]),ut=o.handles?"corners"==o.handles?4:8:0;ut--;)wt=wt.add(t());wt.addClass(c.classPrefix+"-handle").css({position:"absolute",fontSize:0,zIndex:zt+1||1}),!parseInt(wt.css("width"))>=0&&wt.width(5).height(5)}for(G=c.imageWidth/Q||1,J=c.imageHeight/R||1,null!=o.x1&&(v(o.x1,o.y1,o.x2,o.y2),o.show=!o.hide),o.keys&&(c.keys=e.extend({shift:1,ctrl:"resize"},o.keys)),xt.addClass(c.classPrefix+"-outer"),yt.addClass(c.classPrefix+"-selection"),ut=0;4>ut++;)e(gt[ut-1]).addClass(c.classPrefix+"-border"+ut);vt.append(yt.add(gt)).append(wt),Kt&&((ht=(xt.css("filter")||"").match(/opacity=(\d+)/))&&xt.css("opacity",ht[1]/100),(ht=(gt.css("filter")||"").match(/opacity=(\d+)/))&&gt.css("opacity",ht[1]/100)),o.hide?w(vt.add(xt)):o.show&&$&&(ot=!0,vt.add(xt).fadeIn(c.fadeDuration||0),x()),tt=(dt=(c.aspectRatio||"").split(/:/))[0]/dt[1],pt.add(xt).off("mousedown touchstart",D),c.disable||c.enable===!1?(vt.off({"mousemove touchmove":z,"mousedown touchstart":A}),e(window).off("resize",E)):((c.enable||c.disable===!1)&&((c.resizable||c.movable)&&vt.on({"mousemove touchmove":z,"mousedown touchstart":A}),e(window).resize(E)),c.persistent||pt.add(xt).on("mousedown touchstart",D)),c.enable=c.disable=void 0}var $,L,j,Q,R,X,Y,q,B,F,G,J,U,V,Z,_,et,tt,ot,nt,it,st,at,ct,rt,dt,ut,ht,ft,lt,mt,pt=e(a),vt=t(),yt=t(),gt=t().add(t()).add(t()).add(t()),xt=t(),wt=e([]),bt={left:0,top:0},St={left:0,top:0},zt=0,kt="absolute",At={x1:0,y1:0,x2:0,y2:0,width:0,height:0},It=navigator.userAgent,Pt=function(e){var t,o,s=c.keys,a=e.keyCode;if(t=isNaN(s.alt)||!e.altKey&&!e.originalEvent.altKey?!isNaN(s.ctrl)&&e.ctrlKey?s.ctrl:!isNaN(s.shift)&&e.shiftKey?s.shift:isNaN(s.arrows)?10:s.arrows:s.alt,"resize"==s.arrows||"resize"==s.shift&&e.shiftKey||"resize"==s.ctrl&&e.ctrlKey||"resize"==s.alt&&(e.altKey||e.originalEvent.altKey)){switch(a){case 37:t=-t;case 39:o=n(nt,st),nt=i(nt,st),st=n(o+t,nt),I();break;case 38:t=-t;case 40:o=n(it,at),it=i(it,at),at=n(o+t,it),I(!0);break;default:return}K()}else switch(nt=i(nt,st),it=i(it,at),a){case 37:C(n(nt-t,L),it);break;case 38:C(nt,n(it-t,j));break;case 39:C(nt+i(t,Q-u(st)),it);break;case 40:C(nt,it+i(t,R-h(at)));break;default:return}return!1};this.remove=function(){T({disable:!0}),vt.add(xt).remove()},this.getOptions=function(){return c},this.setOptions=T,this.getSelection=p,this.setSelection=v,this.cancelSelection=W,this.update=x;var Kt=(/msie ([\w.]+)/i.exec(It)||[])[1],Nt=/webkit/i.test(It)&&!/chrome/i.test(It);for(rt=pt;rt.length;)zt=n(zt,isNaN(rt.css("z-index"))?zt:rt.css("z-index")),c.parent||"fixed"!=rt.css("position")||(kt="fixed"),rt=rt.parent(":not(body)");zt=c.zIndex||zt,e.imgAreaSelect.keyPress=Kt||Nt?"keydown":"keypress",vt.add(xt).hide().css({position:kt,overflow:"hidden",zIndex:zt||"0"}),vt.css({zIndex:zt+2||2}),yt.add(gt).css({position:"absolute",fontSize:0}),a.complete||"complete"==a.readyState||!pt.is("img")?O():pt.one("load",O),!$&&Kt&&Kt>=7&&(a.src=a.src)},e.fn.imgAreaSelect=function(t){return t=t||{},this.each(function(){e(this).data("imgAreaSelect")?t.remove?(e(this).data("imgAreaSelect").remove(),e(this).removeData("imgAreaSelect")):e(this).data("imgAreaSelect").setOptions(t):t.remove||(void 0===t.enable&&void 0===t.disable&&(t.enable=!0),e(this).data("imgAreaSelect",new e.imgAreaSelect(this,t)))}),t.instance?e(this).data("imgAreaSelect"):this}})(jQuery);
     2 No newline at end of file