[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /*! 2 * jQuery UI Draggable 1.13.3 3 * https://jqueryui.com 4 * 5 * Copyright OpenJS Foundation and other contributors 6 * Released under the MIT license. 7 * https://jquery.org/license 8 */ 9 10 //>>label: Draggable 11 //>>group: Interactions 12 //>>description: Enables dragging functionality for any element. 13 //>>docs: https://api.jqueryui.com/draggable/ 14 //>>demos: https://jqueryui.com/draggable/ 15 //>>css.structure: ../../themes/base/draggable.css 16 17 ( function( factory ) { 18 "use strict"; 19 20 if ( typeof define === "function" && define.amd ) { 21 22 // AMD. Register as an anonymous module. 23 define( [ 24 "jquery", 25 "./mouse", 26 "../data", 27 "../plugin", 28 "../safe-active-element", 29 "../safe-blur", 30 "../scroll-parent", 31 "../version", 32 "../widget" 33 ], factory ); 34 } else { 35 36 // Browser globals 37 factory( jQuery ); 38 } 39 } )( function( $ ) { 40 "use strict"; 41 42 $.widget( "ui.draggable", $.ui.mouse, { 43 version: "1.13.3", 44 widgetEventPrefix: "drag", 45 options: { 46 addClasses: true, 47 appendTo: "parent", 48 axis: false, 49 connectToSortable: false, 50 containment: false, 51 cursor: "auto", 52 cursorAt: false, 53 grid: false, 54 handle: false, 55 helper: "original", 56 iframeFix: false, 57 opacity: false, 58 refreshPositions: false, 59 revert: false, 60 revertDuration: 500, 61 scope: "default", 62 scroll: true, 63 scrollSensitivity: 20, 64 scrollSpeed: 20, 65 snap: false, 66 snapMode: "both", 67 snapTolerance: 20, 68 stack: false, 69 zIndex: false, 70 71 // Callbacks 72 drag: null, 73 start: null, 74 stop: null 75 }, 76 _create: function() { 77 78 if ( this.options.helper === "original" ) { 79 this._setPositionRelative(); 80 } 81 if ( this.options.addClasses ) { 82 this._addClass( "ui-draggable" ); 83 } 84 this._setHandleClassName(); 85 86 this._mouseInit(); 87 }, 88 89 _setOption: function( key, value ) { 90 this._super( key, value ); 91 if ( key === "handle" ) { 92 this._removeHandleClassName(); 93 this._setHandleClassName(); 94 } 95 }, 96 97 _destroy: function() { 98 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 99 this.destroyOnClear = true; 100 return; 101 } 102 this._removeHandleClassName(); 103 this._mouseDestroy(); 104 }, 105 106 _mouseCapture: function( event ) { 107 var o = this.options; 108 109 // Among others, prevent a drag on a resizable-handle 110 if ( this.helper || o.disabled || 111 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 112 return false; 113 } 114 115 //Quit if we're not on a valid handle 116 this.handle = this._getHandle( event ); 117 if ( !this.handle ) { 118 return false; 119 } 120 121 this._blurActiveElement( event ); 122 123 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 124 125 return true; 126 127 }, 128 129 _blockFrames: function( selector ) { 130 this.iframeBlocks = this.document.find( selector ).map( function() { 131 var iframe = $( this ); 132 133 return $( "<div>" ) 134 .css( "position", "absolute" ) 135 .appendTo( iframe.parent() ) 136 .outerWidth( iframe.outerWidth() ) 137 .outerHeight( iframe.outerHeight() ) 138 .offset( iframe.offset() )[ 0 ]; 139 } ); 140 }, 141 142 _unblockFrames: function() { 143 if ( this.iframeBlocks ) { 144 this.iframeBlocks.remove(); 145 delete this.iframeBlocks; 146 } 147 }, 148 149 _blurActiveElement: function( event ) { 150 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 151 target = $( event.target ); 152 153 // Don't blur if the event occurred on an element that is within 154 // the currently focused element 155 // See #10527, #12472 156 if ( target.closest( activeElement ).length ) { 157 return; 158 } 159 160 // Blur any element that currently has focus, see #4261 161 $.ui.safeBlur( activeElement ); 162 }, 163 164 _mouseStart: function( event ) { 165 166 var o = this.options; 167 168 //Create and append the visible helper 169 this.helper = this._createHelper( event ); 170 171 this._addClass( this.helper, "ui-draggable-dragging" ); 172 173 //Cache the helper size 174 this._cacheHelperProportions(); 175 176 //If ddmanager is used for droppables, set the global draggable 177 if ( $.ui.ddmanager ) { 178 $.ui.ddmanager.current = this; 179 } 180 181 /* 182 * - Position generation - 183 * This block generates everything position related - it's the core of draggables. 184 */ 185 186 //Cache the margins of the original element 187 this._cacheMargins(); 188 189 //Store the helper's css position 190 this.cssPosition = this.helper.css( "position" ); 191 this.scrollParent = this.helper.scrollParent( true ); 192 this.offsetParent = this.helper.offsetParent(); 193 this.hasFixedAncestor = this.helper.parents().filter( function() { 194 return $( this ).css( "position" ) === "fixed"; 195 } ).length > 0; 196 197 //The element's absolute position on the page minus margins 198 this.positionAbs = this.element.offset(); 199 this._refreshOffsets( event ); 200 201 //Generate the original position 202 this.originalPosition = this.position = this._generatePosition( event, false ); 203 this.originalPageX = event.pageX; 204 this.originalPageY = event.pageY; 205 206 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 207 if ( o.cursorAt ) { 208 this._adjustOffsetFromHelper( o.cursorAt ); 209 } 210 211 //Set a containment if given in the options 212 this._setContainment(); 213 214 //Trigger event + callbacks 215 if ( this._trigger( "start", event ) === false ) { 216 this._clear(); 217 return false; 218 } 219 220 //Recache the helper size 221 this._cacheHelperProportions(); 222 223 //Prepare the droppable offsets 224 if ( $.ui.ddmanager && !o.dropBehaviour ) { 225 $.ui.ddmanager.prepareOffsets( this, event ); 226 } 227 228 // Execute the drag once - this causes the helper not to be visible before getting its 229 // correct position 230 this._mouseDrag( event, true ); 231 232 // If the ddmanager is used for droppables, inform the manager that dragging has started 233 // (see #5003) 234 if ( $.ui.ddmanager ) { 235 $.ui.ddmanager.dragStart( this, event ); 236 } 237 238 return true; 239 }, 240 241 _refreshOffsets: function( event ) { 242 this.offset = { 243 top: this.positionAbs.top - this.margins.top, 244 left: this.positionAbs.left - this.margins.left, 245 scroll: false, 246 parent: this._getParentOffset(), 247 relative: this._getRelativeOffset() 248 }; 249 250 this.offset.click = { 251 left: event.pageX - this.offset.left, 252 top: event.pageY - this.offset.top 253 }; 254 }, 255 256 _mouseDrag: function( event, noPropagation ) { 257 258 // reset any necessary cached properties (see #5009) 259 if ( this.hasFixedAncestor ) { 260 this.offset.parent = this._getParentOffset(); 261 } 262 263 //Compute the helpers position 264 this.position = this._generatePosition( event, true ); 265 this.positionAbs = this._convertPositionTo( "absolute" ); 266 267 //Call plugins and callbacks and use the resulting position if something is returned 268 if ( !noPropagation ) { 269 var ui = this._uiHash(); 270 if ( this._trigger( "drag", event, ui ) === false ) { 271 this._mouseUp( new $.Event( "mouseup", event ) ); 272 return false; 273 } 274 this.position = ui.position; 275 } 276 277 this.helper[ 0 ].style.left = this.position.left + "px"; 278 this.helper[ 0 ].style.top = this.position.top + "px"; 279 280 if ( $.ui.ddmanager ) { 281 $.ui.ddmanager.drag( this, event ); 282 } 283 284 return false; 285 }, 286 287 _mouseStop: function( event ) { 288 289 //If we are using droppables, inform the manager about the drop 290 var that = this, 291 dropped = false; 292 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 293 dropped = $.ui.ddmanager.drop( this, event ); 294 } 295 296 //if a drop comes from outside (a sortable) 297 if ( this.dropped ) { 298 dropped = this.dropped; 299 this.dropped = false; 300 } 301 302 if ( ( this.options.revert === "invalid" && !dropped ) || 303 ( this.options.revert === "valid" && dropped ) || 304 this.options.revert === true || ( typeof this.options.revert === "function" && 305 this.options.revert.call( this.element, dropped ) ) 306 ) { 307 $( this.helper ).animate( 308 this.originalPosition, 309 parseInt( this.options.revertDuration, 10 ), 310 function() { 311 if ( that._trigger( "stop", event ) !== false ) { 312 that._clear(); 313 } 314 } 315 ); 316 } else { 317 if ( this._trigger( "stop", event ) !== false ) { 318 this._clear(); 319 } 320 } 321 322 return false; 323 }, 324 325 _mouseUp: function( event ) { 326 this._unblockFrames(); 327 328 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 329 // (see #5003) 330 if ( $.ui.ddmanager ) { 331 $.ui.ddmanager.dragStop( this, event ); 332 } 333 334 // Only need to focus if the event occurred on the draggable itself, see #10527 335 if ( this.handleElement.is( event.target ) ) { 336 337 // The interaction is over; whether or not the click resulted in a drag, 338 // focus the element 339 this.element.trigger( "focus" ); 340 } 341 342 return $.ui.mouse.prototype._mouseUp.call( this, event ); 343 }, 344 345 cancel: function() { 346 347 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 348 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 349 } else { 350 this._clear(); 351 } 352 353 return this; 354 355 }, 356 357 _getHandle: function( event ) { 358 return this.options.handle ? 359 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 360 true; 361 }, 362 363 _setHandleClassName: function() { 364 this.handleElement = this.options.handle ? 365 this.element.find( this.options.handle ) : this.element; 366 this._addClass( this.handleElement, "ui-draggable-handle" ); 367 }, 368 369 _removeHandleClassName: function() { 370 this._removeClass( this.handleElement, "ui-draggable-handle" ); 371 }, 372 373 _createHelper: function( event ) { 374 375 var o = this.options, 376 helperIsFunction = typeof o.helper === "function", 377 helper = helperIsFunction ? 378 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 379 ( o.helper === "clone" ? 380 this.element.clone().removeAttr( "id" ) : 381 this.element ); 382 383 if ( !helper.parents( "body" ).length ) { 384 helper.appendTo( ( o.appendTo === "parent" ? 385 this.element[ 0 ].parentNode : 386 o.appendTo ) ); 387 } 388 389 // https://bugs.jqueryui.com/ticket/9446 390 // a helper function can return the original element 391 // which wouldn't have been set to relative in _create 392 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 393 this._setPositionRelative(); 394 } 395 396 if ( helper[ 0 ] !== this.element[ 0 ] && 397 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 398 helper.css( "position", "absolute" ); 399 } 400 401 return helper; 402 403 }, 404 405 _setPositionRelative: function() { 406 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 407 this.element[ 0 ].style.position = "relative"; 408 } 409 }, 410 411 _adjustOffsetFromHelper: function( obj ) { 412 if ( typeof obj === "string" ) { 413 obj = obj.split( " " ); 414 } 415 if ( Array.isArray( obj ) ) { 416 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 417 } 418 if ( "left" in obj ) { 419 this.offset.click.left = obj.left + this.margins.left; 420 } 421 if ( "right" in obj ) { 422 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 423 } 424 if ( "top" in obj ) { 425 this.offset.click.top = obj.top + this.margins.top; 426 } 427 if ( "bottom" in obj ) { 428 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 429 } 430 }, 431 432 _isRootNode: function( element ) { 433 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 434 }, 435 436 _getParentOffset: function() { 437 438 //Get the offsetParent and cache its position 439 var po = this.offsetParent.offset(), 440 document = this.document[ 0 ]; 441 442 // This is a special case where we need to modify a offset calculated on start, since the 443 // following happened: 444 // 1. The position of the helper is absolute, so it's position is calculated based on the 445 // next positioned parent 446 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 447 // the document, which means that the scroll is included in the initial calculation of the 448 // offset of the parent, and never recalculated upon drag 449 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 450 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 451 po.left += this.scrollParent.scrollLeft(); 452 po.top += this.scrollParent.scrollTop(); 453 } 454 455 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 456 po = { top: 0, left: 0 }; 457 } 458 459 return { 460 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 461 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 462 }; 463 464 }, 465 466 _getRelativeOffset: function() { 467 if ( this.cssPosition !== "relative" ) { 468 return { top: 0, left: 0 }; 469 } 470 471 var p = this.element.position(), 472 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 473 474 return { 475 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 476 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 477 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 478 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 479 }; 480 481 }, 482 483 _cacheMargins: function() { 484 this.margins = { 485 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 486 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 487 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 488 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 489 }; 490 }, 491 492 _cacheHelperProportions: function() { 493 this.helperProportions = { 494 width: this.helper.outerWidth(), 495 height: this.helper.outerHeight() 496 }; 497 }, 498 499 _setContainment: function() { 500 501 var isUserScrollable, c, ce, 502 o = this.options, 503 document = this.document[ 0 ]; 504 505 this.relativeContainer = null; 506 507 if ( !o.containment ) { 508 this.containment = null; 509 return; 510 } 511 512 if ( o.containment === "window" ) { 513 this.containment = [ 514 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 515 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 516 $( window ).scrollLeft() + $( window ).width() - 517 this.helperProportions.width - this.margins.left, 518 $( window ).scrollTop() + 519 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 520 this.helperProportions.height - this.margins.top 521 ]; 522 return; 523 } 524 525 if ( o.containment === "document" ) { 526 this.containment = [ 527 0, 528 0, 529 $( document ).width() - this.helperProportions.width - this.margins.left, 530 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 531 this.helperProportions.height - this.margins.top 532 ]; 533 return; 534 } 535 536 if ( o.containment.constructor === Array ) { 537 this.containment = o.containment; 538 return; 539 } 540 541 if ( o.containment === "parent" ) { 542 o.containment = this.helper[ 0 ].parentNode; 543 } 544 545 c = $( o.containment ); 546 ce = c[ 0 ]; 547 548 if ( !ce ) { 549 return; 550 } 551 552 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 553 554 this.containment = [ 555 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 556 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 557 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 558 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 559 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 560 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 561 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 562 this.helperProportions.width - 563 this.margins.left - 564 this.margins.right, 565 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 566 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 567 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 568 this.helperProportions.height - 569 this.margins.top - 570 this.margins.bottom 571 ]; 572 this.relativeContainer = c; 573 }, 574 575 _convertPositionTo: function( d, pos ) { 576 577 if ( !pos ) { 578 pos = this.position; 579 } 580 581 var mod = d === "absolute" ? 1 : -1, 582 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 583 584 return { 585 top: ( 586 587 // The absolute mouse position 588 pos.top + 589 590 // Only for relative positioned nodes: Relative offset from element to offset parent 591 this.offset.relative.top * mod + 592 593 // The offsetParent's offset without borders (offset + border) 594 this.offset.parent.top * mod - 595 ( ( this.cssPosition === "fixed" ? 596 -this.offset.scroll.top : 597 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 598 ), 599 left: ( 600 601 // The absolute mouse position 602 pos.left + 603 604 // Only for relative positioned nodes: Relative offset from element to offset parent 605 this.offset.relative.left * mod + 606 607 // The offsetParent's offset without borders (offset + border) 608 this.offset.parent.left * mod - 609 ( ( this.cssPosition === "fixed" ? 610 -this.offset.scroll.left : 611 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 612 ) 613 }; 614 615 }, 616 617 _generatePosition: function( event, constrainPosition ) { 618 619 var containment, co, top, left, 620 o = this.options, 621 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 622 pageX = event.pageX, 623 pageY = event.pageY; 624 625 // Cache the scroll 626 if ( !scrollIsRootNode || !this.offset.scroll ) { 627 this.offset.scroll = { 628 top: this.scrollParent.scrollTop(), 629 left: this.scrollParent.scrollLeft() 630 }; 631 } 632 633 /* 634 * - Position constraining - 635 * Constrain the position to a mix of grid, containment. 636 */ 637 638 // If we are not dragging yet, we won't check for options 639 if ( constrainPosition ) { 640 if ( this.containment ) { 641 if ( this.relativeContainer ) { 642 co = this.relativeContainer.offset(); 643 containment = [ 644 this.containment[ 0 ] + co.left, 645 this.containment[ 1 ] + co.top, 646 this.containment[ 2 ] + co.left, 647 this.containment[ 3 ] + co.top 648 ]; 649 } else { 650 containment = this.containment; 651 } 652 653 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 654 pageX = containment[ 0 ] + this.offset.click.left; 655 } 656 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 657 pageY = containment[ 1 ] + this.offset.click.top; 658 } 659 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 660 pageX = containment[ 2 ] + this.offset.click.left; 661 } 662 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 663 pageY = containment[ 3 ] + this.offset.click.top; 664 } 665 } 666 667 if ( o.grid ) { 668 669 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 670 // argument errors in IE (see ticket #6950) 671 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 672 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 673 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 674 top - this.offset.click.top > containment[ 3 ] ) ? 675 top : 676 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 677 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 678 679 left = o.grid[ 0 ] ? this.originalPageX + 680 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 681 this.originalPageX; 682 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 683 left - this.offset.click.left > containment[ 2 ] ) ? 684 left : 685 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 686 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 687 } 688 689 if ( o.axis === "y" ) { 690 pageX = this.originalPageX; 691 } 692 693 if ( o.axis === "x" ) { 694 pageY = this.originalPageY; 695 } 696 } 697 698 return { 699 top: ( 700 701 // The absolute mouse position 702 pageY - 703 704 // Click offset (relative to the element) 705 this.offset.click.top - 706 707 // Only for relative positioned nodes: Relative offset from element to offset parent 708 this.offset.relative.top - 709 710 // The offsetParent's offset without borders (offset + border) 711 this.offset.parent.top + 712 ( this.cssPosition === "fixed" ? 713 -this.offset.scroll.top : 714 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 715 ), 716 left: ( 717 718 // The absolute mouse position 719 pageX - 720 721 // Click offset (relative to the element) 722 this.offset.click.left - 723 724 // Only for relative positioned nodes: Relative offset from element to offset parent 725 this.offset.relative.left - 726 727 // The offsetParent's offset without borders (offset + border) 728 this.offset.parent.left + 729 ( this.cssPosition === "fixed" ? 730 -this.offset.scroll.left : 731 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 732 ) 733 }; 734 735 }, 736 737 _clear: function() { 738 this._removeClass( this.helper, "ui-draggable-dragging" ); 739 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 740 this.helper.remove(); 741 } 742 this.helper = null; 743 this.cancelHelperRemoval = false; 744 if ( this.destroyOnClear ) { 745 this.destroy(); 746 } 747 }, 748 749 // From now on bulk stuff - mainly helpers 750 751 _trigger: function( type, event, ui ) { 752 ui = ui || this._uiHash(); 753 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 754 755 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 756 if ( /^(drag|start|stop)/.test( type ) ) { 757 this.positionAbs = this._convertPositionTo( "absolute" ); 758 ui.offset = this.positionAbs; 759 } 760 return $.Widget.prototype._trigger.call( this, type, event, ui ); 761 }, 762 763 plugins: {}, 764 765 _uiHash: function() { 766 return { 767 helper: this.helper, 768 position: this.position, 769 originalPosition: this.originalPosition, 770 offset: this.positionAbs 771 }; 772 } 773 774 } ); 775 776 $.ui.plugin.add( "draggable", "connectToSortable", { 777 start: function( event, ui, draggable ) { 778 var uiSortable = $.extend( {}, ui, { 779 item: draggable.element 780 } ); 781 782 draggable.sortables = []; 783 $( draggable.options.connectToSortable ).each( function() { 784 var sortable = $( this ).sortable( "instance" ); 785 786 if ( sortable && !sortable.options.disabled ) { 787 draggable.sortables.push( sortable ); 788 789 // RefreshPositions is called at drag start to refresh the containerCache 790 // which is used in drag. This ensures it's initialized and synchronized 791 // with any changes that might have happened on the page since initialization. 792 sortable.refreshPositions(); 793 sortable._trigger( "activate", event, uiSortable ); 794 } 795 } ); 796 }, 797 stop: function( event, ui, draggable ) { 798 var uiSortable = $.extend( {}, ui, { 799 item: draggable.element 800 } ); 801 802 draggable.cancelHelperRemoval = false; 803 804 $.each( draggable.sortables, function() { 805 var sortable = this; 806 807 if ( sortable.isOver ) { 808 sortable.isOver = 0; 809 810 // Allow this sortable to handle removing the helper 811 draggable.cancelHelperRemoval = true; 812 sortable.cancelHelperRemoval = false; 813 814 // Use _storedCSS To restore properties in the sortable, 815 // as this also handles revert (#9675) since the draggable 816 // may have modified them in unexpected ways (#8809) 817 sortable._storedCSS = { 818 position: sortable.placeholder.css( "position" ), 819 top: sortable.placeholder.css( "top" ), 820 left: sortable.placeholder.css( "left" ) 821 }; 822 823 sortable._mouseStop( event ); 824 825 // Once drag has ended, the sortable should return to using 826 // its original helper, not the shared helper from draggable 827 sortable.options.helper = sortable.options._helper; 828 } else { 829 830 // Prevent this Sortable from removing the helper. 831 // However, don't set the draggable to remove the helper 832 // either as another connected Sortable may yet handle the removal. 833 sortable.cancelHelperRemoval = true; 834 835 sortable._trigger( "deactivate", event, uiSortable ); 836 } 837 } ); 838 }, 839 drag: function( event, ui, draggable ) { 840 $.each( draggable.sortables, function() { 841 var innermostIntersecting = false, 842 sortable = this; 843 844 // Copy over variables that sortable's _intersectsWith uses 845 sortable.positionAbs = draggable.positionAbs; 846 sortable.helperProportions = draggable.helperProportions; 847 sortable.offset.click = draggable.offset.click; 848 849 if ( sortable._intersectsWith( sortable.containerCache ) ) { 850 innermostIntersecting = true; 851 852 $.each( draggable.sortables, function() { 853 854 // Copy over variables that sortable's _intersectsWith uses 855 this.positionAbs = draggable.positionAbs; 856 this.helperProportions = draggable.helperProportions; 857 this.offset.click = draggable.offset.click; 858 859 if ( this !== sortable && 860 this._intersectsWith( this.containerCache ) && 861 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 862 innermostIntersecting = false; 863 } 864 865 return innermostIntersecting; 866 } ); 867 } 868 869 if ( innermostIntersecting ) { 870 871 // If it intersects, we use a little isOver variable and set it once, 872 // so that the move-in stuff gets fired only once. 873 if ( !sortable.isOver ) { 874 sortable.isOver = 1; 875 876 // Store draggable's parent in case we need to reappend to it later. 877 draggable._parent = ui.helper.parent(); 878 879 sortable.currentItem = ui.helper 880 .appendTo( sortable.element ) 881 .data( "ui-sortable-item", true ); 882 883 // Store helper option to later restore it 884 sortable.options._helper = sortable.options.helper; 885 886 sortable.options.helper = function() { 887 return ui.helper[ 0 ]; 888 }; 889 890 // Fire the start events of the sortable with our passed browser event, 891 // and our own helper (so it doesn't create a new one) 892 event.target = sortable.currentItem[ 0 ]; 893 sortable._mouseCapture( event, true ); 894 sortable._mouseStart( event, true, true ); 895 896 // Because the browser event is way off the new appended portlet, 897 // modify necessary variables to reflect the changes 898 sortable.offset.click.top = draggable.offset.click.top; 899 sortable.offset.click.left = draggable.offset.click.left; 900 sortable.offset.parent.left -= draggable.offset.parent.left - 901 sortable.offset.parent.left; 902 sortable.offset.parent.top -= draggable.offset.parent.top - 903 sortable.offset.parent.top; 904 905 draggable._trigger( "toSortable", event ); 906 907 // Inform draggable that the helper is in a valid drop zone, 908 // used solely in the revert option to handle "valid/invalid". 909 draggable.dropped = sortable.element; 910 911 // Need to refreshPositions of all sortables in the case that 912 // adding to one sortable changes the location of the other sortables (#9675) 913 $.each( draggable.sortables, function() { 914 this.refreshPositions(); 915 } ); 916 917 // Hack so receive/update callbacks work (mostly) 918 draggable.currentItem = draggable.element; 919 sortable.fromOutside = draggable; 920 } 921 922 if ( sortable.currentItem ) { 923 sortable._mouseDrag( event ); 924 925 // Copy the sortable's position because the draggable's can potentially reflect 926 // a relative position, while sortable is always absolute, which the dragged 927 // element has now become. (#8809) 928 ui.position = sortable.position; 929 } 930 } else { 931 932 // If it doesn't intersect with the sortable, and it intersected before, 933 // we fake the drag stop of the sortable, but make sure it doesn't remove 934 // the helper by using cancelHelperRemoval. 935 if ( sortable.isOver ) { 936 937 sortable.isOver = 0; 938 sortable.cancelHelperRemoval = true; 939 940 // Calling sortable's mouseStop would trigger a revert, 941 // so revert must be temporarily false until after mouseStop is called. 942 sortable.options._revert = sortable.options.revert; 943 sortable.options.revert = false; 944 945 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 946 sortable._mouseStop( event, true ); 947 948 // Restore sortable behaviors that were modfied 949 // when the draggable entered the sortable area (#9481) 950 sortable.options.revert = sortable.options._revert; 951 sortable.options.helper = sortable.options._helper; 952 953 if ( sortable.placeholder ) { 954 sortable.placeholder.remove(); 955 } 956 957 // Restore and recalculate the draggable's offset considering the sortable 958 // may have modified them in unexpected ways. (#8809, #10669) 959 ui.helper.appendTo( draggable._parent ); 960 draggable._refreshOffsets( event ); 961 ui.position = draggable._generatePosition( event, true ); 962 963 draggable._trigger( "fromSortable", event ); 964 965 // Inform draggable that the helper is no longer in a valid drop zone 966 draggable.dropped = false; 967 968 // Need to refreshPositions of all sortables just in case removing 969 // from one sortable changes the location of other sortables (#9675) 970 $.each( draggable.sortables, function() { 971 this.refreshPositions(); 972 } ); 973 } 974 } 975 } ); 976 } 977 } ); 978 979 $.ui.plugin.add( "draggable", "cursor", { 980 start: function( event, ui, instance ) { 981 var t = $( "body" ), 982 o = instance.options; 983 984 if ( t.css( "cursor" ) ) { 985 o._cursor = t.css( "cursor" ); 986 } 987 t.css( "cursor", o.cursor ); 988 }, 989 stop: function( event, ui, instance ) { 990 var o = instance.options; 991 if ( o._cursor ) { 992 $( "body" ).css( "cursor", o._cursor ); 993 } 994 } 995 } ); 996 997 $.ui.plugin.add( "draggable", "opacity", { 998 start: function( event, ui, instance ) { 999 var t = $( ui.helper ), 1000 o = instance.options; 1001 if ( t.css( "opacity" ) ) { 1002 o._opacity = t.css( "opacity" ); 1003 } 1004 t.css( "opacity", o.opacity ); 1005 }, 1006 stop: function( event, ui, instance ) { 1007 var o = instance.options; 1008 if ( o._opacity ) { 1009 $( ui.helper ).css( "opacity", o._opacity ); 1010 } 1011 } 1012 } ); 1013 1014 $.ui.plugin.add( "draggable", "scroll", { 1015 start: function( event, ui, i ) { 1016 if ( !i.scrollParentNotHidden ) { 1017 i.scrollParentNotHidden = i.helper.scrollParent( false ); 1018 } 1019 1020 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 1021 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 1022 i.overflowOffset = i.scrollParentNotHidden.offset(); 1023 } 1024 }, 1025 drag: function( event, ui, i ) { 1026 1027 var o = i.options, 1028 scrolled = false, 1029 scrollParent = i.scrollParentNotHidden[ 0 ], 1030 document = i.document[ 0 ]; 1031 1032 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 1033 if ( !o.axis || o.axis !== "x" ) { 1034 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 1035 o.scrollSensitivity ) { 1036 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 1037 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 1038 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 1039 } 1040 } 1041 1042 if ( !o.axis || o.axis !== "y" ) { 1043 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 1044 o.scrollSensitivity ) { 1045 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 1046 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 1047 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 1048 } 1049 } 1050 1051 } else { 1052 1053 if ( !o.axis || o.axis !== "x" ) { 1054 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 1055 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 1056 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 1057 o.scrollSensitivity ) { 1058 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 1059 } 1060 } 1061 1062 if ( !o.axis || o.axis !== "y" ) { 1063 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 1064 scrolled = $( document ).scrollLeft( 1065 $( document ).scrollLeft() - o.scrollSpeed 1066 ); 1067 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 1068 o.scrollSensitivity ) { 1069 scrolled = $( document ).scrollLeft( 1070 $( document ).scrollLeft() + o.scrollSpeed 1071 ); 1072 } 1073 } 1074 1075 } 1076 1077 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 1078 $.ui.ddmanager.prepareOffsets( i, event ); 1079 } 1080 1081 } 1082 } ); 1083 1084 $.ui.plugin.add( "draggable", "snap", { 1085 start: function( event, ui, i ) { 1086 1087 var o = i.options; 1088 1089 i.snapElements = []; 1090 1091 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 1092 .each( function() { 1093 var $t = $( this ), 1094 $o = $t.offset(); 1095 if ( this !== i.element[ 0 ] ) { 1096 i.snapElements.push( { 1097 item: this, 1098 width: $t.outerWidth(), height: $t.outerHeight(), 1099 top: $o.top, left: $o.left 1100 } ); 1101 } 1102 } ); 1103 1104 }, 1105 drag: function( event, ui, inst ) { 1106 1107 var ts, bs, ls, rs, l, r, t, b, i, first, 1108 o = inst.options, 1109 d = o.snapTolerance, 1110 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1111 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1112 1113 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 1114 1115 l = inst.snapElements[ i ].left - inst.margins.left; 1116 r = l + inst.snapElements[ i ].width; 1117 t = inst.snapElements[ i ].top - inst.margins.top; 1118 b = t + inst.snapElements[ i ].height; 1119 1120 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 1121 !$.contains( inst.snapElements[ i ].item.ownerDocument, 1122 inst.snapElements[ i ].item ) ) { 1123 if ( inst.snapElements[ i ].snapping ) { 1124 if ( inst.options.snap.release ) { 1125 inst.options.snap.release.call( 1126 inst.element, 1127 event, 1128 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 1129 ); 1130 } 1131 } 1132 inst.snapElements[ i ].snapping = false; 1133 continue; 1134 } 1135 1136 if ( o.snapMode !== "inner" ) { 1137 ts = Math.abs( t - y2 ) <= d; 1138 bs = Math.abs( b - y1 ) <= d; 1139 ls = Math.abs( l - x2 ) <= d; 1140 rs = Math.abs( r - x1 ) <= d; 1141 if ( ts ) { 1142 ui.position.top = inst._convertPositionTo( "relative", { 1143 top: t - inst.helperProportions.height, 1144 left: 0 1145 } ).top; 1146 } 1147 if ( bs ) { 1148 ui.position.top = inst._convertPositionTo( "relative", { 1149 top: b, 1150 left: 0 1151 } ).top; 1152 } 1153 if ( ls ) { 1154 ui.position.left = inst._convertPositionTo( "relative", { 1155 top: 0, 1156 left: l - inst.helperProportions.width 1157 } ).left; 1158 } 1159 if ( rs ) { 1160 ui.position.left = inst._convertPositionTo( "relative", { 1161 top: 0, 1162 left: r 1163 } ).left; 1164 } 1165 } 1166 1167 first = ( ts || bs || ls || rs ); 1168 1169 if ( o.snapMode !== "outer" ) { 1170 ts = Math.abs( t - y1 ) <= d; 1171 bs = Math.abs( b - y2 ) <= d; 1172 ls = Math.abs( l - x1 ) <= d; 1173 rs = Math.abs( r - x2 ) <= d; 1174 if ( ts ) { 1175 ui.position.top = inst._convertPositionTo( "relative", { 1176 top: t, 1177 left: 0 1178 } ).top; 1179 } 1180 if ( bs ) { 1181 ui.position.top = inst._convertPositionTo( "relative", { 1182 top: b - inst.helperProportions.height, 1183 left: 0 1184 } ).top; 1185 } 1186 if ( ls ) { 1187 ui.position.left = inst._convertPositionTo( "relative", { 1188 top: 0, 1189 left: l 1190 } ).left; 1191 } 1192 if ( rs ) { 1193 ui.position.left = inst._convertPositionTo( "relative", { 1194 top: 0, 1195 left: r - inst.helperProportions.width 1196 } ).left; 1197 } 1198 } 1199 1200 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 1201 if ( inst.options.snap.snap ) { 1202 inst.options.snap.snap.call( 1203 inst.element, 1204 event, 1205 $.extend( inst._uiHash(), { 1206 snapItem: inst.snapElements[ i ].item 1207 } ) ); 1208 } 1209 } 1210 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 1211 1212 } 1213 1214 } 1215 } ); 1216 1217 $.ui.plugin.add( "draggable", "stack", { 1218 start: function( event, ui, instance ) { 1219 var min, 1220 o = instance.options, 1221 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 1222 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 1223 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 1224 } ); 1225 1226 if ( !group.length ) { 1227 return; 1228 } 1229 1230 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 1231 $( group ).each( function( i ) { 1232 $( this ).css( "zIndex", min + i ); 1233 } ); 1234 this.css( "zIndex", ( min + group.length ) ); 1235 } 1236 } ); 1237 1238 $.ui.plugin.add( "draggable", "zIndex", { 1239 start: function( event, ui, instance ) { 1240 var t = $( ui.helper ), 1241 o = instance.options; 1242 1243 if ( t.css( "zIndex" ) ) { 1244 o._zIndex = t.css( "zIndex" ); 1245 } 1246 t.css( "zIndex", o.zIndex ); 1247 }, 1248 stop: function( event, ui, instance ) { 1249 var o = instance.options; 1250 1251 if ( o._zIndex ) { 1252 $( ui.helper ).css( "zIndex", o._zIndex ); 1253 } 1254 } 1255 } ); 1256 1257 return $.ui.draggable; 1258 1259 } );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Tue Dec 17 08:20:01 2024 | Cross-referenced by PHPXref |