From 3cd8e8300fa1e2faf5f17a47750aeb5834b9e620 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Wed, 25 Apr 2012 21:49:57 +0000 Subject: [PATCH] Update jQuery imgAreaSelect plugin to 0.9.8. props ocean90. fixes #19881. git-svn-id: https://develop.svn.wordpress.org/trunk@20602 602fd350-edb4-49c9-b593-d223f7449a82 --- .../js/imgareaselect/imgareaselect.css | 10 +- .../imgareaselect/jquery.imgareaselect.dev.js | 520 +++++++++++++++++- wp-includes/script-loader.php | 4 +- 3 files changed, 505 insertions(+), 29 deletions(-) diff --git a/wp-includes/js/imgareaselect/imgareaselect.css b/wp-includes/js/imgareaselect/imgareaselect.css index 325e2b172f..fd587a69d3 100644 --- a/wp-includes/js/imgareaselect/imgareaselect.css +++ b/wp-includes/js/imgareaselect/imgareaselect.css @@ -20,21 +20,21 @@ .imgareaselect-border1, .imgareaselect-border2, .imgareaselect-border3, .imgareaselect-border4 { - opacity: 0.5; filter: alpha(opacity=50); + opacity: 0.5; } .imgareaselect-handle { background-color: #fff; border: solid 1px #000; - opacity: 0.4; - filter: alpha(opacity=40); + filter: alpha(opacity=50); + opacity: 0.5; } .imgareaselect-outer { background-color: #000; - opacity: 0.4; - filter: alpha(opacity=40); + filter: alpha(opacity=50); + opacity: 0.5; } .imgareaselect-selection { diff --git a/wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js b/wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js index 5fc41c7b57..d349d0532e 100644 --- a/wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js +++ b/wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js @@ -1,6 +1,6 @@ /* * imgAreaSelect jQuery plugin - * version 0.9.6 + * version 0.9.8 * * Copyright (c) 2008-2011 Michal Wojciechowski (odyniec.net) * @@ -13,90 +13,201 @@ (function($) { +/* + * Math functions will be used extensively, so it's convenient to make a few + * shortcuts + */ var abs = Math.abs, max = Math.max, min = Math.min, round = Math.round; +/** + * Create a new HTML div element + * + * @return A jQuery object representing the new element + */ function div() { return $('
'); } +/** + * imgAreaSelect initialization + * + * @param img + * A HTML image element to attach the plugin to + * @param options + * An options object + */ $.imgAreaSelect = function (img, options) { var - + /* jQuery object representing the image */ $img = $(img), + /* Has the image finished loading? */ imgLoaded, + /* Plugin elements */ + + /* Container box */ $box = div(), + /* Selection area */ $area = div(), + /* Border (four divs) */ $border = div().add(div()).add(div()).add(div()), + /* Outer area (four divs) */ $outer = div().add(div()).add(div()).add(div()), + /* Handles (empty by default, initialized in setOptions()) */ $handles = $([]), + /* + * Additional element to work around a cursor problem in Opera + * (explained later) + */ $areaOpera, + /* Image position (relative to viewport) */ left, top, + /* Image offset (as returned by .offset()) */ imgOfs = { left: 0, top: 0 }, + /* Image dimensions (as returned by .width() and .height()) */ imgWidth, imgHeight, + /* + * jQuery object representing the parent element that the plugin + * elements are appended to + */ $parent, + /* Parent element offset (as returned by .offset()) */ parOfs = { left: 0, top: 0 }, + /* Base z-index for plugin elements */ zIndex = 0, + /* Plugin elements position */ position = 'absolute', + /* X/Y coordinates of the starting point for move/resize operations */ startX, startY, + /* Horizontal and vertical scaling factors */ scaleX, scaleY, - resizeMargin = 10, - + /* Current resize mode ("nw", "se", etc.) */ resize, + /* Selection area constraints */ minWidth, minHeight, maxWidth, maxHeight, + /* Aspect ratio to maintain (floating point number) */ aspectRatio, + /* Are the plugin elements currently displayed? */ shown, + /* Current selection (relative to parent element) */ x1, y1, x2, y2, + /* Current selection (relative to scaled image) */ selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, + /* Document element */ docElem = document.documentElement, + /* Various helper variables used throughout the code */ $p, d, i, o, w, h, adjusted; + /* + * Translate selection coordinates (relative to scaled image) to viewport + * coordinates (relative to parent element) + */ + + /** + * Translate selection X to viewport X + * + * @param x + * Selection X + * @return Viewport X + */ function viewX(x) { return x + imgOfs.left - parOfs.left; } + /** + * Translate selection Y to viewport Y + * + * @param y + * Selection Y + * @return Viewport Y + */ function viewY(y) { return y + imgOfs.top - parOfs.top; } + /* + * Translate viewport coordinates to selection coordinates + */ + + /** + * Translate viewport X to selection X + * + * @param x + * Viewport X + * @return Selection X + */ function selX(x) { return x - imgOfs.left + parOfs.left; } + /** + * Translate viewport Y to selection Y + * + * @param y + * Viewport Y + * @return Selection Y + */ function selY(y) { return y - imgOfs.top + parOfs.top; } + /* + * Translate event coordinates (relative to document) to viewport + * coordinates + */ + + /** + * Get event X and translate it to viewport X + * + * @param event + * The event object + * @return Viewport X + */ function evX(event) { return event.pageX - parOfs.left; } + /** + * Get event Y and translate it to viewport Y + * + * @param event + * The event object + * @return Viewport Y + */ function evY(event) { return event.pageY - parOfs.top; } + /** + * Get the current selection + * + * @param noScale + * If set to true, scaling is not applied to the + * returned selection + * @return Selection object + */ function getSelection(noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; @@ -108,6 +219,21 @@ $.imgAreaSelect = function (img, options) { height: round(selection.y2 * sy) - round(selection.y1 * sy) }; } + /** + * Set the current selection + * + * @param x1 + * X coordinate of the upper left corner of the selection area + * @param y1 + * Y coordinate of the upper left corner of the selection area + * @param x2 + * X coordinate of the lower right corner of the selection area + * @param y2 + * Y coordinate of the lower right corner of the selection area + * @param noScale + * If set to true, scaling is not applied to the + * new selection + */ function setSelection(x1, y1, x2, y2, noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; @@ -122,23 +248,41 @@ $.imgAreaSelect = function (img, options) { selection.height = selection.y2 - selection.y1; } + /** + * Recalculate image and parent offsets + */ function adjust() { + /* + * Do not adjust if image width is not a positive number. This might + * happen when imgAreaSelect is put on a parent element which is then + * hidden. + */ if (!$img.width()) return; + /* + * Get image offset. The .offset() method returns float values, so they + * need to be rounded. + */ imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; + /* Get image dimensions */ imgWidth = $img.innerWidth(); imgHeight = $img.innerHeight(); imgOfs.top += ($img.outerHeight() - imgHeight) >> 1; imgOfs.left += ($img.outerWidth() - imgWidth) >> 1; - minWidth = options.minWidth || 0; - minHeight = options.minHeight || 0; - maxWidth = min(options.maxWidth || 1<<24, imgWidth); - maxHeight = min(options.maxHeight || 1<<24, imgHeight); + /* Set minimum and maximum selection area dimensions */ + minWidth = round(options.minWidth / scaleX) || 0; + minHeight = round(options.minHeight / scaleY) || 0; + maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth)); + maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight)); + /* + * Workaround for jQuery 1.3.2 incorrect offset calculation, originally + * observed in Safari 3. Firefox 2 is also affected. + */ if ($().jquery == '1.3.2' && position == 'fixed' && !docElem['getBoundingClientRect']) { @@ -146,7 +290,8 @@ $.imgAreaSelect = function (img, options) { imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft); } - parOfs = $.inArray($parent.css('position'), ['absolute', 'relative']) + 1 ? + /* Determine parent element offset */ + parOfs = /absolute|relative/.test($parent.css('position')) ? { left: round($parent.offset().left) - $parent.scrollLeft(), top: round($parent.offset().top) - $parent.scrollTop() } : position == 'fixed' ? @@ -156,22 +301,44 @@ $.imgAreaSelect = function (img, options) { left = viewX(0); top = viewY(0); + /* + * Check if selection area is within image boundaries, adjust if + * necessary + */ if (selection.x2 > imgWidth || selection.y2 > imgHeight) doResize(); } + /** + * Update plugin elements + * + * @param resetKeyPress + * If set to false, this instance's keypress + * event handler is not activated + */ function update(resetKeyPress) { + /* If plugin elements are hidden, do nothing */ if (!shown) return; + /* + * Set the position and size of the container box and the selection area + * inside it + */ $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) }) .add($area).width(w = selection.width).height(h = selection.height); + /* + * Reset the position of selection area, borders, and handles (IE6/IE7 + * position them incorrectly if we don't do this) + */ $area.add($border).add($handles).css({ left: 0, top: 0 }); + /* Set border dimensions */ $border .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); + /* Arrange the outer area elements */ $($outer[0]).css({ left: left, top: top, width: selection.x1, height: imgHeight }); $($outer[1]).css({ left: left + selection.x1, top: top, @@ -184,6 +351,7 @@ $.imgAreaSelect = function (img, options) { w -= $handles.outerWidth(); h -= $handles.outerHeight(); + /* Arrange handles */ switch ($handles.length) { case 8: $($handles[4]).css({ left: w >> 1 }); @@ -196,21 +364,49 @@ $.imgAreaSelect = function (img, options) { } if (resetKeyPress !== false) { + /* + * Need to reset the document keypress event handler -- unbind the + * current handler + */ if ($.imgAreaSelect.keyPress != docKeyPress) $(document).unbind($.imgAreaSelect.keyPress, $.imgAreaSelect.onKeyPress); if (options.keys) + /* + * Set the document keypress event handler to this instance's + * docKeyPress() function + */ $(document)[$.imgAreaSelect.keyPress]( $.imgAreaSelect.onKeyPress = docKeyPress); } + /* + * Internet Explorer displays 1px-wide dashed borders incorrectly by + * filling the spaces between dashes with white. Toggling the margin + * property between 0 and "auto" fixes this in IE6 and IE7 (IE8 is still + * broken). This workaround is not perfect, as it requires setTimeout() + * and thus causes the border to flicker a bit, but I haven't found a + * better solution. + * + * Note: This only happens with CSS borders, set with the borderWidth, + * borderOpacity, borderColor1, and borderColor2 options (which are now + * deprecated). Borders created with GIF background images are fine. + */ if ($.browser.msie && $border.outerWidth() - $border.innerWidth() == 2) { $border.css('margin', 0); setTimeout(function () { $border.css('margin', 'auto'); }, 0); } } + /** + * Do the complete update sequence: recalculate offsets, update the + * elements, and set the correct values of x1, y1, x2, and y2. + * + * @param resetKeyPress + * If set to false, this instance's keypress + * event handler is not activated + */ function doUpdate(resetKeyPress) { adjust(); update(resetKeyPress); @@ -218,11 +414,24 @@ $.imgAreaSelect = function (img, options) { x2 = viewX(selection.x2); y2 = viewY(selection.y2); } + /** + * Hide or fade out an element (or multiple elements) + * + * @param $elem + * A jQuery object containing the element(s) to hide/fade out + * @param fn + * Callback function to be called when fadeOut() completes + */ function hide($elem, fn) { options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); - } + /** + * Selection area mousemove event handler + * + * @param event + * The event object + */ function areaMouseMove(event) { var x = selX(evX(event)) - selection.x1, y = selY(evY(event)) - selection.y1; @@ -234,9 +443,14 @@ $.imgAreaSelect = function (img, options) { $box.one('mouseout', function () { adjusted = false; }); } + /* Clear the resize mode */ resize = ''; if (options.resizable) { + /* + * Check if the mouse pointer is over the resize margin area and set + * the resize mode accordingly + */ if (y <= options.resizeMargin) resize = 'n'; else if (y >= selection.height - options.resizeMargin) @@ -253,8 +467,19 @@ $.imgAreaSelect = function (img, options) { $areaOpera.toggle(); } + /** + * Document mouseup event handler + * + * @param event + * The event object + */ function docMouseUp(event) { + /* Set back the default cursor */ $('body').css('cursor', ''); + /* + * If autoHide is enabled, or if the selection has zero width/height, + * hide the selection and the outer area + */ if (options.autoHide || selection.width * selection.height == 0) hide($box.add($outer), function () { $(this).hide(); }); @@ -264,12 +489,20 @@ $.imgAreaSelect = function (img, options) { options.onSelectEnd(img, getSelection()); } + /** + * Selection area mousedown event handler + * + * @param event + * The event object + * @return false + */ function areaMouseDown(event) { if (event.which != 1) return false; adjust(); if (resize) { + /* Resize mode is in effect */ $('body').css('cursor', resize + '-resize'); x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); @@ -299,12 +532,18 @@ $.imgAreaSelect = function (img, options) { return false; } + /** + * Adjust the x2/y2 coordinates to maintain aspect ratio (if defined) + * + * @param xFirst + * If set to true, calculate x2 first. Otherwise, + * calculate y2 first. + */ function fixAspectRatio(xFirst) { if (aspectRatio) if (xFirst) { x2 = max(left, min(left + imgWidth, x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); - y2 = round(max(top, min(top + imgHeight, y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); x2 = round(x2); @@ -318,11 +557,21 @@ $.imgAreaSelect = function (img, options) { } } + /** + * Resize the selection area respecting the minimum/maximum dimensions and + * aspect ratio + */ function doResize() { + /* + * Make sure the top left corner of the selection area stays within + * image boundaries (it might not if the image source was dynamically + * changed). + */ x1 = min(x1, left + imgWidth); y1 = min(y1, top + imgHeight); if (abs(x2 - x1) < minWidth) { + /* Selection width is smaller than minWidth */ x2 = x1 - minWidth * (x2 < x1 || -1); if (x2 < left) @@ -332,6 +581,7 @@ $.imgAreaSelect = function (img, options) { } if (abs(y2 - y1) < minHeight) { + /* Selection height is smaller than minHeight */ y2 = y1 - minHeight * (y2 < y1 || -1); if (y2 < top) @@ -346,11 +596,13 @@ $.imgAreaSelect = function (img, options) { fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); if (abs(x2 - x1) > maxWidth) { + /* Selection width is greater than maxWidth */ x2 = x1 - maxWidth * (x2 < x1 || -1); fixAspectRatio(); } if (abs(y2 - y1) > maxHeight) { + /* Selection height is greater than maxHeight */ y2 = y1 - maxHeight * (y2 < y1 || -1); fixAspectRatio(true); } @@ -364,16 +616,30 @@ $.imgAreaSelect = function (img, options) { options.onSelectChange(img, getSelection()); } + /** + * Mousemove event handler triggered when the user is selecting an area + * + * @param event + * The event object + * @return false + */ function selectingMouseMove(event) { - x2 = resize == '' || /w|e/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); - y2 = resize == '' || /n|s/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); + x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); + y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); doResize(); return false; - } + /** + * Move the selection area + * + * @param newX1 + * New viewport X1 + * @param newY1 + * New viewport Y1 + */ function doMove(newX1, newY1) { x2 = (x1 = newX1) + selection.width; y2 = (y1 = newY1) + selection.height; @@ -386,6 +652,13 @@ $.imgAreaSelect = function (img, options) { options.onSelectChange(img, getSelection()); } + /** + * Mousemove event handler triggered when the selection area is being moved + * + * @param event + * The event object + * @return false + */ function movingMouseMove(event) { x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); @@ -393,22 +666,24 @@ $.imgAreaSelect = function (img, options) { doMove(x1, y1); event.preventDefault(); - return false; } + /** + * Start selection + */ function startSelection() { $(document).unbind('mousemove', startSelection); adjust(); x2 = x1; y2 = y1; - doResize(); resize = ''; - if ($outer.is(':not(:visible)')) + if (!$outer.is(':visible')) + /* Show the plugin elements */ $box.add($outer).hide().fadeIn(options.fadeSpeed||0); shown = true; @@ -420,6 +695,9 @@ $.imgAreaSelect = function (img, options) { options.onSelectStart(img, getSelection()); } + /** + * Cancel selection + */ function cancelSelection() { $(document).unbind('mousemove', startSelection) .unbind('mouseup', cancelSelection); @@ -427,29 +705,49 @@ $.imgAreaSelect = function (img, options) { setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); - options.onSelectChange(img, getSelection()); - options.onSelectEnd(img, getSelection()); + /* If this is an API call, callback functions should not be triggered */ + if (!this instanceof $.imgAreaSelect) { + options.onSelectChange(img, getSelection()); + options.onSelectEnd(img, getSelection()); + } } + /** + * Image mousedown event handler + * + * @param event + * The event object + * @return false + */ function imgMouseDown(event) { + /* Ignore the event if animation is in progress */ if (event.which != 1 || $outer.is(':animated')) return false; adjust(); startX = x1 = evX(event); startY = y1 = evY(event); + /* Selection will start when the mouse is moved */ $(document).mousemove(startSelection).mouseup(cancelSelection); return false; } + /** + * Window resize event handler + */ function windowResize() { doUpdate(false); } + /** + * Image load event handler. This is the final part of the initialization + * process. + */ function imgLoad() { imgLoaded = true; + /* Set options */ setOptions(options = $.extend({ classPrefix: 'imgareaselect', movable: true, @@ -471,9 +769,21 @@ $.imgAreaSelect = function (img, options) { $box.add($outer).hide().fadeIn(options.fadeSpeed||0); } + /* + * Call the onInit callback. The setTimeout() call is used to ensure + * that the plugin has been fully initialized and the object instance is + * available (so that it can be obtained in the callback). + */ setTimeout(function () { options.onInit(img, getSelection()); }, 0); } + /** + * Document keypress event handler + * + * @param event + * The event object + * @return false + */ var docKeyPress = function(event) { var k = options.keys, d, t, key = event.keyCode; @@ -486,18 +796,24 @@ $.imgAreaSelect = function (img, options) { (k.ctrl == 'resize' && event.ctrlKey) || (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) { + /* Resize selection */ + switch (key) { case 37: + /* Left */ d = -d; case 39: + /* Right */ t = max(x1, x2); x1 = min(x1, x2); x2 = max(t + d, x1); fixAspectRatio(); break; case 38: + /* Up */ d = -d; case 40: + /* Down */ t = max(y1, y2); y1 = min(y1, y2); y2 = max(t + d, y1); @@ -510,20 +826,26 @@ $.imgAreaSelect = function (img, options) { doResize(); } else { + /* Move selection */ + x1 = min(x1, x2); y1 = min(y1, y2); switch (key) { case 37: + /* Left */ doMove(max(x1 - d, left), y1); break; case 38: + /* Up */ doMove(x1, max(y1 - d, top)); break; case 39: + /* Right */ doMove(x1 + min(d, imgWidth - selX(x2)), y1); break; case 40: + /* Down */ doMove(x1, y1 + min(d, imgHeight - selY(y2))); break; default: @@ -534,21 +856,38 @@ $.imgAreaSelect = function (img, options) { return false; }; + /** + * Apply style options to plugin element (or multiple elements) + * + * @param $elem + * A jQuery object representing the element(s) to style + * @param props + * An object that maps option names to corresponding CSS + * properties + */ function styleOptions($elem, props) { for (option in props) if (options[option] !== undefined) $elem.css(props[option], options[option]); } + /** + * Set plugin options + * + * @param newOptions + * The new options object + */ function setOptions(newOptions) { if (newOptions.parent) ($parent = $(newOptions.parent)).append($box.add($outer)); + /* Merge the new options with the existing ones */ $.extend(options, newOptions); adjust(); if (newOptions.handles != null) { + /* Recreate selection area handles */ $handles.remove(); $handles = $([]); @@ -557,26 +896,42 @@ $.imgAreaSelect = function (img, options) { while (i--) $handles = $handles.add(div()); + /* Add a class to handles and set the CSS properties */ $handles.addClass(options.classPrefix + '-handle').css({ position: 'absolute', + /* + * The font-size property needs to be set to zero, otherwise + * Internet Explorer makes the handles too large + */ fontSize: 0, zIndex: zIndex + 1 || 1 }); + /* + * If handle width/height has not been set with CSS rules, set the + * default 5px + */ if (!parseInt($handles.css('width')) >= 0) $handles.width(5).height(5); + /* + * If the borderWidth option is in use, add a solid border to + * handles + */ if (o = options.borderWidth) $handles.css({ borderWidth: o, borderStyle: 'solid' }); + /* Apply other style options */ styleOptions($handles, { borderColor1: 'border-color', borderColor2: 'background-color', borderOpacity: 'opacity' }); } + /* Calculate scale factors */ scaleX = options.imageWidth / imgWidth || 1; scaleY = options.imageHeight / imgHeight || 1; + /* Set selection */ if (newOptions.x1 != null) { setSelection(newOptions.x1, newOptions.y1, newOptions.x2, newOptions.y2); @@ -584,14 +939,17 @@ $.imgAreaSelect = function (img, options) { } if (newOptions.keys) + /* Enable keyboard support */ options.keys = $.extend({ shift: 1, ctrl: 'resize' }, newOptions.keys); + /* Add classes to plugin elements */ $outer.addClass(options.classPrefix + '-outer'); $area.addClass(options.classPrefix + '-selection'); for (i = 0; i++ < 4;) $($border[i-1]).addClass(options.classPrefix + '-border' + i); + /* Apply style options */ styleOptions($area, { selectionColor: 'background-color', selectionOpacity: 'opacity' }); styleOptions($border, { borderOpacity: 'opacity', @@ -603,12 +961,13 @@ $.imgAreaSelect = function (img, options) { if (o = options.borderColor2) $($border[1]).css({ borderStyle: 'dashed', borderColor: o }); + /* Append all the selection area elements to the container box */ $box.append($area.add($border).add($areaOpera).add($handles)); if ($.browser.msie) { - if (o = $outer.css('filter').match(/opacity=([0-9]+)/)) + if (o = $outer.css('filter').match(/opacity=(\d+)/)) $outer.css('opacity', o[1]/100); - if (o = $border.css('filter').match(/opacity=([0-9]+)/)) + if (o = $border.css('filter').match(/opacity=(\d+)/)) $border.css('opacity', o[1]/100); } @@ -620,16 +979,19 @@ $.imgAreaSelect = function (img, options) { doUpdate(); } + /* Calculate the aspect ratio factor */ aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; $img.add($outer).unbind('mousedown', imgMouseDown); if (options.disable || options.enable === false) { + /* Disable the plugin */ $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); $(window).unbind('resize', windowResize); } else { if (options.enable || options.disable === false) { + /* Enable the plugin */ if (options.resizable || options.movable) $box.mousemove(areaMouseMove).mousedown(areaMouseDown); @@ -643,69 +1005,179 @@ $.imgAreaSelect = function (img, options) { options.enable = options.disable = undefined; } + /** + * Remove plugin completely + */ this.remove = function () { + /* + * Call setOptions with { disable: true } to unbind the event handlers + */ setOptions({ disable: true }); $box.add($outer).remove(); }; + /* + * Public API + */ + + /** + * Get current options + * + * @return An object containing the set of options currently in use + */ this.getOptions = function () { return options; }; + /** + * Set plugin options + * + * @param newOptions + * The new options object + */ this.setOptions = setOptions; + /** + * Get the current selection + * + * @param noScale + * If set to true, scaling is not applied to the + * returned selection + * @return Selection object + */ this.getSelection = getSelection; + /** + * Set the current selection + * + * @param x1 + * X coordinate of the upper left corner of the selection area + * @param y1 + * Y coordinate of the upper left corner of the selection area + * @param x2 + * X coordinate of the lower right corner of the selection area + * @param y2 + * Y coordinate of the lower right corner of the selection area + * @param noScale + * If set to true, scaling is not applied to the + * new selection + */ this.setSelection = setSelection; + /** + * Cancel selection + */ + this.cancelSelection = cancelSelection; + + /** + * Update plugin elements + * + * @param resetKeyPress + * If set to false, this instance's keypress + * event handler is not activated + */ this.update = doUpdate; + /* + * Traverse the image's parent elements (up to ) and find the + * highest z-index + */ $p = $img; while ($p.length) { zIndex = max(zIndex, !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex); + /* Also check if any of the ancestor elements has fixed position */ if ($p.css('position') == 'fixed') position = 'fixed'; $p = $p.parent(':not(body)'); } + /* + * If z-index is given as an option, it overrides the one found by the + * above loop + */ zIndex = options.zIndex || zIndex; if ($.browser.msie) $img.attr('unselectable', 'on'); + /* + * In MSIE and WebKit, we need to use the keydown event instead of keypress + */ $.imgAreaSelect.keyPress = $.browser.msie || $.browser.safari ? 'keydown' : 'keypress'; + /* + * There is a bug affecting the CSS cursor property in Opera (observed in + * versions up to 10.00) that prevents the cursor from being updated unless + * the mouse leaves and enters the element again. To trigger the mouseover + * event, we're adding an additional div to $box and we're going to toggle + * it when mouse moves inside the selection area. + */ if ($.browser.opera) $areaOpera = div().css({ width: '100%', height: '100%', position: 'absolute', zIndex: zIndex + 2 || 2 }); + /* + * We initially set visibility to "hidden" as a workaround for a weird + * behaviour observed in Google Chrome 1.0.154.53 (on Windows XP). Normally + * we would just set display to "none", but, for some reason, if we do so + * then Chrome refuses to later display the element with .show() or + * .fadeIn(). + */ $box.add($outer).css({ visibility: 'hidden', position: position, overflow: 'hidden', zIndex: zIndex || '0' }); $box.css({ zIndex: zIndex + 2 || 2 }); $area.add($border).css({ position: 'absolute', fontSize: 0 }); + /* + * If the image has been fully loaded, or if it is not really an image (eg. + * a div), call imgLoad() immediately; otherwise, bind it to be called once + * on image load event. + */ img.complete || img.readyState == 'complete' || !$img.is('img') ? imgLoad() : $img.one('load', imgLoad); - if ($.browser.msie && $.browser.version >= 9) + /* + * MSIE 9.0 doesn't always fire the image load event -- resetting the src + * attribute seems to trigger it. The check is for version 7 and above to + * accommodate for MSIE 9 running in compatibility mode. + */ + if ($.browser.msie && $.browser.version >= 7) img.src = img.src; }; +/** + * Invoke imgAreaSelect on a jQuery object containing the image(s) + * + * @param options + * Options object + * @return The jQuery object or a reference to imgAreaSelect instance (if the + * instance option was specified) + */ $.fn.imgAreaSelect = function (options) { options = options || {}; this.each(function () { + /* Is there already an imgAreaSelect instance bound to this element? */ if ($(this).data('imgAreaSelect')) { + /* Yes there is -- is it supposed to be removed? */ if (options.remove) { + /* Remove the plugin */ $(this).data('imgAreaSelect').remove(); $(this).removeData('imgAreaSelect'); } else + /* Reset options */ $(this).data('imgAreaSelect').setOptions(options); } else if (!options.remove) { + /* No exising instance -- create a new one */ + + /* + * If neither the "enable" nor the "disable" option is present, add + * "enable" as the default + */ if (options.enable === undefined && options.disable === undefined) options.enable = true; @@ -714,6 +1186,10 @@ $.fn.imgAreaSelect = function (options) { }); if (options.instance) + /* + * Return the imgAreaSelect instance bound to the first element in the + * set + */ return $(this).data('imgAreaSelect'); return this; diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index f81821e5e3..5264c922d8 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -252,7 +252,7 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2011-02-23'); - $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.6-20110515', 1 ); + $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 ); $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array('jquery'), false, 1 ); $scripts->localize( 'password-strength-meter', 'pwsL10n', array( @@ -474,7 +474,7 @@ function wp_default_styles( &$styles ) { $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css' ); $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.3u1' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); - $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' ); + $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.8' ); $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css" ); $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css" ); $styles->add( 'editor-buttons', "/wp-includes/css/editor$suffix.css" );