Ticket #30634: 30634.diff
File 30634.diff, 55.3 KB (added by , 8 years ago) |
---|
-
trunk/wp-includes/js/imgareaselect/jquery.imgareaselect.js
1 1 /* 2 2 * imgAreaSelect jQuery plugin 3 * version 0.9.10-monkey3 * version 1.0.0-rc.1 4 4 * 5 5 * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net) 6 6 * 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. 9 9 * 10 10 * http://odyniec.net/projects/imgareaselect/ 11 11 * … … 16 16 /* 17 17 * Math functions will be used extensively, so it's convenient to make a few 18 18 * shortcuts 19 */ 19 */ 20 20 var abs = Math.abs, 21 21 max = Math.max, 22 22 min = Math.min, … … 24 24 25 25 /** 26 26 * Create a new HTML div element 27 * 27 * 28 28 * @return A jQuery object representing the new element 29 29 */ 30 30 function div() { … … 33 33 34 34 /** 35 35 * imgAreaSelect initialization 36 * 36 * 37 37 * @param img 38 38 * A HTML image element to attach the plugin to 39 39 * @param options … … 40 40 * An options object 41 41 */ 42 42 $.imgAreaSelect = function (img, options) { 43 var 44 /* jQuery object representing the image */ 43 var 44 /* jQuery object representing the image */ 45 45 $img = $(img), 46 46 47 47 /* Has the image finished loading? */ 48 48 imgLoaded, 49 49 50 50 /* Plugin elements */ 51 51 52 52 /* Container box */ 53 53 $box = div(), 54 54 /* Selection area */ … … 55 55 $area = div(), 56 56 /* Border (four divs) */ 57 57 $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(), 60 60 /* Handles (empty by default, initialized in setOptions()) */ 61 61 $handles = $([]), 62 63 /* 64 * Additional element to work around a cursor problem in Opera 65 * (explained later) 66 */ 67 $areaOpera, 68 62 69 63 /* Image position (relative to viewport) */ 70 64 left, top, 71 65 72 66 /* Image offset (as returned by .offset()) */ 73 67 imgOfs = { left: 0, top: 0 }, 74 68 75 69 /* Image dimensions (as returned by .width() and .height()) */ 76 70 imgWidth, imgHeight, 77 71 78 72 /* 79 73 * jQuery object representing the parent element that the plugin 80 74 * elements are appended to 81 75 */ 82 76 $parent, 83 77 84 78 /* Parent element offset (as returned by .offset()) */ 85 79 parOfs = { left: 0, top: 0 }, 86 80 87 81 /* Base z-index for plugin elements */ 88 82 zIndex = 0, 89 83 90 84 /* Plugin elements position */ 91 85 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 */ 94 88 startX, startY, 95 89 90 /* 91 * Distance between the mouse cursor (or touch point) and selection area 92 * edges (when resizing) 93 */ 94 edgeX, edgeY, 95 96 96 /* Horizontal and vertical scaling factors */ 97 97 scaleX, scaleY, 98 98 … … 114 114 /* Current selection (relative to scaled image) */ 115 115 selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, 116 116 117 /* Document element */118 docElem = document.documentElement,119 120 117 /* User agent */ 121 118 ua = navigator.userAgent, 119 120 /* Is the user performing a touch action? */ 121 touch, 122 122 123 /* Various helper variables used throughout the code */ 123 /* Various helper variables used throughout the code */ 124 124 $p, d, i, o, w, h, adjusted; 125 125 126 126 /* … … 127 127 * Translate selection coordinates (relative to scaled image) to viewport 128 128 * coordinates (relative to parent element) 129 129 */ 130 130 131 131 /** 132 132 * Translate selection X to viewport X 133 * 133 * 134 134 * @param x 135 135 * Selection X 136 136 * @return Viewport X … … 141 141 142 142 /** 143 143 * Translate selection Y to viewport Y 144 * 144 * 145 145 * @param y 146 146 * Selection Y 147 147 * @return Viewport Y … … 153 153 /* 154 154 * Translate viewport coordinates to selection coordinates 155 155 */ 156 156 157 157 /** 158 158 * Translate viewport X to selection X 159 * 159 * 160 160 * @param x 161 161 * Viewport X 162 162 * @return Selection X … … 167 167 168 168 /** 169 169 * Translate viewport Y to selection Y 170 * 170 * 171 171 * @param y 172 172 * Viewport Y 173 173 * @return Selection Y … … 175 175 function selY(y) { 176 176 return y - imgOfs.top + parOfs.top; 177 177 } 178 178 179 179 /* 180 180 * Translate event coordinates (relative to document) to viewport 181 181 * coordinates 182 182 */ 183 183 184 184 /** 185 185 * Get event X and translate it to viewport X 186 * 186 * 187 187 * @param event 188 188 * The event object 189 189 * @return Viewport X 190 190 */ 191 191 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; 193 196 } 194 197 195 198 /** 196 199 * Get event Y and translate it to viewport Y 197 * 200 * 198 201 * @param event 199 202 * The event object 200 203 * @return Viewport Y 201 204 */ 202 205 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; 204 210 } 205 211 206 212 /** 207 * Get X and Y coordinates of a touchevent213 * Get the first touch object in an event 208 214 * 209 215 * @param event 210 216 * 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 212 219 */ 213 220 function touchCoords(event) { 214 221 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; 220 224 } 221 225 222 226 /** 223 227 * Get the current selection 224 * 228 * 225 229 * @param noScale 226 230 * If set to <code>true</code>, scaling is not applied to the 227 231 * returned selection … … 229 233 */ 230 234 function getSelection(noScale) { 231 235 var sx = noScale || scaleX, sy = noScale || scaleY; 232 236 233 237 return { x1: round(selection.x1 * sx), 234 238 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, 237 241 width: round(selection.x2 * sx) - round(selection.x1 * sx), 238 242 height: round(selection.y2 * sy) - round(selection.y1 * sy) }; 239 243 } 240 244 241 245 /** 242 246 * Set the current selection 243 * 247 * 244 248 * @param x1 245 249 * X coordinate of the upper left corner of the selection area 246 250 * @param y1 … … 255 259 */ 256 260 function setSelection(x1, y1, x2, y2, noScale) { 257 261 var sx = noScale || scaleX, sy = noScale || scaleY; 258 262 259 263 selection = { 260 264 x1: round(x1 / sx || 0), 261 265 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) 264 268 }; 265 269 266 270 selection.width = selection.x2 - selection.x1; 267 271 selection.height = selection.y2 - selection.y1; 268 272 } … … 278 282 */ 279 283 if (!imgLoaded || !$img.width()) 280 284 return; 281 285 282 286 /* 283 287 * Get image offset. The .offset() method returns float values, so they 284 288 * need to be rounded. 285 289 */ 286 290 imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; 287 291 288 292 /* Get image dimensions */ 289 293 imgWidth = $img.innerWidth(); 290 294 imgHeight = $img.innerHeight(); 291 295 292 296 imgOfs.top += ($img.outerHeight() - imgHeight) >> 1; 293 297 imgOfs.left += ($img.outerWidth() - imgWidth) >> 1; 294 298 … … 297 301 minHeight = round(options.minHeight / scaleY) || 0; 298 302 maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth)); 299 303 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() }; 300 316 301 /*302 * Workaround for jQuery 1.3.2 incorrect offset calculation, originally303 * 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 320 317 left = viewX(0); 321 318 top = viewY(0); 322 319 323 320 /* 324 321 * Check if selection area is within image boundaries, adjust if 325 322 * necessary 326 323 */ 327 324 if (selection.x2 > imgWidth || selection.y2 > imgHeight) 328 doResize();325 fixAreaCoords(); 329 326 } 330 327 331 328 /** 332 329 * Update plugin elements 333 * 330 * 334 331 * @param resetKeyPress 335 332 * If set to <code>false</code>, this instance's keypress 336 333 * event handler is not activated … … 349 346 /* 350 347 * Reset the position of selection area, borders, and handles (IE6/IE7 351 348 * position them incorrectly if we don't do this) 352 */ 349 */ 353 350 $area.add($border).add($handles).css({ left: 0, top: 0 }); 354 351 355 352 /* Set border dimensions */ 356 $border 353 $border.add($outer) 357 354 .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) 358 355 .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); 359 356 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 }); 369 368 370 369 w -= $handles.outerWidth(); 371 370 h -= $handles.outerHeight(); 372 371 373 372 /* Arrange handles */ 374 373 switch ($handles.length) { 375 374 case 8: … … 387 386 * Need to reset the document keypress event handler -- unbind the 388 387 * current handler 389 388 */ 390 if ($.imgAreaSelect. onKeyPress != docKeyPress)389 if ($.imgAreaSelect.keyPress != docKeyPress) 391 390 $(document).unbind($.imgAreaSelect.keyPress, 392 391 $.imgAreaSelect.onKeyPress); 393 392 … … 399 398 $(document)[$.imgAreaSelect.keyPress]( 400 399 $.imgAreaSelect.onKeyPress = docKeyPress); 401 400 } 402 403 /*404 * Internet Explorer displays 1px-wide dashed borders incorrectly by405 * filling the spaces between dashes with white. Toggling the margin406 * property between 0 and "auto" fixes this in IE6 and IE7 (IE8 is still407 * 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 a409 * better solution.410 *411 * Note: This only happens with CSS borders, set with the borderWidth,412 * borderOpacity, borderColor1, and borderColor2 options (which are now413 * 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 }419 401 } 420 402 421 403 /** 422 404 * Do the complete update sequence: recalculate offsets, update the 423 405 * elements, and set the correct values of x1, y1, x2, and y2. 424 * 406 * 425 407 * @param resetKeyPress 426 408 * If set to <code>false</code>, this instance's keypress 427 409 * event handler is not activated … … 432 414 x1 = viewX(selection.x1); y1 = viewY(selection.y1); 433 415 x2 = viewX(selection.x2); y2 = viewY(selection.y2); 434 416 } 435 417 436 418 /** 437 419 * Hide or fade out an element (or multiple elements) 438 * 420 * 439 421 * @param $elem 440 422 * A jQuery object containing the element(s) to hide/fade out 441 423 * @param fn … … 442 424 * Callback function to be called when fadeOut() completes 443 425 */ 444 426 function hide($elem, fn) { 445 options.fade Speed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide();427 options.fadeDuration ? $elem.fadeOut(options.fadeDuration, fn) : $elem.hide(); 446 428 } 447 429 448 430 /** 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 450 433 * 451 434 * @param event 452 435 * The event object 436 * @return True if the event handler should be interrupted 453 437 */ 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) { 455 450 var x = selX(evX(event)) - selection.x1, 456 451 y = selY(evY(event)) - selection.y1; 457 452 458 if (!adjusted) {459 adjust();460 adjusted = true;461 462 $box.one('mouseout', function () { adjusted = false; });463 }464 465 453 /* Clear the resize mode */ 466 454 resize = ''; 467 455 … … 482 470 483 471 $box.css('cursor', resize ? resize + '-resize' : 484 472 options.movable ? 'move' : ''); 485 if ($areaOpera)486 $areaOpera.toggle();487 473 } 488 474 489 475 /** 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 /** 490 496 * Document mouseup event handler 491 * 497 * 492 498 * @param event 493 499 * The event object 494 500 */ 495 501 function docMouseUp(event) { 502 /* Reset touch action flag */ 503 touch = false; 496 504 /* Set back the default cursor */ 497 505 $('body').css('cursor', ''); 498 506 /* … … 504 512 505 513 $(document).off('mousemove touchmove', selectingMouseMove); 506 514 $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()); 509 523 } 510 524 511 525 /** 512 526 * Selection area mousedown event handler 513 * 527 * 514 528 * @param event 515 529 * The event object 516 530 * @return false … … 517 531 */ 518 532 function areaMouseDown(event) { 519 533 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(); 520 545 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; 527 548 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(); 529 558 530 559 if (resize) { 531 560 /* Resize mode is in effect */ 532 $('body').css('cursor', resize + '-resize');533 561 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))]); 536 570 571 edgeX = x2 - evX(event); 572 edgeY = y2 - evY(event); 573 537 574 $(document).on('mousemove touchmove', selectingMouseMove) 538 575 .one('mouseup touchend', docMouseUp); 539 576 $box.off('mousemove touchmove', areaMouseMove); … … 546 583 547 584 $(document).on('mousemove touchmove', movingMouseMove) 548 585 .one('mouseup touchend', function () { 586 touch = false; 549 587 options.onSelectEnd(img, getSelection()); 550 588 551 589 $(document).off('mousemove touchmove', movingMouseMove); … … 560 598 561 599 /** 562 600 * Adjust the x2/y2 coordinates to maintain aspect ratio (if defined) 563 * 601 * 564 602 * @param xFirst 565 603 * If set to <code>true</code>, calculate x2 first. Otherwise, 566 604 * calculate y2 first. … … 569 607 if (aspectRatio) 570 608 if (xFirst) { 571 609 x2 = max(left, min(left + imgWidth, 572 x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); 610 x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); 573 611 y2 = round(max(top, min(top + imgHeight, 574 612 y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); 575 613 x2 = round(x2); … … 584 622 } 585 623 586 624 /** 587 * Resize the selection area respecting the minimum/maximum dimensions and588 * aspect ratio625 * Check if the coordinates of the selection area are within the required 626 * limits and conform to the aspect ratio; adjust if necessary 589 627 */ 590 function doResize() {628 function fixAreaCoords() { 591 629 /* 592 630 * Make sure the top left corner of the selection area stays within 593 631 * image boundaries (it might not if the image source was dynamically … … 595 633 */ 596 634 x1 = min(x1, left + imgWidth); 597 635 y1 = min(y1, top + imgHeight); 598 636 599 637 if (abs(x2 - x1) < minWidth) { 600 638 /* Selection width is smaller than minWidth */ 601 639 x2 = x1 - minWidth * (x2 < x1 || -1); … … 618 656 619 657 x2 = max(left, min(x2, left + imgWidth)); 620 658 y2 = max(top, min(y2, top + imgHeight)); 621 659 622 660 fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); 623 661 624 662 if (abs(x2 - x1) > maxWidth) { … … 636 674 selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), 637 675 y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), 638 676 width: abs(x2 - x1), height: abs(y2 - y1) }; 677 } 639 678 679 /** 680 * Resize the selection area respecting the minimum/maximum dimensions and 681 * aspect ratio 682 */ 683 function doResize() { 684 fixAreaCoords(); 685 640 686 update(); 641 687 642 688 options.onSelectChange(img, getSelection()); … … 644 690 645 691 /** 646 692 * Mousemove event handler triggered when the user is selecting an area 647 * 693 * 648 694 * @param event 649 695 * The event object 650 696 * @return false 651 697 */ 652 698 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(); 655 703 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 656 707 doResize(); 657 708 658 return false; 709 return false; 659 710 } 660 711 661 712 /** 662 713 * Move the selection area 663 * 714 * 664 715 * @param newX1 665 716 * New viewport X1 666 717 * @param newY1 … … 680 731 681 732 /** 682 733 * Mousemove event handler triggered when the selection area is being moved 683 * 734 * 684 735 * @param event 685 736 * The event object 686 737 * @return false 687 738 */ 688 739 function movingMouseMove(event) { 740 if (breakWhenNoTouch(event)) 741 return; 742 689 743 x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); 690 744 y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); 691 745 692 746 doMove(x1, y1); 693 747 694 event.preventDefault(); 748 event.preventDefault(); 695 749 return false; 696 750 } 697 751 … … 703 757 adjust(); 704 758 705 759 x2 = x1; 706 y2 = y1; 760 y2 = y1; 707 761 doResize(); 708 762 709 763 resize = ''; … … 710 764 711 765 if (!$outer.is(':visible')) 712 766 /* Show the plugin elements */ 713 $box.add($outer).hide().fadeIn(options.fade Speed||0);767 $box.add($outer).hide().fadeIn(options.fadeDuration||0) 714 768 715 769 shown = true; 716 770 … … 729 783 $(document).off('mousemove touchmove', startSelection) 730 784 .off('mouseup touchend', cancelSelection); 731 785 hide($box.add($outer)); 732 786 733 787 setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); 734 788 735 789 /* If this is an API call, callback functions should not be triggered */ 736 790 if (!(this instanceof $.imgAreaSelect)) { 737 791 options.onSelectChange(img, getSelection()); … … 741 795 742 796 /** 743 797 * Image mousedown event handler 744 * 798 * 745 799 * @param event 746 800 * The event object 747 801 * @return false … … 748 802 */ 749 803 function imgMouseDown(event) { 750 804 /* 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; 752 808 809 /* If it's a touch action, set the touch flag */ 810 touch = event.type == 'touchstart'; 811 753 812 adjust(); 754 813 startX = x1 = evX(event); 755 814 startY = y1 = evY(event); 815 edgeX = edgeY = 0; 756 816 757 817 /* Selection will start when the mouse is moved */ 758 818 $(document).on({ 'mousemove touchmove': startSelection, … … 760 820 761 821 return false; 762 822 } 763 823 764 824 /** 765 825 * Window resize event handler 766 826 */ … … 788 848 onSelectEnd: function () {} 789 849 }, options)); 790 850 791 $box.add($outer).css({ visibility: '' });792 793 851 if (options.show) { 794 852 shown = true; 795 853 adjust(); 796 854 update(); 797 $box.add($outer).hide().fadeIn(options.fade Speed||0);855 $box.add($outer).hide().fadeIn(options.fadeDuration||0) 798 856 } 799 857 800 858 /* … … 807 865 808 866 /** 809 867 * Document keypress event handler 810 * 868 * 811 869 * @param event 812 870 * The event object 813 871 * @return false … … 814 872 */ 815 873 var docKeyPress = function(event) { 816 874 var k = options.keys, d, t, key = event.keyCode; 817 875 818 876 d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : 819 877 !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : 820 878 !isNaN(k.shift) && event.shiftKey ? k.shift : … … 825 883 (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) 826 884 { 827 885 /* Resize selection */ 828 886 829 887 switch (key) { 830 888 case 37: 831 889 /* Left */ … … 855 913 } 856 914 else { 857 915 /* Move selection */ 858 916 859 917 x1 = min(x1, x2); 860 918 y1 = min(y1, y2); 861 919 … … 885 943 }; 886 944 887 945 /** 888 * Apply style options to plugin element (or multiple elements)889 *890 * @param $elem891 * A jQuery object representing the element(s) to style892 * @param props893 * An object that maps option names to corresponding CSS894 * properties895 */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 /**903 946 * Set plugin options 904 * 947 * 905 948 * @param newOptions 906 949 * The new options object 907 950 */ 908 951 function setOptions(newOptions) { 909 952 if (newOptions.parent) 910 ($parent = $(newOptions.parent)).append($box .add($outer));911 953 ($parent = $(newOptions.parent)).append($box).append($outer); 954 912 955 /* Merge the new options with the existing ones */ 913 956 $.extend(options, newOptions); 914 957 … … 923 966 924 967 while (i--) 925 968 $handles = $handles.add(div()); 926 969 927 970 /* Add a class to handles and set the CSS properties */ 928 971 $handles.addClass(options.classPrefix + '-handle').css({ 929 972 position: 'absolute', … … 934 977 fontSize: 0, 935 978 zIndex: zIndex + 1 || 1 936 979 }); 937 980 938 981 /* 939 982 * If handle width/height has not been set with CSS rules, set the 940 983 * default 5px … … 941 984 */ 942 985 if (!parseInt($handles.css('width')) >= 0) 943 986 $handles.width(5).height(5); 944 945 /*946 * If the borderWidth option is in use, add a solid border to947 * handles948 */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' });956 987 } 957 988 958 989 /* Calculate scale factors */ … … 977 1008 for (i = 0; i++ < 4;) 978 1009 $($border[i-1]).addClass(options.classPrefix + '-border' + i); 979 1010 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 992 1011 /* 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); 994 1013 995 1014 if (msie) { 996 1015 if (o = ($outer.css('filter')||'').match(/opacity=(\d+)/)) … … 998 1017 if (o = ($border.css('filter')||'').match(/opacity=(\d+)/)) 999 1018 $border.css('opacity', o[1]/100); 1000 1019 } 1001 1020 1002 1021 if (newOptions.hide) 1003 1022 hide($box.add($outer)); 1004 1023 else if (newOptions.show && imgLoaded) { 1005 1024 shown = true; 1006 $box.add($outer).fadeIn(options.fade Speed||0);1025 $box.add($outer).fadeIn(options.fadeDuration||0) 1007 1026 doUpdate(); 1008 1027 } 1009 1028 … … 1010 1029 /* Calculate the aspect ratio factor */ 1011 1030 aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; 1012 1031 1013 $img.add($outer). unbind('mousedown', imgMouseDown);1014 1032 $img.add($outer).off('mousedown touchstart', imgMouseDown); 1033 1015 1034 if (options.disable || options.enable === false) { 1016 1035 /* Disable the plugin */ 1017 1036 $box.off({ 'mousemove touchmove': areaMouseMove, … … 1024 1043 if (options.resizable || options.movable) 1025 1044 $box.on({ 'mousemove touchmove': areaMouseMove, 1026 1045 'mousedown touchstart': areaMouseDown }); 1027 1046 1028 1047 $(window).resize(windowResize); 1029 1048 } 1030 1049 … … 1031 1050 if (!options.persistent) 1032 1051 $img.add($outer).on('mousedown touchstart', imgMouseDown); 1033 1052 } 1034 1053 1035 1054 options.enable = options.disable = undefined; 1036 1055 } 1037 1056 1038 1057 /** 1039 1058 * Remove plugin completely 1040 1059 */ … … 1045 1064 setOptions({ disable: true }); 1046 1065 $box.add($outer).remove(); 1047 1066 }; 1048 1067 1049 1068 /* 1050 1069 * Public API 1051 1070 */ 1052 1071 1053 1072 /** 1054 1073 * Get current options 1055 * 1074 * 1056 1075 * @return An object containing the set of options currently in use 1057 1076 */ 1058 1077 this.getOptions = function () { return options; }; 1059 1078 1060 1079 /** 1061 1080 * Set plugin options 1062 * 1081 * 1063 1082 * @param newOptions 1064 1083 * The new options object 1065 1084 */ 1066 1085 this.setOptions = setOptions; 1067 1086 1068 1087 /** 1069 1088 * Get the current selection 1070 * 1089 * 1071 1090 * @param noScale 1072 1091 * If set to <code>true</code>, scaling is not applied to the 1073 1092 * returned selection … … 1074 1093 * @return Selection object 1075 1094 */ 1076 1095 this.getSelection = getSelection; 1077 1096 1078 1097 /** 1079 1098 * Set the current selection 1080 * 1099 * 1081 1100 * @param x1 1082 1101 * X coordinate of the upper left corner of the selection area 1083 1102 * @param y1 … … 1091 1110 * new selection 1092 1111 */ 1093 1112 this.setSelection = setSelection; 1094 1113 1095 1114 /** 1096 1115 * Cancel selection 1097 1116 */ 1098 1117 this.cancelSelection = cancelSelection; 1099 1118 1100 1119 /** 1101 1120 * Update plugin elements 1102 * 1121 * 1103 1122 * @param resetKeyPress 1104 1123 * If set to <code>false</code>, this instance's keypress 1105 1124 * event handler is not activated … … 1108 1127 1109 1128 /* Do the dreaded browser detection */ 1110 1129 var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1], 1111 opera = /opera/i.test(ua),1112 1130 safari = /webkit/i.test(ua) && !/chrome/i.test(ua); 1113 1131 1114 /* 1132 /* 1115 1133 * Traverse the image's parent elements (up to <body>) and find the 1116 1134 * highest z-index 1117 1135 */ … … 1120 1138 while ($p.length) { 1121 1139 zIndex = max(zIndex, 1122 1140 !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') 1125 1146 position = 'fixed'; 1126 1147 1127 1148 $p = $p.parent(':not(body)'); … … 1133 1154 */ 1134 1155 zIndex = options.zIndex || zIndex; 1135 1156 1136 if (msie)1137 $img.attr('unselectable', 'on');1138 1139 1157 /* 1140 1158 * In MSIE and WebKit, we need to use the keydown event instead of keypress 1141 1159 */ 1142 1160 $.imgAreaSelect.keyPress = msie || safari ? 'keydown' : 'keypress'; 1143 1161 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' }); 1164 1164 $box.css({ zIndex: zIndex + 2 || 2 }); 1165 1165 $area.add($border).css({ position: 'absolute', fontSize: 0 }); 1166 1166 1167 1167 /* 1168 1168 * If the image has been fully loaded, or if it is not really an image (eg. 1169 1169 * a div), call imgLoad() immediately; otherwise, bind it to be called once … … 1172 1172 img.complete || img.readyState == 'complete' || !$img.is('img') ? 1173 1173 imgLoad() : $img.one('load', imgLoad); 1174 1174 1175 /* 1175 /* 1176 1176 * MSIE 9.0 doesn't always fire the image load event -- resetting the src 1177 1177 * attribute seems to trigger it. The check is for version 7 and above to 1178 1178 * accommodate for MSIE 9 running in compatibility mode. … … 1183 1183 1184 1184 /** 1185 1185 * Invoke imgAreaSelect on a jQuery object containing the image(s) 1186 * 1186 * 1187 1187 * @param options 1188 1188 * Options object 1189 1189 * @return The jQuery object or a reference to imgAreaSelect instance (if the … … 1207 1207 } 1208 1208 else if (!options.remove) { 1209 1209 /* No exising instance -- create a new one */ 1210 1210 1211 1211 /* 1212 1212 * If neither the "enable" nor the "disable" option is present, add 1213 1213 * "enable" as the default 1214 */ 1214 */ 1215 1215 if (options.enable === undefined && options.disable === undefined) 1216 1216 options.enable = true; 1217 1217 … … 1218 1218 $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); 1219 1219 } 1220 1220 }); 1221 1221 1222 1222 if (options.instance) 1223 1223 /* 1224 1224 * 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&<.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&<.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+)/))&>.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