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