1/*! jQuery UI - v1.12.1 - 2021-09-02 2* http://jqueryui.com 3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/mouse
vendor: 8,818 bytes, lines 3-330
3.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( factory ) { 7 if ( typeof define === "function" && define.amd ) { 8 9 // AMD. Register as an anonymous module. 10 define([ "jquery" ], factory ); 11 } else { 12 13 // Browser globals 14 factory( jQuery ); 15 } 16}(function( $ ) { 17 18$.ui = $.ui || {}; 19 20var version = $.ui.version = "1.12.1"; 21 22 23/*! 24 * jQuery UI Widget 1.12.1 25 * http://jqueryui.com 26 * 27 * Copyright jQuery Foundation and other contributors 28 * Released under the MIT license. 29 * http://jquery.org/license 30 */ 31 32//>>label: Widget 33//>>group: Core 34//>>description: Provides a factory for creating stateful widgets with a common API. 35//>>docs: http://api.jqueryui.com/jQuery.widget/ 36//>>demos: http://jqueryui.com/widget/ 37 38 39 40var widgetUuid = 0; 41var widgetSlice = Array.prototype.slice; 42 43$.cleanData = ( function( orig ) { 44 return function( elems ) { 45 var events, elem, i; 46 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 47 try { 48 49 // Only trigger remove when necessary to save time 50 events = $._data( elem, "events" ); 51 if ( events && events.remove ) { 52 $( elem ).triggerHandler( "remove" ); 53 } 54 55 // Http://bugs.jquery.com/ticket/8235 56 } catch ( e ) {} 57 } 58 orig( elems ); 59 }; 60} )( $.cleanData ); 61 62$.widget = function( name, base, prototype ) { 63 var existingConstructor, constructor, basePrototype; 64 65 // ProxiedPrototype allows the provided prototype to remain unmodified 66 // so that it can be used as a mixin for multiple widgets (#8876) 67 var proxiedPrototype = {}; 68 69 var namespace = name.split( "." )[ 0 ]; 70 name = name.split( "." )[ 1 ]; 71 var fullName = namespace + "-" + name; 72 73 if ( !prototype ) { 74 prototype = base; 75 base = $.Widget; 76 } 77 78 if ( $.isArray( prototype ) ) { 79 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 80 } 81 82 // Create selector for plugin 83 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 84 return !!$.data( elem, fullName ); 85 }; 86 87 $[ namespace ] = $[ namespace ] || {}; 88 existingConstructor = $[ namespace ][ name ]; 89 constructor = $[ namespace ][ name ] = function( options, element ) { 90 91 // Allow instantiation without "new" keyword 92 if ( !this._createWidget ) { 93 return new constructor( options, element ); 94 } 95 96 // Allow instantiation without initializing for simple inheritance 97 // must use "new" keyword (the code above always passes args) 98 if ( arguments.length ) { 99 this._createWidget( options, element ); 100 } 101 }; 102 103 // Extend with the existing constructor to carry over any static properties 104 $.extend( constructor, existingConstructor, { 105 version: prototype.version, 106 107 // Copy the object used to create the prototype in case we need to 108 // redefine the widget later 109 _proto: $.extend( {}, prototype ), 110 111 // Track widgets that inherit from this widget in case this widget is 112 // redefined after a widget inherits from it 113 _childConstructors: [] 114 } ); 115 116 basePrototype = new base(); 117 118 // We need to make the options hash a property directly on the new instance 119 // otherwise we'll modify the options hash on the prototype that we're 120 // inheriting from 121 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 122 $.each( prototype, function( prop, value ) { 123 if ( !$.isFunction( value ) ) { 124 proxiedPrototype[ prop ] = value; 125 return; 126 } 127 proxiedPrototype[ prop ] = ( function() { 128 function _super() { 129 return base.prototype[ prop ].apply( this, arguments ); 130 } 131 132 function _superApply( args ) { 133 return base.prototype[ prop ].apply( this, args ); 134 } 135 136 return function() { 137 var __super = this._super; 138 var __superApply = this._superApply; 139 var returnValue; 140 141 this._super = _super; 142 this._superApply = _superApply; 143 144 returnValue = value.apply( this, arguments ); 145 146 this._super = __super; 147 this._superApply = __superApply; 148 149 return returnValue; 150 }; 151 } )(); 152 } ); 153 constructor.prototype = $.widget.extend( basePrototype, { 154 155 // TODO: remove support for widgetEventPrefix 156 // always use the name + a colon as the prefix, e.g., draggable:start 157 // don't prefix for widgets that aren't DOM-based 158 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 159 }, proxiedPrototype, { 160 constructor: constructor, 161 namespace: namespace, 162 widgetName: name, 163 widgetFullName: fullName 164 } ); 165 166 // If this widget is being redefined then we need to find all widgets that 167 // are inheriting from it and redefine all of them so that they inherit from 168 // the new version of this widget. We're essentially trying to replace one 169 // level in the prototype chain. 170 if ( existingConstructor ) { 171 $.each( existingConstructor._childConstructors, function( i, child ) { 172 var childPrototype = child.prototype; 173 174 // Redefine the child widget using the same prototype that was 175 // originally used, but inherit from the new version of the base 176 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 177 child._proto ); 178 } ); 179 180 // Remove the list of existing child constructors from the old constructor 181 // so the old child constructors can be garbage collected 182 delete existingConstructor._childConstructors; 183 } else { 184 base._childConstructors.push( constructor ); 185 } 186 187 $.widget.bridge( name, constructor ); 188 189 return constructor; 190}; 191 192$.widget.extend = function( target ) { 193 var input = widgetSlice.call( arguments, 1 ); 194 var inputIndex = 0; 195 var inputLength = input.length; 196 var key; 197 var value; 198 199 for ( ; inputIndex < inputLength; inputIndex++ ) { 200 for ( key in input[ inputIndex ] ) { 201 value = input[ inputIndex ][ key ]; 202 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 203 204 // Clone objects 205 if ( $.isPlainObject( value ) ) { 206 target[ key ] = $.isPlainObject( target[ key ] ) ? 207 $.widget.extend( {}, target[ key ], value ) : 208 209 // Don't extend strings, arrays, etc. with objects 210 $.widget.extend( {}, value ); 211 212 // Copy everything else by reference 213 } else { 214 target[ key ] = value; 215 } 216 } 217 } 218 } 219 return target; 220}; 221 222$.widget.bridge = function( name, object ) { 223 var fullName = object.prototype.widgetFullName || name; 224 $.fn[ name ] = function( options ) { 225 var isMethodCall = typeof options === "string"; 226 var args = widgetSlice.call( arguments, 1 ); 227 var returnValue = this; 228 229 if ( isMethodCall ) { 230 231 // If this is an empty collection, we need to have the instance method 232 // return undefined instead of the jQuery instance 233 if ( !this.length && options === "instance" ) { 234 returnValue = undefined; 235 } else { 236 this.each( function() { 237 var methodValue; 238 var instance = $.data( this, fullName ); 239 240 if ( options === "instance" ) { 241 returnValue = instance; 242 return false; 243 } 244 245 if ( !instance ) { 246 return $.error( "cannot call methods on " + name + 247 " prior to initialization; " + 248 "attempted to call method '" + options + "'" ); 249 } 250 251 if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { 252 return $.error( "no such method '" + options + "' for " + name + 253 " widget instance" ); 254 } 255 256 methodValue = instance[ options ].apply( instance, args ); 257 258 if ( methodValue !== instance && methodValue !== undefined ) { 259 returnValue = methodValue && methodValue.jquery ? 260 returnValue.pushStack( methodValue.get() ) : 261 methodValue; 262 return false; 263 } 264 } ); 265 } 266 } else { 267 268 // Allow multiple hashes to be passed on init 269 if ( args.length ) { 270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 271 } 272 273 this.each( function() { 274 var instance = $.data( this, fullName ); 275 if ( instance ) { 276 instance.option( options || {} ); 277 if ( instance._init ) { 278 instance._init(); 279 } 280 } else { 281 $.data( this, fullName, new object( options, this ) ); 282 } 283 } ); 284 } 285 286 return returnValue; 287 }; 288}; 289 290$.Widget = function( /* options, element */ ) {}; 291$.Widget._childConstructors = []; 292 293$.Widget.prototype = { 294 widgetName: "widget", 295 widgetEventPrefix: "", 296 defaultElement: "<div>", 297 298 options: { 299 classes: {}, 300 disabled: false, 301 302 // Callbacks 303 create: null 304 }, 305 306 _createWidget: function( options, element ) { 307 element = $( element || this.defaultElement || this )[ 0 ]; 308 this.element = $( element ); 309 this.uuid = widgetUuid++; 310 this.eventNamespace = "." + this.widgetName + this.uuid; 311 312 this.bindings = $(); 313 this.hoverable = $(); 314 this.focusable = $(); 315 this.classesElementLookup = {}; 316 317 if ( element !== this ) { 318 $.data( element, this.widgetFullName, this ); 319 this._on( true, this.element, { 320 remove: function( event ) { 321 if ( event.target === element ) { 322 this.destroy(); 323 } 324 } 325 } ); 326 this.document = $( element.style ? 327 328 // Element within the document 329 element.ownerDocument : 330
vendor: 27,177 bytes, lines 331-1300
331 // Element is window or document 332 element.document || element ); 333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 334 } 335 336 this.options = $.widget.extend( {}, 337 this.options, 338 this._getCreateOptions(), 339 options ); 340 341 this._create(); 342 343 if ( this.options.disabled ) { 344 this._setOptionDisabled( this.options.disabled ); 345 } 346 347 this._trigger( "create", null, this._getCreateEventData() ); 348 this._init(); 349 }, 350 351 _getCreateOptions: function() { 352 return {}; 353 }, 354 355 _getCreateEventData: $.noop, 356 357 _create: $.noop, 358 359 _init: $.noop, 360 361 destroy: function() { 362 var that = this; 363 364 this._destroy(); 365 $.each( this.classesElementLookup, function( key, value ) { 366 that._removeClass( value, key ); 367 } ); 368 369 // We can probably remove the unbind calls in 2.0 370 // all event bindings should go through this._on() 371 this.element 372 .off( this.eventNamespace ) 373 .removeData( this.widgetFullName ); 374 this.widget() 375 .off( this.eventNamespace ) 376 .removeAttr( "aria-disabled" ); 377 378 // Clean up events and states 379 this.bindings.off( this.eventNamespace ); 380 }, 381 382 _destroy: $.noop, 383 384 widget: function() { 385 return this.element; 386 }, 387 388 option: function( key, value ) { 389 var options = key; 390 var parts; 391 var curOption; 392 var i; 393 394 if ( arguments.length === 0 ) { 395 396 // Don't return a reference to the internal hash 397 return $.widget.extend( {}, this.options ); 398 } 399 400 if ( typeof key === "string" ) { 401 402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 403 options = {}; 404 parts = key.split( "." ); 405 key = parts.shift(); 406 if ( parts.length ) { 407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 408 for ( i = 0; i < parts.length - 1; i++ ) { 409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 410 curOption = curOption[ parts[ i ] ]; 411 } 412 key = parts.pop(); 413 if ( arguments.length === 1 ) { 414 return curOption[ key ] === undefined ? null : curOption[ key ]; 415 } 416 curOption[ key ] = value; 417 } else { 418 if ( arguments.length === 1 ) { 419 return this.options[ key ] === undefined ? null : this.options[ key ]; 420 } 421 options[ key ] = value; 422 } 423 } 424 425 this._setOptions( options ); 426 427 return this; 428 }, 429 430 _setOptions: function( options ) { 431 var key; 432 433 for ( key in options ) { 434 this._setOption( key, options[ key ] ); 435 } 436 437 return this; 438 }, 439 440 _setOption: function( key, value ) { 441 if ( key === "classes" ) { 442 this._setOptionClasses( value ); 443 } 444 445 this.options[ key ] = value; 446 447 if ( key === "disabled" ) { 448 this._setOptionDisabled( value ); 449 } 450 451 return this; 452 }, 453 454 _setOptionClasses: function( value ) { 455 var classKey, elements, currentElements; 456 457 for ( classKey in value ) { 458 currentElements = this.classesElementLookup[ classKey ]; 459 if ( value[ classKey ] === this.options.classes[ classKey ] || 460 !currentElements || 461 !currentElements.length ) { 462 continue; 463 } 464 465 // We are doing this to create a new jQuery object because the _removeClass() call 466 // on the next line is going to destroy the reference to the current elements being 467 // tracked. We need to save a copy of this collection so that we can add the new classes 468 // below. 469 elements = $( currentElements.get() ); 470 this._removeClass( currentElements, classKey ); 471 472 // We don't use _addClass() here, because that uses this.options.classes 473 // for generating the string of classes. We want to use the value passed in from 474 // _setOption(), this is the new value of the classes option which was passed to 475 // _setOption(). We pass this value directly to _classes(). 476 elements.addClass( this._classes( { 477 element: elements, 478 keys: classKey, 479 classes: value, 480 add: true 481 } ) ); 482 } 483 }, 484 485 _setOptionDisabled: function( value ) { 486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 487 488 // If the widget is becoming disabled, then nothing is interactive 489 if ( value ) { 490 this._removeClass( this.hoverable, null, "ui-state-hover" ); 491 this._removeClass( this.focusable, null, "ui-state-focus" ); 492 } 493 }, 494 495 enable: function() { 496 return this._setOptions( { disabled: false } ); 497 }, 498 499 disable: function() { 500 return this._setOptions( { disabled: true } ); 501 }, 502 503 _classes: function( options ) { 504 var full = []; 505 var that = this; 506 507 options = $.extend( { 508 element: this.element, 509 classes: this.options.classes || {} 510 }, options ); 511 512 function processClassString( classes, checkOption ) { 513 var current, i; 514 for ( i = 0; i < classes.length; i++ ) { 515 current = that.classesElementLookup[ classes[ i ] ] || $(); 516 if ( options.add ) { 517 current = $( $.unique( current.get().concat( options.element.get() ) ) ); 518 } else { 519 current = $( current.not( options.element ).get() ); 520 } 521 that.classesElementLookup[ classes[ i ] ] = current; 522 full.push( classes[ i ] ); 523 if ( checkOption && options.classes[ classes[ i ] ] ) { 524 full.push( options.classes[ classes[ i ] ] ); 525 } 526 } 527 } 528 529 this._on( options.element, { 530 "remove": "_untrackClassesElement" 531 } ); 532 533 if ( options.keys ) { 534 processClassString( options.keys.match( /\S+/g ) || [], true ); 535 } 536 if ( options.extra ) { 537 processClassString( options.extra.match( /\S+/g ) || [] ); 538 } 539 540 return full.join( " " ); 541 }, 542 543 _untrackClassesElement: function( event ) { 544 var that = this; 545 $.each( that.classesElementLookup, function( key, value ) { 546 if ( $.inArray( event.target, value ) !== -1 ) { 547 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 548 } 549 } ); 550 }, 551 552 _removeClass: function( element, keys, extra ) { 553 return this._toggleClass( element, keys, extra, false ); 554 }, 555 556 _addClass: function( element, keys, extra ) { 557 return this._toggleClass( element, keys, extra, true ); 558 }, 559 560 _toggleClass: function( element, keys, extra, add ) { 561 add = ( typeof add === "boolean" ) ? add : extra; 562 var shift = ( typeof element === "string" || element === null ), 563 options = { 564 extra: shift ? keys : extra, 565 keys: shift ? element : keys, 566 element: shift ? this.element : element, 567 add: add 568 }; 569 options.element.toggleClass( this._classes( options ), add ); 570 return this; 571 }, 572 573 _on: function( suppressDisabledCheck, element, handlers ) { 574 var delegateElement; 575 var instance = this; 576 577 // No suppressDisabledCheck flag, shuffle arguments 578 if ( typeof suppressDisabledCheck !== "boolean" ) { 579 handlers = element; 580 element = suppressDisabledCheck; 581 suppressDisabledCheck = false; 582 } 583 584 // No element argument, shuffle and use this.element 585 if ( !handlers ) { 586 handlers = element; 587 element = this.element; 588 delegateElement = this.widget(); 589 } else { 590 element = delegateElement = $( element ); 591 this.bindings = this.bindings.add( element ); 592 } 593 594 $.each( handlers, function( event, handler ) { 595 function handlerProxy() { 596 597 // Allow widgets to customize the disabled handling 598 // - disabled as an array instead of boolean 599 // - disabled class as method for disabling individual parts 600 if ( !suppressDisabledCheck && 601 ( instance.options.disabled === true || 602 $( this ).hasClass( "ui-state-disabled" ) ) ) { 603 return; 604 } 605 return ( typeof handler === "string" ? instance[ handler ] : handler ) 606 .apply( instance, arguments ); 607 } 608 609 // Copy the guid so direct unbinding works 610 if ( typeof handler !== "string" ) { 611 handlerProxy.guid = handler.guid = 612 handler.guid || handlerProxy.guid || $.guid++; 613 } 614 615 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 616 var eventName = match[ 1 ] + instance.eventNamespace; 617 var selector = match[ 2 ]; 618 619 if ( selector ) { 620 delegateElement.on( eventName, selector, handlerProxy ); 621 } else { 622 element.on( eventName, handlerProxy ); 623 } 624 } ); 625 }, 626 627 _off: function( element, eventName ) { 628 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 629 this.eventNamespace; 630 element.off( eventName ).off( eventName ); 631 632 // Clear the stack to avoid memory leaks (#10056) 633 this.bindings = $( this.bindings.not( element ).get() ); 634 this.focusable = $( this.focusable.not( element ).get() ); 635 this.hoverable = $( this.hoverable.not( element ).get() ); 636 }, 637 638 _delay: function( handler, delay ) { 639 function handlerProxy() { 640 return ( typeof handler === "string" ? instance[ handler ] : handler ) 641 .apply( instance, arguments ); 642 } 643 var instance = this; 644 return setTimeout( handlerProxy, delay || 0 ); 645 }, 646 647 _hoverable: function( element ) { 648 this.hoverable = this.hoverable.add( element ); 649 this._on( element, { 650 mouseenter: function( event ) { 651 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 652 }, 653 mouseleave: function( event ) { 654 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 655 } 656 } ); 657 }, 658 659 _focusable: function( element ) { 660 this.focusable = this.focusable.add( element ); 661 this._on( element, { 662 focusin: function( event ) { 663 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 664 }, 665 focusout: function( event ) { 666 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 667 } 668 } ); 669 }, 670 671 _trigger: function( type, event, data ) { 672 var prop, orig; 673 var callback = this.options[ type ]; 674 675 data = data || {}; 676 event = $.Event( event ); 677 event.type = ( type === this.widgetEventPrefix ? 678 type : 679 this.widgetEventPrefix + type ).toLowerCase(); 680 681 // The original event may come from any element 682 // so we need to reset the target on the new event 683 event.target = this.element[ 0 ]; 684 685 // Copy original event properties over to the new event 686 orig = event.originalEvent; 687 if ( orig ) { 688 for ( prop in orig ) { 689 if ( !( prop in event ) ) { 690 event[ prop ] = orig[ prop ]; 691 } 692 } 693 } 694 695 this.element.trigger( event, data ); 696 return !( $.isFunction( callback ) && 697 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 698 event.isDefaultPrevented() ); 699 } 700}; 701 702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 703 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 704 if ( typeof options === "string" ) { 705 options = { effect: options }; 706 } 707 708 var hasOptions; 709 var effectName = !options ? 710 method : 711 options === true || typeof options === "number" ? 712 defaultEffect : 713 options.effect || defaultEffect; 714 715 options = options || {}; 716 if ( typeof options === "number" ) { 717 options = { duration: options }; 718 } 719 720 hasOptions = !$.isEmptyObject( options ); 721 options.complete = callback; 722 723 if ( options.delay ) { 724 element.delay( options.delay ); 725 } 726 727 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 728 element[ method ]( options ); 729 } else if ( effectName !== method && element[ effectName ] ) { 730 element[ effectName ]( options.duration, options.easing, callback ); 731 } else { 732 element.queue( function( next ) { 733 $( this )[ method ](); 734 if ( callback ) { 735 callback.call( element[ 0 ] ); 736 } 737 next(); 738 } ); 739 } 740 }; 741} ); 742 743var widget = $.widget; 744 745 746/*! 747 * jQuery UI Position 1.12.1 748 * http://jqueryui.com 749 * 750 * Copyright jQuery Foundation and other contributors 751 * Released under the MIT license. 752 * http://jquery.org/license 753 * 754 * http://api.jqueryui.com/position/ 755 */ 756 757//>>label: Position 758//>>group: Core 759//>>description: Positions elements relative to other elements. 760//>>docs: http://api.jqueryui.com/position/ 761//>>demos: http://jqueryui.com/position/ 762 763 764( function() { 765var cachedScrollbarWidth, 766 max = Math.max, 767 abs = Math.abs, 768 rhorizontal = /left|center|right/, 769 rvertical = /top|center|bottom/, 770 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 771 rposition = /^\w+/, 772 rpercent = /%$/, 773 _position = $.fn.position; 774 775function getOffsets( offsets, width, height ) { 776 return [ 777 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 778 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 779 ]; 780} 781 782function parseCss( element, property ) { 783 return parseInt( $.css( element, property ), 10 ) || 0; 784} 785 786function getDimensions( elem ) { 787 var raw = elem[ 0 ]; 788 if ( raw.nodeType === 9 ) { 789 return { 790 width: elem.width(), 791 height: elem.height(), 792 offset: { top: 0, left: 0 } 793 }; 794 } 795 if ( $.isWindow( raw ) ) { 796 return { 797 width: elem.width(), 798 height: elem.height(), 799 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 800 }; 801 } 802 if ( raw.preventDefault ) { 803 return { 804 width: 0, 805 height: 0, 806 offset: { top: raw.pageY, left: raw.pageX } 807 }; 808 } 809 return { 810 width: elem.outerWidth(), 811 height: elem.outerHeight(), 812 offset: elem.offset() 813 }; 814} 815 816$.position = { 817 scrollbarWidth: function() { 818 if ( cachedScrollbarWidth !== undefined ) { 819 return cachedScrollbarWidth; 820 } 821 var w1, w2, 822 div = $( "<div " + 823 "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + 824 "<div style='height:100px;width:auto;'></div></div>" ), 825 innerDiv = div.children()[ 0 ]; 826 827 $( "body" ).append( div ); 828 w1 = innerDiv.offsetWidth; 829 div.css( "overflow", "scroll" ); 830 831 w2 = innerDiv.offsetWidth; 832 833 if ( w1 === w2 ) { 834 w2 = div[ 0 ].clientWidth; 835 } 836 837 div.remove(); 838 839 return ( cachedScrollbarWidth = w1 - w2 ); 840 }, 841 getScrollInfo: function( within ) { 842 var overflowX = within.isWindow || within.isDocument ? "" : 843 within.element.css( "overflow-x" ), 844 overflowY = within.isWindow || within.isDocument ? "" : 845 within.element.css( "overflow-y" ), 846 hasOverflowX = overflowX === "scroll" || 847 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 848 hasOverflowY = overflowY === "scroll" || 849 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 850 return { 851 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 852 height: hasOverflowX ? $.position.scrollbarWidth() : 0 853 }; 854 }, 855 getWithinInfo: function( element ) { 856 var withinElement = $( element || window ), 857 isWindow = $.isWindow( withinElement[ 0 ] ), 858 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 859 hasOffset = !isWindow && !isDocument; 860 return { 861 element: withinElement, 862 isWindow: isWindow, 863 isDocument: isDocument, 864 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 865 scrollLeft: withinElement.scrollLeft(), 866 scrollTop: withinElement.scrollTop(), 867 width: withinElement.outerWidth(), 868 height: withinElement.outerHeight() 869 }; 870 } 871}; 872 873$.fn.position = function( options ) { 874 if ( !options || !options.of ) { 875 return _position.apply( this, arguments ); 876 } 877 878 // Make a copy, we don't want to modify arguments 879 options = $.extend( {}, options ); 880 881 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 882 target = $( options.of ), 883 within = $.position.getWithinInfo( options.within ), 884 scrollInfo = $.position.getScrollInfo( within ), 885 collision = ( options.collision || "flip" ).split( " " ), 886 offsets = {}; 887 888 dimensions = getDimensions( target ); 889 if ( target[ 0 ].preventDefault ) { 890 891 // Force left top to allow flipping 892 options.at = "left top"; 893 } 894 targetWidth = dimensions.width; 895 targetHeight = dimensions.height; 896 targetOffset = dimensions.offset; 897 898 // Clone to reuse original targetOffset later 899 basePosition = $.extend( {}, targetOffset ); 900 901 // Force my and at to have valid horizontal and vertical positions 902 // if a value is missing or invalid, it will be converted to center 903 $.each( [ "my", "at" ], function() { 904 var pos = ( options[ this ] || "" ).split( " " ), 905 horizontalOffset, 906 verticalOffset; 907 908 if ( pos.length === 1 ) { 909 pos = rhorizontal.test( pos[ 0 ] ) ? 910 pos.concat( [ "center" ] ) : 911 rvertical.test( pos[ 0 ] ) ? 912 [ "center" ].concat( pos ) : 913 [ "center", "center" ]; 914 } 915 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 916 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 917 918 // Calculate offsets 919 horizontalOffset = roffset.exec( pos[ 0 ] ); 920 verticalOffset = roffset.exec( pos[ 1 ] ); 921 offsets[ this ] = [ 922 horizontalOffset ? horizontalOffset[ 0 ] : 0, 923 verticalOffset ? verticalOffset[ 0 ] : 0 924 ]; 925 926 // Reduce to just the positions without the offsets 927 options[ this ] = [ 928 rposition.exec( pos[ 0 ] )[ 0 ], 929 rposition.exec( pos[ 1 ] )[ 0 ] 930 ]; 931 } ); 932 933 // Normalize collision option 934 if ( collision.length === 1 ) { 935 collision[ 1 ] = collision[ 0 ]; 936 } 937 938 if ( options.at[ 0 ] === "right" ) { 939 basePosition.left += targetWidth; 940 } else if ( options.at[ 0 ] === "center" ) { 941 basePosition.left += targetWidth / 2; 942 } 943 944 if ( options.at[ 1 ] === "bottom" ) { 945 basePosition.top += targetHeight; 946 } else if ( options.at[ 1 ] === "center" ) { 947 basePosition.top += targetHeight / 2; 948 } 949 950 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 951 basePosition.left += atOffset[ 0 ]; 952 basePosition.top += atOffset[ 1 ]; 953 954 return this.each( function() { 955 var collisionPosition, using, 956 elem = $( this ), 957 elemWidth = elem.outerWidth(), 958 elemHeight = elem.outerHeight(), 959 marginLeft = parseCss( this, "marginLeft" ), 960 marginTop = parseCss( this, "marginTop" ), 961 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 962 scrollInfo.width, 963 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 964 scrollInfo.height, 965 position = $.extend( {}, basePosition ), 966 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 967 968 if ( options.my[ 0 ] === "right" ) { 969 position.left -= elemWidth; 970 } else if ( options.my[ 0 ] === "center" ) { 971 position.left -= elemWidth / 2; 972 } 973 974 if ( options.my[ 1 ] === "bottom" ) { 975 position.top -= elemHeight; 976 } else if ( options.my[ 1 ] === "center" ) { 977 position.top -= elemHeight / 2; 978 } 979 980 position.left += myOffset[ 0 ]; 981 position.top += myOffset[ 1 ]; 982 983 collisionPosition = { 984 marginLeft: marginLeft, 985 marginTop: marginTop 986 }; 987 988 $.each( [ "left", "top" ], function( i, dir ) { 989 if ( $.ui.position[ collision[ i ] ] ) { 990 $.ui.position[ collision[ i ] ][ dir ]( position, { 991 targetWidth: targetWidth, 992 targetHeight: targetHeight, 993 elemWidth: elemWidth, 994 elemHeight: elemHeight, 995 collisionPosition: collisionPosition, 996 collisionWidth: collisionWidth, 997 collisionHeight: collisionHeight, 998 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 999 my: options.my, 1000 at: options.at, 1001 within: within, 1002 elem: elem 1003 } ); 1004 } 1005 } ); 1006 1007 if ( options.using ) { 1008 1009 // Adds feedback as second argument to using callback, if present 1010 using = function( props ) { 1011 var left = targetOffset.left - position.left, 1012 right = left + targetWidth - elemWidth, 1013 top = targetOffset.top - position.top, 1014 bottom = top + targetHeight - elemHeight, 1015 feedback = { 1016 target: { 1017 element: target, 1018 left: targetOffset.left, 1019 top: targetOffset.top, 1020 width: targetWidth, 1021 height: targetHeight 1022 }, 1023 element: { 1024 element: elem, 1025 left: position.left, 1026 top: position.top, 1027 width: elemWidth, 1028 height: elemHeight 1029 }, 1030 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1031 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1032 }; 1033 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1034 feedback.horizontal = "center"; 1035 } 1036 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1037 feedback.vertical = "middle"; 1038 } 1039 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1040 feedback.important = "horizontal"; 1041 } else { 1042 feedback.important = "vertical"; 1043 } 1044 options.using.call( this, props, feedback ); 1045 }; 1046 } 1047 1048 elem.offset( $.extend( position, { using: using } ) ); 1049 } ); 1050}; 1051 1052$.ui.position = { 1053 fit: { 1054 left: function( position, data ) { 1055 var within = data.within, 1056 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1057 outerWidth = within.width, 1058 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1059 overLeft = withinOffset - collisionPosLeft, 1060 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1061 newOverRight; 1062 1063 // Element is wider than within 1064 if ( data.collisionWidth > outerWidth ) { 1065 1066 // Element is initially over the left side of within 1067 if ( overLeft > 0 && overRight <= 0 ) { 1068 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1069 withinOffset; 1070 position.left += overLeft - newOverRight; 1071 1072 // Element is initially over right side of within 1073 } else if ( overRight > 0 && overLeft <= 0 ) { 1074 position.left = withinOffset; 1075 1076 // Element is initially over both left and right sides of within 1077 } else { 1078 if ( overLeft > overRight ) { 1079 position.left = withinOffset + outerWidth - data.collisionWidth; 1080 } else { 1081 position.left = withinOffset; 1082 } 1083 } 1084 1085 // Too far left -> align with left edge 1086 } else if ( overLeft > 0 ) { 1087 position.left += overLeft; 1088 1089 // Too far right -> align with right edge 1090 } else if ( overRight > 0 ) { 1091 position.left -= overRight; 1092 1093 // Adjust based on position and margin 1094 } else { 1095 position.left = max( position.left - collisionPosLeft, position.left ); 1096 } 1097 }, 1098 top: function( position, data ) { 1099 var within = data.within, 1100 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1101 outerHeight = data.within.height, 1102 collisionPosTop = position.top - data.collisionPosition.marginTop, 1103 overTop = withinOffset - collisionPosTop, 1104 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1105 newOverBottom; 1106 1107 // Element is taller than within 1108 if ( data.collisionHeight > outerHeight ) { 1109 1110 // Element is initially over the top of within 1111 if ( overTop > 0 && overBottom <= 0 ) { 1112 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1113 withinOffset; 1114 position.top += overTop - newOverBottom; 1115 1116 // Element is initially over bottom of within 1117 } else if ( overBottom > 0 && overTop <= 0 ) { 1118 position.top = withinOffset; 1119 1120 // Element is initially over both top and bottom of within 1121 } else { 1122 if ( overTop > overBottom ) { 1123 position.top = withinOffset + outerHeight - data.collisionHeight; 1124 } else { 1125 position.top = withinOffset; 1126 } 1127 } 1128 1129 // Too far up -> align with top 1130 } else if ( overTop > 0 ) { 1131 position.top += overTop; 1132 1133 // Too far down -> align with bottom edge 1134 } else if ( overBottom > 0 ) { 1135 position.top -= overBottom; 1136 1137 // Adjust based on position and margin 1138 } else { 1139 position.top = max( position.top - collisionPosTop, position.top ); 1140 } 1141 } 1142 }, 1143 flip: { 1144 left: function( position, data ) { 1145 var within = data.within, 1146 withinOffset = within.offset.left + within.scrollLeft, 1147 outerWidth = within.width, 1148 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1149 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1150 overLeft = collisionPosLeft - offsetLeft, 1151 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1152 myOffset = data.my[ 0 ] === "left" ? 1153 -data.elemWidth : 1154 data.my[ 0 ] === "right" ? 1155 data.elemWidth : 1156 0, 1157 atOffset = data.at[ 0 ] === "left" ? 1158 data.targetWidth : 1159 data.at[ 0 ] === "right" ? 1160 -data.targetWidth : 1161 0, 1162 offset = -2 * data.offset[ 0 ], 1163 newOverRight, 1164 newOverLeft; 1165 1166 if ( overLeft < 0 ) { 1167 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1168 outerWidth - withinOffset; 1169 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1170 position.left += myOffset + atOffset + offset; 1171 } 1172 } else if ( overRight > 0 ) { 1173 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1174 atOffset + offset - offsetLeft; 1175 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1176 position.left += myOffset + atOffset + offset; 1177 } 1178 } 1179 }, 1180 top: function( position, data ) { 1181 var within = data.within, 1182 withinOffset = within.offset.top + within.scrollTop, 1183 outerHeight = within.height, 1184 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1185 collisionPosTop = position.top - data.collisionPosition.marginTop, 1186 overTop = collisionPosTop - offsetTop, 1187 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1188 top = data.my[ 1 ] === "top", 1189 myOffset = top ? 1190 -data.elemHeight : 1191 data.my[ 1 ] === "bottom" ? 1192 data.elemHeight : 1193 0, 1194 atOffset = data.at[ 1 ] === "top" ? 1195 data.targetHeight : 1196 data.at[ 1 ] === "bottom" ? 1197 -data.targetHeight : 1198 0, 1199 offset = -2 * data.offset[ 1 ], 1200 newOverTop, 1201 newOverBottom; 1202 if ( overTop < 0 ) { 1203 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1204 outerHeight - withinOffset; 1205 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1206 position.top += myOffset + atOffset + offset; 1207 } 1208 } else if ( overBottom > 0 ) { 1209 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1210 offset - offsetTop; 1211 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1212 position.top += myOffset + atOffset + offset; 1213 } 1214 } 1215 } 1216 }, 1217 flipfit: { 1218 left: function() { 1219 $.ui.position.flip.left.apply( this, arguments ); 1220 $.ui.position.fit.left.apply( this, arguments ); 1221 }, 1222 top: function() { 1223 $.ui.position.flip.top.apply( this, arguments ); 1224 $.ui.position.fit.top.apply( this, arguments ); 1225 } 1226 } 1227}; 1228 1229} )(); 1230 1231var position = $.ui.position; 1232 1233 1234/*! 1235 * jQuery UI :data 1.12.1 1236 * http://jqueryui.com 1237 * 1238 * Copyright jQuery Foundation and other contributors 1239 * Released under the MIT license. 1240 * http://jquery.org/license 1241 */ 1242 1243//>>label: :data Selector 1244//>>group: Core 1245//>>description: Selects elements which have data stored under the specified key. 1246//>>docs: http://api.jqueryui.com/data-selector/ 1247 1248 1249var data = $.extend( $.expr[ ":" ], { 1250 data: $.expr.createPseudo ? 1251 $.expr.createPseudo( function( dataName ) { 1252 return function( elem ) { 1253 return !!$.data( elem, dataName ); 1254 }; 1255 } ) : 1256 1257 // Support: jQuery <1.8 1258 function( elem, i, match ) { 1259 return !!$.data( elem, match[ 3 ] ); 1260 } 1261} ); 1262 1263/*! 1264 * jQuery UI Disable Selection 1.12.1 1265 * http://jqueryui.com 1266 * 1267 * Copyright jQuery Foundation and other contributors 1268 * Released under the MIT license. 1269 * http://jquery.org/license 1270 */ 1271 1272//>>label: disableSelection 1273//>>group: Core 1274//>>description: Disable selection of text content within the set of matched elements. 1275//>>docs: http://api.jqueryui.com/disableSelection/ 1276 1277// This file is deprecated 1278 1279 1280var disableSelection = $.fn.extend( { 1281 disableSelection: ( function() { 1282 var eventType = "onselectstart" in document.createElement( "div" ) ? 1283 "selectstart" : 1284 "mousedown"; 1285 1286 return function() { 1287 return this.on( eventType + ".ui-disableSelection", function( event ) { 1288 event.preventDefault(); 1289 } ); 1290 }; 1291 } )(), 1292 1293 enableSelection: function() { 1294 return this.off( ".ui-disableSelection" ); 1295 } 1296} ); 1297 1298 1299/*! 1300 * jQuery UI
vendor: 3,855 bytes, lines 1300-1446
1300Focusable 1.12.1 1301 * http://jqueryui.com 1302 * 1303 * Copyright jQuery Foundation and other contributors 1304 * Released under the MIT license. 1305 * http://jquery.org/license 1306 */ 1307 1308//>>label: :focusable Selector 1309//>>group: Core 1310//>>description: Selects elements which can be focused. 1311//>>docs: http://api.jqueryui.com/focusable-selector/ 1312 1313 1314 1315// Selectors 1316$.ui.focusable = function( element, hasTabindex ) { 1317 var map, mapName, img, focusableIfVisible, fieldset, 1318 nodeName = element.nodeName.toLowerCase(); 1319 1320 if ( "area" === nodeName ) { 1321 map = element.parentNode; 1322 mapName = map.name; 1323 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 1324 return false; 1325 } 1326 img = $( "img[usemap='#" + mapName + "']" ); 1327 return img.length > 0 && img.is( ":visible" ); 1328 } 1329 1330 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 1331 focusableIfVisible = !element.disabled; 1332 1333 if ( focusableIfVisible ) { 1334 1335 // Form controls within a disabled fieldset are disabled. 1336 // However, controls within the fieldset's legend do not get disabled. 1337 // Since controls generally aren't placed inside legends, we skip 1338 // this portion of the check. 1339 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 1340 if ( fieldset ) { 1341 focusableIfVisible = !fieldset.disabled; 1342 } 1343 } 1344 } else if ( "a" === nodeName ) { 1345 focusableIfVisible = element.href || hasTabindex; 1346 } else { 1347 focusableIfVisible = hasTabindex; 1348 } 1349 1350 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 1351}; 1352 1353// Support: IE 8 only 1354// IE 8 doesn't resolve inherit to visible/hidden for computed values 1355function visible( element ) { 1356 var visibility = element.css( "visibility" ); 1357 while ( visibility === "inherit" ) { 1358 element = element.parent(); 1359 visibility = element.css( "visibility" ); 1360 } 1361 return visibility !== "hidden"; 1362} 1363 1364$.extend( $.expr[ ":" ], { 1365 focusable: function( element ) { 1366 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 1367 } 1368} ); 1369 1370var focusable = $.ui.focusable; 1371 1372 1373 1374 1375// Support: IE8 Only 1376// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 1377// with a string, so we need to find the proper form. 1378var form = $.fn.form = function() { 1379 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 1380}; 1381 1382 1383/*! 1384 * jQuery UI Form Reset Mixin 1.12.1 1385 * http://jqueryui.com 1386 * 1387 * Copyright jQuery Foundation and other contributors 1388 * Released under the MIT license. 1389 * http://jquery.org/license 1390 */ 1391 1392//>>label: Form Reset Mixin 1393//>>group: Core 1394//>>description: Refresh input widgets when their form is reset 1395//>>docs: http://api.jqueryui.com/form-reset-mixin/ 1396 1397 1398 1399var formResetMixin = $.ui.formResetMixin = { 1400 _formResetHandler: function() { 1401 var form = $( this ); 1402 1403 // Wait for the form reset to actually happen before refreshing 1404 setTimeout( function() { 1405 var instances = form.data( "ui-form-reset-instances" ); 1406 $.each( instances, function() { 1407 this.refresh(); 1408 } ); 1409 } ); 1410 }, 1411 1412 _bindFormResetHandler: function() { 1413 this.form = this.element.form(); 1414 if ( !this.form.length ) { 1415 return; 1416 } 1417 1418 var instances = this.form.data( "ui-form-reset-instances" ) || []; 1419 if ( !instances.length ) { 1420 1421 // We don't use _on() here because we use a single event handler per form 1422 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 1423 } 1424 instances.push( this ); 1425 this.form.data( "ui-form-reset-instances", instances ); 1426 }, 1427 1428 _unbindFormResetHandler: function() { 1429 if ( !this.form.length ) { 1430 return; 1431 } 1432 1433 var instances = this.form.data( "ui-form-reset-instances" ); 1434 instances.splice( $.inArray( this, instances ), 1 ); 1435 if ( instances.length ) { 1436 this.form.data( "ui-form-reset-instances", instances ); 1437 } else { 1438 this.form 1439 .removeData( "ui-form-reset-instances" ) 1440 .off( "reset.ui-form-reset" ); 1441 } 1442 } 1443}; 1444 1445 1446/*!
vendor: 3,622 bytes, lines 1447-1595
1447 * jQuery UI Keycode 1.12.1 1448 * http://jqueryui.com 1449 * 1450 * Copyright jQuery Foundation and other contributors 1451 * Released under the MIT license. 1452 * http://jquery.org/license 1453 */ 1454 1455//>>label: Keycode 1456//>>group: Core 1457//>>description: Provide keycodes as keynames 1458//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 1459 1460 1461var keycode = $.ui.keyCode = { 1462 BACKSPACE: 8, 1463 COMMA: 188, 1464 DELETE: 46, 1465 DOWN: 40, 1466 END: 35, 1467 ENTER: 13, 1468 ESCAPE: 27, 1469 HOME: 36, 1470 LEFT: 37, 1471 PAGE_DOWN: 34, 1472 PAGE_UP: 33, 1473 PERIOD: 190, 1474 RIGHT: 39, 1475 SPACE: 32, 1476 TAB: 9, 1477 UP: 38 1478}; 1479 1480 1481 1482 1483// Internal use only 1484var escapeSelector = $.ui.escapeSelector = ( function() { 1485 var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; 1486 return function( selector ) { 1487 return selector.replace( selectorEscape, "\\$1" ); 1488 }; 1489} )(); 1490 1491 1492/*! 1493 * jQuery UI Labels 1.12.1 1494 * http://jqueryui.com 1495 * 1496 * Copyright jQuery Foundation and other contributors 1497 * Released under the MIT license. 1498 * http://jquery.org/license 1499 */ 1500 1501//>>label: labels 1502//>>group: Core 1503//>>description: Find all the labels associated with a given input 1504//>>docs: http://api.jqueryui.com/labels/ 1505 1506 1507 1508var labels = $.fn.labels = function() { 1509 var ancestor, selector, id, labels, ancestors; 1510 1511 // Check control.labels first 1512 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 1513 return this.pushStack( this[ 0 ].labels ); 1514 } 1515 1516 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 1517 // Above browsers do not support control.labels. Everything below is to support them 1518 // as well as document fragments. control.labels does not work on document fragments 1519 labels = this.eq( 0 ).parents( "label" ); 1520 1521 // Look for the label based on the id 1522 id = this.attr( "id" ); 1523 if ( id ) { 1524 1525 // We don't search against the document in case the element 1526 // is disconnected from the DOM 1527 ancestor = this.eq( 0 ).parents().last(); 1528 1529 // Get a full set of top level ancestors 1530 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 1531 1532 // Create a selector for the label based on the id 1533 selector = "label[for='" + $.ui.escapeSelector( id ) + "']"; 1534 1535 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 1536 1537 } 1538 1539 // Return whatever we have found for labels 1540 return this.pushStack( labels ); 1541}; 1542 1543 1544/*! 1545 * jQuery UI Scroll Parent 1.12.1 1546 * http://jqueryui.com 1547 * 1548 * Copyright jQuery Foundation and other contributors 1549 * Released under the MIT license. 1550 * http://jquery.org/license 1551 */ 1552 1553//>>label: scrollParent 1554//>>group: Core 1555//>>description: Get the closest ancestor element that is scrollable. 1556//>>docs: http://api.jqueryui.com/scrollParent/ 1557 1558 1559 1560var scrollParent = $.fn.scrollParent = function( includeHidden ) { 1561 var position = this.css( "position" ), 1562 excludeStaticParent = position === "absolute", 1563 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 1564 scrollParent = this.parents().filter( function() { 1565 var parent = $( this ); 1566 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 1567 return false; 1568 } 1569 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 1570 parent.css( "overflow-x" ) ); 1571 } ).eq( 0 ); 1572 1573 return position === "fixed" || !scrollParent.length ? 1574 $( this[ 0 ].ownerDocument || document ) : 1575 scrollParent; 1576}; 1577 1578 1579/*! 1580 * jQuery UI Tabbable 1.12.1 1581 * http://jqueryui.com 1582 * 1583 * Copyright jQuery Foundation and other contributors 1584 * Released under the MIT license. 1585 * http://jquery.org/license 1586 */ 1587 1588//>>label: :tabbable Selector 1589//>>group: Core 1590//>>description: Selects elements which can be tabbed to. 1591//>>docs: http://api.jqueryui.com/tabbable-selector/ 1592 1593 1594 1595var tabbable = $.extend( $.expr[ ":" ]
vendor: 47,374 bytes, lines 1595-3329
1595, { 1596 tabbable: function( element ) { 1597 var tabIndex = $.attr( element, "tabindex" ), 1598 hasTabindex = tabIndex != null; 1599 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 1600 } 1601} ); 1602 1603 1604/*! 1605 * jQuery UI Unique ID 1.12.1 1606 * http://jqueryui.com 1607 * 1608 * Copyright jQuery Foundation and other contributors 1609 * Released under the MIT license. 1610 * http://jquery.org/license 1611 */ 1612 1613//>>label: uniqueId 1614//>>group: Core 1615//>>description: Functions to generate and remove uniqueId's 1616//>>docs: http://api.jqueryui.com/uniqueId/ 1617 1618 1619 1620var uniqueId = $.fn.extend( { 1621 uniqueId: ( function() { 1622 var uuid = 0; 1623 1624 return function() { 1625 return this.each( function() { 1626 if ( !this.id ) { 1627 this.id = "ui-id-" + ( ++uuid ); 1628 } 1629 } ); 1630 }; 1631 } )(), 1632 1633 removeUniqueId: function() { 1634 return this.each( function() { 1635 if ( /^ui-id-\d+$/.test( this.id ) ) { 1636 $( this ).removeAttr( "id" ); 1637 } 1638 } ); 1639 } 1640} ); 1641 1642 1643 1644 1645// This file is deprecated 1646var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 1647 1648/*! 1649 * jQuery UI Mouse 1.12.1 1650 * http://jqueryui.com 1651 * 1652 * Copyright jQuery Foundation and other contributors 1653 * Released under the MIT license. 1654 * http://jquery.org/license 1655 */ 1656 1657//>>label: Mouse 1658//>>group: Widgets 1659//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 1660//>>docs: http://api.jqueryui.com/mouse/ 1661 1662 1663 1664var mouseHandled = false; 1665$( document ).on( "mouseup", function() { 1666 mouseHandled = false; 1667} ); 1668 1669var widgetsMouse = $.widget( "ui.mouse", { 1670 version: "1.12.1", 1671 options: { 1672 cancel: "input, textarea, button, select, option", 1673 distance: 1, 1674 delay: 0 1675 }, 1676 _mouseInit: function() { 1677 var that = this; 1678 1679 this.element 1680 .on( "mousedown." + this.widgetName, function( event ) { 1681 return that._mouseDown( event ); 1682 } ) 1683 .on( "click." + this.widgetName, function( event ) { 1684 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 1685 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 1686 event.stopImmediatePropagation(); 1687 return false; 1688 } 1689 } ); 1690 1691 this.started = false; 1692 }, 1693 1694 // TODO: make sure destroying one instance of mouse doesn't mess with 1695 // other instances of mouse 1696 _mouseDestroy: function() { 1697 this.element.off( "." + this.widgetName ); 1698 if ( this._mouseMoveDelegate ) { 1699 this.document 1700 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1701 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1702 } 1703 }, 1704 1705 _mouseDown: function( event ) { 1706 1707 // don't let more than one widget handle mouseStart 1708 if ( mouseHandled ) { 1709 return; 1710 } 1711 1712 this._mouseMoved = false; 1713 1714 // We may have missed mouseup (out of window) 1715 ( this._mouseStarted && this._mouseUp( event ) ); 1716 1717 this._mouseDownEvent = event; 1718 1719 var that = this, 1720 btnIsLeft = ( event.which === 1 ), 1721 1722 // event.target.nodeName works around a bug in IE 8 with 1723 // disabled inputs (#7620) 1724 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 1725 $( event.target ).closest( this.options.cancel ).length : false ); 1726 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 1727 return true; 1728 } 1729 1730 this.mouseDelayMet = !this.options.delay; 1731 if ( !this.mouseDelayMet ) { 1732 this._mouseDelayTimer = setTimeout( function() { 1733 that.mouseDelayMet = true; 1734 }, this.options.delay ); 1735 } 1736 1737 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1738 this._mouseStarted = ( this._mouseStart( event ) !== false ); 1739 if ( !this._mouseStarted ) { 1740 event.preventDefault(); 1741 return true; 1742 } 1743 } 1744 1745 // Click event may never have fired (Gecko & Opera) 1746 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 1747 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 1748 } 1749 1750 // These delegates are required to keep context 1751 this._mouseMoveDelegate = function( event ) { 1752 return that._mouseMove( event ); 1753 }; 1754 this._mouseUpDelegate = function( event ) { 1755 return that._mouseUp( event ); 1756 }; 1757 1758 this.document 1759 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1760 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1761 1762 event.preventDefault(); 1763 1764 mouseHandled = true; 1765 return true; 1766 }, 1767 1768 _mouseMove: function( event ) { 1769 1770 // Only check for mouseups outside the document if you've moved inside the document 1771 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 1772 // fire a mousemove event if content is placed under the cursor. See #7778 1773 // Support: IE <9 1774 if ( this._mouseMoved ) { 1775 1776 // IE mouseup check - mouseup happened when mouse was out of window 1777 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 1778 !event.button ) { 1779 return this._mouseUp( event ); 1780 1781 // Iframe mouseup check - mouseup occurred in another document 1782 } else if ( !event.which ) { 1783 1784 // Support: Safari <=8 - 9 1785 // Safari sets which to 0 if you press any of the following keys 1786 // during a drag (#14461) 1787 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 1788 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 1789 this.ignoreMissingWhich = true; 1790 } else if ( !this.ignoreMissingWhich ) { 1791 return this._mouseUp( event ); 1792 } 1793 } 1794 } 1795 1796 if ( event.which || event.button ) { 1797 this._mouseMoved = true; 1798 } 1799 1800 if ( this._mouseStarted ) { 1801 this._mouseDrag( event ); 1802 return event.preventDefault(); 1803 } 1804 1805 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1806 this._mouseStarted = 1807 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 1808 ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); 1809 } 1810 1811 return !this._mouseStarted; 1812 }, 1813 1814 _mouseUp: function( event ) { 1815 this.document 1816 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1817 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1818 1819 if ( this._mouseStarted ) { 1820 this._mouseStarted = false; 1821 1822 if ( event.target === this._mouseDownEvent.target ) { 1823 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 1824 } 1825 1826 this._mouseStop( event ); 1827 } 1828 1829 if ( this._mouseDelayTimer ) { 1830 clearTimeout( this._mouseDelayTimer ); 1831 delete this._mouseDelayTimer; 1832 } 1833 1834 this.ignoreMissingWhich = false; 1835 mouseHandled = false; 1836 event.preventDefault(); 1837 }, 1838 1839 _mouseDistanceMet: function( event ) { 1840 return ( Math.max( 1841 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 1842 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 1843 ) >= this.options.distance 1844 ); 1845 }, 1846 1847 _mouseDelayMet: function( /* event */ ) { 1848 return this.mouseDelayMet; 1849 }, 1850 1851 // These are placeholder methods, to be overriden by extending plugin 1852 _mouseStart: function( /* event */ ) {}, 1853 _mouseDrag: function( /* event */ ) {}, 1854 _mouseStop: function( /* event */ ) {}, 1855 _mouseCapture: function( /* event */ ) { return true; } 1856} ); 1857 1858 1859 1860 1861// $.ui.plugin is deprecated. Use $.widget() extensions instead. 1862var plugin = $.ui.plugin = { 1863 add: function( module, option, set ) { 1864 var i, 1865 proto = $.ui[ module ].prototype; 1866 for ( i in set ) { 1867 proto.plugins[ i ] = proto.plugins[ i ] || []; 1868 proto.plugins[ i ].push( [ option, set[ i ] ] ); 1869 } 1870 }, 1871 call: function( instance, name, args, allowDisconnected ) { 1872 var i, 1873 set = instance.plugins[ name ]; 1874 1875 if ( !set ) { 1876 return; 1877 } 1878 1879 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 1880 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 1881 return; 1882 } 1883 1884 for ( i = 0; i < set.length; i++ ) { 1885 if ( instance.options[ set[ i ][ 0 ] ] ) { 1886 set[ i ][ 1 ].apply( instance.element, args ); 1887 } 1888 } 1889 } 1890}; 1891 1892 1893 1894var safeActiveElement = $.ui.safeActiveElement = function( document ) { 1895 var activeElement; 1896 1897 // Support: IE 9 only 1898 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1899 try { 1900 activeElement = document.activeElement; 1901 } catch ( error ) { 1902 activeElement = document.body; 1903 } 1904 1905 // Support: IE 9 - 11 only 1906 // IE may return null instead of an element 1907 // Interestingly, this only seems to occur when NOT in an iframe 1908 if ( !activeElement ) { 1909 activeElement = document.body; 1910 } 1911 1912 // Support: IE 11 only 1913 // IE11 returns a seemingly empty object in some cases when accessing 1914 // document.activeElement from an <iframe> 1915 if ( !activeElement.nodeName ) { 1916 activeElement = document.body; 1917 } 1918 1919 return activeElement; 1920}; 1921 1922 1923 1924var safeBlur = $.ui.safeBlur = function( element ) { 1925 1926 // Support: IE9 - 10 only 1927 // If the <body> is blurred, IE will switch windows, see #9420 1928 if ( element && element.nodeName.toLowerCase() !== "body" ) { 1929 $( element ).trigger( "blur" ); 1930 } 1931}; 1932 1933 1934/*! 1935 * jQuery UI Draggable 1.12.1 1936 * http://jqueryui.com 1937 * 1938 * Copyright jQuery Foundation and other contributors 1939 * Released under the MIT license. 1940 * http://jquery.org/license 1941 */ 1942 1943//>>label: Draggable 1944//>>group: Interactions 1945//>>description: Enables dragging functionality for any element. 1946//>>docs: http://api.jqueryui.com/draggable/ 1947//>>demos: http://jqueryui.com/draggable/ 1948//>>css.structure: ../../themes/base/draggable.css 1949 1950 1951 1952$.widget( "ui.draggable", $.ui.mouse, { 1953 version: "1.12.1", 1954 widgetEventPrefix: "drag", 1955 options: { 1956 addClasses: true, 1957 appendTo: "parent", 1958 axis: false, 1959 connectToSortable: false, 1960 containment: false, 1961 cursor: "auto", 1962 cursorAt: false, 1963 grid: false, 1964 handle: false, 1965 helper: "original", 1966 iframeFix: false, 1967 opacity: false, 1968 refreshPositions: false, 1969 revert: false, 1970 revertDuration: 500, 1971 scope: "default", 1972 scroll: true, 1973 scrollSensitivity: 20, 1974 scrollSpeed: 20, 1975 snap: false, 1976 snapMode: "both", 1977 snapTolerance: 20, 1978 stack: false, 1979 zIndex: false, 1980 1981 // Callbacks 1982 drag: null, 1983 start: null, 1984 stop: null 1985 }, 1986 _create: function() { 1987 1988 if ( this.options.helper === "original" ) { 1989 this._setPositionRelative(); 1990 } 1991 if ( this.options.addClasses ) { 1992 this._addClass( "ui-draggable" ); 1993 } 1994 this._setHandleClassName(); 1995 1996 this._mouseInit(); 1997 }, 1998 1999 _setOption: function( key, value ) { 2000 this._super( key, value ); 2001 if ( key === "handle" ) { 2002 this._removeHandleClassName(); 2003 this._setHandleClassName(); 2004 } 2005 }, 2006 2007 _destroy: function() { 2008 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 2009 this.destroyOnClear = true; 2010 return; 2011 } 2012 this._removeHandleClassName(); 2013 this._mouseDestroy(); 2014 }, 2015 2016 _mouseCapture: function( event ) { 2017 var o = this.options; 2018 2019 // Among others, prevent a drag on a resizable-handle 2020 if ( this.helper || o.disabled || 2021 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 2022 return false; 2023 } 2024 2025 //Quit if we're not on a valid handle 2026 this.handle = this._getHandle( event ); 2027 if ( !this.handle ) { 2028 return false; 2029 } 2030 2031 this._blurActiveElement( event ); 2032 2033 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 2034 2035 return true; 2036 2037 }, 2038 2039 _blockFrames: function( selector ) { 2040 this.iframeBlocks = this.document.find( selector ).map( function() { 2041 var iframe = $( this ); 2042 2043 return $( "<div>" ) 2044 .css( "position", "absolute" ) 2045 .appendTo( iframe.parent() ) 2046 .outerWidth( iframe.outerWidth() ) 2047 .outerHeight( iframe.outerHeight() ) 2048 .offset( iframe.offset() )[ 0 ]; 2049 } ); 2050 }, 2051 2052 _unblockFrames: function() { 2053 if ( this.iframeBlocks ) { 2054 this.iframeBlocks.remove(); 2055 delete this.iframeBlocks; 2056 } 2057 }, 2058 2059 _blurActiveElement: function( event ) { 2060 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 2061 target = $( event.target ); 2062 2063 // Don't blur if the event occurred on an element that is within 2064 // the currently focused element 2065 // See #10527, #12472 2066 if ( target.closest( activeElement ).length ) { 2067 return; 2068 } 2069 2070 // Blur any element that currently has focus, see #4261 2071 $.ui.safeBlur( activeElement ); 2072 }, 2073 2074 _mouseStart: function( event ) { 2075 2076 var o = this.options; 2077 2078 //Create and append the visible helper 2079 this.helper = this._createHelper( event ); 2080 2081 this._addClass( this.helper, "ui-draggable-dragging" ); 2082 2083 //Cache the helper size 2084 this._cacheHelperProportions(); 2085 2086 //If ddmanager is used for droppables, set the global draggable 2087 if ( $.ui.ddmanager ) { 2088 $.ui.ddmanager.current = this; 2089 } 2090 2091 /* 2092 * - Position generation - 2093 * This block generates everything position related - it's the core of draggables. 2094 */ 2095 2096 //Cache the margins of the original element 2097 this._cacheMargins(); 2098 2099 //Store the helper's css position 2100 this.cssPosition = this.helper.css( "position" ); 2101 this.scrollParent = this.helper.scrollParent( true ); 2102 this.offsetParent = this.helper.offsetParent(); 2103 this.hasFixedAncestor = this.helper.parents().filter( function() { 2104 return $( this ).css( "position" ) === "fixed"; 2105 } ).length > 0; 2106 2107 //The element's absolute position on the page minus margins 2108 this.positionAbs = this.element.offset(); 2109 this._refreshOffsets( event ); 2110 2111 //Generate the original position 2112 this.originalPosition = this.position = this._generatePosition( event, false ); 2113 this.originalPageX = event.pageX; 2114 this.originalPageY = event.pageY; 2115 2116 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 2117 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); 2118 2119 //Set a containment if given in the options 2120 this._setContainment(); 2121 2122 //Trigger event + callbacks 2123 if ( this._trigger( "start", event ) === false ) { 2124 this._clear(); 2125 return false; 2126 } 2127 2128 //Recache the helper size 2129 this._cacheHelperProportions(); 2130 2131 //Prepare the droppable offsets 2132 if ( $.ui.ddmanager && !o.dropBehaviour ) { 2133 $.ui.ddmanager.prepareOffsets( this, event ); 2134 } 2135 2136 // Execute the drag once - this causes the helper not to be visible before getting its 2137 // correct position 2138 this._mouseDrag( event, true ); 2139 2140 // If the ddmanager is used for droppables, inform the manager that dragging has started 2141 // (see #5003) 2142 if ( $.ui.ddmanager ) { 2143 $.ui.ddmanager.dragStart( this, event ); 2144 } 2145 2146 return true; 2147 }, 2148 2149 _refreshOffsets: function( event ) { 2150 this.offset = { 2151 top: this.positionAbs.top - this.margins.top, 2152 left: this.positionAbs.left - this.margins.left, 2153 scroll: false, 2154 parent: this._getParentOffset(), 2155 relative: this._getRelativeOffset() 2156 }; 2157 2158 this.offset.click = { 2159 left: event.pageX - this.offset.left, 2160 top: event.pageY - this.offset.top 2161 }; 2162 }, 2163 2164 _mouseDrag: function( event, noPropagation ) { 2165 2166 // reset any necessary cached properties (see #5009) 2167 if ( this.hasFixedAncestor ) { 2168 this.offset.parent = this._getParentOffset(); 2169 } 2170 2171 //Compute the helpers position 2172 this.position = this._generatePosition( event, true ); 2173 this.positionAbs = this._convertPositionTo( "absolute" ); 2174 2175 //Call plugins and callbacks and use the resulting position if something is returned 2176 if ( !noPropagation ) { 2177 var ui = this._uiHash(); 2178 if ( this._trigger( "drag", event, ui ) === false ) { 2179 this._mouseUp( new $.Event( "mouseup", event ) ); 2180 return false; 2181 } 2182 this.position = ui.position; 2183 } 2184 2185 this.helper[ 0 ].style.left = this.position.left + "px"; 2186 this.helper[ 0 ].style.top = this.position.top + "px"; 2187 2188 if ( $.ui.ddmanager ) { 2189 $.ui.ddmanager.drag( this, event ); 2190 } 2191 2192 return false; 2193 }, 2194 2195 _mouseStop: function( event ) { 2196 2197 //If we are using droppables, inform the manager about the drop 2198 var that = this, 2199 dropped = false; 2200 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 2201 dropped = $.ui.ddmanager.drop( this, event ); 2202 } 2203 2204 //if a drop comes from outside (a sortable) 2205 if ( this.dropped ) { 2206 dropped = this.dropped; 2207 this.dropped = false; 2208 } 2209 2210 if ( ( this.options.revert === "invalid" && !dropped ) || 2211 ( this.options.revert === "valid" && dropped ) || 2212 this.options.revert === true || ( $.isFunction( this.options.revert ) && 2213 this.options.revert.call( this.element, dropped ) ) 2214 ) { 2215 $( this.helper ).animate( 2216 this.originalPosition, 2217 parseInt( this.options.revertDuration, 10 ), 2218 function() { 2219 if ( that._trigger( "stop", event ) !== false ) { 2220 that._clear(); 2221 } 2222 } 2223 ); 2224 } else { 2225 if ( this._trigger( "stop", event ) !== false ) { 2226 this._clear(); 2227 } 2228 } 2229 2230 return false; 2231 }, 2232 2233 _mouseUp: function( event ) { 2234 this._unblockFrames(); 2235 2236 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 2237 // (see #5003) 2238 if ( $.ui.ddmanager ) { 2239 $.ui.ddmanager.dragStop( this, event ); 2240 } 2241 2242 // Only need to focus if the event occurred on the draggable itself, see #10527 2243 if ( this.handleElement.is( event.target ) ) { 2244 2245 // The interaction is over; whether or not the click resulted in a drag, 2246 // focus the element 2247 this.element.trigger( "focus" ); 2248 } 2249 2250 return $.ui.mouse.prototype._mouseUp.call( this, event ); 2251 }, 2252 2253 cancel: function() { 2254 2255 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 2256 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 2257 } else { 2258 this._clear(); 2259 } 2260 2261 return this; 2262 2263 }, 2264 2265 _getHandle: function( event ) { 2266 return this.options.handle ? 2267 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 2268 true; 2269 }, 2270 2271 _setHandleClassName: function() { 2272 this.handleElement = this.options.handle ? 2273 this.element.find( this.options.handle ) : this.element; 2274 this._addClass( this.handleElement, "ui-draggable-handle" ); 2275 }, 2276 2277 _removeHandleClassName: function() { 2278 this._removeClass( this.handleElement, "ui-draggable-handle" ); 2279 }, 2280 2281 _createHelper: function( event ) { 2282 2283 var o = this.options, 2284 helperIsFunction = $.isFunction( o.helper ), 2285 helper = helperIsFunction ? 2286 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 2287 ( o.helper === "clone" ? 2288 this.element.clone().removeAttr( "id" ) : 2289 this.element ); 2290 2291 if ( !helper.parents( "body" ).length ) { 2292 helper.appendTo( ( o.appendTo === "parent" ? 2293 this.element[ 0 ].parentNode : 2294 o.appendTo ) ); 2295 } 2296 2297 // Http://bugs.jqueryui.com/ticket/9446 2298 // a helper function can return the original element 2299 // which wouldn't have been set to relative in _create 2300 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 2301 this._setPositionRelative(); 2302 } 2303 2304 if ( helper[ 0 ] !== this.element[ 0 ] && 2305 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 2306 helper.css( "position", "absolute" ); 2307 } 2308 2309 return helper; 2310 2311 }, 2312 2313 _setPositionRelative: function() { 2314 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 2315 this.element[ 0 ].style.position = "relative"; 2316 } 2317 }, 2318 2319 _adjustOffsetFromHelper: function( obj ) { 2320 if ( typeof obj === "string" ) { 2321 obj = obj.split( " " ); 2322 } 2323 if ( $.isArray( obj ) ) { 2324 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 2325 } 2326 if ( "left" in obj ) { 2327 this.offset.click.left = obj.left + this.margins.left; 2328 } 2329 if ( "right" in obj ) { 2330 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 2331 } 2332 if ( "top" in obj ) { 2333 this.offset.click.top = obj.top + this.margins.top; 2334 } 2335 if ( "bottom" in obj ) { 2336 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 2337 } 2338 }, 2339 2340 _isRootNode: function( element ) { 2341 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 2342 }, 2343 2344 _getParentOffset: function() { 2345 2346 //Get the offsetParent and cache its position 2347 var po = this.offsetParent.offset(), 2348 document = this.document[ 0 ]; 2349 2350 // This is a special case where we need to modify a offset calculated on start, since the 2351 // following happened: 2352 // 1. The position of the helper is absolute, so it's position is calculated based on the 2353 // next positioned parent 2354 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 2355 // the document, which means that the scroll is included in the initial calculation of the 2356 // offset of the parent, and never recalculated upon drag 2357 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 2358 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 2359 po.left += this.scrollParent.scrollLeft(); 2360 po.top += this.scrollParent.scrollTop(); 2361 } 2362 2363 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 2364 po = { top: 0, left: 0 }; 2365 } 2366 2367 return { 2368 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 2369 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 2370 }; 2371 2372 }, 2373 2374 _getRelativeOffset: function() { 2375 if ( this.cssPosition !== "relative" ) { 2376 return { top: 0, left: 0 }; 2377 } 2378 2379 var p = this.element.position(), 2380 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2381 2382 return { 2383 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 2384 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 2385 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 2386 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 2387 }; 2388 2389 }, 2390 2391 _cacheMargins: function() { 2392 this.margins = { 2393 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 2394 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 2395 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 2396 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 2397 }; 2398 }, 2399 2400 _cacheHelperProportions: function() { 2401 this.helperProportions = { 2402 width: this.helper.outerWidth(), 2403 height: this.helper.outerHeight() 2404 }; 2405 }, 2406 2407 _setContainment: function() { 2408 2409 var isUserScrollable, c, ce, 2410 o = this.options, 2411 document = this.document[ 0 ]; 2412 2413 this.relativeContainer = null; 2414 2415 if ( !o.containment ) { 2416 this.containment = null; 2417 return; 2418 } 2419 2420 if ( o.containment === "window" ) { 2421 this.containment = [ 2422 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 2423 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 2424 $( window ).scrollLeft() + $( window ).width() - 2425 this.helperProportions.width - this.margins.left, 2426 $( window ).scrollTop() + 2427 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 2428 this.helperProportions.height - this.margins.top 2429 ]; 2430 return; 2431 } 2432 2433 if ( o.containment === "document" ) { 2434 this.containment = [ 2435 0, 2436 0, 2437 $( document ).width() - this.helperProportions.width - this.margins.left, 2438 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 2439 this.helperProportions.height - this.margins.top 2440 ]; 2441 return; 2442 } 2443 2444 if ( o.containment.constructor === Array ) { 2445 this.containment = o.containment; 2446 return; 2447 } 2448 2449 if ( o.containment === "parent" ) { 2450 o.containment = this.helper[ 0 ].parentNode; 2451 } 2452 2453 c = $( o.containment ); 2454 ce = c[ 0 ]; 2455 2456 if ( !ce ) { 2457 return; 2458 } 2459 2460 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 2461 2462 this.containment = [ 2463 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 2464 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 2465 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 2466 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 2467 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 2468 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 2469 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 2470 this.helperProportions.width - 2471 this.margins.left - 2472 this.margins.right, 2473 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 2474 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 2475 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 2476 this.helperProportions.height - 2477 this.margins.top - 2478 this.margins.bottom 2479 ]; 2480 this.relativeContainer = c; 2481 }, 2482 2483 _convertPositionTo: function( d, pos ) { 2484 2485 if ( !pos ) { 2486 pos = this.position; 2487 } 2488 2489 var mod = d === "absolute" ? 1 : -1, 2490 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2491 2492 return { 2493 top: ( 2494 2495 // The absolute mouse position 2496 pos.top + 2497 2498 // Only for relative positioned nodes: Relative offset from element to offset parent 2499 this.offset.relative.top * mod + 2500 2501 // The offsetParent's offset without borders (offset + border) 2502 this.offset.parent.top * mod - 2503 ( ( this.cssPosition === "fixed" ? 2504 -this.offset.scroll.top : 2505 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 2506 ), 2507 left: ( 2508 2509 // The absolute mouse position 2510 pos.left + 2511 2512 // Only for relative positioned nodes: Relative offset from element to offset parent 2513 this.offset.relative.left * mod + 2514 2515 // The offsetParent's offset without borders (offset + border) 2516 this.offset.parent.left * mod - 2517 ( ( this.cssPosition === "fixed" ? 2518 -this.offset.scroll.left : 2519 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 2520 ) 2521 }; 2522 2523 }, 2524 2525 _generatePosition: function( event, constrainPosition ) { 2526 2527 var containment, co, top, left, 2528 o = this.options, 2529 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2530 pageX = event.pageX, 2531 pageY = event.pageY; 2532 2533 // Cache the scroll 2534 if ( !scrollIsRootNode || !this.offset.scroll ) { 2535 this.offset.scroll = { 2536 top: this.scrollParent.scrollTop(), 2537 left: this.scrollParent.scrollLeft() 2538 }; 2539 } 2540 2541 /* 2542 * - Position constraining - 2543 * Constrain the position to a mix of grid, containment. 2544 */ 2545 2546 // If we are not dragging yet, we won't check for options 2547 if ( constrainPosition ) { 2548 if ( this.containment ) { 2549 if ( this.relativeContainer ) { 2550 co = this.relativeContainer.offset(); 2551 containment = [ 2552 this.containment[ 0 ] + co.left, 2553 this.containment[ 1 ] + co.top, 2554 this.containment[ 2 ] + co.left, 2555 this.containment[ 3 ] + co.top 2556 ]; 2557 } else { 2558 containment = this.containment; 2559 } 2560 2561 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 2562 pageX = containment[ 0 ] + this.offset.click.left; 2563 } 2564 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 2565 pageY = containment[ 1 ] + this.offset.click.top; 2566 } 2567 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 2568 pageX = containment[ 2 ] + this.offset.click.left; 2569 } 2570 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 2571 pageY = containment[ 3 ] + this.offset.click.top; 2572 } 2573 } 2574 2575 if ( o.grid ) { 2576 2577 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 2578 // argument errors in IE (see ticket #6950) 2579 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 2580 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 2581 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 2582 top - this.offset.click.top > containment[ 3 ] ) ? 2583 top : 2584 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 2585 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 2586 2587 left = o.grid[ 0 ] ? this.originalPageX + 2588 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 2589 this.originalPageX; 2590 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 2591 left - this.offset.click.left > containment[ 2 ] ) ? 2592 left : 2593 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 2594 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 2595 } 2596 2597 if ( o.axis === "y" ) { 2598 pageX = this.originalPageX; 2599 } 2600 2601 if ( o.axis === "x" ) { 2602 pageY = this.originalPageY; 2603 } 2604 } 2605 2606 return { 2607 top: ( 2608 2609 // The absolute mouse position 2610 pageY - 2611 2612 // Click offset (relative to the element) 2613 this.offset.click.top - 2614 2615 // Only for relative positioned nodes: Relative offset from element to offset parent 2616 this.offset.relative.top - 2617 2618 // The offsetParent's offset without borders (offset + border) 2619 this.offset.parent.top + 2620 ( this.cssPosition === "fixed" ? 2621 -this.offset.scroll.top : 2622 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2623 ), 2624 left: ( 2625 2626 // The absolute mouse position 2627 pageX - 2628 2629 // Click offset (relative to the element) 2630 this.offset.click.left - 2631 2632 // Only for relative positioned nodes: Relative offset from element to offset parent 2633 this.offset.relative.left - 2634 2635 // The offsetParent's offset without borders (offset + border) 2636 this.offset.parent.left + 2637 ( this.cssPosition === "fixed" ? 2638 -this.offset.scroll.left : 2639 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2640 ) 2641 }; 2642 2643 }, 2644 2645 _clear: function() { 2646 this._removeClass( this.helper, "ui-draggable-dragging" ); 2647 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 2648 this.helper.remove(); 2649 } 2650 this.helper = null; 2651 this.cancelHelperRemoval = false; 2652 if ( this.destroyOnClear ) { 2653 this.destroy(); 2654 } 2655 }, 2656 2657 // From now on bulk stuff - mainly helpers 2658 2659 _trigger: function( type, event, ui ) { 2660 ui = ui || this._uiHash(); 2661 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2662 2663 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 2664 if ( /^(drag|start|stop)/.test( type ) ) { 2665 this.positionAbs = this._convertPositionTo( "absolute" ); 2666 ui.offset = this.positionAbs; 2667 } 2668 return $.Widget.prototype._trigger.call( this, type, event, ui ); 2669 }, 2670 2671 plugins: {}, 2672 2673 _uiHash: function() { 2674 return { 2675 helper: this.helper, 2676 position: this.position, 2677 originalPosition: this.originalPosition, 2678 offset: this.positionAbs 2679 }; 2680 } 2681 2682} ); 2683 2684$.ui.plugin.add( "draggable", "connectToSortable", { 2685 start: function( event, ui, draggable ) { 2686 var uiSortable = $.extend( {}, ui, { 2687 item: draggable.element 2688 } ); 2689 2690 draggable.sortables = []; 2691 $( draggable.options.connectToSortable ).each( function() { 2692 var sortable = $( this ).sortable( "instance" ); 2693 2694 if ( sortable && !sortable.options.disabled ) { 2695 draggable.sortables.push( sortable ); 2696 2697 // RefreshPositions is called at drag start to refresh the containerCache 2698 // which is used in drag. This ensures it's initialized and synchronized 2699 // with any changes that might have happened on the page since initialization. 2700 sortable.refreshPositions(); 2701 sortable._trigger( "activate", event, uiSortable ); 2702 } 2703 } ); 2704 }, 2705 stop: function( event, ui, draggable ) { 2706 var uiSortable = $.extend( {}, ui, { 2707 item: draggable.element 2708 } ); 2709 2710 draggable.cancelHelperRemoval = false; 2711 2712 $.each( draggable.sortables, function() { 2713 var sortable = this; 2714 2715 if ( sortable.isOver ) { 2716 sortable.isOver = 0; 2717 2718 // Allow this sortable to handle removing the helper 2719 draggable.cancelHelperRemoval = true; 2720 sortable.cancelHelperRemoval = false; 2721 2722 // Use _storedCSS To restore properties in the sortable, 2723 // as this also handles revert (#9675) since the draggable 2724 // may have modified them in unexpected ways (#8809) 2725 sortable._storedCSS = { 2726 position: sortable.placeholder.css( "position" ), 2727 top: sortable.placeholder.css( "top" ), 2728 left: sortable.placeholder.css( "left" ) 2729 }; 2730 2731 sortable._mouseStop( event ); 2732 2733 // Once drag has ended, the sortable should return to using 2734 // its original helper, not the shared helper from draggable 2735 sortable.options.helper = sortable.options._helper; 2736 } else { 2737 2738 // Prevent this Sortable from removing the helper. 2739 // However, don't set the draggable to remove the helper 2740 // either as another connected Sortable may yet handle the removal. 2741 sortable.cancelHelperRemoval = true; 2742 2743 sortable._trigger( "deactivate", event, uiSortable ); 2744 } 2745 } ); 2746 }, 2747 drag: function( event, ui, draggable ) { 2748 $.each( draggable.sortables, function() { 2749 var innermostIntersecting = false, 2750 sortable = this; 2751 2752 // Copy over variables that sortable's _intersectsWith uses 2753 sortable.positionAbs = draggable.positionAbs; 2754 sortable.helperProportions = draggable.helperProportions; 2755 sortable.offset.click = draggable.offset.click; 2756 2757 if ( sortable._intersectsWith( sortable.containerCache ) ) { 2758 innermostIntersecting = true; 2759 2760 $.each( draggable.sortables, function() { 2761 2762 // Copy over variables that sortable's _intersectsWith uses 2763 this.positionAbs = draggable.positionAbs; 2764 this.helperProportions = draggable.helperProportions; 2765 this.offset.click = draggable.offset.click; 2766 2767 if ( this !== sortable && 2768 this._intersectsWith( this.containerCache ) && 2769 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 2770 innermostIntersecting = false; 2771 } 2772 2773 return innermostIntersecting; 2774 } ); 2775 } 2776 2777 if ( innermostIntersecting ) { 2778 2779 // If it intersects, we use a little isOver variable and set it once, 2780 // so that the move-in stuff gets fired only once. 2781 if ( !sortable.isOver ) { 2782 sortable.isOver = 1; 2783 2784 // Store draggable's parent in case we need to reappend to it later. 2785 draggable._parent = ui.helper.parent(); 2786 2787 sortable.currentItem = ui.helper 2788 .appendTo( sortable.element ) 2789 .data( "ui-sortable-item", true ); 2790 2791 // Store helper option to later restore it 2792 sortable.options._helper = sortable.options.helper; 2793 2794 sortable.options.helper = function() { 2795 return ui.helper[ 0 ]; 2796 }; 2797 2798 // Fire the start events of the sortable with our passed browser event, 2799 // and our own helper (so it doesn't create a new one) 2800 event.target = sortable.currentItem[ 0 ]; 2801 sortable._mouseCapture( event, true ); 2802 sortable._mouseStart( event, true, true ); 2803 2804 // Because the browser event is way off the new appended portlet, 2805 // modify necessary variables to reflect the changes 2806 sortable.offset.click.top = draggable.offset.click.top; 2807 sortable.offset.click.left = draggable.offset.click.left; 2808 sortable.offset.parent.left -= draggable.offset.parent.left - 2809 sortable.offset.parent.left; 2810 sortable.offset.parent.top -= draggable.offset.parent.top - 2811 sortable.offset.parent.top; 2812 2813 draggable._trigger( "toSortable", event ); 2814 2815 // Inform draggable that the helper is in a valid drop zone, 2816 // used solely in the revert option to handle "valid/invalid". 2817 draggable.dropped = sortable.element; 2818 2819 // Need to refreshPositions of all sortables in the case that 2820 // adding to one sortable changes the location of the other sortables (#9675) 2821 $.each( draggable.sortables, function() { 2822 this.refreshPositions(); 2823 } ); 2824 2825 // Hack so receive/update callbacks work (mostly) 2826 draggable.currentItem = draggable.element; 2827 sortable.fromOutside = draggable; 2828 } 2829 2830 if ( sortable.currentItem ) { 2831 sortable._mouseDrag( event ); 2832 2833 // Copy the sortable's position because the draggable's can potentially reflect 2834 // a relative position, while sortable is always absolute, which the dragged 2835 // element has now become. (#8809) 2836 ui.position = sortable.position; 2837 } 2838 } else { 2839 2840 // If it doesn't intersect with the sortable, and it intersected before, 2841 // we fake the drag stop of the sortable, but make sure it doesn't remove 2842 // the helper by using cancelHelperRemoval. 2843 if ( sortable.isOver ) { 2844 2845 sortable.isOver = 0; 2846 sortable.cancelHelperRemoval = true; 2847 2848 // Calling sortable's mouseStop would trigger a revert, 2849 // so revert must be temporarily false until after mouseStop is called. 2850 sortable.options._revert = sortable.options.revert; 2851 sortable.options.revert = false; 2852 2853 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 2854 sortable._mouseStop( event, true ); 2855 2856 // Restore sortable behaviors that were modfied 2857 // when the draggable entered the sortable area (#9481) 2858 sortable.options.revert = sortable.options._revert; 2859 sortable.options.helper = sortable.options._helper; 2860 2861 if ( sortable.placeholder ) { 2862 sortable.placeholder.remove(); 2863 } 2864 2865 // Restore and recalculate the draggable's offset considering the sortable 2866 // may have modified them in unexpected ways. (#8809, #10669) 2867 ui.helper.appendTo( draggable._parent ); 2868 draggable._refreshOffsets( event ); 2869 ui.position = draggable._generatePosition( event, true ); 2870 2871 draggable._trigger( "fromSortable", event ); 2872 2873 // Inform draggable that the helper is no longer in a valid drop zone 2874 draggable.dropped = false; 2875 2876 // Need to refreshPositions of all sortables just in case removing 2877 // from one sortable changes the location of other sortables (#9675) 2878 $.each( draggable.sortables, function() { 2879 this.refreshPositions(); 2880 } ); 2881 } 2882 } 2883 } ); 2884 } 2885} ); 2886 2887$.ui.plugin.add( "draggable", "cursor", { 2888 start: function( event, ui, instance ) { 2889 var t = $( "body" ), 2890 o = instance.options; 2891 2892 if ( t.css( "cursor" ) ) { 2893 o._cursor = t.css( "cursor" ); 2894 } 2895 t.css( "cursor", o.cursor ); 2896 }, 2897 stop: function( event, ui, instance ) { 2898 var o = instance.options; 2899 if ( o._cursor ) { 2900 $( "body" ).css( "cursor", o._cursor ); 2901 } 2902 } 2903} ); 2904 2905$.ui.plugin.add( "draggable", "opacity", { 2906 start: function( event, ui, instance ) { 2907 var t = $( ui.helper ), 2908 o = instance.options; 2909 if ( t.css( "opacity" ) ) { 2910 o._opacity = t.css( "opacity" ); 2911 } 2912 t.css( "opacity", o.opacity ); 2913 }, 2914 stop: function( event, ui, instance ) { 2915 var o = instance.options; 2916 if ( o._opacity ) { 2917 $( ui.helper ).css( "opacity", o._opacity ); 2918 } 2919 } 2920} ); 2921 2922$.ui.plugin.add( "draggable", "scroll", { 2923 start: function( event, ui, i ) { 2924 if ( !i.scrollParentNotHidden ) { 2925 i.scrollParentNotHidden = i.helper.scrollParent( false ); 2926 } 2927 2928 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 2929 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 2930 i.overflowOffset = i.scrollParentNotHidden.offset(); 2931 } 2932 }, 2933 drag: function( event, ui, i ) { 2934 2935 var o = i.options, 2936 scrolled = false, 2937 scrollParent = i.scrollParentNotHidden[ 0 ], 2938 document = i.document[ 0 ]; 2939 2940 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 2941 if ( !o.axis || o.axis !== "x" ) { 2942 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 2943 o.scrollSensitivity ) { 2944 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 2945 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 2946 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 2947 } 2948 } 2949 2950 if ( !o.axis || o.axis !== "y" ) { 2951 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 2952 o.scrollSensitivity ) { 2953 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 2954 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 2955 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 2956 } 2957 } 2958 2959 } else { 2960 2961 if ( !o.axis || o.axis !== "x" ) { 2962 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 2963 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 2964 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 2965 o.scrollSensitivity ) { 2966 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 2967 } 2968 } 2969 2970 if ( !o.axis || o.axis !== "y" ) { 2971 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 2972 scrolled = $( document ).scrollLeft( 2973 $( document ).scrollLeft() - o.scrollSpeed 2974 ); 2975 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 2976 o.scrollSensitivity ) { 2977 scrolled = $( document ).scrollLeft( 2978 $( document ).scrollLeft() + o.scrollSpeed 2979 ); 2980 } 2981 } 2982 2983 } 2984 2985 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 2986 $.ui.ddmanager.prepareOffsets( i, event ); 2987 } 2988 2989 } 2990} ); 2991 2992$.ui.plugin.add( "draggable", "snap", { 2993 start: function( event, ui, i ) { 2994 2995 var o = i.options; 2996 2997 i.snapElements = []; 2998 2999 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 3000 .each( function() { 3001 var $t = $( this ), 3002 $o = $t.offset(); 3003 if ( this !== i.element[ 0 ] ) { 3004 i.snapElements.push( { 3005 item: this, 3006 width: $t.outerWidth(), height: $t.outerHeight(), 3007 top: $o.top, left: $o.left 3008 } ); 3009 } 3010 } ); 3011 3012 }, 3013 drag: function( event, ui, inst ) { 3014 3015 var ts, bs, ls, rs, l, r, t, b, i, first, 3016 o = inst.options, 3017 d = o.snapTolerance, 3018 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 3019 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 3020 3021 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 3022 3023 l = inst.snapElements[ i ].left - inst.margins.left; 3024 r = l + inst.snapElements[ i ].width; 3025 t = inst.snapElements[ i ].top - inst.margins.top; 3026 b = t + inst.snapElements[ i ].height; 3027 3028 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 3029 !$.contains( inst.snapElements[ i ].item.ownerDocument, 3030 inst.snapElements[ i ].item ) ) { 3031 if ( inst.snapElements[ i ].snapping ) { 3032 ( inst.options.snap.release && 3033 inst.options.snap.release.call( 3034 inst.element, 3035 event, 3036 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 3037 ) ); 3038 } 3039 inst.snapElements[ i ].snapping = false; 3040 continue; 3041 } 3042 3043 if ( o.snapMode !== "inner" ) { 3044 ts = Math.abs( t - y2 ) <= d; 3045 bs = Math.abs( b - y1 ) <= d; 3046 ls = Math.abs( l - x2 ) <= d; 3047 rs = Math.abs( r - x1 ) <= d; 3048 if ( ts ) { 3049 ui.position.top = inst._convertPositionTo( "relative", { 3050 top: t - inst.helperProportions.height, 3051 left: 0 3052 } ).top; 3053 } 3054 if ( bs ) { 3055 ui.position.top = inst._convertPositionTo( "relative", { 3056 top: b, 3057 left: 0 3058 } ).top; 3059 } 3060 if ( ls ) { 3061 ui.position.left = inst._convertPositionTo( "relative", { 3062 top: 0, 3063 left: l - inst.helperProportions.width 3064 } ).left; 3065 } 3066 if ( rs ) { 3067 ui.position.left = inst._convertPositionTo( "relative", { 3068 top: 0, 3069 left: r 3070 } ).left; 3071 } 3072 } 3073 3074 first = ( ts || bs || ls || rs ); 3075 3076 if ( o.snapMode !== "outer" ) { 3077 ts = Math.abs( t - y1 ) <= d; 3078 bs = Math.abs( b - y2 ) <= d; 3079 ls = Math.abs( l - x1 ) <= d; 3080 rs = Math.abs( r - x2 ) <= d; 3081 if ( ts ) { 3082 ui.position.top = inst._convertPositionTo( "relative", { 3083 top: t, 3084 left: 0 3085 } ).top; 3086 } 3087 if ( bs ) { 3088 ui.position.top = inst._convertPositionTo( "relative", { 3089 top: b - inst.helperProportions.height, 3090 left: 0 3091 } ).top; 3092 } 3093 if ( ls ) { 3094 ui.position.left = inst._convertPositionTo( "relative", { 3095 top: 0, 3096 left: l 3097 } ).left; 3098 } 3099 if ( rs ) { 3100 ui.position.left = inst._convertPositionTo( "relative", { 3101 top: 0, 3102 left: r - inst.helperProportions.width 3103 } ).left; 3104 } 3105 } 3106 3107 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 3108 ( inst.options.snap.snap && 3109 inst.options.snap.snap.call( 3110 inst.element, 3111 event, 3112 $.extend( inst._uiHash(), { 3113 snapItem: inst.snapElements[ i ].item 3114 } ) ) ); 3115 } 3116 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 3117 3118 } 3119 3120 } 3121} ); 3122 3123$.ui.plugin.add( "draggable", "stack", { 3124 start: function( event, ui, instance ) { 3125 var min, 3126 o = instance.options, 3127 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 3128 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 3129 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 3130 } ); 3131 3132 if ( !group.length ) { return; } 3133 3134 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 3135 $( group ).each( function( i ) { 3136 $( this ).css( "zIndex", min + i ); 3137 } ); 3138 this.css( "zIndex", ( min + group.length ) ); 3139 } 3140} ); 3141 3142$.ui.plugin.add( "draggable", "zIndex", { 3143 start: function( event, ui, instance ) { 3144 var t = $( ui.helper ), 3145 o = instance.options; 3146 3147 if ( t.css( "zIndex" ) ) { 3148 o._zIndex = t.css( "zIndex" ); 3149 } 3150 t.css( "zIndex", o.zIndex ); 3151 }, 3152 stop: function( event, ui, instance ) { 3153 var o = instance.options; 3154 3155 if ( o._zIndex ) { 3156 $( ui.helper ).css( "zIndex", o._zIndex ); 3157 } 3158 } 3159} ); 3160 3161var widgetsDraggable = $.ui.draggable; 3162 3163 3164/*! 3165 * jQuery UI Droppable 1.12.1 3166 * http://jqueryui.com 3167 * 3168 * Copyright jQuery Foundation and other contributors 3169 * Released under the MIT license. 3170 * http://jquery.org/license 3171 */ 3172 3173//>>label: Droppable 3174//>>group: Interactions 3175//>>description: Enables drop targets for draggable elements. 3176//>>docs: http://api.jqueryui.com/droppable/ 3177//>>demos: http://jqueryui.com/droppable/ 3178 3179 3180 3181$.widget( "ui.droppable", { 3182 version: "1.12.1", 3183 widgetEventPrefix: "drop", 3184 options: { 3185 accept: "*", 3186 addClasses: true, 3187 greedy: false, 3188 scope: "default", 3189 tolerance: "intersect", 3190 3191 // Callbacks 3192 activate: null, 3193 deactivate: null, 3194 drop: null, 3195 out: null, 3196 over: null 3197 }, 3198 _create: function() { 3199 3200 var proportions, 3201 o = this.options, 3202 accept = o.accept; 3203 3204 this.isover = false; 3205 this.isout = true; 3206 3207 this.accept = $.isFunction( accept ) ? accept : function( d ) { 3208 return d.is( accept ); 3209 }; 3210 3211 this.proportions = function( /* valueToWrite */ ) { 3212 if ( arguments.length ) { 3213 3214 // Store the droppable's proportions 3215 proportions = arguments[ 0 ]; 3216 } else { 3217 3218 // Retrieve or derive the droppable's proportions 3219 return proportions ? 3220 proportions : 3221 proportions = { 3222 width: this.element[ 0 ].offsetWidth, 3223 height: this.element[ 0 ].offsetHeight 3224 }; 3225 } 3226 }; 3227 3228 this._addToManager( o.scope ); 3229 3230 o.addClasses && this._addClass( "ui-droppable" ); 3231 3232 }, 3233 3234 _addToManager: function( scope ) { 3235 3236 // Add the reference and positions to the manager 3237 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 3238 $.ui.ddmanager.droppables[ scope ].push( this ); 3239 }, 3240 3241 _splice: function( drop ) { 3242 var i = 0; 3243 for ( ; i < drop.length; i++ ) { 3244 if ( drop[ i ] === this ) { 3245 drop.splice( i, 1 ); 3246 } 3247 } 3248 }, 3249 3250 _destroy: function() { 3251 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3252 3253 this._splice( drop ); 3254 }, 3255 3256 _setOption: function( key, value ) { 3257 3258 if ( key === "accept" ) { 3259 this.accept = $.isFunction( value ) ? value : function( d ) { 3260 return d.is( value ); 3261 }; 3262 } else if ( key === "scope" ) { 3263 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3264 3265 this._splice( drop ); 3266 this._addToManager( value ); 3267 } 3268 3269 this._super( key, value ); 3270 }, 3271 3272 _activate: function( event ) { 3273 var draggable = $.ui.ddmanager.current; 3274 3275 this._addActiveClass(); 3276 if ( draggable ) { 3277 this._trigger( "activate", event, this.ui( draggable ) ); 3278 } 3279 }, 3280 3281 _deactivate: function( event ) { 3282 var draggable = $.ui.ddmanager.current; 3283 3284 this._removeActiveClass(); 3285 if ( draggable ) { 3286 this._trigger( "deactivate", event, this.ui( draggable ) ); 3287 } 3288 }, 3289 3290 _over: function( event ) { 3291 3292 var draggable = $.ui.ddmanager.current; 3293 3294 // Bail if draggable and droppable are same element 3295 if ( !draggable || ( draggable.currentItem || 3296 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3297 return; 3298 } 3299 3300 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3301 draggable.element ) ) ) { 3302 this._addHoverClass(); 3303 this._trigger( "over", event, this.ui( draggable ) ); 3304 } 3305 3306 }, 3307 3308 _out: function( event ) { 3309 3310 var draggable = $.ui.ddmanager.current; 3311 3312 // Bail if draggable and droppable are same element 3313 if ( !draggable || ( draggable.currentItem || 3314 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3315 return; 3316 } 3317 3318 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3319 draggable.element ) ) ) { 3320 this._removeHoverClass(); 3321 this._trigger( "out", event, this.ui( draggable ) ); 3322 } 3323 3324 }, 3325 3326 _drop: function( event, custom ) { 3327 3328 var draggable = custom || $.ui.ddmanager.current, 3329 childrenIntersection = false;
vendor: 4,744 bytes, lines 3330-3502
3330 3331 // Bail if draggable and droppable are same element 3332 if ( !draggable || ( draggable.currentItem || 3333 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3334 return false; 3335 } 3336 3337 this.element 3338 .find( ":data(ui-droppable)" ) 3339 .not( ".ui-draggable-dragging" ) 3340 .each( function() { 3341 var inst = $( this ).droppable( "instance" ); 3342 if ( 3343 inst.options.greedy && 3344 !inst.options.disabled && 3345 inst.options.scope === draggable.options.scope && 3346 inst.accept.call( 3347 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 3348 ) && 3349 intersect( 3350 draggable, 3351 $.extend( inst, { offset: inst.element.offset() } ), 3352 inst.options.tolerance, event 3353 ) 3354 ) { 3355 childrenIntersection = true; 3356 return false; } 3357 } ); 3358 if ( childrenIntersection ) { 3359 return false; 3360 } 3361 3362 if ( this.accept.call( this.element[ 0 ], 3363 ( draggable.currentItem || draggable.element ) ) ) { 3364 this._removeActiveClass(); 3365 this._removeHoverClass(); 3366 3367 this._trigger( "drop", event, this.ui( draggable ) ); 3368 return this.element; 3369 } 3370 3371 return false; 3372 3373 }, 3374 3375 ui: function( c ) { 3376 return { 3377 draggable: ( c.currentItem || c.element ), 3378 helper: c.helper, 3379 position: c.position, 3380 offset: c.positionAbs 3381 }; 3382 }, 3383 3384 // Extension points just to make backcompat sane and avoid duplicating logic 3385 // TODO: Remove in 1.13 along with call to it below 3386 _addHoverClass: function() { 3387 this._addClass( "ui-droppable-hover" ); 3388 }, 3389 3390 _removeHoverClass: function() { 3391 this._removeClass( "ui-droppable-hover" ); 3392 }, 3393 3394 _addActiveClass: function() { 3395 this._addClass( "ui-droppable-active" ); 3396 }, 3397 3398 _removeActiveClass: function() { 3399 this._removeClass( "ui-droppable-active" ); 3400 } 3401} ); 3402 3403var intersect = $.ui.intersect = ( function() { 3404 function isOverAxis( x, reference, size ) { 3405 return ( x >= reference ) && ( x < ( reference + size ) ); 3406 } 3407 3408 return function( draggable, droppable, toleranceMode, event ) { 3409 3410 if ( !droppable.offset ) { 3411 return false; 3412 } 3413 3414 var x1 = ( draggable.positionAbs || 3415 draggable.position.absolute ).left + draggable.margins.left, 3416 y1 = ( draggable.positionAbs || 3417 draggable.position.absolute ).top + draggable.margins.top, 3418 x2 = x1 + draggable.helperProportions.width, 3419 y2 = y1 + draggable.helperProportions.height, 3420 l = droppable.offset.left, 3421 t = droppable.offset.top, 3422 r = l + droppable.proportions().width, 3423 b = t + droppable.proportions().height; 3424 3425 switch ( toleranceMode ) { 3426 case "fit": 3427 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 3428 case "intersect": 3429 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 3430 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 3431 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 3432 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 3433 case "pointer": 3434 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 3435 isOverAxis( event.pageX, l, droppable.proportions().width ); 3436 case "touch": 3437 return ( 3438 ( y1 >= t && y1 <= b ) || // Top edge touching 3439 ( y2 >= t && y2 <= b ) || // Bottom edge touching 3440 ( y1 < t && y2 > b ) // Surrounded vertically 3441 ) && ( 3442 ( x1 >= l && x1 <= r ) || // Left edge touching 3443 ( x2 >= l && x2 <= r ) || // Right edge touching 3444 ( x1 < l && x2 > r ) // Surrounded horizontally 3445 ); 3446 default: 3447 return false; 3448 } 3449 }; 3450} )(); 3451 3452/* 3453 This manager tracks offsets of draggables and droppables 3454*/ 3455$.ui.ddmanager = { 3456 current: null, 3457 droppables: { "default": [] }, 3458 prepareOffsets: function( t, event ) { 3459 3460 var i, j, 3461 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 3462 type = event ? event.type : null, // workaround for #2317 3463 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 3464 3465 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 3466 3467 // No disabled and non-accepted 3468 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 3469 ( t.currentItem || t.element ) ) ) ) { 3470 continue; 3471 } 3472 3473 // Filter out elements in the current dragged item 3474 for ( j = 0; j < list.length; j++ ) { 3475 if ( list[ j ] === m[ i ].element[ 0 ] ) { 3476 m[ i ].proportions().height = 0; 3477 continue droppablesLoop; 3478 } 3479 } 3480 3481 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 3482 if ( !m[ i ].visible ) { 3483 continue; 3484 } 3485 3486 // Activate the droppable if used directly from draggables 3487 if ( type === "mousedown" ) { 3488 m[ i ]._activate.call( m[ i ], event ); 3489 } 3490 3491 m[ i ].offset = m[ i ].element.offset(); 3492 m[ i ].proportions( { 3493 width: m[ i ].element[ 0 ].offsetWidth, 3494 height: m[ i ].element[ 0 ].offsetHeight 3495 } ); 3496 3497 } 3498 3499 }, 3500 drop: function( draggable, event ) { 3501 3502 var dropped = false;
vendor: 5,516 bytes, lines 3503-3708
3503 3504 // Create a copy of the droppables in case the list changes during the drop (#9116) 3505 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 3506 3507 if ( !this.options ) { 3508 return; 3509 } 3510 if ( !this.options.disabled && this.visible && 3511 intersect( draggable, this, this.options.tolerance, event ) ) { 3512 dropped = this._drop.call( this, event ) || dropped; 3513 } 3514 3515 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 3516 ( draggable.currentItem || draggable.element ) ) ) { 3517 this.isout = true; 3518 this.isover = false; 3519 this._deactivate.call( this, event ); 3520 } 3521 3522 } ); 3523 return dropped; 3524 3525 }, 3526 dragStart: function( draggable, event ) { 3527 3528 // Listen for scrolling so that if the dragging causes scrolling the position of the 3529 // droppables can be recalculated (see #5003) 3530 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 3531 if ( !draggable.options.refreshPositions ) { 3532 $.ui.ddmanager.prepareOffsets( draggable, event ); 3533 } 3534 } ); 3535 }, 3536 drag: function( draggable, event ) { 3537 3538 // If you have a highly dynamic page, you might try this option. It renders positions 3539 // every time you move the mouse. 3540 if ( draggable.options.refreshPositions ) { 3541 $.ui.ddmanager.prepareOffsets( draggable, event ); 3542 } 3543 3544 // Run through all droppables and check their positions based on specific tolerance options 3545 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 3546 3547 if ( this.options.disabled || this.greedyChild || !this.visible ) { 3548 return; 3549 } 3550 3551 var parentInstance, scope, parent, 3552 intersects = intersect( draggable, this, this.options.tolerance, event ), 3553 c = !intersects && this.isover ? 3554 "isout" : 3555 ( intersects && !this.isover ? "isover" : null ); 3556 if ( !c ) { 3557 return; 3558 } 3559 3560 if ( this.options.greedy ) { 3561 3562 // find droppable parents with same scope 3563 scope = this.options.scope; 3564 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 3565 return $( this ).droppable( "instance" ).options.scope === scope; 3566 } ); 3567 3568 if ( parent.length ) { 3569 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 3570 parentInstance.greedyChild = ( c === "isover" ); 3571 } 3572 } 3573 3574 // We just moved into a greedy child 3575 if ( parentInstance && c === "isover" ) { 3576 parentInstance.isover = false; 3577 parentInstance.isout = true; 3578 parentInstance._out.call( parentInstance, event ); 3579 } 3580 3581 this[ c ] = true; 3582 this[ c === "isout" ? "isover" : "isout" ] = false; 3583 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 3584 3585 // We just moved out of a greedy child 3586 if ( parentInstance && c === "isout" ) { 3587 parentInstance.isout = false; 3588 parentInstance.isover = true; 3589 parentInstance._over.call( parentInstance, event ); 3590 } 3591 } ); 3592 3593 }, 3594 dragStop: function( draggable, event ) { 3595 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 3596 3597 // Call prepareOffsets one final time since IE does not fire return scroll events when 3598 // overflow was caused by drag (see #5003) 3599 if ( !draggable.options.refreshPositions ) { 3600 $.ui.ddmanager.prepareOffsets( draggable, event ); 3601 } 3602 } 3603}; 3604 3605// DEPRECATED 3606// TODO: switch return back to widget declaration at top of file when this is removed 3607if ( $.uiBackCompat !== false ) { 3608 3609 // Backcompat for activeClass and hoverClass options 3610 $.widget( "ui.droppable", $.ui.droppable, { 3611 options: { 3612 hoverClass: false, 3613 activeClass: false 3614 }, 3615 _addActiveClass: function() { 3616 this._super(); 3617 if ( this.options.activeClass ) { 3618 this.element.addClass( this.options.activeClass ); 3619 } 3620 }, 3621 _removeActiveClass: function() { 3622 this._super(); 3623 if ( this.options.activeClass ) { 3624 this.element.removeClass( this.options.activeClass ); 3625 } 3626 }, 3627 _addHoverClass: function() { 3628 this._super(); 3629 if ( this.options.hoverClass ) { 3630 this.element.addClass( this.options.hoverClass ); 3631 } 3632 }, 3633 _removeHoverClass: function() { 3634 this._super(); 3635 if ( this.options.hoverClass ) { 3636 this.element.removeClass( this.options.hoverClass ); 3637 } 3638 } 3639 } ); 3640} 3641 3642var widgetsDroppable = $.ui.droppable; 3643 3644 3645/*! 3646 * jQuery UI Resizable 1.12.1 3647 * http://jqueryui.com 3648 * 3649 * Copyright jQuery Foundation and other contributors 3650 * Released under the MIT license. 3651 * http://jquery.org/license 3652 */ 3653 3654//>>label: Resizable 3655//>>group: Interactions 3656//>>description: Enables resize functionality for any element. 3657//>>docs: http://api.jqueryui.com/resizable/ 3658//>>demos: http://jqueryui.com/resizable/ 3659//>>css.structure: ../../themes/base/core.css 3660//>>css.structure: ../../themes/base/resizable.css 3661//>>css.theme: ../../themes/base/theme.css 3662 3663 3664 3665$.widget( "ui.resizable", $.ui.mouse, { 3666 version: "1.12.1", 3667 widgetEventPrefix: "resize", 3668 options: { 3669 alsoResize: false, 3670 animate: false, 3671 animateDuration: "slow", 3672 animateEasing: "swing", 3673 aspectRatio: false, 3674 autoHide: false, 3675 classes: { 3676 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 3677 }, 3678 containment: false, 3679 ghost: false, 3680 grid: false, 3681 handles: "e,s,se", 3682 helper: false, 3683 maxHeight: null, 3684 maxWidth: null, 3685 minHeight: 10, 3686 minWidth: 10, 3687 3688 // See #7960 3689 zIndex: 90, 3690 3691 // Callbacks 3692 resize: null, 3693 start: null, 3694 stop: null 3695 }, 3696 3697 _num: function( value ) { 3698 return parseFloat( value ) || 0; 3699 }, 3700 3701 _isNumber: function( value ) { 3702 return !isNaN( parseFloat( value ) ); 3703 }, 3704 3705 _hasScroll: function( el, a ) { 3706 3707 if ( $( el ).css( "overflow" ) === "hidden" ) { 3708 return false;
vendor: 26,006 bytes, lines 3709-4737
3709 } 3710 3711 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3712 has = false; 3713 3714 if ( el[ scroll ] > 0 ) { 3715 return true; 3716 } 3717 3718 // TODO: determine which cases actually cause this to happen 3719 // if the element doesn't have the scroll set, see if it's possible to 3720 // set the scroll 3721 el[ scroll ] = 1; 3722 has = ( el[ scroll ] > 0 ); 3723 el[ scroll ] = 0; 3724 return has; 3725 }, 3726 3727 _create: function() { 3728 3729 var margins, 3730 o = this.options, 3731 that = this; 3732 this._addClass( "ui-resizable" ); 3733 3734 $.extend( this, { 3735 _aspectRatio: !!( o.aspectRatio ), 3736 aspectRatio: o.aspectRatio, 3737 originalElement: this.element, 3738 _proportionallyResizeElements: [], 3739 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 3740 } ); 3741 3742 // Wrap the element if it cannot hold child nodes 3743 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 3744 3745 this.element.wrap( 3746 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( { 3747 position: this.element.css( "position" ), 3748 width: this.element.outerWidth(), 3749 height: this.element.outerHeight(), 3750 top: this.element.css( "top" ), 3751 left: this.element.css( "left" ) 3752 } ) 3753 ); 3754 3755 this.element = this.element.parent().data( 3756 "ui-resizable", this.element.resizable( "instance" ) 3757 ); 3758 3759 this.elementIsWrapper = true; 3760 3761 margins = { 3762 marginTop: this.originalElement.css( "marginTop" ), 3763 marginRight: this.originalElement.css( "marginRight" ), 3764 marginBottom: this.originalElement.css( "marginBottom" ), 3765 marginLeft: this.originalElement.css( "marginLeft" ) 3766 }; 3767 3768 this.element.css( margins ); 3769 this.originalElement.css( "margin", 0 ); 3770 3771 // support: Safari 3772 // Prevent Safari textarea resize 3773 this.originalResizeStyle = this.originalElement.css( "resize" ); 3774 this.originalElement.css( "resize", "none" ); 3775 3776 this._proportionallyResizeElements.push( this.originalElement.css( { 3777 position: "static", 3778 zoom: 1, 3779 display: "block" 3780 } ) ); 3781 3782 // Support: IE9 3783 // avoid IE jump (hard set the margin) 3784 this.originalElement.css( margins ); 3785 3786 this._proportionallyResize(); 3787 } 3788 3789 this._setupHandles(); 3790 3791 if ( o.autoHide ) { 3792 $( this.element ) 3793 .on( "mouseenter", function() { 3794 if ( o.disabled ) { 3795 return; 3796 } 3797 that._removeClass( "ui-resizable-autohide" ); 3798 that._handles.show(); 3799 } ) 3800 .on( "mouseleave", function() { 3801 if ( o.disabled ) { 3802 return; 3803 } 3804 if ( !that.resizing ) { 3805 that._addClass( "ui-resizable-autohide" ); 3806 that._handles.hide(); 3807 } 3808 } ); 3809 } 3810 3811 this._mouseInit(); 3812 }, 3813 3814 _destroy: function() { 3815 3816 this._mouseDestroy(); 3817 3818 var wrapper, 3819 _destroy = function( exp ) { 3820 $( exp ) 3821 .removeData( "resizable" ) 3822 .removeData( "ui-resizable" ) 3823 .off( ".resizable" ) 3824 .find( ".ui-resizable-handle" ) 3825 .remove(); 3826 }; 3827 3828 // TODO: Unwrap at same DOM position 3829 if ( this.elementIsWrapper ) { 3830 _destroy( this.element ); 3831 wrapper = this.element; 3832 this.originalElement.css( { 3833 position: wrapper.css( "position" ), 3834 width: wrapper.outerWidth(), 3835 height: wrapper.outerHeight(), 3836 top: wrapper.css( "top" ), 3837 left: wrapper.css( "left" ) 3838 } ).insertAfter( wrapper ); 3839 wrapper.remove(); 3840 } 3841 3842 this.originalElement.css( "resize", this.originalResizeStyle ); 3843 _destroy( this.originalElement ); 3844 3845 return this; 3846 }, 3847 3848 _setOption: function( key, value ) { 3849 this._super( key, value ); 3850 3851 switch ( key ) { 3852 case "handles": 3853 this._removeHandles(); 3854 this._setupHandles(); 3855 break; 3856 default: 3857 break; 3858 } 3859 }, 3860 3861 _setupHandles: function() { 3862 var o = this.options, handle, i, n, hname, axis, that = this; 3863 this.handles = o.handles || 3864 ( !$( ".ui-resizable-handle", this.element ).length ? 3865 "e,s,se" : { 3866 n: ".ui-resizable-n", 3867 e: ".ui-resizable-e", 3868 s: ".ui-resizable-s", 3869 w: ".ui-resizable-w", 3870 se: ".ui-resizable-se", 3871 sw: ".ui-resizable-sw", 3872 ne: ".ui-resizable-ne", 3873 nw: ".ui-resizable-nw" 3874 } ); 3875 3876 this._handles = $(); 3877 if ( this.handles.constructor === String ) { 3878 3879 if ( this.handles === "all" ) { 3880 this.handles = "n,e,s,w,se,sw,ne,nw"; 3881 } 3882 3883 n = this.handles.split( "," ); 3884 this.handles = {}; 3885 3886 for ( i = 0; i < n.length; i++ ) { 3887 3888 handle = $.trim( n[ i ] ); 3889 hname = "ui-resizable-" + handle; 3890 axis = $( "<div>" ); 3891 this._addClass( axis, "ui-resizable-handle " + hname ); 3892 3893 axis.css( { zIndex: o.zIndex } ); 3894 3895 this.handles[ handle ] = ".ui-resizable-" + handle; 3896 this.element.append( axis ); 3897 } 3898 3899 } 3900 3901 this._renderAxis = function( target ) { 3902 3903 var i, axis, padPos, padWrapper; 3904 3905 target = target || this.element; 3906 3907 for ( i in this.handles ) { 3908 3909 if ( this.handles[ i ].constructor === String ) { 3910 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 3911 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 3912 this.handles[ i ] = $( this.handles[ i ] ); 3913 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 3914 } 3915 3916 if ( this.elementIsWrapper && 3917 this.originalElement[ 0 ] 3918 .nodeName 3919 .match( /^(textarea|input|select|button)$/i ) ) { 3920 axis = $( this.handles[ i ], this.element ); 3921 3922 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 3923 axis.outerHeight() : 3924 axis.outerWidth(); 3925 3926 padPos = [ "padding", 3927 /ne|nw|n/.test( i ) ? "Top" : 3928 /se|sw|s/.test( i ) ? "Bottom" : 3929 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 3930 3931 target.css( padPos, padWrapper ); 3932 3933 this._proportionallyResize(); 3934 } 3935 3936 this._handles = this._handles.add( this.handles[ i ] ); 3937 } 3938 }; 3939 3940 // TODO: make renderAxis a prototype function 3941 this._renderAxis( this.element ); 3942 3943 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 3944 this._handles.disableSelection(); 3945 3946 this._handles.on( "mouseover", function() { 3947 if ( !that.resizing ) { 3948 if ( this.className ) { 3949 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 3950 } 3951 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 3952 } 3953 } ); 3954 3955 if ( o.autoHide ) { 3956 this._handles.hide(); 3957 this._addClass( "ui-resizable-autohide" ); 3958 } 3959 }, 3960 3961 _removeHandles: function() { 3962 this._handles.remove(); 3963 }, 3964 3965 _mouseCapture: function( event ) { 3966 var i, handle, 3967 capture = false; 3968 3969 for ( i in this.handles ) { 3970 handle = $( this.handles[ i ] )[ 0 ]; 3971 if ( handle === event.target || $.contains( handle, event.target ) ) { 3972 capture = true; 3973 } 3974 } 3975 3976 return !this.options.disabled && capture; 3977 }, 3978 3979 _mouseStart: function( event ) { 3980 3981 var curleft, curtop, cursor, 3982 o = this.options, 3983 el = this.element; 3984 3985 this.resizing = true; 3986 3987 this._renderProxy(); 3988 3989 curleft = this._num( this.helper.css( "left" ) ); 3990 curtop = this._num( this.helper.css( "top" ) ); 3991 3992 if ( o.containment ) { 3993 curleft += $( o.containment ).scrollLeft() || 0; 3994 curtop += $( o.containment ).scrollTop() || 0; 3995 } 3996 3997 this.offset = this.helper.offset(); 3998 this.position = { left: curleft, top: curtop }; 3999 4000 this.size = this._helper ? { 4001 width: this.helper.width(), 4002 height: this.helper.height() 4003 } : { 4004 width: el.width(), 4005 height: el.height() 4006 }; 4007 4008 this.originalSize = this._helper ? { 4009 width: el.outerWidth(), 4010 height: el.outerHeight() 4011 } : { 4012 width: el.width(), 4013 height: el.height() 4014 }; 4015 4016 this.sizeDiff = { 4017 width: el.outerWidth() - el.width(), 4018 height: el.outerHeight() - el.height() 4019 }; 4020 4021 this.originalPosition = { left: curleft, top: curtop }; 4022 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 4023 4024 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 4025 o.aspectRatio : 4026 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 4027 4028 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 4029 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 4030 4031 this._addClass( "ui-resizable-resizing" ); 4032 this._propagate( "start", event ); 4033 return true; 4034 }, 4035 4036 _mouseDrag: function( event ) { 4037 4038 var data, props, 4039 smp = this.originalMousePosition, 4040 a = this.axis, 4041 dx = ( event.pageX - smp.left ) || 0, 4042 dy = ( event.pageY - smp.top ) || 0, 4043 trigger = this._change[ a ]; 4044 4045 this._updatePrevProperties(); 4046 4047 if ( !trigger ) { 4048 return false; 4049 } 4050 4051 data = trigger.apply( this, [ event, dx, dy ] ); 4052 4053 this._updateVirtualBoundaries( event.shiftKey ); 4054 if ( this._aspectRatio || event.shiftKey ) { 4055 data = this._updateRatio( data, event ); 4056 } 4057 4058 data = this._respectSize( data, event ); 4059 4060 this._updateCache( data ); 4061 4062 this._propagate( "resize", event ); 4063 4064 props = this._applyChanges(); 4065 4066 if ( !this._helper && this._proportionallyResizeElements.length ) { 4067 this._proportionallyResize(); 4068 } 4069 4070 if ( !$.isEmptyObject( props ) ) { 4071 this._updatePrevProperties(); 4072 this._trigger( "resize", event, this.ui() ); 4073 this._applyChanges(); 4074 } 4075 4076 return false; 4077 }, 4078 4079 _mouseStop: function( event ) { 4080 4081 this.resizing = false; 4082 var pr, ista, soffseth, soffsetw, s, left, top, 4083 o = this.options, that = this; 4084 4085 if ( this._helper ) { 4086 4087 pr = this._proportionallyResizeElements; 4088 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 4089 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 4090 soffsetw = ista ? 0 : that.sizeDiff.width; 4091 4092 s = { 4093 width: ( that.helper.width() - soffsetw ), 4094 height: ( that.helper.height() - soffseth ) 4095 }; 4096 left = ( parseFloat( that.element.css( "left" ) ) + 4097 ( that.position.left - that.originalPosition.left ) ) || null; 4098 top = ( parseFloat( that.element.css( "top" ) ) + 4099 ( that.position.top - that.originalPosition.top ) ) || null; 4100 4101 if ( !o.animate ) { 4102 this.element.css( $.extend( s, { top: top, left: left } ) ); 4103 } 4104 4105 that.helper.height( that.size.height ); 4106 that.helper.width( that.size.width ); 4107 4108 if ( this._helper && !o.animate ) { 4109 this._proportionallyResize(); 4110 } 4111 } 4112 4113 $( "body" ).css( "cursor", "auto" ); 4114 4115 this._removeClass( "ui-resizable-resizing" ); 4116 4117 this._propagate( "stop", event ); 4118 4119 if ( this._helper ) { 4120 this.helper.remove(); 4121 } 4122 4123 return false; 4124 4125 }, 4126 4127 _updatePrevProperties: function() { 4128 this.prevPosition = { 4129 top: this.position.top, 4130 left: this.position.left 4131 }; 4132 this.prevSize = { 4133 width: this.size.width, 4134 height: this.size.height 4135 }; 4136 }, 4137 4138 _applyChanges: function() { 4139 var props = {}; 4140 4141 if ( this.position.top !== this.prevPosition.top ) { 4142 props.top = this.position.top + "px"; 4143 } 4144 if ( this.position.left !== this.prevPosition.left ) { 4145 props.left = this.position.left + "px"; 4146 } 4147 if ( this.size.width !== this.prevSize.width ) { 4148 props.width = this.size.width + "px"; 4149 } 4150 if ( this.size.height !== this.prevSize.height ) { 4151 props.height = this.size.height + "px"; 4152 } 4153 4154 this.helper.css( props ); 4155 4156 return props; 4157 }, 4158 4159 _updateVirtualBoundaries: function( forceAspectRatio ) { 4160 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 4161 o = this.options; 4162 4163 b = { 4164 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 4165 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 4166 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 4167 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 4168 }; 4169 4170 if ( this._aspectRatio || forceAspectRatio ) { 4171 pMinWidth = b.minHeight * this.aspectRatio; 4172 pMinHeight = b.minWidth / this.aspectRatio; 4173 pMaxWidth = b.maxHeight * this.aspectRatio; 4174 pMaxHeight = b.maxWidth / this.aspectRatio; 4175 4176 if ( pMinWidth > b.minWidth ) { 4177 b.minWidth = pMinWidth; 4178 } 4179 if ( pMinHeight > b.minHeight ) { 4180 b.minHeight = pMinHeight; 4181 } 4182 if ( pMaxWidth < b.maxWidth ) { 4183 b.maxWidth = pMaxWidth; 4184 } 4185 if ( pMaxHeight < b.maxHeight ) { 4186 b.maxHeight = pMaxHeight; 4187 } 4188 } 4189 this._vBoundaries = b; 4190 }, 4191 4192 _updateCache: function( data ) { 4193 this.offset = this.helper.offset(); 4194 if ( this._isNumber( data.left ) ) { 4195 this.position.left = data.left; 4196 } 4197 if ( this._isNumber( data.top ) ) { 4198 this.position.top = data.top; 4199 } 4200 if ( this._isNumber( data.height ) ) { 4201 this.size.height = data.height; 4202 } 4203 if ( this._isNumber( data.width ) ) { 4204 this.size.width = data.width; 4205 } 4206 }, 4207 4208 _updateRatio: function( data ) { 4209 4210 var cpos = this.position, 4211 csize = this.size, 4212 a = this.axis; 4213 4214 if ( this._isNumber( data.height ) ) { 4215 data.width = ( data.height * this.aspectRatio ); 4216 } else if ( this._isNumber( data.width ) ) { 4217 data.height = ( data.width / this.aspectRatio ); 4218 } 4219 4220 if ( a === "sw" ) { 4221 data.left = cpos.left + ( csize.width - data.width ); 4222 data.top = null; 4223 } 4224 if ( a === "nw" ) { 4225 data.top = cpos.top + ( csize.height - data.height ); 4226 data.left = cpos.left + ( csize.width - data.width ); 4227 } 4228 4229 return data; 4230 }, 4231 4232 _respectSize: function( data ) { 4233 4234 var o = this._vBoundaries, 4235 a = this.axis, 4236 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 4237 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 4238 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 4239 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 4240 dw = this.originalPosition.left + this.originalSize.width, 4241 dh = this.originalPosition.top + this.originalSize.height, 4242 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 4243 if ( isminw ) { 4244 data.width = o.minWidth; 4245 } 4246 if ( isminh ) { 4247 data.height = o.minHeight; 4248 } 4249 if ( ismaxw ) { 4250 data.width = o.maxWidth; 4251 } 4252 if ( ismaxh ) { 4253 data.height = o.maxHeight; 4254 } 4255 4256 if ( isminw && cw ) { 4257 data.left = dw - o.minWidth; 4258 } 4259 if ( ismaxw && cw ) { 4260 data.left = dw - o.maxWidth; 4261 } 4262 if ( isminh && ch ) { 4263 data.top = dh - o.minHeight; 4264 } 4265 if ( ismaxh && ch ) { 4266 data.top = dh - o.maxHeight; 4267 } 4268 4269 // Fixing jump error on top/left - bug #2330 4270 if ( !data.width && !data.height && !data.left && data.top ) { 4271 data.top = null; 4272 } else if ( !data.width && !data.height && !data.top && data.left ) { 4273 data.left = null; 4274 } 4275 4276 return data; 4277 }, 4278 4279 _getPaddingPlusBorderDimensions: function( element ) { 4280 var i = 0, 4281 widths = [], 4282 borders = [ 4283 element.css( "borderTopWidth" ), 4284 element.css( "borderRightWidth" ), 4285 element.css( "borderBottomWidth" ), 4286 element.css( "borderLeftWidth" ) 4287 ], 4288 paddings = [ 4289 element.css( "paddingTop" ), 4290 element.css( "paddingRight" ), 4291 element.css( "paddingBottom" ), 4292 element.css( "paddingLeft" ) 4293 ]; 4294 4295 for ( ; i < 4; i++ ) { 4296 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 4297 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 4298 } 4299 4300 return { 4301 height: widths[ 0 ] + widths[ 2 ], 4302 width: widths[ 1 ] + widths[ 3 ] 4303 }; 4304 }, 4305 4306 _proportionallyResize: function() { 4307 4308 if ( !this._proportionallyResizeElements.length ) { 4309 return; 4310 } 4311 4312 var prel, 4313 i = 0, 4314 element = this.helper || this.element; 4315 4316 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 4317 4318 prel = this._proportionallyResizeElements[ i ]; 4319 4320 // TODO: Seems like a bug to cache this.outerDimensions 4321 // considering that we are in a loop. 4322 if ( !this.outerDimensions ) { 4323 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 4324 } 4325 4326 prel.css( { 4327 height: ( element.height() - this.outerDimensions.height ) || 0, 4328 width: ( element.width() - this.outerDimensions.width ) || 0 4329 } ); 4330 4331 } 4332 4333 }, 4334 4335 _renderProxy: function() { 4336 4337 var el = this.element, o = this.options; 4338 this.elementOffset = el.offset(); 4339 4340 if ( this._helper ) { 4341 4342 this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" ); 4343 4344 this._addClass( this.helper, this._helper ); 4345 this.helper.css( { 4346 width: this.element.outerWidth(), 4347 height: this.element.outerHeight(), 4348 position: "absolute", 4349 left: this.elementOffset.left + "px", 4350 top: this.elementOffset.top + "px", 4351 zIndex: ++o.zIndex //TODO: Don't modify option 4352 } ); 4353 4354 this.helper 4355 .appendTo( "body" ) 4356 .disableSelection(); 4357 4358 } else { 4359 this.helper = this.element; 4360 } 4361 4362 }, 4363 4364 _change: { 4365 e: function( event, dx ) { 4366 return { width: this.originalSize.width + dx }; 4367 }, 4368 w: function( event, dx ) { 4369 var cs = this.originalSize, sp = this.originalPosition; 4370 return { left: sp.left + dx, width: cs.width - dx }; 4371 }, 4372 n: function( event, dx, dy ) { 4373 var cs = this.originalSize, sp = this.originalPosition; 4374 return { top: sp.top + dy, height: cs.height - dy }; 4375 }, 4376 s: function( event, dx, dy ) { 4377 return { height: this.originalSize.height + dy }; 4378 }, 4379 se: function( event, dx, dy ) { 4380 return $.extend( this._change.s.apply( this, arguments ), 4381 this._change.e.apply( this, [ event, dx, dy ] ) ); 4382 }, 4383 sw: function( event, dx, dy ) { 4384 return $.extend( this._change.s.apply( this, arguments ), 4385 this._change.w.apply( this, [ event, dx, dy ] ) ); 4386 }, 4387 ne: function( event, dx, dy ) { 4388 return $.extend( this._change.n.apply( this, arguments ), 4389 this._change.e.apply( this, [ event, dx, dy ] ) ); 4390 }, 4391 nw: function( event, dx, dy ) { 4392 return $.extend( this._change.n.apply( this, arguments ), 4393 this._change.w.apply( this, [ event, dx, dy ] ) ); 4394 } 4395 }, 4396 4397 _propagate: function( n, event ) { 4398 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 4399 ( n !== "resize" && this._trigger( n, event, this.ui() ) ); 4400 }, 4401 4402 plugins: {}, 4403 4404 ui: function() { 4405 return { 4406 originalElement: this.originalElement, 4407 element: this.element, 4408 helper: this.helper, 4409 position: this.position, 4410 size: this.size, 4411 originalSize: this.originalSize, 4412 originalPosition: this.originalPosition 4413 }; 4414 } 4415 4416} ); 4417 4418/* 4419 * Resizable Extensions 4420 */ 4421 4422$.ui.plugin.add( "resizable", "animate", { 4423 4424 stop: function( event ) { 4425 var that = $( this ).resizable( "instance" ), 4426 o = that.options, 4427 pr = that._proportionallyResizeElements, 4428 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 4429 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 4430 soffsetw = ista ? 0 : that.sizeDiff.width, 4431 style = { 4432 width: ( that.size.width - soffsetw ), 4433 height: ( that.size.height - soffseth ) 4434 }, 4435 left = ( parseFloat( that.element.css( "left" ) ) + 4436 ( that.position.left - that.originalPosition.left ) ) || null, 4437 top = ( parseFloat( that.element.css( "top" ) ) + 4438 ( that.position.top - that.originalPosition.top ) ) || null; 4439 4440 that.element.animate( 4441 $.extend( style, top && left ? { top: top, left: left } : {} ), { 4442 duration: o.animateDuration, 4443 easing: o.animateEasing, 4444 step: function() { 4445 4446 var data = { 4447 width: parseFloat( that.element.css( "width" ) ), 4448 height: parseFloat( that.element.css( "height" ) ), 4449 top: parseFloat( that.element.css( "top" ) ), 4450 left: parseFloat( that.element.css( "left" ) ) 4451 }; 4452 4453 if ( pr && pr.length ) { 4454 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 4455 } 4456 4457 // Propagating resize, and updating values for each animation step 4458 that._updateCache( data ); 4459 that._propagate( "resize", event ); 4460 4461 } 4462 } 4463 ); 4464 } 4465 4466} ); 4467 4468$.ui.plugin.add( "resizable", "containment", { 4469 4470 start: function() { 4471 var element, p, co, ch, cw, width, height, 4472 that = $( this ).resizable( "instance" ), 4473 o = that.options, 4474 el = that.element, 4475 oc = o.containment, 4476 ce = ( oc instanceof $ ) ? 4477 oc.get( 0 ) : 4478 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 4479 4480 if ( !ce ) { 4481 return; 4482 } 4483 4484 that.containerElement = $( ce ); 4485 4486 if ( /document/.test( oc ) || oc === document ) { 4487 that.containerOffset = { 4488 left: 0, 4489 top: 0 4490 }; 4491 that.containerPosition = { 4492 left: 0, 4493 top: 0 4494 }; 4495 4496 that.parentData = { 4497 element: $( document ), 4498 left: 0, 4499 top: 0, 4500 width: $( document ).width(), 4501 height: $( document ).height() || document.body.parentNode.scrollHeight 4502 }; 4503 } else { 4504 element = $( ce ); 4505 p = []; 4506 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 4507 p[ i ] = that._num( element.css( "padding" + name ) ); 4508 } ); 4509 4510 that.containerOffset = element.offset(); 4511 that.containerPosition = element.position(); 4512 that.containerSize = { 4513 height: ( element.innerHeight() - p[ 3 ] ), 4514 width: ( element.innerWidth() - p[ 1 ] ) 4515 }; 4516 4517 co = that.containerOffset; 4518 ch = that.containerSize.height; 4519 cw = that.containerSize.width; 4520 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 4521 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 4522 4523 that.parentData = { 4524 element: ce, 4525 left: co.left, 4526 top: co.top, 4527 width: width, 4528 height: height 4529 }; 4530 } 4531 }, 4532 4533 resize: function( event ) { 4534 var woset, hoset, isParent, isOffsetRelative, 4535 that = $( this ).resizable( "instance" ), 4536 o = that.options, 4537 co = that.containerOffset, 4538 cp = that.position, 4539 pRatio = that._aspectRatio || event.shiftKey, 4540 cop = { 4541 top: 0, 4542 left: 0 4543 }, 4544 ce = that.containerElement, 4545 continueResize = true; 4546 4547 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 4548 cop = co; 4549 } 4550 4551 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 4552 that.size.width = that.size.width + 4553 ( that._helper ? 4554 ( that.position.left - co.left ) : 4555 ( that.position.left - cop.left ) ); 4556 4557 if ( pRatio ) { 4558 that.size.height = that.size.width / that.aspectRatio; 4559 continueResize = false; 4560 } 4561 that.position.left = o.helper ? co.left : 0; 4562 } 4563 4564 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 4565 that.size.height = that.size.height + 4566 ( that._helper ? 4567 ( that.position.top - co.top ) : 4568 that.position.top ); 4569 4570 if ( pRatio ) { 4571 that.size.width = that.size.height * that.aspectRatio; 4572 continueResize = false; 4573 } 4574 that.position.top = that._helper ? co.top : 0; 4575 } 4576 4577 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 4578 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 4579 4580 if ( isParent && isOffsetRelative ) { 4581 that.offset.left = that.parentData.left + that.position.left; 4582 that.offset.top = that.parentData.top + that.position.top; 4583 } else { 4584 that.offset.left = that.element.offset().left; 4585 that.offset.top = that.element.offset().top; 4586 } 4587 4588 woset = Math.abs( that.sizeDiff.width + 4589 ( that._helper ? 4590 that.offset.left - cop.left : 4591 ( that.offset.left - co.left ) ) ); 4592 4593 hoset = Math.abs( that.sizeDiff.height + 4594 ( that._helper ? 4595 that.offset.top - cop.top : 4596 ( that.offset.top - co.top ) ) ); 4597 4598 if ( woset + that.size.width >= that.parentData.width ) { 4599 that.size.width = that.parentData.width - woset; 4600 if ( pRatio ) { 4601 that.size.height = that.size.width / that.aspectRatio; 4602 continueResize = false; 4603 } 4604 } 4605 4606 if ( hoset + that.size.height >= that.parentData.height ) { 4607 that.size.height = that.parentData.height - hoset; 4608 if ( pRatio ) { 4609 that.size.width = that.size.height * that.aspectRatio; 4610 continueResize = false; 4611 } 4612 } 4613 4614 if ( !continueResize ) { 4615 that.position.left = that.prevPosition.left; 4616 that.position.top = that.prevPosition.top; 4617 that.size.width = that.prevSize.width; 4618 that.size.height = that.prevSize.height; 4619 } 4620 }, 4621 4622 stop: function() { 4623 var that = $( this ).resizable( "instance" ), 4624 o = that.options, 4625 co = that.containerOffset, 4626 cop = that.containerPosition, 4627 ce = that.containerElement, 4628 helper = $( that.helper ), 4629 ho = helper.offset(), 4630 w = helper.outerWidth() - that.sizeDiff.width, 4631 h = helper.outerHeight() - that.sizeDiff.height; 4632 4633 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 4634 $( this ).css( { 4635 left: ho.left - cop.left - co.left, 4636 width: w, 4637 height: h 4638 } ); 4639 } 4640 4641 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 4642 $( this ).css( { 4643 left: ho.left - cop.left - co.left, 4644 width: w, 4645 height: h 4646 } ); 4647 } 4648 } 4649} ); 4650 4651$.ui.plugin.add( "resizable", "alsoResize", { 4652 4653 start: function() { 4654 var that = $( this ).resizable( "instance" ), 4655 o = that.options; 4656 4657 $( o.alsoResize ).each( function() { 4658 var el = $( this ); 4659 el.data( "ui-resizable-alsoresize", { 4660 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 4661 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 4662 } ); 4663 } ); 4664 }, 4665 4666 resize: function( event, ui ) { 4667 var that = $( this ).resizable( "instance" ), 4668 o = that.options, 4669 os = that.originalSize, 4670 op = that.originalPosition, 4671 delta = { 4672 height: ( that.size.height - os.height ) || 0, 4673 width: ( that.size.width - os.width ) || 0, 4674 top: ( that.position.top - op.top ) || 0, 4675 left: ( that.position.left - op.left ) || 0 4676 }; 4677 4678 $( o.alsoResize ).each( function() { 4679 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 4680 css = el.parents( ui.originalElement[ 0 ] ).length ? 4681 [ "width", "height" ] : 4682 [ "width", "height", "top", "left" ]; 4683 4684 $.each( css, function( i, prop ) { 4685 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 4686 if ( sum && sum >= 0 ) { 4687 style[ prop ] = sum || null; 4688 } 4689 } ); 4690 4691 el.css( style ); 4692 } ); 4693 }, 4694 4695 stop: function() { 4696 $( this ).removeData( "ui-resizable-alsoresize" ); 4697 } 4698} ); 4699 4700$.ui.plugin.add( "resizable", "ghost", { 4701 4702 start: function() { 4703 4704 var that = $( this ).resizable( "instance" ), cs = that.size; 4705 4706 that.ghost = that.originalElement.clone(); 4707 that.ghost.css( { 4708 opacity: 0.25, 4709 display: "block", 4710 position: "relative", 4711 height: cs.height, 4712 width: cs.width, 4713 margin: 0, 4714 left: 0, 4715 top: 0 4716 } ); 4717 4718 that._addClass( that.ghost, "ui-resizable-ghost" ); 4719 4720 // DEPRECATED 4721 // TODO: remove after 1.12 4722 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 4723 4724 // Ghost option 4725 that.ghost.addClass( this.options.ghost ); 4726 } 4727 4728 that.ghost.appendTo( that.helper ); 4729 4730 }, 4731 4732 resize: function() { 4733 var that = $( this ).resizable( "instance" ); 4734 if ( that.ghost ) { 4735 that.ghost.css( { 4736 position: "relative", 4737 height: that.size.height,
vendor: 13,664 bytes, lines 4738-5282
4738 width: that.size.width 4739 } ); 4740 } 4741 }, 4742 4743 stop: function() { 4744 var that = $( this ).resizable( "instance" ); 4745 if ( that.ghost && that.helper ) { 4746 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 4747 } 4748 } 4749 4750} ); 4751 4752$.ui.plugin.add( "resizable", "grid", { 4753 4754 resize: function() { 4755 var outerDimensions, 4756 that = $( this ).resizable( "instance" ), 4757 o = that.options, 4758 cs = that.size, 4759 os = that.originalSize, 4760 op = that.originalPosition, 4761 a = that.axis, 4762 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4763 gridX = ( grid[ 0 ] || 1 ), 4764 gridY = ( grid[ 1 ] || 1 ), 4765 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 4766 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 4767 newWidth = os.width + ox, 4768 newHeight = os.height + oy, 4769 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 4770 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 4771 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 4772 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 4773 4774 o.grid = grid; 4775 4776 if ( isMinWidth ) { 4777 newWidth += gridX; 4778 } 4779 if ( isMinHeight ) { 4780 newHeight += gridY; 4781 } 4782 if ( isMaxWidth ) { 4783 newWidth -= gridX; 4784 } 4785 if ( isMaxHeight ) { 4786 newHeight -= gridY; 4787 } 4788 4789 if ( /^(se|s|e)$/.test( a ) ) { 4790 that.size.width = newWidth; 4791 that.size.height = newHeight; 4792 } else if ( /^(ne)$/.test( a ) ) { 4793 that.size.width = newWidth; 4794 that.size.height = newHeight; 4795 that.position.top = op.top - oy; 4796 } else if ( /^(sw)$/.test( a ) ) { 4797 that.size.width = newWidth; 4798 that.size.height = newHeight; 4799 that.position.left = op.left - ox; 4800 } else { 4801 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 4802 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4803 } 4804 4805 if ( newHeight - gridY > 0 ) { 4806 that.size.height = newHeight; 4807 that.position.top = op.top - oy; 4808 } else { 4809 newHeight = gridY - outerDimensions.height; 4810 that.size.height = newHeight; 4811 that.position.top = op.top + os.height - newHeight; 4812 } 4813 if ( newWidth - gridX > 0 ) { 4814 that.size.width = newWidth; 4815 that.position.left = op.left - ox; 4816 } else { 4817 newWidth = gridX - outerDimensions.width; 4818 that.size.width = newWidth; 4819 that.position.left = op.left + os.width - newWidth; 4820 } 4821 } 4822 } 4823 4824} ); 4825 4826var widgetsResizable = $.ui.resizable; 4827 4828 4829/*! 4830 * jQuery UI Selectable 1.12.1 4831 * http://jqueryui.com 4832 * 4833 * Copyright jQuery Foundation and other contributors 4834 * Released under the MIT license. 4835 * http://jquery.org/license 4836 */ 4837 4838//>>label: Selectable 4839//>>group: Interactions 4840//>>description: Allows groups of elements to be selected with the mouse. 4841//>>docs: http://api.jqueryui.com/selectable/ 4842//>>demos: http://jqueryui.com/selectable/ 4843//>>css.structure: ../../themes/base/selectable.css 4844 4845 4846 4847var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 4848 version: "1.12.1", 4849 options: { 4850 appendTo: "body", 4851 autoRefresh: true, 4852 distance: 0, 4853 filter: "*", 4854 tolerance: "touch", 4855 4856 // Callbacks 4857 selected: null, 4858 selecting: null, 4859 start: null, 4860 stop: null, 4861 unselected: null, 4862 unselecting: null 4863 }, 4864 _create: function() { 4865 var that = this; 4866 4867 this._addClass( "ui-selectable" ); 4868 4869 this.dragged = false; 4870 4871 // Cache selectee children based on filter 4872 this.refresh = function() { 4873 that.elementPos = $( that.element[ 0 ] ).offset(); 4874 that.selectees = $( that.options.filter, that.element[ 0 ] ); 4875 that._addClass( that.selectees, "ui-selectee" ); 4876 that.selectees.each( function() { 4877 var $this = $( this ), 4878 selecteeOffset = $this.offset(), 4879 pos = { 4880 left: selecteeOffset.left - that.elementPos.left, 4881 top: selecteeOffset.top - that.elementPos.top 4882 }; 4883 $.data( this, "selectable-item", { 4884 element: this, 4885 $element: $this, 4886 left: pos.left, 4887 top: pos.top, 4888 right: pos.left + $this.outerWidth(), 4889 bottom: pos.top + $this.outerHeight(), 4890 startselected: false, 4891 selected: $this.hasClass( "ui-selected" ), 4892 selecting: $this.hasClass( "ui-selecting" ), 4893 unselecting: $this.hasClass( "ui-unselecting" ) 4894 } ); 4895 } ); 4896 }; 4897 this.refresh(); 4898 4899 this._mouseInit(); 4900 4901 this.helper = $( "<div>" ); 4902 this._addClass( this.helper, "ui-selectable-helper" ); 4903 }, 4904 4905 _destroy: function() { 4906 this.selectees.removeData( "selectable-item" ); 4907 this._mouseDestroy(); 4908 }, 4909 4910 _mouseStart: function( event ) { 4911 var that = this, 4912 options = this.options; 4913 4914 this.opos = [ event.pageX, event.pageY ]; 4915 this.elementPos = $( this.element[ 0 ] ).offset(); 4916 4917 if ( this.options.disabled ) { 4918 return; 4919 } 4920 4921 this.selectees = $( options.filter, this.element[ 0 ] ); 4922 4923 this._trigger( "start", event ); 4924 4925 $( options.appendTo ).append( this.helper ); 4926 4927 // position helper (lasso) 4928 this.helper.css( { 4929 "left": event.pageX, 4930 "top": event.pageY, 4931 "width": 0, 4932 "height": 0 4933 } ); 4934 4935 if ( options.autoRefresh ) { 4936 this.refresh(); 4937 } 4938 4939 this.selectees.filter( ".ui-selected" ).each( function() { 4940 var selectee = $.data( this, "selectable-item" ); 4941 selectee.startselected = true; 4942 if ( !event.metaKey && !event.ctrlKey ) { 4943 that._removeClass( selectee.$element, "ui-selected" ); 4944 selectee.selected = false; 4945 that._addClass( selectee.$element, "ui-unselecting" ); 4946 selectee.unselecting = true; 4947 4948 // selectable UNSELECTING callback 4949 that._trigger( "unselecting", event, { 4950 unselecting: selectee.element 4951 } ); 4952 } 4953 } ); 4954 4955 $( event.target ).parents().addBack().each( function() { 4956 var doSelect, 4957 selectee = $.data( this, "selectable-item" ); 4958 if ( selectee ) { 4959 doSelect = ( !event.metaKey && !event.ctrlKey ) || 4960 !selectee.$element.hasClass( "ui-selected" ); 4961 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 4962 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 4963 selectee.unselecting = !doSelect; 4964 selectee.selecting = doSelect; 4965 selectee.selected = doSelect; 4966 4967 // selectable (UN)SELECTING callback 4968 if ( doSelect ) { 4969 that._trigger( "selecting", event, { 4970 selecting: selectee.element 4971 } ); 4972 } else { 4973 that._trigger( "unselecting", event, { 4974 unselecting: selectee.element 4975 } ); 4976 } 4977 return false; 4978 } 4979 } ); 4980 4981 }, 4982 4983 _mouseDrag: function( event ) { 4984 4985 this.dragged = true; 4986 4987 if ( this.options.disabled ) { 4988 return; 4989 } 4990 4991 var tmp, 4992 that = this, 4993 options = this.options, 4994 x1 = this.opos[ 0 ], 4995 y1 = this.opos[ 1 ], 4996 x2 = event.pageX, 4997 y2 = event.pageY; 4998 4999 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; } 5000 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; } 5001 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 5002 5003 this.selectees.each( function() { 5004 var selectee = $.data( this, "selectable-item" ), 5005 hit = false, 5006 offset = {}; 5007 5008 //prevent helper from being selected if appendTo: selectable 5009 if ( !selectee || selectee.element === that.element[ 0 ] ) { 5010 return; 5011 } 5012 5013 offset.left = selectee.left + that.elementPos.left; 5014 offset.right = selectee.right + that.elementPos.left; 5015 offset.top = selectee.top + that.elementPos.top; 5016 offset.bottom = selectee.bottom + that.elementPos.top; 5017 5018 if ( options.tolerance === "touch" ) { 5019 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 5020 offset.bottom < y1 ) ); 5021 } else if ( options.tolerance === "fit" ) { 5022 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 5023 offset.bottom < y2 ); 5024 } 5025 5026 if ( hit ) { 5027 5028 // SELECT 5029 if ( selectee.selected ) { 5030 that._removeClass( selectee.$element, "ui-selected" ); 5031 selectee.selected = false; 5032 } 5033 if ( selectee.unselecting ) { 5034 that._removeClass( selectee.$element, "ui-unselecting" ); 5035 selectee.unselecting = false; 5036 } 5037 if ( !selectee.selecting ) { 5038 that._addClass( selectee.$element, "ui-selecting" ); 5039 selectee.selecting = true; 5040 5041 // selectable SELECTING callback 5042 that._trigger( "selecting", event, { 5043 selecting: selectee.element 5044 } ); 5045 } 5046 } else { 5047 5048 // UNSELECT 5049 if ( selectee.selecting ) { 5050 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 5051 that._removeClass( selectee.$element, "ui-selecting" ); 5052 selectee.selecting = false; 5053 that._addClass( selectee.$element, "ui-selected" ); 5054 selectee.selected = true; 5055 } else { 5056 that._removeClass( selectee.$element, "ui-selecting" ); 5057 selectee.selecting = false; 5058 if ( selectee.startselected ) { 5059 that._addClass( selectee.$element, "ui-unselecting" ); 5060 selectee.unselecting = true; 5061 } 5062 5063 // selectable UNSELECTING callback 5064 that._trigger( "unselecting", event, { 5065 unselecting: selectee.element 5066 } ); 5067 } 5068 } 5069 if ( selectee.selected ) { 5070 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 5071 that._removeClass( selectee.$element, "ui-selected" ); 5072 selectee.selected = false; 5073 5074 that._addClass( selectee.$element, "ui-unselecting" ); 5075 selectee.unselecting = true; 5076 5077 // selectable UNSELECTING callback 5078 that._trigger( "unselecting", event, { 5079 unselecting: selectee.element 5080 } ); 5081 } 5082 } 5083 } 5084 } ); 5085 5086 return false; 5087 }, 5088 5089 _mouseStop: function( event ) { 5090 var that = this; 5091 5092 this.dragged = false; 5093 5094 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 5095 var selectee = $.data( this, "selectable-item" ); 5096 that._removeClass( selectee.$element, "ui-unselecting" ); 5097 selectee.unselecting = false; 5098 selectee.startselected = false; 5099 that._trigger( "unselected", event, { 5100 unselected: selectee.element 5101 } ); 5102 } ); 5103 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 5104 var selectee = $.data( this, "selectable-item" ); 5105 that._removeClass( selectee.$element, "ui-selecting" ) 5106 ._addClass( selectee.$element, "ui-selected" ); 5107 selectee.selecting = false; 5108 selectee.selected = true; 5109 selectee.startselected = true; 5110 that._trigger( "selected", event, { 5111 selected: selectee.element 5112 } ); 5113 } ); 5114 this._trigger( "stop", event ); 5115 5116 this.helper.remove(); 5117 5118 return false; 5119 } 5120 5121} ); 5122 5123 5124/*! 5125 * jQuery UI Sortable 1.12.1 5126 * http://jqueryui.com 5127 * 5128 * Copyright jQuery Foundation and other contributors 5129 * Released under the MIT license. 5130 * http://jquery.org/license 5131 */ 5132 5133//>>label: Sortable 5134//>>group: Interactions 5135//>>description: Enables items in a list to be sorted using the mouse. 5136//>>docs: http://api.jqueryui.com/sortable/ 5137//>>demos: http://jqueryui.com/sortable/ 5138//>>css.structure: ../../themes/base/sortable.css 5139 5140 5141 5142var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { 5143 version: "1.12.1", 5144 widgetEventPrefix: "sort", 5145 ready: false, 5146 options: { 5147 appendTo: "parent", 5148 axis: false, 5149 connectWith: false, 5150 containment: false, 5151 cursor: "auto", 5152 cursorAt: false, 5153 dropOnEmpty: true, 5154 forcePlaceholderSize: false, 5155 forceHelperSize: false, 5156 grid: false, 5157 handle: false, 5158 helper: "original", 5159 items: "> *", 5160 opacity: false, 5161 placeholder: false, 5162 revert: false, 5163 scroll: true, 5164 scrollSensitivity: 20, 5165 scrollSpeed: 20, 5166 scope: "default", 5167 tolerance: "intersect", 5168 zIndex: 1000, 5169 5170 // Callbacks 5171 activate: null, 5172 beforeStop: null, 5173 change: null, 5174 deactivate: null, 5175 out: null, 5176 over: null, 5177 receive: null, 5178 remove: null, 5179 sort: null, 5180 start: null, 5181 stop: null, 5182 update: null 5183 }, 5184 5185 _isOverAxis: function( x, reference, size ) { 5186 return ( x >= reference ) && ( x < ( reference + size ) ); 5187 }, 5188 5189 _isFloating: function( item ) { 5190 return ( /left|right/ ).test( item.css( "float" ) ) || 5191 ( /inline|table-cell/ ).test( item.css( "display" ) ); 5192 }, 5193 5194 _create: function() { 5195 this.containerCache = {}; 5196 this._addClass( "ui-sortable" ); 5197 5198 //Get the items 5199 this.refresh(); 5200 5201 //Let's determine the parent's offset 5202 this.offset = this.element.offset(); 5203 5204 //Initialize mouse events for interaction 5205 this._mouseInit(); 5206 5207 this._setHandleClassName(); 5208 5209 //We're ready to go 5210 this.ready = true; 5211 5212 }, 5213 5214 _setOption: function( key, value ) { 5215 this._super( key, value ); 5216 5217 if ( key === "handle" ) { 5218 this._setHandleClassName(); 5219 } 5220 }, 5221 5222 _setHandleClassName: function() { 5223 var that = this; 5224 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 5225 $.each( this.items, function() { 5226 that._addClass( 5227 this.instance.options.handle ? 5228 this.item.find( this.instance.options.handle ) : 5229 this.item, 5230 "ui-sortable-handle" 5231 ); 5232 } ); 5233 }, 5234 5235 _destroy: function() { 5236 this._mouseDestroy(); 5237 5238 for ( var i = this.items.length - 1; i >= 0; i-- ) { 5239 this.items[ i ].item.removeData( this.widgetName + "-item" ); 5240 } 5241 5242 return this; 5243 }, 5244 5245 _mouseCapture: function( event, overrideHandle ) { 5246 var currentItem = null, 5247 validHandle = false, 5248 that = this; 5249 5250 if ( this.reverting ) { 5251 return false; 5252 } 5253 5254 if ( this.options.disabled || this.options.type === "static" ) { 5255 return false; 5256 } 5257 5258 //We have to refresh the items data once first 5259 this._refreshItems( event ); 5260 5261 //Find out if the clicked node (or one of its parents) is a actual item in this.items 5262 $( event.target ).parents().each( function() { 5263 if ( $.data( this, that.widgetName + "-item" ) === that ) { 5264 currentItem = $( this ); 5265 return false; 5266 } 5267 } ); 5268 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 5269 currentItem = $( event.target ); 5270 } 5271 5272 if ( !currentItem ) { 5273 return false; 5274 } 5275 if ( this.options.handle && !overrideHandle ) { 5276 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 5277 if ( this === event.target ) { 5278 validHandle = true; 5279 } 5280 } ); 5281 if ( !validHandle ) { 5282 return false;
vendor: 42,259 bytes, lines 5283-6659
5283 } 5284 } 5285 5286 this.currentItem = currentItem; 5287 this._removeCurrentsFromItems(); 5288 return true; 5289 5290 }, 5291 5292 _mouseStart: function( event, overrideHandle, noActivation ) { 5293 5294 var i, body, 5295 o = this.options; 5296 5297 this.currentContainer = this; 5298 5299 //We only need to call refreshPositions, because the refreshItems call has been moved to 5300 // mouseCapture 5301 this.refreshPositions(); 5302 5303 //Create and append the visible helper 5304 this.helper = this._createHelper( event ); 5305 5306 //Cache the helper size 5307 this._cacheHelperProportions(); 5308 5309 /* 5310 * - Position generation - 5311 * This block generates everything position related - it's the core of draggables. 5312 */ 5313 5314 //Cache the margins of the original element 5315 this._cacheMargins(); 5316 5317 //Get the next scrolling parent 5318 this.scrollParent = this.helper.scrollParent(); 5319 5320 //The element's absolute position on the page minus margins 5321 this.offset = this.currentItem.offset(); 5322 this.offset = { 5323 top: this.offset.top - this.margins.top, 5324 left: this.offset.left - this.margins.left 5325 }; 5326 5327 $.extend( this.offset, { 5328 click: { //Where the click happened, relative to the element 5329 left: event.pageX - this.offset.left, 5330 top: event.pageY - this.offset.top 5331 }, 5332 parent: this._getParentOffset(), 5333 5334 // This is a relative to absolute position minus the actual position calculation - 5335 // only used for relative positioned helper 5336 relative: this._getRelativeOffset() 5337 } ); 5338 5339 // Only after we got the offset, we can change the helper's position to absolute 5340 // TODO: Still need to figure out a way to make relative sorting possible 5341 this.helper.css( "position", "absolute" ); 5342 this.cssPosition = this.helper.css( "position" ); 5343 5344 //Generate the original position 5345 this.originalPosition = this._generatePosition( event ); 5346 this.originalPageX = event.pageX; 5347 this.originalPageY = event.pageY; 5348 5349 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 5350 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); 5351 5352 //Cache the former DOM position 5353 this.domPosition = { 5354 prev: this.currentItem.prev()[ 0 ], 5355 parent: this.currentItem.parent()[ 0 ] 5356 }; 5357 5358 // If the helper is not the original, hide the original so it's not playing any role during 5359 // the drag, won't cause anything bad this way 5360 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 5361 this.currentItem.hide(); 5362 } 5363 5364 //Create the placeholder 5365 this._createPlaceholder(); 5366 5367 //Set a containment if given in the options 5368 if ( o.containment ) { 5369 this._setContainment(); 5370 } 5371 5372 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 5373 body = this.document.find( "body" ); 5374 5375 // Support: IE 5376 this.storedCursor = body.css( "cursor" ); 5377 body.css( "cursor", o.cursor ); 5378 5379 this.storedStylesheet = 5380 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 5381 } 5382 5383 if ( o.opacity ) { // opacity option 5384 if ( this.helper.css( "opacity" ) ) { 5385 this._storedOpacity = this.helper.css( "opacity" ); 5386 } 5387 this.helper.css( "opacity", o.opacity ); 5388 } 5389 5390 if ( o.zIndex ) { // zIndex option 5391 if ( this.helper.css( "zIndex" ) ) { 5392 this._storedZIndex = this.helper.css( "zIndex" ); 5393 } 5394 this.helper.css( "zIndex", o.zIndex ); 5395 } 5396 5397 //Prepare scrolling 5398 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5399 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5400 this.overflowOffset = this.scrollParent.offset(); 5401 } 5402 5403 //Call callbacks 5404 this._trigger( "start", event, this._uiHash() ); 5405 5406 //Recache the helper size 5407 if ( !this._preserveHelperProportions ) { 5408 this._cacheHelperProportions(); 5409 } 5410 5411 //Post "activate" events to possible containers 5412 if ( !noActivation ) { 5413 for ( i = this.containers.length - 1; i >= 0; i-- ) { 5414 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 5415 } 5416 } 5417 5418 //Prepare possible droppables 5419 if ( $.ui.ddmanager ) { 5420 $.ui.ddmanager.current = this; 5421 } 5422 5423 if ( $.ui.ddmanager && !o.dropBehaviour ) { 5424 $.ui.ddmanager.prepareOffsets( this, event ); 5425 } 5426 5427 this.dragging = true; 5428 5429 this._addClass( this.helper, "ui-sortable-helper" ); 5430 5431 // Execute the drag once - this causes the helper not to be visiblebefore getting its 5432 // correct position 5433 this._mouseDrag( event ); 5434 return true; 5435 5436 }, 5437 5438 _mouseDrag: function( event ) { 5439 var i, item, itemElement, intersection, 5440 o = this.options, 5441 scrolled = false; 5442 5443 //Compute the helpers position 5444 this.position = this._generatePosition( event ); 5445 this.positionAbs = this._convertPositionTo( "absolute" ); 5446 5447 if ( !this.lastPositionAbs ) { 5448 this.lastPositionAbs = this.positionAbs; 5449 } 5450 5451 //Do scrolling 5452 if ( this.options.scroll ) { 5453 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5454 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5455 5456 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 5457 event.pageY < o.scrollSensitivity ) { 5458 this.scrollParent[ 0 ].scrollTop = 5459 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 5460 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 5461 this.scrollParent[ 0 ].scrollTop = 5462 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 5463 } 5464 5465 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 5466 event.pageX < o.scrollSensitivity ) { 5467 this.scrollParent[ 0 ].scrollLeft = scrolled = 5468 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 5469 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 5470 this.scrollParent[ 0 ].scrollLeft = scrolled = 5471 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 5472 } 5473 5474 } else { 5475 5476 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 5477 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 5478 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 5479 o.scrollSensitivity ) { 5480 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 5481 } 5482 5483 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 5484 scrolled = this.document.scrollLeft( 5485 this.document.scrollLeft() - o.scrollSpeed 5486 ); 5487 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 5488 o.scrollSensitivity ) { 5489 scrolled = this.document.scrollLeft( 5490 this.document.scrollLeft() + o.scrollSpeed 5491 ); 5492 } 5493 5494 } 5495 5496 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 5497 $.ui.ddmanager.prepareOffsets( this, event ); 5498 } 5499 } 5500 5501 //Regenerate the absolute position used for position checks 5502 this.positionAbs = this._convertPositionTo( "absolute" ); 5503 5504 //Set the helper position 5505 if ( !this.options.axis || this.options.axis !== "y" ) { 5506 this.helper[ 0 ].style.left = this.position.left + "px"; 5507 } 5508 if ( !this.options.axis || this.options.axis !== "x" ) { 5509 this.helper[ 0 ].style.top = this.position.top + "px"; 5510 } 5511 5512 //Rearrange 5513 for ( i = this.items.length - 1; i >= 0; i-- ) { 5514 5515 //Cache variables and intersection, continue if no intersection 5516 item = this.items[ i ]; 5517 itemElement = item.item[ 0 ]; 5518 intersection = this._intersectsWithPointer( item ); 5519 if ( !intersection ) { 5520 continue; 5521 } 5522 5523 // Only put the placeholder inside the current Container, skip all 5524 // items from other containers. This works because when moving 5525 // an item from one container to another the 5526 // currentContainer is switched before the placeholder is moved. 5527 // 5528 // Without this, moving items in "sub-sortables" can cause 5529 // the placeholder to jitter between the outer and inner container. 5530 if ( item.instance !== this.currentContainer ) { 5531 continue; 5532 } 5533 5534 // Cannot intersect with itself 5535 // no useless actions that have been done before 5536 // no action if the item moved is the parent of the item checked 5537 if ( itemElement !== this.currentItem[ 0 ] && 5538 this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement && 5539 !$.contains( this.placeholder[ 0 ], itemElement ) && 5540 ( this.options.type === "semi-dynamic" ? 5541 !$.contains( this.element[ 0 ], itemElement ) : 5542 true 5543 ) 5544 ) { 5545 5546 this.direction = intersection === 1 ? "down" : "up"; 5547 5548 if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) { 5549 this._rearrange( event, item ); 5550 } else { 5551 break; 5552 } 5553 5554 this._trigger( "change", event, this._uiHash() ); 5555 break; 5556 } 5557 } 5558 5559 //Post events to containers 5560 this._contactContainers( event ); 5561 5562 //Interconnect with droppables 5563 if ( $.ui.ddmanager ) { 5564 $.ui.ddmanager.drag( this, event ); 5565 } 5566 5567 //Call callbacks 5568 this._trigger( "sort", event, this._uiHash() ); 5569 5570 this.lastPositionAbs = this.positionAbs; 5571 return false; 5572 5573 }, 5574 5575 _mouseStop: function( event, noPropagation ) { 5576 5577 if ( !event ) { 5578 return; 5579 } 5580 5581 //If we are using droppables, inform the manager about the drop 5582 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 5583 $.ui.ddmanager.drop( this, event ); 5584 } 5585 5586 if ( this.options.revert ) { 5587 var that = this, 5588 cur = this.placeholder.offset(), 5589 axis = this.options.axis, 5590 animation = {}; 5591 5592 if ( !axis || axis === "x" ) { 5593 animation.left = cur.left - this.offset.parent.left - this.margins.left + 5594 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5595 0 : 5596 this.offsetParent[ 0 ].scrollLeft 5597 ); 5598 } 5599 if ( !axis || axis === "y" ) { 5600 animation.top = cur.top - this.offset.parent.top - this.margins.top + 5601 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5602 0 : 5603 this.offsetParent[ 0 ].scrollTop 5604 ); 5605 } 5606 this.reverting = true; 5607 $( this.helper ).animate( 5608 animation, 5609 parseInt( this.options.revert, 10 ) || 500, 5610 function() { 5611 that._clear( event ); 5612 } 5613 ); 5614 } else { 5615 this._clear( event, noPropagation ); 5616 } 5617 5618 return false; 5619 5620 }, 5621 5622 cancel: function() { 5623 5624 if ( this.dragging ) { 5625 5626 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 5627 5628 if ( this.options.helper === "original" ) { 5629 this.currentItem.css( this._storedCSS ); 5630 this._removeClass( this.currentItem, "ui-sortable-helper" ); 5631 } else { 5632 this.currentItem.show(); 5633 } 5634 5635 //Post deactivating events to containers 5636 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 5637 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 5638 if ( this.containers[ i ].containerCache.over ) { 5639 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 5640 this.containers[ i ].containerCache.over = 0; 5641 } 5642 } 5643 5644 } 5645 5646 if ( this.placeholder ) { 5647 5648 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 5649 // it unbinds ALL events from the original node! 5650 if ( this.placeholder[ 0 ].parentNode ) { 5651 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 5652 } 5653 if ( this.options.helper !== "original" && this.helper && 5654 this.helper[ 0 ].parentNode ) { 5655 this.helper.remove(); 5656 } 5657 5658 $.extend( this, { 5659 helper: null, 5660 dragging: false, 5661 reverting: false, 5662 _noFinalSort: null 5663 } ); 5664 5665 if ( this.domPosition.prev ) { 5666 $( this.domPosition.prev ).after( this.currentItem ); 5667 } else { 5668 $( this.domPosition.parent ).prepend( this.currentItem ); 5669 } 5670 } 5671 5672 return this; 5673 5674 }, 5675 5676 serialize: function( o ) { 5677 5678 var items = this._getItemsAsjQuery( o && o.connected ), 5679 str = []; 5680 o = o || {}; 5681 5682 $( items ).each( function() { 5683 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 5684 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 5685 if ( res ) { 5686 str.push( 5687 ( o.key || res[ 1 ] + "[]" ) + 5688 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 5689 } 5690 } ); 5691 5692 if ( !str.length && o.key ) { 5693 str.push( o.key + "=" ); 5694 } 5695 5696 return str.join( "&" ); 5697 5698 }, 5699 5700 toArray: function( o ) { 5701 5702 var items = this._getItemsAsjQuery( o && o.connected ), 5703 ret = []; 5704 5705 o = o || {}; 5706 5707 items.each( function() { 5708 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 5709 } ); 5710 return ret; 5711 5712 }, 5713 5714 /* Be careful with the following core functions */ 5715 _intersectsWith: function( item ) { 5716 5717 var x1 = this.positionAbs.left, 5718 x2 = x1 + this.helperProportions.width, 5719 y1 = this.positionAbs.top, 5720 y2 = y1 + this.helperProportions.height, 5721 l = item.left, 5722 r = l + item.width, 5723 t = item.top, 5724 b = t + item.height, 5725 dyClick = this.offset.click.top, 5726 dxClick = this.offset.click.left, 5727 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 5728 ( y1 + dyClick ) < b ), 5729 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 5730 ( x1 + dxClick ) < r ), 5731 isOverElement = isOverElementHeight && isOverElementWidth; 5732 5733 if ( this.options.tolerance === "pointer" || 5734 this.options.forcePointerForContainers || 5735 ( this.options.tolerance !== "pointer" && 5736 this.helperProportions[ this.floating ? "width" : "height" ] > 5737 item[ this.floating ? "width" : "height" ] ) 5738 ) { 5739 return isOverElement; 5740 } else { 5741 5742 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 5743 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 5744 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 5745 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 5746 5747 } 5748 }, 5749 5750 _intersectsWithPointer: function( item ) { 5751 var verticalDirection, horizontalDirection, 5752 isOverElementHeight = ( this.options.axis === "x" ) || 5753 this._isOverAxis( 5754 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 5755 isOverElementWidth = ( this.options.axis === "y" ) || 5756 this._isOverAxis( 5757 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 5758 isOverElement = isOverElementHeight && isOverElementWidth; 5759 5760 if ( !isOverElement ) { 5761 return false; 5762 } 5763 5764 verticalDirection = this._getDragVerticalDirection(); 5765 horizontalDirection = this._getDragHorizontalDirection(); 5766 5767 return this.floating ? 5768 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) 5769 : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 5770 5771 }, 5772 5773 _intersectsWithSides: function( item ) { 5774 5775 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 5776 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 5777 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 5778 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 5779 verticalDirection = this._getDragVerticalDirection(), 5780 horizontalDirection = this._getDragHorizontalDirection(); 5781 5782 if ( this.floating && horizontalDirection ) { 5783 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 5784 ( horizontalDirection === "left" && !isOverRightHalf ) ); 5785 } else { 5786 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 5787 ( verticalDirection === "up" && !isOverBottomHalf ) ); 5788 } 5789 5790 }, 5791 5792 _getDragVerticalDirection: function() { 5793 var delta = this.positionAbs.top - this.lastPositionAbs.top; 5794 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 5795 }, 5796 5797 _getDragHorizontalDirection: function() { 5798 var delta = this.positionAbs.left - this.lastPositionAbs.left; 5799 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 5800 }, 5801 5802 refresh: function( event ) { 5803 this._refreshItems( event ); 5804 this._setHandleClassName(); 5805 this.refreshPositions(); 5806 return this; 5807 }, 5808 5809 _connectWith: function() { 5810 var options = this.options; 5811 return options.connectWith.constructor === String ? 5812 [ options.connectWith ] : 5813 options.connectWith; 5814 }, 5815 5816 _getItemsAsjQuery: function( connected ) { 5817 5818 var i, j, cur, inst, 5819 items = [], 5820 queries = [], 5821 connectWith = this._connectWith(); 5822 5823 if ( connectWith && connected ) { 5824 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5825 cur = $( connectWith[ i ], this.document[ 0 ] ); 5826 for ( j = cur.length - 1; j >= 0; j-- ) { 5827 inst = $.data( cur[ j ], this.widgetFullName ); 5828 if ( inst && inst !== this && !inst.options.disabled ) { 5829 queries.push( [ $.isFunction( inst.options.items ) ? 5830 inst.options.items.call( inst.element ) : 5831 $( inst.options.items, inst.element ) 5832 .not( ".ui-sortable-helper" ) 5833 .not( ".ui-sortable-placeholder" ), inst ] ); 5834 } 5835 } 5836 } 5837 } 5838 5839 queries.push( [ $.isFunction( this.options.items ) ? 5840 this.options.items 5841 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 5842 $( this.options.items, this.element ) 5843 .not( ".ui-sortable-helper" ) 5844 .not( ".ui-sortable-placeholder" ), this ] ); 5845 5846 function addItems() { 5847 items.push( this ); 5848 } 5849 for ( i = queries.length - 1; i >= 0; i-- ) { 5850 queries[ i ][ 0 ].each( addItems ); 5851 } 5852 5853 return $( items ); 5854 5855 }, 5856 5857 _removeCurrentsFromItems: function() { 5858 5859 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 5860 5861 this.items = $.grep( this.items, function( item ) { 5862 for ( var j = 0; j < list.length; j++ ) { 5863 if ( list[ j ] === item.item[ 0 ] ) { 5864 return false; 5865 } 5866 } 5867 return true; 5868 } ); 5869 5870 }, 5871 5872 _refreshItems: function( event ) { 5873 5874 this.items = []; 5875 this.containers = [ this ]; 5876 5877 var i, j, cur, inst, targetData, _queries, item, queriesLength, 5878 items = this.items, 5879 queries = [ [ $.isFunction( this.options.items ) ? 5880 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 5881 $( this.options.items, this.element ), this ] ], 5882 connectWith = this._connectWith(); 5883 5884 //Shouldn't be run the first time through due to massive slow-down 5885 if ( connectWith && this.ready ) { 5886 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5887 cur = $( connectWith[ i ], this.document[ 0 ] ); 5888 for ( j = cur.length - 1; j >= 0; j-- ) { 5889 inst = $.data( cur[ j ], this.widgetFullName ); 5890 if ( inst && inst !== this && !inst.options.disabled ) { 5891 queries.push( [ $.isFunction( inst.options.items ) ? 5892 inst.options.items 5893 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 5894 $( inst.options.items, inst.element ), inst ] ); 5895 this.containers.push( inst ); 5896 } 5897 } 5898 } 5899 } 5900 5901 for ( i = queries.length - 1; i >= 0; i-- ) { 5902 targetData = queries[ i ][ 1 ]; 5903 _queries = queries[ i ][ 0 ]; 5904 5905 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 5906 item = $( _queries[ j ] ); 5907 5908 // Data for target checking (mouse manager) 5909 item.data( this.widgetName + "-item", targetData ); 5910 5911 items.push( { 5912 item: item, 5913 instance: targetData, 5914 width: 0, height: 0, 5915 left: 0, top: 0 5916 } ); 5917 } 5918 } 5919 5920 }, 5921 5922 refreshPositions: function( fast ) { 5923 5924 // Determine whether items are being displayed horizontally 5925 this.floating = this.items.length ? 5926 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 5927 false; 5928 5929 //This has to be redone because due to the item being moved out/into the offsetParent, 5930 // the offsetParent's position will change 5931 if ( this.offsetParent && this.helper ) { 5932 this.offset.parent = this._getParentOffset(); 5933 } 5934 5935 var i, item, t, p; 5936 5937 for ( i = this.items.length - 1; i >= 0; i-- ) { 5938 item = this.items[ i ]; 5939 5940 //We ignore calculating positions of all connected containers when we're not over them 5941 if ( item.instance !== this.currentContainer && this.currentContainer && 5942 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 5943 continue; 5944 } 5945 5946 t = this.options.toleranceElement ? 5947 $( this.options.toleranceElement, item.item ) : 5948 item.item; 5949 5950 if ( !fast ) { 5951 item.width = t.outerWidth(); 5952 item.height = t.outerHeight(); 5953 } 5954 5955 p = t.offset(); 5956 item.left = p.left; 5957 item.top = p.top; 5958 } 5959 5960 if ( this.options.custom && this.options.custom.refreshContainers ) { 5961 this.options.custom.refreshContainers.call( this ); 5962 } else { 5963 for ( i = this.containers.length - 1; i >= 0; i-- ) { 5964 p = this.containers[ i ].element.offset(); 5965 this.containers[ i ].containerCache.left = p.left; 5966 this.containers[ i ].containerCache.top = p.top; 5967 this.containers[ i ].containerCache.width = 5968 this.containers[ i ].element.outerWidth(); 5969 this.containers[ i ].containerCache.height = 5970 this.containers[ i ].element.outerHeight(); 5971 } 5972 } 5973 5974 return this; 5975 }, 5976 5977 _createPlaceholder: function( that ) { 5978 that = that || this; 5979 var className, 5980 o = that.options; 5981 5982 if ( !o.placeholder || o.placeholder.constructor === String ) { 5983 className = o.placeholder; 5984 o.placeholder = { 5985 element: function() { 5986 5987 var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(), 5988 element = $( "<" + nodeName + ">", that.document[ 0 ] ); 5989 5990 that._addClass( element, "ui-sortable-placeholder", 5991 className || that.currentItem[ 0 ].className ) 5992 ._removeClass( element, "ui-sortable-helper" ); 5993 5994 if ( nodeName === "tbody" ) { 5995 that._createTrPlaceholder( 5996 that.currentItem.find( "tr" ).eq( 0 ), 5997 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 5998 ); 5999 } else if ( nodeName === "tr" ) { 6000 that._createTrPlaceholder( that.currentItem, element ); 6001 } else if ( nodeName === "img" ) { 6002 element.attr( "src", that.currentItem.attr( "src" ) ); 6003 } 6004 6005 if ( !className ) { 6006 element.css( "visibility", "hidden" ); 6007 } 6008 6009 return element; 6010 }, 6011 update: function( container, p ) { 6012 6013 // 1. If a className is set as 'placeholder option, we don't force sizes - 6014 // the class is responsible for that 6015 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 6016 // class name is specified 6017 if ( className && !o.forcePlaceholderSize ) { 6018 return; 6019 } 6020 6021 //If the element doesn't have a actual height by itself (without styles coming 6022 // from a stylesheet), it receives the inline height from the dragged item 6023 if ( !p.height() ) { 6024 p.height( 6025 that.currentItem.innerHeight() - 6026 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 6027 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 6028 } 6029 if ( !p.width() ) { 6030 p.width( 6031 that.currentItem.innerWidth() - 6032 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 6033 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 6034 } 6035 } 6036 }; 6037 } 6038 6039 //Create the placeholder 6040 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 6041 6042 //Append it after the actual current item 6043 that.currentItem.after( that.placeholder ); 6044 6045 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 6046 o.placeholder.update( that, that.placeholder ); 6047 6048 }, 6049 6050 _createTrPlaceholder: function( sourceTr, targetTr ) { 6051 var that = this; 6052 6053 sourceTr.children().each( function() { 6054 $( "<td> </td>", that.document[ 0 ] ) 6055 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 6056 .appendTo( targetTr ); 6057 } ); 6058 }, 6059 6060 _contactContainers: function( event ) { 6061 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 6062 floating, axis, 6063 innermostContainer = null, 6064 innermostIndex = null; 6065 6066 // Get innermost container that intersects with item 6067 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6068 6069 // Never consider a container that's located within the item itself 6070 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 6071 continue; 6072 } 6073 6074 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 6075 6076 // If we've already found a container and it's more "inner" than this, then continue 6077 if ( innermostContainer && 6078 $.contains( 6079 this.containers[ i ].element[ 0 ], 6080 innermostContainer.element[ 0 ] ) ) { 6081 continue; 6082 } 6083 6084 innermostContainer = this.containers[ i ]; 6085 innermostIndex = i; 6086 6087 } else { 6088 6089 // container doesn't intersect. trigger "out" event if necessary 6090 if ( this.containers[ i ].containerCache.over ) { 6091 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 6092 this.containers[ i ].containerCache.over = 0; 6093 } 6094 } 6095 6096 } 6097 6098 // If no intersecting containers found, return 6099 if ( !innermostContainer ) { 6100 return; 6101 } 6102 6103 // Move the item into the container if it's not there already 6104 if ( this.containers.length === 1 ) { 6105 if ( !this.containers[ innermostIndex ].containerCache.over ) { 6106 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6107 this.containers[ innermostIndex ].containerCache.over = 1; 6108 } 6109 } else { 6110 6111 // When entering a new container, we will find the item with the least distance and 6112 // append our item near it 6113 dist = 10000; 6114 itemWithLeastDistance = null; 6115 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 6116 posProperty = floating ? "left" : "top"; 6117 sizeProperty = floating ? "width" : "height"; 6118 axis = floating ? "pageX" : "pageY"; 6119 6120 for ( j = this.items.length - 1; j >= 0; j-- ) { 6121 if ( !$.contains( 6122 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 6123 ) { 6124 continue; 6125 } 6126 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 6127 continue; 6128 } 6129 6130 cur = this.items[ j ].item.offset()[ posProperty ]; 6131 nearBottom = false; 6132 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 6133 nearBottom = true; 6134 } 6135 6136 if ( Math.abs( event[ axis ] - cur ) < dist ) { 6137 dist = Math.abs( event[ axis ] - cur ); 6138 itemWithLeastDistance = this.items[ j ]; 6139 this.direction = nearBottom ? "up" : "down"; 6140 } 6141 } 6142 6143 //Check if dropOnEmpty is enabled 6144 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 6145 return; 6146 } 6147 6148 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 6149 if ( !this.currentContainer.containerCache.over ) { 6150 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 6151 this.currentContainer.containerCache.over = 1; 6152 } 6153 return; 6154 } 6155 6156 itemWithLeastDistance ? 6157 this._rearrange( event, itemWithLeastDistance, null, true ) : 6158 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 6159 this._trigger( "change", event, this._uiHash() ); 6160 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 6161 this.currentContainer = this.containers[ innermostIndex ]; 6162 6163 //Update the placeholder 6164 this.options.placeholder.update( this.currentContainer, this.placeholder ); 6165 6166 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6167 this.containers[ innermostIndex ].containerCache.over = 1; 6168 } 6169 6170 }, 6171 6172 _createHelper: function( event ) { 6173 6174 var o = this.options, 6175 helper = $.isFunction( o.helper ) ? 6176 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 6177 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 6178 6179 //Add the helper to the DOM if that didn't happen already 6180 if ( !helper.parents( "body" ).length ) { 6181 $( o.appendTo !== "parent" ? 6182 o.appendTo : 6183 this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); 6184 } 6185 6186 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 6187 this._storedCSS = { 6188 width: this.currentItem[ 0 ].style.width, 6189 height: this.currentItem[ 0 ].style.height, 6190 position: this.currentItem.css( "position" ), 6191 top: this.currentItem.css( "top" ), 6192 left: this.currentItem.css( "left" ) 6193 }; 6194 } 6195 6196 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 6197 helper.width( this.currentItem.width() ); 6198 } 6199 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 6200 helper.height( this.currentItem.height() ); 6201 } 6202 6203 return helper; 6204 6205 }, 6206 6207 _adjustOffsetFromHelper: function( obj ) { 6208 if ( typeof obj === "string" ) { 6209 obj = obj.split( " " ); 6210 } 6211 if ( $.isArray( obj ) ) { 6212 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 6213 } 6214 if ( "left" in obj ) { 6215 this.offset.click.left = obj.left + this.margins.left; 6216 } 6217 if ( "right" in obj ) { 6218 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6219 } 6220 if ( "top" in obj ) { 6221 this.offset.click.top = obj.top + this.margins.top; 6222 } 6223 if ( "bottom" in obj ) { 6224 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6225 } 6226 }, 6227 6228 _getParentOffset: function() { 6229 6230 //Get the offsetParent and cache its position 6231 this.offsetParent = this.helper.offsetParent(); 6232 var po = this.offsetParent.offset(); 6233 6234 // This is a special case where we need to modify a offset calculated on start, since the 6235 // following happened: 6236 // 1. The position of the helper is absolute, so it's position is calculated based on the 6237 // next positioned parent 6238 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 6239 // the document, which means that the scroll is included in the initial calculation of the 6240 // offset of the parent, and never recalculated upon drag 6241 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 6242 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 6243 po.left += this.scrollParent.scrollLeft(); 6244 po.top += this.scrollParent.scrollTop(); 6245 } 6246 6247 // This needs to be actually done for all browsers, since pageX/pageY includes this 6248 // information with an ugly IE fix 6249 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || 6250 ( this.offsetParent[ 0 ].tagName && 6251 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { 6252 po = { top: 0, left: 0 }; 6253 } 6254 6255 return { 6256 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 6257 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 6258 }; 6259 6260 }, 6261 6262 _getRelativeOffset: function() { 6263 6264 if ( this.cssPosition === "relative" ) { 6265 var p = this.currentItem.position(); 6266 return { 6267 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 6268 this.scrollParent.scrollTop(), 6269 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 6270 this.scrollParent.scrollLeft() 6271 }; 6272 } else { 6273 return { top: 0, left: 0 }; 6274 } 6275 6276 }, 6277 6278 _cacheMargins: function() { 6279 this.margins = { 6280 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 6281 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 6282 }; 6283 }, 6284 6285 _cacheHelperProportions: function() { 6286 this.helperProportions = { 6287 width: this.helper.outerWidth(), 6288 height: this.helper.outerHeight() 6289 }; 6290 }, 6291 6292 _setContainment: function() { 6293 6294 var ce, co, over, 6295 o = this.options; 6296 if ( o.containment === "parent" ) { 6297 o.containment = this.helper[ 0 ].parentNode; 6298 } 6299 if ( o.containment === "document" || o.containment === "window" ) { 6300 this.containment = [ 6301 0 - this.offset.relative.left - this.offset.parent.left, 6302 0 - this.offset.relative.top - this.offset.parent.top, 6303 o.containment === "document" ? 6304 this.document.width() : 6305 this.window.width() - this.helperProportions.width - this.margins.left, 6306 ( o.containment === "document" ? 6307 ( this.document.height() || document.body.parentNode.scrollHeight ) : 6308 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 6309 ) - this.helperProportions.height - this.margins.top 6310 ]; 6311 } 6312 6313 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 6314 ce = $( o.containment )[ 0 ]; 6315 co = $( o.containment ).offset(); 6316 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 6317 6318 this.containment = [ 6319 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 6320 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 6321 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 6322 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 6323 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 6324 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 6325 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 6326 this.helperProportions.width - this.margins.left, 6327 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 6328 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 6329 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 6330 this.helperProportions.height - this.margins.top 6331 ]; 6332 } 6333 6334 }, 6335 6336 _convertPositionTo: function( d, pos ) { 6337 6338 if ( !pos ) { 6339 pos = this.position; 6340 } 6341 var mod = d === "absolute" ? 1 : -1, 6342 scroll = this.cssPosition === "absolute" && 6343 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6344 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6345 this.offsetParent : 6346 this.scrollParent, 6347 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6348 6349 return { 6350 top: ( 6351 6352 // The absolute mouse position 6353 pos.top + 6354 6355 // Only for relative positioned nodes: Relative offset from element to offset parent 6356 this.offset.relative.top * mod + 6357 6358 // The offsetParent's offset without borders (offset + border) 6359 this.offset.parent.top * mod - 6360 ( ( this.cssPosition === "fixed" ? 6361 -this.scrollParent.scrollTop() : 6362 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 6363 ), 6364 left: ( 6365 6366 // The absolute mouse position 6367 pos.left + 6368 6369 // Only for relative positioned nodes: Relative offset from element to offset parent 6370 this.offset.relative.left * mod + 6371 6372 // The offsetParent's offset without borders (offset + border) 6373 this.offset.parent.left * mod - 6374 ( ( this.cssPosition === "fixed" ? 6375 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : 6376 scroll.scrollLeft() ) * mod ) 6377 ) 6378 }; 6379 6380 }, 6381 6382 _generatePosition: function( event ) { 6383 6384 var top, left, 6385 o = this.options, 6386 pageX = event.pageX, 6387 pageY = event.pageY, 6388 scroll = this.cssPosition === "absolute" && 6389 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6390 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6391 this.offsetParent : 6392 this.scrollParent, 6393 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6394 6395 // This is another very weird special case that only happens for relative elements: 6396 // 1. If the css position is relative 6397 // 2. and the scroll parent is the document or similar to the offset parent 6398 // we have to refresh the relative offset during the scroll so there are no jumps 6399 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6400 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 6401 this.offset.relative = this._getRelativeOffset(); 6402 } 6403 6404 /* 6405 * - Position constraining - 6406 * Constrain the position to a mix of grid, containment. 6407 */ 6408 6409 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 6410 6411 if ( this.containment ) { 6412 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 6413 pageX = this.containment[ 0 ] + this.offset.click.left; 6414 } 6415 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 6416 pageY = this.containment[ 1 ] + this.offset.click.top; 6417 } 6418 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 6419 pageX = this.containment[ 2 ] + this.offset.click.left; 6420 } 6421 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 6422 pageY = this.containment[ 3 ] + this.offset.click.top; 6423 } 6424 } 6425 6426 if ( o.grid ) { 6427 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 6428 o.grid[ 1 ] ) * o.grid[ 1 ]; 6429 pageY = this.containment ? 6430 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 6431 top - this.offset.click.top <= this.containment[ 3 ] ) ? 6432 top : 6433 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 6434 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 6435 top; 6436 6437 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 6438 o.grid[ 0 ] ) * o.grid[ 0 ]; 6439 pageX = this.containment ? 6440 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 6441 left - this.offset.click.left <= this.containment[ 2 ] ) ? 6442 left : 6443 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 6444 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 6445 left; 6446 } 6447 6448 } 6449 6450 return { 6451 top: ( 6452 6453 // The absolute mouse position 6454 pageY - 6455 6456 // Click offset (relative to the element) 6457 this.offset.click.top - 6458 6459 // Only for relative positioned nodes: Relative offset from element to offset parent 6460 this.offset.relative.top - 6461 6462 // The offsetParent's offset without borders (offset + border) 6463 this.offset.parent.top + 6464 ( ( this.cssPosition === "fixed" ? 6465 -this.scrollParent.scrollTop() : 6466 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 6467 ), 6468 left: ( 6469 6470 // The absolute mouse position 6471 pageX - 6472 6473 // Click offset (relative to the element) 6474 this.offset.click.left - 6475 6476 // Only for relative positioned nodes: Relative offset from element to offset parent 6477 this.offset.relative.left - 6478 6479 // The offsetParent's offset without borders (offset + border) 6480 this.offset.parent.left + 6481 ( ( this.cssPosition === "fixed" ? 6482 -this.scrollParent.scrollLeft() : 6483 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 6484 ) 6485 }; 6486 6487 }, 6488 6489 _rearrange: function( event, i, a, hardRefresh ) { 6490 6491 a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : 6492 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 6493 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 6494 6495 //Various things done here to improve the performance: 6496 // 1. we create a setTimeout, that calls refreshPositions 6497 // 2. on the instance, we have a counter variable, that get's higher after every append 6498 // 3. on the local scope, we copy the counter variable, and check in the timeout, 6499 // if it's still the same 6500 // 4. this lets only the last addition to the timeout stack through 6501 this.counter = this.counter ? ++this.counter : 1; 6502 var counter = this.counter; 6503 6504 this._delay( function() { 6505 if ( counter === this.counter ) { 6506 6507 //Precompute after each DOM insertion, NOT on mousemove 6508 this.refreshPositions( !hardRefresh ); 6509 } 6510 } ); 6511 6512 }, 6513 6514 _clear: function( event, noPropagation ) { 6515 6516 this.reverting = false; 6517 6518 // We delay all events that have to be triggered to after the point where the placeholder 6519 // has been removed and everything else normalized again 6520 var i, 6521 delayedTriggers = []; 6522 6523 // We first have to update the dom position of the actual currentItem 6524 // Note: don't do it if the current item is already removed (by a user), or it gets 6525 // reappended (see #4088) 6526 if ( !this._noFinalSort && this.currentItem.parent().length ) { 6527 this.placeholder.before( this.currentItem ); 6528 } 6529 this._noFinalSort = null; 6530 6531 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 6532 for ( i in this._storedCSS ) { 6533 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 6534 this._storedCSS[ i ] = ""; 6535 } 6536 } 6537 this.currentItem.css( this._storedCSS ); 6538 this._removeClass( this.currentItem, "ui-sortable-helper" ); 6539 } else { 6540 this.currentItem.show(); 6541 } 6542 6543 if ( this.fromOutside && !noPropagation ) { 6544 delayedTriggers.push( function( event ) { 6545 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 6546 } ); 6547 } 6548 if ( ( this.fromOutside || 6549 this.domPosition.prev !== 6550 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 6551 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 6552 6553 // Trigger update callback if the DOM position has changed 6554 delayedTriggers.push( function( event ) { 6555 this._trigger( "update", event, this._uiHash() ); 6556 } ); 6557 } 6558 6559 // Check if the items Container has Changed and trigger appropriate 6560 // events. 6561 if ( this !== this.currentContainer ) { 6562 if ( !noPropagation ) { 6563 delayedTriggers.push( function( event ) { 6564 this._trigger( "remove", event, this._uiHash() ); 6565 } ); 6566 delayedTriggers.push( ( function( c ) { 6567 return function( event ) { 6568 c._trigger( "receive", event, this._uiHash( this ) ); 6569 }; 6570 } ).call( this, this.currentContainer ) ); 6571 delayedTriggers.push( ( function( c ) { 6572 return function( event ) { 6573 c._trigger( "update", event, this._uiHash( this ) ); 6574 }; 6575 } ).call( this, this.currentContainer ) ); 6576 } 6577 } 6578 6579 //Post events to containers 6580 function delayEvent( type, instance, container ) { 6581 return function( event ) { 6582 container._trigger( type, event, instance._uiHash( instance ) ); 6583 }; 6584 } 6585 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6586 if ( !noPropagation ) { 6587 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 6588 } 6589 if ( this.containers[ i ].containerCache.over ) { 6590 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 6591 this.containers[ i ].containerCache.over = 0; 6592 } 6593 } 6594 6595 //Do what was originally in plugins 6596 if ( this.storedCursor ) { 6597 this.document.find( "body" ).css( "cursor", this.storedCursor ); 6598 this.storedStylesheet.remove(); 6599 } 6600 if ( this._storedOpacity ) { 6601 this.helper.css( "opacity", this._storedOpacity ); 6602 } 6603 if ( this._storedZIndex ) { 6604 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 6605 } 6606 6607 this.dragging = false; 6608 6609 if ( !noPropagation ) { 6610 this._trigger( "beforeStop", event, this._uiHash() ); 6611 } 6612 6613 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 6614 // it unbinds ALL events from the original node! 6615 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 6616 6617 if ( !this.cancelHelperRemoval ) { 6618 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 6619 this.helper.remove(); 6620 } 6621 this.helper = null; 6622 } 6623 6624 if ( !noPropagation ) { 6625 for ( i = 0; i < delayedTriggers.length; i++ ) { 6626 6627 // Trigger all delayed events 6628 delayedTriggers[ i ].call( this, event ); 6629 } 6630 this._trigger( "stop", event, this._uiHash() ); 6631 } 6632 6633 this.fromOutside = false; 6634 return !this.cancelHelperRemoval; 6635 6636 }, 6637 6638 _trigger: function() { 6639 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 6640 this.cancel(); 6641 } 6642 }, 6643 6644 _uiHash: function( _inst ) { 6645 var inst = _inst || this; 6646 return { 6647 helper: inst.helper, 6648 placeholder: inst.placeholder || $( [] ), 6649 position: inst.position, 6650 originalPosition: inst.originalPosition, 6651 offset: inst.positionAbs, 6652 item: inst.currentItem, 6653 sender: _inst ? _inst.element : null 6654 }; 6655 } 6656 6657} ); 6658 6659
6660 6661 6662}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.