else if (newOptions.show && imgLoaded) {
$box.add($outer).fadeIn(options.fadeSpeed||0);
/* Calculate the aspect ratio factor */
aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1];
$img.add($outer).off('mousedown', imgMouseDown);
if (options.disable || options.enable === false) {
$box.off({ 'mousemove touchmove': areaMouseMove,
'mousedown touchstart': areaMouseDown });
$(window).off('resize', windowResize);
if (options.enable || options.disable === false) {
if (options.resizable || options.movable)
$box.on({ 'mousemove touchmove': areaMouseMove,
'mousedown touchstart': areaMouseDown });
$(window).on( 'resize', windowResize);
$img.add($outer).on('mousedown touchstart', imgMouseDown);
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();
* @return An object containing the set of options currently in use
this.getOptions = function () { return options; };
this.setOptions = setOptions;
* Get the current selection
* If set to <code>true</code>, scaling is not applied to the
* @return Selection object
this.getSelection = getSelection;
* Set the current selection
* X coordinate of the upper left corner of the selection area
* Y coordinate of the upper left corner of the selection area
* X coordinate of the lower right corner of the selection area
* Y coordinate of the lower right corner of the selection area
* If set to <code>true</code>, scaling is not applied to the
this.setSelection = setSelection;
this.cancelSelection = cancelSelection;
* If set to <code>false</code>, this instance's keypress
* event handler is not activated
/* Do the dreaded browser detection */
var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1],
opera = /opera/i.test(ua),
safari = /webkit/i.test(ua) && !/chrome/i.test(ua);
* Traverse the image's parent elements (up to <body>) and find the
!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')
$p = $p.parent(':not(body)');
* If z-index is given as an option, it overrides the one found by the
zIndex = options.zIndex || zIndex;
$img.attr('unselectable', 'on');
* In MSIE and WebKit, we need to use the keydown event instead of keypress
$.imgAreaSelect.keyPress = msie || 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.
$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
$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
img.complete || img.readyState == 'complete' || !$img.is('img') ?
imgLoad() : $img.one('load', imgLoad);
* 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 (!imgLoaded && msie && msie >= 7)
* Invoke imgAreaSelect on a jQuery object containing the image(s)
* @return The jQuery object or a reference to imgAreaSelect instance (if the
* <code>instance</code> option was specified)
$.fn.imgAreaSelect = function (options) {
/* Is there already an imgAreaSelect instance bound to this element? */
if ($(this).data('imgAreaSelect')) {
/* Yes there is -- is it supposed to be removed? */
$(this).data('imgAreaSelect').remove();
$(this).removeData('imgAreaSelect');
$(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)
$(this).data('imgAreaSelect', new $.imgAreaSelect(this, options));
* Return the imgAreaSelect instance bound to the first element in the
return $(this).data('imgAreaSelect');