1/*! jQuery UI - v1.14.2 - 2026-02-23 2* https://jqueryui.com 3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-patch.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/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer
vendor: 25,280 bytes, lines 3-943
3.js 4* Copyright OpenJS Foundation and other contributors; Licensed MIT */ 5 6( function( factory ) { 7 "use strict"; 8 9 if ( typeof define === "function" && define.amd ) { 10 11 // AMD. Register as an anonymous module. 12 define( [ "jquery" ], factory ); 13 } else { 14 15 // Browser globals 16 factory( jQuery ); 17 } 18} )( function( $ ) { 19"use strict"; 20 21$.ui = $.ui || {}; 22 23var version = $.ui.version = "1.14.2"; 24 25 26/*! 27 * jQuery UI Widget 1.14.2 28 * https://jqueryui.com 29 * 30 * Copyright OpenJS Foundation and other contributors 31 * Released under the MIT license. 32 * https://jquery.org/license 33 */ 34 35//>>label: Widget 36//>>group: Core 37//>>description: Provides a factory for creating stateful widgets with a common API. 38//>>docs: https://api.jqueryui.com/jQuery.widget/ 39//>>demos: https://jqueryui.com/widget/ 40 41 42var widgetUuid = 0; 43var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 44var widgetSlice = Array.prototype.slice; 45 46$.cleanData = ( function( orig ) { 47 return function( elems ) { 48 var events, elem, i; 49 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 50 51 // Only trigger remove when necessary to save time 52 events = $._data( elem, "events" ); 53 if ( events && events.remove ) { 54 $( elem ).triggerHandler( "remove" ); 55 } 56 } 57 orig( elems ); 58 }; 59} )( $.cleanData ); 60 61$.widget = function( name, base, prototype ) { 62 var existingConstructor, constructor, basePrototype; 63 64 // ProxiedPrototype allows the provided prototype to remain unmodified 65 // so that it can be used as a mixin for multiple widgets (#8876) 66 var proxiedPrototype = {}; 67 68 var namespace = name.split( "." )[ 0 ]; 69 name = name.split( "." )[ 1 ]; 70 if ( name === "__proto__" || name === "constructor" ) { 71 return $.error( "Invalid widget name: " + name ); 72 } 73 var fullName = namespace + "-" + name; 74 75 if ( !prototype ) { 76 prototype = base; 77 base = $.Widget; 78 } 79 80 if ( Array.isArray( prototype ) ) { 81 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 82 } 83 84 // Create selector for plugin 85 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 86 return !!$.data( elem, fullName ); 87 }; 88 89 $[ namespace ] = $[ namespace ] || {}; 90 existingConstructor = $[ namespace ][ name ]; 91 constructor = $[ namespace ][ name ] = function( options, element ) { 92 93 // Allow instantiation without "new" keyword 94 if ( !this || !this._createWidget ) { 95 return new constructor( options, element ); 96 } 97 98 // Allow instantiation without initializing for simple inheritance 99 // must use "new" keyword (the code above always passes args) 100 if ( arguments.length ) { 101 this._createWidget( options, element ); 102 } 103 }; 104 105 // Extend with the existing constructor to carry over any static properties 106 $.extend( constructor, existingConstructor, { 107 version: prototype.version, 108 109 // Copy the object used to create the prototype in case we need to 110 // redefine the widget later 111 _proto: $.extend( {}, prototype ), 112 113 // Track widgets that inherit from this widget in case this widget is 114 // redefined after a widget inherits from it 115 _childConstructors: [] 116 } ); 117 118 basePrototype = new base(); 119 120 // We need to make the options hash a property directly on the new instance 121 // otherwise we'll modify the options hash on the prototype that we're 122 // inheriting from 123 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 124 $.each( prototype, function( prop, value ) { 125 if ( typeof value !== "function" ) { 126 proxiedPrototype[ prop ] = value; 127 return; 128 } 129 proxiedPrototype[ prop ] = ( function() { 130 function _super() { 131 return base.prototype[ prop ].apply( this, arguments ); 132 } 133 134 function _superApply( args ) { 135 return base.prototype[ prop ].apply( this, args ); 136 } 137 138 return function() { 139 var __super = this._super; 140 var __superApply = this._superApply; 141 var returnValue; 142 143 this._super = _super; 144 this._superApply = _superApply; 145 146 returnValue = value.apply( this, arguments ); 147 148 this._super = __super; 149 this._superApply = __superApply; 150 151 return returnValue; 152 }; 153 } )(); 154 } ); 155 constructor.prototype = $.widget.extend( basePrototype, { 156 157 // TODO: remove support for widgetEventPrefix 158 // always use the name + a colon as the prefix, e.g., draggable:start 159 // don't prefix for widgets that aren't DOM-based 160 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 161 }, proxiedPrototype, { 162 constructor: constructor, 163 namespace: namespace, 164 widgetName: name, 165 widgetFullName: fullName 166 } ); 167 168 // If this widget is being redefined then we need to find all widgets that 169 // are inheriting from it and redefine all of them so that they inherit from 170 // the new version of this widget. We're essentially trying to replace one 171 // level in the prototype chain. 172 if ( existingConstructor ) { 173 $.each( existingConstructor._childConstructors, function( i, child ) { 174 var childPrototype = child.prototype; 175 176 // Redefine the child widget using the same prototype that was 177 // originally used, but inherit from the new version of the base 178 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 179 child._proto ); 180 } ); 181 182 // Remove the list of existing child constructors from the old constructor 183 // so the old child constructors can be garbage collected 184 delete existingConstructor._childConstructors; 185 } else { 186 base._childConstructors.push( constructor ); 187 } 188 189 $.widget.bridge( name, constructor ); 190 191 return constructor; 192}; 193 194$.widget.extend = function( target ) { 195 var input = widgetSlice.call( arguments, 1 ); 196 var inputIndex = 0; 197 var inputLength = input.length; 198 var key; 199 var value; 200 201 for ( ; inputIndex < inputLength; inputIndex++ ) { 202 for ( key in input[ inputIndex ] ) { 203 value = input[ inputIndex ][ key ]; 204 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 205 206 // Clone objects 207 if ( $.isPlainObject( value ) ) { 208 target[ key ] = $.isPlainObject( target[ key ] ) ? 209 $.widget.extend( {}, target[ key ], value ) : 210 211 // Don't extend strings, arrays, etc. with objects 212 $.widget.extend( {}, value ); 213 214 // Copy everything else by reference 215 } else { 216 target[ key ] = value; 217 } 218 } 219 } 220 } 221 return target; 222}; 223 224$.widget.bridge = function( name, object ) { 225 var fullName = object.prototype.widgetFullName || name; 226 $.fn[ name ] = function( options ) { 227 var isMethodCall = typeof options === "string"; 228 var args = widgetSlice.call( arguments, 1 ); 229 var returnValue = this; 230 231 if ( isMethodCall ) { 232 233 // If this is an empty collection, we need to have the instance method 234 // return undefined instead of the jQuery instance 235 if ( !this.length && options === "instance" ) { 236 returnValue = undefined; 237 } else { 238 this.each( function() { 239 var methodValue; 240 var instance = $.data( this, fullName ); 241 242 if ( options === "instance" ) { 243 returnValue = instance; 244 return false; 245 } 246 247 if ( !instance ) { 248 return $.error( "cannot call methods on " + name + 249 " prior to initialization; " + 250 "attempted to call method '" + options + "'" ); 251 } 252 253 if ( typeof instance[ options ] !== "function" || 254 options.charAt( 0 ) === "_" ) { 255 return $.error( "no such method '" + options + "' for " + name + 256 " widget instance" ); 257 } 258 259 methodValue = instance[ options ].apply( instance, args ); 260 261 if ( methodValue !== instance && methodValue !== undefined ) { 262 returnValue = methodValue && methodValue.jquery ? 263 returnValue.pushStack( methodValue.get() ) : 264 methodValue; 265 return false; 266 } 267 } ); 268 } 269 } else { 270 271 // Allow multiple hashes to be passed on init 272 if ( args.length ) { 273 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 274 } 275 276 this.each( function() { 277 var instance = $.data( this, fullName ); 278 if ( instance ) { 279 instance.option( options || {} ); 280 if ( instance._init ) { 281 instance._init(); 282 } 283 } else { 284 $.data( this, fullName, new object( options, this ) ); 285 } 286 } ); 287 } 288 289 return returnValue; 290 }; 291}; 292 293$.Widget = function( /* options, element */ ) {}; 294$.Widget._childConstructors = []; 295 296$.Widget.prototype = { 297 widgetName: "widget", 298 widgetEventPrefix: "", 299 defaultElement: "<div>", 300 301 options: { 302 classes: {}, 303 disabled: false, 304 305 // Callbacks 306 create: null 307 }, 308 309 _createWidget: function( options, element ) { 310 element = $( element || this.defaultElement || this )[ 0 ]; 311 this.element = $( element ); 312 this.uuid = widgetUuid++; 313 this.eventNamespace = "." + this.widgetName + this.uuid; 314 315 this.bindings = $(); 316 this.hoverable = $(); 317 this.focusable = $(); 318 this.classesElementLookup = {}; 319 320 if ( element !== this ) { 321 $.data( element, this.widgetFullName, this ); 322 this._on( true, this.element, { 323 remove: function( event ) { 324 if ( event.target === element ) { 325 this.destroy(); 326 } 327 } 328 } ); 329 this.document = $( element.style ? 330 331 // Element within the document 332 element.ownerDocument : 333 334 // Element is window or document 335 element.document || element ); 336 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 337 } 338 339 this.options = $.widget.extend( {}, 340 this.options, 341 this._getCreateOptions(), 342 options ); 343 344 this._create(); 345 346 if ( this.options.disabled ) { 347 this._setOptionDisabled( this.options.disabled ); 348 } 349 350 this._trigger( "create", null, this._getCreateEventData() ); 351 this._init(); 352 }, 353 354 _getCreateOptions: function() { 355 return {}; 356 }, 357 358 _getCreateEventData: $.noop, 359 360 _create: $.noop, 361 362 _init: $.noop, 363 364 destroy: function() { 365 var that = this; 366 367 this._destroy(); 368 $.each( this.classesElementLookup, function( key, value ) { 369 that._removeClass( value, key ); 370 } ); 371 372 // We can probably remove the unbind calls in 2.0 373 // all event bindings should go through this._on() 374 this.element 375 .off( this.eventNamespace ) 376 .removeData( this.widgetFullName ); 377 this.widget() 378 .off( this.eventNamespace ) 379 .removeAttr( "aria-disabled" ); 380 381 // Clean up events and states 382 this.bindings.off( this.eventNamespace ); 383 }, 384 385 _destroy: $.noop, 386 387 widget: function() { 388 return this.element; 389 }, 390 391 option: function( key, value ) { 392 var options = key; 393 var parts; 394 var curOption; 395 var i; 396 397 if ( arguments.length === 0 ) { 398 399 // Don't return a reference to the internal hash 400 return $.widget.extend( {}, this.options ); 401 } 402 403 if ( typeof key === "string" ) { 404 405 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 406 options = {}; 407 parts = key.split( "." ); 408 key = parts.shift(); 409 if ( parts.length ) { 410 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 411 for ( i = 0; i < parts.length - 1; i++ ) { 412 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 413 curOption = curOption[ parts[ i ] ]; 414 } 415 key = parts.pop(); 416 if ( arguments.length === 1 ) { 417 return curOption[ key ] === undefined ? null : curOption[ key ]; 418 } 419 curOption[ key ] = value; 420 } else { 421 if ( arguments.length === 1 ) { 422 return this.options[ key ] === undefined ? null : this.options[ key ]; 423 } 424 options[ key ] = value; 425 } 426 } 427 428 this._setOptions( options ); 429 430 return this; 431 }, 432 433 _setOptions: function( options ) { 434 var key; 435 436 for ( key in options ) { 437 this._setOption( key, options[ key ] ); 438 } 439 440 return this; 441 }, 442 443 _setOption: function( key, value ) { 444 if ( key === "classes" ) { 445 this._setOptionClasses( value ); 446 } 447 448 this.options[ key ] = value; 449 450 if ( key === "disabled" ) { 451 this._setOptionDisabled( value ); 452 } 453 454 return this; 455 }, 456 457 _setOptionClasses: function( value ) { 458 var classKey, elements, currentElements; 459 460 for ( classKey in value ) { 461 currentElements = this.classesElementLookup[ classKey ]; 462 if ( value[ classKey ] === this.options.classes[ classKey ] || 463 !currentElements || 464 !currentElements.length ) { 465 continue; 466 } 467 468 // We are doing this to create a new jQuery object because the _removeClass() call 469 // on the next line is going to destroy the reference to the current elements being 470 // tracked. We need to save a copy of this collection so that we can add the new classes 471 // below. 472 elements = $( currentElements.get() ); 473 this._removeClass( currentElements, classKey ); 474 475 // We don't use _addClass() here, because that uses this.options.classes 476 // for generating the string of classes. We want to use the value passed in from 477 // _setOption(), this is the new value of the classes option which was passed to 478 // _setOption(). We pass this value directly to _classes(). 479 elements.addClass( this._classes( { 480 element: elements, 481 keys: classKey, 482 classes: value, 483 add: true 484 } ) ); 485 } 486 }, 487 488 _setOptionDisabled: function( value ) { 489 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 490 491 // If the widget is becoming disabled, then nothing is interactive 492 if ( value ) { 493 this._removeClass( this.hoverable, null, "ui-state-hover" ); 494 this._removeClass( this.focusable, null, "ui-state-focus" ); 495 } 496 }, 497 498 enable: function() { 499 return this._setOptions( { disabled: false } ); 500 }, 501 502 disable: function() { 503 return this._setOptions( { disabled: true } ); 504 }, 505 506 _classes: function( options ) { 507 var full = []; 508 var that = this; 509 510 options = $.extend( { 511 element: this.element, 512 classes: this.options.classes || {} 513 }, options ); 514 515 function bindRemoveEvent() { 516 var nodesToBind = []; 517 518 options.element.each( function( _, element ) { 519 var isTracked = $.map( that.classesElementLookup, function( elements ) { 520 return elements; 521 } ) 522 .some( function( elements ) { 523 return elements.is( element ); 524 } ); 525 526 if ( !isTracked ) { 527 nodesToBind.push( element ); 528 } 529 } ); 530 531 that._on( $( nodesToBind ), { 532 remove: "_untrackClassesElement" 533 } ); 534 } 535 536 function processClassString( classes, checkOption ) { 537 var current, i; 538 for ( i = 0; i < classes.length; i++ ) { 539 current = that.classesElementLookup[ classes[ i ] ] || $(); 540 if ( options.add ) { 541 bindRemoveEvent(); 542 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 543 } else { 544 current = $( current.not( options.element ).get() ); 545 } 546 that.classesElementLookup[ classes[ i ] ] = current; 547 full.push( classes[ i ] ); 548 if ( checkOption && options.classes[ classes[ i ] ] ) { 549 full.push( options.classes[ classes[ i ] ] ); 550 } 551 } 552 } 553 554 if ( options.keys ) { 555 processClassString( options.keys.match( /\S+/g ) || [], true ); 556 } 557 if ( options.extra ) { 558 processClassString( options.extra.match( /\S+/g ) || [] ); 559 } 560 561 return full.join( " " ); 562 }, 563 564 _untrackClassesElement: function( event ) { 565 var that = this; 566 $.each( that.classesElementLookup, function( key, value ) { 567 if ( $.inArray( event.target, value ) !== -1 ) { 568 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 569 } 570 } ); 571 572 this._off( $( event.target ) ); 573 }, 574 575 _removeClass: function( element, keys, extra ) { 576 return this._toggleClass( element, keys, extra, false ); 577 }, 578 579 _addClass: function( element, keys, extra ) { 580 return this._toggleClass( element, keys, extra, true ); 581 }, 582 583 _toggleClass: function( element, keys, extra, add ) { 584 add = ( typeof add === "boolean" ) ? add : extra; 585 var shift = ( typeof element === "string" || element === null ), 586 options = { 587 extra: shift ? keys : extra, 588 keys: shift ? element : keys, 589 element: shift ? this.element : element, 590 add: add 591 }; 592 options.element.toggleClass( this._classes( options ), add ); 593 return this; 594 }, 595 596 _on: function( suppressDisabledCheck, element, handlers ) { 597 var delegateElement; 598 var instance = this; 599 600 // No suppressDisabledCheck flag, shuffle arguments 601 if ( typeof suppressDisabledCheck !== "boolean" ) { 602 handlers = element; 603 element = suppressDisabledCheck; 604 suppressDisabledCheck = false; 605 } 606 607 // No element argument, shuffle and use this.element 608 if ( !handlers ) { 609 handlers = element; 610 element = this.element; 611 delegateElement = this.widget(); 612 } else { 613 element = delegateElement = $( element ); 614 this.bindings = this.bindings.add( element ); 615 } 616 617 $.each( handlers, function( event, handler ) { 618 function handlerProxy() { 619 620 // Allow widgets to customize the disabled handling 621 // - disabled as an array instead of boolean 622 // - disabled class as method for disabling individual parts 623 if ( !suppressDisabledCheck && 624 ( instance.options.disabled === true || 625 $( this ).hasClass( "ui-state-disabled" ) ) ) { 626 return; 627 } 628 return ( typeof handler === "string" ? instance[ handler ] : handler ) 629 .apply( instance, arguments ); 630 } 631 632 // Copy the guid so direct unbinding works 633 if ( typeof handler !== "string" ) { 634 handlerProxy.guid = handler.guid = 635 handler.guid || handlerProxy.guid || $.guid++; 636 } 637 638 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 639 var eventName = match[ 1 ] + instance.eventNamespace; 640 var selector = match[ 2 ]; 641 642 if ( selector ) { 643 delegateElement.on( eventName, selector, handlerProxy ); 644 } else { 645 element.on( eventName, handlerProxy ); 646 } 647 } ); 648 }, 649 650 _off: function( element, eventName ) { 651 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 652 this.eventNamespace; 653 element.off( eventName ); 654 655 // Clear the stack to avoid memory leaks (#10056) 656 this.bindings = $( this.bindings.not( element ).get() ); 657 this.focusable = $( this.focusable.not( element ).get() ); 658 this.hoverable = $( this.hoverable.not( element ).get() ); 659 }, 660 661 _delay: function( handler, delay ) { 662 function handlerProxy() { 663 return ( typeof handler === "string" ? instance[ handler ] : handler ) 664 .apply( instance, arguments ); 665 } 666 var instance = this; 667 return setTimeout( handlerProxy, delay || 0 ); 668 }, 669 670 _hoverable: function( element ) { 671 this.hoverable = this.hoverable.add( element ); 672 this._on( element, { 673 mouseenter: function( event ) { 674 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 675 }, 676 mouseleave: function( event ) { 677 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 678 } 679 } ); 680 }, 681 682 _focusable: function( element ) { 683 this.focusable = this.focusable.add( element ); 684 this._on( element, { 685 focusin: function( event ) { 686 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 687 }, 688 focusout: function( event ) { 689 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 690 } 691 } ); 692 }, 693 694 _trigger: function( type, event, data ) { 695 var prop, orig; 696 var callback = this.options[ type ]; 697 698 data = data || {}; 699 event = $.Event( event ); 700 event.type = ( type === this.widgetEventPrefix ? 701 type : 702 this.widgetEventPrefix + type ).toLowerCase(); 703 704 // The original event may come from any element 705 // so we need to reset the target on the new event 706 event.target = this.element[ 0 ]; 707 708 // Copy original event properties over to the new event 709 orig = event.originalEvent; 710 if ( orig ) { 711 for ( prop in orig ) { 712 if ( !( prop in event ) ) { 713 event[ prop ] = orig[ prop ]; 714 } 715 } 716 } 717 718 this.element.trigger( event, data ); 719 return !( typeof callback === "function" && 720 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 721 event.isDefaultPrevented() ); 722 } 723}; 724 725$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 726 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 727 if ( typeof options === "string" ) { 728 options = { effect: options }; 729 } 730 731 var hasOptions; 732 var effectName = !options ? 733 method : 734 options === true || typeof options === "number" ? 735 defaultEffect : 736 options.effect || defaultEffect; 737 738 options = options || {}; 739 if ( typeof options === "number" ) { 740 options = { duration: options }; 741 } else if ( options === true ) { 742 options = {}; 743 } 744 745 hasOptions = !$.isEmptyObject( options ); 746 options.complete = callback; 747 748 if ( options.delay ) { 749 element.delay( options.delay ); 750 } 751 752 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 753 element[ method ]( options ); 754 } else if ( effectName !== method && element[ effectName ] ) { 755 element[ effectName ]( options.duration, options.easing, callback ); 756 } else { 757 element.queue( function( next ) { 758 $( this )[ method ](); 759 if ( callback ) { 760 callback.call( element[ 0 ] ); 761 } 762 next(); 763 } ); 764 } 765 }; 766} ); 767 768var widget = $.widget; 769 770 771/*! 772 * jQuery UI Position 1.14.2 773 * https://jqueryui.com 774 * 775 * Copyright OpenJS Foundation and other contributors 776 * Released under the MIT license. 777 * https://jquery.org/license 778 * 779 * https://api.jqueryui.com/position/ 780 */ 781 782//>>label: Position 783//>>group: Core 784//>>description: Positions elements relative to other elements. 785//>>docs: https://api.jqueryui.com/position/ 786//>>demos: https://jqueryui.com/position/ 787 788 789( function() { 790var cachedScrollbarWidth, 791 max = Math.max, 792 abs = Math.abs, 793 rhorizontal = /left|center|right/, 794 rvertical = /top|center|bottom/, 795 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 796 rposition = /^\w+/, 797 rpercent = /%$/, 798 _position = $.fn.position; 799 800function getOffsets( offsets, width, height ) { 801 return [ 802 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 803 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 804 ]; 805} 806 807function parseCss( element, property ) { 808 return parseInt( $.css( element, property ), 10 ) || 0; 809} 810 811function isWindow( obj ) { 812 return obj != null && obj === obj.window; 813} 814 815function getDimensions( elem ) { 816 var raw = elem[ 0 ]; 817 if ( raw.nodeType === 9 ) { 818 return { 819 width: elem.width(), 820 height: elem.height(), 821 offset: { top: 0, left: 0 } 822 }; 823 } 824 if ( isWindow( raw ) ) { 825 return { 826 width: elem.width(), 827 height: elem.height(), 828 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 829 }; 830 } 831 if ( raw.preventDefault ) { 832 return { 833 width: 0, 834 height: 0, 835 offset: { top: raw.pageY, left: raw.pageX } 836 }; 837 } 838 return { 839 width: elem.outerWidth(), 840 height: elem.outerHeight(), 841 offset: elem.offset() 842 }; 843} 844 845$.position = { 846 scrollbarWidth: function() { 847 if ( cachedScrollbarWidth !== undefined ) { 848 return cachedScrollbarWidth; 849 } 850 var w1, w2, 851 div = $( "<div style=" + 852 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 853 "<div style='height:300px;width:auto;'></div></div>" ), 854 innerDiv = div.children()[ 0 ]; 855 856 $( "body" ).append( div ); 857 w1 = innerDiv.offsetWidth; 858 div.css( "overflow", "scroll" ); 859 860 w2 = innerDiv.offsetWidth; 861 862 if ( w1 === w2 ) { 863 w2 = div[ 0 ].clientWidth; 864 } 865 866 div.remove(); 867 868 return ( cachedScrollbarWidth = w1 - w2 ); 869 }, 870 getScrollInfo: function( within ) { 871 var overflowX = within.isWindow || within.isDocument ? "" : 872 within.element.css( "overflow-x" ), 873 overflowY = within.isWindow || within.isDocument ? "" : 874 within.element.css( "overflow-y" ), 875 hasOverflowX = overflowX === "scroll" || 876 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 877 hasOverflowY = overflowY === "scroll" || 878 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 879 return { 880 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 881 height: hasOverflowX ? $.position.scrollbarWidth() : 0 882 }; 883 }, 884 getWithinInfo: function( element ) { 885 var withinElement = $( element || window ), 886 isElemWindow = isWindow( withinElement[ 0 ] ), 887 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 888 hasOffset = !isElemWindow && !isDocument; 889 return { 890 element: withinElement, 891 isWindow: isElemWindow, 892 isDocument: isDocument, 893 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 894 scrollLeft: withinElement.scrollLeft(), 895 scrollTop: withinElement.scrollTop(), 896 width: withinElement.outerWidth(), 897 height: withinElement.outerHeight() 898 }; 899 } 900}; 901 902$.fn.position = function( options ) { 903 if ( !options || !options.of ) { 904 return _position.apply( this, arguments ); 905 } 906 907 // Make a copy, we don't want to modify arguments 908 options = $.extend( {}, options ); 909 910 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 911 912 // Make sure string options are treated as CSS selectors 913 target = typeof options.of === "string" ? 914 $( document ).find( options.of ) : 915 $( options.of ), 916 917 within = $.position.getWithinInfo( options.within ), 918 scrollInfo = $.position.getScrollInfo( within ), 919 collision = ( options.collision || "flip" ).split( " " ), 920 offsets = {}; 921 922 dimensions = getDimensions( target ); 923 if ( target[ 0 ].preventDefault ) { 924 925 // Force left top to allow flipping 926 options.at = "left top"; 927 } 928 targetWidth = dimensions.width; 929 targetHeight = dimensions.height; 930 targetOffset = dimensions.offset; 931 932 // Clone to reuse original targetOffset later 933 basePosition = $.extend( {}, targetOffset ); 934 935 // Force my and at to have valid horizontal and vertical positions 936 // if a value is missing or invalid, it will be converted to center 937 $.each( [ "my", "at" ], function() { 938 var pos = ( options[ this ] || "" ).split( " " ), 939 horizontalOffset, 940 verticalOffset; 941 942 if ( pos.length === 1 ) { 943 pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 4,599 bytes, lines 944-1096
944 pos.concat( [ "center" ] ) : 945 rvertical.test( pos[ 0 ] ) ? 946 [ "center" ].concat( pos ) : 947 [ "center", "center" ]; 948 } 949 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 950 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 951 952 // Calculate offsets 953 horizontalOffset = roffset.exec( pos[ 0 ] ); 954 verticalOffset = roffset.exec( pos[ 1 ] ); 955 offsets[ this ] = [ 956 horizontalOffset ? horizontalOffset[ 0 ] : 0, 957 verticalOffset ? verticalOffset[ 0 ] : 0 958 ]; 959 960 // Reduce to just the positions without the offsets 961 options[ this ] = [ 962 rposition.exec( pos[ 0 ] )[ 0 ], 963 rposition.exec( pos[ 1 ] )[ 0 ] 964 ]; 965 } ); 966 967 // Normalize collision option 968 if ( collision.length === 1 ) { 969 collision[ 1 ] = collision[ 0 ]; 970 } 971 972 if ( options.at[ 0 ] === "right" ) { 973 basePosition.left += targetWidth; 974 } else if ( options.at[ 0 ] === "center" ) { 975 basePosition.left += targetWidth / 2; 976 } 977 978 if ( options.at[ 1 ] === "bottom" ) { 979 basePosition.top += targetHeight; 980 } else if ( options.at[ 1 ] === "center" ) { 981 basePosition.top += targetHeight / 2; 982 } 983 984 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 985 basePosition.left += atOffset[ 0 ]; 986 basePosition.top += atOffset[ 1 ]; 987 988 return this.each( function() { 989 var collisionPosition, using, 990 elem = $( this ), 991 elemWidth = elem.outerWidth(), 992 elemHeight = elem.outerHeight(), 993 marginLeft = parseCss( this, "marginLeft" ), 994 marginTop = parseCss( this, "marginTop" ), 995 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 996 scrollInfo.width, 997 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 998 scrollInfo.height, 999 position = $.extend( {}, basePosition ), 1000 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1001 1002 if ( options.my[ 0 ] === "right" ) { 1003 position.left -= elemWidth; 1004 } else if ( options.my[ 0 ] === "center" ) { 1005 position.left -= elemWidth / 2; 1006 } 1007 1008 if ( options.my[ 1 ] === "bottom" ) { 1009 position.top -= elemHeight; 1010 } else if ( options.my[ 1 ] === "center" ) { 1011 position.top -= elemHeight / 2; 1012 } 1013 1014 position.left += myOffset[ 0 ]; 1015 position.top += myOffset[ 1 ]; 1016 1017 collisionPosition = { 1018 marginLeft: marginLeft, 1019 marginTop: marginTop 1020 }; 1021 1022 $.each( [ "left", "top" ], function( i, dir ) { 1023 if ( $.ui.position[ collision[ i ] ] ) { 1024 $.ui.position[ collision[ i ] ][ dir ]( position, { 1025 targetWidth: targetWidth, 1026 targetHeight: targetHeight, 1027 elemWidth: elemWidth, 1028 elemHeight: elemHeight, 1029 collisionPosition: collisionPosition, 1030 collisionWidth: collisionWidth, 1031 collisionHeight: collisionHeight, 1032 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1033 my: options.my, 1034 at: options.at, 1035 within: within, 1036 elem: elem 1037 } ); 1038 } 1039 } ); 1040 1041 if ( options.using ) { 1042 1043 // Adds feedback as second argument to using callback, if present 1044 using = function( props ) { 1045 var left = targetOffset.left - position.left, 1046 right = left + targetWidth - elemWidth, 1047 top = targetOffset.top - position.top, 1048 bottom = top + targetHeight - elemHeight, 1049 feedback = { 1050 target: { 1051 element: target, 1052 left: targetOffset.left, 1053 top: targetOffset.top, 1054 width: targetWidth, 1055 height: targetHeight 1056 }, 1057 element: { 1058 element: elem, 1059 left: position.left, 1060 top: position.top, 1061 width: elemWidth, 1062 height: elemHeight 1063 }, 1064 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1065 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1066 }; 1067 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1068 feedback.horizontal = "center"; 1069 } 1070 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1071 feedback.vertical = "middle"; 1072 } 1073 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1074 feedback.important = "horizontal"; 1075 } else { 1076 feedback.important = "vertical"; 1077 } 1078 options.using.call( this, props, feedback ); 1079 }; 1080 } 1081 1082 elem.offset( $.extend( position, { using: using } ) ); 1083 } ); 1084}; 1085 1086$.ui.position = { 1087 fit: { 1088 left: function( position, data ) { 1089 var within = data.within, 1090 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1091 outerWidth = within.width, 1092 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1093 overLeft = withinOffset - collisionPosLeft, 1094 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1095 newOverRight; 1096
vendor: 6,851 bytes, lines 1097-1325
1097 // Element is wider than within 1098 if ( data.collisionWidth > outerWidth ) { 1099 1100 // Element is initially over the left side of within 1101 if ( overLeft > 0 && overRight <= 0 ) { 1102 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1103 withinOffset; 1104 position.left += overLeft - newOverRight; 1105 1106 // Element is initially over right side of within 1107 } else if ( overRight > 0 && overLeft <= 0 ) { 1108 position.left = withinOffset; 1109 1110 // Element is initially over both left and right sides of within 1111 } else { 1112 if ( overLeft > overRight ) { 1113 position.left = withinOffset + outerWidth - data.collisionWidth; 1114 } else { 1115 position.left = withinOffset; 1116 } 1117 } 1118 1119 // Too far left -> align with left edge 1120 } else if ( overLeft > 0 ) { 1121 position.left += overLeft; 1122 1123 // Too far right -> align with right edge 1124 } else if ( overRight > 0 ) { 1125 position.left -= overRight; 1126 1127 // Adjust based on position and margin 1128 } else { 1129 position.left = max( position.left - collisionPosLeft, position.left ); 1130 } 1131 }, 1132 top: function( position, data ) { 1133 var within = data.within, 1134 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1135 outerHeight = data.within.height, 1136 collisionPosTop = position.top - data.collisionPosition.marginTop, 1137 overTop = withinOffset - collisionPosTop, 1138 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1139 newOverBottom; 1140 1141 // Element is taller than within 1142 if ( data.collisionHeight > outerHeight ) { 1143 1144 // Element is initially over the top of within 1145 if ( overTop > 0 && overBottom <= 0 ) { 1146 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1147 withinOffset; 1148 position.top += overTop - newOverBottom; 1149 1150 // Element is initially over bottom of within 1151 } else if ( overBottom > 0 && overTop <= 0 ) { 1152 position.top = withinOffset; 1153 1154 // Element is initially over both top and bottom of within 1155 } else { 1156 if ( overTop > overBottom ) { 1157 position.top = withinOffset + outerHeight - data.collisionHeight; 1158 } else { 1159 position.top = withinOffset; 1160 } 1161 } 1162 1163 // Too far up -> align with top 1164 } else if ( overTop > 0 ) { 1165 position.top += overTop; 1166 1167 // Too far down -> align with bottom edge 1168 } else if ( overBottom > 0 ) { 1169 position.top -= overBottom; 1170 1171 // Adjust based on position and margin 1172 } else { 1173 position.top = max( position.top - collisionPosTop, position.top ); 1174 } 1175 } 1176 }, 1177 flip: { 1178 left: function( position, data ) { 1179 var within = data.within, 1180 withinOffset = within.offset.left + within.scrollLeft, 1181 outerWidth = within.width, 1182 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1183 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1184 overLeft = collisionPosLeft - offsetLeft, 1185 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1186 myOffset = data.my[ 0 ] === "left" ? 1187 -data.elemWidth : 1188 data.my[ 0 ] === "right" ? 1189 data.elemWidth : 1190 0, 1191 atOffset = data.at[ 0 ] === "left" ? 1192 data.targetWidth : 1193 data.at[ 0 ] === "right" ? 1194 -data.targetWidth : 1195 0, 1196 offset = -2 * data.offset[ 0 ], 1197 newOverRight, 1198 newOverLeft; 1199 1200 if ( overLeft < 0 ) { 1201 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1202 outerWidth - withinOffset; 1203 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1204 position.left += myOffset + atOffset + offset; 1205 } 1206 } else if ( overRight > 0 ) { 1207 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1208 atOffset + offset - offsetLeft; 1209 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1210 position.left += myOffset + atOffset + offset; 1211 } 1212 } 1213 }, 1214 top: function( position, data ) { 1215 var within = data.within, 1216 withinOffset = within.offset.top + within.scrollTop, 1217 outerHeight = within.height, 1218 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1219 collisionPosTop = position.top - data.collisionPosition.marginTop, 1220 overTop = collisionPosTop - offsetTop, 1221 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1222 top = data.my[ 1 ] === "top", 1223 myOffset = top ? 1224 -data.elemHeight : 1225 data.my[ 1 ] === "bottom" ? 1226 data.elemHeight : 1227 0, 1228 atOffset = data.at[ 1 ] === "top" ? 1229 data.targetHeight : 1230 data.at[ 1 ] === "bottom" ? 1231 -data.targetHeight : 1232 0, 1233 offset = -2 * data.offset[ 1 ], 1234 newOverTop, 1235 newOverBottom; 1236 if ( overTop < 0 ) { 1237 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1238 outerHeight - withinOffset; 1239 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1240 position.top += myOffset + atOffset + offset; 1241 } 1242 } else if ( overBottom > 0 ) { 1243 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1244 offset - offsetTop; 1245 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1246 position.top += myOffset + atOffset + offset; 1247 } 1248 } 1249 } 1250 }, 1251 flipfit: { 1252 left: function() { 1253 $.ui.position.flip.left.apply( this, arguments ); 1254 $.ui.position.fit.left.apply( this, arguments ); 1255 }, 1256 top: function() { 1257 $.ui.position.flip.top.apply( this, arguments ); 1258 $.ui.position.fit.top.apply( this, arguments ); 1259 } 1260 } 1261}; 1262 1263} )(); 1264 1265var position = $.ui.position; 1266 1267 1268/*! 1269 * jQuery UI :data 1.14.2 1270 * https://jqueryui.com 1271 * 1272 * Copyright OpenJS Foundation and other contributors 1273 * Released under the MIT license. 1274 * https://jquery.org/license 1275 */ 1276 1277//>>label: :data Selector 1278//>>group: Core 1279//>>description: Selects elements which have data stored under the specified key. 1280//>>docs: https://api.jqueryui.com/data-selector/ 1281 1282 1283var data = $.extend( $.expr.pseudos, { 1284 data: $.expr.createPseudo( function( dataName ) { 1285 return function( elem ) { 1286 return !!$.data( elem, dataName ); 1287 }; 1288 } ) 1289} ); 1290 1291/*! 1292 * jQuery UI Disable Selection 1.14.2 1293 * https://jqueryui.com 1294 * 1295 * Copyright OpenJS Foundation and other contributors 1296 * Released under the MIT license. 1297 * https://jquery.org/license 1298 */ 1299 1300//>>label: disableSelection 1301//>>group: Core 1302//>>description: Disable selection of text content within the set of matched elements. 1303//>>docs: https://api.jqueryui.com/disableSelection/ 1304 1305// This file is deprecated 1306 1307var disableSelection = $.fn.extend( { 1308 disableSelection: ( function() { 1309 var eventType = "onselectstart" in document.createElement( "div" ) ? 1310 "selectstart" : 1311 "mousedown"; 1312 1313 return function() { 1314 return this.on( eventType + ".ui-disableSelection", function( event ) { 1315 event.preventDefault(); 1316 } ); 1317 }; 1318 } )(), 1319 1320 enableSelection: function() { 1321 return this.off( ".ui-disableSelection" ); 1322 } 1323} ); 1324 1325
vendor: 8,547 bytes, lines 1326-1675
1326/*! 1327 * jQuery UI Focusable 1.14.2 1328 * https://jqueryui.com 1329 * 1330 * Copyright OpenJS Foundation and other contributors 1331 * Released under the MIT license. 1332 * https://jquery.org/license 1333 */ 1334 1335//>>label: :focusable Selector 1336//>>group: Core 1337//>>description: Selects elements which can be focused. 1338//>>docs: https://api.jqueryui.com/focusable-selector/ 1339 1340 1341// Selectors 1342$.ui.focusable = function( element, hasTabindex ) { 1343 var map, mapName, img, focusableIfVisible, fieldset, 1344 nodeName = element.nodeName.toLowerCase(); 1345 1346 if ( "area" === nodeName ) { 1347 map = element.parentNode; 1348 mapName = map.name; 1349 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 1350 return false; 1351 } 1352 img = $( "img[usemap='#" + mapName + "']" ); 1353 return img.length > 0 && img.is( ":visible" ); 1354 } 1355 1356 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 1357 focusableIfVisible = !element.disabled; 1358 1359 if ( focusableIfVisible ) { 1360 1361 // Form controls within a disabled fieldset are disabled. 1362 // However, controls within the fieldset's legend do not get disabled. 1363 // Since controls generally aren't placed inside legends, we skip 1364 // this portion of the check. 1365 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 1366 if ( fieldset ) { 1367 focusableIfVisible = !fieldset.disabled; 1368 } 1369 } 1370 } else if ( "a" === nodeName ) { 1371 focusableIfVisible = element.href || hasTabindex; 1372 } else { 1373 focusableIfVisible = hasTabindex; 1374 } 1375 1376 return focusableIfVisible && $( element ).is( ":visible" ) && 1377 $( element ).css( "visibility" ) === "visible"; 1378}; 1379 1380$.extend( $.expr.pseudos, { 1381 focusable: function( element ) { 1382 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 1383 } 1384} ); 1385 1386var focusable = $.ui.focusable; 1387 1388 1389/*! 1390 * jQuery UI Form Reset Mixin 1.14.2 1391 * https://jqueryui.com 1392 * 1393 * Copyright OpenJS Foundation and other contributors 1394 * Released under the MIT license. 1395 * https://jquery.org/license 1396 */ 1397 1398//>>label: Form Reset Mixin 1399//>>group: Core 1400//>>description: Refresh input widgets when their form is reset 1401//>>docs: https://api.jqueryui.com/form-reset-mixin/ 1402 1403 1404var formResetMixin = $.ui.formResetMixin = { 1405 _formResetHandler: function() { 1406 var form = $( this ); 1407 1408 // Wait for the form reset to actually happen before refreshing 1409 setTimeout( function() { 1410 var instances = form.data( "ui-form-reset-instances" ); 1411 $.each( instances, function() { 1412 this.refresh(); 1413 } ); 1414 } ); 1415 }, 1416 1417 _bindFormResetHandler: function() { 1418 this.form = $( this.element.prop( "form" ) ); 1419 if ( !this.form.length ) { 1420 return; 1421 } 1422 1423 var instances = this.form.data( "ui-form-reset-instances" ) || []; 1424 if ( !instances.length ) { 1425 1426 // We don't use _on() here because we use a single event handler per form 1427 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 1428 } 1429 instances.push( this ); 1430 this.form.data( "ui-form-reset-instances", instances ); 1431 }, 1432 1433 _unbindFormResetHandler: function() { 1434 if ( !this.form.length ) { 1435 return; 1436 } 1437 1438 var instances = this.form.data( "ui-form-reset-instances" ); 1439 instances.splice( $.inArray( this, instances ), 1 ); 1440 if ( instances.length ) { 1441 this.form.data( "ui-form-reset-instances", instances ); 1442 } else { 1443 this.form 1444 .removeData( "ui-form-reset-instances" ) 1445 .off( "reset.ui-form-reset" ); 1446 } 1447 } 1448}; 1449 1450 1451/*! 1452 * jQuery UI Legacy jQuery Core patches 1.14.2 1453 * https://jqueryui.com 1454 * 1455 * Copyright OpenJS Foundation and other contributors 1456 * Released under the MIT license. 1457 * https://jquery.org/license 1458 * 1459 */ 1460 1461//>>label: Legacy jQuery Core patches 1462//>>group: Core 1463//>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated) 1464 1465 1466// Support: jQuery 2.2.x or older. 1467// This method has been defined in jQuery 3.0.0. 1468// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 1469if ( !$.escapeSelector ) { 1470 $.escapeSelector = function( id ) { 1471 return CSS.escape( id + "" ); 1472 }; 1473} 1474 1475// Support: jQuery 3.4.x or older 1476// These methods have been defined in jQuery 3.5.0. 1477if ( !$.fn.even || !$.fn.odd ) { 1478 $.fn.extend( { 1479 even: function() { 1480 return this.filter( function( i ) { 1481 return i % 2 === 0; 1482 } ); 1483 }, 1484 odd: function() { 1485 return this.filter( function( i ) { 1486 return i % 2 === 1; 1487 } ); 1488 } 1489 } ); 1490} 1491 1492; 1493/*! 1494 * jQuery UI Keycode 1.14.2 1495 * https://jqueryui.com 1496 * 1497 * Copyright OpenJS Foundation and other contributors 1498 * Released under the MIT license. 1499 * https://jquery.org/license 1500 */ 1501 1502//>>label: Keycode 1503//>>group: Core 1504//>>description: Provide keycodes as keynames 1505//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/ 1506 1507 1508var keycode = $.ui.keyCode = { 1509 BACKSPACE: 8, 1510 COMMA: 188, 1511 DELETE: 46, 1512 DOWN: 40, 1513 END: 35, 1514 ENTER: 13, 1515 ESCAPE: 27, 1516 HOME: 36, 1517 LEFT: 37, 1518 PAGE_DOWN: 34, 1519 PAGE_UP: 33, 1520 PERIOD: 190, 1521 RIGHT: 39, 1522 SPACE: 32, 1523 TAB: 9, 1524 UP: 38 1525}; 1526 1527 1528/*! 1529 * jQuery UI Labels 1.14.2 1530 * https://jqueryui.com 1531 * 1532 * Copyright OpenJS Foundation and other contributors 1533 * Released under the MIT license. 1534 * https://jquery.org/license 1535 */ 1536 1537//>>label: labels 1538//>>group: Core 1539//>>description: Find all the labels associated with a given input 1540//>>docs: https://api.jqueryui.com/labels/ 1541 1542 1543var labels = $.fn.labels = function() { 1544 var ancestor, selector, id, labels, ancestors; 1545 1546 if ( !this.length ) { 1547 return this.pushStack( [] ); 1548 } 1549 1550 // Check control.labels first 1551 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 1552 return this.pushStack( this[ 0 ].labels ); 1553 } 1554 1555 // If `control.labels` is empty - e.g. inside of document fragments - find 1556 // the labels manually 1557 labels = this.eq( 0 ).parents( "label" ); 1558 1559 // Look for the label based on the id 1560 id = this.attr( "id" ); 1561 if ( id ) { 1562 1563 // We don't search against the document in case the element 1564 // is disconnected from the DOM 1565 ancestor = this.eq( 0 ).parents().last(); 1566 1567 // Get a full set of top level ancestors 1568 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 1569 1570 // Create a selector for the label based on the id 1571 selector = "label[for='" + CSS.escape( id ) + "']"; 1572 1573 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 1574 1575 } 1576 1577 // Return whatever we have found for labels 1578 return this.pushStack( labels ); 1579}; 1580 1581 1582/*! 1583 * jQuery UI Scroll Parent 1.14.2 1584 * https://jqueryui.com 1585 * 1586 * Copyright OpenJS Foundation and other contributors 1587 * Released under the MIT license. 1588 * https://jquery.org/license 1589 */ 1590 1591//>>label: scrollParent 1592//>>group: Core 1593//>>description: Get the closest ancestor element that is scrollable. 1594//>>docs: https://api.jqueryui.com/scrollParent/ 1595 1596 1597var scrollParent = $.fn.scrollParent = function( includeHidden ) { 1598 var position = this.css( "position" ), 1599 excludeStaticParent = position === "absolute", 1600 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 1601 scrollParent = this.parents().filter( function() { 1602 var parent = $( this ); 1603 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 1604 return false; 1605 } 1606 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 1607 parent.css( "overflow-x" ) ); 1608 } ).eq( 0 ); 1609 1610 return position === "fixed" || !scrollParent.length ? 1611 $( this[ 0 ].ownerDocument || document ) : 1612 scrollParent; 1613}; 1614 1615 1616/*! 1617 * jQuery UI Tabbable 1.14.2 1618 * https://jqueryui.com 1619 * 1620 * Copyright OpenJS Foundation and other contributors 1621 * Released under the MIT license. 1622 * https://jquery.org/license 1623 */ 1624 1625//>>label: :tabbable Selector 1626//>>group: Core 1627//>>description: Selects elements which can be tabbed to. 1628//>>docs: https://api.jqueryui.com/tabbable-selector/ 1629 1630 1631var tabbable = $.extend( $.expr.pseudos, { 1632 tabbable: function( element ) { 1633 var tabIndex = $.attr( element, "tabindex" ), 1634 hasTabindex = tabIndex != null; 1635 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 1636 } 1637} ); 1638 1639 1640/*! 1641 * jQuery UI Unique ID 1.14.2 1642 * https://jqueryui.com 1643 * 1644 * Copyright OpenJS Foundation and other contributors 1645 * Released under the MIT license. 1646 * https://jquery.org/license 1647 */ 1648 1649//>>label: uniqueId 1650//>>group: Core 1651//>>description: Functions to generate and remove uniqueId's 1652//>>docs: https://api.jqueryui.com/uniqueId/ 1653 1654 1655var uniqueId = $.fn.extend( { 1656 uniqueId: ( function() { 1657 var uuid = 0; 1658 1659 return function() { 1660 return this.each( function() { 1661 if ( !this.id ) { 1662 this.id = "ui-id-" + ( ++uuid ); 1663 } 1664 } ); 1665 }; 1666 } )(), 1667 1668 removeUniqueId: function() { 1669 return this.each( function() { 1670 if ( /^ui-id-\d+$/.test( this.id ) ) { 1671 $( this ).removeAttr( "id" ); 1672 } 1673 } ); 1674 } 1675} )
vendor: 19,830 bytes, lines 1675-2427
1675; 1676 1677 1678/*! 1679 * jQuery UI Mouse 1.14.2 1680 * https://jqueryui.com 1681 * 1682 * Copyright OpenJS Foundation and other contributors 1683 * Released under the MIT license. 1684 * https://jquery.org/license 1685 */ 1686 1687//>>label: Mouse 1688//>>group: Widgets 1689//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 1690//>>docs: https://api.jqueryui.com/mouse/ 1691 1692 1693var mouseHandled = false; 1694$( document ).on( "mouseup", function() { 1695 mouseHandled = false; 1696} ); 1697 1698var widgetsMouse = $.widget( "ui.mouse", { 1699 version: "1.14.2", 1700 options: { 1701 cancel: "input, textarea, button, select, option", 1702 distance: 1, 1703 delay: 0 1704 }, 1705 _mouseInit: function() { 1706 var that = this; 1707 1708 this.element 1709 .on( "mousedown." + this.widgetName, function( event ) { 1710 return that._mouseDown( event ); 1711 } ) 1712 .on( "click." + this.widgetName, function( event ) { 1713 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 1714 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 1715 event.stopImmediatePropagation(); 1716 return false; 1717 } 1718 } ); 1719 1720 this.started = false; 1721 }, 1722 1723 // TODO: make sure destroying one instance of mouse doesn't mess with 1724 // other instances of mouse 1725 _mouseDestroy: function() { 1726 this.element.off( "." + this.widgetName ); 1727 if ( this._mouseMoveDelegate ) { 1728 this.document 1729 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1730 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1731 } 1732 }, 1733 1734 _mouseDown: function( event ) { 1735 1736 // don't let more than one widget handle mouseStart 1737 if ( mouseHandled ) { 1738 return; 1739 } 1740 1741 this._mouseMoved = false; 1742 1743 // We may have missed mouseup (out of window) 1744 if ( this._mouseStarted ) { 1745 this._mouseUp( event ); 1746 } 1747 1748 this._mouseDownEvent = event; 1749 1750 var that = this, 1751 btnIsLeft = event.which === 1, 1752 elIsCancel = typeof this.options.cancel === "string" ? 1753 $( event.target ).closest( this.options.cancel ).length : 1754 false; 1755 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 1756 return true; 1757 } 1758 1759 this.mouseDelayMet = !this.options.delay; 1760 if ( !this.mouseDelayMet ) { 1761 this._mouseDelayTimer = setTimeout( function() { 1762 that.mouseDelayMet = true; 1763 }, this.options.delay ); 1764 } 1765 1766 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1767 this._mouseStarted = ( this._mouseStart( event ) !== false ); 1768 if ( !this._mouseStarted ) { 1769 event.preventDefault(); 1770 return true; 1771 } 1772 } 1773 1774 // Click event may never have fired (Gecko & Opera) 1775 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 1776 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 1777 } 1778 1779 // These delegates are required to keep context 1780 this._mouseMoveDelegate = function( event ) { 1781 return that._mouseMove( event ); 1782 }; 1783 this._mouseUpDelegate = function( event ) { 1784 return that._mouseUp( event ); 1785 }; 1786 1787 this.document 1788 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1789 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1790 1791 event.preventDefault(); 1792 1793 mouseHandled = true; 1794 return true; 1795 }, 1796 1797 _mouseMove: function( event ) { 1798 1799 // Only check for mouseups outside the document if you've moved inside the document 1800 // at least once. 1801 if ( this._mouseMoved && !event.which ) { 1802 1803 // Support: Safari <=8 - 9 1804 // Safari sets which to 0 if you press any of the following keys 1805 // during a drag (#14461) 1806 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 1807 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 1808 this.ignoreMissingWhich = true; 1809 } else if ( !this.ignoreMissingWhich ) { 1810 return this._mouseUp( event ); 1811 } 1812 } 1813 1814 if ( event.which || event.button ) { 1815 this._mouseMoved = true; 1816 } 1817 1818 if ( this._mouseStarted ) { 1819 this._mouseDrag( event ); 1820 return event.preventDefault(); 1821 } 1822 1823 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1824 this._mouseStarted = 1825 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 1826 if ( this._mouseStarted ) { 1827 this._mouseDrag( event ); 1828 } else { 1829 this._mouseUp( event ); 1830 } 1831 } 1832 1833 return !this._mouseStarted; 1834 }, 1835 1836 _mouseUp: function( event ) { 1837 this.document 1838 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1839 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1840 1841 if ( this._mouseStarted ) { 1842 this._mouseStarted = false; 1843 1844 if ( event.target === this._mouseDownEvent.target ) { 1845 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 1846 } 1847 1848 this._mouseStop( event ); 1849 } 1850 1851 if ( this._mouseDelayTimer ) { 1852 clearTimeout( this._mouseDelayTimer ); 1853 delete this._mouseDelayTimer; 1854 } 1855 1856 this.ignoreMissingWhich = false; 1857 mouseHandled = false; 1858 event.preventDefault(); 1859 }, 1860 1861 _mouseDistanceMet: function( event ) { 1862 return ( Math.max( 1863 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 1864 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 1865 ) >= this.options.distance 1866 ); 1867 }, 1868 1869 _mouseDelayMet: function( /* event */ ) { 1870 return this.mouseDelayMet; 1871 }, 1872 1873 // These are placeholder methods, to be overriden by extending plugin 1874 _mouseStart: function( /* event */ ) {}, 1875 _mouseDrag: function( /* event */ ) {}, 1876 _mouseStop: function( /* event */ ) {}, 1877 _mouseCapture: function( /* event */ ) { 1878 return true; 1879 } 1880} ); 1881 1882 1883 1884// $.ui.plugin is deprecated. Use $.widget() extensions instead. 1885var plugin = $.ui.plugin = { 1886 add: function( module, option, set ) { 1887 var i, 1888 proto = $.ui[ module ].prototype; 1889 for ( i in set ) { 1890 proto.plugins[ i ] = proto.plugins[ i ] || []; 1891 proto.plugins[ i ].push( [ option, set[ i ] ] ); 1892 } 1893 }, 1894 call: function( instance, name, args, allowDisconnected ) { 1895 var i, 1896 set = instance.plugins[ name ]; 1897 1898 if ( !set ) { 1899 return; 1900 } 1901 1902 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 1903 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 1904 return; 1905 } 1906 1907 for ( i = 0; i < set.length; i++ ) { 1908 if ( instance.options[ set[ i ][ 0 ] ] ) { 1909 set[ i ][ 1 ].apply( instance.element, args ); 1910 } 1911 } 1912 } 1913}; 1914 1915 1916/*! 1917 * jQuery UI Draggable 1.14.2 1918 * https://jqueryui.com 1919 * 1920 * Copyright OpenJS Foundation and other contributors 1921 * Released under the MIT license. 1922 * https://jquery.org/license 1923 */ 1924 1925//>>label: Draggable 1926//>>group: Interactions 1927//>>description: Enables dragging functionality for any element. 1928//>>docs: https://api.jqueryui.com/draggable/ 1929//>>demos: https://jqueryui.com/draggable/ 1930//>>css.structure: ../../themes/base/draggable.css 1931 1932 1933$.widget( "ui.draggable", $.ui.mouse, { 1934 version: "1.14.2", 1935 widgetEventPrefix: "drag", 1936 options: { 1937 addClasses: true, 1938 appendTo: "parent", 1939 axis: false, 1940 connectToSortable: false, 1941 containment: false, 1942 cursor: "auto", 1943 cursorAt: false, 1944 grid: false, 1945 handle: false, 1946 helper: "original", 1947 iframeFix: false, 1948 opacity: false, 1949 refreshPositions: false, 1950 revert: false, 1951 revertDuration: 500, 1952 scope: "default", 1953 scroll: true, 1954 scrollSensitivity: 20, 1955 scrollSpeed: 20, 1956 snap: false, 1957 snapMode: "both", 1958 snapTolerance: 20, 1959 stack: false, 1960 zIndex: false, 1961 1962 // Callbacks 1963 drag: null, 1964 start: null, 1965 stop: null 1966 }, 1967 _create: function() { 1968 1969 if ( this.options.helper === "original" ) { 1970 this._setPositionRelative(); 1971 } 1972 if ( this.options.addClasses ) { 1973 this._addClass( "ui-draggable" ); 1974 } 1975 this._setHandleClassName(); 1976 1977 this._mouseInit(); 1978 }, 1979 1980 _setOption: function( key, value ) { 1981 this._super( key, value ); 1982 if ( key === "handle" ) { 1983 this._removeHandleClassName(); 1984 this._setHandleClassName(); 1985 } 1986 }, 1987 1988 _destroy: function() { 1989 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 1990 this.destroyOnClear = true; 1991 return; 1992 } 1993 this._removeHandleClassName(); 1994 this._mouseDestroy(); 1995 }, 1996 1997 _mouseCapture: function( event ) { 1998 var o = this.options; 1999 2000 // Among others, prevent a drag on a resizable-handle 2001 if ( this.helper || o.disabled || 2002 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 2003 return false; 2004 } 2005 2006 //Quit if we're not on a valid handle 2007 this.handle = this._getHandle( event ); 2008 if ( !this.handle ) { 2009 return false; 2010 } 2011 2012 this._blurActiveElement( event ); 2013 2014 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 2015 2016 return true; 2017 2018 }, 2019 2020 _blockFrames: function( selector ) { 2021 this.iframeBlocks = this.document.find( selector ).map( function() { 2022 var iframe = $( this ); 2023 2024 return $( "<div>" ) 2025 .css( "position", "absolute" ) 2026 .appendTo( iframe.parent() ) 2027 .outerWidth( iframe.outerWidth() ) 2028 .outerHeight( iframe.outerHeight() ) 2029 .offset( iframe.offset() )[ 0 ]; 2030 } ); 2031 }, 2032 2033 _unblockFrames: function() { 2034 if ( this.iframeBlocks ) { 2035 this.iframeBlocks.remove(); 2036 delete this.iframeBlocks; 2037 } 2038 }, 2039 2040 _blurActiveElement: function( event ) { 2041 var activeElement = this.document[ 0 ].activeElement, 2042 target = $( event.target ); 2043 2044 // Don't blur if the event occurred on an element that is within 2045 // the currently focused element 2046 // See #10527, #12472 2047 if ( target.closest( activeElement ).length ) { 2048 return; 2049 } 2050 2051 // Blur any element that currently has focus, see #4261 2052 $( activeElement ).trigger( "blur" ); 2053 }, 2054 2055 _mouseStart: function( event ) { 2056 2057 var o = this.options; 2058 2059 //Create and append the visible helper 2060 this.helper = this._createHelper( event ); 2061 2062 this._addClass( this.helper, "ui-draggable-dragging" ); 2063 2064 //Cache the helper size 2065 this._cacheHelperProportions(); 2066 2067 //If ddmanager is used for droppables, set the global draggable 2068 if ( $.ui.ddmanager ) { 2069 $.ui.ddmanager.current = this; 2070 } 2071 2072 /* 2073 * - Position generation - 2074 * This block generates everything position related - it's the core of draggables. 2075 */ 2076 2077 //Cache the margins of the original element 2078 this._cacheMargins(); 2079 2080 //Store the helper's css position 2081 this.cssPosition = this.helper.css( "position" ); 2082 this.scrollParent = this.helper.scrollParent( true ); 2083 this.offsetParent = this.helper.offsetParent(); 2084 this.hasFixedAncestor = this.helper.parents().filter( function() { 2085 return $( this ).css( "position" ) === "fixed"; 2086 } ).length > 0; 2087 2088 //The element's absolute position on the page minus margins 2089 this.positionAbs = this.element.offset(); 2090 this._refreshOffsets( event ); 2091 2092 //Generate the original position 2093 this.originalPosition = this.position = this._generatePosition( event, false ); 2094 this.originalPageX = event.pageX; 2095 this.originalPageY = event.pageY; 2096 2097 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 2098 if ( o.cursorAt ) { 2099 this._adjustOffsetFromHelper( o.cursorAt ); 2100 } 2101 2102 //Set a containment if given in the options 2103 this._setContainment(); 2104 2105 //Trigger event + callbacks 2106 if ( this._trigger( "start", event ) === false ) { 2107 this._clear(); 2108 return false; 2109 } 2110 2111 //Recache the helper size 2112 this._cacheHelperProportions(); 2113 2114 //Prepare the droppable offsets 2115 if ( $.ui.ddmanager && !o.dropBehaviour ) { 2116 $.ui.ddmanager.prepareOffsets( this, event ); 2117 } 2118 2119 // Execute the drag once - this causes the helper not to be visible before getting its 2120 // correct position 2121 this._mouseDrag( event, true ); 2122 2123 // If the ddmanager is used for droppables, inform the manager that dragging has started 2124 // (see #5003) 2125 if ( $.ui.ddmanager ) { 2126 $.ui.ddmanager.dragStart( this, event ); 2127 } 2128 2129 return true; 2130 }, 2131 2132 _refreshOffsets: function( event ) { 2133 this.offset = { 2134 top: this.positionAbs.top - this.margins.top, 2135 left: this.positionAbs.left - this.margins.left, 2136 scroll: false, 2137 parent: this._getParentOffset(), 2138 relative: this._getRelativeOffset() 2139 }; 2140 2141 this.offset.click = { 2142 left: event.pageX - this.offset.left, 2143 top: event.pageY - this.offset.top 2144 }; 2145 }, 2146 2147 _mouseDrag: function( event, noPropagation ) { 2148 2149 // reset any necessary cached properties (see #5009) 2150 if ( this.hasFixedAncestor ) { 2151 this.offset.parent = this._getParentOffset(); 2152 } 2153 2154 //Compute the helpers position 2155 this.position = this._generatePosition( event, true ); 2156 this.positionAbs = this._convertPositionTo( "absolute" ); 2157 2158 //Call plugins and callbacks and use the resulting position if something is returned 2159 if ( !noPropagation ) { 2160 var ui = this._uiHash(); 2161 if ( this._trigger( "drag", event, ui ) === false ) { 2162 this._mouseUp( new $.Event( "mouseup", event ) ); 2163 return false; 2164 } 2165 this.position = ui.position; 2166 } 2167 2168 this.helper[ 0 ].style.left = this.position.left + "px"; 2169 this.helper[ 0 ].style.top = this.position.top + "px"; 2170 2171 if ( $.ui.ddmanager ) { 2172 $.ui.ddmanager.drag( this, event ); 2173 } 2174 2175 return false; 2176 }, 2177 2178 _mouseStop: function( event ) { 2179 2180 //If we are using droppables, inform the manager about the drop 2181 var that = this, 2182 dropped = false; 2183 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 2184 dropped = $.ui.ddmanager.drop( this, event ); 2185 } 2186 2187 //if a drop comes from outside (a sortable) 2188 if ( this.dropped ) { 2189 dropped = this.dropped; 2190 this.dropped = false; 2191 } 2192 2193 if ( ( this.options.revert === "invalid" && !dropped ) || 2194 ( this.options.revert === "valid" && dropped ) || 2195 this.options.revert === true || ( typeof this.options.revert === "function" && 2196 this.options.revert.call( this.element, dropped ) ) 2197 ) { 2198 $( this.helper ).animate( 2199 this.originalPosition, 2200 parseInt( this.options.revertDuration, 10 ), 2201 function() { 2202 if ( that._trigger( "stop", event ) !== false ) { 2203 that._clear(); 2204 } 2205 } 2206 ); 2207 } else { 2208 if ( this._trigger( "stop", event ) !== false ) { 2209 this._clear(); 2210 } 2211 } 2212 2213 return false; 2214 }, 2215 2216 _mouseUp: function( event ) { 2217 this._unblockFrames(); 2218 2219 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 2220 // (see #5003) 2221 if ( $.ui.ddmanager ) { 2222 $.ui.ddmanager.dragStop( this, event ); 2223 } 2224 2225 // Only need to focus if the event occurred on the draggable itself, see #10527 2226 if ( this.handleElement.is( event.target ) ) { 2227 2228 // The interaction is over; whether or not the click resulted in a drag, 2229 // focus the element 2230 this.element.trigger( "focus" ); 2231 } 2232 2233 return $.ui.mouse.prototype._mouseUp.call( this, event ); 2234 }, 2235 2236 cancel: function() { 2237 2238 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 2239 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 2240 } else { 2241 this._clear(); 2242 } 2243 2244 return this; 2245 2246 }, 2247 2248 _getHandle: function( event ) { 2249 return this.options.handle ? 2250 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 2251 true; 2252 }, 2253 2254 _setHandleClassName: function() { 2255 this.handleElement = this.options.handle ? 2256 this.element.find( this.options.handle ) : this.element; 2257 this._addClass( this.handleElement, "ui-draggable-handle" ); 2258 }, 2259 2260 _removeHandleClassName: function() { 2261 this._removeClass( this.handleElement, "ui-draggable-handle" ); 2262 }, 2263 2264 _createHelper: function( event ) { 2265 2266 var o = this.options, 2267 helperIsFunction = typeof o.helper === "function", 2268 helper = helperIsFunction ? 2269 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 2270 ( o.helper === "clone" ? 2271 this.element.clone().removeAttr( "id" ) : 2272 this.element ); 2273 2274 if ( !helper.parents( "body" ).length ) { 2275 helper.appendTo( ( o.appendTo === "parent" ? 2276 this.element[ 0 ].parentNode : 2277 o.appendTo ) ); 2278 } 2279 2280 // https://bugs.jqueryui.com/ticket/9446 2281 // a helper function can return the original element 2282 // which wouldn't have been set to relative in _create 2283 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 2284 this._setPositionRelative(); 2285 } 2286 2287 if ( helper[ 0 ] !== this.element[ 0 ] && 2288 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 2289 helper.css( "position", "absolute" ); 2290 } 2291 2292 return helper; 2293 2294 }, 2295 2296 _setPositionRelative: function() { 2297 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 2298 this.element[ 0 ].style.position = "relative"; 2299 } 2300 }, 2301 2302 _adjustOffsetFromHelper: function( obj ) { 2303 if ( typeof obj === "string" ) { 2304 obj = obj.split( " " ); 2305 } 2306 if ( Array.isArray( obj ) ) { 2307 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 2308 } 2309 if ( "left" in obj ) { 2310 this.offset.click.left = obj.left + this.margins.left; 2311 } 2312 if ( "right" in obj ) { 2313 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 2314 } 2315 if ( "top" in obj ) { 2316 this.offset.click.top = obj.top + this.margins.top; 2317 } 2318 if ( "bottom" in obj ) { 2319 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 2320 } 2321 }, 2322 2323 _isRootNode: function( element ) { 2324 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 2325 }, 2326 2327 _getParentOffset: function() { 2328 2329 //Get the offsetParent and cache its position 2330 var po = this.offsetParent.offset(), 2331 document = this.document[ 0 ]; 2332 2333 // This is a special case where we need to modify a offset calculated on start, since the 2334 // following happened: 2335 // 1. The position of the helper is absolute, so it's position is calculated based on the 2336 // next positioned parent 2337 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 2338 // the document, which means that the scroll is included in the initial calculation of the 2339 // offset of the parent, and never recalculated upon drag 2340 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 2341 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 2342 po.left += this.scrollParent.scrollLeft(); 2343 po.top += this.scrollParent.scrollTop(); 2344 } 2345 2346 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 2347 po = { top: 0, left: 0 }; 2348 } 2349 2350 return { 2351 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 2352 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 2353 }; 2354 2355 }, 2356 2357 _getRelativeOffset: function() { 2358 if ( this.cssPosition !== "relative" ) { 2359 return { top: 0, left: 0 }; 2360 } 2361 2362 var p = this.element.position(), 2363 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2364 2365 return { 2366 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 2367 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 2368 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 2369 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 2370 }; 2371 2372 }, 2373 2374 _cacheMargins: function() { 2375 this.margins = { 2376 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 2377 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 2378 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 2379 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 2380 }; 2381 }, 2382 2383 _cacheHelperProportions: function() { 2384 this.helperProportions = { 2385 width: this.helper.outerWidth(), 2386 height: this.helper.outerHeight() 2387 }; 2388 }, 2389 2390 _setContainment: function() { 2391 2392 var isUserScrollable, c, ce, 2393 o = this.options, 2394 document = this.document[ 0 ]; 2395 2396 this.relativeContainer = null; 2397 2398 if ( !o.containment ) { 2399 this.containment = null; 2400 return; 2401 } 2402 2403 if ( o.containment === "window" ) { 2404 this.containment = [ 2405 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 2406 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 2407 $( window ).scrollLeft() + $( window ).width() - 2408 this.helperProportions.width - this.margins.left, 2409 $( window ).scrollTop() + 2410 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 2411 this.helperProportions.height - this.margins.top 2412 ]; 2413 return; 2414 } 2415 2416 if ( o.containment === "document" ) { 2417 this.containment = [ 2418 0, 2419 0, 2420 $( document ).width() - this.helperProportions.width - this.margins.left, 2421 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 2422 this.helperProportions.height - this.margins.top 2423 ]; 2424 return; 2425 } 2426 2427 if ( o.containment.constructor === Array ) {
vendor: 10,369 bytes, lines 2428-2774
2428 this.containment = o.containment; 2429 return; 2430 } 2431 2432 if ( o.containment === "parent" ) { 2433 o.containment = this.helper[ 0 ].parentNode; 2434 } 2435 2436 c = $( o.containment ); 2437 ce = c[ 0 ]; 2438 2439 if ( !ce ) { 2440 return; 2441 } 2442 2443 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 2444 2445 this.containment = [ 2446 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 2447 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 2448 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 2449 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 2450 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 2451 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 2452 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 2453 this.helperProportions.width - 2454 this.margins.left - 2455 this.margins.right, 2456 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 2457 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 2458 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 2459 this.helperProportions.height - 2460 this.margins.top - 2461 this.margins.bottom 2462 ]; 2463 this.relativeContainer = c; 2464 }, 2465 2466 _convertPositionTo: function( d, pos ) { 2467 2468 if ( !pos ) { 2469 pos = this.position; 2470 } 2471 2472 var mod = d === "absolute" ? 1 : -1, 2473 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2474 2475 return { 2476 top: ( 2477 2478 // The absolute mouse position 2479 pos.top + 2480 2481 // Only for relative positioned nodes: Relative offset from element to offset parent 2482 this.offset.relative.top * mod + 2483 2484 // The offsetParent's offset without borders (offset + border) 2485 this.offset.parent.top * mod - 2486 ( ( this.cssPosition === "fixed" ? 2487 -this.offset.scroll.top : 2488 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 2489 ), 2490 left: ( 2491 2492 // The absolute mouse position 2493 pos.left + 2494 2495 // Only for relative positioned nodes: Relative offset from element to offset parent 2496 this.offset.relative.left * mod + 2497 2498 // The offsetParent's offset without borders (offset + border) 2499 this.offset.parent.left * mod - 2500 ( ( this.cssPosition === "fixed" ? 2501 -this.offset.scroll.left : 2502 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 2503 ) 2504 }; 2505 2506 }, 2507 2508 _generatePosition: function( event, constrainPosition ) { 2509 2510 var containment, co, top, left, 2511 o = this.options, 2512 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2513 pageX = event.pageX, 2514 pageY = event.pageY; 2515 2516 // Cache the scroll 2517 if ( !scrollIsRootNode || !this.offset.scroll ) { 2518 this.offset.scroll = { 2519 top: this.scrollParent.scrollTop(), 2520 left: this.scrollParent.scrollLeft() 2521 }; 2522 } 2523 2524 /* 2525 * - Position constraining - 2526 * Constrain the position to a mix of grid, containment. 2527 */ 2528 2529 // If we are not dragging yet, we won't check for options 2530 if ( constrainPosition ) { 2531 if ( this.containment ) { 2532 if ( this.relativeContainer ) { 2533 co = this.relativeContainer.offset(); 2534 containment = [ 2535 this.containment[ 0 ] + co.left, 2536 this.containment[ 1 ] + co.top, 2537 this.containment[ 2 ] + co.left, 2538 this.containment[ 3 ] + co.top 2539 ]; 2540 } else { 2541 containment = this.containment; 2542 } 2543 2544 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 2545 pageX = containment[ 0 ] + this.offset.click.left; 2546 } 2547 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 2548 pageY = containment[ 1 ] + this.offset.click.top; 2549 } 2550 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 2551 pageX = containment[ 2 ] + this.offset.click.left; 2552 } 2553 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 2554 pageY = containment[ 3 ] + this.offset.click.top; 2555 } 2556 } 2557 2558 if ( o.grid ) { 2559 2560 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 2561 // argument errors in IE (see ticket #6950) 2562 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 2563 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 2564 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 2565 top - this.offset.click.top > containment[ 3 ] ) ? 2566 top : 2567 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 2568 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 2569 2570 left = o.grid[ 0 ] ? this.originalPageX + 2571 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 2572 this.originalPageX; 2573 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 2574 left - this.offset.click.left > containment[ 2 ] ) ? 2575 left : 2576 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 2577 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 2578 } 2579 2580 if ( o.axis === "y" ) { 2581 pageX = this.originalPageX; 2582 } 2583 2584 if ( o.axis === "x" ) { 2585 pageY = this.originalPageY; 2586 } 2587 } 2588 2589 return { 2590 top: ( 2591 2592 // The absolute mouse position 2593 pageY - 2594 2595 // Click offset (relative to the element) 2596 this.offset.click.top - 2597 2598 // Only for relative positioned nodes: Relative offset from element to offset parent 2599 this.offset.relative.top - 2600 2601 // The offsetParent's offset without borders (offset + border) 2602 this.offset.parent.top + 2603 ( this.cssPosition === "fixed" ? 2604 -this.offset.scroll.top : 2605 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2606 ), 2607 left: ( 2608 2609 // The absolute mouse position 2610 pageX - 2611 2612 // Click offset (relative to the element) 2613 this.offset.click.left - 2614 2615 // Only for relative positioned nodes: Relative offset from element to offset parent 2616 this.offset.relative.left - 2617 2618 // The offsetParent's offset without borders (offset + border) 2619 this.offset.parent.left + 2620 ( this.cssPosition === "fixed" ? 2621 -this.offset.scroll.left : 2622 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2623 ) 2624 }; 2625 2626 }, 2627 2628 _clear: function() { 2629 this._removeClass( this.helper, "ui-draggable-dragging" ); 2630 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 2631 this.helper.remove(); 2632 } 2633 this.helper = null; 2634 this.cancelHelperRemoval = false; 2635 if ( this.destroyOnClear ) { 2636 this.destroy(); 2637 } 2638 }, 2639 2640 // From now on bulk stuff - mainly helpers 2641 2642 _trigger: function( type, event, ui ) { 2643 ui = ui || this._uiHash(); 2644 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2645 2646 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 2647 if ( /^(drag|start|stop)/.test( type ) ) { 2648 this.positionAbs = this._convertPositionTo( "absolute" ); 2649 ui.offset = this.positionAbs; 2650 } 2651 return $.Widget.prototype._trigger.call( this, type, event, ui ); 2652 }, 2653 2654 plugins: {}, 2655 2656 _uiHash: function() { 2657 return { 2658 helper: this.helper, 2659 position: this.position, 2660 originalPosition: this.originalPosition, 2661 offset: this.positionAbs 2662 }; 2663 } 2664 2665} ); 2666 2667$.ui.plugin.add( "draggable", "connectToSortable", { 2668 start: function( event, ui, draggable ) { 2669 var uiSortable = $.extend( {}, ui, { 2670 item: draggable.element 2671 } ); 2672 2673 draggable.sortables = []; 2674 $( draggable.options.connectToSortable ).each( function() { 2675 var sortable = $( this ).sortable( "instance" ); 2676 2677 if ( sortable && !sortable.options.disabled ) { 2678 draggable.sortables.push( sortable ); 2679 2680 // RefreshPositions is called at drag start to refresh the containerCache 2681 // which is used in drag. This ensures it's initialized and synchronized 2682 // with any changes that might have happened on the page since initialization. 2683 sortable.refreshPositions(); 2684 sortable._trigger( "activate", event, uiSortable ); 2685 } 2686 } ); 2687 }, 2688 stop: function( event, ui, draggable ) { 2689 var uiSortable = $.extend( {}, ui, { 2690 item: draggable.element 2691 } ); 2692 2693 draggable.cancelHelperRemoval = false; 2694 2695 $.each( draggable.sortables, function() { 2696 var sortable = this; 2697 2698 if ( sortable.isOver ) { 2699 sortable.isOver = 0; 2700 2701 // Allow this sortable to handle removing the helper 2702 draggable.cancelHelperRemoval = true; 2703 sortable.cancelHelperRemoval = false; 2704 2705 // Use _storedCSS To restore properties in the sortable, 2706 // as this also handles revert (#9675) since the draggable 2707 // may have modified them in unexpected ways (#8809) 2708 sortable._storedCSS = { 2709 position: sortable.placeholder.css( "position" ), 2710 top: sortable.placeholder.css( "top" ), 2711 left: sortable.placeholder.css( "left" ) 2712 }; 2713 2714 sortable._mouseStop( event ); 2715 2716 // Once drag has ended, the sortable should return to using 2717 // its original helper, not the shared helper from draggable 2718 sortable.options.helper = sortable.options._helper; 2719 } else { 2720 2721 // Prevent this Sortable from removing the helper. 2722 // However, don't set the draggable to remove the helper 2723 // either as another connected Sortable may yet handle the removal. 2724 sortable.cancelHelperRemoval = true; 2725 2726 sortable._trigger( "deactivate", event, uiSortable ); 2727 } 2728 } ); 2729 }, 2730 drag: function( event, ui, draggable ) { 2731 $.each( draggable.sortables, function() { 2732 var innermostIntersecting = false, 2733 sortable = this; 2734 2735 // Copy over variables that sortable's _intersectsWith uses 2736 sortable.positionAbs = draggable.positionAbs; 2737 sortable.helperProportions = draggable.helperProportions; 2738 sortable.offset.click = draggable.offset.click; 2739 2740 if ( sortable._intersectsWith( sortable.containerCache ) ) { 2741 innermostIntersecting = true; 2742 2743 $.each( draggable.sortables, function() { 2744 2745 // Copy over variables that sortable's _intersectsWith uses 2746 this.positionAbs = draggable.positionAbs; 2747 this.helperProportions = draggable.helperProportions; 2748 this.offset.click = draggable.offset.click; 2749 2750 if ( this !== sortable && 2751 this._intersectsWith( this.containerCache ) && 2752 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 2753 innermostIntersecting = false; 2754 } 2755 2756 return innermostIntersecting; 2757 } ); 2758 } 2759 2760 if ( innermostIntersecting ) { 2761 2762 // If it intersects, we use a little isOver variable and set it once, 2763 // so that the move-in stuff gets fired only once. 2764 if ( !sortable.isOver ) { 2765 sortable.isOver = 1; 2766 2767 // Store draggable's parent in case we need to reappend to it later. 2768 draggable._parent = ui.helper.parent(); 2769 2770 sortable.currentItem = ui.helper 2771 .appendTo( sortable.element ) 2772 .data( "ui-sortable-item", true ); 2773 2774 // Store helper option to later restore it
vendor: 55,332 bytes, lines 2775-4889
2775 sortable.options._helper = sortable.options.helper; 2776 2777 sortable.options.helper = function() { 2778 return ui.helper[ 0 ]; 2779 }; 2780 2781 // Fire the start events of the sortable with our passed browser event, 2782 // and our own helper (so it doesn't create a new one) 2783 event.target = sortable.currentItem[ 0 ]; 2784 sortable._mouseCapture( event, true ); 2785 sortable._mouseStart( event, true, true ); 2786 2787 // Because the browser event is way off the new appended portlet, 2788 // modify necessary variables to reflect the changes 2789 sortable.offset.click.top = draggable.offset.click.top; 2790 sortable.offset.click.left = draggable.offset.click.left; 2791 sortable.offset.parent.left -= draggable.offset.parent.left - 2792 sortable.offset.parent.left; 2793 sortable.offset.parent.top -= draggable.offset.parent.top - 2794 sortable.offset.parent.top; 2795 2796 draggable._trigger( "toSortable", event ); 2797 2798 // Inform draggable that the helper is in a valid drop zone, 2799 // used solely in the revert option to handle "valid/invalid". 2800 draggable.dropped = sortable.element; 2801 2802 // Need to refreshPositions of all sortables in the case that 2803 // adding to one sortable changes the location of the other sortables (#9675) 2804 $.each( draggable.sortables, function() { 2805 this.refreshPositions(); 2806 } ); 2807 2808 // Hack so receive/update callbacks work (mostly) 2809 draggable.currentItem = draggable.element; 2810 sortable.fromOutside = draggable; 2811 } 2812 2813 if ( sortable.currentItem ) { 2814 sortable._mouseDrag( event ); 2815 2816 // Copy the sortable's position because the draggable's can potentially reflect 2817 // a relative position, while sortable is always absolute, which the dragged 2818 // element has now become. (#8809) 2819 ui.position = sortable.position; 2820 } 2821 } else { 2822 2823 // If it doesn't intersect with the sortable, and it intersected before, 2824 // we fake the drag stop of the sortable, but make sure it doesn't remove 2825 // the helper by using cancelHelperRemoval. 2826 if ( sortable.isOver ) { 2827 2828 sortable.isOver = 0; 2829 sortable.cancelHelperRemoval = true; 2830 2831 // Calling sortable's mouseStop would trigger a revert, 2832 // so revert must be temporarily false until after mouseStop is called. 2833 sortable.options._revert = sortable.options.revert; 2834 sortable.options.revert = false; 2835 2836 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 2837 sortable._mouseStop( event, true ); 2838 2839 // Restore sortable behaviors that were modfied 2840 // when the draggable entered the sortable area (#9481) 2841 sortable.options.revert = sortable.options._revert; 2842 sortable.options.helper = sortable.options._helper; 2843 2844 if ( sortable.placeholder ) { 2845 sortable.placeholder.remove(); 2846 } 2847 2848 // Restore and recalculate the draggable's offset considering the sortable 2849 // may have modified them in unexpected ways. (#8809, #10669) 2850 ui.helper.appendTo( draggable._parent ); 2851 draggable._refreshOffsets( event ); 2852 ui.position = draggable._generatePosition( event, true ); 2853 2854 draggable._trigger( "fromSortable", event ); 2855 2856 // Inform draggable that the helper is no longer in a valid drop zone 2857 draggable.dropped = false; 2858 2859 // Need to refreshPositions of all sortables just in case removing 2860 // from one sortable changes the location of other sortables (#9675) 2861 $.each( draggable.sortables, function() { 2862 this.refreshPositions(); 2863 } ); 2864 } 2865 } 2866 } ); 2867 } 2868} ); 2869 2870$.ui.plugin.add( "draggable", "cursor", { 2871 start: function( event, ui, instance ) { 2872 var t = $( "body" ), 2873 o = instance.options; 2874 2875 if ( t.css( "cursor" ) ) { 2876 o._cursor = t.css( "cursor" ); 2877 } 2878 t.css( "cursor", o.cursor ); 2879 }, 2880 stop: function( event, ui, instance ) { 2881 var o = instance.options; 2882 if ( o._cursor ) { 2883 $( "body" ).css( "cursor", o._cursor ); 2884 } 2885 } 2886} ); 2887 2888$.ui.plugin.add( "draggable", "opacity", { 2889 start: function( event, ui, instance ) { 2890 var t = $( ui.helper ), 2891 o = instance.options; 2892 if ( t.css( "opacity" ) ) { 2893 o._opacity = t.css( "opacity" ); 2894 } 2895 t.css( "opacity", o.opacity ); 2896 }, 2897 stop: function( event, ui, instance ) { 2898 var o = instance.options; 2899 if ( o._opacity ) { 2900 $( ui.helper ).css( "opacity", o._opacity ); 2901 } 2902 } 2903} ); 2904 2905$.ui.plugin.add( "draggable", "scroll", { 2906 start: function( event, ui, i ) { 2907 if ( !i.scrollParentNotHidden ) { 2908 i.scrollParentNotHidden = i.helper.scrollParent( false ); 2909 } 2910 2911 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 2912 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 2913 i.overflowOffset = i.scrollParentNotHidden.offset(); 2914 } 2915 }, 2916 drag: function( event, ui, i ) { 2917 2918 var o = i.options, 2919 scrolled = false, 2920 scrollParent = i.scrollParentNotHidden[ 0 ], 2921 document = i.document[ 0 ]; 2922 2923 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 2924 if ( !o.axis || o.axis !== "x" ) { 2925 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 2926 o.scrollSensitivity ) { 2927 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 2928 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 2929 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 2930 } 2931 } 2932 2933 if ( !o.axis || o.axis !== "y" ) { 2934 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 2935 o.scrollSensitivity ) { 2936 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 2937 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 2938 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 2939 } 2940 } 2941 2942 } else { 2943 2944 if ( !o.axis || o.axis !== "x" ) { 2945 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 2946 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 2947 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 2948 o.scrollSensitivity ) { 2949 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 2950 } 2951 } 2952 2953 if ( !o.axis || o.axis !== "y" ) { 2954 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 2955 scrolled = $( document ).scrollLeft( 2956 $( document ).scrollLeft() - o.scrollSpeed 2957 ); 2958 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 2959 o.scrollSensitivity ) { 2960 scrolled = $( document ).scrollLeft( 2961 $( document ).scrollLeft() + o.scrollSpeed 2962 ); 2963 } 2964 } 2965 2966 } 2967 2968 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 2969 $.ui.ddmanager.prepareOffsets( i, event ); 2970 } 2971 2972 } 2973} ); 2974 2975$.ui.plugin.add( "draggable", "snap", { 2976 start: function( event, ui, i ) { 2977 2978 var o = i.options; 2979 2980 i.snapElements = []; 2981 2982 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 2983 .each( function() { 2984 var $t = $( this ), 2985 $o = $t.offset(); 2986 if ( this !== i.element[ 0 ] ) { 2987 i.snapElements.push( { 2988 item: this, 2989 width: $t.outerWidth(), height: $t.outerHeight(), 2990 top: $o.top, left: $o.left 2991 } ); 2992 } 2993 } ); 2994 2995 }, 2996 drag: function( event, ui, inst ) { 2997 2998 var ts, bs, ls, rs, l, r, t, b, i, first, 2999 o = inst.options, 3000 d = o.snapTolerance, 3001 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 3002 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 3003 3004 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 3005 3006 l = inst.snapElements[ i ].left - inst.margins.left; 3007 r = l + inst.snapElements[ i ].width; 3008 t = inst.snapElements[ i ].top - inst.margins.top; 3009 b = t + inst.snapElements[ i ].height; 3010 3011 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 3012 !$.contains( inst.snapElements[ i ].item.ownerDocument, 3013 inst.snapElements[ i ].item ) ) { 3014 if ( inst.snapElements[ i ].snapping ) { 3015 if ( inst.options.snap.release ) { 3016 inst.options.snap.release.call( 3017 inst.element, 3018 event, 3019 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 3020 ); 3021 } 3022 } 3023 inst.snapElements[ i ].snapping = false; 3024 continue; 3025 } 3026 3027 if ( o.snapMode !== "inner" ) { 3028 ts = Math.abs( t - y2 ) <= d; 3029 bs = Math.abs( b - y1 ) <= d; 3030 ls = Math.abs( l - x2 ) <= d; 3031 rs = Math.abs( r - x1 ) <= d; 3032 if ( ts ) { 3033 ui.position.top = inst._convertPositionTo( "relative", { 3034 top: t - inst.helperProportions.height, 3035 left: 0 3036 } ).top; 3037 } 3038 if ( bs ) { 3039 ui.position.top = inst._convertPositionTo( "relative", { 3040 top: b, 3041 left: 0 3042 } ).top; 3043 } 3044 if ( ls ) { 3045 ui.position.left = inst._convertPositionTo( "relative", { 3046 top: 0, 3047 left: l - inst.helperProportions.width 3048 } ).left; 3049 } 3050 if ( rs ) { 3051 ui.position.left = inst._convertPositionTo( "relative", { 3052 top: 0, 3053 left: r 3054 } ).left; 3055 } 3056 } 3057 3058 first = ( ts || bs || ls || rs ); 3059 3060 if ( o.snapMode !== "outer" ) { 3061 ts = Math.abs( t - y1 ) <= d; 3062 bs = Math.abs( b - y2 ) <= d; 3063 ls = Math.abs( l - x1 ) <= d; 3064 rs = Math.abs( r - x2 ) <= d; 3065 if ( ts ) { 3066 ui.position.top = inst._convertPositionTo( "relative", { 3067 top: t, 3068 left: 0 3069 } ).top; 3070 } 3071 if ( bs ) { 3072 ui.position.top = inst._convertPositionTo( "relative", { 3073 top: b - inst.helperProportions.height, 3074 left: 0 3075 } ).top; 3076 } 3077 if ( ls ) { 3078 ui.position.left = inst._convertPositionTo( "relative", { 3079 top: 0, 3080 left: l 3081 } ).left; 3082 } 3083 if ( rs ) { 3084 ui.position.left = inst._convertPositionTo( "relative", { 3085 top: 0, 3086 left: r - inst.helperProportions.width 3087 } ).left; 3088 } 3089 } 3090 3091 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 3092 if ( inst.options.snap.snap ) { 3093 inst.options.snap.snap.call( 3094 inst.element, 3095 event, 3096 $.extend( inst._uiHash(), { 3097 snapItem: inst.snapElements[ i ].item 3098 } ) ); 3099 } 3100 } 3101 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 3102 3103 } 3104 3105 } 3106} ); 3107 3108$.ui.plugin.add( "draggable", "stack", { 3109 start: function( event, ui, instance ) { 3110 var min, 3111 o = instance.options, 3112 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 3113 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 3114 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 3115 } ); 3116 3117 if ( !group.length ) { 3118 return; 3119 } 3120 3121 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 3122 $( group ).each( function( i ) { 3123 $( this ).css( "zIndex", min + i ); 3124 } ); 3125 this.css( "zIndex", ( min + group.length ) ); 3126 } 3127} ); 3128 3129$.ui.plugin.add( "draggable", "zIndex", { 3130 start: function( event, ui, instance ) { 3131 var t = $( ui.helper ), 3132 o = instance.options; 3133 3134 if ( t.css( "zIndex" ) ) { 3135 o._zIndex = t.css( "zIndex" ); 3136 } 3137 t.css( "zIndex", o.zIndex ); 3138 }, 3139 stop: function( event, ui, instance ) { 3140 var o = instance.options; 3141 3142 if ( o._zIndex ) { 3143 $( ui.helper ).css( "zIndex", o._zIndex ); 3144 } 3145 } 3146} ); 3147 3148var widgetsDraggable = $.ui.draggable; 3149 3150 3151/*! 3152 * jQuery UI Droppable 1.14.2 3153 * https://jqueryui.com 3154 * 3155 * Copyright OpenJS Foundation and other contributors 3156 * Released under the MIT license. 3157 * https://jquery.org/license 3158 */ 3159 3160//>>label: Droppable 3161//>>group: Interactions 3162//>>description: Enables drop targets for draggable elements. 3163//>>docs: https://api.jqueryui.com/droppable/ 3164//>>demos: https://jqueryui.com/droppable/ 3165 3166 3167$.widget( "ui.droppable", { 3168 version: "1.14.2", 3169 widgetEventPrefix: "drop", 3170 options: { 3171 accept: "*", 3172 addClasses: true, 3173 greedy: false, 3174 scope: "default", 3175 tolerance: "intersect", 3176 3177 // Callbacks 3178 activate: null, 3179 deactivate: null, 3180 drop: null, 3181 out: null, 3182 over: null 3183 }, 3184 _create: function() { 3185 3186 var proportions, 3187 o = this.options, 3188 accept = o.accept; 3189 3190 this.isover = false; 3191 this.isout = true; 3192 3193 this.accept = typeof accept === "function" ? accept : function( d ) { 3194 return d.is( accept ); 3195 }; 3196 3197 this.proportions = function( /* valueToWrite */ ) { 3198 if ( arguments.length ) { 3199 3200 // Store the droppable's proportions 3201 proportions = arguments[ 0 ]; 3202 } else { 3203 3204 // Retrieve or derive the droppable's proportions 3205 return proportions ? 3206 proportions : 3207 proportions = { 3208 width: this.element[ 0 ].offsetWidth, 3209 height: this.element[ 0 ].offsetHeight 3210 }; 3211 } 3212 }; 3213 3214 this._addToManager( o.scope ); 3215 3216 if ( o.addClasses ) { 3217 this._addClass( "ui-droppable" ); 3218 } 3219 3220 }, 3221 3222 _addToManager: function( scope ) { 3223 3224 // Add the reference and positions to the manager 3225 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 3226 $.ui.ddmanager.droppables[ scope ].push( this ); 3227 }, 3228 3229 _splice: function( drop ) { 3230 var i = 0; 3231 for ( ; i < drop.length; i++ ) { 3232 if ( drop[ i ] === this ) { 3233 drop.splice( i, 1 ); 3234 } 3235 } 3236 }, 3237 3238 _destroy: function() { 3239 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3240 3241 this._splice( drop ); 3242 }, 3243 3244 _setOption: function( key, value ) { 3245 3246 if ( key === "accept" ) { 3247 this.accept = typeof value === "function" ? value : function( d ) { 3248 return d.is( value ); 3249 }; 3250 } else if ( key === "scope" ) { 3251 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3252 3253 this._splice( drop ); 3254 this._addToManager( value ); 3255 } 3256 3257 this._super( key, value ); 3258 }, 3259 3260 _activate: function( event ) { 3261 var draggable = $.ui.ddmanager.current; 3262 3263 this._addActiveClass(); 3264 if ( draggable ) { 3265 this._trigger( "activate", event, this.ui( draggable ) ); 3266 } 3267 }, 3268 3269 _deactivate: function( event ) { 3270 var draggable = $.ui.ddmanager.current; 3271 3272 this._removeActiveClass(); 3273 if ( draggable ) { 3274 this._trigger( "deactivate", event, this.ui( draggable ) ); 3275 } 3276 }, 3277 3278 _over: function( event ) { 3279 3280 var draggable = $.ui.ddmanager.current; 3281 3282 // Bail if draggable and droppable are same element 3283 if ( !draggable || ( draggable.currentItem || 3284 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3285 return; 3286 } 3287 3288 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3289 draggable.element ) ) ) { 3290 this._addHoverClass(); 3291 this._trigger( "over", event, this.ui( draggable ) ); 3292 } 3293 3294 }, 3295 3296 _out: function( event ) { 3297 3298 var draggable = $.ui.ddmanager.current; 3299 3300 // Bail if draggable and droppable are same element 3301 if ( !draggable || ( draggable.currentItem || 3302 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3303 return; 3304 } 3305 3306 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3307 draggable.element ) ) ) { 3308 this._removeHoverClass(); 3309 this._trigger( "out", event, this.ui( draggable ) ); 3310 } 3311 3312 }, 3313 3314 _drop: function( event, custom ) { 3315 3316 var draggable = custom || $.ui.ddmanager.current, 3317 childrenIntersection = false; 3318 3319 // Bail if draggable and droppable are same element 3320 if ( !draggable || ( draggable.currentItem || 3321 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3322 return false; 3323 } 3324 3325 this.element 3326 .find( ":data(ui-droppable)" ) 3327 .not( ".ui-draggable-dragging" ) 3328 .each( function() { 3329 var inst = $( this ).droppable( "instance" ); 3330 if ( 3331 inst.options.greedy && 3332 !inst.options.disabled && 3333 inst.options.scope === draggable.options.scope && 3334 inst.accept.call( 3335 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 3336 ) && 3337 $.ui.intersect( 3338 draggable, 3339 $.extend( inst, { offset: inst.element.offset() } ), 3340 inst.options.tolerance, event 3341 ) 3342 ) { 3343 childrenIntersection = true; 3344 return false; 3345 } 3346 } ); 3347 if ( childrenIntersection ) { 3348 return false; 3349 } 3350 3351 if ( this.accept.call( this.element[ 0 ], 3352 ( draggable.currentItem || draggable.element ) ) ) { 3353 this._removeActiveClass(); 3354 this._removeHoverClass(); 3355 3356 this._trigger( "drop", event, this.ui( draggable ) ); 3357 return this.element; 3358 } 3359 3360 return false; 3361 3362 }, 3363 3364 ui: function( c ) { 3365 return { 3366 draggable: ( c.currentItem || c.element ), 3367 helper: c.helper, 3368 position: c.position, 3369 offset: c.positionAbs 3370 }; 3371 }, 3372 3373 // Extension points just to make backcompat sane and avoid duplicating logic 3374 // TODO: Remove in 1.14 along with call to it below 3375 _addHoverClass: function() { 3376 this._addClass( "ui-droppable-hover" ); 3377 }, 3378 3379 _removeHoverClass: function() { 3380 this._removeClass( "ui-droppable-hover" ); 3381 }, 3382 3383 _addActiveClass: function() { 3384 this._addClass( "ui-droppable-active" ); 3385 }, 3386 3387 _removeActiveClass: function() { 3388 this._removeClass( "ui-droppable-active" ); 3389 } 3390} ); 3391 3392$.ui.intersect = ( function() { 3393 function isOverAxis( x, reference, size ) { 3394 return ( x >= reference ) && ( x < ( reference + size ) ); 3395 } 3396 3397 return function( draggable, droppable, toleranceMode, event ) { 3398 3399 if ( !droppable.offset ) { 3400 return false; 3401 } 3402 3403 var x1 = ( draggable.positionAbs || 3404 draggable.position.absolute ).left + draggable.margins.left, 3405 y1 = ( draggable.positionAbs || 3406 draggable.position.absolute ).top + draggable.margins.top, 3407 x2 = x1 + draggable.helperProportions.width, 3408 y2 = y1 + draggable.helperProportions.height, 3409 l = droppable.offset.left, 3410 t = droppable.offset.top, 3411 r = l + droppable.proportions().width, 3412 b = t + droppable.proportions().height; 3413 3414 switch ( toleranceMode ) { 3415 case "fit": 3416 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 3417 case "intersect": 3418 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 3419 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 3420 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 3421 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 3422 case "pointer": 3423 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 3424 isOverAxis( event.pageX, l, droppable.proportions().width ); 3425 case "touch": 3426 return ( 3427 ( y1 >= t && y1 <= b ) || // Top edge touching 3428 ( y2 >= t && y2 <= b ) || // Bottom edge touching 3429 ( y1 < t && y2 > b ) // Surrounded vertically 3430 ) && ( 3431 ( x1 >= l && x1 <= r ) || // Left edge touching 3432 ( x2 >= l && x2 <= r ) || // Right edge touching 3433 ( x1 < l && x2 > r ) // Surrounded horizontally 3434 ); 3435 default: 3436 return false; 3437 } 3438 }; 3439} )(); 3440 3441/* 3442 This manager tracks offsets of draggables and droppables 3443*/ 3444$.ui.ddmanager = { 3445 current: null, 3446 droppables: { "default": [] }, 3447 prepareOffsets: function( t, event ) { 3448 3449 var i, j, 3450 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 3451 type = event ? event.type : null, // workaround for #2317 3452 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 3453 3454 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 3455 3456 // No disabled and non-accepted 3457 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 3458 ( t.currentItem || t.element ) ) ) ) { 3459 continue; 3460 } 3461 3462 // Filter out elements in the current dragged item 3463 for ( j = 0; j < list.length; j++ ) { 3464 if ( list[ j ] === m[ i ].element[ 0 ] ) { 3465 m[ i ].proportions().height = 0; 3466 continue droppablesLoop; 3467 } 3468 } 3469 3470 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 3471 if ( !m[ i ].visible ) { 3472 continue; 3473 } 3474 3475 // Activate the droppable if used directly from draggables 3476 if ( type === "mousedown" ) { 3477 m[ i ]._activate.call( m[ i ], event ); 3478 } 3479 3480 m[ i ].offset = m[ i ].element.offset(); 3481 m[ i ].proportions( { 3482 width: m[ i ].element[ 0 ].offsetWidth, 3483 height: m[ i ].element[ 0 ].offsetHeight 3484 } ); 3485 3486 } 3487 3488 }, 3489 drop: function( draggable, event ) { 3490 3491 var dropped = false; 3492 3493 // Create a copy of the droppables in case the list changes during the drop (#9116) 3494 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 3495 3496 if ( !this.options ) { 3497 return; 3498 } 3499 if ( !this.options.disabled && this.visible && 3500 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 3501 dropped = this._drop.call( this, event ) || dropped; 3502 } 3503 3504 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 3505 ( draggable.currentItem || draggable.element ) ) ) { 3506 this.isout = true; 3507 this.isover = false; 3508 this._deactivate.call( this, event ); 3509 } 3510 3511 } ); 3512 return dropped; 3513 3514 }, 3515 dragStart: function( draggable, event ) { 3516 3517 // Listen for scrolling so that if the dragging causes scrolling the position of the 3518 // droppables can be recalculated (see #5003) 3519 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 3520 if ( !draggable.options.refreshPositions ) { 3521 $.ui.ddmanager.prepareOffsets( draggable, event ); 3522 } 3523 } ); 3524 }, 3525 drag: function( draggable, event ) { 3526 3527 // If you have a highly dynamic page, you might try this option. It renders positions 3528 // every time you move the mouse. 3529 if ( draggable.options.refreshPositions ) { 3530 $.ui.ddmanager.prepareOffsets( draggable, event ); 3531 } 3532 3533 // Run through all droppables and check their positions based on specific tolerance options 3534 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 3535 3536 if ( this.options.disabled || this.greedyChild || !this.visible ) { 3537 return; 3538 } 3539 3540 var parentInstance, scope, parent, 3541 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 3542 c = !intersects && this.isover ? 3543 "isout" : 3544 ( intersects && !this.isover ? "isover" : null ); 3545 if ( !c ) { 3546 return; 3547 } 3548 3549 if ( this.options.greedy ) { 3550 3551 // find droppable parents with same scope 3552 scope = this.options.scope; 3553 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 3554 return $( this ).droppable( "instance" ).options.scope === scope; 3555 } ); 3556 3557 if ( parent.length ) { 3558 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 3559 parentInstance.greedyChild = ( c === "isover" ); 3560 } 3561 } 3562 3563 // We just moved into a greedy child 3564 if ( parentInstance && c === "isover" ) { 3565 parentInstance.isover = false; 3566 parentInstance.isout = true; 3567 parentInstance._out.call( parentInstance, event ); 3568 } 3569 3570 this[ c ] = true; 3571 this[ c === "isout" ? "isover" : "isout" ] = false; 3572 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 3573 3574 // We just moved out of a greedy child 3575 if ( parentInstance && c === "isout" ) { 3576 parentInstance.isout = false; 3577 parentInstance.isover = true; 3578 parentInstance._over.call( parentInstance, event ); 3579 } 3580 } ); 3581 3582 }, 3583 dragStop: function( draggable, event ) { 3584 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 3585 3586 // Call prepareOffsets one final time since IE does not fire return scroll events when 3587 // overflow was caused by drag (see #5003) 3588 if ( !draggable.options.refreshPositions ) { 3589 $.ui.ddmanager.prepareOffsets( draggable, event ); 3590 } 3591 } 3592}; 3593 3594// DEPRECATED 3595// TODO: switch return back to widget declaration at top of file when this is removed 3596if ( $.uiBackCompat === true ) { 3597 3598 // Backcompat for activeClass and hoverClass options 3599 $.widget( "ui.droppable", $.ui.droppable, { 3600 options: { 3601 hoverClass: false, 3602 activeClass: false 3603 }, 3604 _addActiveClass: function() { 3605 this._super(); 3606 if ( this.options.activeClass ) { 3607 this.element.addClass( this.options.activeClass ); 3608 } 3609 }, 3610 _removeActiveClass: function() { 3611 this._super(); 3612 if ( this.options.activeClass ) { 3613 this.element.removeClass( this.options.activeClass ); 3614 } 3615 }, 3616 _addHoverClass: function() { 3617 this._super(); 3618 if ( this.options.hoverClass ) { 3619 this.element.addClass( this.options.hoverClass ); 3620 } 3621 }, 3622 _removeHoverClass: function() { 3623 this._super(); 3624 if ( this.options.hoverClass ) { 3625 this.element.removeClass( this.options.hoverClass ); 3626 } 3627 } 3628 } ); 3629} 3630 3631var widgetsDroppable = $.ui.droppable; 3632 3633 3634/*! 3635 * jQuery UI Resizable 1.14.2 3636 * https://jqueryui.com 3637 * 3638 * Copyright OpenJS Foundation and other contributors 3639 * Released under the MIT license. 3640 * https://jquery.org/license 3641 */ 3642 3643//>>label: Resizable 3644//>>group: Interactions 3645//>>description: Enables resize functionality for any element. 3646//>>docs: https://api.jqueryui.com/resizable/ 3647//>>demos: https://jqueryui.com/resizable/ 3648//>>css.structure: ../../themes/base/core.css 3649//>>css.structure: ../../themes/base/resizable.css 3650//>>css.theme: ../../themes/base/theme.css 3651 3652 3653$.widget( "ui.resizable", $.ui.mouse, { 3654 version: "1.14.2", 3655 widgetEventPrefix: "resize", 3656 options: { 3657 alsoResize: false, 3658 animate: false, 3659 animateDuration: "slow", 3660 animateEasing: "swing", 3661 aspectRatio: false, 3662 autoHide: false, 3663 classes: { 3664 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 3665 }, 3666 containment: false, 3667 ghost: false, 3668 grid: false, 3669 handles: "e,s,se", 3670 helper: false, 3671 maxHeight: null, 3672 maxWidth: null, 3673 minHeight: 10, 3674 minWidth: 10, 3675 3676 // See #7960 3677 zIndex: 90, 3678 3679 // Callbacks 3680 resize: null, 3681 start: null, 3682 stop: null 3683 }, 3684 3685 _num: function( value ) { 3686 return parseFloat( value ) || 0; 3687 }, 3688 3689 _isNumber: function( value ) { 3690 return !isNaN( parseFloat( value ) ); 3691 }, 3692 3693 _hasScroll: function( el, a ) { 3694 3695 var scroll, 3696 has = false, 3697 overflow = $( el ).css( "overflow" ); 3698 3699 if ( overflow === "hidden" ) { 3700 return false; 3701 } 3702 if ( overflow === "scroll" ) { 3703 return true; 3704 } 3705 3706 scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop"; 3707 3708 if ( el[ scroll ] > 0 ) { 3709 return true; 3710 } 3711 3712 // TODO: determine which cases actually cause this to happen 3713 // if the element doesn't have the scroll set, see if it's possible to 3714 // set the scroll 3715 try { 3716 el[ scroll ] = 1; 3717 has = ( el[ scroll ] > 0 ); 3718 el[ scroll ] = 0; 3719 } catch ( _e ) { 3720 3721 // `el` might be a string, then setting `scroll` will throw 3722 // an error in strict mode; ignore it. 3723 } 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'></div>" ).css( { 3747 overflow: "hidden", 3748 position: this.element.css( "position" ), 3749 width: this.element.outerWidth(), 3750 height: this.element.outerHeight(), 3751 top: this.element.css( "top" ), 3752 left: this.element.css( "left" ) 3753 } ) 3754 ); 3755 3756 this.element = this.element.parent().data( 3757 "ui-resizable", this.element.resizable( "instance" ) 3758 ); 3759 3760 this.elementIsWrapper = true; 3761 3762 margins = { 3763 marginTop: this.originalElement.css( "marginTop" ), 3764 marginRight: this.originalElement.css( "marginRight" ), 3765 marginBottom: this.originalElement.css( "marginBottom" ), 3766 marginLeft: this.originalElement.css( "marginLeft" ) 3767 }; 3768 3769 this.element.css( margins ); 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 this._proportionallyResize(); 3783 } 3784 3785 this._setupHandles(); 3786 3787 if ( o.autoHide ) { 3788 $( this.element ) 3789 .on( "mouseenter", function() { 3790 if ( o.disabled ) { 3791 return; 3792 } 3793 that._removeClass( "ui-resizable-autohide" ); 3794 that._handles.show(); 3795 } ) 3796 .on( "mouseleave", function() { 3797 if ( o.disabled ) { 3798 return; 3799 } 3800 if ( !that.resizing ) { 3801 that._addClass( "ui-resizable-autohide" ); 3802 that._handles.hide(); 3803 } 3804 } ); 3805 } 3806 3807 this._mouseInit(); 3808 }, 3809 3810 _destroy: function() { 3811 3812 this._mouseDestroy(); 3813 this._addedHandles.remove(); 3814 3815 var wrapper, 3816 _destroy = function( exp ) { 3817 $( exp ) 3818 .removeData( "resizable" ) 3819 .removeData( "ui-resizable" ) 3820 .off( ".resizable" ); 3821 }; 3822 3823 // TODO: Unwrap at same DOM position 3824 if ( this.elementIsWrapper ) { 3825 _destroy( this.element ); 3826 wrapper = this.element; 3827 this.originalElement.css( { 3828 position: wrapper.css( "position" ), 3829 width: wrapper.outerWidth(), 3830 height: wrapper.outerHeight(), 3831 top: wrapper.css( "top" ), 3832 left: wrapper.css( "left" ) 3833 } ).insertAfter( wrapper ); 3834 wrapper.remove(); 3835 } 3836 3837 this.originalElement.css( "resize", this.originalResizeStyle ); 3838 _destroy( this.originalElement ); 3839 3840 return this; 3841 }, 3842 3843 _setOption: function( key, value ) { 3844 this._super( key, value ); 3845 3846 switch ( key ) { 3847 case "handles": 3848 this._removeHandles(); 3849 this._setupHandles(); 3850 break; 3851 case "aspectRatio": 3852 this._aspectRatio = !!value; 3853 break; 3854 default: 3855 break; 3856 } 3857 }, 3858 3859 _setupHandles: function() { 3860 var o = this.options, handle, i, n, hname, axis, that = this; 3861 this.handles = o.handles || 3862 ( !$( ".ui-resizable-handle", this.element ).length ? 3863 "e,s,se" : { 3864 n: ".ui-resizable-n", 3865 e: ".ui-resizable-e", 3866 s: ".ui-resizable-s", 3867 w: ".ui-resizable-w", 3868 se: ".ui-resizable-se", 3869 sw: ".ui-resizable-sw", 3870 ne: ".ui-resizable-ne", 3871 nw: ".ui-resizable-nw" 3872 } ); 3873 3874 this._handles = $(); 3875 this._addedHandles = $(); 3876 if ( this.handles.constructor === String ) { 3877 3878 if ( this.handles === "all" ) { 3879 this.handles = "n,e,s,w,se,sw,ne,nw"; 3880 } 3881 3882 n = this.handles.split( "," ); 3883 this.handles = {}; 3884 3885 for ( i = 0; i < n.length; i++ ) { 3886 3887 handle = String.prototype.trim.call( n[ i ] ); 3888 hname = "ui-resizable-" + handle; 3889 axis = $( "<div>" ); 3890 this._addClass( axis, "ui-resizable-handle " + hname ); 3891 3892 axis.css( { zIndex: o.zIndex } ); 3893 3894 this.handles[ handle ] = ".ui-resizable-" + handle; 3895 if ( !this.element.children( this.handles[ handle ] ).length ) { 3896 this.element.append( axis ); 3897 this._addedHandles = this._addedHandles.add( axis ); 3898 } 3899 } 3900 3901 } 3902 3903 this._renderAxis = function( target ) { 3904 3905 var i, axis, padPos, padWrapper; 3906 3907 target = target || this.element; 3908 3909 for ( i in this.handles ) { 3910 3911 if ( this.handles[ i ].constructor === String ) { 3912 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 3913 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 3914 this.handles[ i ] = $( this.handles[ i ] ); 3915 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 3916 } 3917 3918 if ( this.elementIsWrapper && 3919 this.originalElement[ 0 ] 3920 .nodeName 3921 .match( /^(textarea|input|select|button)$/i ) ) { 3922 axis = $( this.handles[ i ], this.element ); 3923 3924 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 3925 axis.outerHeight() : 3926 axis.outerWidth(); 3927 3928 padPos = [ "padding", 3929 /ne|nw|n/.test( i ) ? "Top" : 3930 /se|sw|s/.test( i ) ? "Bottom" : 3931 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 3932 3933 target.css( padPos, padWrapper ); 3934 3935 this._proportionallyResize(); 3936 } 3937 3938 this._handles = this._handles.add( this.handles[ i ] ); 3939 } 3940 }; 3941 3942 // TODO: make renderAxis a prototype function 3943 this._renderAxis( this.element ); 3944 3945 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 3946 this._handles.disableSelection(); 3947 3948 this._handles.on( "mouseover", function() { 3949 if ( !that.resizing ) { 3950 if ( this.className ) { 3951 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 3952 } 3953 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 3954 } 3955 } ); 3956 3957 if ( o.autoHide ) { 3958 this._handles.hide(); 3959 this._addClass( "ui-resizable-autohide" ); 3960 } 3961 }, 3962 3963 _removeHandles: function() { 3964 this._addedHandles.remove(); 3965 }, 3966 3967 _mouseCapture: function( event ) { 3968 var i, handle, 3969 capture = false; 3970 3971 for ( i in this.handles ) { 3972 handle = $( this.handles[ i ] )[ 0 ]; 3973 if ( handle === event.target || $.contains( handle, event.target ) ) { 3974 capture = true; 3975 } 3976 } 3977 3978 return !this.options.disabled && capture; 3979 }, 3980 3981 _mouseStart: function( event ) { 3982 3983 var curleft, curtop, cursor, calculatedSize, 3984 o = this.options, 3985 el = this.element; 3986 3987 this.resizing = true; 3988 3989 this._renderProxy(); 3990 3991 curleft = this._num( this.helper.css( "left" ) ); 3992 curtop = this._num( this.helper.css( "top" ) ); 3993 3994 if ( o.containment ) { 3995 curleft += $( o.containment ).scrollLeft() || 0; 3996 curtop += $( o.containment ).scrollTop() || 0; 3997 } 3998 3999 this.offset = this.helper.offset(); 4000 this.position = { left: curleft, top: curtop }; 4001 4002 if ( !this._helper ) { 4003 calculatedSize = this._calculateAdjustedElementDimensions( el ); 4004 } 4005 4006 this.size = this._helper ? { 4007 width: this.helper.width(), 4008 height: this.helper.height() 4009 } : { 4010 width: calculatedSize.width, 4011 height: calculatedSize.height 4012 }; 4013 4014 this.originalSize = this._helper ? { 4015 width: el.outerWidth(), 4016 height: el.outerHeight() 4017 } : { 4018 width: calculatedSize.width, 4019 height: calculatedSize.height 4020 }; 4021 4022 this.sizeDiff = { 4023 width: el.outerWidth() - el.width(), 4024 height: el.outerHeight() - el.height() 4025 }; 4026 4027 this.originalPosition = { left: curleft, top: curtop }; 4028 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 4029 4030 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 4031 o.aspectRatio : 4032 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 4033 4034 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 4035 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 4036 4037 this._addClass( "ui-resizable-resizing" ); 4038 this._propagate( "start", event ); 4039 return true; 4040 }, 4041 4042 _mouseDrag: function( event ) { 4043 4044 var data, props, 4045 smp = this.originalMousePosition, 4046 a = this.axis, 4047 dx = ( event.pageX - smp.left ) || 0, 4048 dy = ( event.pageY - smp.top ) || 0, 4049 trigger = this._change[ a ]; 4050 4051 this._updatePrevProperties(); 4052 4053 if ( !trigger ) { 4054 return false; 4055 } 4056 4057 data = trigger.apply( this, [ event, dx, dy ] ); 4058 4059 this._updateVirtualBoundaries( event.shiftKey ); 4060 if ( this._aspectRatio || event.shiftKey ) { 4061 data = this._updateRatio( data, event ); 4062 } 4063 4064 data = this._respectSize( data, event ); 4065 4066 this._updateCache( data ); 4067 4068 this._propagate( "resize", event ); 4069 4070 props = this._applyChanges(); 4071 4072 if ( !this._helper && this._proportionallyResizeElements.length ) { 4073 this._proportionallyResize(); 4074 } 4075 4076 if ( !$.isEmptyObject( props ) ) { 4077 this._updatePrevProperties(); 4078 this._trigger( "resize", event, this.ui() ); 4079 this._applyChanges(); 4080 } 4081 4082 return false; 4083 }, 4084 4085 _mouseStop: function( event ) { 4086 4087 this.resizing = false; 4088 var pr, ista, soffseth, soffsetw, s, left, top, 4089 o = this.options, that = this; 4090 4091 if ( this._helper ) { 4092 4093 pr = this._proportionallyResizeElements; 4094 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 4095 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 4096 soffsetw = ista ? 0 : that.sizeDiff.width; 4097 4098 s = { 4099 width: ( that.helper.width() - soffsetw ), 4100 height: ( that.helper.height() - soffseth ) 4101 }; 4102 left = ( parseFloat( that.element.css( "left" ) ) + 4103 ( that.position.left - that.originalPosition.left ) ) || null; 4104 top = ( parseFloat( that.element.css( "top" ) ) + 4105 ( that.position.top - that.originalPosition.top ) ) || null; 4106 4107 if ( !o.animate ) { 4108 this.element.css( $.extend( s, { top: top, left: left } ) ); 4109 } 4110 4111 that.helper.height( that.size.height ); 4112 that.helper.width( that.size.width ); 4113 4114 if ( this._helper && !o.animate ) { 4115 this._proportionallyResize(); 4116 } 4117 } 4118 4119 $( "body" ).css( "cursor", "auto" ); 4120 4121 this._removeClass( "ui-resizable-resizing" ); 4122 4123 this._propagate( "stop", event ); 4124 4125 if ( this._helper ) { 4126 this.helper.remove(); 4127 } 4128 4129 return false; 4130 4131 }, 4132 4133 _updatePrevProperties: function() { 4134 this.prevPosition = { 4135 top: this.position.top, 4136 left: this.position.left 4137 }; 4138 this.prevSize = { 4139 width: this.size.width, 4140 height: this.size.height 4141 }; 4142 }, 4143 4144 _applyChanges: function() { 4145 var props = {}; 4146 4147 if ( this.position.top !== this.prevPosition.top ) { 4148 props.top = this.position.top + "px"; 4149 } 4150 if ( this.position.left !== this.prevPosition.left ) { 4151 props.left = this.position.left + "px"; 4152 } 4153 4154 this.helper.css( props ); 4155 4156 if ( this.size.width !== this.prevSize.width ) { 4157 props.width = this.size.width + "px"; 4158 this.helper.width( props.width ); 4159 } 4160 if ( this.size.height !== this.prevSize.height ) { 4161 props.height = this.size.height + "px"; 4162 this.helper.height( props.height ); 4163 } 4164 4165 return props; 4166 }, 4167 4168 _updateVirtualBoundaries: function( forceAspectRatio ) { 4169 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 4170 o = this.options; 4171 4172 b = { 4173 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 4174 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 4175 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 4176 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 4177 }; 4178 4179 if ( this._aspectRatio || forceAspectRatio ) { 4180 pMinWidth = b.minHeight * this.aspectRatio; 4181 pMinHeight = b.minWidth / this.aspectRatio; 4182 pMaxWidth = b.maxHeight * this.aspectRatio; 4183 pMaxHeight = b.maxWidth / this.aspectRatio; 4184 4185 if ( pMinWidth > b.minWidth ) { 4186 b.minWidth = pMinWidth; 4187 } 4188 if ( pMinHeight > b.minHeight ) { 4189 b.minHeight = pMinHeight; 4190 } 4191 if ( pMaxWidth < b.maxWidth ) { 4192 b.maxWidth = pMaxWidth; 4193 } 4194 if ( pMaxHeight < b.maxHeight ) { 4195 b.maxHeight = pMaxHeight; 4196 } 4197 } 4198 this._vBoundaries = b; 4199 }, 4200 4201 _updateCache: function( data ) { 4202 this.offset = this.helper.offset(); 4203 if ( this._isNumber( data.left ) ) { 4204 this.position.left = data.left; 4205 } 4206 if ( this._isNumber( data.top ) ) { 4207 this.position.top = data.top; 4208 } 4209 if ( this._isNumber( data.height ) ) { 4210 this.size.height = data.height; 4211 } 4212 if ( this._isNumber( data.width ) ) { 4213 this.size.width = data.width; 4214 } 4215 }, 4216 4217 _updateRatio: function( data ) { 4218 4219 var cpos = this.position, 4220 csize = this.size, 4221 a = this.axis; 4222 4223 if ( this._isNumber( data.height ) ) { 4224 data.width = ( data.height * this.aspectRatio ); 4225 } else if ( this._isNumber( data.width ) ) { 4226 data.height = ( data.width / this.aspectRatio ); 4227 } 4228 4229 if ( a === "sw" ) { 4230 data.left = cpos.left + ( csize.width - data.width ); 4231 data.top = null; 4232 } 4233 if ( a === "nw" ) { 4234 data.top = cpos.top + ( csize.height - data.height ); 4235 data.left = cpos.left + ( csize.width - data.width ); 4236 } 4237 4238 return data; 4239 }, 4240 4241 _respectSize: function( data ) { 4242 4243 var o = this._vBoundaries, 4244 a = this.axis, 4245 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 4246 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 4247 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 4248 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 4249 dw = this.originalPosition.left + this.originalSize.width, 4250 dh = this.originalPosition.top + this.originalSize.height, 4251 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 4252 if ( isminw ) { 4253 data.width = o.minWidth; 4254 } 4255 if ( isminh ) { 4256 data.height = o.minHeight; 4257 } 4258 if ( ismaxw ) { 4259 data.width = o.maxWidth; 4260 } 4261 if ( ismaxh ) { 4262 data.height = o.maxHeight; 4263 } 4264 4265 if ( isminw && cw ) { 4266 data.left = dw - o.minWidth; 4267 } 4268 if ( ismaxw && cw ) { 4269 data.left = dw - o.maxWidth; 4270 } 4271 if ( isminh && ch ) { 4272 data.top = dh - o.minHeight; 4273 } 4274 if ( ismaxh && ch ) { 4275 data.top = dh - o.maxHeight; 4276 } 4277 4278 // Fixing jump error on top/left - bug #2330 4279 if ( !data.width && !data.height && !data.left && data.top ) { 4280 data.top = null; 4281 } else if ( !data.width && !data.height && !data.top && data.left ) { 4282 data.left = null; 4283 } 4284 4285 return data; 4286 }, 4287 4288 _getPaddingPlusBorderDimensions: function( element ) { 4289 var i = 0, 4290 widths = [], 4291 borders = [ 4292 element.css( "borderTopWidth" ), 4293 element.css( "borderRightWidth" ), 4294 element.css( "borderBottomWidth" ), 4295 element.css( "borderLeftWidth" ) 4296 ], 4297 paddings = [ 4298 element.css( "paddingTop" ), 4299 element.css( "paddingRight" ), 4300 element.css( "paddingBottom" ), 4301 element.css( "paddingLeft" ) 4302 ]; 4303 4304 for ( ; i < 4; i++ ) { 4305 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 4306 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 4307 } 4308 4309 return { 4310 height: widths[ 0 ] + widths[ 2 ], 4311 width: widths[ 1 ] + widths[ 3 ] 4312 }; 4313 }, 4314 4315 _calculateAdjustedElementDimensions: function( element ) { 4316 var elWidth, elHeight, paddingBorder, 4317 ce = element.get( 0 ); 4318 4319 if ( element.css( "box-sizing" ) !== "content-box" || 4320 ( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) { 4321 return { 4322 height: parseFloat( element.css( "height" ) ), 4323 width: parseFloat( element.css( "width" ) ) 4324 }; 4325 } 4326 4327 // Check if CSS inline styles are set and use those (usually from previous resizes) 4328 elWidth = parseFloat( ce.style.width ); 4329 elHeight = parseFloat( ce.style.height ); 4330 4331 paddingBorder = this._getPaddingPlusBorderDimensions( element ); 4332 elWidth = isNaN( elWidth ) ? 4333 this._getElementTheoreticalSize( element, paddingBorder, "width" ) : 4334 elWidth; 4335 elHeight = isNaN( elHeight ) ? 4336 this._getElementTheoreticalSize( element, paddingBorder, "height" ) : 4337 elHeight; 4338 4339 return { 4340 height: elHeight, 4341 width: elWidth 4342 }; 4343 }, 4344 4345 _getElementTheoreticalSize: function( element, extraSize, dimension ) { 4346 4347 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 4348 var size = Math.max( 0, Math.ceil( 4349 element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 4350 extraSize[ dimension ] - 4351 0.5 4352 4353 // If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size. 4354 // Use an explicit zero to avoid NaN. 4355 // See https://github.com/jquery/jquery/issues/3964 4356 ) ) || 0; 4357 4358 return size; 4359 }, 4360 4361 _proportionallyResize: function() { 4362 4363 if ( !this._proportionallyResizeElements.length ) { 4364 return; 4365 } 4366 4367 var prel, 4368 i = 0, 4369 element = this.helper || this.element; 4370 4371 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 4372 4373 prel = this._proportionallyResizeElements[ i ]; 4374 4375 // TODO: Seems like a bug to cache this.outerDimensions 4376 // considering that we are in a loop. 4377 if ( !this.outerDimensions ) { 4378 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 4379 } 4380 4381 prel.css( { 4382 height: ( element.height() - this.outerDimensions.height ) || 0, 4383 width: ( element.width() - this.outerDimensions.width ) || 0 4384 } ); 4385 4386 } 4387 4388 }, 4389 4390 _renderProxy: function() { 4391 4392 var el = this.element, o = this.options; 4393 this.elementOffset = el.offset(); 4394 4395 if ( this._helper ) { 4396 4397 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); 4398 4399 this._addClass( this.helper, this._helper ); 4400 this.helper.css( { 4401 width: this.element.outerWidth(), 4402 height: this.element.outerHeight(), 4403 position: "absolute", 4404 left: this.elementOffset.left + "px", 4405 top: this.elementOffset.top + "px", 4406 zIndex: ++o.zIndex //TODO: Don't modify option 4407 } ); 4408 4409 this.helper 4410 .appendTo( "body" ) 4411 .disableSelection(); 4412 4413 } else { 4414 this.helper = this.element; 4415 } 4416 4417 }, 4418 4419 _change: { 4420 e: function( event, dx ) { 4421 return { width: this.originalSize.width + dx }; 4422 }, 4423 w: function( event, dx ) { 4424 var cs = this.originalSize, sp = this.originalPosition; 4425 return { left: sp.left + dx, width: cs.width - dx }; 4426 }, 4427 n: function( event, dx, dy ) { 4428 var cs = this.originalSize, sp = this.originalPosition; 4429 return { top: sp.top + dy, height: cs.height - dy }; 4430 }, 4431 s: function( event, dx, dy ) { 4432 return { height: this.originalSize.height + dy }; 4433 }, 4434 se: function( event, dx, dy ) { 4435 return $.extend( this._change.s.apply( this, arguments ), 4436 this._change.e.apply( this, [ event, dx, dy ] ) ); 4437 }, 4438 sw: function( event, dx, dy ) { 4439 return $.extend( this._change.s.apply( this, arguments ), 4440 this._change.w.apply( this, [ event, dx, dy ] ) ); 4441 }, 4442 ne: function( event, dx, dy ) { 4443 return $.extend( this._change.n.apply( this, arguments ), 4444 this._change.e.apply( this, [ event, dx, dy ] ) ); 4445 }, 4446 nw: function( event, dx, dy ) { 4447 return $.extend( this._change.n.apply( this, arguments ), 4448 this._change.w.apply( this, [ event, dx, dy ] ) ); 4449 } 4450 }, 4451 4452 _propagate: function( n, event ) { 4453 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 4454 if ( n !== "resize" ) { 4455 this._trigger( n, event, this.ui() ); 4456 } 4457 }, 4458 4459 plugins: {}, 4460 4461 ui: function() { 4462 return { 4463 originalElement: this.originalElement, 4464 element: this.element, 4465 helper: this.helper, 4466 position: this.position, 4467 size: this.size, 4468 originalSize: this.originalSize, 4469 originalPosition: this.originalPosition 4470 }; 4471 } 4472 4473} ); 4474 4475/* 4476 * Resizable Extensions 4477 */ 4478 4479$.ui.plugin.add( "resizable", "animate", { 4480 4481 stop: function( event ) { 4482 var that = $( this ).resizable( "instance" ), 4483 o = that.options, 4484 pr = that._proportionallyResizeElements, 4485 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 4486 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 4487 soffsetw = ista ? 0 : that.sizeDiff.width, 4488 style = { 4489 width: ( that.size.width - soffsetw ), 4490 height: ( that.size.height - soffseth ) 4491 }, 4492 left = ( parseFloat( that.element.css( "left" ) ) + 4493 ( that.position.left - that.originalPosition.left ) ) || null, 4494 top = ( parseFloat( that.element.css( "top" ) ) + 4495 ( that.position.top - that.originalPosition.top ) ) || null; 4496 4497 that.element.animate( 4498 $.extend( style, top && left ? { top: top, left: left } : {} ), { 4499 duration: o.animateDuration, 4500 easing: o.animateEasing, 4501 step: function() { 4502 4503 var data = { 4504 width: parseFloat( that.element.css( "width" ) ), 4505 height: parseFloat( that.element.css( "height" ) ), 4506 top: parseFloat( that.element.css( "top" ) ), 4507 left: parseFloat( that.element.css( "left" ) ) 4508 }; 4509 4510 if ( pr && pr.length ) { 4511 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 4512 } 4513 4514 // Propagating resize, and updating values for each animation step 4515 that._updateCache( data ); 4516 that._propagate( "resize", event ); 4517 4518 } 4519 } 4520 ); 4521 } 4522 4523} ); 4524 4525$.ui.plugin.add( "resizable", "containment", { 4526 4527 start: function() { 4528 var element, p, co, ch, cw, width, height, 4529 that = $( this ).resizable( "instance" ), 4530 o = that.options, 4531 el = that.element, 4532 oc = o.containment, 4533 ce = ( oc instanceof $ ) ? 4534 oc.get( 0 ) : 4535 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 4536 4537 if ( !ce ) { 4538 return; 4539 } 4540 4541 that.containerElement = $( ce ); 4542 4543 if ( /document/.test( oc ) || oc === document ) { 4544 that.containerOffset = { 4545 left: 0, 4546 top: 0 4547 }; 4548 that.containerPosition = { 4549 left: 0, 4550 top: 0 4551 }; 4552 4553 that.parentData = { 4554 element: $( document ), 4555 left: 0, 4556 top: 0, 4557 width: $( document ).width(), 4558 height: $( document ).height() || document.body.parentNode.scrollHeight 4559 }; 4560 } else { 4561 element = $( ce ); 4562 p = []; 4563 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 4564 p[ i ] = that._num( element.css( "padding" + name ) ); 4565 } ); 4566 4567 that.containerOffset = element.offset(); 4568 that.containerPosition = element.position(); 4569 that.containerSize = { 4570 height: ( element.innerHeight() - p[ 3 ] ), 4571 width: ( element.innerWidth() - p[ 1 ] ) 4572 }; 4573 4574 co = that.containerOffset; 4575 ch = that.containerSize.height; 4576 cw = that.containerSize.width; 4577 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); 4578 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); 4579 4580 that.parentData = { 4581 element: ce, 4582 left: co.left, 4583 top: co.top, 4584 width: width, 4585 height: height 4586 }; 4587 } 4588 }, 4589 4590 resize: function( event ) { 4591 var woset, hoset, isParent, isOffsetRelative, 4592 that = $( this ).resizable( "instance" ), 4593 o = that.options, 4594 co = that.containerOffset, 4595 cp = that.position, 4596 pRatio = that._aspectRatio || event.shiftKey, 4597 cop = { 4598 top: 0, 4599 left: 0 4600 }, 4601 ce = that.containerElement, 4602 continueResize = true; 4603 4604 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 4605 cop = co; 4606 } 4607 4608 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 4609 that.size.width = that.size.width + 4610 ( that._helper ? 4611 ( that.position.left - co.left ) : 4612 ( that.position.left - cop.left ) ); 4613 4614 if ( pRatio ) { 4615 that.size.height = that.size.width / that.aspectRatio; 4616 continueResize = false; 4617 } 4618 that.position.left = o.helper ? co.left : 0; 4619 } 4620 4621 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 4622 that.size.height = that.size.height + 4623 ( that._helper ? 4624 ( that.position.top - co.top ) : 4625 that.position.top ); 4626 4627 if ( pRatio ) { 4628 that.size.width = that.size.height * that.aspectRatio; 4629 continueResize = false; 4630 } 4631 that.position.top = that._helper ? co.top : 0; 4632 } 4633 4634 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 4635 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 4636 4637 if ( isParent && isOffsetRelative ) { 4638 that.offset.left = that.parentData.left + that.position.left; 4639 that.offset.top = that.parentData.top + that.position.top; 4640 } else { 4641 that.offset.left = that.element.offset().left; 4642 that.offset.top = that.element.offset().top; 4643 } 4644 4645 woset = Math.abs( that.sizeDiff.width + 4646 ( that._helper ? 4647 that.offset.left - cop.left : 4648 ( that.offset.left - co.left ) ) ); 4649 4650 hoset = Math.abs( that.sizeDiff.height + 4651 ( that._helper ? 4652 that.offset.top - cop.top : 4653 ( that.offset.top - co.top ) ) ); 4654 4655 if ( woset + that.size.width >= that.parentData.width ) { 4656 that.size.width = that.parentData.width - woset; 4657 if ( pRatio ) { 4658 that.size.height = that.size.width / that.aspectRatio; 4659 continueResize = false; 4660 } 4661 } 4662 4663 if ( hoset + that.size.height >= that.parentData.height ) { 4664 that.size.height = that.parentData.height - hoset; 4665 if ( pRatio ) { 4666 that.size.width = that.size.height * that.aspectRatio; 4667 continueResize = false; 4668 } 4669 } 4670 4671 if ( !continueResize ) { 4672 that.position.left = that.prevPosition.left; 4673 that.position.top = that.prevPosition.top; 4674 that.size.width = that.prevSize.width; 4675 that.size.height = that.prevSize.height; 4676 } 4677 }, 4678 4679 stop: function() { 4680 var that = $( this ).resizable( "instance" ), 4681 o = that.options, 4682 co = that.containerOffset, 4683 cop = that.containerPosition, 4684 ce = that.containerElement, 4685 helper = $( that.helper ), 4686 ho = helper.offset(), 4687 w = helper.outerWidth() - that.sizeDiff.width, 4688 h = helper.outerHeight() - that.sizeDiff.height; 4689 4690 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 4691 $( this ).css( { 4692 left: ho.left - cop.left - co.left, 4693 width: w, 4694 height: h 4695 } ); 4696 } 4697 4698 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 4699 $( this ).css( { 4700 left: ho.left - cop.left - co.left, 4701 width: w, 4702 height: h 4703 } ); 4704 } 4705 } 4706} ); 4707 4708$.ui.plugin.add( "resizable", "alsoResize", { 4709 4710 start: function() { 4711 var that = $( this ).resizable( "instance" ), 4712 o = that.options; 4713 4714 $( o.alsoResize ).each( function() { 4715 var el = $( this ), 4716 elSize = that._calculateAdjustedElementDimensions( el ); 4717 4718 el.data( "ui-resizable-alsoresize", { 4719 width: elSize.width, height: elSize.height, 4720 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 4721 } ); 4722 } ); 4723 }, 4724 4725 resize: function( event, ui ) { 4726 var that = $( this ).resizable( "instance" ), 4727 o = that.options, 4728 os = that.originalSize, 4729 op = that.originalPosition, 4730 delta = { 4731 height: ( that.size.height - os.height ) || 0, 4732 width: ( that.size.width - os.width ) || 0, 4733 top: ( that.position.top - op.top ) || 0, 4734 left: ( that.position.left - op.left ) || 0 4735 }; 4736 4737 $( o.alsoResize ).each( function() { 4738 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 4739 css = el.parents( ui.originalElement[ 0 ] ).length ? 4740 [ "width", "height" ] : 4741 [ "width", "height", "top", "left" ]; 4742 4743 $.each( css, function( i, prop ) { 4744 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 4745 if ( sum && sum >= 0 ) { 4746 style[ prop ] = sum || null; 4747 } 4748 } ); 4749 4750 el.css( style ); 4751 } ); 4752 }, 4753 4754 stop: function() { 4755 $( this ).removeData( "ui-resizable-alsoresize" ); 4756 } 4757} ); 4758 4759$.ui.plugin.add( "resizable", "ghost", { 4760 4761 start: function() { 4762 4763 var that = $( this ).resizable( "instance" ), cs = that.size; 4764 4765 that.ghost = that.originalElement.clone(); 4766 that.ghost.css( { 4767 opacity: 0.25, 4768 display: "block", 4769 position: "relative", 4770 height: cs.height, 4771 width: cs.width, 4772 margin: 0, 4773 left: 0, 4774 top: 0 4775 } ); 4776 4777 that._addClass( that.ghost, "ui-resizable-ghost" ); 4778 4779 // DEPRECATED 4780 // TODO: remove after 1.12 4781 if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) { 4782 4783 // Ghost option 4784 that.ghost.addClass( this.options.ghost ); 4785 } 4786 4787 that.ghost.appendTo( that.helper ); 4788 4789 }, 4790 4791 resize: function() { 4792 var that = $( this ).resizable( "instance" ); 4793 if ( that.ghost ) { 4794 that.ghost.css( { 4795 position: "relative", 4796 height: that.size.height, 4797 width: that.size.width 4798 } ); 4799 } 4800 }, 4801 4802 stop: function() { 4803 var that = $( this ).resizable( "instance" ); 4804 if ( that.ghost && that.helper ) { 4805 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 4806 } 4807 } 4808 4809} ); 4810 4811$.ui.plugin.add( "resizable", "grid", { 4812 4813 resize: function() { 4814 var outerDimensions, 4815 that = $( this ).resizable( "instance" ), 4816 o = that.options, 4817 cs = that.size, 4818 os = that.originalSize, 4819 op = that.originalPosition, 4820 a = that.axis, 4821 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4822 gridX = ( grid[ 0 ] || 1 ), 4823 gridY = ( grid[ 1 ] || 1 ), 4824 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 4825 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 4826 newWidth = os.width + ox, 4827 newHeight = os.height + oy, 4828 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 4829 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 4830 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 4831 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 4832 4833 o.grid = grid; 4834 4835 if ( isMinWidth ) { 4836 newWidth += gridX; 4837 } 4838 if ( isMinHeight ) { 4839 newHeight += gridY; 4840 } 4841 if ( isMaxWidth ) { 4842 newWidth -= gridX; 4843 } 4844 if ( isMaxHeight ) { 4845 newHeight -= gridY; 4846 } 4847 4848 if ( /^(se|s|e)$/.test( a ) ) { 4849 that.size.width = newWidth; 4850 that.size.height = newHeight; 4851 } else if ( /^(ne)$/.test( a ) ) { 4852 that.size.width = newWidth; 4853 that.size.height = newHeight; 4854 that.position.top = op.top - oy; 4855 } else if ( /^(sw)$/.test( a ) ) { 4856 that.size.width = newWidth; 4857 that.size.height = newHeight; 4858 that.position.left = op.left - ox; 4859 } else { 4860 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 4861 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4862 } 4863 4864 if ( newHeight - gridY > 0 ) { 4865 that.size.height = newHeight; 4866 that.position.top = op.top - oy; 4867 } else { 4868 newHeight = gridY - outerDimensions.height; 4869 that.size.height = newHeight; 4870 that.position.top = op.top + os.height - newHeight; 4871 } 4872 if ( newWidth - gridX > 0 ) { 4873 that.size.width = newWidth; 4874 that.position.left = op.left - ox; 4875 } else { 4876 newWidth = gridX - outerDimensions.width; 4877 that.size.width = newWidth; 4878 that.position.left = op.left + os.width - newWidth; 4879 } 4880 } 4881 } 4882 4883} ); 4884 4885var widgetsResizable = $.ui.resizable; 4886 4887 4888/*! 4889 * jQuery UI
vendor: 8,269 bytes, lines 4889-5203
4889Selectable 1.14.2 4890 * https://jqueryui.com 4891 * 4892 * Copyright OpenJS Foundation and other contributors 4893 * Released under the MIT license. 4894 * https://jquery.org/license 4895 */ 4896 4897//>>label: Selectable 4898//>>group: Interactions 4899//>>description: Allows groups of elements to be selected with the mouse. 4900//>>docs: https://api.jqueryui.com/selectable/ 4901//>>demos: https://jqueryui.com/selectable/ 4902//>>css.structure: ../../themes/base/selectable.css 4903 4904 4905var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 4906 version: "1.14.2", 4907 options: { 4908 appendTo: "body", 4909 autoRefresh: true, 4910 distance: 0, 4911 filter: "*", 4912 tolerance: "touch", 4913 4914 // Callbacks 4915 selected: null, 4916 selecting: null, 4917 start: null, 4918 stop: null, 4919 unselected: null, 4920 unselecting: null 4921 }, 4922 _create: function() { 4923 var that = this; 4924 4925 this._addClass( "ui-selectable" ); 4926 4927 this.dragged = false; 4928 4929 // Cache selectee children based on filter 4930 this.refresh = function() { 4931 that.elementPos = $( that.element[ 0 ] ).offset(); 4932 that.selectees = $( that.options.filter, that.element[ 0 ] ); 4933 that._addClass( that.selectees, "ui-selectee" ); 4934 that.selectees.each( function() { 4935 var $this = $( this ), 4936 selecteeOffset = $this.offset(), 4937 pos = { 4938 left: selecteeOffset.left - that.elementPos.left, 4939 top: selecteeOffset.top - that.elementPos.top 4940 }; 4941 $.data( this, "selectable-item", { 4942 element: this, 4943 $element: $this, 4944 left: pos.left, 4945 top: pos.top, 4946 right: pos.left + $this.outerWidth(), 4947 bottom: pos.top + $this.outerHeight(), 4948 startselected: false, 4949 selected: $this.hasClass( "ui-selected" ), 4950 selecting: $this.hasClass( "ui-selecting" ), 4951 unselecting: $this.hasClass( "ui-unselecting" ) 4952 } ); 4953 } ); 4954 }; 4955 this.refresh(); 4956 4957 this._mouseInit(); 4958 4959 this.helper = $( "<div>" ); 4960 this._addClass( this.helper, "ui-selectable-helper" ); 4961 }, 4962 4963 _destroy: function() { 4964 this.selectees.removeData( "selectable-item" ); 4965 this._mouseDestroy(); 4966 }, 4967 4968 _mouseStart: function( event ) { 4969 var that = this, 4970 options = this.options; 4971 4972 this.opos = [ event.pageX, event.pageY ]; 4973 this.elementPos = $( this.element[ 0 ] ).offset(); 4974 4975 if ( this.options.disabled ) { 4976 return; 4977 } 4978 4979 this.selectees = $( options.filter, this.element[ 0 ] ); 4980 4981 this._trigger( "start", event ); 4982 4983 $( options.appendTo ).append( this.helper ); 4984 4985 // position helper (lasso) 4986 this.helper.css( { 4987 "left": event.pageX, 4988 "top": event.pageY, 4989 "width": 0, 4990 "height": 0 4991 } ); 4992 4993 if ( options.autoRefresh ) { 4994 this.refresh(); 4995 } 4996 4997 this.selectees.filter( ".ui-selected" ).each( function() { 4998 var selectee = $.data( this, "selectable-item" ); 4999 selectee.startselected = true; 5000 if ( !event.metaKey && !event.ctrlKey ) { 5001 that._removeClass( selectee.$element, "ui-selected" ); 5002 selectee.selected = false; 5003 that._addClass( selectee.$element, "ui-unselecting" ); 5004 selectee.unselecting = true; 5005 5006 // selectable UNSELECTING callback 5007 that._trigger( "unselecting", event, { 5008 unselecting: selectee.element 5009 } ); 5010 } 5011 } ); 5012 5013 $( event.target ).parents().addBack().each( function() { 5014 var doSelect, 5015 selectee = $.data( this, "selectable-item" ); 5016 if ( selectee ) { 5017 doSelect = ( !event.metaKey && !event.ctrlKey ) || 5018 !selectee.$element.hasClass( "ui-selected" ); 5019 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 5020 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 5021 selectee.unselecting = !doSelect; 5022 selectee.selecting = doSelect; 5023 selectee.selected = doSelect; 5024 5025 // selectable (UN)SELECTING callback 5026 if ( doSelect ) { 5027 that._trigger( "selecting", event, { 5028 selecting: selectee.element 5029 } ); 5030 } else { 5031 that._trigger( "unselecting", event, { 5032 unselecting: selectee.element 5033 } ); 5034 } 5035 return false; 5036 } 5037 } ); 5038 5039 }, 5040 5041 _mouseDrag: function( event ) { 5042 5043 this.dragged = true; 5044 5045 if ( this.options.disabled ) { 5046 return; 5047 } 5048 5049 var tmp, 5050 that = this, 5051 options = this.options, 5052 x1 = this.opos[ 0 ], 5053 y1 = this.opos[ 1 ], 5054 x2 = event.pageX, 5055 y2 = event.pageY; 5056 5057 if ( x1 > x2 ) { 5058 tmp = x2; x2 = x1; x1 = tmp; 5059 } 5060 if ( y1 > y2 ) { 5061 tmp = y2; y2 = y1; y1 = tmp; 5062 } 5063 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 5064 5065 this.selectees.each( function() { 5066 var selectee = $.data( this, "selectable-item" ), 5067 hit = false, 5068 offset = {}; 5069 5070 //prevent helper from being selected if appendTo: selectable 5071 if ( !selectee || selectee.element === that.element[ 0 ] ) { 5072 return; 5073 } 5074 5075 offset.left = selectee.left + that.elementPos.left; 5076 offset.right = selectee.right + that.elementPos.left; 5077 offset.top = selectee.top + that.elementPos.top; 5078 offset.bottom = selectee.bottom + that.elementPos.top; 5079 5080 if ( options.tolerance === "touch" ) { 5081 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 5082 offset.bottom < y1 ) ); 5083 } else if ( options.tolerance === "fit" ) { 5084 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 5085 offset.bottom < y2 ); 5086 } 5087 5088 if ( hit ) { 5089 5090 // SELECT 5091 if ( selectee.selected ) { 5092 that._removeClass( selectee.$element, "ui-selected" ); 5093 selectee.selected = false; 5094 } 5095 if ( selectee.unselecting ) { 5096 that._removeClass( selectee.$element, "ui-unselecting" ); 5097 selectee.unselecting = false; 5098 } 5099 if ( !selectee.selecting ) { 5100 that._addClass( selectee.$element, "ui-selecting" ); 5101 selectee.selecting = true; 5102 5103 // selectable SELECTING callback 5104 that._trigger( "selecting", event, { 5105 selecting: selectee.element 5106 } ); 5107 } 5108 } else { 5109 5110 // UNSELECT 5111 if ( selectee.selecting ) { 5112 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 5113 that._removeClass( selectee.$element, "ui-selecting" ); 5114 selectee.selecting = false; 5115 that._addClass( selectee.$element, "ui-selected" ); 5116 selectee.selected = true; 5117 } else { 5118 that._removeClass( selectee.$element, "ui-selecting" ); 5119 selectee.selecting = false; 5120 if ( selectee.startselected ) { 5121 that._addClass( selectee.$element, "ui-unselecting" ); 5122 selectee.unselecting = true; 5123 } 5124 5125 // selectable UNSELECTING callback 5126 that._trigger( "unselecting", event, { 5127 unselecting: selectee.element 5128 } ); 5129 } 5130 } 5131 if ( selectee.selected ) { 5132 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 5133 that._removeClass( selectee.$element, "ui-selected" ); 5134 selectee.selected = false; 5135 5136 that._addClass( selectee.$element, "ui-unselecting" ); 5137 selectee.unselecting = true; 5138 5139 // selectable UNSELECTING callback 5140 that._trigger( "unselecting", event, { 5141 unselecting: selectee.element 5142 } ); 5143 } 5144 } 5145 } 5146 } ); 5147 5148 return false; 5149 }, 5150 5151 _mouseStop: function( event ) { 5152 var that = this; 5153 5154 this.dragged = false; 5155 5156 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 5157 var selectee = $.data( this, "selectable-item" ); 5158 that._removeClass( selectee.$element, "ui-unselecting" ); 5159 selectee.unselecting = false; 5160 selectee.startselected = false; 5161 that._trigger( "unselected", event, { 5162 unselected: selectee.element 5163 } ); 5164 } ); 5165 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 5166 var selectee = $.data( this, "selectable-item" ); 5167 that._removeClass( selectee.$element, "ui-selecting" ) 5168 ._addClass( selectee.$element, "ui-selected" ); 5169 selectee.selecting = false; 5170 selectee.selected = true; 5171 selectee.startselected = true; 5172 that._trigger( "selected", event, { 5173 selected: selectee.element 5174 } ); 5175 } ); 5176 this._trigger( "stop", event ); 5177 5178 this.helper.remove(); 5179 5180 return false; 5181 } 5182 5183} ); 5184 5185 5186/*! 5187 * jQuery UI Sortable 1.14.2 5188 * https://jqueryui.com 5189 * 5190 * Copyright OpenJS Foundation and other contributors 5191 * Released under the MIT license. 5192 * https://jquery.org/license 5193 */ 5194 5195//>>label: Sortable 5196//>>group: Interactions 5197//>>description: Enables items in a list to be sorted using the mouse. 5198//>>docs: https://api.jqueryui.com/sortable/ 5199//>>demos: https://jqueryui.com/sortable/ 5200//>>css.structure: ../../themes/base/sortable.css 5201 5202 5203var widgetsSortable =
vendor: 12,373 bytes, lines 5203-5662
5203 $.widget( "ui.sortable", $.ui.mouse, { 5204 version: "1.14.2", 5205 widgetEventPrefix: "sort", 5206 ready: false, 5207 options: { 5208 appendTo: "parent", 5209 axis: false, 5210 connectWith: false, 5211 containment: false, 5212 cursor: "auto", 5213 cursorAt: false, 5214 dropOnEmpty: true, 5215 forcePlaceholderSize: false, 5216 forceHelperSize: false, 5217 grid: false, 5218 handle: false, 5219 helper: "original", 5220 items: "> *", 5221 opacity: false, 5222 placeholder: false, 5223 revert: false, 5224 scroll: true, 5225 scrollSensitivity: 20, 5226 scrollSpeed: 20, 5227 scope: "default", 5228 tolerance: "intersect", 5229 zIndex: 1000, 5230 5231 // Callbacks 5232 activate: null, 5233 beforeStop: null, 5234 change: null, 5235 deactivate: null, 5236 out: null, 5237 over: null, 5238 receive: null, 5239 remove: null, 5240 sort: null, 5241 start: null, 5242 stop: null, 5243 update: null 5244 }, 5245 5246 _isOverAxis: function( x, reference, size ) { 5247 return ( x >= reference ) && ( x < ( reference + size ) ); 5248 }, 5249 5250 _isFloating: function( item ) { 5251 return ( /left|right/ ).test( item.css( "float" ) ) || 5252 ( /inline|table-cell/ ).test( item.css( "display" ) ); 5253 }, 5254 5255 _create: function() { 5256 this.containerCache = {}; 5257 this._addClass( "ui-sortable" ); 5258 5259 //Get the items 5260 this.refresh(); 5261 5262 //Let's determine the parent's offset 5263 this.offset = this.element.offset(); 5264 5265 //Initialize mouse events for interaction 5266 this._mouseInit(); 5267 5268 this._setHandleClassName(); 5269 5270 //We're ready to go 5271 this.ready = true; 5272 5273 }, 5274 5275 _setOption: function( key, value ) { 5276 this._super( key, value ); 5277 5278 if ( key === "handle" ) { 5279 this._setHandleClassName(); 5280 } 5281 }, 5282 5283 _setHandleClassName: function() { 5284 var that = this; 5285 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 5286 $.each( this.items, function() { 5287 that._addClass( 5288 this.instance.options.handle ? 5289 this.item.find( this.instance.options.handle ) : 5290 this.item, 5291 "ui-sortable-handle" 5292 ); 5293 } ); 5294 }, 5295 5296 _destroy: function() { 5297 this._mouseDestroy(); 5298 5299 for ( var i = this.items.length - 1; i >= 0; i-- ) { 5300 this.items[ i ].item.removeData( this.widgetName + "-item" ); 5301 } 5302 5303 return this; 5304 }, 5305 5306 _mouseCapture: function( event, overrideHandle ) { 5307 var currentItem = null, 5308 validHandle = false, 5309 that = this; 5310 5311 if ( this.reverting ) { 5312 return false; 5313 } 5314 5315 if ( this.options.disabled || this.options.type === "static" ) { 5316 return false; 5317 } 5318 5319 //We have to refresh the items data once first 5320 this._refreshItems( event ); 5321 5322 //Find out if the clicked node (or one of its parents) is a actual item in this.items 5323 $( event.target ).parents().each( function() { 5324 if ( $.data( this, that.widgetName + "-item" ) === that ) { 5325 currentItem = $( this ); 5326 return false; 5327 } 5328 } ); 5329 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 5330 currentItem = $( event.target ); 5331 } 5332 5333 if ( !currentItem ) { 5334 return false; 5335 } 5336 if ( this.options.handle && !overrideHandle ) { 5337 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 5338 if ( this === event.target ) { 5339 validHandle = true; 5340 } 5341 } ); 5342 if ( !validHandle ) { 5343 return false; 5344 } 5345 } 5346 5347 this.currentItem = currentItem; 5348 this._removeCurrentsFromItems(); 5349 return true; 5350 5351 }, 5352 5353 _mouseStart: function( event, overrideHandle, noActivation ) { 5354 5355 var i, body, 5356 o = this.options; 5357 5358 this.currentContainer = this; 5359 5360 //We only need to call refreshPositions, because the refreshItems call has been moved to 5361 // mouseCapture 5362 this.refreshPositions(); 5363 5364 //Prepare the dragged items parent 5365 this.appendTo = $( o.appendTo !== "parent" ? 5366 o.appendTo : 5367 this.currentItem.parent() ); 5368 5369 //Create and append the visible helper 5370 this.helper = this._createHelper( event ); 5371 5372 //Cache the helper size 5373 this._cacheHelperProportions(); 5374 5375 /* 5376 * - Position generation - 5377 * This block generates everything position related - it's the core of draggables. 5378 */ 5379 5380 //Cache the margins of the original element 5381 this._cacheMargins(); 5382 5383 //The element's absolute position on the page minus margins 5384 this.offset = this.currentItem.offset(); 5385 this.offset = { 5386 top: this.offset.top - this.margins.top, 5387 left: this.offset.left - this.margins.left 5388 }; 5389 5390 $.extend( this.offset, { 5391 click: { //Where the click happened, relative to the element 5392 left: event.pageX - this.offset.left, 5393 top: event.pageY - this.offset.top 5394 }, 5395 5396 // This is a relative to absolute position minus the actual position calculation - 5397 // only used for relative positioned helper 5398 relative: this._getRelativeOffset() 5399 } ); 5400 5401 // After we get the helper offset, but before we get the parent offset we can 5402 // change the helper's position to absolute 5403 // TODO: Still need to figure out a way to make relative sorting possible 5404 this.helper.css( "position", "absolute" ); 5405 this.cssPosition = this.helper.css( "position" ); 5406 5407 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 5408 if ( o.cursorAt ) { 5409 this._adjustOffsetFromHelper( o.cursorAt ); 5410 } 5411 5412 //Cache the former DOM position 5413 this.domPosition = { 5414 prev: this.currentItem.prev()[ 0 ], 5415 parent: this.currentItem.parent()[ 0 ] 5416 }; 5417 5418 // If the helper is not the original, hide the original so it's not playing any role during 5419 // the drag, won't cause anything bad this way 5420 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 5421 this.currentItem.hide(); 5422 } 5423 5424 //Create the placeholder 5425 this._createPlaceholder(); 5426 5427 //Get the next scrolling parent 5428 this.scrollParent = this.placeholder.scrollParent(); 5429 5430 $.extend( this.offset, { 5431 parent: this._getParentOffset() 5432 } ); 5433 5434 //Set a containment if given in the options 5435 if ( o.containment ) { 5436 this._setContainment(); 5437 } 5438 5439 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 5440 body = this.document.find( "body" ); 5441 5442 this._storedStylesheet = 5443 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 5444 } 5445 5446 // We need to make sure to grab the zIndex before setting the 5447 // opacity, because setting the opacity to anything lower than 1 5448 // causes the zIndex to change from "auto" to 0. 5449 if ( o.zIndex ) { // zIndex option 5450 if ( this.helper.css( "zIndex" ) ) { 5451 this._storedZIndex = this.helper.css( "zIndex" ); 5452 } 5453 this.helper.css( "zIndex", o.zIndex ); 5454 } 5455 5456 if ( o.opacity ) { // opacity option 5457 if ( this.helper.css( "opacity" ) ) { 5458 this._storedOpacity = this.helper.css( "opacity" ); 5459 } 5460 this.helper.css( "opacity", o.opacity ); 5461 } 5462 5463 //Prepare scrolling 5464 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5465 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5466 this.overflowOffset = this.scrollParent.offset(); 5467 } 5468 5469 //Call callbacks 5470 this._trigger( "start", event, this._uiHash() ); 5471 5472 //Recache the helper size 5473 if ( !this._preserveHelperProportions ) { 5474 this._cacheHelperProportions(); 5475 } 5476 5477 //Post "activate" events to possible containers 5478 if ( !noActivation ) { 5479 for ( i = this.containers.length - 1; i >= 0; i-- ) { 5480 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 5481 } 5482 } 5483 5484 //Prepare possible droppables 5485 if ( $.ui.ddmanager ) { 5486 $.ui.ddmanager.current = this; 5487 } 5488 5489 if ( $.ui.ddmanager && !o.dropBehaviour ) { 5490 $.ui.ddmanager.prepareOffsets( this, event ); 5491 } 5492 5493 this.dragging = true; 5494 5495 this._addClass( this.helper, "ui-sortable-helper" ); 5496 5497 //Move the helper, if needed 5498 if ( !this.helper.parent().is( this.appendTo ) ) { 5499 this.helper.detach().appendTo( this.appendTo ); 5500 5501 //Update position 5502 this.offset.parent = this._getParentOffset(); 5503 } 5504 5505 //Generate the original position 5506 this.position = this.originalPosition = this._generatePosition( event ); 5507 this.originalPageX = event.pageX; 5508 this.originalPageY = event.pageY; 5509 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); 5510 5511 this._mouseDrag( event ); 5512 5513 return true; 5514 5515 }, 5516 5517 _scroll: function( event ) { 5518 var o = this.options, 5519 scrolled = false; 5520 5521 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5522 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5523 5524 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 5525 event.pageY < o.scrollSensitivity ) { 5526 this.scrollParent[ 0 ].scrollTop = 5527 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 5528 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 5529 this.scrollParent[ 0 ].scrollTop = 5530 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 5531 } 5532 5533 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 5534 event.pageX < o.scrollSensitivity ) { 5535 this.scrollParent[ 0 ].scrollLeft = scrolled = 5536 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 5537 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 5538 this.scrollParent[ 0 ].scrollLeft = scrolled = 5539 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 5540 } 5541 5542 } else { 5543 5544 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 5545 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 5546 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 5547 o.scrollSensitivity ) { 5548 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 5549 } 5550 5551 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 5552 scrolled = this.document.scrollLeft( 5553 this.document.scrollLeft() - o.scrollSpeed 5554 ); 5555 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 5556 o.scrollSensitivity ) { 5557 scrolled = this.document.scrollLeft( 5558 this.document.scrollLeft() + o.scrollSpeed 5559 ); 5560 } 5561 5562 } 5563 5564 return scrolled; 5565 }, 5566 5567 _mouseDrag: function( event ) { 5568 var i, item, itemElement, intersection, 5569 o = this.options; 5570 5571 //Compute the helpers position 5572 this.position = this._generatePosition( event ); 5573 this.positionAbs = this._convertPositionTo( "absolute" ); 5574 5575 //Set the helper position 5576 if ( !this.options.axis || this.options.axis !== "y" ) { 5577 this.helper[ 0 ].style.left = this.position.left + "px"; 5578 } 5579 if ( !this.options.axis || this.options.axis !== "x" ) { 5580 this.helper[ 0 ].style.top = this.position.top + "px"; 5581 } 5582 5583 //Do scrolling 5584 if ( o.scroll ) { 5585 if ( this._scroll( event ) !== false ) { 5586 5587 //Update item positions used in position checks 5588 this._refreshItemPositions( true ); 5589 5590 if ( $.ui.ddmanager && !o.dropBehaviour ) { 5591 $.ui.ddmanager.prepareOffsets( this, event ); 5592 } 5593 } 5594 } 5595 5596 this.dragDirection = { 5597 vertical: this._getDragVerticalDirection(), 5598 horizontal: this._getDragHorizontalDirection() 5599 }; 5600 5601 //Rearrange 5602 for ( i = this.items.length - 1; i >= 0; i-- ) { 5603 5604 //Cache variables and intersection, continue if no intersection 5605 item = this.items[ i ]; 5606 itemElement = item.item[ 0 ]; 5607 intersection = this._intersectsWithPointer( item ); 5608 if ( !intersection ) { 5609 continue; 5610 } 5611 5612 // Only put the placeholder inside the current Container, skip all 5613 // items from other containers. This works because when moving 5614 // an item from one container to another the 5615 // currentContainer is switched before the placeholder is moved. 5616 // 5617 // Without this, moving items in "sub-sortables" can cause 5618 // the placeholder to jitter between the outer and inner container. 5619 if ( item.instance !== this.currentContainer ) { 5620 continue; 5621 } 5622 5623 // Cannot intersect with itself 5624 // no useless actions that have been done before 5625 // no action if the item moved is the parent of the item checked 5626 if ( itemElement !== this.currentItem[ 0 ] && 5627 this.placeholder[ intersection === 1 ? 5628 "next" : "prev" ]()[ 0 ] !== itemElement && 5629 !$.contains( this.placeholder[ 0 ], itemElement ) && 5630 ( this.options.type === "semi-dynamic" ? 5631 !$.contains( this.element[ 0 ], itemElement ) : 5632 true 5633 ) 5634 ) { 5635 5636 this.direction = intersection === 1 ? "down" : "up"; 5637 5638 if ( this.options.tolerance === "pointer" || 5639 this._intersectsWithSides( item ) ) { 5640 this._rearrange( event, item ); 5641 } else { 5642 break; 5643 } 5644 5645 this._trigger( "change", event, this._uiHash() ); 5646 break; 5647 } 5648 } 5649 5650 //Post events to containers 5651 this._contactContainers( event ); 5652 5653 //Interconnect with droppables 5654 if ( $.ui.ddmanager ) { 5655 $.ui.ddmanager.drag( this, event ); 5656 } 5657 5658 //Call callbacks 5659 this._trigger( "sort", event, this._uiHash() ); 5660 5661 this.lastPositionAbs = this.positionAbs; 5662 return false;
vendor: 5,063 bytes, lines 5663-5852
5663 5664 }, 5665 5666 _mouseStop: function( event, noPropagation ) { 5667 5668 if ( !event ) { 5669 return; 5670 } 5671 5672 //If we are using droppables, inform the manager about the drop 5673 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 5674 $.ui.ddmanager.drop( this, event ); 5675 } 5676 5677 if ( this.options.revert ) { 5678 var that = this, 5679 cur = this.placeholder.offset(), 5680 axis = this.options.axis, 5681 animation = {}; 5682 5683 if ( !axis || axis === "x" ) { 5684 animation.left = cur.left - this.offset.parent.left - this.margins.left + 5685 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5686 0 : 5687 this.offsetParent[ 0 ].scrollLeft 5688 ); 5689 } 5690 if ( !axis || axis === "y" ) { 5691 animation.top = cur.top - this.offset.parent.top - this.margins.top + 5692 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5693 0 : 5694 this.offsetParent[ 0 ].scrollTop 5695 ); 5696 } 5697 this.reverting = true; 5698 $( this.helper ).animate( 5699 animation, 5700 parseInt( this.options.revert, 10 ) || 500, 5701 function() { 5702 that._clear( event ); 5703 } 5704 ); 5705 } else { 5706 this._clear( event, noPropagation ); 5707 } 5708 5709 return false; 5710 5711 }, 5712 5713 cancel: function() { 5714 5715 if ( this.dragging ) { 5716 5717 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 5718 5719 if ( this.options.helper === "original" ) { 5720 this.currentItem.css( this._storedCSS ); 5721 this._removeClass( this.currentItem, "ui-sortable-helper" ); 5722 } else { 5723 this.currentItem.show(); 5724 } 5725 5726 //Post deactivating events to containers 5727 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 5728 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 5729 if ( this.containers[ i ].containerCache.over ) { 5730 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 5731 this.containers[ i ].containerCache.over = 0; 5732 } 5733 } 5734 5735 } 5736 5737 if ( this.placeholder ) { 5738 5739 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 5740 // it unbinds ALL events from the original node! 5741 if ( this.placeholder[ 0 ].parentNode ) { 5742 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 5743 } 5744 if ( this.options.helper !== "original" && this.helper && 5745 this.helper[ 0 ].parentNode ) { 5746 this.helper.remove(); 5747 } 5748 5749 $.extend( this, { 5750 helper: null, 5751 dragging: false, 5752 reverting: false, 5753 _noFinalSort: null 5754 } ); 5755 5756 if ( this.domPosition.prev ) { 5757 $( this.domPosition.prev ).after( this.currentItem ); 5758 } else { 5759 $( this.domPosition.parent ).prepend( this.currentItem ); 5760 } 5761 } 5762 5763 return this; 5764 5765 }, 5766 5767 serialize: function( o ) { 5768 5769 var items = this._getItemsAsjQuery( o && o.connected ), 5770 str = []; 5771 o = o || {}; 5772 5773 $( items ).each( function() { 5774 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 5775 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 5776 if ( res ) { 5777 str.push( 5778 ( o.key || res[ 1 ] + "[]" ) + 5779 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 5780 } 5781 } ); 5782 5783 if ( !str.length && o.key ) { 5784 str.push( o.key + "=" ); 5785 } 5786 5787 return str.join( "&" ); 5788 5789 }, 5790 5791 toArray: function( o ) { 5792 5793 var items = this._getItemsAsjQuery( o && o.connected ), 5794 ret = []; 5795 5796 o = o || {}; 5797 5798 items.each( function() { 5799 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 5800 } ); 5801 return ret; 5802 5803 }, 5804 5805 /* Be careful with the following core functions */ 5806 _intersectsWith: function( item ) { 5807 5808 var x1 = this.positionAbs.left, 5809 x2 = x1 + this.helperProportions.width, 5810 y1 = this.positionAbs.top, 5811 y2 = y1 + this.helperProportions.height, 5812 l = item.left, 5813 r = l + item.width, 5814 t = item.top, 5815 b = t + item.height, 5816 dyClick = this.offset.click.top, 5817 dxClick = this.offset.click.left, 5818 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 5819 ( y1 + dyClick ) < b ), 5820 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 5821 ( x1 + dxClick ) < r ), 5822 isOverElement = isOverElementHeight && isOverElementWidth; 5823 5824 if ( this.options.tolerance === "pointer" || 5825 this.options.forcePointerForContainers || 5826 ( this.options.tolerance !== "pointer" && 5827 this.helperProportions[ this.floating ? "width" : "height" ] > 5828 item[ this.floating ? "width" : "height" ] ) 5829 ) { 5830 return isOverElement; 5831 } else { 5832 5833 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 5834 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 5835 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 5836 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 5837 5838 } 5839 }, 5840 5841 _intersectsWithPointer: function( item ) { 5842 var verticalDirection, horizontalDirection, 5843 isOverElementHeight = ( this.options.axis === "x" ) || 5844 this._isOverAxis( 5845 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 5846 isOverElementWidth = ( this.options.axis === "y" ) || 5847 this._isOverAxis( 5848 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 5849 isOverElement = isOverElementHeight && isOverElementWidth; 5850 5851 if ( !isOverElement ) { 5852 return false;
vendor: 18,528 bytes, lines 5853-6433
5853 } 5854 5855 verticalDirection = this.dragDirection.vertical; 5856 horizontalDirection = this.dragDirection.horizontal; 5857 5858 return this.floating ? 5859 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : 5860 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 5861 5862 }, 5863 5864 _intersectsWithSides: function( item ) { 5865 5866 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 5867 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 5868 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 5869 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 5870 verticalDirection = this.dragDirection.vertical, 5871 horizontalDirection = this.dragDirection.horizontal; 5872 5873 if ( this.floating && horizontalDirection ) { 5874 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 5875 ( horizontalDirection === "left" && !isOverRightHalf ) ); 5876 } else { 5877 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 5878 ( verticalDirection === "up" && !isOverBottomHalf ) ); 5879 } 5880 5881 }, 5882 5883 _getDragVerticalDirection: function() { 5884 var delta = this.positionAbs.top - this.lastPositionAbs.top; 5885 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 5886 }, 5887 5888 _getDragHorizontalDirection: function() { 5889 var delta = this.positionAbs.left - this.lastPositionAbs.left; 5890 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 5891 }, 5892 5893 refresh: function( event ) { 5894 this._refreshItems( event ); 5895 this._setHandleClassName(); 5896 this.refreshPositions(); 5897 return this; 5898 }, 5899 5900 _connectWith: function() { 5901 var options = this.options; 5902 return options.connectWith.constructor === String ? 5903 [ options.connectWith ] : 5904 options.connectWith; 5905 }, 5906 5907 _getItemsAsjQuery: function( connected ) { 5908 5909 var i, j, cur, inst, 5910 items = [], 5911 queries = [], 5912 connectWith = this._connectWith(); 5913 5914 if ( connectWith && connected ) { 5915 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5916 cur = $( connectWith[ i ], this.document[ 0 ] ); 5917 for ( j = cur.length - 1; j >= 0; j-- ) { 5918 inst = $.data( cur[ j ], this.widgetFullName ); 5919 if ( inst && inst !== this && !inst.options.disabled ) { 5920 queries.push( [ typeof inst.options.items === "function" ? 5921 inst.options.items.call( inst.element ) : 5922 $( inst.options.items, inst.element ) 5923 .not( ".ui-sortable-helper" ) 5924 .not( ".ui-sortable-placeholder" ), inst ] ); 5925 } 5926 } 5927 } 5928 } 5929 5930 queries.push( [ typeof this.options.items === "function" ? 5931 this.options.items 5932 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 5933 $( this.options.items, this.element ) 5934 .not( ".ui-sortable-helper" ) 5935 .not( ".ui-sortable-placeholder" ), this ] ); 5936 5937 function addItems() { 5938 items.push( this ); 5939 } 5940 for ( i = queries.length - 1; i >= 0; i-- ) { 5941 queries[ i ][ 0 ].each( addItems ); 5942 } 5943 5944 return $( items ); 5945 5946 }, 5947 5948 _removeCurrentsFromItems: function() { 5949 5950 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 5951 5952 this.items = $.grep( this.items, function( item ) { 5953 for ( var j = 0; j < list.length; j++ ) { 5954 if ( list[ j ] === item.item[ 0 ] ) { 5955 return false; 5956 } 5957 } 5958 return true; 5959 } ); 5960 5961 }, 5962 5963 _refreshItems: function( event ) { 5964 5965 this.items = []; 5966 this.containers = [ this ]; 5967 5968 var i, j, cur, inst, targetData, _queries, item, queriesLength, 5969 items = this.items, 5970 queries = [ [ typeof this.options.items === "function" ? 5971 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 5972 $( this.options.items, this.element ), this ] ], 5973 connectWith = this._connectWith(); 5974 5975 //Shouldn't be run the first time through due to massive slow-down 5976 if ( connectWith && this.ready ) { 5977 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5978 cur = $( connectWith[ i ], this.document[ 0 ] ); 5979 for ( j = cur.length - 1; j >= 0; j-- ) { 5980 inst = $.data( cur[ j ], this.widgetFullName ); 5981 if ( inst && inst !== this && !inst.options.disabled ) { 5982 queries.push( [ typeof inst.options.items === "function" ? 5983 inst.options.items 5984 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 5985 $( inst.options.items, inst.element ), inst ] ); 5986 this.containers.push( inst ); 5987 } 5988 } 5989 } 5990 } 5991 5992 for ( i = queries.length - 1; i >= 0; i-- ) { 5993 targetData = queries[ i ][ 1 ]; 5994 _queries = queries[ i ][ 0 ]; 5995 5996 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 5997 item = $( _queries[ j ] ); 5998 5999 // Data for target checking (mouse manager) 6000 item.data( this.widgetName + "-item", targetData ); 6001 6002 items.push( { 6003 item: item, 6004 instance: targetData, 6005 width: 0, height: 0, 6006 left: 0, top: 0 6007 } ); 6008 } 6009 } 6010 6011 }, 6012 6013 _refreshItemPositions: function( fast ) { 6014 var i, item, t, p; 6015 6016 for ( i = this.items.length - 1; i >= 0; i-- ) { 6017 item = this.items[ i ]; 6018 6019 //We ignore calculating positions of all connected containers when we're not over them 6020 if ( this.currentContainer && item.instance !== this.currentContainer && 6021 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 6022 continue; 6023 } 6024 6025 t = this.options.toleranceElement ? 6026 $( this.options.toleranceElement, item.item ) : 6027 item.item; 6028 6029 if ( !fast ) { 6030 item.width = t.outerWidth(); 6031 item.height = t.outerHeight(); 6032 } 6033 6034 p = t.offset(); 6035 item.left = p.left; 6036 item.top = p.top; 6037 } 6038 }, 6039 6040 refreshPositions: function( fast ) { 6041 6042 // Determine whether items are being displayed horizontally 6043 this.floating = this.items.length ? 6044 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 6045 false; 6046 6047 // This has to be redone because due to the item being moved out/into the offsetParent, 6048 // the offsetParent's position will change 6049 if ( this.offsetParent && this.helper ) { 6050 this.offset.parent = this._getParentOffset(); 6051 } 6052 6053 this._refreshItemPositions( fast ); 6054 6055 var i, p; 6056 6057 if ( this.options.custom && this.options.custom.refreshContainers ) { 6058 this.options.custom.refreshContainers.call( this ); 6059 } else { 6060 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6061 p = this.containers[ i ].element.offset(); 6062 this.containers[ i ].containerCache.left = p.left; 6063 this.containers[ i ].containerCache.top = p.top; 6064 this.containers[ i ].containerCache.width = 6065 this.containers[ i ].element.outerWidth(); 6066 this.containers[ i ].containerCache.height = 6067 this.containers[ i ].element.outerHeight(); 6068 } 6069 } 6070 6071 return this; 6072 }, 6073 6074 _createPlaceholder: function( that ) { 6075 that = that || this; 6076 var className, nodeName, 6077 o = that.options; 6078 6079 if ( !o.placeholder || o.placeholder.constructor === String ) { 6080 className = o.placeholder; 6081 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); 6082 o.placeholder = { 6083 element: function() { 6084 6085 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); 6086 6087 that._addClass( element, "ui-sortable-placeholder", 6088 className || that.currentItem[ 0 ].className ) 6089 ._removeClass( element, "ui-sortable-helper" ); 6090 6091 if ( nodeName === "tbody" ) { 6092 that._createTrPlaceholder( 6093 that.currentItem.find( "tr" ).eq( 0 ), 6094 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 6095 ); 6096 } else if ( nodeName === "tr" ) { 6097 that._createTrPlaceholder( that.currentItem, element ); 6098 } else if ( nodeName === "img" ) { 6099 element.attr( "src", that.currentItem.attr( "src" ) ); 6100 } 6101 6102 if ( !className ) { 6103 element.css( "visibility", "hidden" ); 6104 } 6105 6106 return element; 6107 }, 6108 update: function( container, p ) { 6109 6110 // 1. If a className is set as 'placeholder option, we don't force sizes - 6111 // the class is responsible for that 6112 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 6113 // class name is specified 6114 if ( className && !o.forcePlaceholderSize ) { 6115 return; 6116 } 6117 6118 // If the element doesn't have a actual height or width by itself (without 6119 // styles coming from a stylesheet), it receives the inline height and width 6120 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height 6121 // anyway since we're populating them with <td>s above, but they're unlikely to 6122 // be the correct height on their own if the row heights are dynamic, so we'll 6123 // always assign the height of the dragged item given forcePlaceholderSize 6124 // is true. 6125 if ( !p.height() || ( o.forcePlaceholderSize && 6126 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { 6127 p.height( 6128 that.currentItem.innerHeight() - 6129 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 6130 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 6131 } 6132 if ( !p.width() ) { 6133 p.width( 6134 that.currentItem.innerWidth() - 6135 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 6136 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 6137 } 6138 } 6139 }; 6140 } 6141 6142 //Create the placeholder 6143 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 6144 6145 //Append it after the actual current item 6146 that.currentItem.after( that.placeholder ); 6147 6148 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 6149 o.placeholder.update( that, that.placeholder ); 6150 6151 }, 6152 6153 _createTrPlaceholder: function( sourceTr, targetTr ) { 6154 var that = this; 6155 6156 sourceTr.children().each( function() { 6157 $( "<td> </td>", that.document[ 0 ] ) 6158 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 6159 .appendTo( targetTr ); 6160 } ); 6161 }, 6162 6163 _contactContainers: function( event ) { 6164 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 6165 floating, axis, 6166 innermostContainer = null, 6167 innermostIndex = null; 6168 6169 // Get innermost container that intersects with item 6170 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6171 6172 // Never consider a container that's located within the item itself 6173 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 6174 continue; 6175 } 6176 6177 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 6178 6179 // If we've already found a container and it's more "inner" than this, then continue 6180 if ( innermostContainer && 6181 $.contains( 6182 this.containers[ i ].element[ 0 ], 6183 innermostContainer.element[ 0 ] ) ) { 6184 continue; 6185 } 6186 6187 innermostContainer = this.containers[ i ]; 6188 innermostIndex = i; 6189 6190 } else { 6191 6192 // container doesn't intersect. trigger "out" event if necessary 6193 if ( this.containers[ i ].containerCache.over ) { 6194 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 6195 this.containers[ i ].containerCache.over = 0; 6196 } 6197 } 6198 6199 } 6200 6201 // If no intersecting containers found, return 6202 if ( !innermostContainer ) { 6203 return; 6204 } 6205 6206 // Move the item into the container if it's not there already 6207 if ( this.containers.length === 1 ) { 6208 if ( !this.containers[ innermostIndex ].containerCache.over ) { 6209 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6210 this.containers[ innermostIndex ].containerCache.over = 1; 6211 } 6212 } else { 6213 6214 // When entering a new container, we will find the item with the least distance and 6215 // append our item near it 6216 dist = 10000; 6217 itemWithLeastDistance = null; 6218 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 6219 posProperty = floating ? "left" : "top"; 6220 sizeProperty = floating ? "width" : "height"; 6221 axis = floating ? "pageX" : "pageY"; 6222 6223 for ( j = this.items.length - 1; j >= 0; j-- ) { 6224 if ( !$.contains( 6225 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 6226 ) { 6227 continue; 6228 } 6229 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 6230 continue; 6231 } 6232 6233 cur = this.items[ j ].item.offset()[ posProperty ]; 6234 nearBottom = false; 6235 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 6236 nearBottom = true; 6237 } 6238 6239 if ( Math.abs( event[ axis ] - cur ) < dist ) { 6240 dist = Math.abs( event[ axis ] - cur ); 6241 itemWithLeastDistance = this.items[ j ]; 6242 this.direction = nearBottom ? "up" : "down"; 6243 } 6244 } 6245 6246 //Check if dropOnEmpty is enabled 6247 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 6248 return; 6249 } 6250 6251 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 6252 if ( !this.currentContainer.containerCache.over ) { 6253 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 6254 this.currentContainer.containerCache.over = 1; 6255 } 6256 return; 6257 } 6258 6259 if ( itemWithLeastDistance ) { 6260 this._rearrange( event, itemWithLeastDistance, null, true ); 6261 } else { 6262 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 6263 } 6264 this._trigger( "change", event, this._uiHash() ); 6265 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 6266 this.currentContainer = this.containers[ innermostIndex ]; 6267 6268 //Update the placeholder 6269 this.options.placeholder.update( this.currentContainer, this.placeholder ); 6270 6271 //Update scrollParent 6272 this.scrollParent = this.placeholder.scrollParent(); 6273 6274 //Update overflowOffset 6275 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6276 this.scrollParent[ 0 ].tagName !== "HTML" ) { 6277 this.overflowOffset = this.scrollParent.offset(); 6278 } 6279 6280 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6281 this.containers[ innermostIndex ].containerCache.over = 1; 6282 } 6283 6284 }, 6285 6286 _createHelper: function( event ) { 6287 6288 var o = this.options, 6289 helper = typeof o.helper === "function" ? 6290 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 6291 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 6292 6293 //Add the helper to the DOM if that didn't happen already 6294 if ( !helper.parents( "body" ).length ) { 6295 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); 6296 } 6297 6298 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 6299 this._storedCSS = { 6300 width: this.currentItem[ 0 ].style.width, 6301 height: this.currentItem[ 0 ].style.height, 6302 position: this.currentItem.css( "position" ), 6303 top: this.currentItem.css( "top" ), 6304 left: this.currentItem.css( "left" ) 6305 }; 6306 } 6307 6308 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 6309 helper.width( this.currentItem.width() ); 6310 } 6311 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 6312 helper.height( this.currentItem.height() ); 6313 } 6314 6315 return helper; 6316 6317 }, 6318 6319 _adjustOffsetFromHelper: function( obj ) { 6320 if ( typeof obj === "string" ) { 6321 obj = obj.split( " " ); 6322 } 6323 if ( Array.isArray( obj ) ) { 6324 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 6325 } 6326 if ( "left" in obj ) { 6327 this.offset.click.left = obj.left + this.margins.left; 6328 } 6329 if ( "right" in obj ) { 6330 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6331 } 6332 if ( "top" in obj ) { 6333 this.offset.click.top = obj.top + this.margins.top; 6334 } 6335 if ( "bottom" in obj ) { 6336 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6337 } 6338 }, 6339 6340 _getParentOffset: function() { 6341 6342 //Get the offsetParent and cache its position 6343 this.offsetParent = this.helper.offsetParent(); 6344 var po = this.offsetParent.offset(); 6345 6346 // This is a special case where we need to modify a offset calculated on start, since the 6347 // following happened: 6348 // 1. The position of the helper is absolute, so it's position is calculated based on the 6349 // next positioned parent 6350 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 6351 // the document, which means that the scroll is included in the initial calculation of the 6352 // offset of the parent, and never recalculated upon drag 6353 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 6354 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 6355 po.left += this.scrollParent.scrollLeft(); 6356 po.top += this.scrollParent.scrollTop(); 6357 } 6358 6359 // This needs to be actually done for all browsers, since pageX/pageY includes 6360 // this information. 6361 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) { 6362 po = { top: 0, left: 0 }; 6363 } 6364 6365 return { 6366 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 6367 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 6368 }; 6369 6370 }, 6371 6372 _getRelativeOffset: function() { 6373 6374 if ( this.cssPosition === "relative" ) { 6375 var p = this.currentItem.position(); 6376 return { 6377 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 6378 this.scrollParent.scrollTop(), 6379 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 6380 this.scrollParent.scrollLeft() 6381 }; 6382 } else { 6383 return { top: 0, left: 0 }; 6384 } 6385 6386 }, 6387 6388 _cacheMargins: function() { 6389 this.margins = { 6390 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 6391 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 6392 }; 6393 }, 6394 6395 _cacheHelperProportions: function() { 6396 this.helperProportions = { 6397 width: this.helper.outerWidth(), 6398 height: this.helper.outerHeight() 6399 }; 6400 }, 6401 6402 _setContainment: function() { 6403 6404 var ce, co, over, 6405 o = this.options; 6406 if ( o.containment === "parent" ) { 6407 o.containment = this.helper[ 0 ].parentNode; 6408 } 6409 if ( o.containment === "document" || o.containment === "window" ) { 6410 this.containment = [ 6411 0 - this.offset.relative.left - this.offset.parent.left, 6412 0 - this.offset.relative.top - this.offset.parent.top, 6413 o.containment === "document" ? 6414 this.document.width() : 6415 this.window.width() - this.helperProportions.width - this.margins.left, 6416 ( o.containment === "document" ? 6417 ( this.document.height() || document.body.parentNode.scrollHeight ) : 6418 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 6419 ) - this.helperProportions.height - this.margins.top 6420 ]; 6421 } 6422 6423 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 6424 ce = $( o.containment )[ 0 ]; 6425 co = $( o.containment ).offset(); 6426 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 6427 6428 this.containment = [ 6429 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 6430 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 6431 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 6432 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 6433 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth )
vendor: 1,747 bytes, lines 6433-6485
6433: ce.offsetWidth ) - 6434 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 6435 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 6436 this.helperProportions.width - this.margins.left, 6437 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 6438 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 6439 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 6440 this.helperProportions.height - this.margins.top 6441 ]; 6442 } 6443 6444 }, 6445 6446 _convertPositionTo: function( d, pos ) { 6447 6448 if ( !pos ) { 6449 pos = this.position; 6450 } 6451 var mod = d === "absolute" ? 1 : -1, 6452 scroll = this.cssPosition === "absolute" && 6453 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6454 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6455 this.offsetParent : 6456 this.scrollParent, 6457 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6458 6459 return { 6460 top: ( 6461 6462 // The absolute mouse position 6463 pos.top + 6464 6465 // Only for relative positioned nodes: Relative offset from element to offset parent 6466 this.offset.relative.top * mod + 6467 6468 // The offsetParent's offset without borders (offset + border) 6469 this.offset.parent.top * mod - 6470 ( ( this.cssPosition === "fixed" ? 6471 -this.scrollParent.scrollTop() : 6472 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 6473 ), 6474 left: ( 6475 6476 // The absolute mouse position 6477 pos.left + 6478 6479 // Only for relative positioned nodes: Relative offset from element to offset parent 6480 this.offset.relative.left * mod + 6481 6482 // The offsetParent's offset without borders (offset + border) 6483 this.offset.parent.left * mod - 6484 ( ( this.cssPosition === "fixed" ? 6485 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 8,856 bytes, lines 6486-6771
6486 scroll.scrollLeft() ) * mod ) 6487 ) 6488 }; 6489 6490 }, 6491 6492 _generatePosition: function( event ) { 6493 6494 var top, left, 6495 o = this.options, 6496 pageX = event.pageX, 6497 pageY = event.pageY, 6498 scroll = this.cssPosition === "absolute" && 6499 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6500 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6501 this.offsetParent : 6502 this.scrollParent, 6503 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6504 6505 // This is another very weird special case that only happens for relative elements: 6506 // 1. If the css position is relative 6507 // 2. and the scroll parent is the document or similar to the offset parent 6508 // we have to refresh the relative offset during the scroll so there are no jumps 6509 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6510 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 6511 this.offset.relative = this._getRelativeOffset(); 6512 } 6513 6514 /* 6515 * - Position constraining - 6516 * Constrain the position to a mix of grid, containment. 6517 */ 6518 6519 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 6520 6521 if ( this.containment ) { 6522 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 6523 pageX = this.containment[ 0 ] + this.offset.click.left; 6524 } 6525 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 6526 pageY = this.containment[ 1 ] + this.offset.click.top; 6527 } 6528 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 6529 pageX = this.containment[ 2 ] + this.offset.click.left; 6530 } 6531 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 6532 pageY = this.containment[ 3 ] + this.offset.click.top; 6533 } 6534 } 6535 6536 if ( o.grid ) { 6537 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 6538 o.grid[ 1 ] ) * o.grid[ 1 ]; 6539 pageY = this.containment ? 6540 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 6541 top - this.offset.click.top <= this.containment[ 3 ] ) ? 6542 top : 6543 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 6544 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 6545 top; 6546 6547 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 6548 o.grid[ 0 ] ) * o.grid[ 0 ]; 6549 pageX = this.containment ? 6550 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 6551 left - this.offset.click.left <= this.containment[ 2 ] ) ? 6552 left : 6553 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 6554 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 6555 left; 6556 } 6557 6558 } 6559 6560 return { 6561 top: ( 6562 6563 // The absolute mouse position 6564 pageY - 6565 6566 // Click offset (relative to the element) 6567 this.offset.click.top - 6568 6569 // Only for relative positioned nodes: Relative offset from element to offset parent 6570 this.offset.relative.top - 6571 6572 // The offsetParent's offset without borders (offset + border) 6573 this.offset.parent.top + 6574 ( ( this.cssPosition === "fixed" ? 6575 -this.scrollParent.scrollTop() : 6576 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 6577 ), 6578 left: ( 6579 6580 // The absolute mouse position 6581 pageX - 6582 6583 // Click offset (relative to the element) 6584 this.offset.click.left - 6585 6586 // Only for relative positioned nodes: Relative offset from element to offset parent 6587 this.offset.relative.left - 6588 6589 // The offsetParent's offset without borders (offset + border) 6590 this.offset.parent.left + 6591 ( ( this.cssPosition === "fixed" ? 6592 -this.scrollParent.scrollLeft() : 6593 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 6594 ) 6595 }; 6596 6597 }, 6598 6599 _rearrange: function( event, i, a, hardRefresh ) { 6600 6601 if ( a ) { 6602 a[ 0 ].appendChild( this.placeholder[ 0 ] ); 6603 } else { 6604 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 6605 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 6606 } 6607 6608 //Various things done here to improve the performance: 6609 // 1. we create a setTimeout, that calls refreshPositions 6610 // 2. on the instance, we have a counter variable, that get's higher after every append 6611 // 3. on the local scope, we copy the counter variable, and check in the timeout, 6612 // if it's still the same 6613 // 4. this lets only the last addition to the timeout stack through 6614 this.counter = this.counter ? ++this.counter : 1; 6615 var counter = this.counter; 6616 6617 this._delay( function() { 6618 if ( counter === this.counter ) { 6619 6620 //Precompute after each DOM insertion, NOT on mousemove 6621 this.refreshPositions( !hardRefresh ); 6622 } 6623 } ); 6624 6625 }, 6626 6627 _clear: function( event, noPropagation ) { 6628 6629 this.reverting = false; 6630 6631 // We delay all events that have to be triggered to after the point where the placeholder 6632 // has been removed and everything else normalized again 6633 var i, 6634 delayedTriggers = []; 6635 6636 // We first have to update the dom position of the actual currentItem 6637 // Note: don't do it if the current item is already removed (by a user), or it gets 6638 // reappended (see #4088) 6639 if ( !this._noFinalSort && this.currentItem.parent().length ) { 6640 this.placeholder.before( this.currentItem ); 6641 } 6642 this._noFinalSort = null; 6643 6644 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 6645 for ( i in this._storedCSS ) { 6646 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 6647 this._storedCSS[ i ] = ""; 6648 } 6649 } 6650 this.currentItem.css( this._storedCSS ); 6651 this._removeClass( this.currentItem, "ui-sortable-helper" ); 6652 } else { 6653 this.currentItem.show(); 6654 } 6655 6656 if ( this.fromOutside && !noPropagation ) { 6657 delayedTriggers.push( function( event ) { 6658 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 6659 } ); 6660 } 6661 if ( ( this.fromOutside || 6662 this.domPosition.prev !== 6663 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 6664 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 6665 6666 // Trigger update callback if the DOM position has changed 6667 delayedTriggers.push( function( event ) { 6668 this._trigger( "update", event, this._uiHash() ); 6669 } ); 6670 } 6671 6672 // Check if the items Container has Changed and trigger appropriate 6673 // events. 6674 if ( this !== this.currentContainer ) { 6675 if ( !noPropagation ) { 6676 delayedTriggers.push( function( event ) { 6677 this._trigger( "remove", event, this._uiHash() ); 6678 } ); 6679 delayedTriggers.push( ( function( c ) { 6680 return function( event ) { 6681 c._trigger( "receive", event, this._uiHash( this ) ); 6682 }; 6683 } ).call( this, this.currentContainer ) ); 6684 delayedTriggers.push( ( function( c ) { 6685 return function( event ) { 6686 c._trigger( "update", event, this._uiHash( this ) ); 6687 }; 6688 } ).call( this, this.currentContainer ) ); 6689 } 6690 } 6691 6692 //Post events to containers 6693 function delayEvent( type, instance, container ) { 6694 return function( event ) { 6695 container._trigger( type, event, instance._uiHash( instance ) ); 6696 }; 6697 } 6698 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6699 if ( !noPropagation ) { 6700 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 6701 } 6702 if ( this.containers[ i ].containerCache.over ) { 6703 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 6704 this.containers[ i ].containerCache.over = 0; 6705 } 6706 } 6707 6708 //Do what was originally in plugins 6709 if ( this._storedStylesheet ) { 6710 this._storedStylesheet.remove(); 6711 this._storedStylesheet = null; 6712 } 6713 if ( this._storedOpacity ) { 6714 this.helper.css( "opacity", this._storedOpacity ); 6715 } 6716 if ( this._storedZIndex ) { 6717 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 6718 } 6719 6720 this.dragging = false; 6721 6722 if ( !noPropagation ) { 6723 this._trigger( "beforeStop", event, this._uiHash() ); 6724 } 6725 6726 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 6727 // it unbinds ALL events from the original node! 6728 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 6729 6730 if ( !this.cancelHelperRemoval ) { 6731 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 6732 this.helper.remove(); 6733 } 6734 this.helper = null; 6735 } 6736 6737 if ( !noPropagation ) { 6738 for ( i = 0; i < delayedTriggers.length; i++ ) { 6739 6740 // Trigger all delayed events 6741 delayedTriggers[ i ].call( this, event ); 6742 } 6743 this._trigger( "stop", event, this._uiHash() ); 6744 } 6745 6746 this.fromOutside = false; 6747 return !this.cancelHelperRemoval; 6748 6749 }, 6750 6751 _trigger: function() { 6752 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 6753 this.cancel(); 6754 } 6755 }, 6756 6757 _uiHash: function( _inst ) { 6758 var inst = _inst || this; 6759 return { 6760 helper: inst.helper, 6761 placeholder: inst.placeholder || $( [] ), 6762 position: inst.position, 6763 originalPosition: inst.originalPosition, 6764 offset: inst.positionAbs, 6765 item: inst.currentItem, 6766 sender: _inst ? _inst.element : null 6767 }; 6768 } 6769 6770} ); 6771
vendor: 21,760 bytes, lines 6772-7612
6772 6773/*! 6774 * jQuery UI Accordion 1.14.2 6775 * https://jqueryui.com 6776 * 6777 * Copyright OpenJS Foundation and other contributors 6778 * Released under the MIT license. 6779 * https://jquery.org/license 6780 */ 6781 6782//>>label: Accordion 6783//>>group: Widgets 6784//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 6785//>>docs: https://api.jqueryui.com/accordion/ 6786//>>demos: https://jqueryui.com/accordion/ 6787//>>css.structure: ../../themes/base/core.css 6788//>>css.structure: ../../themes/base/accordion.css 6789//>>css.theme: ../../themes/base/theme.css 6790 6791 6792var widgetsAccordion = $.widget( "ui.accordion", { 6793 version: "1.14.2", 6794 options: { 6795 active: 0, 6796 animate: {}, 6797 classes: { 6798 "ui-accordion-header": "ui-corner-top", 6799 "ui-accordion-header-collapsed": "ui-corner-all", 6800 "ui-accordion-content": "ui-corner-bottom" 6801 }, 6802 collapsible: false, 6803 event: "click", 6804 header: function( elem ) { 6805 return elem 6806 .find( "> li > :first-child" ) 6807 .add( 6808 elem.find( "> :not(li)" ) 6809 6810 // Support: jQuery <3.5 only 6811 // We could use `.even()` but that's unavailable in older jQuery. 6812 .filter( function( i ) { 6813 return i % 2 === 0; 6814 } ) 6815 ); 6816 }, 6817 heightStyle: "auto", 6818 icons: { 6819 activeHeader: "ui-icon-triangle-1-s", 6820 header: "ui-icon-triangle-1-e" 6821 }, 6822 6823 // Callbacks 6824 activate: null, 6825 beforeActivate: null 6826 }, 6827 6828 hideProps: { 6829 borderTopWidth: "hide", 6830 borderBottomWidth: "hide", 6831 paddingTop: "hide", 6832 paddingBottom: "hide", 6833 height: "hide" 6834 }, 6835 6836 showProps: { 6837 borderTopWidth: "show", 6838 borderBottomWidth: "show", 6839 paddingTop: "show", 6840 paddingBottom: "show", 6841 height: "show" 6842 }, 6843 6844 _create: function() { 6845 var options = this.options; 6846 6847 this.prevShow = this.prevHide = $(); 6848 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 6849 this.element.attr( "role", "tablist" ); 6850 6851 // Don't allow collapsible: false and active: false / null 6852 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 6853 options.active = 0; 6854 } 6855 6856 this._processPanels(); 6857 6858 // handle negative values 6859 if ( options.active < 0 ) { 6860 options.active += this.headers.length; 6861 } 6862 this._refresh(); 6863 }, 6864 6865 _getCreateEventData: function() { 6866 return { 6867 header: this.active, 6868 panel: !this.active.length ? $() : this.active.next() 6869 }; 6870 }, 6871 6872 _createIcons: function() { 6873 var icon, children, 6874 icons = this.options.icons; 6875 6876 if ( icons ) { 6877 icon = $( "<span>" ); 6878 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 6879 icon.prependTo( this.headers ); 6880 children = this.active.children( ".ui-accordion-header-icon" ); 6881 this._removeClass( children, icons.header ) 6882 ._addClass( children, null, icons.activeHeader ) 6883 ._addClass( this.headers, "ui-accordion-icons" ); 6884 } 6885 }, 6886 6887 _destroyIcons: function() { 6888 this._removeClass( this.headers, "ui-accordion-icons" ); 6889 this.headers.children( ".ui-accordion-header-icon" ).remove(); 6890 }, 6891 6892 _destroy: function() { 6893 var contents; 6894 6895 // Clean up main element 6896 this.element.removeAttr( "role" ); 6897 6898 // Clean up headers 6899 this.headers 6900 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 6901 .removeUniqueId(); 6902 6903 this._destroyIcons(); 6904 6905 // Clean up content panels 6906 contents = this.headers.next() 6907 .css( "display", "" ) 6908 .removeAttr( "role aria-hidden aria-labelledby" ) 6909 .removeUniqueId(); 6910 6911 if ( this.options.heightStyle !== "content" ) { 6912 contents.css( "height", "" ); 6913 } 6914 }, 6915 6916 _setOption: function( key, value ) { 6917 if ( key === "active" ) { 6918 6919 // _activate() will handle invalid values and update this.options 6920 this._activate( value ); 6921 return; 6922 } 6923 6924 if ( key === "event" ) { 6925 if ( this.options.event ) { 6926 this._off( this.headers, this.options.event ); 6927 } 6928 this._setupEvents( value ); 6929 } 6930 6931 this._super( key, value ); 6932 6933 // Setting collapsible: false while collapsed; open first panel 6934 if ( key === "collapsible" && !value && this.options.active === false ) { 6935 this._activate( 0 ); 6936 } 6937 6938 if ( key === "icons" ) { 6939 this._destroyIcons(); 6940 if ( value ) { 6941 this._createIcons(); 6942 } 6943 } 6944 }, 6945 6946 _setOptionDisabled: function( value ) { 6947 this._super( value ); 6948 6949 this.element.attr( "aria-disabled", value ); 6950 this._toggleClass( null, "ui-state-disabled", !!value ); 6951 }, 6952 6953 _keydown: function( event ) { 6954 if ( event.altKey || event.ctrlKey ) { 6955 return; 6956 } 6957 6958 var keyCode = $.ui.keyCode, 6959 length = this.headers.length, 6960 currentIndex = this.headers.index( event.target ), 6961 toFocus = false; 6962 6963 switch ( event.keyCode ) { 6964 case keyCode.RIGHT: 6965 case keyCode.DOWN: 6966 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6967 break; 6968 case keyCode.LEFT: 6969 case keyCode.UP: 6970 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6971 break; 6972 case keyCode.SPACE: 6973 case keyCode.ENTER: 6974 this._eventHandler( event ); 6975 break; 6976 case keyCode.HOME: 6977 toFocus = this.headers[ 0 ]; 6978 break; 6979 case keyCode.END: 6980 toFocus = this.headers[ length - 1 ]; 6981 break; 6982 } 6983 6984 if ( toFocus ) { 6985 $( event.target ).attr( "tabIndex", -1 ); 6986 $( toFocus ).attr( "tabIndex", 0 ); 6987 $( toFocus ).trigger( "focus" ); 6988 event.preventDefault(); 6989 } 6990 }, 6991 6992 _panelKeyDown: function( event ) { 6993 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6994 $( event.currentTarget ).prev().trigger( "focus" ); 6995 } 6996 }, 6997 6998 refresh: function() { 6999 var options = this.options; 7000 this._processPanels(); 7001 7002 // Was collapsed or no panel 7003 if ( ( options.active === false && options.collapsible === true ) || 7004 !this.headers.length ) { 7005 options.active = false; 7006 this.active = $(); 7007 7008 // active false only when collapsible is true 7009 } else if ( options.active === false ) { 7010 this._activate( 0 ); 7011 7012 // was active, but active panel is gone 7013 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 7014 7015 // all remaining panel are disabled 7016 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 7017 options.active = false; 7018 this.active = $(); 7019 7020 // activate previous panel 7021 } else { 7022 this._activate( Math.max( 0, options.active - 1 ) ); 7023 } 7024 7025 // was active, active panel still exists 7026 } else { 7027 7028 // make sure active index is correct 7029 options.active = this.headers.index( this.active ); 7030 } 7031 7032 this._destroyIcons(); 7033 7034 this._refresh(); 7035 }, 7036 7037 _processPanels: function() { 7038 var prevHeaders = this.headers, 7039 prevPanels = this.panels; 7040 7041 if ( typeof this.options.header === "function" ) { 7042 this.headers = this.options.header( this.element ); 7043 } else { 7044 this.headers = this.element.find( this.options.header ); 7045 } 7046 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 7047 "ui-state-default" ); 7048 7049 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 7050 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 7051 7052 // Avoid memory leaks (#10056) 7053 if ( prevPanels ) { 7054 this._off( prevHeaders.not( this.headers ) ); 7055 this._off( prevPanels.not( this.panels ) ); 7056 } 7057 }, 7058 7059 _refresh: function() { 7060 var maxHeight, 7061 options = this.options, 7062 heightStyle = options.heightStyle, 7063 parent = this.element.parent(); 7064 7065 this.active = this._findActive( options.active ); 7066 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 7067 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 7068 this._addClass( this.active.next(), "ui-accordion-content-active" ); 7069 this.active.next().show(); 7070 7071 this.headers 7072 .attr( "role", "tab" ) 7073 .each( function() { 7074 var header = $( this ), 7075 headerId = header.uniqueId().attr( "id" ), 7076 panel = header.next(), 7077 panelId = panel.uniqueId().attr( "id" ); 7078 header.attr( "aria-controls", panelId ); 7079 panel.attr( "aria-labelledby", headerId ); 7080 } ) 7081 .next() 7082 .attr( "role", "tabpanel" ); 7083 7084 this.headers 7085 .not( this.active ) 7086 .attr( { 7087 "aria-selected": "false", 7088 "aria-expanded": "false", 7089 tabIndex: -1 7090 } ) 7091 .next() 7092 .attr( { 7093 "aria-hidden": "true" 7094 } ) 7095 .hide(); 7096 7097 // Make sure at least one header is in the tab order 7098 if ( !this.active.length ) { 7099 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 7100 } else { 7101 this.active.attr( { 7102 "aria-selected": "true", 7103 "aria-expanded": "true", 7104 tabIndex: 0 7105 } ) 7106 .next() 7107 .attr( { 7108 "aria-hidden": "false" 7109 } ); 7110 } 7111 7112 this._createIcons(); 7113 7114 this._setupEvents( options.event ); 7115 7116 if ( heightStyle === "fill" ) { 7117 maxHeight = parent.height(); 7118 this.element.siblings( ":visible" ).each( function() { 7119 var elem = $( this ), 7120 position = elem.css( "position" ); 7121 7122 if ( position === "absolute" || position === "fixed" ) { 7123 return; 7124 } 7125 maxHeight -= elem.outerHeight( true ); 7126 } ); 7127 7128 this.headers.each( function() { 7129 maxHeight -= $( this ).outerHeight( true ); 7130 } ); 7131 7132 this.headers.next() 7133 .each( function() { 7134 $( this ).height( Math.max( 0, maxHeight - 7135 $( this ).innerHeight() + $( this ).height() ) ); 7136 } ) 7137 .css( "overflow", "auto" ); 7138 } else if ( heightStyle === "auto" ) { 7139 maxHeight = 0; 7140 this.headers.next() 7141 .each( function() { 7142 var isVisible = $( this ).is( ":visible" ); 7143 if ( !isVisible ) { 7144 $( this ).show(); 7145 } 7146 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 7147 if ( !isVisible ) { 7148 $( this ).hide(); 7149 } 7150 } ) 7151 .height( maxHeight ); 7152 } 7153 }, 7154 7155 _activate: function( index ) { 7156 var active = this._findActive( index )[ 0 ]; 7157 7158 // Trying to activate the already active panel 7159 if ( active === this.active[ 0 ] ) { 7160 return; 7161 } 7162 7163 // Trying to collapse, simulate a click on the currently active header 7164 active = active || this.active[ 0 ]; 7165 7166 this._eventHandler( { 7167 target: active, 7168 currentTarget: active, 7169 preventDefault: $.noop 7170 } ); 7171 }, 7172 7173 _findActive: function( selector ) { 7174 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 7175 }, 7176 7177 _setupEvents: function( event ) { 7178 var events = { 7179 keydown: "_keydown" 7180 }; 7181 if ( event ) { 7182 $.each( event.split( " " ), function( index, eventName ) { 7183 events[ eventName ] = "_eventHandler"; 7184 } ); 7185 } 7186 7187 this._off( this.headers.add( this.headers.next() ) ); 7188 this._on( this.headers, events ); 7189 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 7190 this._hoverable( this.headers ); 7191 this._focusable( this.headers ); 7192 }, 7193 7194 _eventHandler: function( event ) { 7195 var activeChildren, clickedChildren, 7196 options = this.options, 7197 active = this.active, 7198 clicked = $( event.currentTarget ), 7199 clickedIsActive = clicked[ 0 ] === active[ 0 ], 7200 collapsing = clickedIsActive && options.collapsible, 7201 toShow = collapsing ? $() : clicked.next(), 7202 toHide = active.next(), 7203 eventData = { 7204 oldHeader: active, 7205 oldPanel: toHide, 7206 newHeader: collapsing ? $() : clicked, 7207 newPanel: toShow 7208 }; 7209 7210 event.preventDefault(); 7211 7212 if ( 7213 7214 // click on active header, but not collapsible 7215 ( clickedIsActive && !options.collapsible ) || 7216 7217 // allow canceling activation 7218 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 7219 return; 7220 } 7221 7222 options.active = collapsing ? false : this.headers.index( clicked ); 7223 7224 // When the call to ._toggle() comes after the class changes 7225 // it causes a very odd bug in IE 8 (see #6720) 7226 this.active = clickedIsActive ? $() : clicked; 7227 this._toggle( eventData ); 7228 7229 // Switch classes 7230 // corner classes on the previously active header stay after the animation 7231 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 7232 if ( options.icons ) { 7233 activeChildren = active.children( ".ui-accordion-header-icon" ); 7234 this._removeClass( activeChildren, null, options.icons.activeHeader ) 7235 ._addClass( activeChildren, null, options.icons.header ); 7236 } 7237 7238 if ( !clickedIsActive ) { 7239 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 7240 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 7241 if ( options.icons ) { 7242 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 7243 this._removeClass( clickedChildren, null, options.icons.header ) 7244 ._addClass( clickedChildren, null, options.icons.activeHeader ); 7245 } 7246 7247 this._addClass( clicked.next(), "ui-accordion-content-active" ); 7248 } 7249 }, 7250 7251 _toggle: function( data ) { 7252 var toShow = data.newPanel, 7253 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 7254 7255 // Handle activating a panel during the animation for another activation 7256 this.prevShow.add( this.prevHide ).stop( true, true ); 7257 this.prevShow = toShow; 7258 this.prevHide = toHide; 7259 7260 if ( this.options.animate ) { 7261 this._animate( toShow, toHide, data ); 7262 } else { 7263 toHide.hide(); 7264 toShow.show(); 7265 this._toggleComplete( data ); 7266 } 7267 7268 toHide.attr( { 7269 "aria-hidden": "true" 7270 } ); 7271 toHide.prev().attr( { 7272 "aria-selected": "false", 7273 "aria-expanded": "false" 7274 } ); 7275 7276 // if we're switching panels, remove the old header from the tab order 7277 // if we're opening from collapsed state, remove the previous header from the tab order 7278 // if we're collapsing, then keep the collapsing header in the tab order 7279 if ( toShow.length && toHide.length ) { 7280 toHide.prev().attr( { 7281 "tabIndex": -1, 7282 "aria-expanded": "false" 7283 } ); 7284 } else if ( toShow.length ) { 7285 this.headers.filter( function() { 7286 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 7287 } ) 7288 .attr( "tabIndex", -1 ); 7289 } 7290 7291 toShow 7292 .attr( "aria-hidden", "false" ) 7293 .prev() 7294 .attr( { 7295 "aria-selected": "true", 7296 "aria-expanded": "true", 7297 tabIndex: 0 7298 } ); 7299 }, 7300 7301 _animate: function( toShow, toHide, data ) { 7302 var total, easing, duration, 7303 that = this, 7304 adjust = 0, 7305 boxSizing = toShow.css( "box-sizing" ), 7306 down = toShow.length && 7307 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 7308 animate = this.options.animate || {}, 7309 options = down && animate.down || animate, 7310 complete = function() { 7311 that._toggleComplete( data ); 7312 }; 7313 7314 if ( typeof options === "number" ) { 7315 duration = options; 7316 } 7317 if ( typeof options === "string" ) { 7318 easing = options; 7319 } 7320 7321 // fall back from options to animation in case of partial down settings 7322 easing = easing || options.easing || animate.easing; 7323 duration = duration || options.duration || animate.duration; 7324 7325 if ( !toHide.length ) { 7326 return toShow.animate( this.showProps, duration, easing, complete ); 7327 } 7328 if ( !toShow.length ) { 7329 return toHide.animate( this.hideProps, duration, easing, complete ); 7330 } 7331 7332 total = toShow.show().outerHeight(); 7333 toHide.animate( this.hideProps, { 7334 duration: duration, 7335 easing: easing, 7336 step: function( now, fx ) { 7337 fx.now = Math.round( now ); 7338 } 7339 } ); 7340 toShow 7341 .hide() 7342 .animate( this.showProps, { 7343 duration: duration, 7344 easing: easing, 7345 complete: complete, 7346 step: function( now, fx ) { 7347 fx.now = Math.round( now ); 7348 if ( fx.prop !== "height" ) { 7349 if ( boxSizing === "content-box" ) { 7350 adjust += fx.now; 7351 } 7352 } else if ( that.options.heightStyle !== "content" ) { 7353 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 7354 adjust = 0; 7355 } 7356 } 7357 } ); 7358 }, 7359 7360 _toggleComplete: function( data ) { 7361 var toHide = data.oldPanel, 7362 prev = toHide.prev(); 7363 7364 this._removeClass( toHide, "ui-accordion-content-active" ); 7365 this._removeClass( prev, "ui-accordion-header-active" ) 7366 ._addClass( prev, "ui-accordion-header-collapsed" ); 7367 7368 this._trigger( "activate", null, data ); 7369 } 7370} ); 7371 7372 7373/*! 7374 * jQuery UI Menu 1.14.2 7375 * https://jqueryui.com 7376 * 7377 * Copyright OpenJS Foundation and other contributors 7378 * Released under the MIT license. 7379 * https://jquery.org/license 7380 */ 7381 7382//>>label: Menu 7383//>>group: Widgets 7384//>>description: Creates nestable menus. 7385//>>docs: https://api.jqueryui.com/menu/ 7386//>>demos: https://jqueryui.com/menu/ 7387//>>css.structure: ../../themes/base/core.css 7388//>>css.structure: ../../themes/base/menu.css 7389//>>css.theme: ../../themes/base/theme.css 7390 7391 7392var widgetsMenu = $.widget( "ui.menu", { 7393 version: "1.14.2", 7394 defaultElement: "<ul>", 7395 delay: 300, 7396 options: { 7397 icons: { 7398 submenu: "ui-icon-caret-1-e" 7399 }, 7400 items: "> *", 7401 menus: "ul", 7402 position: { 7403 my: "left top", 7404 at: "right top" 7405 }, 7406 role: "menu", 7407 7408 // Callbacks 7409 blur: null, 7410 focus: null, 7411 select: null 7412 }, 7413 7414 _create: function() { 7415 this.activeMenu = this.element; 7416 7417 // Flag used to prevent firing of the click handler 7418 // as the event bubbles up through nested menus 7419 this.mouseHandled = false; 7420 this.lastMousePosition = { x: null, y: null }; 7421 this.element 7422 .uniqueId() 7423 .attr( { 7424 role: this.options.role, 7425 tabIndex: 0 7426 } ); 7427 7428 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 7429 this._on( { 7430 7431 // Prevent focus from sticking to links inside menu after clicking 7432 // them (focus should always stay on UL during navigation). 7433 "mousedown .ui-menu-item": function( event ) { 7434 event.preventDefault(); 7435 7436 this._activateItem( event ); 7437 }, 7438 "click .ui-menu-item": function( event ) { 7439 var target = $( event.target ); 7440 var active = $( this.document[ 0 ].activeElement ); 7441 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 7442 this.select( event ); 7443 7444 // Only set the mouseHandled flag if the event will bubble, see #9469. 7445 if ( !event.isPropagationStopped() ) { 7446 this.mouseHandled = true; 7447 } 7448 7449 // Open submenu on click 7450 if ( target.has( ".ui-menu" ).length ) { 7451 this.expand( event ); 7452 } else if ( !this.element.is( ":focus" ) && 7453 active.closest( ".ui-menu" ).length ) { 7454 7455 // Redirect focus to the menu 7456 this.element.trigger( "focus", [ true ] ); 7457 7458 // If the active item is on the top level, let it stay active. 7459 // Otherwise, blur the active item since it is no longer visible. 7460 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 7461 clearTimeout( this.timer ); 7462 } 7463 } 7464 } 7465 }, 7466 "mouseenter .ui-menu-item": "_activateItem", 7467 "mousemove .ui-menu-item": "_activateItem", 7468 mouseleave: "collapseAll", 7469 "mouseleave .ui-menu": "collapseAll", 7470 focus: function( event, keepActiveItem ) { 7471 7472 // If there's already an active item, keep it active 7473 // If not, activate the first item 7474 var item = this.active || this._menuItems().first(); 7475 7476 if ( !keepActiveItem ) { 7477 this.focus( event, item ); 7478 } 7479 }, 7480 blur: function( event ) { 7481 this._delay( function() { 7482 var notContained = !$.contains( 7483 this.element[ 0 ], 7484 this.document[ 0 ].activeElement 7485 ); 7486 if ( notContained ) { 7487 this.collapseAll( event ); 7488 } 7489 } ); 7490 }, 7491 keydown: "_keydown" 7492 } ); 7493 7494 this.refresh(); 7495 7496 // Clicks outside of a menu collapse any open menus 7497 this._on( this.document, { 7498 click: function( event ) { 7499 if ( this._closeOnDocumentClick( event ) ) { 7500 this.collapseAll( event, true ); 7501 } 7502 7503 // Reset the mouseHandled flag 7504 this.mouseHandled = false; 7505 } 7506 } ); 7507 }, 7508 7509 _activateItem: function( event ) { 7510 7511 // Ignore mouse events while typeahead is active, see #10458. 7512 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 7513 // is over an item in the menu 7514 if ( this.previousFilter ) { 7515 return; 7516 } 7517 7518 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 7519 if ( event.clientX === this.lastMousePosition.x && 7520 event.clientY === this.lastMousePosition.y ) { 7521 return; 7522 } 7523 7524 this.lastMousePosition = { 7525 x: event.clientX, 7526 y: event.clientY 7527 }; 7528 7529 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 7530 target = $( event.currentTarget ); 7531 7532 // Ignore bubbled events on parent items, see #11641 7533 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 7534 return; 7535 } 7536 7537 // If the item is already active, there's nothing to do 7538 if ( target.is( ".ui-state-active" ) ) { 7539 return; 7540 } 7541 7542 // Remove ui-state-active class from siblings of the newly focused menu item 7543 // to avoid a jump caused by adjacent elements both having a class with a border 7544 this._removeClass( target.siblings().children( ".ui-state-active" ), 7545 null, "ui-state-active" ); 7546 this.focus( event, target ); 7547 }, 7548 7549 _destroy: function() { 7550 var items = this.element.find( ".ui-menu-item" ) 7551 .removeAttr( "role aria-disabled" ), 7552 submenus = items.children( ".ui-menu-item-wrapper" ) 7553 .removeUniqueId() 7554 .removeAttr( "tabIndex role aria-haspopup" ); 7555 7556 // Destroy (sub)menus 7557 this.element 7558 .removeAttr( "aria-activedescendant" ) 7559 .find( ".ui-menu" ).addBack() 7560 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 7561 "tabIndex" ) 7562 .removeUniqueId() 7563 .show(); 7564 7565 submenus.children().each( function() { 7566 var elem = $( this ); 7567 if ( elem.data( "ui-menu-submenu-caret" ) ) { 7568 elem.remove(); 7569 } 7570 } ); 7571 }, 7572 7573 _keydown: function( event ) { 7574 var match, prev, character, skip, 7575 preventDefault = true; 7576 7577 switch ( event.keyCode ) { 7578 case $.ui.keyCode.PAGE_UP: 7579 this.previousPage( event ); 7580 break; 7581 case $.ui.keyCode.PAGE_DOWN: 7582 this.nextPage( event ); 7583 break; 7584 case $.ui.keyCode.HOME: 7585 this._move( "first", "first", event ); 7586 break; 7587 case $.ui.keyCode.END: 7588 this._move( "last", "last", event ); 7589 break; 7590 case $.ui.keyCode.UP: 7591 this.previous( event ); 7592 break; 7593 case $.ui.keyCode.DOWN: 7594 this.next( event ); 7595 break; 7596 case $.ui.keyCode.LEFT: 7597 this.collapse( event ); 7598 break; 7599 case $.ui.keyCode.RIGHT: 7600 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7601 this.expand( event ); 7602 } 7603 break; 7604 case $.ui.keyCode.ENTER: 7605 case $.ui.keyCode.SPACE: 7606 this._activate( event ); 7607 break; 7608 case $.ui.keyCode.ESCAPE: 7609 this.collapse( event ); 7610 break; 7611 default: 7612 preventDefault = false;
vendor: 6,930 bytes, lines 7613-7861
7613 prev = this.previousFilter || ""; 7614 skip = false; 7615 7616 // Support number pad values 7617 character = event.keyCode >= 96 && event.keyCode <= 105 ? 7618 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 7619 7620 clearTimeout( this.filterTimer ); 7621 7622 if ( character === prev ) { 7623 skip = true; 7624 } else { 7625 character = prev + character; 7626 } 7627 7628 match = this._filterMenuItems( character ); 7629 match = skip && match.index( this.active.next() ) !== -1 ? 7630 this.active.nextAll( ".ui-menu-item" ) : 7631 match; 7632 7633 // If no matches on the current filter, reset to the last character pressed 7634 // to move down the menu to the first item that starts with that character 7635 if ( !match.length ) { 7636 character = String.fromCharCode( event.keyCode ); 7637 match = this._filterMenuItems( character ); 7638 } 7639 7640 if ( match.length ) { 7641 this.focus( event, match ); 7642 this.previousFilter = character; 7643 this.filterTimer = this._delay( function() { 7644 delete this.previousFilter; 7645 }, 1000 ); 7646 } else { 7647 delete this.previousFilter; 7648 } 7649 } 7650 7651 if ( preventDefault ) { 7652 event.preventDefault(); 7653 } 7654 }, 7655 7656 _activate: function( event ) { 7657 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7658 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 7659 this.expand( event ); 7660 } else { 7661 this.select( event ); 7662 } 7663 } 7664 }, 7665 7666 refresh: function() { 7667 var menus, items, newSubmenus, newItems, newWrappers, 7668 that = this, 7669 icon = this.options.icons.submenu, 7670 submenus = this.element.find( this.options.menus ); 7671 7672 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 7673 7674 // Initialize nested menus 7675 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 7676 .hide() 7677 .attr( { 7678 role: this.options.role, 7679 "aria-hidden": "true", 7680 "aria-expanded": "false" 7681 } ) 7682 .each( function() { 7683 var menu = $( this ), 7684 item = menu.prev(), 7685 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 7686 7687 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 7688 item 7689 .attr( "aria-haspopup", "true" ) 7690 .prepend( submenuCaret ); 7691 menu.attr( "aria-labelledby", item.attr( "id" ) ); 7692 } ); 7693 7694 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 7695 7696 menus = submenus.add( this.element ); 7697 items = menus.find( this.options.items ); 7698 7699 // Initialize menu-items containing spaces and/or dashes only as dividers 7700 items.not( ".ui-menu-item" ).each( function() { 7701 var item = $( this ); 7702 if ( that._isDivider( item ) ) { 7703 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 7704 } 7705 } ); 7706 7707 // Don't refresh list items that are already adapted 7708 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 7709 newWrappers = newItems.children() 7710 .not( ".ui-menu" ) 7711 .uniqueId() 7712 .attr( { 7713 tabIndex: -1, 7714 role: this._itemRole() 7715 } ); 7716 this._addClass( newItems, "ui-menu-item" ) 7717 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 7718 7719 // Add aria-disabled attribute to any disabled menu item 7720 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 7721 7722 // If the active item has been removed, blur the menu 7723 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 7724 this.blur(); 7725 } 7726 }, 7727 7728 _itemRole: function() { 7729 return { 7730 menu: "menuitem", 7731 listbox: "option" 7732 }[ this.options.role ]; 7733 }, 7734 7735 _setOption: function( key, value ) { 7736 if ( key === "icons" ) { 7737 var icons = this.element.find( ".ui-menu-icon" ); 7738 this._removeClass( icons, null, this.options.icons.submenu ) 7739 ._addClass( icons, null, value.submenu ); 7740 } 7741 this._super( key, value ); 7742 }, 7743 7744 _setOptionDisabled: function( value ) { 7745 this._super( value ); 7746 7747 this.element.attr( "aria-disabled", String( value ) ); 7748 this._toggleClass( null, "ui-state-disabled", !!value ); 7749 }, 7750 7751 focus: function( event, item ) { 7752 var nested, focused, activeParent; 7753 this.blur( event, event && event.type === "focus" ); 7754 7755 this._scrollIntoView( item ); 7756 7757 this.active = item.first(); 7758 7759 focused = this.active.children( ".ui-menu-item-wrapper" ); 7760 this._addClass( focused, null, "ui-state-active" ); 7761 7762 // Only update aria-activedescendant if there's a role 7763 // otherwise we assume focus is managed elsewhere 7764 if ( this.options.role ) { 7765 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 7766 } 7767 7768 // Highlight active parent menu item, if any 7769 activeParent = this.active 7770 .parent() 7771 .closest( ".ui-menu-item" ) 7772 .children( ".ui-menu-item-wrapper" ); 7773 this._addClass( activeParent, null, "ui-state-active" ); 7774 7775 if ( event && event.type === "keydown" ) { 7776 this._close(); 7777 } else { 7778 this.timer = this._delay( function() { 7779 this._close(); 7780 }, this.delay ); 7781 } 7782 7783 nested = item.children( ".ui-menu" ); 7784 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 7785 this._startOpening( nested ); 7786 } 7787 this.activeMenu = item.parent(); 7788 7789 this._trigger( "focus", event, { item: item } ); 7790 }, 7791 7792 _scrollIntoView: function( item ) { 7793 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 7794 if ( this._hasScroll() ) { 7795 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 7796 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 7797 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 7798 scroll = this.activeMenu.scrollTop(); 7799 elementHeight = this.activeMenu.height(); 7800 itemHeight = item.outerHeight(); 7801 7802 if ( offset < 0 ) { 7803 this.activeMenu.scrollTop( scroll + offset ); 7804 } else if ( offset + itemHeight > elementHeight ) { 7805 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 7806 } 7807 } 7808 }, 7809 7810 blur: function( event, fromFocus ) { 7811 if ( !fromFocus ) { 7812 clearTimeout( this.timer ); 7813 } 7814 7815 if ( !this.active ) { 7816 return; 7817 } 7818 7819 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 7820 null, "ui-state-active" ); 7821 7822 this._trigger( "blur", event, { item: this.active } ); 7823 this.active = null; 7824 }, 7825 7826 _startOpening: function( submenu ) { 7827 clearTimeout( this.timer ); 7828 7829 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 7830 // shift in the submenu position when mousing over the caret icon 7831 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 7832 return; 7833 } 7834 7835 this.timer = this._delay( function() { 7836 this._close(); 7837 this._open( submenu ); 7838 }, this.delay ); 7839 }, 7840 7841 _open: function( submenu ) { 7842 var position = $.extend( { 7843 of: this.active 7844 }, this.options.position ); 7845 7846 clearTimeout( this.timer ); 7847 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 7848 .hide() 7849 .attr( "aria-hidden", "true" ); 7850 7851 submenu 7852 .show() 7853 .removeAttr( "aria-hidden" ) 7854 .attr( "aria-expanded", "true" ) 7855 .position( position ); 7856 }, 7857 7858 collapseAll: function( event, all ) { 7859 clearTimeout( this.timer ); 7860 this.timer = this._delay( function() { 7861
vendor: 51,558 bytes, lines 7862-9739
7862 // If we were passed an event, look for the submenu that contains the event 7863 var currentMenu = all ? this.element : 7864 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 7865 7866 // If we found no valid submenu ancestor, use the main menu to close all 7867 // sub menus anyway 7868 if ( !currentMenu.length ) { 7869 currentMenu = this.element; 7870 } 7871 7872 this._close( currentMenu ); 7873 7874 this.blur( event ); 7875 7876 // Work around active item staying active after menu is blurred 7877 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 7878 7879 this.activeMenu = currentMenu; 7880 }, all ? 0 : this.delay ); 7881 }, 7882 7883 // With no arguments, closes the currently active menu - if nothing is active 7884 // it closes all menus. If passed an argument, it will search for menus BELOW 7885 _close: function( startMenu ) { 7886 if ( !startMenu ) { 7887 startMenu = this.active ? this.active.parent() : this.element; 7888 } 7889 7890 startMenu.find( ".ui-menu" ) 7891 .hide() 7892 .attr( "aria-hidden", "true" ) 7893 .attr( "aria-expanded", "false" ); 7894 }, 7895 7896 _closeOnDocumentClick: function( event ) { 7897 return !$( event.target ).closest( ".ui-menu" ).length; 7898 }, 7899 7900 _isDivider: function( item ) { 7901 7902 // Match hyphen, em dash, en dash 7903 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 7904 }, 7905 7906 collapse: function( event ) { 7907 var newItem = this.active && 7908 this.active.parent().closest( ".ui-menu-item", this.element ); 7909 if ( newItem && newItem.length ) { 7910 this._close(); 7911 this.focus( event, newItem ); 7912 } 7913 }, 7914 7915 expand: function( event ) { 7916 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 7917 7918 if ( newItem && newItem.length ) { 7919 this._open( newItem.parent() ); 7920 7921 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 7922 this._delay( function() { 7923 this.focus( event, newItem ); 7924 } ); 7925 } 7926 }, 7927 7928 next: function( event ) { 7929 this._move( "next", "first", event ); 7930 }, 7931 7932 previous: function( event ) { 7933 this._move( "prev", "last", event ); 7934 }, 7935 7936 isFirstItem: function() { 7937 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 7938 }, 7939 7940 isLastItem: function() { 7941 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 7942 }, 7943 7944 _menuItems: function( menu ) { 7945 return ( menu || this.element ) 7946 .find( this.options.items ) 7947 .filter( ".ui-menu-item" ); 7948 }, 7949 7950 _move: function( direction, filter, event ) { 7951 var next; 7952 if ( this.active ) { 7953 if ( direction === "first" || direction === "last" ) { 7954 next = this.active 7955 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 7956 .last(); 7957 } else { 7958 next = this.active 7959 [ direction + "All" ]( ".ui-menu-item" ) 7960 .first(); 7961 } 7962 } 7963 if ( !next || !next.length || !this.active ) { 7964 next = this._menuItems( this.activeMenu )[ filter ](); 7965 } 7966 7967 this.focus( event, next ); 7968 }, 7969 7970 nextPage: function( event ) { 7971 var item, base, height; 7972 7973 if ( !this.active ) { 7974 this.next( event ); 7975 return; 7976 } 7977 if ( this.isLastItem() ) { 7978 return; 7979 } 7980 if ( this._hasScroll() ) { 7981 base = this.active.offset().top; 7982 height = this.element.innerHeight(); 7983 7984 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 7985 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 7986 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 7987 } 7988 7989 this.active.nextAll( ".ui-menu-item" ).each( function() { 7990 item = $( this ); 7991 return item.offset().top - base - height < 0; 7992 } ); 7993 7994 this.focus( event, item ); 7995 } else { 7996 this.focus( event, this._menuItems( this.activeMenu ) 7997 [ !this.active ? "first" : "last" ]() ); 7998 } 7999 }, 8000 8001 previousPage: function( event ) { 8002 var item, base, height; 8003 if ( !this.active ) { 8004 this.next( event ); 8005 return; 8006 } 8007 if ( this.isFirstItem() ) { 8008 return; 8009 } 8010 if ( this._hasScroll() ) { 8011 base = this.active.offset().top; 8012 height = this.element.innerHeight(); 8013 8014 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 8015 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 8016 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 8017 } 8018 8019 this.active.prevAll( ".ui-menu-item" ).each( function() { 8020 item = $( this ); 8021 return item.offset().top - base + height > 0; 8022 } ); 8023 8024 this.focus( event, item ); 8025 } else { 8026 this.focus( event, this._menuItems( this.activeMenu ).first() ); 8027 } 8028 }, 8029 8030 _hasScroll: function() { 8031 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 8032 }, 8033 8034 select: function( event ) { 8035 8036 // TODO: It should never be possible to not have an active item at this 8037 // point, but the tests don't trigger mouseenter before click. 8038 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 8039 var ui = { item: this.active }; 8040 if ( !this.active.has( ".ui-menu" ).length ) { 8041 this.collapseAll( event, true ); 8042 } 8043 this._trigger( "select", event, ui ); 8044 }, 8045 8046 _filterMenuItems: function( character ) { 8047 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 8048 regex = new RegExp( "^" + escapedCharacter, "i" ); 8049 8050 return this.activeMenu 8051 .find( this.options.items ) 8052 8053 // Only match on items, not dividers or other content (#10571) 8054 .filter( ".ui-menu-item" ) 8055 .filter( function() { 8056 return regex.test( 8057 String.prototype.trim.call( 8058 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 8059 } ); 8060 } 8061} ); 8062 8063 8064/*! 8065 * jQuery UI Autocomplete 1.14.2 8066 * https://jqueryui.com 8067 * 8068 * Copyright OpenJS Foundation and other contributors 8069 * Released under the MIT license. 8070 * https://jquery.org/license 8071 */ 8072 8073//>>label: Autocomplete 8074//>>group: Widgets 8075//>>description: Lists suggested words as the user is typing. 8076//>>docs: https://api.jqueryui.com/autocomplete/ 8077//>>demos: https://jqueryui.com/autocomplete/ 8078//>>css.structure: ../../themes/base/core.css 8079//>>css.structure: ../../themes/base/autocomplete.css 8080//>>css.theme: ../../themes/base/theme.css 8081 8082 8083$.widget( "ui.autocomplete", { 8084 version: "1.14.2", 8085 defaultElement: "<input>", 8086 options: { 8087 appendTo: null, 8088 autoFocus: false, 8089 delay: 300, 8090 minLength: 1, 8091 position: { 8092 my: "left top", 8093 at: "left bottom", 8094 collision: "none" 8095 }, 8096 source: null, 8097 8098 // Callbacks 8099 change: null, 8100 close: null, 8101 focus: null, 8102 open: null, 8103 response: null, 8104 search: null, 8105 select: null 8106 }, 8107 8108 requestIndex: 0, 8109 pending: 0, 8110 liveRegionTimer: null, 8111 8112 _create: function() { 8113 8114 // Some browsers only repeat keydown events, not keypress events, 8115 // so we use the suppressKeyPress flag to determine if we've already 8116 // handled the keydown event. #7269 8117 // Unfortunately the code for & in keypress is the same as the up arrow, 8118 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 8119 // events when we know the keydown event was used to modify the 8120 // search term. #7799 8121 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 8122 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 8123 isTextarea = nodeName === "textarea", 8124 isInput = nodeName === "input"; 8125 8126 // Textareas are always multi-line 8127 // Inputs are always single-line, even if inside a contentEditable element 8128 // All other element types are determined by whether they're contentEditable 8129 this.isMultiLine = isTextarea || 8130 !isInput && this.element.prop( "contentEditable" ) === "true"; 8131 8132 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 8133 this.isNewMenu = true; 8134 8135 this._addClass( "ui-autocomplete-input" ); 8136 this.element.attr( "autocomplete", "off" ); 8137 8138 this._on( this.element, { 8139 keydown: function( event ) { 8140 if ( this.element.prop( "readOnly" ) ) { 8141 suppressKeyPress = true; 8142 suppressInput = true; 8143 suppressKeyPressRepeat = true; 8144 return; 8145 } 8146 8147 suppressKeyPress = false; 8148 suppressInput = false; 8149 suppressKeyPressRepeat = false; 8150 var keyCode = $.ui.keyCode; 8151 switch ( event.keyCode ) { 8152 case keyCode.PAGE_UP: 8153 suppressKeyPress = true; 8154 this._move( "previousPage", event ); 8155 break; 8156 case keyCode.PAGE_DOWN: 8157 suppressKeyPress = true; 8158 this._move( "nextPage", event ); 8159 break; 8160 case keyCode.UP: 8161 suppressKeyPress = true; 8162 this._keyEvent( "previous", event ); 8163 break; 8164 case keyCode.DOWN: 8165 suppressKeyPress = true; 8166 this._keyEvent( "next", event ); 8167 break; 8168 case keyCode.ENTER: 8169 8170 // when menu is open and has focus 8171 if ( this.menu.active ) { 8172 8173 // #6055 - Opera still allows the keypress to occur 8174 // which causes forms to submit 8175 suppressKeyPress = true; 8176 event.preventDefault(); 8177 this.menu.select( event ); 8178 } 8179 break; 8180 case keyCode.TAB: 8181 if ( this.menu.active ) { 8182 this.menu.select( event ); 8183 } 8184 break; 8185 case keyCode.ESCAPE: 8186 if ( this.menu.element.is( ":visible" ) ) { 8187 if ( !this.isMultiLine ) { 8188 this._value( this.term ); 8189 } 8190 this.close( event ); 8191 8192 // Different browsers have different default behavior for escape 8193 // Single press can mean undo or clear 8194 event.preventDefault(); 8195 } 8196 break; 8197 default: 8198 suppressKeyPressRepeat = true; 8199 8200 // search timeout should be triggered before the input value is changed 8201 this._searchTimeout( event ); 8202 break; 8203 } 8204 }, 8205 keypress: function( event ) { 8206 if ( suppressKeyPress ) { 8207 suppressKeyPress = false; 8208 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8209 event.preventDefault(); 8210 } 8211 return; 8212 } 8213 if ( suppressKeyPressRepeat ) { 8214 return; 8215 } 8216 8217 // Replicate some key handlers to allow them to repeat in Firefox and Opera 8218 var keyCode = $.ui.keyCode; 8219 switch ( event.keyCode ) { 8220 case keyCode.PAGE_UP: 8221 this._move( "previousPage", event ); 8222 break; 8223 case keyCode.PAGE_DOWN: 8224 this._move( "nextPage", event ); 8225 break; 8226 case keyCode.UP: 8227 this._keyEvent( "previous", event ); 8228 break; 8229 case keyCode.DOWN: 8230 this._keyEvent( "next", event ); 8231 break; 8232 } 8233 }, 8234 input: function( event ) { 8235 if ( suppressInput ) { 8236 suppressInput = false; 8237 event.preventDefault(); 8238 return; 8239 } 8240 this._searchTimeout( event ); 8241 }, 8242 focus: function() { 8243 this.selectedItem = null; 8244 this.previous = this._value(); 8245 }, 8246 blur: function( event ) { 8247 clearTimeout( this.searching ); 8248 this.close( event ); 8249 this._change( event ); 8250 } 8251 } ); 8252 8253 this._initSource(); 8254 this.menu = $( "<ul>" ) 8255 .appendTo( this._appendTo() ) 8256 .menu( { 8257 8258 // disable ARIA support, the live region takes care of that 8259 role: null 8260 } ) 8261 .hide() 8262 .menu( "instance" ); 8263 8264 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 8265 this._on( this.menu.element, { 8266 mousedown: function( event ) { 8267 8268 // Prevent moving focus out of the text field 8269 event.preventDefault(); 8270 }, 8271 menufocus: function( event, ui ) { 8272 var label, item; 8273 8274 // Support: Firefox 8275 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 8276 if ( this.isNewMenu ) { 8277 this.isNewMenu = false; 8278 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 8279 this.menu.blur(); 8280 8281 this.document.one( "mousemove", function() { 8282 $( event.target ).trigger( event.originalEvent ); 8283 } ); 8284 8285 return; 8286 } 8287 } 8288 8289 item = ui.item.data( "ui-autocomplete-item" ); 8290 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 8291 8292 // use value to match what will end up in the input, if it was a key event 8293 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 8294 this._value( item.value ); 8295 } 8296 } 8297 8298 // Announce the value in the liveRegion 8299 label = ui.item.attr( "aria-label" ) || item.value; 8300 if ( label && String.prototype.trim.call( label ).length ) { 8301 clearTimeout( this.liveRegionTimer ); 8302 this.liveRegionTimer = this._delay( function() { 8303 this.liveRegion.html( $( "<div>" ).text( label ) ); 8304 }, 100 ); 8305 } 8306 }, 8307 menuselect: function( event, ui ) { 8308 var item = ui.item.data( "ui-autocomplete-item" ), 8309 previous = this.previous; 8310 8311 // Only trigger when focus was lost (click on menu) 8312 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 8313 this.element.trigger( "focus" ); 8314 this.previous = previous; 8315 } 8316 8317 if ( false !== this._trigger( "select", event, { item: item } ) ) { 8318 this._value( item.value ); 8319 } 8320 8321 // reset the term after the select event 8322 // this allows custom select handling to work properly 8323 this.term = this._value(); 8324 8325 this.close( event ); 8326 this.selectedItem = item; 8327 } 8328 } ); 8329 8330 this.liveRegion = $( "<div>", { 8331 role: "status", 8332 "aria-live": "assertive", 8333 "aria-relevant": "additions" 8334 } ) 8335 .appendTo( this.document[ 0 ].body ); 8336 8337 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 8338 8339 // Turning off autocomplete prevents the browser from remembering the 8340 // value when navigating through history, so we re-enable autocomplete 8341 // if the page is unloaded before the widget is destroyed. #7790 8342 this._on( this.window, { 8343 beforeunload: function() { 8344 this.element.removeAttr( "autocomplete" ); 8345 } 8346 } ); 8347 }, 8348 8349 _destroy: function() { 8350 clearTimeout( this.searching ); 8351 this.element.removeAttr( "autocomplete" ); 8352 this.menu.element.remove(); 8353 this.liveRegion.remove(); 8354 }, 8355 8356 _setOption: function( key, value ) { 8357 this._super( key, value ); 8358 if ( key === "source" ) { 8359 this._initSource(); 8360 } 8361 if ( key === "appendTo" ) { 8362 this.menu.element.appendTo( this._appendTo() ); 8363 } 8364 if ( key === "disabled" && value && this.xhr ) { 8365 this.xhr.abort(); 8366 } 8367 }, 8368 8369 _isEventTargetInWidget: function( event ) { 8370 var menuElement = this.menu.element[ 0 ]; 8371 8372 return event.target === this.element[ 0 ] || 8373 event.target === menuElement || 8374 $.contains( menuElement, event.target ); 8375 }, 8376 8377 _closeOnClickOutside: function( event ) { 8378 if ( !this._isEventTargetInWidget( event ) ) { 8379 this.close(); 8380 } 8381 }, 8382 8383 _appendTo: function() { 8384 var element = this.options.appendTo; 8385 8386 if ( element ) { 8387 element = element.jquery || element.nodeType ? 8388 $( element ) : 8389 this.document.find( element ).eq( 0 ); 8390 } 8391 8392 if ( !element || !element[ 0 ] ) { 8393 element = this.element.closest( ".ui-front, dialog" ); 8394 } 8395 8396 if ( !element.length ) { 8397 element = this.document[ 0 ].body; 8398 } 8399 8400 return element; 8401 }, 8402 8403 _initSource: function() { 8404 var array, url, 8405 that = this; 8406 if ( Array.isArray( this.options.source ) ) { 8407 array = this.options.source; 8408 this.source = function( request, response ) { 8409 response( $.ui.autocomplete.filter( array, request.term ) ); 8410 }; 8411 } else if ( typeof this.options.source === "string" ) { 8412 url = this.options.source; 8413 this.source = function( request, response ) { 8414 if ( that.xhr ) { 8415 that.xhr.abort(); 8416 } 8417 that.xhr = $.ajax( { 8418 url: url, 8419 data: request, 8420 dataType: "json", 8421 success: function( data ) { 8422 response( data ); 8423 }, 8424 error: function() { 8425 response( [] ); 8426 } 8427 } ); 8428 }; 8429 } else { 8430 this.source = this.options.source; 8431 } 8432 }, 8433 8434 _searchTimeout: function( event ) { 8435 clearTimeout( this.searching ); 8436 this.searching = this._delay( function() { 8437 8438 // Search if the value has changed, or if the user retypes the same value (see #7434) 8439 var equalValues = this.term === this._value(), 8440 menuVisible = this.menu.element.is( ":visible" ), 8441 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 8442 8443 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 8444 this.selectedItem = null; 8445 this.search( null, event ); 8446 } 8447 }, this.options.delay ); 8448 }, 8449 8450 search: function( value, event ) { 8451 value = value != null ? value : this._value(); 8452 8453 // Always save the actual value, not the one passed as an argument 8454 this.term = this._value(); 8455 8456 if ( value.length < this.options.minLength ) { 8457 return this.close( event ); 8458 } 8459 8460 if ( this._trigger( "search", event ) === false ) { 8461 return; 8462 } 8463 8464 return this._search( value ); 8465 }, 8466 8467 _search: function( value ) { 8468 this.pending++; 8469 this._addClass( "ui-autocomplete-loading" ); 8470 this.cancelSearch = false; 8471 8472 this.source( { term: value }, this._response() ); 8473 }, 8474 8475 _response: function() { 8476 var index = ++this.requestIndex; 8477 8478 return function( content ) { 8479 if ( index === this.requestIndex ) { 8480 this.__response( content ); 8481 } 8482 8483 this.pending--; 8484 if ( !this.pending ) { 8485 this._removeClass( "ui-autocomplete-loading" ); 8486 } 8487 }.bind( this ); 8488 }, 8489 8490 __response: function( content ) { 8491 if ( content ) { 8492 content = this._normalize( content ); 8493 } 8494 this._trigger( "response", null, { content: content } ); 8495 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 8496 this._suggest( content ); 8497 this._trigger( "open" ); 8498 } else { 8499 8500 // use ._close() instead of .close() so we don't cancel future searches 8501 this._close(); 8502 } 8503 }, 8504 8505 close: function( event ) { 8506 this.cancelSearch = true; 8507 this._close( event ); 8508 }, 8509 8510 _close: function( event ) { 8511 8512 // Remove the handler that closes the menu on outside clicks 8513 this._off( this.document, "mousedown" ); 8514 8515 if ( this.menu.element.is( ":visible" ) ) { 8516 this.menu.element.hide(); 8517 this.menu.blur(); 8518 this.isNewMenu = true; 8519 this._trigger( "close", event ); 8520 } 8521 }, 8522 8523 _change: function( event ) { 8524 if ( this.previous !== this._value() ) { 8525 this._trigger( "change", event, { item: this.selectedItem } ); 8526 } 8527 }, 8528 8529 _normalize: function( items ) { 8530 8531 // assume all items have the right format when the first item is complete 8532 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 8533 return items; 8534 } 8535 return $.map( items, function( item ) { 8536 if ( typeof item === "string" ) { 8537 return { 8538 label: item, 8539 value: item 8540 }; 8541 } 8542 return $.extend( {}, item, { 8543 label: item.label || item.value, 8544 value: item.value || item.label 8545 } ); 8546 } ); 8547 }, 8548 8549 _suggest: function( items ) { 8550 var ul = this.menu.element.empty(); 8551 this._renderMenu( ul, items ); 8552 this.isNewMenu = true; 8553 this.menu.refresh(); 8554 8555 // Size and position menu 8556 ul.show(); 8557 this._resizeMenu(); 8558 ul.position( $.extend( { 8559 of: this.element 8560 }, this.options.position ) ); 8561 8562 if ( this.options.autoFocus ) { 8563 this.menu.next(); 8564 } 8565 8566 // Listen for interactions outside of the widget (#6642) 8567 this._on( this.document, { 8568 mousedown: "_closeOnClickOutside" 8569 } ); 8570 }, 8571 8572 _resizeMenu: function() { 8573 var ul = this.menu.element; 8574 ul.outerWidth( Math.max( 8575 8576 // Firefox wraps long text (possibly a rounding bug) 8577 // so we add 1px to avoid the wrapping (#7513) 8578 ul.width( "" ).outerWidth() + 1, 8579 this.element.outerWidth() 8580 ) ); 8581 }, 8582 8583 _renderMenu: function( ul, items ) { 8584 var that = this; 8585 $.each( items, function( index, item ) { 8586 that._renderItemData( ul, item ); 8587 } ); 8588 }, 8589 8590 _renderItemData: function( ul, item ) { 8591 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 8592 }, 8593 8594 _renderItem: function( ul, item ) { 8595 return $( "<li>" ) 8596 .append( $( "<div>" ).text( item.label ) ) 8597 .appendTo( ul ); 8598 }, 8599 8600 _move: function( direction, event ) { 8601 if ( !this.menu.element.is( ":visible" ) ) { 8602 this.search( null, event ); 8603 return; 8604 } 8605 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 8606 this.menu.isLastItem() && /^next/.test( direction ) ) { 8607 8608 if ( !this.isMultiLine ) { 8609 this._value( this.term ); 8610 } 8611 8612 this.menu.blur(); 8613 return; 8614 } 8615 this.menu[ direction ]( event ); 8616 }, 8617 8618 widget: function() { 8619 return this.menu.element; 8620 }, 8621 8622 _value: function() { 8623 return this.valueMethod.apply( this.element, arguments ); 8624 }, 8625 8626 _keyEvent: function( keyEvent, event ) { 8627 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8628 this._move( keyEvent, event ); 8629 8630 // Prevents moving cursor to beginning/end of the text field in some browsers 8631 event.preventDefault(); 8632 } 8633 } 8634} ); 8635 8636$.extend( $.ui.autocomplete, { 8637 escapeRegex: function( value ) { 8638 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 8639 }, 8640 filter: function( array, term ) { 8641 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 8642 return $.grep( array, function( value ) { 8643 return matcher.test( value.label || value.value || value ); 8644 } ); 8645 } 8646} ); 8647 8648// Live region extension, adding a `messages` option 8649// NOTE: This is an experimental API. We are still investigating 8650// a full solution for string manipulation and internationalization. 8651$.widget( "ui.autocomplete", $.ui.autocomplete, { 8652 options: { 8653 messages: { 8654 noResults: "No search results.", 8655 results: function( amount ) { 8656 return amount + ( amount > 1 ? " results are" : " result is" ) + 8657 " available, use up and down arrow keys to navigate."; 8658 } 8659 } 8660 }, 8661 8662 __response: function( content ) { 8663 var message; 8664 this._superApply( arguments ); 8665 if ( this.options.disabled || this.cancelSearch ) { 8666 return; 8667 } 8668 if ( content && content.length ) { 8669 message = this.options.messages.results( content.length ); 8670 } else { 8671 message = this.options.messages.noResults; 8672 } 8673 clearTimeout( this.liveRegionTimer ); 8674 this.liveRegionTimer = this._delay( function() { 8675 this.liveRegion.html( $( "<div>" ).text( message ) ); 8676 }, 100 ); 8677 } 8678} ); 8679 8680var widgetsAutocomplete = $.ui.autocomplete; 8681 8682 8683/*! 8684 * jQuery UI Controlgroup 1.14.2 8685 * https://jqueryui.com 8686 * 8687 * Copyright OpenJS Foundation and other contributors 8688 * Released under the MIT license. 8689 * https://jquery.org/license 8690 */ 8691 8692//>>label: Controlgroup 8693//>>group: Widgets 8694//>>description: Visually groups form control widgets 8695//>>docs: https://api.jqueryui.com/controlgroup/ 8696//>>demos: https://jqueryui.com/controlgroup/ 8697//>>css.structure: ../../themes/base/core.css 8698//>>css.structure: ../../themes/base/controlgroup.css 8699//>>css.theme: ../../themes/base/theme.css 8700 8701 8702var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 8703 8704var widgetsControlgroup = $.widget( "ui.controlgroup", { 8705 version: "1.14.2", 8706 defaultElement: "<div>", 8707 options: { 8708 direction: "horizontal", 8709 disabled: null, 8710 onlyVisible: true, 8711 items: { 8712 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 8713 "controlgroupLabel": ".ui-controlgroup-label", 8714 "checkboxradio": "input[type='checkbox'], input[type='radio']", 8715 "selectmenu": "select", 8716 "spinner": ".ui-spinner-input" 8717 } 8718 }, 8719 8720 _create: function() { 8721 this._enhance(); 8722 }, 8723 8724 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 8725 _enhance: function() { 8726 this.element.attr( "role", "toolbar" ); 8727 this.refresh(); 8728 }, 8729 8730 _destroy: function() { 8731 this._callChildMethod( "destroy" ); 8732 this.childWidgets.removeData( "ui-controlgroup-data" ); 8733 this.element.removeAttr( "role" ); 8734 if ( this.options.items.controlgroupLabel ) { 8735 this.element 8736 .find( this.options.items.controlgroupLabel ) 8737 .find( ".ui-controlgroup-label-contents" ) 8738 .contents().unwrap(); 8739 } 8740 }, 8741 8742 _initWidgets: function() { 8743 var that = this, 8744 childWidgets = []; 8745 8746 // First we iterate over each of the items options 8747 $.each( this.options.items, function( widget, selector ) { 8748 var labels; 8749 var options = {}; 8750 8751 // Make sure the widget has a selector set 8752 if ( !selector ) { 8753 return; 8754 } 8755 8756 if ( widget === "controlgroupLabel" ) { 8757 labels = that.element.find( selector ); 8758 labels.each( function() { 8759 var element = $( this ); 8760 8761 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 8762 return; 8763 } 8764 element.contents() 8765 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 8766 } ); 8767 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 8768 childWidgets = childWidgets.concat( labels.get() ); 8769 return; 8770 } 8771 8772 // Make sure the widget actually exists 8773 if ( !$.fn[ widget ] ) { 8774 return; 8775 } 8776 8777 // We assume everything is in the middle to start because we can't determine 8778 // first / last elements until all enhancments are done. 8779 if ( that[ "_" + widget + "Options" ] ) { 8780 options = that[ "_" + widget + "Options" ]( "middle" ); 8781 } else { 8782 options = { classes: {} }; 8783 } 8784 8785 // Find instances of this widget inside controlgroup and init them 8786 that.element 8787 .find( selector ) 8788 .each( function() { 8789 var element = $( this ); 8790 var instance = element[ widget ]( "instance" ); 8791 8792 // We need to clone the default options for this type of widget to avoid 8793 // polluting the variable options which has a wider scope than a single widget. 8794 var instanceOptions = $.widget.extend( {}, options ); 8795 8796 // If the button is the child of a spinner ignore it 8797 // TODO: Find a more generic solution 8798 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 8799 return; 8800 } 8801 8802 // Create the widget if it doesn't exist 8803 if ( !instance ) { 8804 instance = element[ widget ]()[ widget ]( "instance" ); 8805 } 8806 if ( instance ) { 8807 instanceOptions.classes = 8808 that._resolveClassesValues( instanceOptions.classes, instance ); 8809 } 8810 element[ widget ]( instanceOptions ); 8811 8812 // Store an instance of the controlgroup to be able to reference 8813 // from the outermost element for changing options and refresh 8814 var widgetElement = element[ widget ]( "widget" ); 8815 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 8816 instance ? instance : element[ widget ]( "instance" ) ); 8817 8818 childWidgets.push( widgetElement[ 0 ] ); 8819 } ); 8820 } ); 8821 8822 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 8823 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 8824 }, 8825 8826 _callChildMethod: function( method ) { 8827 this.childWidgets.each( function() { 8828 var element = $( this ), 8829 data = element.data( "ui-controlgroup-data" ); 8830 if ( data && data[ method ] ) { 8831 data[ method ](); 8832 } 8833 } ); 8834 }, 8835 8836 _updateCornerClass: function( element, position ) { 8837 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 8838 var add = this._buildSimpleOptions( position, "label" ).classes.label; 8839 8840 this._removeClass( element, null, remove ); 8841 this._addClass( element, null, add ); 8842 }, 8843 8844 _buildSimpleOptions: function( position, key ) { 8845 var direction = this.options.direction === "vertical"; 8846 var result = { 8847 classes: {} 8848 }; 8849 result.classes[ key ] = { 8850 "middle": "", 8851 "first": "ui-corner-" + ( direction ? "top" : "left" ), 8852 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 8853 "only": "ui-corner-all" 8854 }[ position ]; 8855 8856 return result; 8857 }, 8858 8859 _spinnerOptions: function( position ) { 8860 var options = this._buildSimpleOptions( position, "ui-spinner" ); 8861 8862 options.classes[ "ui-spinner-up" ] = ""; 8863 options.classes[ "ui-spinner-down" ] = ""; 8864 8865 return options; 8866 }, 8867 8868 _buttonOptions: function( position ) { 8869 return this._buildSimpleOptions( position, "ui-button" ); 8870 }, 8871 8872 _checkboxradioOptions: function( position ) { 8873 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 8874 }, 8875 8876 _selectmenuOptions: function( position ) { 8877 var direction = this.options.direction === "vertical"; 8878 return { 8879 width: direction ? "auto" : false, 8880 classes: { 8881 middle: { 8882 "ui-selectmenu-button-open": "", 8883 "ui-selectmenu-button-closed": "" 8884 }, 8885 first: { 8886 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 8887 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 8888 }, 8889 last: { 8890 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 8891 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 8892 }, 8893 only: { 8894 "ui-selectmenu-button-open": "ui-corner-top", 8895 "ui-selectmenu-button-closed": "ui-corner-all" 8896 } 8897 8898 }[ position ] 8899 }; 8900 }, 8901 8902 _resolveClassesValues: function( classes, instance ) { 8903 var result = {}; 8904 $.each( classes, function( key ) { 8905 var current = instance.options.classes[ key ] || ""; 8906 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 8907 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 8908 } ); 8909 return result; 8910 }, 8911 8912 _setOption: function( key, value ) { 8913 if ( key === "direction" ) { 8914 this._removeClass( "ui-controlgroup-" + this.options.direction ); 8915 } 8916 8917 this._super( key, value ); 8918 if ( key === "disabled" ) { 8919 this._callChildMethod( value ? "disable" : "enable" ); 8920 return; 8921 } 8922 8923 this.refresh(); 8924 }, 8925 8926 refresh: function() { 8927 var children, 8928 that = this; 8929 8930 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 8931 8932 if ( this.options.direction === "horizontal" ) { 8933 this._addClass( null, "ui-helper-clearfix" ); 8934 } 8935 this._initWidgets(); 8936 8937 children = this.childWidgets; 8938 8939 // We filter here because we need to track all childWidgets not just the visible ones 8940 if ( this.options.onlyVisible ) { 8941 children = children.filter( ":visible" ); 8942 } 8943 8944 if ( children.length ) { 8945 8946 // We do this last because we need to make sure all enhancment is done 8947 // before determining first and last 8948 $.each( [ "first", "last" ], function( index, value ) { 8949 var instance = children[ value ]().data( "ui-controlgroup-data" ); 8950 8951 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 8952 var options = that[ "_" + instance.widgetName + "Options" ]( 8953 children.length === 1 ? "only" : value 8954 ); 8955 options.classes = that._resolveClassesValues( options.classes, instance ); 8956 instance.element[ instance.widgetName ]( options ); 8957 } else { 8958 that._updateCornerClass( children[ value ](), value ); 8959 } 8960 } ); 8961 8962 // Finally call the refresh method on each of the child widgets. 8963 this._callChildMethod( "refresh" ); 8964 } 8965 } 8966} ); 8967 8968/*! 8969 * jQuery UI Checkboxradio 1.14.2 8970 * https://jqueryui.com 8971 * 8972 * Copyright OpenJS Foundation and other contributors 8973 * Released under the MIT license. 8974 * https://jquery.org/license 8975 */ 8976 8977//>>label: Checkboxradio 8978//>>group: Widgets 8979//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 8980//>>docs: https://api.jqueryui.com/checkboxradio/ 8981//>>demos: https://jqueryui.com/checkboxradio/ 8982//>>css.structure: ../../themes/base/core.css 8983//>>css.structure: ../../themes/base/button.css 8984//>>css.structure: ../../themes/base/checkboxradio.css 8985//>>css.theme: ../../themes/base/theme.css 8986 8987 8988$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 8989 version: "1.14.2", 8990 options: { 8991 disabled: null, 8992 label: null, 8993 icon: true, 8994 classes: { 8995 "ui-checkboxradio-label": "ui-corner-all", 8996 "ui-checkboxradio-icon": "ui-corner-all" 8997 } 8998 }, 8999 9000 _getCreateOptions: function() { 9001 var disabled, labels, labelContents; 9002 var options = this._super() || {}; 9003 9004 // We read the type here, because it makes more sense to throw a element type error first, 9005 // rather then the error for lack of a label. Often if its the wrong type, it 9006 // won't have a label (e.g. calling on a div, btn, etc) 9007 this._readType(); 9008 9009 labels = this.element.labels(); 9010 9011 // If there are multiple labels, use the last one 9012 this.label = $( labels[ labels.length - 1 ] ); 9013 if ( !this.label.length ) { 9014 $.error( "No label found for checkboxradio widget" ); 9015 } 9016 9017 this.originalLabel = ""; 9018 9019 // We need to get the label text but this may also need to make sure it does not contain the 9020 // input itself. 9021 // The label contents could be text, html, or a mix. We wrap all elements 9022 // and read the wrapper's `innerHTML` to get a string representation of 9023 // the label, without the input as part of it. 9024 labelContents = this.label.contents().not( this.element[ 0 ] ); 9025 9026 if ( labelContents.length ) { 9027 this.originalLabel += labelContents 9028 .clone() 9029 .wrapAll( "<div></div>" ) 9030 .parent() 9031 .html(); 9032 } 9033 9034 // Set the label option if we found label text 9035 if ( this.originalLabel ) { 9036 options.label = this.originalLabel; 9037 } 9038 9039 disabled = this.element[ 0 ].disabled; 9040 if ( disabled != null ) { 9041 options.disabled = disabled; 9042 } 9043 return options; 9044 }, 9045 9046 _create: function() { 9047 var checked = this.element[ 0 ].checked; 9048 9049 this._bindFormResetHandler(); 9050 9051 if ( this.options.disabled == null ) { 9052 this.options.disabled = this.element[ 0 ].disabled; 9053 } 9054 9055 this._setOption( "disabled", this.options.disabled ); 9056 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 9057 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 9058 9059 if ( this.type === "radio" ) { 9060 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 9061 } 9062 9063 if ( this.options.label && this.options.label !== this.originalLabel ) { 9064 this._updateLabel(); 9065 } else if ( this.originalLabel ) { 9066 this.options.label = this.originalLabel; 9067 } 9068 9069 this._enhance(); 9070 9071 if ( checked ) { 9072 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 9073 } 9074 9075 this._on( { 9076 change: "_toggleClasses", 9077 focus: function() { 9078 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9079 }, 9080 blur: function() { 9081 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9082 } 9083 } ); 9084 }, 9085 9086 _readType: function() { 9087 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 9088 this.type = this.element[ 0 ].type; 9089 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 9090 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 9091 " and element.type=" + this.type ); 9092 } 9093 }, 9094 9095 // Support jQuery Mobile enhanced option 9096 _enhance: function() { 9097 this._updateIcon( this.element[ 0 ].checked ); 9098 }, 9099 9100 widget: function() { 9101 return this.label; 9102 }, 9103 9104 _getRadioGroup: function() { 9105 var group; 9106 var name = this.element[ 0 ].name; 9107 var nameSelector = "input[name='" + CSS.escape( name ) + "']"; 9108 9109 if ( !name ) { 9110 return $( [] ); 9111 } 9112 9113 if ( this.form.length ) { 9114 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 9115 } else { 9116 9117 // Not inside a form, check all inputs that also are not inside a form 9118 group = $( nameSelector ).filter( function() { 9119 return $( $( this ).prop( "form" ) ).length === 0; 9120 } ); 9121 } 9122 9123 return group.not( this.element ); 9124 }, 9125 9126 _toggleClasses: function() { 9127 var checked = this.element[ 0 ].checked; 9128 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9129 9130 if ( this.options.icon && this.type === "checkbox" ) { 9131 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 9132 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 9133 } 9134 9135 if ( this.type === "radio" ) { 9136 this._getRadioGroup() 9137 .each( function() { 9138 var instance = $( this ).checkboxradio( "instance" ); 9139 9140 if ( instance ) { 9141 instance._removeClass( instance.label, 9142 "ui-checkboxradio-checked", "ui-state-active" ); 9143 } 9144 } ); 9145 } 9146 }, 9147 9148 _destroy: function() { 9149 this._unbindFormResetHandler(); 9150 9151 if ( this.icon ) { 9152 this.icon.remove(); 9153 this.iconSpace.remove(); 9154 } 9155 }, 9156 9157 _setOption: function( key, value ) { 9158 9159 // We don't allow the value to be set to nothing 9160 if ( key === "label" && !value ) { 9161 return; 9162 } 9163 9164 this._super( key, value ); 9165 9166 if ( key === "disabled" ) { 9167 this._toggleClass( this.label, null, "ui-state-disabled", value ); 9168 this.element[ 0 ].disabled = value; 9169 9170 // Don't refresh when setting disabled 9171 return; 9172 } 9173 this.refresh(); 9174 }, 9175 9176 _updateIcon: function( checked ) { 9177 var toAdd = "ui-icon ui-icon-background "; 9178 9179 if ( this.options.icon ) { 9180 if ( !this.icon ) { 9181 this.icon = $( "<span>" ); 9182 this.iconSpace = $( "<span> </span>" ); 9183 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 9184 } 9185 9186 if ( this.type === "checkbox" ) { 9187 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 9188 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 9189 } else { 9190 toAdd += "ui-icon-blank"; 9191 } 9192 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 9193 if ( !checked ) { 9194 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 9195 } 9196 this.icon.prependTo( this.label ).after( this.iconSpace ); 9197 } else if ( this.icon !== undefined ) { 9198 this.icon.remove(); 9199 this.iconSpace.remove(); 9200 delete this.icon; 9201 } 9202 }, 9203 9204 _updateLabel: function() { 9205 9206 // Remove the contents of the label ( minus the icon, icon space, and input ) 9207 var contents = this.label.contents().not( this.element[ 0 ] ); 9208 if ( this.icon ) { 9209 contents = contents.not( this.icon[ 0 ] ); 9210 } 9211 if ( this.iconSpace ) { 9212 contents = contents.not( this.iconSpace[ 0 ] ); 9213 } 9214 contents.remove(); 9215 9216 this.label.append( this.options.label ); 9217 }, 9218 9219 refresh: function() { 9220 var checked = this.element[ 0 ].checked, 9221 isDisabled = this.element[ 0 ].disabled; 9222 9223 this._updateIcon( checked ); 9224 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9225 if ( this.options.label !== null ) { 9226 this._updateLabel(); 9227 } 9228 9229 if ( isDisabled !== this.options.disabled ) { 9230 this._setOptions( { "disabled": isDisabled } ); 9231 } 9232 } 9233 9234} ] ); 9235 9236var widgetsCheckboxradio = $.ui.checkboxradio; 9237 9238 9239/*! 9240 * jQuery UI Button 1.14.2 9241 * https://jqueryui.com 9242 * 9243 * Copyright OpenJS Foundation and other contributors 9244 * Released under the MIT license. 9245 * https://jquery.org/license 9246 */ 9247 9248//>>label: Button 9249//>>group: Widgets 9250//>>description: Enhances a form with themeable buttons. 9251//>>docs: https://api.jqueryui.com/button/ 9252//>>demos: https://jqueryui.com/button/ 9253//>>css.structure: ../../themes/base/core.css 9254//>>css.structure: ../../themes/base/button.css 9255//>>css.theme: ../../themes/base/theme.css 9256 9257 9258$.widget( "ui.button", { 9259 version: "1.14.2", 9260 defaultElement: "<button>", 9261 options: { 9262 classes: { 9263 "ui-button": "ui-corner-all" 9264 }, 9265 disabled: null, 9266 icon: null, 9267 iconPosition: "beginning", 9268 label: null, 9269 showLabel: true 9270 }, 9271 9272 _getCreateOptions: function() { 9273 var disabled, 9274 9275 // This is to support cases like in jQuery Mobile where the base widget does have 9276 // an implementation of _getCreateOptions 9277 options = this._super() || {}; 9278 9279 this.isInput = this.element.is( "input" ); 9280 9281 disabled = this.element[ 0 ].disabled; 9282 if ( disabled != null ) { 9283 options.disabled = disabled; 9284 } 9285 9286 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 9287 if ( this.originalLabel ) { 9288 options.label = this.originalLabel; 9289 } 9290 9291 return options; 9292 }, 9293 9294 _create: function() { 9295 if ( !this.option.showLabel & !this.options.icon ) { 9296 this.options.showLabel = true; 9297 } 9298 9299 // We have to check the option again here even though we did in _getCreateOptions, 9300 // because null may have been passed on init which would override what was set in 9301 // _getCreateOptions 9302 if ( this.options.disabled == null ) { 9303 this.options.disabled = this.element[ 0 ].disabled || false; 9304 } 9305 9306 this.hasTitle = !!this.element.attr( "title" ); 9307 9308 // Check to see if the label needs to be set or if its already correct 9309 if ( this.options.label && this.options.label !== this.originalLabel ) { 9310 if ( this.isInput ) { 9311 this.element.val( this.options.label ); 9312 } else { 9313 this.element.html( this.options.label ); 9314 } 9315 } 9316 this._addClass( "ui-button", "ui-widget" ); 9317 this._setOption( "disabled", this.options.disabled ); 9318 this._enhance(); 9319 9320 if ( this.element.is( "a" ) ) { 9321 this._on( { 9322 "keyup": function( event ) { 9323 if ( event.keyCode === $.ui.keyCode.SPACE ) { 9324 event.preventDefault(); 9325 9326 // If a native click is available use it, so we 9327 // actually cause navigation. Otherwise, just trigger 9328 // a click event. 9329 if ( this.element[ 0 ].click ) { 9330 this.element[ 0 ].click(); 9331 } else { 9332 this.element.trigger( "click" ); 9333 } 9334 } 9335 } 9336 } ); 9337 } 9338 }, 9339 9340 _enhance: function() { 9341 if ( !this.element.is( "button" ) ) { 9342 this.element.attr( "role", "button" ); 9343 } 9344 9345 if ( this.options.icon ) { 9346 this._updateIcon( "icon", this.options.icon ); 9347 this._updateTooltip(); 9348 } 9349 }, 9350 9351 _updateTooltip: function() { 9352 this.title = this.element.attr( "title" ); 9353 9354 if ( !this.options.showLabel && !this.title ) { 9355 this.element.attr( "title", this.options.label ); 9356 } 9357 }, 9358 9359 _updateIcon: function( option, value ) { 9360 var icon = option !== "iconPosition", 9361 position = icon ? this.options.iconPosition : value, 9362 displayBlock = position === "top" || position === "bottom"; 9363 9364 // Create icon 9365 if ( !this.icon ) { 9366 this.icon = $( "<span>" ); 9367 9368 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 9369 9370 if ( !this.options.showLabel ) { 9371 this._addClass( "ui-button-icon-only" ); 9372 } 9373 } else if ( icon ) { 9374 9375 // If we are updating the icon remove the old icon class 9376 this._removeClass( this.icon, null, this.options.icon ); 9377 } 9378 9379 // If we are updating the icon add the new icon class 9380 if ( icon ) { 9381 this._addClass( this.icon, null, value ); 9382 } 9383 9384 this._attachIcon( position ); 9385 9386 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 9387 // the iconSpace if there is one. 9388 if ( displayBlock ) { 9389 this._addClass( this.icon, null, "ui-widget-icon-block" ); 9390 if ( this.iconSpace ) { 9391 this.iconSpace.remove(); 9392 } 9393 } else { 9394 9395 // Position is beginning or end so remove the ui-widget-icon-block class and add the 9396 // space if it does not exist 9397 if ( !this.iconSpace ) { 9398 this.iconSpace = $( "<span> </span>" ); 9399 this._addClass( this.iconSpace, "ui-button-icon-space" ); 9400 } 9401 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 9402 this._attachIconSpace( position ); 9403 } 9404 }, 9405 9406 _destroy: function() { 9407 this.element.removeAttr( "role" ); 9408 9409 if ( this.icon ) { 9410 this.icon.remove(); 9411 } 9412 if ( this.iconSpace ) { 9413 this.iconSpace.remove(); 9414 } 9415 if ( !this.hasTitle ) { 9416 this.element.removeAttr( "title" ); 9417 } 9418 }, 9419 9420 _attachIconSpace: function( iconPosition ) { 9421 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 9422 }, 9423 9424 _attachIcon: function( iconPosition ) { 9425 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 9426 }, 9427 9428 _setOptions: function( options ) { 9429 var newShowLabel = options.showLabel === undefined ? 9430 this.options.showLabel : 9431 options.showLabel, 9432 newIcon = options.icon === undefined ? this.options.icon : options.icon; 9433 9434 if ( !newShowLabel && !newIcon ) { 9435 options.showLabel = true; 9436 } 9437 this._super( options ); 9438 }, 9439 9440 _setOption: function( key, value ) { 9441 if ( key === "icon" ) { 9442 if ( value ) { 9443 this._updateIcon( key, value ); 9444 } else if ( this.icon ) { 9445 this.icon.remove(); 9446 if ( this.iconSpace ) { 9447 this.iconSpace.remove(); 9448 } 9449 } 9450 } 9451 9452 if ( key === "iconPosition" ) { 9453 this._updateIcon( key, value ); 9454 } 9455 9456 // Make sure we can't end up with a button that has neither text nor icon 9457 if ( key === "showLabel" ) { 9458 this._toggleClass( "ui-button-icon-only", null, !value ); 9459 this._updateTooltip(); 9460 } 9461 9462 if ( key === "label" ) { 9463 if ( this.isInput ) { 9464 this.element.val( value ); 9465 } else { 9466 9467 // If there is an icon, append it, else nothing then append the value 9468 // this avoids removal of the icon when setting label text 9469 this.element.html( value ); 9470 if ( this.icon ) { 9471 this._attachIcon( this.options.iconPosition ); 9472 this._attachIconSpace( this.options.iconPosition ); 9473 } 9474 } 9475 } 9476 9477 this._super( key, value ); 9478 9479 if ( key === "disabled" ) { 9480 this._toggleClass( null, "ui-state-disabled", value ); 9481 this.element[ 0 ].disabled = value; 9482 if ( value ) { 9483 this.element.trigger( "blur" ); 9484 } 9485 } 9486 }, 9487 9488 refresh: function() { 9489 9490 // Make sure to only check disabled if its an element that supports this otherwise 9491 // check for the disabled class to determine state 9492 var isDisabled = this.element.is( "input, button" ) ? 9493 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 9494 9495 if ( isDisabled !== this.options.disabled ) { 9496 this._setOptions( { disabled: isDisabled } ); 9497 } 9498 9499 this._updateTooltip(); 9500 } 9501} ); 9502 9503// DEPRECATED 9504if ( $.uiBackCompat === true ) { 9505 9506 // Text and Icons options 9507 $.widget( "ui.button", $.ui.button, { 9508 options: { 9509 text: true, 9510 icons: { 9511 primary: null, 9512 secondary: null 9513 } 9514 }, 9515 9516 _create: function() { 9517 if ( this.options.showLabel && !this.options.text ) { 9518 this.options.showLabel = this.options.text; 9519 } 9520 if ( !this.options.showLabel && this.options.text ) { 9521 this.options.text = this.options.showLabel; 9522 } 9523 if ( !this.options.icon && ( this.options.icons.primary || 9524 this.options.icons.secondary ) ) { 9525 if ( this.options.icons.primary ) { 9526 this.options.icon = this.options.icons.primary; 9527 } else { 9528 this.options.icon = this.options.icons.secondary; 9529 this.options.iconPosition = "end"; 9530 } 9531 } else if ( this.options.icon ) { 9532 this.options.icons.primary = this.options.icon; 9533 } 9534 this._super(); 9535 }, 9536 9537 _setOption: function( key, value ) { 9538 if ( key === "text" ) { 9539 this._super( "showLabel", value ); 9540 return; 9541 } 9542 if ( key === "showLabel" ) { 9543 this.options.text = value; 9544 } 9545 if ( key === "icon" ) { 9546 this.options.icons.primary = value; 9547 } 9548 if ( key === "icons" ) { 9549 if ( value.primary ) { 9550 this._super( "icon", value.primary ); 9551 this._super( "iconPosition", "beginning" ); 9552 } else if ( value.secondary ) { 9553 this._super( "icon", value.secondary ); 9554 this._super( "iconPosition", "end" ); 9555 } 9556 } 9557 this._superApply( arguments ); 9558 } 9559 } ); 9560 9561 $.fn.button = ( function( orig ) { 9562 return function( options ) { 9563 var isMethodCall = typeof options === "string"; 9564 var args = Array.prototype.slice.call( arguments, 1 ); 9565 var returnValue = this; 9566 9567 if ( isMethodCall ) { 9568 9569 // If this is an empty collection, we need to have the instance method 9570 // return undefined instead of the jQuery instance 9571 if ( !this.length && options === "instance" ) { 9572 returnValue = undefined; 9573 } else { 9574 this.each( function() { 9575 var methodValue; 9576 var type = $( this ).attr( "type" ); 9577 var name = type !== "checkbox" && type !== "radio" ? 9578 "button" : 9579 "checkboxradio"; 9580 var instance = $.data( this, "ui-" + name ); 9581 9582 if ( options === "instance" ) { 9583 returnValue = instance; 9584 return false; 9585 } 9586 9587 if ( !instance ) { 9588 return $.error( "cannot call methods on button" + 9589 " prior to initialization; " + 9590 "attempted to call method '" + options + "'" ); 9591 } 9592 9593 if ( typeof instance[ options ] !== "function" || 9594 options.charAt( 0 ) === "_" ) { 9595 return $.error( "no such method '" + options + "' for button" + 9596 " widget instance" ); 9597 } 9598 9599 methodValue = instance[ options ].apply( instance, args ); 9600 9601 if ( methodValue !== instance && methodValue !== undefined ) { 9602 returnValue = methodValue && methodValue.jquery ? 9603 returnValue.pushStack( methodValue.get() ) : 9604 methodValue; 9605 return false; 9606 } 9607 } ); 9608 } 9609 } else { 9610 9611 // Allow multiple hashes to be passed on init 9612 if ( args.length ) { 9613 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 9614 } 9615 9616 this.each( function() { 9617 var type = $( this ).attr( "type" ); 9618 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 9619 var instance = $.data( this, "ui-" + name ); 9620 9621 if ( instance ) { 9622 instance.option( options || {} ); 9623 if ( instance._init ) { 9624 instance._init(); 9625 } 9626 } else { 9627 if ( name === "button" ) { 9628 orig.call( $( this ), options ); 9629 return; 9630 } 9631 9632 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 9633 } 9634 } ); 9635 } 9636 9637 return returnValue; 9638 }; 9639 } )( $.fn.button ); 9640 9641 $.fn.buttonset = function() { 9642 if ( !$.ui.controlgroup ) { 9643 $.error( "Controlgroup widget missing" ); 9644 } 9645 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 9646 return this.controlgroup.apply( this, 9647 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 9648 } 9649 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 9650 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 9651 } 9652 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 9653 arguments[ 0 ].items = { 9654 button: arguments[ 0 ].items 9655 }; 9656 } 9657 return this.controlgroup.apply( this, arguments ); 9658 }; 9659} 9660 9661var widgetsButton = $.ui.button; 9662 9663 9664/* eslint-disable max-len */ 9665/*! 9666 * jQuery UI Datepicker 1.14.2 9667 * https://jqueryui.com 9668 * 9669 * Copyright OpenJS Foundation and other contributors 9670 * Released under the MIT license. 9671 * https://jquery.org/license 9672 */ 9673 9674//>>label: Datepicker 9675//>>group: Widgets 9676//>>description: Displays a calendar from an input or inline for selecting dates. 9677//>>docs: https://api.jqueryui.com/datepicker/ 9678//>>demos: https://jqueryui.com/datepicker/ 9679//>>css.structure: ../../themes/base/core.css 9680//>>css.structure: ../../themes/base/datepicker.css 9681//>>css.theme: ../../themes/base/theme.css 9682 9683 9684$.extend( $.ui, { datepicker: { version: "1.14.2" } } ); 9685 9686var datepicker_instActive; 9687 9688function datepicker_getZindex( elem ) { 9689 var position, value; 9690 while ( elem.length && elem[ 0 ] !== document ) { 9691 9692 // Ignore z-index if position is set to a value where z-index is ignored by the browser 9693 // This makes behavior of this function consistent across browsers 9694 // WebKit always returns auto if the element is positioned 9695 position = elem.css( "position" ); 9696 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 9697 9698 // IE returns 0 when zIndex is not specified 9699 // other browsers return a string 9700 // we ignore the case of nested elements with an explicit value of 0 9701 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 9702 value = parseInt( elem.css( "zIndex" ), 10 ); 9703 if ( !isNaN( value ) && value !== 0 ) { 9704 return value; 9705 } 9706 } 9707 elem = elem.parent(); 9708 } 9709 9710 return 0; 9711} 9712 9713/* Date picker manager. 9714 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 9715 Settings for (groups of) date pickers are maintained in an instance object, 9716 allowing multiple different settings on the same page. */ 9717 9718function Datepicker() { 9719 this._curInst = null; // The current instance in use 9720 this._keyEvent = false; // If the last event was a key event 9721 this._disabledInputs = []; // List of date picker inputs that have been disabled 9722 this._datepickerShowing = false; // True if the popup picker is showing , false if not 9723 this._inDialog = false; // True if showing within a "dialog", false if not 9724 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 9725 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 9726 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 9727 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 9728 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 9729 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 9730 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 9731 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 9732 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 9733 this.regional = []; // Available regional settings, indexed by language code 9734 this.regional[ "" ] = { // Default regional settings 9735 closeText: "Done", // Display text for close link 9736 prevText: "Prev", // Display text for previous month link 9737 nextText: "Next", // Display text for next month link 9738 currentText: "Today", // Display text for current month link 9739 monthNames: [ "January", "February", "March", "April", "May", "June",
vendor: 40,309 bytes, lines 9740-10834
9740 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 9741 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 9742 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 9743 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 9744 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 9745 weekHeader: "Wk", // Column header for week of the year 9746 dateFormat: "mm/dd/yy", // See format options on parseDate 9747 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 9748 isRTL: false, // True if right-to-left language, false if left-to-right 9749 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 9750 yearSuffix: "", // Additional text to append to the year in the month headers, 9751 selectMonthLabel: "Select month", // Invisible label for month selector 9752 selectYearLabel: "Select year" // Invisible label for year selector 9753 }; 9754 this._defaults = { // Global defaults for all the date picker instances 9755 showOn: "focus", // "focus" for popup on focus, 9756 // "button" for trigger button, or "both" for either 9757 showAnim: "fadeIn", // Name of jQuery animation for popup 9758 showOptions: {}, // Options for enhanced animations 9759 defaultDate: null, // Used when field is blank: actual date, 9760 // +/-number for offset from today, null for today 9761 appendText: "", // Display text following the input box, e.g. showing the format 9762 buttonText: "...", // Text for trigger button 9763 buttonImage: "", // URL for trigger button image 9764 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 9765 hideIfNoPrevNext: false, // True to hide next/previous month links 9766 // if not applicable, false to just disable them 9767 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 9768 gotoCurrent: false, // True if today link goes back to current selection instead 9769 changeMonth: false, // True if month can be selected directly, false if only prev/next 9770 changeYear: false, // True if year can be selected directly, false if only prev/next 9771 yearRange: "c-10:c+10", // Range of years to display in drop-down, 9772 // either relative to today's year (-nn:+nn), relative to currently displayed year 9773 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 9774 showOtherMonths: false, // True to show dates in other months, false to leave blank 9775 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 9776 showWeek: false, // True to show week of the year, false to not show it 9777 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 9778 // takes a Date and returns the number of the week for it 9779 shortYearCutoff: "+10", // Short year values < this are in the current century, 9780 // > this are in the previous century, 9781 // string value starting with "+" for current year + value 9782 minDate: null, // The earliest selectable date, or null for no limit 9783 maxDate: null, // The latest selectable date, or null for no limit 9784 duration: "fast", // Duration of display/closure 9785 beforeShowDay: null, // Function that takes a date and returns an array with 9786 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 9787 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 9788 beforeShow: null, // Function that takes an input field and 9789 // returns a set of custom settings for the date picker 9790 onSelect: null, // Define a callback function when a date is selected 9791 onChangeMonthYear: null, // Define a callback function when the month or year is changed 9792 onClose: null, // Define a callback function when the datepicker is closed 9793 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 9794 numberOfMonths: 1, // Number of months to show at a time 9795 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 9796 stepMonths: 1, // Number of months to step back/forward 9797 stepBigMonths: 12, // Number of months to step back/forward for the big links 9798 altField: "", // Selector for an alternate field to store selected dates into 9799 altFormat: "", // The date format to use for the alternate field 9800 constrainInput: true, // The input is constrained by the current date format 9801 showButtonPanel: false, // True to show button panel, false to not show it 9802 autoSize: false, // True to size the input for the date format, false to leave as is 9803 disabled: false // The initial disabled state 9804 }; 9805 $.extend( this._defaults, this.regional[ "" ] ); 9806 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 9807 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 9808 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 9809} 9810 9811$.extend( Datepicker.prototype, { 9812 9813 /* Class name added to elements to indicate already configured with a date picker. */ 9814 markerClassName: "hasDatepicker", 9815 9816 //Keep track of the maximum number of rows displayed (see #7043) 9817 maxRows: 4, 9818 9819 // TODO rename to "widget" when switching to widget factory 9820 _widgetDatepicker: function() { 9821 return this.dpDiv; 9822 }, 9823 9824 /* Override the default settings for all instances of the date picker. 9825 * @param settings object - the new settings to use as defaults (anonymous object) 9826 * @return the manager object 9827 */ 9828 setDefaults: function( settings ) { 9829 datepicker_extendRemove( this._defaults, settings || {} ); 9830 return this; 9831 }, 9832 9833 /* Attach the date picker to a jQuery selection. 9834 * @param target element - the target input field or division or span 9835 * @param settings object - the new settings to use for this date picker instance (anonymous) 9836 */ 9837 _attachDatepicker: function( target, settings ) { 9838 var nodeName, inline, inst; 9839 nodeName = target.nodeName.toLowerCase(); 9840 inline = ( nodeName === "div" || nodeName === "span" ); 9841 if ( !target.id ) { 9842 this.uuid += 1; 9843 target.id = "dp" + this.uuid; 9844 } 9845 inst = this._newInst( $( target ), inline ); 9846 inst.settings = $.extend( {}, settings || {} ); 9847 if ( nodeName === "input" ) { 9848 this._connectDatepicker( target, inst ); 9849 } else if ( inline ) { 9850 this._inlineDatepicker( target, inst ); 9851 } 9852 }, 9853 9854 /* Create a new instance object. */ 9855 _newInst: function( target, inline ) { 9856 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 9857 return { id: id, input: target, // associated target 9858 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 9859 drawMonth: 0, drawYear: 0, // month being drawn 9860 inline: inline, // is datepicker inline or not 9861 dpDiv: ( !inline ? this.dpDiv : // presentation div 9862 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 9863 }, 9864 9865 /* Attach the date picker to an input field. */ 9866 _connectDatepicker: function( target, inst ) { 9867 var input = $( target ); 9868 inst.append = $( [] ); 9869 inst.trigger = $( [] ); 9870 if ( input.hasClass( this.markerClassName ) ) { 9871 return; 9872 } 9873 this._attachments( input, inst ); 9874 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 9875 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 9876 this._autoSize( inst ); 9877 $.data( target, "datepicker", inst ); 9878 9879 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 9880 if ( inst.settings.disabled ) { 9881 this._disableDatepicker( target ); 9882 } 9883 }, 9884 9885 /* Make attachments based on settings. */ 9886 _attachments: function( input, inst ) { 9887 var showOn, buttonText, buttonImage, 9888 appendText = this._get( inst, "appendText" ), 9889 isRTL = this._get( inst, "isRTL" ); 9890 9891 if ( inst.append ) { 9892 inst.append.remove(); 9893 } 9894 if ( appendText ) { 9895 inst.append = $( "<span>" ) 9896 .addClass( this._appendClass ) 9897 .text( appendText ); 9898 input[ isRTL ? "before" : "after" ]( inst.append ); 9899 } 9900 9901 input.off( "focus", this._showDatepicker ); 9902 9903 if ( inst.trigger ) { 9904 inst.trigger.remove(); 9905 } 9906 9907 showOn = this._get( inst, "showOn" ); 9908 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 9909 input.on( "focus", this._showDatepicker ); 9910 } 9911 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 9912 buttonText = this._get( inst, "buttonText" ); 9913 buttonImage = this._get( inst, "buttonImage" ); 9914 9915 if ( this._get( inst, "buttonImageOnly" ) ) { 9916 inst.trigger = $( "<img>" ) 9917 .addClass( this._triggerClass ) 9918 .attr( { 9919 src: buttonImage, 9920 alt: buttonText, 9921 title: buttonText 9922 } ); 9923 } else { 9924 inst.trigger = $( "<button type='button'>" ) 9925 .addClass( this._triggerClass ); 9926 if ( buttonImage ) { 9927 inst.trigger.html( 9928 $( "<img>" ) 9929 .attr( { 9930 src: buttonImage, 9931 alt: buttonText, 9932 title: buttonText 9933 } ) 9934 ); 9935 } else { 9936 inst.trigger.text( buttonText ); 9937 } 9938 } 9939 9940 input[ isRTL ? "before" : "after" ]( inst.trigger ); 9941 inst.trigger.on( "click", function() { 9942 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 9943 $.datepicker._hideDatepicker(); 9944 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 9945 $.datepicker._hideDatepicker(); 9946 $.datepicker._showDatepicker( input[ 0 ] ); 9947 } else { 9948 $.datepicker._showDatepicker( input[ 0 ] ); 9949 } 9950 return false; 9951 } ); 9952 } 9953 }, 9954 9955 /* Apply the maximum length for the date format. */ 9956 _autoSize: function( inst ) { 9957 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 9958 var findMax, max, maxI, i, 9959 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 9960 dateFormat = this._get( inst, "dateFormat" ); 9961 9962 if ( dateFormat.match( /[DM]/ ) ) { 9963 findMax = function( names ) { 9964 max = 0; 9965 maxI = 0; 9966 for ( i = 0; i < names.length; i++ ) { 9967 if ( names[ i ].length > max ) { 9968 max = names[ i ].length; 9969 maxI = i; 9970 } 9971 } 9972 return maxI; 9973 }; 9974 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 9975 "monthNames" : "monthNamesShort" ) ) ) ); 9976 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 9977 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 9978 } 9979 inst.input.attr( "size", this._formatDate( inst, date ).length ); 9980 } 9981 }, 9982 9983 /* Attach an inline date picker to a div. */ 9984 _inlineDatepicker: function( target, inst ) { 9985 var divSpan = $( target ); 9986 if ( divSpan.hasClass( this.markerClassName ) ) { 9987 return; 9988 } 9989 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 9990 $.data( target, "datepicker", inst ); 9991 this._setDate( inst, this._getDefaultDate( inst ), true ); 9992 this._updateDatepicker( inst ); 9993 this._updateAlternate( inst ); 9994 9995 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 9996 if ( inst.settings.disabled ) { 9997 this._disableDatepicker( target ); 9998 } 9999 10000 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 10001 // https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 10002 inst.dpDiv.css( "display", "block" ); 10003 }, 10004 10005 /* Pop-up the date picker in a "dialog" box. 10006 * @param input element - ignored 10007 * @param date string or Date - the initial date to display 10008 * @param onSelect function - the function to call when a date is selected 10009 * @param settings object - update the dialog date picker instance's settings (anonymous object) 10010 * @param pos int[2] - coordinates for the dialog's position within the screen or 10011 * event - with x/y coordinates or 10012 * leave empty for default (screen centre) 10013 * @return the manager object 10014 */ 10015 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 10016 var id, browserWidth, browserHeight, scrollX, scrollY, 10017 inst = this._dialogInst; // internal instance 10018 10019 if ( !inst ) { 10020 this.uuid += 1; 10021 id = "dp" + this.uuid; 10022 this._dialogInput = $( "<input type='text' id='" + id + 10023 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 10024 this._dialogInput.on( "keydown", this._doKeyDown ); 10025 $( "body" ).append( this._dialogInput ); 10026 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 10027 inst.settings = {}; 10028 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 10029 } 10030 datepicker_extendRemove( inst.settings, settings || {} ); 10031 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 10032 this._dialogInput.val( date ); 10033 10034 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 10035 if ( !this._pos ) { 10036 browserWidth = document.documentElement.clientWidth; 10037 browserHeight = document.documentElement.clientHeight; 10038 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 10039 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 10040 this._pos = // should use actual width/height below 10041 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 10042 } 10043 10044 // Move input on screen for focus, but hidden behind dialog 10045 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 10046 inst.settings.onSelect = onSelect; 10047 this._inDialog = true; 10048 this.dpDiv.addClass( this._dialogClass ); 10049 this._showDatepicker( this._dialogInput[ 0 ] ); 10050 if ( $.blockUI ) { 10051 $.blockUI( this.dpDiv ); 10052 } 10053 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 10054 return this; 10055 }, 10056 10057 /* Detach a datepicker from its control. 10058 * @param target element - the target input field or division or span 10059 */ 10060 _destroyDatepicker: function( target ) { 10061 var nodeName, 10062 $target = $( target ), 10063 inst = $.data( target, "datepicker" ); 10064 10065 if ( !$target.hasClass( this.markerClassName ) ) { 10066 return; 10067 } 10068 10069 nodeName = target.nodeName.toLowerCase(); 10070 $.removeData( target, "datepicker" ); 10071 if ( nodeName === "input" ) { 10072 inst.append.remove(); 10073 inst.trigger.remove(); 10074 $target.removeClass( this.markerClassName ). 10075 off( "focus", this._showDatepicker ). 10076 off( "keydown", this._doKeyDown ). 10077 off( "keypress", this._doKeyPress ). 10078 off( "keyup", this._doKeyUp ); 10079 } else if ( nodeName === "div" || nodeName === "span" ) { 10080 $target.removeClass( this.markerClassName ).empty(); 10081 } 10082 10083 $.datepicker._hideDatepicker(); 10084 if ( datepicker_instActive === inst ) { 10085 datepicker_instActive = null; 10086 this._curInst = null; 10087 } 10088 }, 10089 10090 /* Enable the date picker to a jQuery selection. 10091 * @param target element - the target input field or division or span 10092 */ 10093 _enableDatepicker: function( target ) { 10094 var nodeName, inline, 10095 $target = $( target ), 10096 inst = $.data( target, "datepicker" ); 10097 10098 if ( !$target.hasClass( this.markerClassName ) ) { 10099 return; 10100 } 10101 10102 nodeName = target.nodeName.toLowerCase(); 10103 if ( nodeName === "input" ) { 10104 target.disabled = false; 10105 inst.trigger.filter( "button" ). 10106 each( function() { 10107 this.disabled = false; 10108 } ).end(). 10109 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 10110 } else if ( nodeName === "div" || nodeName === "span" ) { 10111 inline = $target.children( "." + this._inlineClass ); 10112 inline.children().removeClass( "ui-state-disabled" ); 10113 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 10114 prop( "disabled", false ); 10115 } 10116 this._disabledInputs = $.map( this._disabledInputs, 10117 10118 // Delete entry 10119 function( value ) { 10120 return ( value === target ? null : value ); 10121 } ); 10122 }, 10123 10124 /* Disable the date picker to a jQuery selection. 10125 * @param target element - the target input field or division or span 10126 */ 10127 _disableDatepicker: function( target ) { 10128 var nodeName, inline, 10129 $target = $( target ), 10130 inst = $.data( target, "datepicker" ); 10131 10132 if ( !$target.hasClass( this.markerClassName ) ) { 10133 return; 10134 } 10135 10136 nodeName = target.nodeName.toLowerCase(); 10137 if ( nodeName === "input" ) { 10138 target.disabled = true; 10139 inst.trigger.filter( "button" ). 10140 each( function() { 10141 this.disabled = true; 10142 } ).end(). 10143 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 10144 } else if ( nodeName === "div" || nodeName === "span" ) { 10145 inline = $target.children( "." + this._inlineClass ); 10146 inline.children().addClass( "ui-state-disabled" ); 10147 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 10148 prop( "disabled", true ); 10149 } 10150 this._disabledInputs = $.map( this._disabledInputs, 10151 10152 // Delete entry 10153 function( value ) { 10154 return ( value === target ? null : value ); 10155 } ); 10156 this._disabledInputs[ this._disabledInputs.length ] = target; 10157 }, 10158 10159 /* Is the first field in a jQuery collection disabled as a datepicker? 10160 * @param target element - the target input field or division or span 10161 * @return boolean - true if disabled, false if enabled 10162 */ 10163 _isDisabledDatepicker: function( target ) { 10164 if ( !target ) { 10165 return false; 10166 } 10167 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 10168 if ( this._disabledInputs[ i ] === target ) { 10169 return true; 10170 } 10171 } 10172 return false; 10173 }, 10174 10175 /* Retrieve the instance data for the target control. 10176 * @param target element - the target input field or division or span 10177 * @return object - the associated instance data 10178 * @throws error if a jQuery problem getting data 10179 */ 10180 _getInst: function( target ) { 10181 try { 10182 return $.data( target, "datepicker" ); 10183 } catch ( _err ) { 10184 throw "Missing instance data for this datepicker"; 10185 } 10186 }, 10187 10188 /* Update or retrieve the settings for a date picker attached to an input field or division. 10189 * @param target element - the target input field or division or span 10190 * @param name object - the new settings to update or 10191 * string - the name of the setting to change or retrieve, 10192 * when retrieving also "all" for all instance settings or 10193 * "defaults" for all global defaults 10194 * @param value any - the new value for the setting 10195 * (omit if above is an object or to retrieve a value) 10196 */ 10197 _optionDatepicker: function( target, name, value ) { 10198 var settings, date, minDate, maxDate, 10199 inst = this._getInst( target ); 10200 10201 if ( arguments.length === 2 && typeof name === "string" ) { 10202 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 10203 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 10204 this._get( inst, name ) ) : null ) ); 10205 } 10206 10207 settings = name || {}; 10208 if ( typeof name === "string" ) { 10209 settings = {}; 10210 settings[ name ] = value; 10211 } 10212 10213 if ( inst ) { 10214 if ( this._curInst === inst ) { 10215 this._hideDatepicker(); 10216 } 10217 10218 date = this._getDateDatepicker( target, true ); 10219 minDate = this._getMinMaxDate( inst, "min" ); 10220 maxDate = this._getMinMaxDate( inst, "max" ); 10221 datepicker_extendRemove( inst.settings, settings ); 10222 10223 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 10224 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 10225 inst.settings.minDate = this._formatDate( inst, minDate ); 10226 } 10227 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 10228 inst.settings.maxDate = this._formatDate( inst, maxDate ); 10229 } 10230 if ( "disabled" in settings ) { 10231 if ( settings.disabled ) { 10232 this._disableDatepicker( target ); 10233 } else { 10234 this._enableDatepicker( target ); 10235 } 10236 } 10237 this._attachments( $( target ), inst ); 10238 this._autoSize( inst ); 10239 this._setDate( inst, date ); 10240 this._updateAlternate( inst ); 10241 this._updateDatepicker( inst ); 10242 } 10243 }, 10244 10245 // Change method deprecated 10246 _changeDatepicker: function( target, name, value ) { 10247 this._optionDatepicker( target, name, value ); 10248 }, 10249 10250 /* Redraw the date picker attached to an input field or division. 10251 * @param target element - the target input field or division or span 10252 */ 10253 _refreshDatepicker: function( target ) { 10254 var inst = this._getInst( target ); 10255 if ( inst ) { 10256 this._updateDatepicker( inst ); 10257 } 10258 }, 10259 10260 /* Set the dates for a jQuery selection. 10261 * @param target element - the target input field or division or span 10262 * @param date Date - the new date 10263 */ 10264 _setDateDatepicker: function( target, date ) { 10265 var inst = this._getInst( target ); 10266 if ( inst ) { 10267 this._setDate( inst, date ); 10268 this._updateDatepicker( inst ); 10269 this._updateAlternate( inst ); 10270 } 10271 }, 10272 10273 /* Get the date(s) for the first entry in a jQuery selection. 10274 * @param target element - the target input field or division or span 10275 * @param noDefault boolean - true if no default date is to be used 10276 * @return Date - the current date 10277 */ 10278 _getDateDatepicker: function( target, noDefault ) { 10279 var inst = this._getInst( target ); 10280 if ( inst && !inst.inline ) { 10281 this._setDateFromField( inst, noDefault ); 10282 } 10283 return ( inst ? this._getDate( inst ) : null ); 10284 }, 10285 10286 /* Handle keystrokes. */ 10287 _doKeyDown: function( event ) { 10288 var onSelect, dateStr, sel, 10289 inst = $.datepicker._getInst( event.target ), 10290 handled = true, 10291 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 10292 10293 inst._keyEvent = true; 10294 if ( $.datepicker._datepickerShowing ) { 10295 switch ( event.keyCode ) { 10296 case 9: $.datepicker._hideDatepicker(); 10297 handled = false; 10298 break; // hide on tab out 10299 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 10300 $.datepicker._currentClass + ")", inst.dpDiv ); 10301 if ( sel[ 0 ] ) { 10302 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 10303 } 10304 10305 onSelect = $.datepicker._get( inst, "onSelect" ); 10306 if ( onSelect ) { 10307 dateStr = $.datepicker._formatDate( inst ); 10308 10309 // Trigger custom callback 10310 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 10311 } else { 10312 $.datepicker._hideDatepicker(); 10313 } 10314 10315 return false; // don't submit the form 10316 case 27: $.datepicker._hideDatepicker(); 10317 break; // hide on escape 10318 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10319 -$.datepicker._get( inst, "stepBigMonths" ) : 10320 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10321 break; // previous month/year on page up/+ ctrl 10322 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10323 +$.datepicker._get( inst, "stepBigMonths" ) : 10324 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10325 break; // next month/year on page down/+ ctrl 10326 case 35: if ( event.ctrlKey || event.metaKey ) { 10327 $.datepicker._clearDate( event.target ); 10328 } 10329 handled = event.ctrlKey || event.metaKey; 10330 break; // clear on ctrl or command +end 10331 case 36: if ( event.ctrlKey || event.metaKey ) { 10332 $.datepicker._gotoToday( event.target ); 10333 } 10334 handled = event.ctrlKey || event.metaKey; 10335 break; // current on ctrl or command +home 10336 case 37: if ( event.ctrlKey || event.metaKey ) { 10337 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 10338 } 10339 handled = event.ctrlKey || event.metaKey; 10340 10341 // -1 day on ctrl or command +left 10342 if ( event.originalEvent.altKey ) { 10343 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10344 -$.datepicker._get( inst, "stepBigMonths" ) : 10345 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10346 } 10347 10348 // next month/year on alt +left on Mac 10349 break; 10350 case 38: if ( event.ctrlKey || event.metaKey ) { 10351 $.datepicker._adjustDate( event.target, -7, "D" ); 10352 } 10353 handled = event.ctrlKey || event.metaKey; 10354 break; // -1 week on ctrl or command +up 10355 case 39: if ( event.ctrlKey || event.metaKey ) { 10356 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 10357 } 10358 handled = event.ctrlKey || event.metaKey; 10359 10360 // +1 day on ctrl or command +right 10361 if ( event.originalEvent.altKey ) { 10362 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10363 +$.datepicker._get( inst, "stepBigMonths" ) : 10364 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10365 } 10366 10367 // next month/year on alt +right 10368 break; 10369 case 40: if ( event.ctrlKey || event.metaKey ) { 10370 $.datepicker._adjustDate( event.target, +7, "D" ); 10371 } 10372 handled = event.ctrlKey || event.metaKey; 10373 break; // +1 week on ctrl or command +down 10374 default: handled = false; 10375 } 10376 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 10377 $.datepicker._showDatepicker( this ); 10378 } else { 10379 handled = false; 10380 } 10381 10382 if ( handled ) { 10383 event.preventDefault(); 10384 event.stopPropagation(); 10385 } 10386 }, 10387 10388 /* Filter entered characters - based on date format. */ 10389 _doKeyPress: function( event ) { 10390 var chars, chr, 10391 inst = $.datepicker._getInst( event.target ); 10392 10393 if ( $.datepicker._get( inst, "constrainInput" ) ) { 10394 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 10395 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 10396 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 10397 } 10398 }, 10399 10400 /* Synchronise manual entry and field/alternate field. */ 10401 _doKeyUp: function( event ) { 10402 var date, 10403 inst = $.datepicker._getInst( event.target ); 10404 10405 if ( inst.input.val() !== inst.lastVal ) { 10406 try { 10407 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 10408 ( inst.input ? inst.input.val() : null ), 10409 $.datepicker._getFormatConfig( inst ) ); 10410 10411 if ( date ) { // only if valid 10412 $.datepicker._setDateFromField( inst ); 10413 $.datepicker._updateAlternate( inst ); 10414 $.datepicker._updateDatepicker( inst ); 10415 } 10416 } catch ( _err ) { 10417 } 10418 } 10419 return true; 10420 }, 10421 10422 /* Pop-up the date picker for a given input field. 10423 * If false returned from beforeShow event handler do not show. 10424 * @param input element - the input field attached to the date picker or 10425 * event - if triggered by focus 10426 */ 10427 _showDatepicker: function( input ) { 10428 input = input.target || input; 10429 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 10430 input = $( "input", input.parentNode )[ 0 ]; 10431 } 10432 10433 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 10434 return; 10435 } 10436 10437 var inst, beforeShow, beforeShowSettings, isFixed, 10438 offset, showAnim, duration; 10439 10440 inst = $.datepicker._getInst( input ); 10441 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 10442 $.datepicker._curInst.dpDiv.stop( true, true ); 10443 if ( inst && $.datepicker._datepickerShowing ) { 10444 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 10445 } 10446 } 10447 10448 beforeShow = $.datepicker._get( inst, "beforeShow" ); 10449 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 10450 if ( beforeShowSettings === false ) { 10451 return; 10452 } 10453 datepicker_extendRemove( inst.settings, beforeShowSettings ); 10454 10455 inst.lastVal = null; 10456 $.datepicker._lastInput = input; 10457 $.datepicker._setDateFromField( inst ); 10458 10459 if ( $.datepicker._inDialog ) { // hide cursor 10460 input.value = ""; 10461 } 10462 if ( !$.datepicker._pos ) { // position below input 10463 $.datepicker._pos = $.datepicker._findPos( input ); 10464 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 10465 } 10466 10467 isFixed = false; 10468 $( input ).parents().each( function() { 10469 isFixed |= $( this ).css( "position" ) === "fixed"; 10470 return !isFixed; 10471 } ); 10472 10473 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 10474 $.datepicker._pos = null; 10475 10476 //to avoid flashes on Firefox 10477 inst.dpDiv.empty(); 10478 10479 // determine sizing offscreen 10480 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 10481 $.datepicker._updateDatepicker( inst ); 10482 10483 // fix width for dynamic number of date pickers 10484 // and adjust position before showing 10485 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 10486 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 10487 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 10488 left: offset.left + "px", top: offset.top + "px" } ); 10489 10490 if ( !inst.inline ) { 10491 showAnim = $.datepicker._get( inst, "showAnim" ); 10492 duration = $.datepicker._get( inst, "duration" ); 10493 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 10494 $.datepicker._datepickerShowing = true; 10495 10496 if ( $.effects && $.effects.effect[ showAnim ] ) { 10497 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 10498 } else { 10499 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 10500 } 10501 10502 if ( $.datepicker._shouldFocusInput( inst ) ) { 10503 inst.input.trigger( "focus" ); 10504 } 10505 10506 $.datepicker._curInst = inst; 10507 } 10508 }, 10509 10510 /* Generate the date picker content. */ 10511 _updateDatepicker: function( inst ) { 10512 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 10513 datepicker_instActive = inst; // for delegate hover events 10514 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 10515 this._attachHandlers( inst ); 10516 10517 var origyearshtml, 10518 numMonths = this._getNumberOfMonths( inst ), 10519 cols = numMonths[ 1 ], 10520 width = 17, 10521 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 10522 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 10523 10524 if ( activeCell.length > 0 ) { 10525 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 10526 } 10527 10528 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 10529 if ( cols > 1 ) { 10530 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 10531 } 10532 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 10533 "Class" ]( "ui-datepicker-multi" ); 10534 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 10535 "Class" ]( "ui-datepicker-rtl" ); 10536 10537 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 10538 inst.input.trigger( "focus" ); 10539 } 10540 10541 // Deffered render of the years select (to avoid flashes on Firefox) 10542 if ( inst.yearshtml ) { 10543 origyearshtml = inst.yearshtml; 10544 setTimeout( function() { 10545 10546 //assure that inst.yearshtml didn't change. 10547 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 10548 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 10549 } 10550 origyearshtml = inst.yearshtml = null; 10551 }, 0 ); 10552 } 10553 10554 if ( onUpdateDatepicker ) { 10555 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 10556 } 10557 }, 10558 10559 _shouldFocusInput: function( inst ) { 10560 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ); 10561 }, 10562 10563 /* Check positioning to remain on screen. */ 10564 _checkOffset: function( inst, offset, isFixed ) { 10565 var dpWidth = inst.dpDiv.outerWidth(), 10566 dpHeight = inst.dpDiv.outerHeight(), 10567 inputWidth = inst.input ? inst.input.outerWidth() : 0, 10568 inputHeight = inst.input ? inst.input.outerHeight() : 0, 10569 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 10570 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 10571 10572 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 10573 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 10574 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 10575 10576 // Now check if datepicker is showing outside window viewport - move to a better place if so. 10577 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 10578 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 10579 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 10580 Math.abs( dpHeight + inputHeight ) : 0 ); 10581 10582 return offset; 10583 }, 10584 10585 /* Find an object's position on the screen. */ 10586 _findPos: function( obj ) { 10587 var position, 10588 inst = this._getInst( obj ), 10589 isRTL = this._get( inst, "isRTL" ); 10590 10591 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 10592 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 10593 } 10594 10595 position = $( obj ).offset(); 10596 return [ position.left, position.top ]; 10597 }, 10598 10599 /* Hide the date picker from view. 10600 * @param input element - the input field attached to the date picker 10601 */ 10602 _hideDatepicker: function( input ) { 10603 var showAnim, duration, postProcess, onClose, 10604 inst = this._curInst; 10605 10606 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 10607 return; 10608 } 10609 10610 if ( this._datepickerShowing ) { 10611 showAnim = this._get( inst, "showAnim" ); 10612 duration = this._get( inst, "duration" ); 10613 postProcess = function() { 10614 $.datepicker._tidyDialog( inst ); 10615 }; 10616 10617 if ( $.effects && ( $.effects.effect[ showAnim ] ) ) { 10618 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 10619 } else { 10620 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 10621 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 10622 } 10623 10624 if ( !showAnim ) { 10625 postProcess(); 10626 } 10627 this._datepickerShowing = false; 10628 10629 onClose = this._get( inst, "onClose" ); 10630 if ( onClose ) { 10631 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 10632 } 10633 10634 this._lastInput = null; 10635 if ( this._inDialog ) { 10636 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 10637 if ( $.blockUI ) { 10638 $.unblockUI(); 10639 $( "body" ).append( this.dpDiv ); 10640 } 10641 } 10642 this._inDialog = false; 10643 } 10644 }, 10645 10646 /* Tidy up after a dialog display. */ 10647 _tidyDialog: function( inst ) { 10648 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 10649 }, 10650 10651 /* Close date picker if clicked elsewhere. */ 10652 _checkExternalClick: function( event ) { 10653 if ( !$.datepicker._curInst ) { 10654 return; 10655 } 10656 10657 var $target = $( event.target ), 10658 inst = $.datepicker._getInst( $target[ 0 ] ); 10659 10660 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 10661 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 10662 !$target.hasClass( $.datepicker.markerClassName ) && 10663 !$target.closest( "." + $.datepicker._triggerClass ).length && 10664 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 10665 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 10666 $.datepicker._hideDatepicker(); 10667 } 10668 }, 10669 10670 /* Adjust one of the date sub-fields. */ 10671 _adjustDate: function( id, offset, period ) { 10672 var target = $( id ), 10673 inst = this._getInst( target[ 0 ] ); 10674 10675 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 10676 return; 10677 } 10678 this._adjustInstDate( inst, offset, period ); 10679 this._updateDatepicker( inst ); 10680 }, 10681 10682 /* Action for current link. */ 10683 _gotoToday: function( id ) { 10684 var date, 10685 target = $( id ), 10686 inst = this._getInst( target[ 0 ] ); 10687 10688 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 10689 inst.selectedDay = inst.currentDay; 10690 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 10691 inst.drawYear = inst.selectedYear = inst.currentYear; 10692 } else { 10693 date = new Date(); 10694 inst.selectedDay = date.getDate(); 10695 inst.drawMonth = inst.selectedMonth = date.getMonth(); 10696 inst.drawYear = inst.selectedYear = date.getFullYear(); 10697 } 10698 this._notifyChange( inst ); 10699 this._adjustDate( target ); 10700 }, 10701 10702 /* Action for selecting a new month/year. */ 10703 _selectMonthYear: function( id, select, period ) { 10704 var target = $( id ), 10705 inst = this._getInst( target[ 0 ] ); 10706 10707 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 10708 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 10709 parseInt( select.options[ select.selectedIndex ].value, 10 ); 10710 10711 this._notifyChange( inst ); 10712 this._adjustDate( target ); 10713 }, 10714 10715 /* Action for selecting a day. */ 10716 _selectDay: function( id, month, year, td ) { 10717 var inst, 10718 target = $( id ); 10719 10720 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 10721 return; 10722 } 10723 10724 inst = this._getInst( target[ 0 ] ); 10725 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 10726 inst.selectedMonth = inst.currentMonth = month; 10727 inst.selectedYear = inst.currentYear = year; 10728 this._selectDate( id, this._formatDate( inst, 10729 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 10730 }, 10731 10732 /* Erase the input field and hide the date picker. */ 10733 _clearDate: function( id ) { 10734 var target = $( id ); 10735 this._selectDate( target, "" ); 10736 }, 10737 10738 /* Update the input field with the selected date. */ 10739 _selectDate: function( id, dateStr ) { 10740 var onSelect, 10741 target = $( id ), 10742 inst = this._getInst( target[ 0 ] ); 10743 10744 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 10745 if ( inst.input ) { 10746 inst.input.val( dateStr ); 10747 } 10748 this._updateAlternate( inst ); 10749 10750 onSelect = this._get( inst, "onSelect" ); 10751 if ( onSelect ) { 10752 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 10753 } else if ( inst.input ) { 10754 inst.input.trigger( "change" ); // fire the change event 10755 } 10756 10757 if ( inst.inline ) { 10758 this._updateDatepicker( inst ); 10759 } else { 10760 this._hideDatepicker(); 10761 this._lastInput = inst.input[ 0 ]; 10762 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 10763 inst.input.trigger( "focus" ); // restore focus 10764 } 10765 this._lastInput = null; 10766 } 10767 }, 10768 10769 /* Update any alternate field to synchronise with the main field. */ 10770 _updateAlternate: function( inst ) { 10771 var altFormat, date, dateStr, 10772 altField = this._get( inst, "altField" ); 10773 10774 if ( altField ) { // update alternate field too 10775 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 10776 date = this._getDate( inst ); 10777 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 10778 $( document ).find( altField ).val( dateStr ); 10779 } 10780 }, 10781 10782 /* Set as beforeShowDay function to prevent selection of weekends. 10783 * @param date Date - the date to customise 10784 * @return [boolean, string] - is this date selectable?, what is its CSS class? 10785 */ 10786 noWeekends: function( date ) { 10787 var day = date.getDay(); 10788 return [ ( day > 0 && day < 6 ), "" ]; 10789 }, 10790 10791 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 10792 * @param date Date - the date to get the week for 10793 * @return number - the number of the week within the year that contains this date 10794 */ 10795 iso8601Week: function( date ) { 10796 var time, 10797 checkDate = new Date( date.getTime() ); 10798 10799 // Find Thursday of this week starting on Monday 10800 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 10801 10802 time = checkDate.getTime(); 10803 checkDate.setMonth( 0 ); // Compare with Jan 1 10804 checkDate.setDate( 1 ); 10805 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 10806 }, 10807 10808 /* Parse a string value into a date object. 10809 * See formatDate below for the possible formats. 10810 * 10811 * @param format string - the expected format of the date 10812 * @param value string - the date in the above format 10813 * @param settings Object - attributes include: 10814 * shortYearCutoff number - the cutoff year for determining the century (optional) 10815 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 10816 * dayNames string[7] - names of the days from Sunday (optional) 10817 * monthNamesShort string[12] - abbreviated names of the months (optional) 10818 * monthNames string[12] - names of the months (optional) 10819 * @return Date - the extracted date value or null if value is blank 10820 */ 10821 parseDate: function( format, value, settings ) { 10822 if ( format == null || value == null ) { 10823 throw "Invalid arguments"; 10824 } 10825 10826 value = ( typeof value === "object" ? value.toString() : value + "" ); 10827 if ( value === "" ) { 10828 return null; 10829 } 10830 10831 var iFormat, dim, extra, 10832 iValue = 0, 10833 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 10834 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,431 bytes, lines 10834-11024
10834: 10835 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 10836 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 10837 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 10838 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 10839 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 10840 year = -1, 10841 month = -1, 10842 day = -1, 10843 doy = -1, 10844 literal = false, 10845 date, 10846 10847 // Check whether a format character is doubled 10848 lookAhead = function( match ) { 10849 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 10850 if ( matches ) { 10851 iFormat++; 10852 } 10853 return matches; 10854 }, 10855 10856 // Extract a number from the string value 10857 getNumber = function( match ) { 10858 var isDoubled = lookAhead( match ), 10859 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 10860 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 10861 minSize = ( match === "y" ? size : 1 ), 10862 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 10863 num = value.substring( iValue ).match( digits ); 10864 if ( !num ) { 10865 throw "Missing number at position " + iValue; 10866 } 10867 iValue += num[ 0 ].length; 10868 return parseInt( num[ 0 ], 10 ); 10869 }, 10870 10871 // Extract a name from the string value and convert to an index 10872 getName = function( match, shortNames, longNames ) { 10873 var index = -1, 10874 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 10875 return [ [ k, v ] ]; 10876 } ).sort( function( a, b ) { 10877 return -( a[ 1 ].length - b[ 1 ].length ); 10878 } ); 10879 10880 $.each( names, function( i, pair ) { 10881 var name = pair[ 1 ]; 10882 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 10883 index = pair[ 0 ]; 10884 iValue += name.length; 10885 return false; 10886 } 10887 } ); 10888 if ( index !== -1 ) { 10889 return index + 1; 10890 } else { 10891 throw "Unknown name at position " + iValue; 10892 } 10893 }, 10894 10895 // Confirm that a literal character matches the string value 10896 checkLiteral = function() { 10897 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 10898 throw "Unexpected literal at position " + iValue; 10899 } 10900 iValue++; 10901 }; 10902 10903 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 10904 if ( literal ) { 10905 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 10906 literal = false; 10907 } else { 10908 checkLiteral(); 10909 } 10910 } else { 10911 switch ( format.charAt( iFormat ) ) { 10912 case "d": 10913 day = getNumber( "d" ); 10914 break; 10915 case "D": 10916 getName( "D", dayNamesShort, dayNames ); 10917 break; 10918 case "o": 10919 doy = getNumber( "o" ); 10920 break; 10921 case "m": 10922 month = getNumber( "m" ); 10923 break; 10924 case "M": 10925 month = getName( "M", monthNamesShort, monthNames ); 10926 break; 10927 case "y": 10928 year = getNumber( "y" ); 10929 break; 10930 case "@": 10931 date = new Date( getNumber( "@" ) ); 10932 year = date.getFullYear(); 10933 month = date.getMonth() + 1; 10934 day = date.getDate(); 10935 break; 10936 case "!": 10937 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 10938 year = date.getFullYear(); 10939 month = date.getMonth() + 1; 10940 day = date.getDate(); 10941 break; 10942 case "'": 10943 if ( lookAhead( "'" ) ) { 10944 checkLiteral(); 10945 } else { 10946 literal = true; 10947 } 10948 break; 10949 default: 10950 checkLiteral(); 10951 } 10952 } 10953 } 10954 10955 if ( iValue < value.length ) { 10956 extra = value.substr( iValue ); 10957 if ( !/^\s+/.test( extra ) ) { 10958 throw "Extra/unparsed characters found in date: " + extra; 10959 } 10960 } 10961 10962 if ( year === -1 ) { 10963 year = new Date().getFullYear(); 10964 } else if ( year < 100 ) { 10965 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 10966 ( year <= shortYearCutoff ? 0 : -100 ); 10967 } 10968 10969 if ( doy > -1 ) { 10970 month = 1; 10971 day = doy; 10972 do { 10973 dim = this._getDaysInMonth( year, month - 1 ); 10974 if ( day <= dim ) { 10975 break; 10976 } 10977 month++; 10978 day -= dim; 10979 } while ( true ); 10980 } 10981 10982 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 10983 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 10984 throw "Invalid date"; // E.g. 31/02/00 10985 } 10986 return date; 10987 }, 10988 10989 /* Standard date formats. */ 10990 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 10991 COOKIE: "D, dd M yy", 10992 ISO_8601: "yy-mm-dd", 10993 RFC_822: "D, d M y", 10994 RFC_850: "DD, dd-M-y", 10995 RFC_1036: "D, d M y", 10996 RFC_1123: "D, d M yy", 10997 RFC_2822: "D, d M yy", 10998 RSS: "D, d M y", // RFC 822 10999 TICKS: "!", 11000 TIMESTAMP: "@", 11001 W3C: "yy-mm-dd", // ISO 8601 11002 11003 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 11004 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 11005 11006 /* Format a date object into a string value. 11007 * The format can be combinations of the following: 11008 * d - day of month (no leading zero) 11009 * dd - day of month (two digit) 11010 * o - day of year (no leading zeros) 11011 * oo - day of year (three digit) 11012 * D - day name short 11013 * DD - day name long 11014 * m - month of year (no leading zero) 11015 * mm - month of year (two digit) 11016 * M - month name short 11017 * MM - month name long 11018 * y - year (two digit) 11019 * yy - year (four digit) 11020 * @ - Unix timestamp (ms since 01/01/1970) 11021 * ! - Windows ticks (100ns since 01/01/0001) 11022 * "..." - literal text 11023 * '' - single quote 11024 *
vendor: 6,198 bytes, lines 11025-11224
11025 * @param format string - the desired format of the date 11026 * @param date Date - the date value to format 11027 * @param settings Object - attributes include: 11028 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11029 * dayNames string[7] - names of the days from Sunday (optional) 11030 * monthNamesShort string[12] - abbreviated names of the months (optional) 11031 * monthNames string[12] - names of the months (optional) 11032 * @return string - the date in the above format 11033 */ 11034 formatDate: function( format, date, settings ) { 11035 if ( !date ) { 11036 return ""; 11037 } 11038 11039 var iFormat, 11040 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 11041 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 11042 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 11043 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 11044 11045 // Check whether a format character is doubled 11046 lookAhead = function( match ) { 11047 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 11048 if ( matches ) { 11049 iFormat++; 11050 } 11051 return matches; 11052 }, 11053 11054 // Format a number, with leading zero if necessary 11055 formatNumber = function( match, value, len ) { 11056 var num = "" + value; 11057 if ( lookAhead( match ) ) { 11058 while ( num.length < len ) { 11059 num = "0" + num; 11060 } 11061 } 11062 return num; 11063 }, 11064 11065 // Format a name, short or long as requested 11066 formatName = function( match, value, shortNames, longNames ) { 11067 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 11068 }, 11069 output = "", 11070 literal = false; 11071 11072 if ( date ) { 11073 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 11074 if ( literal ) { 11075 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 11076 literal = false; 11077 } else { 11078 output += format.charAt( iFormat ); 11079 } 11080 } else { 11081 switch ( format.charAt( iFormat ) ) { 11082 case "d": 11083 output += formatNumber( "d", date.getDate(), 2 ); 11084 break; 11085 case "D": 11086 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 11087 break; 11088 case "o": 11089 output += formatNumber( "o", 11090 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 11091 break; 11092 case "m": 11093 output += formatNumber( "m", date.getMonth() + 1, 2 ); 11094 break; 11095 case "M": 11096 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 11097 break; 11098 case "y": 11099 output += ( lookAhead( "y" ) ? date.getFullYear() : 11100 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 11101 break; 11102 case "@": 11103 output += date.getTime(); 11104 break; 11105 case "!": 11106 output += date.getTime() * 10000 + this._ticksTo1970; 11107 break; 11108 case "'": 11109 if ( lookAhead( "'" ) ) { 11110 output += "'"; 11111 } else { 11112 literal = true; 11113 } 11114 break; 11115 default: 11116 output += format.charAt( iFormat ); 11117 } 11118 } 11119 } 11120 } 11121 return output; 11122 }, 11123 11124 /* Extract all possible characters from the date format. */ 11125 _possibleChars: function( format ) { 11126 var iFormat, 11127 chars = "", 11128 literal = false, 11129 11130 // Check whether a format character is doubled 11131 lookAhead = function( match ) { 11132 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 11133 if ( matches ) { 11134 iFormat++; 11135 } 11136 return matches; 11137 }; 11138 11139 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 11140 if ( literal ) { 11141 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 11142 literal = false; 11143 } else { 11144 chars += format.charAt( iFormat ); 11145 } 11146 } else { 11147 switch ( format.charAt( iFormat ) ) { 11148 case "d": case "m": case "y": case "@": 11149 chars += "0123456789"; 11150 break; 11151 case "D": case "M": 11152 return null; // Accept anything 11153 case "'": 11154 if ( lookAhead( "'" ) ) { 11155 chars += "'"; 11156 } else { 11157 literal = true; 11158 } 11159 break; 11160 default: 11161 chars += format.charAt( iFormat ); 11162 } 11163 } 11164 } 11165 return chars; 11166 }, 11167 11168 /* Get a setting value, defaulting if necessary. */ 11169 _get: function( inst, name ) { 11170 return inst.settings[ name ] !== undefined ? 11171 inst.settings[ name ] : this._defaults[ name ]; 11172 }, 11173 11174 /* Parse existing date and initialise date picker. */ 11175 _setDateFromField: function( inst, noDefault ) { 11176 if ( inst.input.val() === inst.lastVal ) { 11177 return; 11178 } 11179 11180 var dateFormat = this._get( inst, "dateFormat" ), 11181 dates = inst.lastVal = inst.input ? inst.input.val() : null, 11182 defaultDate = this._getDefaultDate( inst ), 11183 date = defaultDate, 11184 settings = this._getFormatConfig( inst ); 11185 11186 try { 11187 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 11188 } catch ( _err ) { 11189 dates = ( noDefault ? "" : dates ); 11190 } 11191 inst.selectedDay = date.getDate(); 11192 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11193 inst.drawYear = inst.selectedYear = date.getFullYear(); 11194 inst.currentDay = ( dates ? date.getDate() : 0 ); 11195 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 11196 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 11197 this._adjustInstDate( inst ); 11198 }, 11199 11200 /* Retrieve the default date shown on opening. */ 11201 _getDefaultDate: function( inst ) { 11202 return this._restrictMinMax( inst, 11203 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 11204 }, 11205 11206 /* A date may be specified as an exact value or a relative one. */ 11207 _determineDate: function( inst, date, defaultDate ) { 11208 var offsetNumeric = function( offset ) { 11209 var date = new Date(); 11210 date.setDate( date.getDate() + offset ); 11211 return date; 11212 }, 11213 offsetString = function( offset ) { 11214 try { 11215 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 11216 offset, $.datepicker._getFormatConfig( inst ) ); 11217 } catch ( _e ) { 11218 11219 // Ignore 11220 } 11221 11222 var date = ( offset.toLowerCase().match( /^c/ ) ? 11223 $.datepicker._getDate( inst ) : null ) || new Date(), 11224 year = date.getFullYear(),
vendor: 5,359 bytes, lines 11225-11363
11225 month = date.getMonth(), 11226 day = date.getDate(), 11227 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 11228 matches = pattern.exec( offset ); 11229 11230 while ( matches ) { 11231 switch ( matches[ 2 ] || "d" ) { 11232 case "d" : case "D" : 11233 day += parseInt( matches[ 1 ], 10 ); break; 11234 case "w" : case "W" : 11235 day += parseInt( matches[ 1 ], 10 ) * 7; break; 11236 case "m" : case "M" : 11237 month += parseInt( matches[ 1 ], 10 ); 11238 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11239 break; 11240 case "y": case "Y" : 11241 year += parseInt( matches[ 1 ], 10 ); 11242 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11243 break; 11244 } 11245 matches = pattern.exec( offset ); 11246 } 11247 return new Date( year, month, day ); 11248 }, 11249 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 11250 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 11251 11252 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 11253 if ( newDate ) { 11254 newDate.setHours( 0 ); 11255 newDate.setMinutes( 0 ); 11256 newDate.setSeconds( 0 ); 11257 newDate.setMilliseconds( 0 ); 11258 } 11259 return this._daylightSavingAdjust( newDate ); 11260 }, 11261 11262 /* Handle switch to/from daylight saving. 11263 * Hours may be non-zero on daylight saving cut-over: 11264 * > 12 when midnight changeover, but then cannot generate 11265 * midnight datetime, so jump to 1AM, otherwise reset. 11266 * @param date (Date) the date to check 11267 * @return (Date) the corrected date 11268 */ 11269 _daylightSavingAdjust: function( date ) { 11270 if ( !date ) { 11271 return null; 11272 } 11273 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 11274 return date; 11275 }, 11276 11277 /* Set the date(s) directly. */ 11278 _setDate: function( inst, date, noChange ) { 11279 var clear = !date, 11280 origMonth = inst.selectedMonth, 11281 origYear = inst.selectedYear, 11282 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 11283 11284 inst.selectedDay = inst.currentDay = newDate.getDate(); 11285 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 11286 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 11287 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 11288 this._notifyChange( inst ); 11289 } 11290 this._adjustInstDate( inst ); 11291 if ( inst.input ) { 11292 inst.input.val( clear ? "" : this._formatDate( inst ) ); 11293 } 11294 }, 11295 11296 /* Retrieve the date(s) directly. */ 11297 _getDate: function( inst ) { 11298 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 11299 this._daylightSavingAdjust( new Date( 11300 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11301 return startDate; 11302 }, 11303 11304 /* Attach the onxxx handlers. These are declared statically so 11305 * they work with static code transformers like Caja. 11306 */ 11307 _attachHandlers: function( inst ) { 11308 var stepMonths = this._get( inst, "stepMonths" ), 11309 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 11310 inst.dpDiv.find( "[data-handler]" ).map( function() { 11311 var handler = { 11312 prev: function() { 11313 $.datepicker._adjustDate( id, -stepMonths, "M" ); 11314 }, 11315 next: function() { 11316 $.datepicker._adjustDate( id, +stepMonths, "M" ); 11317 }, 11318 hide: function() { 11319 $.datepicker._hideDatepicker(); 11320 }, 11321 today: function() { 11322 $.datepicker._gotoToday( id ); 11323 }, 11324 selectDay: function() { 11325 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 11326 return false; 11327 }, 11328 selectMonth: function() { 11329 $.datepicker._selectMonthYear( id, this, "M" ); 11330 return false; 11331 }, 11332 selectYear: function() { 11333 $.datepicker._selectMonthYear( id, this, "Y" ); 11334 return false; 11335 } 11336 }; 11337 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 11338 } ); 11339 }, 11340 11341 /* Generate the HTML for the current state of the date picker. */ 11342 _generateHTML: function( inst ) { 11343 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 11344 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 11345 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 11346 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 11347 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 11348 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 11349 tempDate = new Date(), 11350 today = this._daylightSavingAdjust( 11351 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 11352 isRTL = this._get( inst, "isRTL" ), 11353 showButtonPanel = this._get( inst, "showButtonPanel" ), 11354 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 11355 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 11356 numMonths = this._getNumberOfMonths( inst ), 11357 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 11358 stepMonths = this._get( inst, "stepMonths" ), 11359 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 11360 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 11361 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 11362 minDate = this._getMinMaxDate( inst, "min" ), 11363 maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,264 bytes, lines 11364-11879
11364 drawMonth = inst.drawMonth - showCurrentAtPos, 11365 drawYear = inst.drawYear; 11366 11367 if ( drawMonth < 0 ) { 11368 drawMonth += 12; 11369 drawYear--; 11370 } 11371 if ( maxDate ) { 11372 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 11373 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 11374 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 11375 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 11376 drawMonth--; 11377 if ( drawMonth < 0 ) { 11378 drawMonth = 11; 11379 drawYear--; 11380 } 11381 } 11382 } 11383 inst.drawMonth = drawMonth; 11384 inst.drawYear = drawYear; 11385 11386 prevText = this._get( inst, "prevText" ); 11387 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 11388 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 11389 this._getFormatConfig( inst ) ) ); 11390 11391 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 11392 prev = $( "<a>" ) 11393 .attr( { 11394 "class": "ui-datepicker-prev ui-corner-all", 11395 "data-handler": "prev", 11396 "data-event": "click", 11397 title: prevText 11398 } ) 11399 .append( 11400 $( "<span>" ) 11401 .addClass( "ui-icon ui-icon-circle-triangle-" + 11402 ( isRTL ? "e" : "w" ) ) 11403 .text( prevText ) 11404 )[ 0 ].outerHTML; 11405 } else if ( hideIfNoPrevNext ) { 11406 prev = ""; 11407 } else { 11408 prev = $( "<a>" ) 11409 .attr( { 11410 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 11411 title: prevText 11412 } ) 11413 .append( 11414 $( "<span>" ) 11415 .addClass( "ui-icon ui-icon-circle-triangle-" + 11416 ( isRTL ? "e" : "w" ) ) 11417 .text( prevText ) 11418 )[ 0 ].outerHTML; 11419 } 11420 11421 nextText = this._get( inst, "nextText" ); 11422 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 11423 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 11424 this._getFormatConfig( inst ) ) ); 11425 11426 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 11427 next = $( "<a>" ) 11428 .attr( { 11429 "class": "ui-datepicker-next ui-corner-all", 11430 "data-handler": "next", 11431 "data-event": "click", 11432 title: nextText 11433 } ) 11434 .append( 11435 $( "<span>" ) 11436 .addClass( "ui-icon ui-icon-circle-triangle-" + 11437 ( isRTL ? "w" : "e" ) ) 11438 .text( nextText ) 11439 )[ 0 ].outerHTML; 11440 } else if ( hideIfNoPrevNext ) { 11441 next = ""; 11442 } else { 11443 next = $( "<a>" ) 11444 .attr( { 11445 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 11446 title: nextText 11447 } ) 11448 .append( 11449 $( "<span>" ) 11450 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 11451 ( isRTL ? "w" : "e" ) ) 11452 .text( nextText ) 11453 )[ 0 ].outerHTML; 11454 } 11455 11456 currentText = this._get( inst, "currentText" ); 11457 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 11458 currentText = ( !navigationAsDateFormat ? currentText : 11459 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 11460 11461 controls = ""; 11462 if ( !inst.inline ) { 11463 controls = $( "<button>" ) 11464 .attr( { 11465 type: "button", 11466 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 11467 "data-handler": "hide", 11468 "data-event": "click" 11469 } ) 11470 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 11471 } 11472 11473 buttonPanel = ""; 11474 if ( showButtonPanel ) { 11475 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 11476 .append( isRTL ? controls : "" ) 11477 .append( this._isInRange( inst, gotoDate ) ? 11478 $( "<button>" ) 11479 .attr( { 11480 type: "button", 11481 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 11482 "data-handler": "today", 11483 "data-event": "click" 11484 } ) 11485 .text( currentText ) : 11486 "" ) 11487 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 11488 } 11489 11490 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 11491 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 11492 11493 showWeek = this._get( inst, "showWeek" ); 11494 dayNames = this._get( inst, "dayNames" ); 11495 dayNamesMin = this._get( inst, "dayNamesMin" ); 11496 monthNames = this._get( inst, "monthNames" ); 11497 monthNamesShort = this._get( inst, "monthNamesShort" ); 11498 beforeShowDay = this._get( inst, "beforeShowDay" ); 11499 showOtherMonths = this._get( inst, "showOtherMonths" ); 11500 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 11501 defaultDate = this._getDefaultDate( inst ); 11502 html = ""; 11503 11504 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 11505 group = ""; 11506 this.maxRows = 4; 11507 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 11508 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 11509 cornerClass = " ui-corner-all"; 11510 calender = ""; 11511 if ( isMultiMonth ) { 11512 calender += "<div class='ui-datepicker-group"; 11513 if ( numMonths[ 1 ] > 1 ) { 11514 switch ( col ) { 11515 case 0: calender += " ui-datepicker-group-first"; 11516 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 11517 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 11518 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 11519 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 11520 } 11521 } 11522 calender += "'>"; 11523 } 11524 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 11525 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 11526 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 11527 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 11528 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 11529 "</div><table class='ui-datepicker-calendar'><thead>" + 11530 "<tr>"; 11531 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 11532 for ( dow = 0; dow < 7; dow++ ) { // days of the week 11533 day = ( dow + firstDay ) % 7; 11534 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 11535 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 11536 } 11537 calender += thead + "</tr></thead><tbody>"; 11538 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 11539 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 11540 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 11541 } 11542 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 11543 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 11544 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 11545 this.maxRows = numRows; 11546 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 11547 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 11548 calender += "<tr>"; 11549 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 11550 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 11551 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 11552 daySettings = ( beforeShowDay ? 11553 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 11554 otherMonth = ( printDate.getMonth() !== drawMonth ); 11555 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 11556 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 11557 tbody += "<td class='" + 11558 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 11559 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 11560 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 11561 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 11562 11563 // or defaultDate is current printedDate and defaultDate is selectedDate 11564 " " + this._dayOverClass : "" ) + // highlight selected day 11565 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 11566 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 11567 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 11568 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 11569 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 11570 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 11571 ( otherMonth && !showOtherMonths ? " " : // display for other months 11572 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 11573 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 11574 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 11575 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 11576 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 11577 "' data-date='" + printDate.getDate() + // store date as data 11578 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 11579 printDate.setDate( printDate.getDate() + 1 ); 11580 printDate = this._daylightSavingAdjust( printDate ); 11581 } 11582 calender += tbody + "</tr>"; 11583 } 11584 drawMonth++; 11585 if ( drawMonth > 11 ) { 11586 drawMonth = 0; 11587 drawYear++; 11588 } 11589 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 11590 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 11591 group += calender; 11592 } 11593 html += group; 11594 } 11595 html += buttonPanel; 11596 inst._keyEvent = false; 11597 return html; 11598 }, 11599 11600 /* Generate the month and year header. */ 11601 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 11602 secondary, monthNames, monthNamesShort ) { 11603 11604 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 11605 changeMonth = this._get( inst, "changeMonth" ), 11606 changeYear = this._get( inst, "changeYear" ), 11607 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 11608 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 11609 selectYearLabel = this._get( inst, "selectYearLabel" ), 11610 html = "<div class='ui-datepicker-title'>", 11611 monthHtml = ""; 11612 11613 // Month selection 11614 if ( secondary || !changeMonth ) { 11615 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 11616 } else { 11617 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 11618 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 11619 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 11620 for ( month = 0; month < 12; month++ ) { 11621 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 11622 monthHtml += "<option value='" + month + "'" + 11623 ( month === drawMonth ? " selected='selected'" : "" ) + 11624 ">" + monthNamesShort[ month ] + "</option>"; 11625 } 11626 } 11627 monthHtml += "</select>"; 11628 } 11629 11630 if ( !showMonthAfterYear ) { 11631 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 11632 } 11633 11634 // Year selection 11635 if ( !inst.yearshtml ) { 11636 inst.yearshtml = ""; 11637 if ( secondary || !changeYear ) { 11638 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 11639 } else { 11640 11641 // determine range of years to display 11642 years = this._get( inst, "yearRange" ).split( ":" ); 11643 thisYear = new Date().getFullYear(); 11644 determineYear = function( value ) { 11645 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 11646 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 11647 parseInt( value, 10 ) ) ); 11648 return ( isNaN( year ) ? thisYear : year ); 11649 }; 11650 year = determineYear( years[ 0 ] ); 11651 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 11652 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 11653 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 11654 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 11655 for ( ; year <= endYear; year++ ) { 11656 inst.yearshtml += "<option value='" + year + "'" + 11657 ( year === drawYear ? " selected='selected'" : "" ) + 11658 ">" + year + "</option>"; 11659 } 11660 inst.yearshtml += "</select>"; 11661 11662 html += inst.yearshtml; 11663 inst.yearshtml = null; 11664 } 11665 } 11666 11667 html += this._get( inst, "yearSuffix" ); 11668 if ( showMonthAfterYear ) { 11669 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 11670 } 11671 html += "</div>"; // Close datepicker_header 11672 return html; 11673 }, 11674 11675 /* Adjust one of the date sub-fields. */ 11676 _adjustInstDate: function( inst, offset, period ) { 11677 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 11678 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 11679 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 11680 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 11681 11682 inst.selectedDay = date.getDate(); 11683 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11684 inst.drawYear = inst.selectedYear = date.getFullYear(); 11685 if ( period === "M" || period === "Y" ) { 11686 this._notifyChange( inst ); 11687 } 11688 }, 11689 11690 /* Ensure a date is within any min/max bounds. */ 11691 _restrictMinMax: function( inst, date ) { 11692 var minDate = this._getMinMaxDate( inst, "min" ), 11693 maxDate = this._getMinMaxDate( inst, "max" ), 11694 newDate = ( minDate && date < minDate ? minDate : date ); 11695 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 11696 }, 11697 11698 /* Notify change of month/year. */ 11699 _notifyChange: function( inst ) { 11700 var onChange = this._get( inst, "onChangeMonthYear" ); 11701 if ( onChange ) { 11702 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 11703 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 11704 } 11705 }, 11706 11707 /* Determine the number of months to show. */ 11708 _getNumberOfMonths: function( inst ) { 11709 var numMonths = this._get( inst, "numberOfMonths" ); 11710 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 11711 }, 11712 11713 /* Determine the current maximum date - ensure no time components are set. */ 11714 _getMinMaxDate: function( inst, minMax ) { 11715 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 11716 }, 11717 11718 /* Find the number of days in a given month. */ 11719 _getDaysInMonth: function( year, month ) { 11720 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 11721 }, 11722 11723 /* Find the day of the week of the first of a month. */ 11724 _getFirstDayOfMonth: function( year, month ) { 11725 return new Date( year, month, 1 ).getDay(); 11726 }, 11727 11728 /* Determines if we should allow a "next/prev" month display change. */ 11729 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 11730 var numMonths = this._getNumberOfMonths( inst ), 11731 date = this._daylightSavingAdjust( new Date( curYear, 11732 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 11733 11734 if ( offset < 0 ) { 11735 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 11736 } 11737 return this._isInRange( inst, date ); 11738 }, 11739 11740 /* Is the given date in the accepted range? */ 11741 _isInRange: function( inst, date ) { 11742 var yearSplit, currentYear, 11743 minDate = this._getMinMaxDate( inst, "min" ), 11744 maxDate = this._getMinMaxDate( inst, "max" ), 11745 minYear = null, 11746 maxYear = null, 11747 years = this._get( inst, "yearRange" ); 11748 if ( years ) { 11749 yearSplit = years.split( ":" ); 11750 currentYear = new Date().getFullYear(); 11751 minYear = parseInt( yearSplit[ 0 ], 10 ); 11752 maxYear = parseInt( yearSplit[ 1 ], 10 ); 11753 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 11754 minYear += currentYear; 11755 } 11756 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 11757 maxYear += currentYear; 11758 } 11759 } 11760 11761 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 11762 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 11763 ( !minYear || date.getFullYear() >= minYear ) && 11764 ( !maxYear || date.getFullYear() <= maxYear ) ); 11765 }, 11766 11767 /* Provide the configuration settings for formatting/parsing. */ 11768 _getFormatConfig: function( inst ) { 11769 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 11770 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 11771 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 11772 return { shortYearCutoff: shortYearCutoff, 11773 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 11774 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 11775 }, 11776 11777 /* Format the given date for display. */ 11778 _formatDate: function( inst, day, month, year ) { 11779 if ( !day ) { 11780 inst.currentDay = inst.selectedDay; 11781 inst.currentMonth = inst.selectedMonth; 11782 inst.currentYear = inst.selectedYear; 11783 } 11784 var date = ( day ? ( typeof day === "object" ? day : 11785 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 11786 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11787 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 11788 } 11789} ); 11790 11791/* 11792 * Bind hover events for datepicker elements. 11793 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 11794 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 11795 */ 11796function datepicker_bindHover( dpDiv ) { 11797 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 11798 return dpDiv.on( "mouseout", selector, function() { 11799 $( this ).removeClass( "ui-state-hover" ); 11800 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11801 $( this ).removeClass( "ui-datepicker-prev-hover" ); 11802 } 11803 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11804 $( this ).removeClass( "ui-datepicker-next-hover" ); 11805 } 11806 } ) 11807 .on( "mouseover", selector, datepicker_handleMouseover ); 11808} 11809 11810function datepicker_handleMouseover() { 11811 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 11812 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 11813 $( this ).addClass( "ui-state-hover" ); 11814 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11815 $( this ).addClass( "ui-datepicker-prev-hover" ); 11816 } 11817 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11818 $( this ).addClass( "ui-datepicker-next-hover" ); 11819 } 11820 } 11821} 11822 11823/* jQuery extend now ignores nulls! */ 11824function datepicker_extendRemove( target, props ) { 11825 $.extend( target, props ); 11826 for ( var name in props ) { 11827 if ( props[ name ] == null ) { 11828 target[ name ] = props[ name ]; 11829 } 11830 } 11831 return target; 11832} 11833 11834/* Invoke the datepicker functionality. 11835 @param options string - a command, optionally followed by additional parameters or 11836 Object - settings for attaching new datepicker functionality 11837 @return jQuery object */ 11838$.fn.datepicker = function( options ) { 11839 11840 /* Verify an empty collection wasn't passed - Fixes #6976 */ 11841 if ( !this.length ) { 11842 return this; 11843 } 11844 11845 /* Initialise the date picker. */ 11846 if ( !$.datepicker.initialized ) { 11847 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 11848 $.datepicker.initialized = true; 11849 } 11850 11851 /* Append datepicker main container to body if not exist. */ 11852 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 11853 $( "body" ).append( $.datepicker.dpDiv ); 11854 } 11855 11856 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 11857 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 11858 return $.datepicker[ "_" + options + "Datepicker" ]. 11859 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11860 } 11861 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 11862 return $.datepicker[ "_" + options + "Datepicker" ]. 11863 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11864 } 11865 return this.each( function() { 11866 if ( typeof options === "string" ) { 11867 $.datepicker[ "_" + options + "Datepicker" ] 11868 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 11869 } else { 11870 $.datepicker._attachDatepicker( this, options ); 11871 } 11872 } ); 11873}; 11874 11875$.datepicker = new Datepicker(); // singleton instance 11876$.datepicker.initialized = false; 11877$.datepicker.uuid = new Date().getTime(); 11878$.datepicker.version = "1.14.2"; 11879
vendor: 4,962 bytes, lines 11880-12106
11880var widgetsDatepicker = $.datepicker; 11881 11882 11883/*! 11884 * jQuery UI Dialog 1.14.2 11885 * https://jqueryui.com 11886 * 11887 * Copyright OpenJS Foundation and other contributors 11888 * Released under the MIT license. 11889 * https://jquery.org/license 11890 */ 11891 11892//>>label: Dialog 11893//>>group: Widgets 11894//>>description: Displays customizable dialog windows. 11895//>>docs: https://api.jqueryui.com/dialog/ 11896//>>demos: https://jqueryui.com/dialog/ 11897//>>css.structure: ../../themes/base/core.css 11898//>>css.structure: ../../themes/base/dialog.css 11899//>>css.theme: ../../themes/base/theme.css 11900 11901 11902$.widget( "ui.dialog", { 11903 version: "1.14.2", 11904 options: { 11905 appendTo: "body", 11906 autoOpen: true, 11907 buttons: [], 11908 classes: { 11909 "ui-dialog": "ui-corner-all", 11910 "ui-dialog-titlebar": "ui-corner-all" 11911 }, 11912 closeOnEscape: true, 11913 closeText: "Close", 11914 draggable: true, 11915 hide: null, 11916 height: "auto", 11917 maxHeight: null, 11918 maxWidth: null, 11919 minHeight: 150, 11920 minWidth: 150, 11921 modal: false, 11922 position: { 11923 my: "center", 11924 at: "center", 11925 of: window, 11926 collision: "fit", 11927 11928 // Ensure the titlebar is always visible 11929 using: function( pos ) { 11930 var topOffset = $( this ).css( pos ).offset().top; 11931 if ( topOffset < 0 ) { 11932 $( this ).css( "top", pos.top - topOffset ); 11933 } 11934 } 11935 }, 11936 resizable: true, 11937 show: null, 11938 title: null, 11939 uiDialogTitleHeadingLevel: 0, 11940 width: 300, 11941 11942 // Callbacks 11943 beforeClose: null, 11944 close: null, 11945 drag: null, 11946 dragStart: null, 11947 dragStop: null, 11948 focus: null, 11949 open: null, 11950 resize: null, 11951 resizeStart: null, 11952 resizeStop: null 11953 }, 11954 11955 sizeRelatedOptions: { 11956 buttons: true, 11957 height: true, 11958 maxHeight: true, 11959 maxWidth: true, 11960 minHeight: true, 11961 minWidth: true, 11962 width: true 11963 }, 11964 11965 resizableRelatedOptions: { 11966 maxHeight: true, 11967 maxWidth: true, 11968 minHeight: true, 11969 minWidth: true 11970 }, 11971 11972 _create: function() { 11973 this.originalCss = { 11974 display: this.element[ 0 ].style.display, 11975 width: this.element[ 0 ].style.width, 11976 minHeight: this.element[ 0 ].style.minHeight, 11977 maxHeight: this.element[ 0 ].style.maxHeight, 11978 height: this.element[ 0 ].style.height 11979 }; 11980 this.originalPosition = { 11981 parent: this.element.parent(), 11982 index: this.element.parent().children().index( this.element ) 11983 }; 11984 this.originalTitle = this.element.attr( "title" ); 11985 if ( this.options.title == null && this.originalTitle != null ) { 11986 this.options.title = this.originalTitle; 11987 } 11988 11989 // Dialogs can't be disabled 11990 if ( this.options.disabled ) { 11991 this.options.disabled = false; 11992 } 11993 11994 this._createWrapper(); 11995 11996 this.element 11997 .show() 11998 .removeAttr( "title" ) 11999 .appendTo( this.uiDialog ); 12000 12001 this._addClass( "ui-dialog-content", "ui-widget-content" ); 12002 12003 this._createTitlebar(); 12004 this._createButtonPane(); 12005 12006 if ( this.options.draggable && $.fn.draggable ) { 12007 this._makeDraggable(); 12008 } 12009 if ( this.options.resizable && $.fn.resizable ) { 12010 this._makeResizable(); 12011 } 12012 12013 this._isOpen = false; 12014 12015 this._trackFocus(); 12016 }, 12017 12018 _init: function() { 12019 if ( this.options.autoOpen ) { 12020 this.open(); 12021 } 12022 }, 12023 12024 _appendTo: function() { 12025 var element = this.options.appendTo; 12026 if ( element && ( element.jquery || element.nodeType ) ) { 12027 return $( element ); 12028 } 12029 return this.document.find( element || "body" ).eq( 0 ); 12030 }, 12031 12032 _destroy: function() { 12033 var next, 12034 originalPosition = this.originalPosition; 12035 12036 this._untrackInstance(); 12037 this._destroyOverlay(); 12038 12039 this.element 12040 .removeUniqueId() 12041 .css( this.originalCss ) 12042 12043 // Without detaching first, the following becomes really slow 12044 .detach(); 12045 12046 this.uiDialog.remove(); 12047 12048 if ( this.originalTitle ) { 12049 this.element.attr( "title", this.originalTitle ); 12050 } 12051 12052 next = originalPosition.parent.children().eq( originalPosition.index ); 12053 12054 // Don't try to place the dialog next to itself (#8613) 12055 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 12056 next.before( this.element ); 12057 } else { 12058 originalPosition.parent.append( this.element ); 12059 } 12060 }, 12061 12062 widget: function() { 12063 return this.uiDialog; 12064 }, 12065 12066 disable: $.noop, 12067 enable: $.noop, 12068 12069 close: function( event ) { 12070 var that = this; 12071 12072 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 12073 return; 12074 } 12075 12076 this._isOpen = false; 12077 this._focusedElement = null; 12078 this._destroyOverlay(); 12079 this._untrackInstance(); 12080 12081 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 12082 12083 // Hiding a focused element doesn't trigger blur in WebKit 12084 // so in case we have nothing to focus on, explicitly blur the active element 12085 // https://bugs.webkit.org/show_bug.cgi?id=47182 12086 $( this.document[ 0 ].activeElement ).trigger( "blur" ); 12087 } 12088 12089 this._hide( this.uiDialog, this.options.hide, function() { 12090 that._trigger( "close", event ); 12091 } ); 12092 }, 12093 12094 isOpen: function() { 12095 console.log('TESTING') 12096 return this._isOpen; 12097 }, 12098 12099 moveToTop: function() { 12100 this._moveToTop(); 12101 }, 12102 12103 _moveToTop: function( event, silent ) { 12104 var moved = false, 12105 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 12106 console.log('TESTING:', $(this))
vendor: 18,047 bytes, lines 12106-12804
12106 12107 return +$( this ).css( "z-index" ); 12108 } ).get(), 12109 zIndexMax = Math.max.apply( null, zIndices ); 12110 12111 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 12112 this.uiDialog.css( "z-index", zIndexMax + 1 ); 12113 moved = true; 12114 } 12115 12116 if ( moved && !silent ) { 12117 this._trigger( "focus", event ); 12118 } 12119 return moved; 12120 }, 12121 12122 open: function() { 12123 var that = this; 12124 if ( this._isOpen ) { 12125 if ( this._moveToTop() ) { 12126 this._focusTabbable(); 12127 } 12128 return; 12129 } 12130 12131 this._isOpen = true; 12132 this.opener = $( this.document[ 0 ].activeElement ); 12133 12134 this._size(); 12135 this._position(); 12136 this._createOverlay(); 12137 this._moveToTop( null, true ); 12138 12139 // Ensure the overlay is moved to the top with the dialog, but only when 12140 // opening. The overlay shouldn't move after the dialog is open so that 12141 // modeless dialogs opened after the modal dialog stack properly. 12142 if ( this.overlay ) { 12143 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 12144 } 12145 12146 this._show( this.uiDialog, this.options.show, function() { 12147 that._focusTabbable(); 12148 that._trigger( "focus" ); 12149 } ); 12150 12151 // Track the dialog immediately upon opening in case a focus event 12152 // somehow occurs outside of the dialog before an element inside the 12153 // dialog is focused (#10152) 12154 this._makeFocusTarget(); 12155 12156 this._trigger( "open" ); 12157 }, 12158 12159 _focusTabbable: function() { 12160 12161 // Set focus to the first match: 12162 // 1. An element that was focused previously 12163 // 2. First element inside the dialog matching [autofocus] 12164 // 3. Tabbable element inside the content element 12165 // 4. Tabbable element inside the buttonpane 12166 // 5. The close button 12167 // 6. The dialog itself 12168 var hasFocus = this._focusedElement; 12169 if ( !hasFocus ) { 12170 hasFocus = this.element.find( "[autofocus]" ); 12171 } 12172 if ( !hasFocus.length ) { 12173 hasFocus = this.element.find( ":tabbable" ); 12174 } 12175 if ( !hasFocus.length ) { 12176 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 12177 } 12178 if ( !hasFocus.length ) { 12179 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 12180 } 12181 if ( !hasFocus.length ) { 12182 hasFocus = this.uiDialog; 12183 } 12184 hasFocus.eq( 0 ).trigger( "focus" ); 12185 }, 12186 12187 _restoreTabbableFocus: function() { 12188 var activeElement = this.document[ 0 ].activeElement, 12189 isActive = this.uiDialog[ 0 ] === activeElement || 12190 $.contains( this.uiDialog[ 0 ], activeElement ); 12191 if ( !isActive ) { 12192 this._focusTabbable(); 12193 } 12194 }, 12195 12196 _keepFocus: function( event ) { 12197 event.preventDefault(); 12198 this._restoreTabbableFocus(); 12199 }, 12200 12201 _createWrapper: function() { 12202 this.uiDialog = $( "<div>" ) 12203 .hide() 12204 .attr( { 12205 12206 // Setting tabIndex makes the div focusable 12207 tabIndex: -1, 12208 role: "dialog", 12209 "aria-modal": this.options.modal ? "true" : null 12210 } ) 12211 .appendTo( this._appendTo() ); 12212 12213 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 12214 this._on( this.uiDialog, { 12215 keydown: function( event ) { 12216 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 12217 event.keyCode === $.ui.keyCode.ESCAPE ) { 12218 event.preventDefault(); 12219 this.close( event ); 12220 return; 12221 } 12222 12223 // Prevent tabbing out of dialogs 12224 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 12225 return; 12226 } 12227 var tabbables = this.uiDialog.find( ":tabbable" ), 12228 first = tabbables.first(), 12229 last = tabbables.last(); 12230 12231 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 12232 !event.shiftKey ) { 12233 this._delay( function() { 12234 first.trigger( "focus" ); 12235 } ); 12236 event.preventDefault(); 12237 } else if ( ( event.target === first[ 0 ] || 12238 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 12239 this._delay( function() { 12240 last.trigger( "focus" ); 12241 } ); 12242 event.preventDefault(); 12243 } 12244 }, 12245 mousedown: function( event ) { 12246 if ( this._moveToTop( event ) ) { 12247 this._focusTabbable(); 12248 } 12249 } 12250 } ); 12251 12252 // We assume that any existing aria-describedby attribute means 12253 // that the dialog content is marked up properly 12254 // otherwise we brute force the content as the description 12255 if ( !this.element.find( "[aria-describedby]" ).length ) { 12256 this.uiDialog.attr( { 12257 "aria-describedby": this.element.uniqueId().attr( "id" ) 12258 } ); 12259 } 12260 }, 12261 12262 _createTitlebar: function() { 12263 var uiDialogTitle; 12264 12265 this.uiDialogTitlebar = $( "<div>" ); 12266 this._addClass( this.uiDialogTitlebar, 12267 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 12268 this._on( this.uiDialogTitlebar, { 12269 mousedown: function( event ) { 12270 12271 // Don't prevent click on close button (#8838) 12272 // Focusing a dialog that is partially scrolled out of view 12273 // causes the browser to scroll it into view, preventing the click event 12274 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 12275 12276 // Dialog isn't getting focus when dragging (#8063) 12277 this.uiDialog.trigger( "focus" ); 12278 } 12279 } 12280 } ); 12281 12282 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 12283 .button( { 12284 label: $( "<a>" ).text( this.options.closeText ).html(), 12285 icon: "ui-icon-closethick", 12286 showLabel: false 12287 } ) 12288 .appendTo( this.uiDialogTitlebar ); 12289 12290 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 12291 this._on( this.uiDialogTitlebarClose, { 12292 click: function( event ) { 12293 event.preventDefault(); 12294 this.close( event ); 12295 } 12296 } ); 12297 12298 var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) && 12299 this.options.uiDialogTitleHeadingLevel > 0 && 12300 this.options.uiDialogTitleHeadingLevel <= 6 ? 12301 "h" + this.options.uiDialogTitleHeadingLevel : "span"; 12302 12303 uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" ) 12304 .uniqueId().prependTo( this.uiDialogTitlebar ); 12305 this._addClass( uiDialogTitle, "ui-dialog-title" ); 12306 this._title( uiDialogTitle ); 12307 12308 this.uiDialogTitlebar.prependTo( this.uiDialog ); 12309 12310 this.uiDialog.attr( { 12311 "aria-labelledby": uiDialogTitle.attr( "id" ) 12312 } ); 12313 }, 12314 12315 _title: function( title ) { 12316 if ( this.options.title ) { 12317 title.text( this.options.title ); 12318 } else { 12319 title.html( " " ); 12320 } 12321 }, 12322 12323 _createButtonPane: function() { 12324 this.uiDialogButtonPane = $( "<div>" ); 12325 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 12326 "ui-widget-content ui-helper-clearfix" ); 12327 12328 this.uiButtonSet = $( "<div>" ) 12329 .appendTo( this.uiDialogButtonPane ); 12330 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 12331 12332 this._createButtons(); 12333 }, 12334 12335 _createButtons: function() { 12336 var that = this, 12337 buttons = this.options.buttons; 12338 12339 // If we already have a button pane, remove it 12340 this.uiDialogButtonPane.remove(); 12341 this.uiButtonSet.empty(); 12342 12343 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { 12344 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 12345 return; 12346 } 12347 12348 $.each( buttons, function( name, props ) { 12349 var click, buttonOptions; 12350 props = typeof props === "function" ? 12351 { click: props, text: name } : 12352 props; 12353 12354 // Default to a non-submitting button 12355 props = $.extend( { type: "button" }, props ); 12356 12357 // Change the context for the click callback to be the main element 12358 click = props.click; 12359 buttonOptions = { 12360 icon: props.icon, 12361 iconPosition: props.iconPosition, 12362 showLabel: props.showLabel, 12363 12364 // Deprecated options 12365 icons: props.icons, 12366 text: props.text 12367 }; 12368 12369 delete props.click; 12370 delete props.icon; 12371 delete props.iconPosition; 12372 delete props.showLabel; 12373 12374 // Deprecated options 12375 delete props.icons; 12376 if ( typeof props.text === "boolean" ) { 12377 delete props.text; 12378 } 12379 12380 $( "<button></button>", props ) 12381 .button( buttonOptions ) 12382 .appendTo( that.uiButtonSet ) 12383 .on( "click", function() { 12384 click.apply( that.element[ 0 ], arguments ); 12385 } ); 12386 } ); 12387 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 12388 this.uiDialogButtonPane.appendTo( this.uiDialog ); 12389 }, 12390 12391 _makeDraggable: function() { 12392 var that = this, 12393 options = this.options; 12394 12395 function filteredUi( ui ) { 12396 return { 12397 position: ui.position, 12398 offset: ui.offset 12399 }; 12400 } 12401 12402 this.uiDialog.draggable( { 12403 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 12404 handle: ".ui-dialog-titlebar", 12405 containment: "document", 12406 start: function( event, ui ) { 12407 that._addClass( $( this ), "ui-dialog-dragging" ); 12408 that._blockFrames(); 12409 that._trigger( "dragStart", event, filteredUi( ui ) ); 12410 }, 12411 drag: function( event, ui ) { 12412 that._trigger( "drag", event, filteredUi( ui ) ); 12413 }, 12414 stop: function( event, ui ) { 12415 var left = ui.offset.left - that.document.scrollLeft(), 12416 top = ui.offset.top - that.document.scrollTop(); 12417 12418 options.position = { 12419 my: "left top", 12420 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12421 "top" + ( top >= 0 ? "+" : "" ) + top, 12422 of: that.window 12423 }; 12424 that._removeClass( $( this ), "ui-dialog-dragging" ); 12425 that._unblockFrames(); 12426 that._trigger( "dragStop", event, filteredUi( ui ) ); 12427 } 12428 } ); 12429 }, 12430 12431 _makeResizable: function() { 12432 var that = this, 12433 options = this.options, 12434 handles = options.resizable, 12435 12436 // .ui-resizable has position: relative defined in the stylesheet 12437 // but dialogs have to use absolute or fixed positioning 12438 position = this.uiDialog.css( "position" ), 12439 resizeHandles = typeof handles === "string" ? 12440 handles : 12441 "n,e,s,w,se,sw,ne,nw"; 12442 12443 function filteredUi( ui ) { 12444 return { 12445 originalPosition: ui.originalPosition, 12446 originalSize: ui.originalSize, 12447 position: ui.position, 12448 size: ui.size 12449 }; 12450 } 12451 12452 this.uiDialog.resizable( { 12453 cancel: ".ui-dialog-content", 12454 containment: "document", 12455 alsoResize: this.element, 12456 maxWidth: options.maxWidth, 12457 maxHeight: options.maxHeight, 12458 minWidth: options.minWidth, 12459 minHeight: this._minHeight(), 12460 handles: resizeHandles, 12461 start: function( event, ui ) { 12462 that._addClass( $( this ), "ui-dialog-resizing" ); 12463 that._blockFrames(); 12464 that._trigger( "resizeStart", event, filteredUi( ui ) ); 12465 }, 12466 resize: function( event, ui ) { 12467 that._trigger( "resize", event, filteredUi( ui ) ); 12468 }, 12469 stop: function( event, ui ) { 12470 var offset = that.uiDialog.offset(), 12471 left = offset.left - that.document.scrollLeft(), 12472 top = offset.top - that.document.scrollTop(); 12473 12474 options.height = that.uiDialog.height(); 12475 options.width = that.uiDialog.width(); 12476 options.position = { 12477 my: "left top", 12478 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12479 "top" + ( top >= 0 ? "+" : "" ) + top, 12480 of: that.window 12481 }; 12482 that._removeClass( $( this ), "ui-dialog-resizing" ); 12483 that._unblockFrames(); 12484 that._trigger( "resizeStop", event, filteredUi( ui ) ); 12485 } 12486 } ) 12487 .css( "position", position ); 12488 }, 12489 12490 _trackFocus: function() { 12491 this._on( this.widget(), { 12492 focusin: function( event ) { 12493 this._makeFocusTarget(); 12494 this._focusedElement = $( event.target ); 12495 } 12496 } ); 12497 }, 12498 12499 _makeFocusTarget: function() { 12500 this._untrackInstance(); 12501 this._trackingInstances().unshift( this ); 12502 }, 12503 12504 _untrackInstance: function() { 12505 var instances = this._trackingInstances(), 12506 exists = $.inArray( this, instances ); 12507 if ( exists !== -1 ) { 12508 instances.splice( exists, 1 ); 12509 } 12510 }, 12511 12512 _trackingInstances: function() { 12513 var instances = this.document.data( "ui-dialog-instances" ); 12514 if ( !instances ) { 12515 instances = []; 12516 this.document.data( "ui-dialog-instances", instances ); 12517 } 12518 return instances; 12519 }, 12520 12521 _minHeight: function() { 12522 var options = this.options; 12523 12524 return options.height === "auto" ? 12525 options.minHeight : 12526 Math.min( options.minHeight, options.height ); 12527 }, 12528 12529 _position: function() { 12530 12531 // Need to show the dialog to get the actual offset in the position plugin 12532 var isVisible = this.uiDialog.is( ":visible" ); 12533 if ( !isVisible ) { 12534 this.uiDialog.show(); 12535 } 12536 this.uiDialog.position( this.options.position ); 12537 if ( !isVisible ) { 12538 this.uiDialog.hide(); 12539 } 12540 }, 12541 12542 _setOptions: function( options ) { 12543 var that = this, 12544 resize = false, 12545 resizableOptions = {}; 12546 12547 $.each( options, function( key, value ) { 12548 that._setOption( key, value ); 12549 12550 if ( key in that.sizeRelatedOptions ) { 12551 resize = true; 12552 } 12553 if ( key in that.resizableRelatedOptions ) { 12554 resizableOptions[ key ] = value; 12555 } 12556 } ); 12557 12558 if ( resize ) { 12559 this._size(); 12560 this._position(); 12561 } 12562 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 12563 this.uiDialog.resizable( "option", resizableOptions ); 12564 } 12565 }, 12566 12567 _setOption: function( key, value ) { 12568 var isDraggable, isResizable, 12569 uiDialog = this.uiDialog; 12570 12571 if ( key === "disabled" ) { 12572 return; 12573 } 12574 12575 this._super( key, value ); 12576 12577 if ( key === "appendTo" ) { 12578 this.uiDialog.appendTo( this._appendTo() ); 12579 } 12580 12581 if ( key === "buttons" ) { 12582 this._createButtons(); 12583 } 12584 12585 if ( key === "closeText" ) { 12586 this.uiDialogTitlebarClose.button( { 12587 12588 // Ensure that we always pass a string 12589 label: $( "<a>" ).text( "" + this.options.closeText ).html() 12590 } ); 12591 } 12592 12593 if ( key === "draggable" ) { 12594 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 12595 if ( isDraggable && !value ) { 12596 uiDialog.draggable( "destroy" ); 12597 } 12598 12599 if ( !isDraggable && value ) { 12600 this._makeDraggable(); 12601 } 12602 } 12603 12604 if ( key === "position" ) { 12605 this._position(); 12606 } 12607 12608 if ( key === "resizable" ) { 12609 12610 // currently resizable, becoming non-resizable 12611 isResizable = uiDialog.is( ":data(ui-resizable)" ); 12612 if ( isResizable && !value ) { 12613 uiDialog.resizable( "destroy" ); 12614 } 12615 12616 // Currently resizable, changing handles 12617 if ( isResizable && typeof value === "string" ) { 12618 uiDialog.resizable( "option", "handles", value ); 12619 } 12620 12621 // Currently non-resizable, becoming resizable 12622 if ( !isResizable && value !== false ) { 12623 this._makeResizable(); 12624 } 12625 } 12626 12627 if ( key === "title" ) { 12628 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 12629 } 12630 12631 if ( key === "modal" ) { 12632 uiDialog.attr( "aria-modal", value ? "true" : null ); 12633 } 12634 }, 12635 12636 _size: function() { 12637 12638 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 12639 // divs will both have width and height set, so we need to reset them 12640 var nonContentHeight, minContentHeight, maxContentHeight, 12641 options = this.options; 12642 12643 // Reset content sizing 12644 this.element.show().css( { 12645 width: "auto", 12646 minHeight: 0, 12647 maxHeight: "none", 12648 height: 0 12649 } ); 12650 12651 if ( options.minWidth > options.width ) { 12652 options.width = options.minWidth; 12653 } 12654 12655 // Reset wrapper sizing 12656 // determine the height of all the non-content elements 12657 nonContentHeight = this.uiDialog.css( { 12658 height: "auto", 12659 width: options.width 12660 } ) 12661 .outerHeight(); 12662 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 12663 maxContentHeight = typeof options.maxHeight === "number" ? 12664 Math.max( 0, options.maxHeight - nonContentHeight ) : 12665 "none"; 12666 12667 if ( options.height === "auto" ) { 12668 this.element.css( { 12669 minHeight: minContentHeight, 12670 maxHeight: maxContentHeight, 12671 height: "auto" 12672 } ); 12673 } else { 12674 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 12675 } 12676 12677 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 12678 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 12679 } 12680 }, 12681 12682 _blockFrames: function() { 12683 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 12684 var iframe = $( this ); 12685 12686 return $( "<div>" ) 12687 .css( { 12688 position: "absolute", 12689 width: iframe.outerWidth(), 12690 height: iframe.outerHeight() 12691 } ) 12692 .appendTo( iframe.parent() ) 12693 .offset( iframe.offset() )[ 0 ]; 12694 } ); 12695 }, 12696 12697 _unblockFrames: function() { 12698 if ( this.iframeBlocks ) { 12699 this.iframeBlocks.remove(); 12700 delete this.iframeBlocks; 12701 } 12702 }, 12703 12704 _allowInteraction: function( event ) { 12705 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 12706 return true; 12707 } 12708 12709 // TODO: Remove hack when datepicker implements 12710 // the .ui-front logic (#8989) 12711 return !!$( event.target ).closest( ".ui-datepicker" ).length; 12712 }, 12713 12714 _createOverlay: function() { 12715 if ( !this.options.modal ) { 12716 return; 12717 } 12718 12719 // We use a delay in case the overlay is created from an 12720 // event that we're going to be cancelling (#2804) 12721 var isOpening = true; 12722 this._delay( function() { 12723 isOpening = false; 12724 } ); 12725 12726 if ( !this.document.data( "ui-dialog-overlays" ) ) { 12727 12728 // Prevent use of anchors and inputs 12729 // This doesn't use `_on()` because it is a shared event handler 12730 // across all open modal dialogs. 12731 this.document.on( "focusin.ui-dialog", function( event ) { 12732 if ( isOpening ) { 12733 return; 12734 } 12735 12736 var instance = this._trackingInstances()[ 0 ]; 12737 if ( !instance._allowInteraction( event ) ) { 12738 event.preventDefault(); 12739 instance._focusTabbable(); 12740 } 12741 }.bind( this ) ); 12742 } 12743 12744 this.overlay = $( "<div>" ) 12745 .appendTo( this._appendTo() ); 12746 12747 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 12748 this._on( this.overlay, { 12749 mousedown: "_keepFocus" 12750 } ); 12751 this.document.data( "ui-dialog-overlays", 12752 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 12753 }, 12754 12755 _destroyOverlay: function() { 12756 if ( !this.options.modal ) { 12757 return; 12758 } 12759 12760 if ( this.overlay ) { 12761 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 12762 12763 if ( !overlays ) { 12764 this.document.off( "focusin.ui-dialog" ); 12765 this.document.removeData( "ui-dialog-overlays" ); 12766 } else { 12767 this.document.data( "ui-dialog-overlays", overlays ); 12768 } 12769 12770 this.overlay.remove(); 12771 this.overlay = null; 12772 } 12773 } 12774} ); 12775 12776// DEPRECATED 12777// TODO: switch return back to widget declaration at top of file when this is removed 12778if ( $.uiBackCompat === true ) { 12779 12780 // Backcompat for dialogClass option 12781 $.widget( "ui.dialog", $.ui.dialog, { 12782 options: { 12783 dialogClass: "" 12784 }, 12785 _createWrapper: function() { 12786 this._super(); 12787 this.uiDialog.addClass( this.options.dialogClass ); 12788 }, 12789 _setOption: function( key, value ) { 12790 if ( key === "dialogClass" ) { 12791 this.uiDialog 12792 .removeClass( this.options.dialogClass ) 12793 .addClass( value ); 12794 } 12795 this._superApply( arguments ); 12796 } 12797 } ); 12798} 12799 12800var widgetsDialog = $.ui.dialog; 12801 12802 12803/*! 12804 * jQuery UI
vendor: 3,870 bytes, lines 12804-12960
12804Progressbar 1.14.2 12805 * https://jqueryui.com 12806 * 12807 * Copyright OpenJS Foundation and other contributors 12808 * Released under the MIT license. 12809 * https://jquery.org/license 12810 */ 12811 12812//>>label: Progressbar 12813//>>group: Widgets 12814//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 12815//>>docs: https://api.jqueryui.com/progressbar/ 12816//>>demos: https://jqueryui.com/progressbar/ 12817//>>css.structure: ../../themes/base/core.css 12818//>>css.structure: ../../themes/base/progressbar.css 12819//>>css.theme: ../../themes/base/theme.css 12820 12821 12822var widgetsProgressbar = $.widget( "ui.progressbar", { 12823 version: "1.14.2", 12824 options: { 12825 classes: { 12826 "ui-progressbar": "ui-corner-all", 12827 "ui-progressbar-value": "ui-corner-left", 12828 "ui-progressbar-complete": "ui-corner-right" 12829 }, 12830 max: 100, 12831 value: 0, 12832 12833 change: null, 12834 complete: null 12835 }, 12836 12837 min: 0, 12838 12839 _create: function() { 12840 12841 // Constrain initial value 12842 this.oldValue = this.options.value = this._constrainedValue(); 12843 12844 this.element.attr( { 12845 12846 // Only set static values; aria-valuenow and aria-valuemax are 12847 // set inside _refreshValue() 12848 role: "progressbar", 12849 "aria-valuemin": this.min 12850 } ); 12851 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 12852 12853 this.valueDiv = $( "<div>" ).appendTo( this.element ); 12854 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 12855 this._refreshValue(); 12856 }, 12857 12858 _destroy: function() { 12859 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 12860 12861 this.valueDiv.remove(); 12862 }, 12863 12864 value: function( newValue ) { 12865 if ( newValue === undefined ) { 12866 return this.options.value; 12867 } 12868 12869 this.options.value = this._constrainedValue( newValue ); 12870 this._refreshValue(); 12871 }, 12872 12873 _constrainedValue: function( newValue ) { 12874 if ( newValue === undefined ) { 12875 newValue = this.options.value; 12876 } 12877 12878 this.indeterminate = newValue === false; 12879 12880 // Sanitize value 12881 if ( typeof newValue !== "number" ) { 12882 newValue = 0; 12883 } 12884 12885 return this.indeterminate ? false : 12886 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12887 }, 12888 12889 _setOptions: function( options ) { 12890 12891 // Ensure "value" option is set after other values (like max) 12892 var value = options.value; 12893 delete options.value; 12894 12895 this._super( options ); 12896 12897 this.options.value = this._constrainedValue( value ); 12898 this._refreshValue(); 12899 }, 12900 12901 _setOption: function( key, value ) { 12902 if ( key === "max" ) { 12903 12904 // Don't allow a max less than min 12905 value = Math.max( this.min, value ); 12906 } 12907 this._super( key, value ); 12908 }, 12909 12910 _setOptionDisabled: function( value ) { 12911 this._super( value ); 12912 12913 this.element.attr( "aria-disabled", value ); 12914 this._toggleClass( null, "ui-state-disabled", !!value ); 12915 }, 12916 12917 _percentage: function() { 12918 return this.indeterminate ? 12919 100 : 12920 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12921 }, 12922 12923 _refreshValue: function() { 12924 var value = this.options.value, 12925 percentage = this._percentage(); 12926 12927 this.valueDiv 12928 .toggle( this.indeterminate || value > this.min ) 12929 .width( percentage.toFixed( 0 ) + "%" ); 12930 12931 this 12932 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 12933 value === this.options.max ) 12934 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 12935 12936 if ( this.indeterminate ) { 12937 this.element.removeAttr( "aria-valuenow" ); 12938 if ( !this.overlayDiv ) { 12939 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 12940 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 12941 } 12942 } else { 12943 this.element.attr( { 12944 "aria-valuemax": this.options.max, 12945 "aria-valuenow": value 12946 } ); 12947 if ( this.overlayDiv ) { 12948 this.overlayDiv.remove(); 12949 this.overlayDiv = null; 12950 } 12951 } 12952 12953 if ( this.oldValue !== value ) { 12954 this.oldValue = value; 12955 this._trigger( "change" ); 12956 } 12957 if ( value === this.options.max ) { 12958 this._trigger( "complete" ); 12959 } 12960 }
vendor: 19,361 bytes, lines 12960-13768
12960 12961} ); 12962 12963 12964/*! 12965 * jQuery UI Selectmenu 1.14.2 12966 * https://jqueryui.com 12967 * 12968 * Copyright OpenJS Foundation and other contributors 12969 * Released under the MIT license. 12970 * https://jquery.org/license 12971 */ 12972 12973//>>label: Selectmenu 12974//>>group: Widgets 12975//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. 12976//>>docs: https://api.jqueryui.com/selectmenu/ 12977//>>demos: https://jqueryui.com/selectmenu/ 12978//>>css.structure: ../../themes/base/core.css 12979//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 12980//>>css.theme: ../../themes/base/theme.css 12981 12982 12983var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 12984 version: "1.14.2", 12985 defaultElement: "<select>", 12986 options: { 12987 appendTo: null, 12988 classes: { 12989 "ui-selectmenu-button-open": "ui-corner-top", 12990 "ui-selectmenu-button-closed": "ui-corner-all" 12991 }, 12992 disabled: null, 12993 icons: { 12994 button: "ui-icon-triangle-1-s" 12995 }, 12996 position: { 12997 my: "left top", 12998 at: "left bottom", 12999 collision: "none" 13000 }, 13001 width: false, 13002 13003 // Callbacks 13004 change: null, 13005 close: null, 13006 focus: null, 13007 open: null, 13008 select: null 13009 }, 13010 13011 _create: function() { 13012 var selectmenuId = this.element.uniqueId().attr( "id" ); 13013 this.ids = { 13014 element: selectmenuId, 13015 button: selectmenuId + "-button", 13016 menu: selectmenuId + "-menu" 13017 }; 13018 13019 this._drawButton(); 13020 this._drawMenu(); 13021 this._bindFormResetHandler(); 13022 13023 this._rendered = false; 13024 this.menuItems = $(); 13025 }, 13026 13027 _drawButton: function() { 13028 var icon, 13029 that = this, 13030 item = this._parseOption( 13031 this.element.find( "option:selected" ), 13032 this.element[ 0 ].selectedIndex 13033 ); 13034 13035 // Associate existing label with the new button 13036 this.labels = this.element.labels().attr( "for", this.ids.button ); 13037 this._on( this.labels, { 13038 click: function( event ) { 13039 this.button.trigger( "focus" ); 13040 event.preventDefault(); 13041 } 13042 } ); 13043 13044 // Hide original select element 13045 this.element.hide(); 13046 13047 // Create button 13048 this.button = $( "<span>", { 13049 tabindex: this.options.disabled ? -1 : 0, 13050 id: this.ids.button, 13051 role: "combobox", 13052 "aria-expanded": "false", 13053 "aria-autocomplete": "list", 13054 "aria-owns": this.ids.menu, 13055 "aria-haspopup": "true", 13056 title: this.element.attr( "title" ) 13057 } ) 13058 .insertAfter( this.element ); 13059 13060 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 13061 "ui-button ui-widget" ); 13062 13063 icon = $( "<span>" ).appendTo( this.button ); 13064 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 13065 this.buttonItem = this._renderButtonItem( item ) 13066 .appendTo( this.button ); 13067 13068 if ( this.options.width !== false ) { 13069 this._resizeButton(); 13070 } 13071 13072 this._on( this.button, this._buttonEvents ); 13073 this.button.one( "focusin", function() { 13074 13075 // Delay rendering the menu items until the button receives focus. 13076 // The menu may have already been rendered via a programmatic open. 13077 if ( !that._rendered ) { 13078 that._refreshMenu(); 13079 } 13080 } ); 13081 }, 13082 13083 _drawMenu: function() { 13084 var that = this; 13085 13086 // Create menu 13087 this.menu = $( "<ul>", { 13088 "aria-hidden": "true", 13089 "aria-labelledby": this.ids.button, 13090 id: this.ids.menu 13091 } ); 13092 13093 // Wrap menu 13094 this.menuWrap = $( "<div>" ).append( this.menu ); 13095 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 13096 this.menuWrap.appendTo( this._appendTo() ); 13097 13098 // Initialize menu widget 13099 this.menuInstance = this.menu 13100 .menu( { 13101 classes: { 13102 "ui-menu": "ui-corner-bottom" 13103 }, 13104 role: "listbox", 13105 select: function( event, ui ) { 13106 event.preventDefault(); 13107 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 13108 }, 13109 focus: function( event, ui ) { 13110 var item = ui.item.data( "ui-selectmenu-item" ); 13111 13112 // Prevent inital focus from firing and check if its a newly focused item 13113 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 13114 that._trigger( "focus", event, { item: item } ); 13115 if ( !that.isOpen ) { 13116 that._select( item, event ); 13117 } 13118 } 13119 that.focusIndex = item.index; 13120 13121 that.button.attr( "aria-activedescendant", 13122 that.menuItems.eq( item.index ).attr( "id" ) ); 13123 } 13124 } ) 13125 .menu( "instance" ); 13126 13127 // Don't close the menu on mouseleave 13128 this.menuInstance._off( this.menu, "mouseleave" ); 13129 13130 // Cancel the menu's collapseAll on document click 13131 this.menuInstance._closeOnDocumentClick = function() { 13132 return false; 13133 }; 13134 13135 // Selects often contain empty items, but never contain dividers 13136 this.menuInstance._isDivider = function() { 13137 return false; 13138 }; 13139 }, 13140 13141 refresh: function() { 13142 this._refreshMenu(); 13143 this.buttonItem.replaceWith( 13144 this.buttonItem = this._renderButtonItem( 13145 13146 // Fall back to an empty object in case there are no options 13147 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 13148 ) 13149 ); 13150 if ( this.options.width === null ) { 13151 this._resizeButton(); 13152 } 13153 }, 13154 13155 _refreshMenu: function() { 13156 var item, 13157 options = this.element.find( "option" ); 13158 13159 this.menu.empty(); 13160 13161 this._parseOptions( options ); 13162 this._renderMenu( this.menu, this.items ); 13163 13164 this.menuInstance.refresh(); 13165 this.menuItems = this.menu.find( "li" ) 13166 .not( ".ui-selectmenu-optgroup" ) 13167 .find( ".ui-menu-item-wrapper" ); 13168 13169 this._rendered = true; 13170 13171 if ( !options.length ) { 13172 return; 13173 } 13174 13175 item = this._getSelectedItem(); 13176 13177 // Update the menu to have the correct item focused 13178 this.menuInstance.focus( null, item ); 13179 this._setAria( item.data( "ui-selectmenu-item" ) ); 13180 13181 // Set disabled state 13182 this._setOption( "disabled", this.element.prop( "disabled" ) ); 13183 }, 13184 13185 open: function( event ) { 13186 if ( this.options.disabled ) { 13187 return; 13188 } 13189 13190 // If this is the first time the menu is being opened, render the items 13191 if ( !this._rendered ) { 13192 this._refreshMenu(); 13193 } else { 13194 13195 // Menu clears focus on close, reset focus to selected item 13196 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 13197 this.menuInstance.focus( null, this._getSelectedItem() ); 13198 } 13199 13200 // If there are no options, don't open the menu 13201 if ( !this.menuItems.length ) { 13202 return; 13203 } 13204 13205 this.isOpen = true; 13206 this._toggleAttr(); 13207 this._resizeMenu(); 13208 this._position(); 13209 13210 this._on( this.document, this._documentClick ); 13211 13212 this._trigger( "open", event ); 13213 }, 13214 13215 _position: function() { 13216 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 13217 }, 13218 13219 close: function( event ) { 13220 if ( !this.isOpen ) { 13221 return; 13222 } 13223 13224 this.isOpen = false; 13225 this._toggleAttr(); 13226 13227 this.range = null; 13228 this._off( this.document ); 13229 13230 this._trigger( "close", event ); 13231 }, 13232 13233 widget: function() { 13234 return this.button; 13235 }, 13236 13237 menuWidget: function() { 13238 return this.menu; 13239 }, 13240 13241 _renderButtonItem: function( item ) { 13242 var buttonItem = $( "<span>" ); 13243 13244 this._setText( buttonItem, item.label ); 13245 this._addClass( buttonItem, "ui-selectmenu-text" ); 13246 13247 return buttonItem; 13248 }, 13249 13250 _renderMenu: function( ul, items ) { 13251 var that = this, 13252 currentOptgroup = ""; 13253 13254 $.each( items, function( index, item ) { 13255 var li; 13256 13257 if ( item.optgroup !== currentOptgroup ) { 13258 li = $( "<li>", { 13259 text: item.optgroup 13260 } ); 13261 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 13262 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 13263 " ui-state-disabled" : 13264 "" ) ); 13265 13266 li.appendTo( ul ); 13267 13268 currentOptgroup = item.optgroup; 13269 } 13270 13271 that._renderItemData( ul, item ); 13272 } ); 13273 }, 13274 13275 _renderItemData: function( ul, item ) { 13276 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 13277 }, 13278 13279 _renderItem: function( ul, item ) { 13280 var li = $( "<li>" ), 13281 wrapper = $( "<div>", { 13282 title: item.element.attr( "title" ) 13283 } ); 13284 13285 if ( item.disabled ) { 13286 this._addClass( li, null, "ui-state-disabled" ); 13287 } 13288 13289 if ( item.hidden ) { 13290 li.prop( "hidden", true ); 13291 } else { 13292 this._setText( wrapper, item.label ); 13293 } 13294 13295 return li.append( wrapper ).appendTo( ul ); 13296 }, 13297 13298 _setText: function( element, value ) { 13299 if ( value ) { 13300 element.text( value ); 13301 } else { 13302 element.html( " " ); 13303 } 13304 }, 13305 13306 _move: function( direction, event ) { 13307 var item, next, 13308 filter = ".ui-menu-item"; 13309 13310 if ( this.isOpen ) { 13311 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13312 } else { 13313 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13314 filter += ":not(.ui-state-disabled)"; 13315 } 13316 13317 if ( direction === "first" || direction === "last" ) { 13318 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 13319 } else { 13320 next = item[ direction + "All" ]( filter ).eq( 0 ); 13321 } 13322 13323 if ( next.length ) { 13324 this.menuInstance.focus( event, next ); 13325 } 13326 }, 13327 13328 _getSelectedItem: function() { 13329 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13330 }, 13331 13332 _toggle: function( event ) { 13333 this[ this.isOpen ? "close" : "open" ]( event ); 13334 }, 13335 13336 _setSelection: function() { 13337 var selection; 13338 13339 if ( !this.range ) { 13340 return; 13341 } 13342 13343 selection = window.getSelection(); 13344 selection.removeAllRanges(); 13345 selection.addRange( this.range ); 13346 }, 13347 13348 _documentClick: { 13349 mousedown: function( event ) { 13350 if ( !this.isOpen ) { 13351 return; 13352 } 13353 13354 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 13355 CSS.escape( this.ids.button ) ).length ) { 13356 this.close( event ); 13357 } 13358 } 13359 }, 13360 13361 _buttonEvents: { 13362 13363 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 13364 mousedown: function() { 13365 var selection = window.getSelection(); 13366 if ( selection.rangeCount ) { 13367 this.range = selection.getRangeAt( 0 ); 13368 } 13369 }, 13370 13371 click: function( event ) { 13372 this._setSelection(); 13373 this._toggle( event ); 13374 }, 13375 13376 keydown: function( event ) { 13377 var preventDefault = true; 13378 switch ( event.keyCode ) { 13379 case $.ui.keyCode.TAB: 13380 case $.ui.keyCode.ESCAPE: 13381 this.close( event ); 13382 preventDefault = false; 13383 break; 13384 case $.ui.keyCode.ENTER: 13385 if ( this.isOpen ) { 13386 this._selectFocusedItem( event ); 13387 } 13388 break; 13389 case $.ui.keyCode.UP: 13390 if ( event.altKey ) { 13391 this._toggle( event ); 13392 } else { 13393 this._move( "prev", event ); 13394 } 13395 break; 13396 case $.ui.keyCode.DOWN: 13397 if ( event.altKey ) { 13398 this._toggle( event ); 13399 } else { 13400 this._move( "next", event ); 13401 } 13402 break; 13403 case $.ui.keyCode.SPACE: 13404 if ( this.isOpen ) { 13405 this._selectFocusedItem( event ); 13406 } else { 13407 this._toggle( event ); 13408 } 13409 break; 13410 case $.ui.keyCode.LEFT: 13411 this._move( "prev", event ); 13412 break; 13413 case $.ui.keyCode.RIGHT: 13414 this._move( "next", event ); 13415 break; 13416 case $.ui.keyCode.HOME: 13417 case $.ui.keyCode.PAGE_UP: 13418 this._move( "first", event ); 13419 break; 13420 case $.ui.keyCode.END: 13421 case $.ui.keyCode.PAGE_DOWN: 13422 this._move( "last", event ); 13423 break; 13424 default: 13425 this.menu.trigger( event ); 13426 preventDefault = false; 13427 } 13428 13429 if ( preventDefault ) { 13430 event.preventDefault(); 13431 } 13432 } 13433 }, 13434 13435 _selectFocusedItem: function( event ) { 13436 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13437 if ( !item.hasClass( "ui-state-disabled" ) ) { 13438 this._select( item.data( "ui-selectmenu-item" ), event ); 13439 } 13440 }, 13441 13442 _select: function( item, event ) { 13443 var oldIndex = this.element[ 0 ].selectedIndex; 13444 13445 // Change native select element 13446 this.element[ 0 ].selectedIndex = item.index; 13447 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 13448 this._setAria( item ); 13449 this._trigger( "select", event, { item: item } ); 13450 13451 if ( item.index !== oldIndex ) { 13452 this._trigger( "change", event, { item: item } ); 13453 } 13454 13455 this.close( event ); 13456 }, 13457 13458 _setAria: function( item ) { 13459 var id = this.menuItems.eq( item.index ).attr( "id" ); 13460 13461 this.button.attr( { 13462 "aria-labelledby": id, 13463 "aria-activedescendant": id 13464 } ); 13465 this.menu.attr( "aria-activedescendant", id ); 13466 }, 13467 13468 _setOption: function( key, value ) { 13469 if ( key === "icons" ) { 13470 var icon = this.button.find( "span.ui-icon" ); 13471 this._removeClass( icon, null, this.options.icons.button ) 13472 ._addClass( icon, null, value.button ); 13473 } 13474 13475 this._super( key, value ); 13476 13477 if ( key === "appendTo" ) { 13478 this.menuWrap.appendTo( this._appendTo() ); 13479 } 13480 13481 if ( key === "width" ) { 13482 this._resizeButton(); 13483 } 13484 }, 13485 13486 _setOptionDisabled: function( value ) { 13487 this._super( value ); 13488 13489 this.menuInstance.option( "disabled", value ); 13490 this.button.attr( "aria-disabled", value ); 13491 this._toggleClass( this.button, null, "ui-state-disabled", value ); 13492 13493 this.element.prop( "disabled", value ); 13494 if ( value ) { 13495 this.button.attr( "tabindex", -1 ); 13496 this.close(); 13497 } else { 13498 this.button.attr( "tabindex", 0 ); 13499 } 13500 }, 13501 13502 _appendTo: function() { 13503 var element = this.options.appendTo; 13504 13505 if ( element ) { 13506 element = element.jquery || element.nodeType ? 13507 $( element ) : 13508 this.document.find( element ).eq( 0 ); 13509 } 13510 13511 if ( !element || !element[ 0 ] ) { 13512 element = this.element.closest( ".ui-front, dialog" ); 13513 } 13514 13515 if ( !element.length ) { 13516 element = this.document[ 0 ].body; 13517 } 13518 13519 return element; 13520 }, 13521 13522 _toggleAttr: function() { 13523 this.button.attr( "aria-expanded", this.isOpen ); 13524 13525 // We can't use two _toggleClass() calls here, because we need to make sure 13526 // we always remove classes first and add them second, otherwise if both classes have the 13527 // same theme class, it will be removed after we add it. 13528 this._removeClass( this.button, "ui-selectmenu-button-" + 13529 ( this.isOpen ? "closed" : "open" ) ) 13530 ._addClass( this.button, "ui-selectmenu-button-" + 13531 ( this.isOpen ? "open" : "closed" ) ) 13532 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 13533 13534 this.menu.attr( "aria-hidden", !this.isOpen ); 13535 }, 13536 13537 _resizeButton: function() { 13538 var width = this.options.width; 13539 13540 // For `width: false`, just remove inline style and stop 13541 if ( width === false ) { 13542 this.button.css( "width", "" ); 13543 return; 13544 } 13545 13546 // For `width: null`, match the width of the original element 13547 if ( width === null ) { 13548 width = this.element.show().outerWidth(); 13549 this.element.hide(); 13550 } 13551 13552 this.button.outerWidth( width ); 13553 }, 13554 13555 _resizeMenu: function() { 13556 this.menu.outerWidth( Math.max( 13557 this.button.outerWidth(), 13558 this.menu.width( "" ).outerWidth() 13559 ) ); 13560 }, 13561 13562 _getCreateOptions: function() { 13563 var options = this._super(); 13564 13565 options.disabled = this.element.prop( "disabled" ); 13566 13567 return options; 13568 }, 13569 13570 _parseOptions: function( options ) { 13571 var that = this, 13572 data = []; 13573 options.each( function( index, item ) { 13574 data.push( that._parseOption( $( item ), index ) ); 13575 } ); 13576 this.items = data; 13577 }, 13578 13579 _parseOption: function( option, index ) { 13580 var optgroup = option.parent( "optgroup" ); 13581 13582 return { 13583 element: option, 13584 index: index, 13585 value: option.val(), 13586 label: option.text(), 13587 hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ), 13588 optgroup: optgroup.attr( "label" ) || "", 13589 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 13590 }; 13591 }, 13592 13593 _destroy: function() { 13594 this._unbindFormResetHandler(); 13595 this.menuWrap.remove(); 13596 this.button.remove(); 13597 this.element.show(); 13598 this.element.removeUniqueId(); 13599 this.labels.attr( "for", this.ids.element ); 13600 } 13601} ] ); 13602 13603 13604/*! 13605 * jQuery UI Slider 1.14.2 13606 * https://jqueryui.com 13607 * 13608 * Copyright OpenJS Foundation and other contributors 13609 * Released under the MIT license. 13610 * https://jquery.org/license 13611 */ 13612 13613//>>label: Slider 13614//>>group: Widgets 13615//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 13616//>>docs: https://api.jqueryui.com/slider/ 13617//>>demos: https://jqueryui.com/slider/ 13618//>>css.structure: ../../themes/base/core.css 13619//>>css.structure: ../../themes/base/slider.css 13620//>>css.theme: ../../themes/base/theme.css 13621 13622 13623var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 13624 version: "1.14.2", 13625 widgetEventPrefix: "slide", 13626 13627 options: { 13628 animate: false, 13629 classes: { 13630 "ui-slider": "ui-corner-all", 13631 "ui-slider-handle": "ui-corner-all", 13632 13633 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 13634 // element, but worked best visually with a variety of themes 13635 "ui-slider-range": "ui-corner-all ui-widget-header" 13636 }, 13637 distance: 0, 13638 max: 100, 13639 min: 0, 13640 orientation: "horizontal", 13641 range: false, 13642 step: 1, 13643 value: 0, 13644 values: null, 13645 13646 // Callbacks 13647 change: null, 13648 slide: null, 13649 start: null, 13650 stop: null 13651 }, 13652 13653 // Number of pages in a slider 13654 // (how many times can you page up/down to go through the whole range) 13655 numPages: 5, 13656 13657 _create: function() { 13658 this._keySliding = false; 13659 this._mouseSliding = false; 13660 this._animateOff = true; 13661 this._handleIndex = null; 13662 this._detectOrientation(); 13663 this._mouseInit(); 13664 this._calculateNewMax(); 13665 13666 this._addClass( "ui-slider ui-slider-" + this.orientation, 13667 "ui-widget ui-widget-content" ); 13668 13669 this._refresh(); 13670 13671 this._animateOff = false; 13672 }, 13673 13674 _refresh: function() { 13675 this._createRange(); 13676 this._createHandles(); 13677 this._setupEvents(); 13678 this._refreshValue(); 13679 }, 13680 13681 _createHandles: function() { 13682 var i, handleCount, 13683 options = this.options, 13684 existingHandles = this.element.find( ".ui-slider-handle" ), 13685 handle = "<span tabindex='0'></span>", 13686 handles = []; 13687 13688 handleCount = ( options.values && options.values.length ) || 1; 13689 13690 if ( existingHandles.length > handleCount ) { 13691 existingHandles.slice( handleCount ).remove(); 13692 existingHandles = existingHandles.slice( 0, handleCount ); 13693 } 13694 13695 for ( i = existingHandles.length; i < handleCount; i++ ) { 13696 handles.push( handle ); 13697 } 13698 13699 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13700 13701 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 13702 13703 this.handle = this.handles.eq( 0 ); 13704 13705 this.handles.each( function( i ) { 13706 $( this ) 13707 .data( "ui-slider-handle-index", i ) 13708 .attr( "tabIndex", 0 ); 13709 } ); 13710 }, 13711 13712 _createRange: function() { 13713 var options = this.options; 13714 13715 if ( options.range ) { 13716 if ( options.range === true ) { 13717 if ( !options.values ) { 13718 options.values = [ this._valueMin(), this._valueMin() ]; 13719 } else if ( options.values.length && options.values.length !== 2 ) { 13720 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 13721 } else if ( Array.isArray( options.values ) ) { 13722 options.values = options.values.slice( 0 ); 13723 } 13724 } 13725 13726 if ( !this.range || !this.range.length ) { 13727 this.range = $( "<div>" ) 13728 .appendTo( this.element ); 13729 13730 this._addClass( this.range, "ui-slider-range" ); 13731 } else { 13732 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 13733 13734 // Handle range switching from true to min/max 13735 this.range.css( { 13736 "left": "", 13737 "bottom": "" 13738 } ); 13739 } 13740 if ( options.range === "min" || options.range === "max" ) { 13741 this._addClass( this.range, "ui-slider-range-" + options.range ); 13742 } 13743 } else { 13744 if ( this.range ) { 13745 this.range.remove(); 13746 } 13747 this.range = null; 13748 } 13749 }, 13750 13751 _setupEvents: function() { 13752 this._off( this.handles ); 13753 this._on( this.handles, this._handleEvents ); 13754 this._hoverable( this.handles ); 13755 this._focusable( this.handles ); 13756 }, 13757 13758 _destroy: function() { 13759 this.handles.remove(); 13760 if ( this.range ) { 13761 this.range.remove(); 13762 } 13763 13764 this._mouseDestroy(); 13765 }, 13766 13767 _mouseCapture: function( event ) { 13768 var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 5,217 bytes, lines 13768-13967
13768seOverHandle, 13769 that = this, 13770 o = this.options; 13771 13772 if ( o.disabled ) { 13773 return false; 13774 } 13775 13776 this.elementSize = { 13777 width: this.element.outerWidth(), 13778 height: this.element.outerHeight() 13779 }; 13780 this.elementOffset = this.element.offset(); 13781 13782 position = { x: event.pageX, y: event.pageY }; 13783 normValue = this._normValueFromMouse( position ); 13784 distance = this._valueMax() - this._valueMin() + 1; 13785 this.handles.each( function( i ) { 13786 var thisDistance = Math.abs( normValue - that.values( i ) ); 13787 if ( ( distance > thisDistance ) || 13788 ( distance === thisDistance && 13789 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 13790 distance = thisDistance; 13791 closestHandle = $( this ); 13792 index = i; 13793 } 13794 } ); 13795 13796 allowed = this._start( event, index ); 13797 if ( allowed === false ) { 13798 return false; 13799 } 13800 this._mouseSliding = true; 13801 13802 this._handleIndex = index; 13803 13804 this._addClass( closestHandle, null, "ui-state-active" ); 13805 closestHandle.trigger( "focus" ); 13806 13807 offset = closestHandle.offset(); 13808 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13809 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13810 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13811 top: event.pageY - offset.top - 13812 ( closestHandle.height() / 2 ) - 13813 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 13814 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 13815 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 13816 }; 13817 13818 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13819 this._slide( event, index, normValue ); 13820 } 13821 this._animateOff = true; 13822 return true; 13823 }, 13824 13825 _mouseStart: function() { 13826 return true; 13827 }, 13828 13829 _mouseDrag: function( event ) { 13830 var position = { x: event.pageX, y: event.pageY }, 13831 normValue = this._normValueFromMouse( position ); 13832 13833 this._slide( event, this._handleIndex, normValue ); 13834 13835 return false; 13836 }, 13837 13838 _mouseStop: function( event ) { 13839 this._removeClass( this.handles, null, "ui-state-active" ); 13840 this._mouseSliding = false; 13841 13842 this._stop( event, this._handleIndex ); 13843 this._change( event, this._handleIndex ); 13844 13845 this._handleIndex = null; 13846 this._clickOffset = null; 13847 this._animateOff = false; 13848 13849 return false; 13850 }, 13851 13852 _detectOrientation: function() { 13853 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13854 }, 13855 13856 _normValueFromMouse: function( position ) { 13857 var pixelTotal, 13858 pixelMouse, 13859 percentMouse, 13860 valueTotal, 13861 valueMouse; 13862 13863 if ( this.orientation === "horizontal" ) { 13864 pixelTotal = this.elementSize.width; 13865 pixelMouse = position.x - this.elementOffset.left - 13866 ( this._clickOffset ? this._clickOffset.left : 0 ); 13867 } else { 13868 pixelTotal = this.elementSize.height; 13869 pixelMouse = position.y - this.elementOffset.top - 13870 ( this._clickOffset ? this._clickOffset.top : 0 ); 13871 } 13872 13873 percentMouse = ( pixelMouse / pixelTotal ); 13874 if ( percentMouse > 1 ) { 13875 percentMouse = 1; 13876 } 13877 if ( percentMouse < 0 ) { 13878 percentMouse = 0; 13879 } 13880 if ( this.orientation === "vertical" ) { 13881 percentMouse = 1 - percentMouse; 13882 } 13883 13884 valueTotal = this._valueMax() - this._valueMin(); 13885 valueMouse = this._valueMin() + percentMouse * valueTotal; 13886 13887 return this._trimAlignValue( valueMouse ); 13888 }, 13889 13890 _uiHash: function( index, value, values ) { 13891 var uiHash = { 13892 handle: this.handles[ index ], 13893 handleIndex: index, 13894 value: value !== undefined ? value : this.value() 13895 }; 13896 13897 if ( this._hasMultipleValues() ) { 13898 uiHash.value = value !== undefined ? value : this.values( index ); 13899 uiHash.values = values || this.values(); 13900 } 13901 13902 return uiHash; 13903 }, 13904 13905 _hasMultipleValues: function() { 13906 return this.options.values && this.options.values.length; 13907 }, 13908 13909 _start: function( event, index ) { 13910 return this._trigger( "start", event, this._uiHash( index ) ); 13911 }, 13912 13913 _slide: function( event, index, newVal ) { 13914 var allowed, otherVal, 13915 currentValue = this.value(), 13916 newValues = this.values(); 13917 13918 if ( this._hasMultipleValues() ) { 13919 otherVal = this.values( index ? 0 : 1 ); 13920 currentValue = this.values( index ); 13921 13922 if ( this.options.values.length === 2 && this.options.range === true ) { 13923 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 13924 } 13925 13926 newValues[ index ] = newVal; 13927 } 13928 13929 if ( newVal === currentValue ) { 13930 return; 13931 } 13932 13933 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 13934 13935 // A slide can be canceled by returning false from the slide callback 13936 if ( allowed === false ) { 13937 return; 13938 } 13939 13940 if ( this._hasMultipleValues() ) { 13941 this.values( index, newVal ); 13942 } else { 13943 this.value( newVal ); 13944 } 13945 }, 13946 13947 _stop: function( event, index ) { 13948 this._trigger( "stop", event, this._uiHash( index ) ); 13949 }, 13950 13951 _change: function( event, index ) { 13952 if ( !this._keySliding && !this._mouseSliding ) { 13953 13954 //store the last changed value index for reference when handles overlap 13955 this._lastChangedValue = index; 13956 this._trigger( "change", event, this._uiHash( index ) ); 13957 } 13958 }, 13959 13960 value: function( newValue ) { 13961 if ( arguments.length ) { 13962 this.options.value = this._trimAlignValue( newValue ); 13963 this._refreshValue(); 13964 this._change( null, 0 ); 13965 return; 13966 } 13967
vendor: 4,358 bytes, lines 13968-14140
13968 return this._value(); 13969 }, 13970 13971 values: function( index, newValue ) { 13972 var vals, 13973 newValues, 13974 i; 13975 13976 if ( arguments.length > 1 ) { 13977 this.options.values[ index ] = this._trimAlignValue( newValue ); 13978 this._refreshValue(); 13979 this._change( null, index ); 13980 return; 13981 } 13982 13983 if ( arguments.length ) { 13984 if ( Array.isArray( arguments[ 0 ] ) ) { 13985 vals = this.options.values; 13986 newValues = arguments[ 0 ]; 13987 for ( i = 0; i < vals.length; i += 1 ) { 13988 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13989 this._change( null, i ); 13990 } 13991 this._refreshValue(); 13992 } else { 13993 if ( this._hasMultipleValues() ) { 13994 return this._values( index ); 13995 } else { 13996 return this.value(); 13997 } 13998 } 13999 } else { 14000 return this._values(); 14001 } 14002 }, 14003 14004 _setOption: function( key, value ) { 14005 var i, 14006 valsLength = 0; 14007 14008 if ( key === "range" && this.options.range === true ) { 14009 if ( value === "min" ) { 14010 this.options.value = this._values( 0 ); 14011 this.options.values = null; 14012 } else if ( value === "max" ) { 14013 this.options.value = this._values( this.options.values.length - 1 ); 14014 this.options.values = null; 14015 } 14016 } 14017 14018 if ( Array.isArray( this.options.values ) ) { 14019 valsLength = this.options.values.length; 14020 } 14021 14022 this._super( key, value ); 14023 14024 switch ( key ) { 14025 case "orientation": 14026 this._detectOrientation(); 14027 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 14028 ._addClass( "ui-slider-" + this.orientation ); 14029 this._refreshValue(); 14030 if ( this.options.range ) { 14031 this._refreshRange( value ); 14032 } 14033 14034 // Reset positioning from previous orientation 14035 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 14036 break; 14037 case "value": 14038 this._animateOff = true; 14039 this._refreshValue(); 14040 this._change( null, 0 ); 14041 this._animateOff = false; 14042 break; 14043 case "values": 14044 this._animateOff = true; 14045 this._refreshValue(); 14046 14047 // Start from the last handle to prevent unreachable handles (#9046) 14048 for ( i = valsLength - 1; i >= 0; i-- ) { 14049 this._change( null, i ); 14050 } 14051 this._animateOff = false; 14052 break; 14053 case "step": 14054 case "min": 14055 case "max": 14056 this._animateOff = true; 14057 this._calculateNewMax(); 14058 this._refreshValue(); 14059 this._animateOff = false; 14060 break; 14061 case "range": 14062 this._animateOff = true; 14063 this._refresh(); 14064 this._animateOff = false; 14065 break; 14066 } 14067 }, 14068 14069 _setOptionDisabled: function( value ) { 14070 this._super( value ); 14071 14072 this._toggleClass( null, "ui-state-disabled", !!value ); 14073 }, 14074 14075 //internal value getter 14076 // _value() returns value trimmed by min and max, aligned by step 14077 _value: function() { 14078 var val = this.options.value; 14079 val = this._trimAlignValue( val ); 14080 14081 return val; 14082 }, 14083 14084 //internal values getter 14085 // _values() returns array of values trimmed by min and max, aligned by step 14086 // _values( index ) returns single value trimmed by min and max, aligned by step 14087 _values: function( index ) { 14088 var val, 14089 vals, 14090 i; 14091 14092 if ( arguments.length ) { 14093 val = this.options.values[ index ]; 14094 val = this._trimAlignValue( val ); 14095 14096 return val; 14097 } else if ( this._hasMultipleValues() ) { 14098 14099 // .slice() creates a copy of the array 14100 // this copy gets trimmed by min and max and then returned 14101 vals = this.options.values.slice(); 14102 for ( i = 0; i < vals.length; i += 1 ) { 14103 vals[ i ] = this._trimAlignValue( vals[ i ] ); 14104 } 14105 14106 return vals; 14107 } else { 14108 return []; 14109 } 14110 }, 14111 14112 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 14113 _trimAlignValue: function( val ) { 14114 if ( val <= this._valueMin() ) { 14115 return this._valueMin(); 14116 } 14117 if ( val >= this._valueMax() ) { 14118 return this._valueMax(); 14119 } 14120 var step = ( this.options.step > 0 ) ? this.options.step : 1, 14121 valModStep = ( val - this._valueMin() ) % step, 14122 alignValue = val - valModStep; 14123 14124 if ( Math.abs( valModStep ) * 2 >= step ) { 14125 alignValue += ( valModStep > 0 ) ? step : ( -step ); 14126 } 14127 14128 // Since JavaScript has problems with large floats, round 14129 // the final value to 5 digits after the decimal point (see #4124) 14130 return parseFloat( alignValue.toFixed( 5 ) ); 14131 }, 14132 14133 _calculateNewMax: function() { 14134 var max = this.options.max, 14135 min = this._valueMin(), 14136 step = this.options.step, 14137 aboveMin = Math.round( ( max - min ) / step ) * step; 14138 max = aboveMin + min; 14139 if ( max > this.options.max ) { 14140
vendor: 5,583 bytes, lines 14141-14340
14141 //If max is not divisible by step, rounding off may increase its value 14142 max -= step; 14143 } 14144 this.max = parseFloat( max.toFixed( this._precision() ) ); 14145 }, 14146 14147 _precision: function() { 14148 var precision = this._precisionOf( this.options.step ); 14149 if ( this.options.min !== null ) { 14150 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14151 } 14152 return precision; 14153 }, 14154 14155 _precisionOf: function( num ) { 14156 var str = num.toString(), 14157 decimal = str.indexOf( "." ); 14158 return decimal === -1 ? 0 : str.length - decimal - 1; 14159 }, 14160 14161 _valueMin: function() { 14162 return this.options.min; 14163 }, 14164 14165 _valueMax: function() { 14166 return this.max; 14167 }, 14168 14169 _refreshRange: function( orientation ) { 14170 if ( orientation === "vertical" ) { 14171 this.range.css( { "width": "", "left": "" } ); 14172 } 14173 if ( orientation === "horizontal" ) { 14174 this.range.css( { "height": "", "bottom": "" } ); 14175 } 14176 }, 14177 14178 _refreshValue: function() { 14179 var lastValPercent, valPercent, value, valueMin, valueMax, 14180 oRange = this.options.range, 14181 o = this.options, 14182 that = this, 14183 animate = ( !this._animateOff ) ? o.animate : false, 14184 _set = {}; 14185 14186 if ( this._hasMultipleValues() ) { 14187 this.handles.each( function( i ) { 14188 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 14189 that._valueMin() ) * 100; 14190 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14191 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14192 if ( that.options.range === true ) { 14193 if ( that.orientation === "horizontal" ) { 14194 if ( i === 0 ) { 14195 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14196 left: valPercent + "%" 14197 }, o.animate ); 14198 } 14199 if ( i === 1 ) { 14200 that.range[ animate ? "animate" : "css" ]( { 14201 width: ( valPercent - lastValPercent ) + "%" 14202 }, { 14203 queue: false, 14204 duration: o.animate 14205 } ); 14206 } 14207 } else { 14208 if ( i === 0 ) { 14209 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14210 bottom: ( valPercent ) + "%" 14211 }, o.animate ); 14212 } 14213 if ( i === 1 ) { 14214 that.range[ animate ? "animate" : "css" ]( { 14215 height: ( valPercent - lastValPercent ) + "%" 14216 }, { 14217 queue: false, 14218 duration: o.animate 14219 } ); 14220 } 14221 } 14222 } 14223 lastValPercent = valPercent; 14224 } ); 14225 } else { 14226 value = this.value(); 14227 valueMin = this._valueMin(); 14228 valueMax = this._valueMax(); 14229 valPercent = ( valueMax !== valueMin ) ? 14230 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 14231 0; 14232 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14233 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14234 14235 if ( oRange === "min" && this.orientation === "horizontal" ) { 14236 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14237 width: valPercent + "%" 14238 }, o.animate ); 14239 } 14240 if ( oRange === "max" && this.orientation === "horizontal" ) { 14241 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14242 width: ( 100 - valPercent ) + "%" 14243 }, o.animate ); 14244 } 14245 if ( oRange === "min" && this.orientation === "vertical" ) { 14246 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14247 height: valPercent + "%" 14248 }, o.animate ); 14249 } 14250 if ( oRange === "max" && this.orientation === "vertical" ) { 14251 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14252 height: ( 100 - valPercent ) + "%" 14253 }, o.animate ); 14254 } 14255 } 14256 }, 14257 14258 _handleEvents: { 14259 keydown: function( event ) { 14260 var allowed, curVal, newVal, step, 14261 index = $( event.target ).data( "ui-slider-handle-index" ); 14262 14263 switch ( event.keyCode ) { 14264 case $.ui.keyCode.HOME: 14265 case $.ui.keyCode.END: 14266 case $.ui.keyCode.PAGE_UP: 14267 case $.ui.keyCode.PAGE_DOWN: 14268 case $.ui.keyCode.UP: 14269 case $.ui.keyCode.RIGHT: 14270 case $.ui.keyCode.DOWN: 14271 case $.ui.keyCode.LEFT: 14272 event.preventDefault(); 14273 if ( !this._keySliding ) { 14274 this._keySliding = true; 14275 this._addClass( $( event.target ), null, "ui-state-active" ); 14276 allowed = this._start( event, index ); 14277 if ( allowed === false ) { 14278 return; 14279 } 14280 } 14281 break; 14282 } 14283 14284 step = this.options.step; 14285 if ( this._hasMultipleValues() ) { 14286 curVal = newVal = this.values( index ); 14287 } else { 14288 curVal = newVal = this.value(); 14289 } 14290 14291 switch ( event.keyCode ) { 14292 case $.ui.keyCode.HOME: 14293 newVal = this._valueMin(); 14294 break; 14295 case $.ui.keyCode.END: 14296 newVal = this._valueMax(); 14297 break; 14298 case $.ui.keyCode.PAGE_UP: 14299 newVal = this._trimAlignValue( 14300 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 14301 ); 14302 break; 14303 case $.ui.keyCode.PAGE_DOWN: 14304 newVal = this._trimAlignValue( 14305 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 14306 break; 14307 case $.ui.keyCode.UP: 14308 case $.ui.keyCode.RIGHT: 14309 if ( curVal === this._valueMax() ) { 14310 return; 14311 } 14312 newVal = this._trimAlignValue( curVal + step ); 14313 break; 14314 case $.ui.keyCode.DOWN: 14315 case $.ui.keyCode.LEFT: 14316 if ( curVal === this._valueMin() ) { 14317 return; 14318 } 14319 newVal = this._trimAlignValue( curVal - step ); 14320 break; 14321 } 14322 14323 this._slide( event, index, newVal ); 14324 }, 14325 keyup: function( event ) { 14326 var index = $( event.target ).data( "ui-slider-handle-index" ); 14327 14328 if ( this._keySliding ) { 14329 this._keySliding = false; 14330 this._stop( event, index ); 14331 this._change( event, index ); 14332 this._removeClass( $( event.target ), null, "ui-state-active" ); 14333 } 14334 } 14335 } 14336} ); 14337 14338 14339/*! 14340 * jQuery UI S
vendor: 37,718 bytes, lines 14340-15811
14340pinner 1.14.2 14341 * https://jqueryui.com 14342 * 14343 * Copyright OpenJS Foundation and other contributors 14344 * Released under the MIT license. 14345 * https://jquery.org/license 14346 */ 14347 14348//>>label: Spinner 14349//>>group: Widgets 14350//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 14351//>>docs: https://api.jqueryui.com/spinner/ 14352//>>demos: https://jqueryui.com/spinner/ 14353//>>css.structure: ../../themes/base/core.css 14354//>>css.structure: ../../themes/base/spinner.css 14355//>>css.theme: ../../themes/base/theme.css 14356 14357 14358function spinnerModifier( fn ) { 14359 return function() { 14360 var previous = this.element.val(); 14361 fn.apply( this, arguments ); 14362 this._refresh(); 14363 if ( previous !== this.element.val() ) { 14364 this._trigger( "change" ); 14365 } 14366 }; 14367} 14368 14369$.widget( "ui.spinner", { 14370 version: "1.14.2", 14371 defaultElement: "<input>", 14372 widgetEventPrefix: "spin", 14373 options: { 14374 classes: { 14375 "ui-spinner": "ui-corner-all", 14376 "ui-spinner-down": "ui-corner-br", 14377 "ui-spinner-up": "ui-corner-tr" 14378 }, 14379 culture: null, 14380 icons: { 14381 down: "ui-icon-triangle-1-s", 14382 up: "ui-icon-triangle-1-n" 14383 }, 14384 incremental: true, 14385 max: null, 14386 min: null, 14387 numberFormat: null, 14388 page: 10, 14389 step: 1, 14390 14391 change: null, 14392 spin: null, 14393 start: null, 14394 stop: null 14395 }, 14396 14397 _create: function() { 14398 14399 // handle string values that need to be parsed 14400 this._setOption( "max", this.options.max ); 14401 this._setOption( "min", this.options.min ); 14402 this._setOption( "step", this.options.step ); 14403 14404 // Only format if there is a value, prevents the field from being marked 14405 // as invalid in Firefox, see #9573. 14406 if ( this.value() !== "" ) { 14407 14408 // Format the value, but don't constrain. 14409 this._value( this.element.val(), true ); 14410 } 14411 14412 this._draw(); 14413 this._on( this._events ); 14414 this._refresh(); 14415 14416 // Turning off autocomplete prevents the browser from remembering the 14417 // value when navigating through history, so we re-enable autocomplete 14418 // if the page is unloaded before the widget is destroyed. #7790 14419 this._on( this.window, { 14420 beforeunload: function() { 14421 this.element.removeAttr( "autocomplete" ); 14422 } 14423 } ); 14424 }, 14425 14426 _getCreateOptions: function() { 14427 var options = this._super(); 14428 var element = this.element; 14429 14430 $.each( [ "min", "max", "step" ], function( i, option ) { 14431 var value = element.attr( option ); 14432 if ( value != null && value.length ) { 14433 options[ option ] = value; 14434 } 14435 } ); 14436 14437 return options; 14438 }, 14439 14440 _events: { 14441 keydown: function( event ) { 14442 if ( this._start( event ) && this._keydown( event ) ) { 14443 event.preventDefault(); 14444 } 14445 }, 14446 keyup: "_stop", 14447 focus: function() { 14448 this.previous = this.element.val(); 14449 }, 14450 blur: function( event ) { 14451 this._stop(); 14452 this._refresh(); 14453 if ( this.previous !== this.element.val() ) { 14454 this._trigger( "change", event ); 14455 } 14456 }, 14457 wheel: function( event ) { 14458 var activeElement = this.document[ 0 ].activeElement; 14459 var isActive = this.element[ 0 ] === activeElement; 14460 var delta = event.deltaY || event.originalEvent && event.originalEvent.deltaY; 14461 14462 if ( !isActive || !delta ) { 14463 return; 14464 } 14465 14466 if ( !this.spinning && !this._start( event ) ) { 14467 return false; 14468 } 14469 14470 this._spin( ( delta > 0 ? -1 : 1 ) * this.options.step, event ); 14471 clearTimeout( this.mousewheelTimer ); 14472 this.mousewheelTimer = this._delay( function() { 14473 if ( this.spinning ) { 14474 this._stop( event ); 14475 } 14476 }, 100 ); 14477 event.preventDefault(); 14478 }, 14479 14480 // DEPRECATED 14481 // Kept for backwards compatibility. Please use the modern `wheel` 14482 // event. The `delta` parameter is provided by the jQuery Mousewheel 14483 // plugin if one is loaded. 14484 mousewheel: function( event, delta ) { 14485 if ( !event.isTrigger ) { 14486 14487 // If this is not a trigger call, the `wheel` handler will 14488 // fire as well, let's not duplicate it. 14489 return; 14490 } 14491 14492 var wheelEvent = $.Event( event ); 14493 wheelEvent.type = "wheel"; 14494 if ( delta ) { 14495 wheelEvent.deltaY = -delta; 14496 } 14497 return this._events.wheel.call( this, wheelEvent ); 14498 }, 14499 14500 "mousedown .ui-spinner-button": function( event ) { 14501 var previous; 14502 14503 // We never want the buttons to have focus; whenever the user is 14504 // interacting with the spinner, the focus should be on the input. 14505 // If the input is focused then this.previous is properly set from 14506 // when the input first received focus. If the input is not focused 14507 // then we need to set this.previous based on the value before spinning. 14508 previous = this.element[ 0 ] === this.document[ 0 ].activeElement ? 14509 this.previous : this.element.val(); 14510 function checkFocus() { 14511 var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement; 14512 if ( !isActive ) { 14513 this.element.trigger( "focus" ); 14514 this.previous = previous; 14515 } 14516 } 14517 14518 // Ensure focus is on (or stays on) the text field 14519 event.preventDefault(); 14520 checkFocus.call( this ); 14521 14522 if ( this._start( event ) === false ) { 14523 return; 14524 } 14525 14526 this._repeat( null, $( event.currentTarget ) 14527 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14528 }, 14529 "mouseup .ui-spinner-button": "_stop", 14530 "mouseenter .ui-spinner-button": function( event ) { 14531 14532 // button will add ui-state-active if mouse was down while mouseleave and kept down 14533 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14534 return; 14535 } 14536 14537 if ( this._start( event ) === false ) { 14538 return false; 14539 } 14540 this._repeat( null, $( event.currentTarget ) 14541 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14542 }, 14543 14544 // TODO: do we really want to consider this a stop? 14545 // shouldn't we just stop the repeater and wait until mouseup before 14546 // we trigger the stop event? 14547 "mouseleave .ui-spinner-button": "_stop" 14548 }, 14549 14550 // Support mobile enhanced option and make backcompat more sane 14551 _enhance: function() { 14552 this.uiSpinner = this.element 14553 .attr( "autocomplete", "off" ) 14554 .wrap( "<span>" ) 14555 .parent() 14556 14557 // Add buttons 14558 .append( 14559 "<a></a><a></a>" 14560 ); 14561 }, 14562 14563 _draw: function() { 14564 this._enhance(); 14565 14566 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 14567 this._addClass( "ui-spinner-input" ); 14568 14569 this.element.attr( "role", "spinbutton" ); 14570 14571 // Button bindings 14572 this.buttons = this.uiSpinner.children( "a" ) 14573 .attr( "tabIndex", -1 ) 14574 .attr( "aria-hidden", true ) 14575 .button( { 14576 classes: { 14577 "ui-button": "" 14578 } 14579 } ); 14580 14581 // TODO: Right now button does not support classes this is already updated in button PR 14582 this._removeClass( this.buttons, "ui-corner-all" ); 14583 14584 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 14585 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 14586 this.buttons.first().button( { 14587 "icon": this.options.icons.up, 14588 "showLabel": false 14589 } ); 14590 this.buttons.last().button( { 14591 "icon": this.options.icons.down, 14592 "showLabel": false 14593 } ); 14594 14595 // IE 6 doesn't understand height: 50% for the buttons 14596 // unless the wrapper has an explicit height 14597 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 14598 this.uiSpinner.height() > 0 ) { 14599 this.uiSpinner.height( this.uiSpinner.height() ); 14600 } 14601 }, 14602 14603 _keydown: function( event ) { 14604 var options = this.options, 14605 keyCode = $.ui.keyCode; 14606 14607 switch ( event.keyCode ) { 14608 case keyCode.UP: 14609 this._repeat( null, 1, event ); 14610 return true; 14611 case keyCode.DOWN: 14612 this._repeat( null, -1, event ); 14613 return true; 14614 case keyCode.PAGE_UP: 14615 this._repeat( null, options.page, event ); 14616 return true; 14617 case keyCode.PAGE_DOWN: 14618 this._repeat( null, -options.page, event ); 14619 return true; 14620 } 14621 14622 return false; 14623 }, 14624 14625 _start: function( event ) { 14626 if ( !this.spinning && this._trigger( "start", event ) === false ) { 14627 return false; 14628 } 14629 14630 if ( !this.counter ) { 14631 this.counter = 1; 14632 } 14633 this.spinning = true; 14634 return true; 14635 }, 14636 14637 _repeat: function( i, steps, event ) { 14638 i = i || 500; 14639 14640 clearTimeout( this.timer ); 14641 this.timer = this._delay( function() { 14642 this._repeat( 40, steps, event ); 14643 }, i ); 14644 14645 this._spin( steps * this.options.step, event ); 14646 }, 14647 14648 _spin: function( step, event ) { 14649 var value = this.value() || 0; 14650 14651 if ( !this.counter ) { 14652 this.counter = 1; 14653 } 14654 14655 value = this._adjustValue( value + step * this._increment( this.counter ) ); 14656 14657 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 14658 this._value( value ); 14659 this.counter++; 14660 } 14661 }, 14662 14663 _increment: function( i ) { 14664 var incremental = this.options.incremental; 14665 14666 if ( incremental ) { 14667 return typeof incremental === "function" ? 14668 incremental( i ) : 14669 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 14670 } 14671 14672 return 1; 14673 }, 14674 14675 _precision: function() { 14676 var precision = this._precisionOf( this.options.step ); 14677 if ( this.options.min !== null ) { 14678 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14679 } 14680 return precision; 14681 }, 14682 14683 _precisionOf: function( num ) { 14684 var str = num.toString(), 14685 decimal = str.indexOf( "." ); 14686 return decimal === -1 ? 0 : str.length - decimal - 1; 14687 }, 14688 14689 _adjustValue: function( value ) { 14690 var base, aboveMin, 14691 options = this.options; 14692 14693 // Make sure we're at a valid step 14694 // - find out where we are relative to the base (min or 0) 14695 base = options.min !== null ? options.min : 0; 14696 aboveMin = value - base; 14697 14698 // - round to the nearest step 14699 aboveMin = Math.round( aboveMin / options.step ) * options.step; 14700 14701 // - rounding is based on 0, so adjust back to our base 14702 value = base + aboveMin; 14703 14704 // Fix precision from bad JS floating point math 14705 value = parseFloat( value.toFixed( this._precision() ) ); 14706 14707 // Clamp the value 14708 if ( options.max !== null && value > options.max ) { 14709 return options.max; 14710 } 14711 if ( options.min !== null && value < options.min ) { 14712 return options.min; 14713 } 14714 14715 return value; 14716 }, 14717 14718 _stop: function( event ) { 14719 if ( !this.spinning ) { 14720 return; 14721 } 14722 14723 clearTimeout( this.timer ); 14724 clearTimeout( this.mousewheelTimer ); 14725 this.counter = 0; 14726 this.spinning = false; 14727 this._trigger( "stop", event ); 14728 }, 14729 14730 _setOption: function( key, value ) { 14731 var prevValue, first, last; 14732 14733 if ( key === "culture" || key === "numberFormat" ) { 14734 prevValue = this._parse( this.element.val() ); 14735 this.options[ key ] = value; 14736 this.element.val( this._format( prevValue ) ); 14737 return; 14738 } 14739 14740 if ( key === "max" || key === "min" || key === "step" ) { 14741 if ( typeof value === "string" ) { 14742 value = this._parse( value ); 14743 } 14744 } 14745 if ( key === "icons" ) { 14746 first = this.buttons.first().find( ".ui-icon" ); 14747 this._removeClass( first, null, this.options.icons.up ); 14748 this._addClass( first, null, value.up ); 14749 last = this.buttons.last().find( ".ui-icon" ); 14750 this._removeClass( last, null, this.options.icons.down ); 14751 this._addClass( last, null, value.down ); 14752 } 14753 14754 this._super( key, value ); 14755 }, 14756 14757 _setOptionDisabled: function( value ) { 14758 this._super( value ); 14759 14760 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 14761 this.element.prop( "disabled", !!value ); 14762 this.buttons.button( value ? "disable" : "enable" ); 14763 }, 14764 14765 _setOptions: spinnerModifier( function( options ) { 14766 this._super( options ); 14767 } ), 14768 14769 _parse: function( val ) { 14770 if ( typeof val === "string" && val !== "" ) { 14771 val = window.Globalize && this.options.numberFormat ? 14772 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 14773 } 14774 return val === "" || isNaN( val ) ? null : val; 14775 }, 14776 14777 _format: function( value ) { 14778 if ( value === "" ) { 14779 return ""; 14780 } 14781 return window.Globalize && this.options.numberFormat ? 14782 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 14783 value; 14784 }, 14785 14786 _refresh: function() { 14787 this.element.attr( { 14788 "aria-valuemin": this.options.min, 14789 "aria-valuemax": this.options.max, 14790 14791 // TODO: what should we do with values that can't be parsed? 14792 "aria-valuenow": this._parse( this.element.val() ) 14793 } ); 14794 }, 14795 14796 isValid: function() { 14797 var value = this.value(); 14798 14799 // Null is invalid 14800 if ( value === null ) { 14801 return false; 14802 } 14803 14804 // If value gets adjusted, it's invalid 14805 return value === this._adjustValue( value ); 14806 }, 14807 14808 // Update the value without triggering change 14809 _value: function( value, allowAny ) { 14810 var parsed; 14811 if ( value !== "" ) { 14812 parsed = this._parse( value ); 14813 if ( parsed !== null ) { 14814 if ( !allowAny ) { 14815 parsed = this._adjustValue( parsed ); 14816 } 14817 value = this._format( parsed ); 14818 } 14819 } 14820 this.element.val( value ); 14821 this._refresh(); 14822 }, 14823 14824 _destroy: function() { 14825 this.element 14826 .prop( "disabled", false ) 14827 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 14828 14829 this.uiSpinner.replaceWith( this.element ); 14830 }, 14831 14832 stepUp: spinnerModifier( function( steps ) { 14833 this._stepUp( steps ); 14834 } ), 14835 _stepUp: function( steps ) { 14836 if ( this._start() ) { 14837 this._spin( ( steps || 1 ) * this.options.step ); 14838 this._stop(); 14839 } 14840 }, 14841 14842 stepDown: spinnerModifier( function( steps ) { 14843 this._stepDown( steps ); 14844 } ), 14845 _stepDown: function( steps ) { 14846 if ( this._start() ) { 14847 this._spin( ( steps || 1 ) * -this.options.step ); 14848 this._stop(); 14849 } 14850 }, 14851 14852 pageUp: spinnerModifier( function( pages ) { 14853 this._stepUp( ( pages || 1 ) * this.options.page ); 14854 } ), 14855 14856 pageDown: spinnerModifier( function( pages ) { 14857 this._stepDown( ( pages || 1 ) * this.options.page ); 14858 } ), 14859 14860 value: function( newVal ) { 14861 if ( !arguments.length ) { 14862 return this._parse( this.element.val() ); 14863 } 14864 spinnerModifier( this._value ).call( this, newVal ); 14865 }, 14866 14867 widget: function() { 14868 return this.uiSpinner; 14869 } 14870} ); 14871 14872// DEPRECATED 14873// TODO: switch return back to widget declaration at top of file when this is removed 14874if ( $.uiBackCompat === true ) { 14875 14876 // Backcompat for spinner html extension points 14877 $.widget( "ui.spinner", $.ui.spinner, { 14878 _enhance: function() { 14879 this.uiSpinner = this.element 14880 .attr( "autocomplete", "off" ) 14881 .wrap( this._uiSpinnerHtml() ) 14882 .parent() 14883 14884 // Add buttons 14885 .append( this._buttonHtml() ); 14886 }, 14887 _uiSpinnerHtml: function() { 14888 return "<span>"; 14889 }, 14890 14891 _buttonHtml: function() { 14892 return "<a></a><a></a>"; 14893 } 14894 } ); 14895} 14896 14897var widgetsSpinner = $.ui.spinner; 14898 14899 14900/*! 14901 * jQuery UI Tabs 1.14.2 14902 * https://jqueryui.com 14903 * 14904 * Copyright OpenJS Foundation and other contributors 14905 * Released under the MIT license. 14906 * https://jquery.org/license 14907 */ 14908 14909//>>label: Tabs 14910//>>group: Widgets 14911//>>description: Transforms a set of container elements into a tab structure. 14912//>>docs: https://api.jqueryui.com/tabs/ 14913//>>demos: https://jqueryui.com/tabs/ 14914//>>css.structure: ../../themes/base/core.css 14915//>>css.structure: ../../themes/base/tabs.css 14916//>>css.theme: ../../themes/base/theme.css 14917 14918 14919$.widget( "ui.tabs", { 14920 version: "1.14.2", 14921 delay: 300, 14922 options: { 14923 active: null, 14924 classes: { 14925 "ui-tabs": "ui-corner-all", 14926 "ui-tabs-nav": "ui-corner-all", 14927 "ui-tabs-panel": "ui-corner-bottom", 14928 "ui-tabs-tab": "ui-corner-top" 14929 }, 14930 collapsible: false, 14931 event: "click", 14932 heightStyle: "content", 14933 hide: null, 14934 show: null, 14935 14936 // Callbacks 14937 activate: null, 14938 beforeActivate: null, 14939 beforeLoad: null, 14940 load: null 14941 }, 14942 14943 _isLocal: function( anchor ) { 14944 var anchorUrl = new URL( anchor.href ), 14945 locationUrl = new URL( location.href ); 14946 14947 return anchor.hash.length > 1 && 14948 14949 // `href` may contain a hash but also username & password; 14950 // we want to ignore them, so we check the three fields 14951 // below instead. 14952 anchorUrl.origin === locationUrl.origin && 14953 anchorUrl.pathname === locationUrl.pathname && 14954 anchorUrl.search === locationUrl.search; 14955 }, 14956 14957 _create: function() { 14958 var that = this, 14959 options = this.options; 14960 14961 this.running = false; 14962 14963 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 14964 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 14965 14966 this._processTabs(); 14967 options.active = this._initialActive(); 14968 14969 // Take disabling tabs via class attribute from HTML 14970 // into account and update option properly. 14971 if ( Array.isArray( options.disabled ) ) { 14972 options.disabled = $.uniqueSort( options.disabled.concat( 14973 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 14974 return that.tabs.index( li ); 14975 } ) 14976 ) ).sort(); 14977 } 14978 14979 // Check for length avoids error when initializing empty list 14980 if ( this.options.active !== false && this.anchors.length ) { 14981 this.active = this._findActive( options.active ); 14982 } else { 14983 this.active = $(); 14984 } 14985 14986 this._refresh(); 14987 14988 if ( this.active.length ) { 14989 this.load( options.active ); 14990 } 14991 }, 14992 14993 _initialActive: function() { 14994 var active = this.options.active, 14995 collapsible = this.options.collapsible, 14996 locationHash = location.hash.substring( 1 ), 14997 locationHashDecoded = decodeURIComponent( locationHash ); 14998 14999 if ( active === null ) { 15000 15001 // check the fragment identifier in the URL 15002 if ( locationHash ) { 15003 this.tabs.each( function( i, tab ) { 15004 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 15005 active = i; 15006 return false; 15007 } 15008 } ); 15009 15010 // If not found, decode the hash & try again. 15011 // See the comment in `_processTabs` under the `_isLocal` check 15012 // for more information. 15013 if ( active === null ) { 15014 this.tabs.each( function( i, tab ) { 15015 if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) { 15016 active = i; 15017 return false; 15018 } 15019 } ); 15020 } 15021 } 15022 15023 // Check for a tab marked active via a class 15024 if ( active === null ) { 15025 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 15026 } 15027 15028 // No active tab, set to false 15029 if ( active === null || active === -1 ) { 15030 active = this.tabs.length ? 0 : false; 15031 } 15032 } 15033 15034 // Handle numbers: negative, out of range 15035 if ( active !== false ) { 15036 active = this.tabs.index( this.tabs.eq( active ) ); 15037 if ( active === -1 ) { 15038 active = collapsible ? false : 0; 15039 } 15040 } 15041 15042 // Don't allow collapsible: false and active: false 15043 if ( !collapsible && active === false && this.anchors.length ) { 15044 active = 0; 15045 } 15046 15047 return active; 15048 }, 15049 15050 _getCreateEventData: function() { 15051 return { 15052 tab: this.active, 15053 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 15054 }; 15055 }, 15056 15057 _tabKeydown: function( event ) { 15058 var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ), 15059 selectedIndex = this.tabs.index( focusedTab ), 15060 goingForward = true; 15061 15062 if ( this._handlePageNav( event ) ) { 15063 return; 15064 } 15065 15066 switch ( event.keyCode ) { 15067 case $.ui.keyCode.RIGHT: 15068 case $.ui.keyCode.DOWN: 15069 selectedIndex++; 15070 break; 15071 case $.ui.keyCode.UP: 15072 case $.ui.keyCode.LEFT: 15073 goingForward = false; 15074 selectedIndex--; 15075 break; 15076 case $.ui.keyCode.END: 15077 selectedIndex = this.anchors.length - 1; 15078 break; 15079 case $.ui.keyCode.HOME: 15080 selectedIndex = 0; 15081 break; 15082 case $.ui.keyCode.SPACE: 15083 15084 // Activate only, no collapsing 15085 event.preventDefault(); 15086 clearTimeout( this.activating ); 15087 this._activate( selectedIndex ); 15088 return; 15089 case $.ui.keyCode.ENTER: 15090 15091 // Toggle (cancel delayed activation, allow collapsing) 15092 event.preventDefault(); 15093 clearTimeout( this.activating ); 15094 15095 // Determine if we should collapse or activate 15096 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 15097 return; 15098 default: 15099 return; 15100 } 15101 15102 // Focus the appropriate tab, based on which key was pressed 15103 event.preventDefault(); 15104 clearTimeout( this.activating ); 15105 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 15106 15107 // Navigating with control/command key will prevent automatic activation 15108 if ( !event.ctrlKey && !event.metaKey ) { 15109 15110 // Update aria-selected immediately so that AT think the tab is already selected. 15111 // Otherwise AT may confuse the user by stating that they need to activate the tab, 15112 // but the tab will already be activated by the time the announcement finishes. 15113 focusedTab.attr( "aria-selected", "false" ); 15114 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 15115 15116 this.activating = this._delay( function() { 15117 this.option( "active", selectedIndex ); 15118 }, this.delay ); 15119 } 15120 }, 15121 15122 _panelKeydown: function( event ) { 15123 if ( this._handlePageNav( event ) ) { 15124 return; 15125 } 15126 15127 // Ctrl+up moves focus to the current tab 15128 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 15129 event.preventDefault(); 15130 this.active.trigger( "focus" ); 15131 } 15132 }, 15133 15134 // Alt+page up/down moves focus to the previous/next tab (and activates) 15135 _handlePageNav: function( event ) { 15136 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 15137 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 15138 return true; 15139 } 15140 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 15141 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 15142 return true; 15143 } 15144 }, 15145 15146 _findNextTab: function( index, goingForward ) { 15147 var lastTabIndex = this.tabs.length - 1; 15148 15149 function constrain() { 15150 if ( index > lastTabIndex ) { 15151 index = 0; 15152 } 15153 if ( index < 0 ) { 15154 index = lastTabIndex; 15155 } 15156 return index; 15157 } 15158 15159 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 15160 index = goingForward ? index + 1 : index - 1; 15161 } 15162 15163 return index; 15164 }, 15165 15166 _focusNextTab: function( index, goingForward ) { 15167 index = this._findNextTab( index, goingForward ); 15168 this.tabs.eq( index ).trigger( "focus" ); 15169 return index; 15170 }, 15171 15172 _setOption: function( key, value ) { 15173 if ( key === "active" ) { 15174 15175 // _activate() will handle invalid values and update this.options 15176 this._activate( value ); 15177 return; 15178 } 15179 15180 this._super( key, value ); 15181 15182 if ( key === "collapsible" ) { 15183 this._toggleClass( "ui-tabs-collapsible", null, value ); 15184 15185 // Setting collapsible: false while collapsed; open first panel 15186 if ( !value && this.options.active === false ) { 15187 this._activate( 0 ); 15188 } 15189 } 15190 15191 if ( key === "event" ) { 15192 this._setupEvents( value ); 15193 } 15194 15195 if ( key === "heightStyle" ) { 15196 this._setupHeightStyle( value ); 15197 } 15198 }, 15199 15200 refresh: function() { 15201 var options = this.options, 15202 lis = this.tablist.children( ":has(a[href])" ); 15203 15204 // Get disabled tabs from class attribute from HTML 15205 // this will get converted to a boolean if needed in _refresh() 15206 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15207 return lis.index( tab ); 15208 } ); 15209 15210 this._processTabs(); 15211 15212 // Was collapsed or no tabs 15213 if ( options.active === false || !this.anchors.length ) { 15214 options.active = false; 15215 this.active = $(); 15216 15217 // was active, but active tab is gone 15218 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15219 15220 // all remaining tabs are disabled 15221 if ( this.tabs.length === options.disabled.length ) { 15222 options.active = false; 15223 this.active = $(); 15224 15225 // activate previous tab 15226 } else { 15227 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15228 } 15229 15230 // was active, active tab still exists 15231 } else { 15232 15233 // make sure active index is correct 15234 options.active = this.tabs.index( this.active ); 15235 } 15236 15237 this._refresh(); 15238 }, 15239 15240 _refresh: function() { 15241 this._setOptionDisabled( this.options.disabled ); 15242 this._setupEvents( this.options.event ); 15243 this._setupHeightStyle( this.options.heightStyle ); 15244 15245 this.tabs.not( this.active ).attr( { 15246 "aria-selected": "false", 15247 "aria-expanded": "false", 15248 tabIndex: -1 15249 } ); 15250 this.panels.not( this._getPanelForTab( this.active ) ) 15251 .hide() 15252 .attr( { 15253 "aria-hidden": "true" 15254 } ); 15255 15256 // Make sure one tab is in the tab order 15257 if ( !this.active.length ) { 15258 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15259 } else { 15260 this.active 15261 .attr( { 15262 "aria-selected": "true", 15263 "aria-expanded": "true", 15264 tabIndex: 0 15265 } ); 15266 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 15267 this._getPanelForTab( this.active ) 15268 .show() 15269 .attr( { 15270 "aria-hidden": "false" 15271 } ); 15272 } 15273 }, 15274 15275 _processTabs: function() { 15276 var that = this, 15277 prevTabs = this.tabs, 15278 prevAnchors = this.anchors, 15279 prevPanels = this.panels; 15280 15281 this.tablist = this._getList().attr( "role", "tablist" ); 15282 this._addClass( this.tablist, "ui-tabs-nav", 15283 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 15284 15285 // Prevent users from focusing disabled tabs via click 15286 this.tablist 15287 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 15288 if ( $( this ).is( ".ui-state-disabled" ) ) { 15289 event.preventDefault(); 15290 } 15291 } ); 15292 15293 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15294 .attr( { 15295 role: "tab", 15296 tabIndex: -1 15297 } ); 15298 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 15299 15300 this.anchors = this.tabs.map( function() { 15301 return $( "a", this )[ 0 ]; 15302 } ) 15303 .attr( { 15304 tabIndex: -1 15305 } ); 15306 this._addClass( this.anchors, "ui-tabs-anchor" ); 15307 15308 this.panels = $(); 15309 15310 this.anchors.each( function( i, anchor ) { 15311 var selector, panel, panelId, 15312 anchorId = $( anchor ).uniqueId().attr( "id" ), 15313 tab = $( anchor ).closest( "li" ), 15314 originalAriaControls = tab.attr( "aria-controls" ); 15315 15316 // Inline tab 15317 if ( that._isLocal( anchor ) ) { 15318 15319 // The "scrolling to a fragment" section of the HTML spec: 15320 // https://html.spec.whatwg.org/#scrolling-to-a-fragment 15321 // uses a concept of document's indicated part: 15322 // https://html.spec.whatwg.org/#the-indicated-part-of-the-document 15323 // Slightly below there's an algorithm to compute the indicated 15324 // part: 15325 // https://html.spec.whatwg.org/#the-indicated-part-of-the-document 15326 // First, the algorithm tries the hash as-is, without decoding. 15327 // Then, if one is not found, the same is attempted with a decoded 15328 // hash. Replicate this logic. 15329 selector = anchor.hash; 15330 panelId = selector.substring( 1 ); 15331 panel = that.element.find( "#" + CSS.escape( panelId ) ); 15332 if ( !panel.length ) { 15333 panelId = decodeURIComponent( panelId ); 15334 panel = that.element.find( "#" + CSS.escape( panelId ) ); 15335 } 15336 15337 // remote tab 15338 } else { 15339 15340 // If the tab doesn't already have aria-controls, 15341 // generate an id by using a throw-away element 15342 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15343 selector = "#" + panelId; 15344 panel = that.element.find( selector ); 15345 if ( !panel.length ) { 15346 panel = that._createPanel( panelId ); 15347 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15348 } 15349 panel.attr( "aria-live", "polite" ); 15350 } 15351 15352 if ( panel.length ) { 15353 that.panels = that.panels.add( panel ); 15354 } 15355 if ( originalAriaControls ) { 15356 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15357 } 15358 tab.attr( { 15359 "aria-controls": panelId, 15360 "aria-labelledby": anchorId 15361 } ); 15362 panel.attr( "aria-labelledby", anchorId ); 15363 } ); 15364 15365 this.panels.attr( "role", "tabpanel" ); 15366 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 15367 15368 // Avoid memory leaks (#10056) 15369 if ( prevTabs ) { 15370 this._off( prevTabs.not( this.tabs ) ); 15371 this._off( prevAnchors.not( this.anchors ) ); 15372 this._off( prevPanels.not( this.panels ) ); 15373 } 15374 }, 15375 15376 // Allow overriding how to find the list for rare usage scenarios (#7715) 15377 _getList: function() { 15378 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 15379 }, 15380 15381 _createPanel: function( id ) { 15382 return $( "<div>" ) 15383 .attr( "id", id ) 15384 .data( "ui-tabs-destroy", true ); 15385 }, 15386 15387 _setOptionDisabled: function( disabled ) { 15388 var currentItem, li, i; 15389 15390 if ( Array.isArray( disabled ) ) { 15391 if ( !disabled.length ) { 15392 disabled = false; 15393 } else if ( disabled.length === this.anchors.length ) { 15394 disabled = true; 15395 } 15396 } 15397 15398 // Disable tabs 15399 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 15400 currentItem = $( li ); 15401 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15402 currentItem.attr( "aria-disabled", "true" ); 15403 this._addClass( currentItem, null, "ui-state-disabled" ); 15404 } else { 15405 currentItem.removeAttr( "aria-disabled" ); 15406 this._removeClass( currentItem, null, "ui-state-disabled" ); 15407 } 15408 } 15409 15410 this.options.disabled = disabled; 15411 15412 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 15413 disabled === true ); 15414 }, 15415 15416 _setupEvents: function( event ) { 15417 var events = {}; 15418 if ( event ) { 15419 $.each( event.split( " " ), function( index, eventName ) { 15420 events[ eventName ] = "_eventHandler"; 15421 } ); 15422 } 15423 15424 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15425 15426 // Always prevent the default action, even when disabled 15427 this._on( true, this.anchors, { 15428 click: function( event ) { 15429 event.preventDefault(); 15430 } 15431 } ); 15432 this._on( this.anchors, events ); 15433 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15434 this._on( this.panels, { keydown: "_panelKeydown" } ); 15435 15436 this._focusable( this.tabs ); 15437 this._hoverable( this.tabs ); 15438 }, 15439 15440 _setupHeightStyle: function( heightStyle ) { 15441 var maxHeight, 15442 parent = this.element.parent(); 15443 15444 if ( heightStyle === "fill" ) { 15445 maxHeight = parent.height(); 15446 maxHeight -= this.element.outerHeight() - this.element.height(); 15447 15448 this.element.siblings( ":visible" ).each( function() { 15449 var elem = $( this ), 15450 position = elem.css( "position" ); 15451 15452 if ( position === "absolute" || position === "fixed" ) { 15453 return; 15454 } 15455 maxHeight -= elem.outerHeight( true ); 15456 } ); 15457 15458 this.element.children().not( this.panels ).each( function() { 15459 maxHeight -= $( this ).outerHeight( true ); 15460 } ); 15461 15462 this.panels.each( function() { 15463 $( this ).height( Math.max( 0, maxHeight - 15464 $( this ).innerHeight() + $( this ).height() ) ); 15465 } ) 15466 .css( "overflow", "auto" ); 15467 } else if ( heightStyle === "auto" ) { 15468 maxHeight = 0; 15469 this.panels.each( function() { 15470 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15471 } ).height( maxHeight ); 15472 } 15473 }, 15474 15475 _eventHandler: function( event ) { 15476 var options = this.options, 15477 active = this.active, 15478 anchor = $( event.currentTarget ), 15479 tab = anchor.closest( "li" ), 15480 clickedIsActive = tab[ 0 ] === active[ 0 ], 15481 collapsing = clickedIsActive && options.collapsible, 15482 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15483 toHide = !active.length ? $() : this._getPanelForTab( active ), 15484 eventData = { 15485 oldTab: active, 15486 oldPanel: toHide, 15487 newTab: collapsing ? $() : tab, 15488 newPanel: toShow 15489 }; 15490 15491 event.preventDefault(); 15492 15493 if ( tab.hasClass( "ui-state-disabled" ) || 15494 15495 // tab is already loading 15496 tab.hasClass( "ui-tabs-loading" ) || 15497 15498 // can't switch durning an animation 15499 this.running || 15500 15501 // click on active header, but not collapsible 15502 ( clickedIsActive && !options.collapsible ) || 15503 15504 // allow canceling activation 15505 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15506 return; 15507 } 15508 15509 options.active = collapsing ? false : this.tabs.index( tab ); 15510 15511 this.active = clickedIsActive ? $() : tab; 15512 if ( this.xhr ) { 15513 this.xhr.abort(); 15514 } 15515 15516 if ( !toHide.length && !toShow.length ) { 15517 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15518 } 15519 15520 if ( toShow.length ) { 15521 this.load( this.tabs.index( tab ), event ); 15522 } 15523 this._toggle( event, eventData ); 15524 }, 15525 15526 // Handles show/hide for selecting tabs 15527 _toggle: function( event, eventData ) { 15528 var that = this, 15529 toShow = eventData.newPanel, 15530 toHide = eventData.oldPanel; 15531 15532 this.running = true; 15533 15534 function complete() { 15535 that.running = false; 15536 that._trigger( "activate", event, eventData ); 15537 } 15538 15539 function show() { 15540 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 15541 15542 if ( toShow.length && that.options.show ) { 15543 that._show( toShow, that.options.show, complete ); 15544 } else { 15545 toShow.show(); 15546 complete(); 15547 } 15548 } 15549 15550 // Start out by hiding, then showing, then completing 15551 if ( toHide.length && this.options.hide ) { 15552 this._hide( toHide, this.options.hide, function() { 15553 that._removeClass( eventData.oldTab.closest( "li" ), 15554 "ui-tabs-active", "ui-state-active" ); 15555 show(); 15556 } ); 15557 } else { 15558 this._removeClass( eventData.oldTab.closest( "li" ), 15559 "ui-tabs-active", "ui-state-active" ); 15560 toHide.hide(); 15561 show(); 15562 } 15563 15564 toHide.attr( "aria-hidden", "true" ); 15565 eventData.oldTab.attr( { 15566 "aria-selected": "false", 15567 "aria-expanded": "false" 15568 } ); 15569 15570 // If we're switching tabs, remove the old tab from the tab order. 15571 // If we're opening from collapsed state, remove the previous tab from the tab order. 15572 // If we're collapsing, then keep the collapsing tab in the tab order. 15573 if ( toShow.length && toHide.length ) { 15574 eventData.oldTab.attr( "tabIndex", -1 ); 15575 } else if ( toShow.length ) { 15576 this.tabs.filter( function() { 15577 return $( this ).attr( "tabIndex" ) === 0; 15578 } ) 15579 .attr( "tabIndex", -1 ); 15580 } 15581 15582 toShow.attr( "aria-hidden", "false" ); 15583 eventData.newTab.attr( { 15584 "aria-selected": "true", 15585 "aria-expanded": "true", 15586 tabIndex: 0 15587 } ); 15588 }, 15589 15590 _activate: function( index ) { 15591 var anchor, 15592 active = this._findActive( index ); 15593 15594 // Trying to activate the already active panel 15595 if ( active[ 0 ] === this.active[ 0 ] ) { 15596 return; 15597 } 15598 15599 // Trying to collapse, simulate a click on the current active header 15600 if ( !active.length ) { 15601 active = this.active; 15602 } 15603 15604 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15605 this._eventHandler( { 15606 target: anchor, 15607 currentTarget: anchor, 15608 preventDefault: $.noop 15609 } ); 15610 }, 15611 15612 _findActive: function( index ) { 15613 return index === false ? $() : this.tabs.eq( index ); 15614 }, 15615 15616 _getIndex: function( index ) { 15617 15618 // meta-function to give users option to provide a href string instead of a numerical index. 15619 if ( typeof index === "string" ) { 15620 index = this.anchors.index( this.anchors.filter( "[href$='" + 15621 CSS.escape( index ) + "']" ) ); 15622 } 15623 15624 return index; 15625 }, 15626 15627 _destroy: function() { 15628 if ( this.xhr ) { 15629 this.xhr.abort(); 15630 } 15631 15632 this.tablist 15633 .removeAttr( "role" ) 15634 .off( this.eventNamespace ); 15635 15636 this.anchors 15637 .removeAttr( "role tabIndex" ) 15638 .removeUniqueId(); 15639 15640 this.tabs.add( this.panels ).each( function() { 15641 if ( $.data( this, "ui-tabs-destroy" ) ) { 15642 $( this ).remove(); 15643 } else { 15644 $( this ).removeAttr( "role tabIndex " + 15645 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 15646 } 15647 } ); 15648 15649 this.tabs.each( function() { 15650 var li = $( this ), 15651 prev = li.data( "ui-tabs-aria-controls" ); 15652 if ( prev ) { 15653 li 15654 .attr( "aria-controls", prev ) 15655 .removeData( "ui-tabs-aria-controls" ); 15656 } else { 15657 li.removeAttr( "aria-controls" ); 15658 } 15659 } ); 15660 15661 this.panels.show(); 15662 15663 if ( this.options.heightStyle !== "content" ) { 15664 this.panels.css( "height", "" ); 15665 } 15666 }, 15667 15668 enable: function( index ) { 15669 var disabled = this.options.disabled; 15670 if ( disabled === false ) { 15671 return; 15672 } 15673 15674 if ( index === undefined ) { 15675 disabled = false; 15676 } else { 15677 index = this._getIndex( index ); 15678 if ( Array.isArray( disabled ) ) { 15679 disabled = $.map( disabled, function( num ) { 15680 return num !== index ? num : null; 15681 } ); 15682 } else { 15683 disabled = $.map( this.tabs, function( li, num ) { 15684 return num !== index ? num : null; 15685 } ); 15686 } 15687 } 15688 this._setOptionDisabled( disabled ); 15689 }, 15690 15691 disable: function( index ) { 15692 var disabled = this.options.disabled; 15693 if ( disabled === true ) { 15694 return; 15695 } 15696 15697 if ( index === undefined ) { 15698 disabled = true; 15699 } else { 15700 index = this._getIndex( index ); 15701 if ( $.inArray( index, disabled ) !== -1 ) { 15702 return; 15703 } 15704 if ( Array.isArray( disabled ) ) { 15705 disabled = $.merge( [ index ], disabled ).sort(); 15706 } else { 15707 disabled = [ index ]; 15708 } 15709 } 15710 this._setOptionDisabled( disabled ); 15711 }, 15712 15713 load: function( index, event ) { 15714 index = this._getIndex( index ); 15715 var that = this, 15716 tab = this.tabs.eq( index ), 15717 anchor = tab.find( ".ui-tabs-anchor" ), 15718 panel = this._getPanelForTab( tab ), 15719 eventData = { 15720 tab: tab, 15721 panel: panel 15722 }, 15723 complete = function( jqXHR, status ) { 15724 if ( status === "abort" ) { 15725 that.panels.stop( false, true ); 15726 } 15727 15728 that._removeClass( tab, "ui-tabs-loading" ); 15729 panel.removeAttr( "aria-busy" ); 15730 15731 if ( jqXHR === that.xhr ) { 15732 delete that.xhr; 15733 } 15734 }; 15735 15736 // Not remote 15737 if ( this._isLocal( anchor[ 0 ] ) ) { 15738 return; 15739 } 15740 15741 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 15742 15743 if ( this.xhr.statusText !== "canceled" ) { 15744 this._addClass( tab, "ui-tabs-loading" ); 15745 panel.attr( "aria-busy", "true" ); 15746 15747 this.xhr 15748 .done( function( response, status, jqXHR ) { 15749 panel.html( response ); 15750 that._trigger( "load", event, eventData ); 15751 15752 complete( jqXHR, status ); 15753 } ) 15754 .fail( function( jqXHR, status ) { 15755 complete( jqXHR, status ); 15756 } ); 15757 } 15758 }, 15759 15760 _ajaxSettings: function( anchor, event, eventData ) { 15761 var that = this; 15762 return { 15763 url: anchor.attr( "href" ), 15764 beforeSend: function( jqXHR, settings ) { 15765 return that._trigger( "beforeLoad", event, 15766 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 15767 } 15768 }; 15769 }, 15770 15771 _getPanelForTab: function( tab ) { 15772 var id = $( tab ).attr( "aria-controls" ); 15773 return this.element.find( "#" + CSS.escape( id ) ); 15774 } 15775} ); 15776 15777// DEPRECATED 15778// TODO: Switch return back to widget declaration at top of file when this is removed 15779if ( $.uiBackCompat === true ) { 15780 15781 // Backcompat for ui-tab class (now ui-tabs-tab) 15782 $.widget( "ui.tabs", $.ui.tabs, { 15783 _processTabs: function() { 15784 this._superApply( arguments ); 15785 this._addClass( this.tabs, "ui-tab" ); 15786 } 15787 } ); 15788} 15789 15790var widgetsTabs = $.ui.tabs; 15791 15792 15793/*! 15794 * jQuery UI Tooltip 1.14.2 15795 * https://jqueryui.com 15796 * 15797 * Copyright OpenJS Foundation and other contributors 15798 * Released under the MIT license. 15799 * https://jquery.org/license 15800 */ 15801 15802//>>label: Tooltip 15803//>>group: Widgets 15804//>>description: Shows additional information for any element on hover or focus. 15805//>>docs: https://api.jqueryui.com/tooltip/ 15806//>>demos: https://jqueryui.com/tooltip/ 15807//>>css.structure: ../../themes/base/core.css 15808//>>css.structure: ../../themes/base/tooltip.css 15809//>>css.theme: ../../themes/base/theme.css 15810 15811
15812if (0)
vendor: 77,811 bytes, lines 15812-18841
15812$.widget( "ui.tooltip", { 15813 version: "1.14.2", 15814 options: { 15815 classes: { 15816 "ui-tooltip": "ui-corner-all ui-widget-shadow" 15817 }, 15818 content: function() { 15819 var title = $( this ).attr( "title" ); 15820 15821 // Escape title, since we're going from an attribute to raw HTML 15822 return $( "<a>" ).text( title ).html(); 15823 }, 15824 hide: true, 15825 15826 // Disabled elements have inconsistent behavior across browsers (#8661) 15827 items: "[title]:not([disabled])", 15828 position: { 15829 my: "left top+15", 15830 at: "left bottom", 15831 collision: "flipfit flip" 15832 }, 15833 show: true, 15834 track: false, 15835 15836 // Callbacks 15837 close: null, 15838 open: null 15839 }, 15840 15841 _addDescribedBy: function( elem, id ) { 15842 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 15843 describedby.push( id ); 15844 elem 15845 .data( "ui-tooltip-id", id ) 15846 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 15847 }, 15848 15849 _removeDescribedBy: function( elem ) { 15850 var id = elem.data( "ui-tooltip-id" ), 15851 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 15852 index = $.inArray( id, describedby ); 15853 15854 if ( index !== -1 ) { 15855 describedby.splice( index, 1 ); 15856 } 15857 15858 elem.removeData( "ui-tooltip-id" ); 15859 describedby = String.prototype.trim.call( describedby.join( " " ) ); 15860 if ( describedby ) { 15861 elem.attr( "aria-describedby", describedby ); 15862 } else { 15863 elem.removeAttr( "aria-describedby" ); 15864 } 15865 }, 15866 15867 _create: function() { 15868 this._on( { 15869 mouseover: "open", 15870 focusin: "open" 15871 } ); 15872 15873 // IDs of generated tooltips, needed for destroy 15874 this.tooltips = {}; 15875 15876 // IDs of parent tooltips where we removed the title attribute 15877 this.parents = {}; 15878 15879 // Append the aria-live region so tooltips announce correctly 15880 this.liveRegion = $( "<div>" ) 15881 .attr( { 15882 role: "log", 15883 "aria-live": "assertive", 15884 "aria-relevant": "additions" 15885 } ) 15886 .appendTo( this.document[ 0 ].body ); 15887 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 15888 15889 this.disabledTitles = $( [] ); 15890 }, 15891 15892 _setOption: function( key, value ) { 15893 var that = this; 15894 15895 this._super( key, value ); 15896 15897 if ( key === "content" ) { 15898 $.each( this.tooltips, function( id, tooltipData ) { 15899 that._updateContent( tooltipData.element ); 15900 } ); 15901 } 15902 }, 15903 15904 _setOptionDisabled: function( value ) { 15905 this[ value ? "_disable" : "_enable" ](); 15906 }, 15907 15908 _disable: function() { 15909 var that = this; 15910 15911 // Close open tooltips 15912 $.each( this.tooltips, function( id, tooltipData ) { 15913 var event = $.Event( "blur" ); 15914 event.target = event.currentTarget = tooltipData.element[ 0 ]; 15915 that.close( event, true ); 15916 } ); 15917 15918 // Remove title attributes to prevent native tooltips 15919 this.disabledTitles = this.disabledTitles.add( 15920 this.element.find( this.options.items ).addBack() 15921 .filter( function() { 15922 var element = $( this ); 15923 if ( element.is( "[title]" ) ) { 15924 return element 15925 .data( "ui-tooltip-title", element.attr( "title" ) ) 15926 .removeAttr( "title" ); 15927 } 15928 } ) 15929 ); 15930 }, 15931 15932 _enable: function() { 15933 15934 // restore title attributes 15935 this.disabledTitles.each( function() { 15936 var element = $( this ); 15937 if ( element.data( "ui-tooltip-title" ) ) { 15938 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15939 } 15940 } ); 15941 this.disabledTitles = $( [] ); 15942 }, 15943 15944 open: function( event ) { 15945 var that = this, 15946 target = $( event ? event.target : this.element ) 15947 15948 // we need closest here due to mouseover bubbling, 15949 // but always pointing at the same event target 15950 .closest( this.options.items ); 15951 15952 // No element to show a tooltip for or the tooltip is already open 15953 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 15954 return; 15955 } 15956 15957 if ( target.attr( "title" ) ) { 15958 target.data( "ui-tooltip-title", target.attr( "title" ) ); 15959 } 15960 15961 target.data( "ui-tooltip-open", true ); 15962 15963 // Kill parent tooltips, custom or native, for hover 15964 if ( event && event.type === "mouseover" ) { 15965 target.parents().each( function() { 15966 var parent = $( this ), 15967 blurEvent; 15968 if ( parent.data( "ui-tooltip-open" ) ) { 15969 blurEvent = $.Event( "blur" ); 15970 blurEvent.target = blurEvent.currentTarget = this; 15971 that.close( blurEvent, true ); 15972 } 15973 if ( parent.attr( "title" ) ) { 15974 parent.uniqueId(); 15975 that.parents[ this.id ] = { 15976 element: this, 15977 title: parent.attr( "title" ) 15978 }; 15979 parent.attr( "title", "" ); 15980 } 15981 } ); 15982 } 15983 15984 this._registerCloseHandlers( event, target ); 15985 this._updateContent( target, event ); 15986 }, 15987 15988 _updateContent: function( target, event ) { 15989 var content, 15990 contentOption = this.options.content, 15991 that = this, 15992 eventType = event ? event.type : null; 15993 15994 if ( typeof contentOption === "string" || contentOption.nodeType || 15995 contentOption.jquery ) { 15996 return this._open( event, target, contentOption ); 15997 } 15998 15999 content = contentOption.call( target[ 0 ], function( response ) { 16000 16001 // Ignore async response if tooltip was closed already 16002 if ( !target.data( "ui-tooltip-open" ) ) { 16003 return; 16004 } 16005 16006 // JQuery creates a special event for focusin when it doesn't 16007 // exist natively. To improve performance, the native event 16008 // object is reused and the type is changed. Therefore, we can't 16009 // rely on the type being correct after the event finished 16010 // bubbling, so we set it back to the previous value. (#8740) 16011 if ( event ) { 16012 event.type = eventType; 16013 } 16014 that._open( event, target, response ); 16015 } ); 16016 if ( content ) { 16017 this._open( event, target, content ); 16018 } 16019 }, 16020 16021 _open: function( event, target, content ) { 16022 var tooltipData, tooltip, delayedShow, a11yContent, 16023 positionOption = $.extend( {}, this.options.position ); 16024 16025 if ( !content ) { 16026 return; 16027 } 16028 16029 // Content can be updated multiple times. If the tooltip already 16030 // exists, then just update the content and bail. 16031 tooltipData = this._find( target ); 16032 if ( tooltipData ) { 16033 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 16034 return; 16035 } 16036 16037 // If we have a title, clear it to prevent the native tooltip 16038 // we have to check first to avoid defining a title if none exists 16039 // (we don't want to cause an element to start matching [title]) 16040 // 16041 // We use removeAttr only for key events, to allow IE to export the correct 16042 // accessible attributes. For mouse events, set to empty string to avoid 16043 // native tooltip showing up (happens only when removing inside mouseover). 16044 if ( target.is( "[title]" ) ) { 16045 if ( event && event.type === "mouseover" ) { 16046 target.attr( "title", "" ); 16047 } else { 16048 target.removeAttr( "title" ); 16049 } 16050 } 16051 16052 tooltipData = this._tooltip( target ); 16053 tooltip = tooltipData.tooltip; 16054 this._addDescribedBy( target, tooltip.attr( "id" ) ); 16055 tooltip.find( ".ui-tooltip-content" ).html( content ); 16056 16057 // Support: Voiceover on OS X, JAWS on IE <= 9 16058 // JAWS announces deletions even when aria-relevant="additions" 16059 // Voiceover will sometimes re-read the entire log region's contents from the beginning 16060 this.liveRegion.children().hide(); 16061 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 16062 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 16063 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 16064 a11yContent.appendTo( this.liveRegion ); 16065 16066 function position( event ) { 16067 positionOption.of = event; 16068 if ( tooltip.is( ":hidden" ) ) { 16069 return; 16070 } 16071 tooltip.position( positionOption ); 16072 } 16073 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 16074 this._on( this.document, { 16075 mousemove: position 16076 } ); 16077 16078 // trigger once to override element-relative positioning 16079 position( event ); 16080 } else { 16081 tooltip.position( $.extend( { 16082 of: target 16083 }, this.options.position ) ); 16084 } 16085 16086 tooltip.hide(); 16087 16088 this._show( tooltip, this.options.show ); 16089 16090 // Handle tracking tooltips that are shown with a delay (#8644). As soon 16091 // as the tooltip is visible, position the tooltip using the most recent 16092 // event. 16093 // Adds the check to add the timers only when both delay and track options are set (#14682) 16094 if ( this.options.track && this.options.show && this.options.show.delay ) { 16095 delayedShow = this.delayedShow = setInterval( function() { 16096 if ( tooltip.is( ":visible" ) ) { 16097 position( positionOption.of ); 16098 clearInterval( delayedShow ); 16099 } 16100 }, 13 ); 16101 } 16102 16103 this._trigger( "open", event, { tooltip: tooltip } ); 16104 }, 16105 16106 _registerCloseHandlers: function( event, target ) { 16107 var events = { 16108 keyup: function( event ) { 16109 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 16110 var fakeEvent = $.Event( event ); 16111 fakeEvent.currentTarget = target[ 0 ]; 16112 this.close( fakeEvent, true ); 16113 } 16114 } 16115 }; 16116 16117 // Only bind remove handler for delegated targets. Non-delegated 16118 // tooltips will handle this in destroy. 16119 if ( target[ 0 ] !== this.element[ 0 ] ) { 16120 events.remove = function() { 16121 var targetElement = this._find( target ); 16122 if ( targetElement ) { 16123 this._removeTooltip( targetElement.tooltip ); 16124 } 16125 }; 16126 } 16127 16128 if ( !event || event.type === "mouseover" ) { 16129 events.mouseleave = "close"; 16130 } 16131 if ( !event || event.type === "focusin" ) { 16132 events.focusout = "close"; 16133 } 16134 this._on( true, target, events ); 16135 }, 16136 16137 close: function( event ) { 16138 var tooltip, 16139 that = this, 16140 target = $( event ? event.currentTarget : this.element ), 16141 tooltipData = this._find( target ); 16142 16143 // The tooltip may already be closed 16144 if ( !tooltipData ) { 16145 16146 // We set ui-tooltip-open immediately upon open (in open()), but only set the 16147 // additional data once there's actually content to show (in _open()). So even if the 16148 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 16149 // the period between open() and _open(). 16150 target.removeData( "ui-tooltip-open" ); 16151 return; 16152 } 16153 16154 tooltip = tooltipData.tooltip; 16155 16156 // Disabling closes the tooltip, so we need to track when we're closing 16157 // to avoid an infinite loop in case the tooltip becomes disabled on close 16158 if ( tooltipData.closing ) { 16159 return; 16160 } 16161 16162 // Clear the interval for delayed tracking tooltips 16163 clearInterval( this.delayedShow ); 16164 16165 // Only set title if we had one before (see comment in _open()) 16166 // If the title attribute has changed since open(), don't restore 16167 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16168 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16169 } 16170 16171 this._removeDescribedBy( target ); 16172 16173 tooltipData.hiding = true; 16174 tooltip.stop( true ); 16175 this._hide( tooltip, this.options.hide, function() { 16176 that._removeTooltip( $( this ) ); 16177 } ); 16178 16179 target.removeData( "ui-tooltip-open" ); 16180 this._off( target, "mouseleave focusout keyup" ); 16181 16182 // Remove 'remove' binding only on delegated targets 16183 if ( target[ 0 ] !== this.element[ 0 ] ) { 16184 this._off( target, "remove" ); 16185 } 16186 this._off( this.document, "mousemove" ); 16187 16188 if ( event && event.type === "mouseleave" ) { 16189 $.each( this.parents, function( id, parent ) { 16190 $( parent.element ).attr( "title", parent.title ); 16191 delete that.parents[ id ]; 16192 } ); 16193 } 16194 16195 tooltipData.closing = true; 16196 this._trigger( "close", event, { tooltip: tooltip } ); 16197 if ( !tooltipData.hiding ) { 16198 tooltipData.closing = false; 16199 } 16200 }, 16201 16202 _tooltip: function( element ) { 16203 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 16204 content = $( "<div>" ).appendTo( tooltip ), 16205 id = tooltip.uniqueId().attr( "id" ); 16206 16207 this._addClass( content, "ui-tooltip-content" ); 16208 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 16209 16210 tooltip.appendTo( this._appendTo( element ) ); 16211 16212 return this.tooltips[ id ] = { 16213 element: element, 16214 tooltip: tooltip 16215 }; 16216 }, 16217 16218 _find: function( target ) { 16219 var id = target.data( "ui-tooltip-id" ); 16220 return id ? this.tooltips[ id ] : null; 16221 }, 16222 16223 _removeTooltip: function( tooltip ) { 16224 16225 // Clear the interval for delayed tracking tooltips 16226 clearInterval( this.delayedShow ); 16227 16228 tooltip.remove(); 16229 delete this.tooltips[ tooltip.attr( "id" ) ]; 16230 }, 16231 16232 _appendTo: function( target ) { 16233 var element = target.closest( ".ui-front, dialog" ); 16234 16235 if ( !element.length ) { 16236 element = this.document[ 0 ].body; 16237 } 16238 16239 return element; 16240 }, 16241 16242 _destroy: function() { 16243 var that = this; 16244 16245 // Close open tooltips 16246 $.each( this.tooltips, function( id, tooltipData ) { 16247 16248 // Delegate to close method to handle common cleanup 16249 var event = $.Event( "blur" ), 16250 element = tooltipData.element; 16251 event.target = event.currentTarget = element[ 0 ]; 16252 that.close( event, true ); 16253 16254 // Remove immediately; destroying an open tooltip doesn't use the 16255 // hide animation 16256 $( "#" + id ).remove(); 16257 16258 // Restore the title 16259 if ( element.data( "ui-tooltip-title" ) ) { 16260 16261 // If the title attribute has changed since open(), don't restore 16262 if ( !element.attr( "title" ) ) { 16263 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16264 } 16265 element.removeData( "ui-tooltip-title" ); 16266 } 16267 } ); 16268 this.liveRegion.remove(); 16269 } 16270} ); 16271 16272// DEPRECATED 16273// TODO: Switch return back to widget declaration at top of file when this is removed 16274if ( $.uiBackCompat === true ) { 16275 16276 // Backcompat for tooltipClass option 16277 $.widget( "ui.tooltip", $.ui.tooltip, { 16278 options: { 16279 tooltipClass: null 16280 }, 16281 _tooltip: function() { 16282 var tooltipData = this._superApply( arguments ); 16283 if ( this.options.tooltipClass ) { 16284 tooltipData.tooltip.addClass( this.options.tooltipClass ); 16285 } 16286 return tooltipData; 16287 } 16288 } ); 16289} 16290 16291var widgetsTooltip = $.ui.tooltip; 16292 16293 16294 16295// Create a local jQuery because jQuery Color relies on it and the 16296// global may not exist with AMD and a custom build (#10199). 16297// This module is a noop if used as a regular AMD module. 16298// eslint-disable-next-line no-unused-vars 16299var jQuery = $; 16300 16301 16302/*! 16303 * jQuery Color Animations v3.0.0 16304 * https://github.com/jquery/jquery-color 16305 * 16306 * Copyright OpenJS Foundation and other contributors 16307 * Released under the MIT license. 16308 * https://jquery.org/license 16309 * 16310 * Date: Wed May 15 16:49:44 2024 +0200 16311 */ 16312 16313 16314 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 16315 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 16316 16317 class2type = {}, 16318 toString = class2type.toString, 16319 16320 // plusequals test for += 100 -= 100 16321 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 16322 16323 // a set of RE's that can match strings and generate color tuples. 16324 stringParsers = [ { 16325 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16326 parse: function( execResult ) { 16327 return [ 16328 execResult[ 1 ], 16329 execResult[ 2 ], 16330 execResult[ 3 ], 16331 execResult[ 4 ] 16332 ]; 16333 } 16334 }, { 16335 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16336 parse: function( execResult ) { 16337 return [ 16338 execResult[ 1 ] * 2.55, 16339 execResult[ 2 ] * 2.55, 16340 execResult[ 3 ] * 2.55, 16341 execResult[ 4 ] 16342 ]; 16343 } 16344 }, { 16345 16346 // this regex ignores A-F because it's compared against an already lowercased string 16347 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 16348 parse: function( execResult ) { 16349 return [ 16350 parseInt( execResult[ 1 ], 16 ), 16351 parseInt( execResult[ 2 ], 16 ), 16352 parseInt( execResult[ 3 ], 16 ), 16353 execResult[ 4 ] ? 16354 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 16355 1 16356 ]; 16357 } 16358 }, { 16359 16360 // this regex ignores A-F because it's compared against an already lowercased string 16361 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 16362 parse: function( execResult ) { 16363 return [ 16364 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 16365 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 16366 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 16367 execResult[ 4 ] ? 16368 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 16369 .toFixed( 2 ) : 16370 1 16371 ]; 16372 } 16373 }, { 16374 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16375 space: "hsla", 16376 parse: function( execResult ) { 16377 return [ 16378 execResult[ 1 ], 16379 execResult[ 2 ] / 100, 16380 execResult[ 3 ] / 100, 16381 execResult[ 4 ] 16382 ]; 16383 } 16384 } ], 16385 16386 // jQuery.Color( ) 16387 color = jQuery.Color = function( color, green, blue, alpha ) { 16388 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 16389 }, 16390 spaces = { 16391 rgba: { 16392 props: { 16393 red: { 16394 idx: 0, 16395 type: "byte" 16396 }, 16397 green: { 16398 idx: 1, 16399 type: "byte" 16400 }, 16401 blue: { 16402 idx: 2, 16403 type: "byte" 16404 } 16405 } 16406 }, 16407 16408 hsla: { 16409 props: { 16410 hue: { 16411 idx: 0, 16412 type: "degrees" 16413 }, 16414 saturation: { 16415 idx: 1, 16416 type: "percent" 16417 }, 16418 lightness: { 16419 idx: 2, 16420 type: "percent" 16421 } 16422 } 16423 } 16424 }, 16425 propTypes = { 16426 "byte": { 16427 floor: true, 16428 max: 255 16429 }, 16430 "percent": { 16431 max: 1 16432 }, 16433 "degrees": { 16434 mod: 360, 16435 floor: true 16436 } 16437 }, 16438 16439 // colors = jQuery.Color.names 16440 colors, 16441 16442 // local aliases of functions called often 16443 each = jQuery.each; 16444 16445// define cache name and alpha properties 16446// for rgba and hsla spaces 16447each( spaces, function( spaceName, space ) { 16448 space.cache = "_" + spaceName; 16449 space.props.alpha = { 16450 idx: 3, 16451 type: "percent", 16452 def: 1 16453 }; 16454} ); 16455 16456// Populate the class2type map 16457jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 16458 function( _i, name ) { 16459 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 16460 } ); 16461 16462function getType( obj ) { 16463 if ( obj == null ) { 16464 return obj + ""; 16465 } 16466 16467 return typeof obj === "object" ? 16468 class2type[ toString.call( obj ) ] || "object" : 16469 typeof obj; 16470} 16471 16472function clamp( value, prop, allowEmpty ) { 16473 var type = propTypes[ prop.type ] || {}; 16474 16475 if ( value == null ) { 16476 return ( allowEmpty || !prop.def ) ? null : prop.def; 16477 } 16478 16479 // ~~ is an short way of doing floor for positive numbers 16480 value = type.floor ? ~~value : parseFloat( value ); 16481 16482 if ( type.mod ) { 16483 16484 // we add mod before modding to make sure that negatives values 16485 // get converted properly: -10 -> 350 16486 return ( value + type.mod ) % type.mod; 16487 } 16488 16489 // for now all property types without mod have min and max 16490 return Math.min( type.max, Math.max( 0, value ) ); 16491} 16492 16493function stringParse( string ) { 16494 var inst = color(), 16495 rgba = inst._rgba = []; 16496 16497 string = string.toLowerCase(); 16498 16499 each( stringParsers, function( _i, parser ) { 16500 var parsed, 16501 match = parser.re.exec( string ), 16502 values = match && parser.parse( match ), 16503 spaceName = parser.space || "rgba"; 16504 16505 if ( values ) { 16506 parsed = inst[ spaceName ]( values ); 16507 16508 // if this was an rgba parse the assignment might happen twice 16509 // oh well.... 16510 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 16511 rgba = inst._rgba = parsed._rgba; 16512 16513 // exit each( stringParsers ) here because we matched 16514 return false; 16515 } 16516 } ); 16517 16518 // Found a stringParser that handled it 16519 if ( rgba.length ) { 16520 16521 // if this came from a parsed string, force "transparent" when alpha is 0 16522 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 16523 if ( rgba.join() === "0,0,0,0" ) { 16524 jQuery.extend( rgba, colors.transparent ); 16525 } 16526 return inst; 16527 } 16528 16529 // named colors 16530 return colors[ string ]; 16531} 16532 16533color.fn = jQuery.extend( color.prototype, { 16534 parse: function( red, green, blue, alpha ) { 16535 if ( red === undefined ) { 16536 this._rgba = [ null, null, null, null ]; 16537 return this; 16538 } 16539 if ( red.jquery || red.nodeType ) { 16540 red = jQuery( red ).css( green ); 16541 green = undefined; 16542 } 16543 16544 var inst = this, 16545 type = getType( red ), 16546 rgba = this._rgba = []; 16547 16548 // more than 1 argument specified - assume ( red, green, blue, alpha ) 16549 if ( green !== undefined ) { 16550 red = [ red, green, blue, alpha ]; 16551 type = "array"; 16552 } 16553 16554 if ( type === "string" ) { 16555 return this.parse( stringParse( red ) || colors._default ); 16556 } 16557 16558 if ( type === "array" ) { 16559 each( spaces.rgba.props, function( _key, prop ) { 16560 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 16561 } ); 16562 return this; 16563 } 16564 16565 if ( type === "object" ) { 16566 if ( red instanceof color ) { 16567 each( spaces, function( _spaceName, space ) { 16568 if ( red[ space.cache ] ) { 16569 inst[ space.cache ] = red[ space.cache ].slice(); 16570 } 16571 } ); 16572 } else { 16573 each( spaces, function( _spaceName, space ) { 16574 var cache = space.cache; 16575 each( space.props, function( key, prop ) { 16576 16577 // if the cache doesn't exist, and we know how to convert 16578 if ( !inst[ cache ] && space.to ) { 16579 16580 // if the value was null, we don't need to copy it 16581 // if the key was alpha, we don't need to copy it either 16582 if ( key === "alpha" || red[ key ] == null ) { 16583 return; 16584 } 16585 inst[ cache ] = space.to( inst._rgba ); 16586 } 16587 16588 // this is the only case where we allow nulls for ALL properties. 16589 // call clamp with alwaysAllowEmpty 16590 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 16591 } ); 16592 16593 // everything defined but alpha? 16594 if ( inst[ cache ] && jQuery.inArray( 16595 null, 16596 inst[ cache ].slice( 0, 3 ) 16597 ) < 0 ) { 16598 16599 // use the default of 1 16600 if ( inst[ cache ][ 3 ] == null ) { 16601 inst[ cache ][ 3 ] = 1; 16602 } 16603 16604 if ( space.from ) { 16605 inst._rgba = space.from( inst[ cache ] ); 16606 } 16607 } 16608 } ); 16609 } 16610 return this; 16611 } 16612 }, 16613 is: function( compare ) { 16614 var is = color( compare ), 16615 same = true, 16616 inst = this; 16617 16618 each( spaces, function( _, space ) { 16619 var localCache, 16620 isCache = is[ space.cache ]; 16621 if ( isCache ) { 16622 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 16623 each( space.props, function( _, prop ) { 16624 if ( isCache[ prop.idx ] != null ) { 16625 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 16626 return same; 16627 } 16628 } ); 16629 } 16630 return same; 16631 } ); 16632 return same; 16633 }, 16634 _space: function() { 16635 var used = [], 16636 inst = this; 16637 each( spaces, function( spaceName, space ) { 16638 if ( inst[ space.cache ] ) { 16639 used.push( spaceName ); 16640 } 16641 } ); 16642 return used.pop(); 16643 }, 16644 transition: function( other, distance ) { 16645 var end = color( other ), 16646 spaceName = end._space(), 16647 space = spaces[ spaceName ], 16648 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 16649 start = startColor[ space.cache ] || space.to( startColor._rgba ), 16650 result = start.slice(); 16651 16652 end = end[ space.cache ]; 16653 each( space.props, function( _key, prop ) { 16654 var index = prop.idx, 16655 startValue = start[ index ], 16656 endValue = end[ index ], 16657 type = propTypes[ prop.type ] || {}; 16658 16659 // if null, don't override start value 16660 if ( endValue === null ) { 16661 return; 16662 } 16663 16664 // if null - use end 16665 if ( startValue === null ) { 16666 result[ index ] = endValue; 16667 } else { 16668 if ( type.mod ) { 16669 if ( endValue - startValue > type.mod / 2 ) { 16670 startValue += type.mod; 16671 } else if ( startValue - endValue > type.mod / 2 ) { 16672 startValue -= type.mod; 16673 } 16674 } 16675 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 16676 } 16677 } ); 16678 return this[ spaceName ]( result ); 16679 }, 16680 blend: function( opaque ) { 16681 16682 // if we are already opaque - return ourself 16683 if ( this._rgba[ 3 ] === 1 ) { 16684 return this; 16685 } 16686 16687 var rgb = this._rgba.slice(), 16688 a = rgb.pop(), 16689 blend = color( opaque )._rgba; 16690 16691 return color( jQuery.map( rgb, function( v, i ) { 16692 return ( 1 - a ) * blend[ i ] + a * v; 16693 } ) ); 16694 }, 16695 toRgbaString: function() { 16696 var prefix = "rgba(", 16697 rgba = jQuery.map( this._rgba, function( v, i ) { 16698 if ( v != null ) { 16699 return v; 16700 } 16701 return i > 2 ? 1 : 0; 16702 } ); 16703 16704 if ( rgba[ 3 ] === 1 ) { 16705 rgba.pop(); 16706 prefix = "rgb("; 16707 } 16708 16709 return prefix + rgba.join( ", " ) + ")"; 16710 }, 16711 toHslaString: function() { 16712 var prefix = "hsla(", 16713 hsla = jQuery.map( this.hsla(), function( v, i ) { 16714 if ( v == null ) { 16715 v = i > 2 ? 1 : 0; 16716 } 16717 16718 // catch 1 and 2 16719 if ( i && i < 3 ) { 16720 v = Math.round( v * 100 ) + "%"; 16721 } 16722 return v; 16723 } ); 16724 16725 if ( hsla[ 3 ] === 1 ) { 16726 hsla.pop(); 16727 prefix = "hsl("; 16728 } 16729 return prefix + hsla.join( ", " ) + ")"; 16730 }, 16731 toHexString: function( includeAlpha ) { 16732 var rgba = this._rgba.slice(), 16733 alpha = rgba.pop(); 16734 16735 if ( includeAlpha ) { 16736 rgba.push( ~~( alpha * 255 ) ); 16737 } 16738 16739 return "#" + jQuery.map( rgba, function( v ) { 16740 16741 // default to 0 when nulls exist 16742 return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 ); 16743 } ).join( "" ); 16744 }, 16745 toString: function() { 16746 return this.toRgbaString(); 16747 } 16748} ); 16749color.fn.parse.prototype = color.fn; 16750 16751// hsla conversions adapted from: 16752// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 16753 16754function hue2rgb( p, q, h ) { 16755 h = ( h + 1 ) % 1; 16756 if ( h * 6 < 1 ) { 16757 return p + ( q - p ) * h * 6; 16758 } 16759 if ( h * 2 < 1 ) { 16760 return q; 16761 } 16762 if ( h * 3 < 2 ) { 16763 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 16764 } 16765 return p; 16766} 16767 16768spaces.hsla.to = function( rgba ) { 16769 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 16770 return [ null, null, null, rgba[ 3 ] ]; 16771 } 16772 var r = rgba[ 0 ] / 255, 16773 g = rgba[ 1 ] / 255, 16774 b = rgba[ 2 ] / 255, 16775 a = rgba[ 3 ], 16776 max = Math.max( r, g, b ), 16777 min = Math.min( r, g, b ), 16778 diff = max - min, 16779 add = max + min, 16780 l = add * 0.5, 16781 h, s; 16782 16783 if ( min === max ) { 16784 h = 0; 16785 } else if ( r === max ) { 16786 h = ( 60 * ( g - b ) / diff ) + 360; 16787 } else if ( g === max ) { 16788 h = ( 60 * ( b - r ) / diff ) + 120; 16789 } else { 16790 h = ( 60 * ( r - g ) / diff ) + 240; 16791 } 16792 16793 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 16794 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 16795 if ( diff === 0 ) { 16796 s = 0; 16797 } else if ( l <= 0.5 ) { 16798 s = diff / add; 16799 } else { 16800 s = diff / ( 2 - add ); 16801 } 16802 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 16803}; 16804 16805spaces.hsla.from = function( hsla ) { 16806 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 16807 return [ null, null, null, hsla[ 3 ] ]; 16808 } 16809 var h = hsla[ 0 ] / 360, 16810 s = hsla[ 1 ], 16811 l = hsla[ 2 ], 16812 a = hsla[ 3 ], 16813 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 16814 p = 2 * l - q; 16815 16816 return [ 16817 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 16818 Math.round( hue2rgb( p, q, h ) * 255 ), 16819 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 16820 a 16821 ]; 16822}; 16823 16824 16825each( spaces, function( spaceName, space ) { 16826 var props = space.props, 16827 cache = space.cache, 16828 to = space.to, 16829 from = space.from; 16830 16831 // makes rgba() and hsla() 16832 color.fn[ spaceName ] = function( value ) { 16833 16834 // generate a cache for this space if it doesn't exist 16835 if ( to && !this[ cache ] ) { 16836 this[ cache ] = to( this._rgba ); 16837 } 16838 if ( value === undefined ) { 16839 return this[ cache ].slice(); 16840 } 16841 16842 var ret, 16843 type = getType( value ), 16844 arr = ( type === "array" || type === "object" ) ? value : arguments, 16845 local = this[ cache ].slice(); 16846 16847 each( props, function( key, prop ) { 16848 var val = arr[ type === "object" ? key : prop.idx ]; 16849 if ( val == null ) { 16850 val = local[ prop.idx ]; 16851 } 16852 local[ prop.idx ] = clamp( val, prop ); 16853 } ); 16854 16855 if ( from ) { 16856 ret = color( from( local ) ); 16857 ret[ cache ] = local; 16858 return ret; 16859 } else { 16860 return color( local ); 16861 } 16862 }; 16863 16864 // makes red() green() blue() alpha() hue() saturation() lightness() 16865 each( props, function( key, prop ) { 16866 16867 // alpha is included in more than one space 16868 if ( color.fn[ key ] ) { 16869 return; 16870 } 16871 color.fn[ key ] = function( value ) { 16872 var local, cur, match, fn, 16873 vtype = getType( value ); 16874 16875 if ( key === "alpha" ) { 16876 fn = this._hsla ? "hsla" : "rgba"; 16877 } else { 16878 fn = spaceName; 16879 } 16880 local = this[ fn ](); 16881 cur = local[ prop.idx ]; 16882 16883 if ( vtype === "undefined" ) { 16884 return cur; 16885 } 16886 16887 if ( vtype === "function" ) { 16888 value = value.call( this, cur ); 16889 vtype = getType( value ); 16890 } 16891 if ( value == null && prop.empty ) { 16892 return this; 16893 } 16894 if ( vtype === "string" ) { 16895 match = rplusequals.exec( value ); 16896 if ( match ) { 16897 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 16898 } 16899 } 16900 local[ prop.idx ] = value; 16901 return this[ fn ]( local ); 16902 }; 16903 } ); 16904} ); 16905 16906// add cssHook and .fx.step function for each named hook. 16907// accept a space separated string of properties 16908color.hook = function( hook ) { 16909 var hooks = hook.split( " " ); 16910 each( hooks, function( _i, hook ) { 16911 jQuery.cssHooks[ hook ] = { 16912 set: function( elem, value ) { 16913 var parsed; 16914 16915 if ( value !== "transparent" && 16916 ( getType( value ) !== "string" || 16917 ( parsed = stringParse( value ) ) ) ) { 16918 value = color( parsed || value ); 16919 value = value.toRgbaString(); 16920 } 16921 elem.style[ hook ] = value; 16922 } 16923 }; 16924 jQuery.fx.step[ hook ] = function( fx ) { 16925 if ( !fx.colorInit ) { 16926 fx.start = color( fx.elem, hook ); 16927 fx.end = color( fx.end ); 16928 fx.colorInit = true; 16929 } 16930 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 16931 }; 16932 } ); 16933 16934}; 16935 16936color.hook( stepHooks ); 16937 16938jQuery.cssHooks.borderColor = { 16939 expand: function( value ) { 16940 var expanded = {}; 16941 16942 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 16943 expanded[ "border" + part + "Color" ] = value; 16944 } ); 16945 return expanded; 16946 } 16947}; 16948 16949// Basic color names only. 16950// Usage of any of the other color names requires adding yourself or including 16951// jquery.color.svg-names.js. 16952colors = jQuery.Color.names = { 16953 16954 // 4.1. Basic color keywords 16955 aqua: "#00ffff", 16956 black: "#000000", 16957 blue: "#0000ff", 16958 fuchsia: "#ff00ff", 16959 gray: "#808080", 16960 green: "#008000", 16961 lime: "#00ff00", 16962 maroon: "#800000", 16963 navy: "#000080", 16964 olive: "#808000", 16965 purple: "#800080", 16966 red: "#ff0000", 16967 silver: "#c0c0c0", 16968 teal: "#008080", 16969 white: "#ffffff", 16970 yellow: "#ffff00", 16971 16972 // 4.2.3. "transparent" color keyword 16973 transparent: [ null, null, null, 0 ], 16974 16975 _default: "#ffffff" 16976}; 16977 16978 16979/*! 16980 * jQuery UI Effects 1.14.2 16981 * https://jqueryui.com 16982 * 16983 * Copyright OpenJS Foundation and other contributors 16984 * Released under the MIT license. 16985 * https://jquery.org/license 16986 */ 16987 16988//>>label: Effects Core 16989//>>group: Effects 16990//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 16991//>>docs: https://api.jqueryui.com/category/effects-core/ 16992//>>demos: https://jqueryui.com/effect/ 16993 16994 16995var dataSpace = "ui-effects-", 16996 dataSpaceStyle = "ui-effects-style", 16997 dataSpaceAnimated = "ui-effects-animated"; 16998 16999$.effects = { 17000 effect: {} 17001}; 17002 17003/******************************************************************************/ 17004/****************************** CLASS ANIMATIONS ******************************/ 17005/******************************************************************************/ 17006( function() { 17007 17008var classAnimationActions = [ "add", "remove", "toggle" ], 17009 shorthandStyles = { 17010 border: 1, 17011 borderBottom: 1, 17012 borderColor: 1, 17013 borderLeft: 1, 17014 borderRight: 1, 17015 borderTop: 1, 17016 borderWidth: 1, 17017 margin: 1, 17018 padding: 1 17019 }; 17020 17021$.each( 17022 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 17023 function( _, prop ) { 17024 $.fx.step[ prop ] = function( fx ) { 17025 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 17026 jQuery.style( fx.elem, prop, fx.end ); 17027 fx.setAttr = true; 17028 } 17029 }; 17030 } 17031); 17032 17033function camelCase( string ) { 17034 return string.replace( /-([\da-z])/gi, function( all, letter ) { 17035 return letter.toUpperCase(); 17036 } ); 17037} 17038 17039function getElementStyles( elem ) { 17040 var key, len, 17041 style = elem.ownerDocument.defaultView.getComputedStyle( elem ), 17042 styles = {}; 17043 17044 len = style.length; 17045 while ( len-- ) { 17046 key = style[ len ]; 17047 if ( typeof style[ key ] === "string" ) { 17048 styles[ camelCase( key ) ] = style[ key ]; 17049 } 17050 } 17051 17052 return styles; 17053} 17054 17055function styleDifference( oldStyle, newStyle ) { 17056 var diff = {}, 17057 name, value; 17058 17059 for ( name in newStyle ) { 17060 value = newStyle[ name ]; 17061 if ( oldStyle[ name ] !== value ) { 17062 if ( !shorthandStyles[ name ] ) { 17063 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 17064 diff[ name ] = value; 17065 } 17066 } 17067 } 17068 } 17069 17070 return diff; 17071} 17072 17073$.effects.animateClass = function( value, duration, easing, callback ) { 17074 var o = $.speed( duration, easing, callback ); 17075 17076 return this.queue( function() { 17077 var animated = $( this ), 17078 baseClass = animated.attr( "class" ) || "", 17079 applyClassChange, 17080 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 17081 17082 // Map the animated objects to store the original styles. 17083 allAnimations = allAnimations.map( function() { 17084 var el = $( this ); 17085 return { 17086 el: el, 17087 start: getElementStyles( this ) 17088 }; 17089 } ); 17090 17091 // Apply class change 17092 applyClassChange = function() { 17093 $.each( classAnimationActions, function( i, action ) { 17094 if ( value[ action ] ) { 17095 animated[ action + "Class" ]( value[ action ] ); 17096 } 17097 } ); 17098 }; 17099 applyClassChange(); 17100 17101 // Map all animated objects again - calculate new styles and diff 17102 allAnimations = allAnimations.map( function() { 17103 this.end = getElementStyles( this.el[ 0 ] ); 17104 this.diff = styleDifference( this.start, this.end ); 17105 return this; 17106 } ); 17107 17108 // Apply original class 17109 animated.attr( "class", baseClass ); 17110 17111 // Map all animated objects again - this time collecting a promise 17112 allAnimations = allAnimations.map( function() { 17113 var styleInfo = this, 17114 dfd = $.Deferred(), 17115 opts = $.extend( {}, o, { 17116 queue: false, 17117 complete: function() { 17118 dfd.resolve( styleInfo ); 17119 } 17120 } ); 17121 17122 this.el.animate( this.diff, opts ); 17123 return dfd.promise(); 17124 } ); 17125 17126 // Once all animations have completed: 17127 $.when.apply( $, allAnimations.get() ).done( function() { 17128 17129 // Set the final class 17130 applyClassChange(); 17131 17132 // For each animated element, 17133 // clear all css properties that were animated 17134 $.each( arguments, function() { 17135 var el = this.el; 17136 $.each( this.diff, function( key ) { 17137 el.css( key, "" ); 17138 } ); 17139 } ); 17140 17141 // This is guarnteed to be there if you use jQuery.speed() 17142 // it also handles dequeuing the next anim... 17143 o.complete.call( animated[ 0 ] ); 17144 } ); 17145 } ); 17146}; 17147 17148$.fn.extend( { 17149 addClass: ( function( orig ) { 17150 return function( classNames, speed, easing, callback ) { 17151 return speed ? 17152 $.effects.animateClass.call( this, 17153 { add: classNames }, speed, easing, callback ) : 17154 orig.apply( this, arguments ); 17155 }; 17156 } )( $.fn.addClass ), 17157 17158 removeClass: ( function( orig ) { 17159 return function( classNames, speed, easing, callback ) { 17160 return arguments.length > 1 ? 17161 $.effects.animateClass.call( this, 17162 { remove: classNames }, speed, easing, callback ) : 17163 orig.apply( this, arguments ); 17164 }; 17165 } )( $.fn.removeClass ), 17166 17167 toggleClass: ( function( orig ) { 17168 return function( classNames, force, speed, easing, callback ) { 17169 if ( typeof force === "boolean" || force === undefined ) { 17170 if ( !speed ) { 17171 17172 // Without speed parameter 17173 return orig.apply( this, arguments ); 17174 } else { 17175 return $.effects.animateClass.call( this, 17176 ( force ? { add: classNames } : { remove: classNames } ), 17177 speed, easing, callback ); 17178 } 17179 } else { 17180 17181 // Without force parameter 17182 return $.effects.animateClass.call( this, 17183 { toggle: classNames }, force, speed, easing ); 17184 } 17185 }; 17186 } )( $.fn.toggleClass ), 17187 17188 switchClass: function( remove, add, speed, easing, callback ) { 17189 return $.effects.animateClass.call( this, { 17190 add: add, 17191 remove: remove 17192 }, speed, easing, callback ); 17193 } 17194} ); 17195 17196} )(); 17197 17198/******************************************************************************/ 17199/*********************************** EFFECTS **********************************/ 17200/******************************************************************************/ 17201 17202( function() { 17203 17204if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 17205 $.expr.pseudos.animated = ( function( orig ) { 17206 return function( elem ) { 17207 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 17208 }; 17209 } )( $.expr.pseudos.animated ); 17210} 17211 17212if ( $.uiBackCompat === true ) { 17213 $.extend( $.effects, { 17214 17215 // Saves a set of properties in a data storage 17216 save: function( element, set ) { 17217 var i = 0, length = set.length; 17218 for ( ; i < length; i++ ) { 17219 if ( set[ i ] !== null ) { 17220 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 17221 } 17222 } 17223 }, 17224 17225 // Restores a set of previously saved properties from a data storage 17226 restore: function( element, set ) { 17227 var val, i = 0, length = set.length; 17228 for ( ; i < length; i++ ) { 17229 if ( set[ i ] !== null ) { 17230 val = element.data( dataSpace + set[ i ] ); 17231 element.css( set[ i ], val ); 17232 } 17233 } 17234 }, 17235 17236 setMode: function( el, mode ) { 17237 if ( mode === "toggle" ) { 17238 mode = el.is( ":hidden" ) ? "show" : "hide"; 17239 } 17240 return mode; 17241 }, 17242 17243 // Wraps the element around a wrapper that copies position properties 17244 createWrapper: function( element ) { 17245 17246 // If the element is already wrapped, return it 17247 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17248 return element.parent(); 17249 } 17250 17251 // Wrap the element 17252 var props = { 17253 width: element.outerWidth( true ), 17254 height: element.outerHeight( true ), 17255 "float": element.css( "float" ) 17256 }, 17257 wrapper = $( "<div></div>" ) 17258 .addClass( "ui-effects-wrapper" ) 17259 .css( { 17260 fontSize: "100%", 17261 background: "transparent", 17262 border: "none", 17263 margin: 0, 17264 padding: 0 17265 } ), 17266 17267 // Store the size in case width/height are defined in % - Fixes #5245 17268 size = { 17269 width: element.width(), 17270 height: element.height() 17271 }, 17272 active = document.activeElement; 17273 17274 // Support: Firefox 17275 // Firefox incorrectly exposes anonymous content 17276 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 17277 try { 17278 // eslint-disable-next-line no-unused-expressions 17279 active.id; 17280 } catch ( _e ) { 17281 active = document.body; 17282 } 17283 17284 element.wrap( wrapper ); 17285 17286 // Fixes #7595 - Elements lose focus when wrapped. 17287 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17288 $( active ).trigger( "focus" ); 17289 } 17290 17291 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 17292 // lose the reference to the wrapped element 17293 wrapper = element.parent(); 17294 17295 // Transfer positioning properties to the wrapper 17296 if ( element.css( "position" ) === "static" ) { 17297 wrapper.css( { position: "relative" } ); 17298 element.css( { position: "relative" } ); 17299 } else { 17300 $.extend( props, { 17301 position: element.css( "position" ), 17302 zIndex: element.css( "z-index" ) 17303 } ); 17304 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 17305 props[ pos ] = element.css( pos ); 17306 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 17307 props[ pos ] = "auto"; 17308 } 17309 } ); 17310 element.css( { 17311 position: "relative", 17312 top: 0, 17313 left: 0, 17314 right: "auto", 17315 bottom: "auto" 17316 } ); 17317 } 17318 element.css( size ); 17319 17320 return wrapper.css( props ).show(); 17321 }, 17322 17323 removeWrapper: function( element ) { 17324 var active = document.activeElement; 17325 17326 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17327 element.parent().replaceWith( element ); 17328 17329 // Fixes #7595 - Elements lose focus when wrapped. 17330 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17331 $( active ).trigger( "focus" ); 17332 } 17333 } 17334 17335 return element; 17336 } 17337 } ); 17338} 17339 17340$.extend( $.effects, { 17341 version: "1.14.2", 17342 17343 define: function( name, mode, effect ) { 17344 if ( !effect ) { 17345 effect = mode; 17346 mode = "effect"; 17347 } 17348 17349 $.effects.effect[ name ] = effect; 17350 $.effects.effect[ name ].mode = mode; 17351 17352 return effect; 17353 }, 17354 17355 scaledDimensions: function( element, percent, direction ) { 17356 if ( percent === 0 ) { 17357 return { 17358 height: 0, 17359 width: 0, 17360 outerHeight: 0, 17361 outerWidth: 0 17362 }; 17363 } 17364 17365 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 17366 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 17367 17368 return { 17369 height: element.height() * y, 17370 width: element.width() * x, 17371 outerHeight: element.outerHeight() * y, 17372 outerWidth: element.outerWidth() * x 17373 }; 17374 17375 }, 17376 17377 clipToBox: function( animation ) { 17378 return { 17379 width: animation.clip.right - animation.clip.left, 17380 height: animation.clip.bottom - animation.clip.top, 17381 left: animation.clip.left, 17382 top: animation.clip.top 17383 }; 17384 }, 17385 17386 // Injects recently queued functions to be first in line (after "inprogress") 17387 unshift: function( element, queueLength, count ) { 17388 var queue = element.queue(); 17389 17390 if ( queueLength > 1 ) { 17391 queue.splice.apply( queue, 17392 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 17393 } 17394 element.dequeue(); 17395 }, 17396 17397 saveStyle: function( element ) { 17398 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 17399 }, 17400 17401 restoreStyle: function( element ) { 17402 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 17403 element.removeData( dataSpaceStyle ); 17404 }, 17405 17406 mode: function( element, mode ) { 17407 var hidden = element.is( ":hidden" ); 17408 17409 if ( mode === "toggle" ) { 17410 mode = hidden ? "show" : "hide"; 17411 } 17412 if ( hidden ? mode === "hide" : mode === "show" ) { 17413 mode = "none"; 17414 } 17415 return mode; 17416 }, 17417 17418 // Translates a [top,left] array into a baseline value 17419 getBaseline: function( origin, original ) { 17420 var y, x; 17421 17422 switch ( origin[ 0 ] ) { 17423 case "top": 17424 y = 0; 17425 break; 17426 case "middle": 17427 y = 0.5; 17428 break; 17429 case "bottom": 17430 y = 1; 17431 break; 17432 default: 17433 y = origin[ 0 ] / original.height; 17434 } 17435 17436 switch ( origin[ 1 ] ) { 17437 case "left": 17438 x = 0; 17439 break; 17440 case "center": 17441 x = 0.5; 17442 break; 17443 case "right": 17444 x = 1; 17445 break; 17446 default: 17447 x = origin[ 1 ] / original.width; 17448 } 17449 17450 return { 17451 x: x, 17452 y: y 17453 }; 17454 }, 17455 17456 // Creates a placeholder element so that the original element can be made absolute 17457 createPlaceholder: function( element ) { 17458 var placeholder, 17459 cssPosition = element.css( "position" ), 17460 position = element.position(); 17461 17462 // Lock in margins first to account for form elements, which 17463 // will change margin if you explicitly set height 17464 // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 17465 // Support: Safari 17466 element.css( { 17467 marginTop: element.css( "marginTop" ), 17468 marginBottom: element.css( "marginBottom" ), 17469 marginLeft: element.css( "marginLeft" ), 17470 marginRight: element.css( "marginRight" ) 17471 } ) 17472 .outerWidth( element.outerWidth() ) 17473 .outerHeight( element.outerHeight() ); 17474 17475 if ( /^(static|relative)/.test( cssPosition ) ) { 17476 cssPosition = "absolute"; 17477 17478 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 17479 17480 // Convert inline to inline block to account for inline elements 17481 // that turn to inline block based on content (like img) 17482 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 17483 "inline-block" : 17484 "block", 17485 visibility: "hidden", 17486 17487 // Margins need to be set to account for margin collapse 17488 marginTop: element.css( "marginTop" ), 17489 marginBottom: element.css( "marginBottom" ), 17490 marginLeft: element.css( "marginLeft" ), 17491 marginRight: element.css( "marginRight" ), 17492 "float": element.css( "float" ) 17493 } ) 17494 .outerWidth( element.outerWidth() ) 17495 .outerHeight( element.outerHeight() ) 17496 .addClass( "ui-effects-placeholder" ); 17497 17498 element.data( dataSpace + "placeholder", placeholder ); 17499 } 17500 17501 element.css( { 17502 position: cssPosition, 17503 left: position.left, 17504 top: position.top 17505 } ); 17506 17507 return placeholder; 17508 }, 17509 17510 removePlaceholder: function( element ) { 17511 var dataKey = dataSpace + "placeholder", 17512 placeholder = element.data( dataKey ); 17513 17514 if ( placeholder ) { 17515 placeholder.remove(); 17516 element.removeData( dataKey ); 17517 } 17518 }, 17519 17520 // Removes a placeholder if it exists and restores 17521 // properties that were modified during placeholder creation 17522 cleanUp: function( element ) { 17523 $.effects.restoreStyle( element ); 17524 $.effects.removePlaceholder( element ); 17525 }, 17526 17527 setTransition: function( element, list, factor, value ) { 17528 value = value || {}; 17529 $.each( list, function( i, x ) { 17530 var unit = element.cssUnit( x ); 17531 if ( unit[ 0 ] > 0 ) { 17532 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 17533 } 17534 } ); 17535 return value; 17536 } 17537} ); 17538 17539// Return an effect options object for the given parameters: 17540function _normalizeArguments( effect, options, speed, callback ) { 17541 17542 // Allow passing all options as the first parameter 17543 if ( $.isPlainObject( effect ) ) { 17544 options = effect; 17545 effect = effect.effect; 17546 } 17547 17548 // Convert to an object 17549 effect = { effect: effect }; 17550 17551 // Catch (effect, null, ...) 17552 if ( options == null ) { 17553 options = {}; 17554 } 17555 17556 // Catch (effect, callback) 17557 if ( typeof options === "function" ) { 17558 callback = options; 17559 speed = null; 17560 options = {}; 17561 } 17562 17563 // Catch (effect, speed, ?) 17564 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 17565 callback = speed; 17566 speed = options; 17567 options = {}; 17568 } 17569 17570 // Catch (effect, options, callback) 17571 if ( typeof speed === "function" ) { 17572 callback = speed; 17573 speed = null; 17574 } 17575 17576 // Add options to effect 17577 if ( options ) { 17578 $.extend( effect, options ); 17579 } 17580 17581 speed = speed || options.duration; 17582 effect.duration = $.fx.off ? 0 : 17583 typeof speed === "number" ? speed : 17584 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 17585 $.fx.speeds._default; 17586 17587 effect.complete = callback || options.complete; 17588 17589 return effect; 17590} 17591 17592function standardAnimationOption( option ) { 17593 17594 // Valid standard speeds (nothing, number, named speed) 17595 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 17596 return true; 17597 } 17598 17599 // Invalid strings - treat as "normal" speed 17600 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 17601 return true; 17602 } 17603 17604 // Complete callback 17605 if ( typeof option === "function" ) { 17606 return true; 17607 } 17608 17609 // Options hash (but not naming an effect) 17610 if ( typeof option === "object" && !option.effect ) { 17611 return true; 17612 } 17613 17614 // Didn't match any standard API 17615 return false; 17616} 17617 17618$.fn.extend( { 17619 effect: function( /* effect, options, speed, callback */ ) { 17620 var args = _normalizeArguments.apply( this, arguments ), 17621 effectMethod = $.effects.effect[ args.effect ], 17622 defaultMode = effectMethod.mode, 17623 queue = args.queue, 17624 queueName = queue || "fx", 17625 complete = args.complete, 17626 mode = args.mode, 17627 modes = [], 17628 prefilter = function( next ) { 17629 var el = $( this ), 17630 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 17631 17632 // Sentinel for duck-punching the :animated pseudo-selector 17633 el.data( dataSpaceAnimated, true ); 17634 17635 // Save effect mode for later use, 17636 // we can't just call $.effects.mode again later, 17637 // as the .show() below destroys the initial state 17638 modes.push( normalizedMode ); 17639 17640 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 17641 if ( defaultMode && ( normalizedMode === "show" || 17642 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 17643 el.show(); 17644 } 17645 17646 if ( !defaultMode || normalizedMode !== "none" ) { 17647 $.effects.saveStyle( el ); 17648 } 17649 17650 if ( typeof next === "function" ) { 17651 next(); 17652 } 17653 }; 17654 17655 if ( $.fx.off || !effectMethod ) { 17656 17657 // Delegate to the original method (e.g., .show()) if possible 17658 if ( mode ) { 17659 return this[ mode ]( args.duration, complete ); 17660 } else { 17661 return this.each( function() { 17662 if ( complete ) { 17663 complete.call( this ); 17664 } 17665 } ); 17666 } 17667 } 17668 17669 function run( next ) { 17670 var elem = $( this ); 17671 17672 function cleanup() { 17673 elem.removeData( dataSpaceAnimated ); 17674 17675 $.effects.cleanUp( elem ); 17676 17677 if ( args.mode === "hide" ) { 17678 elem.hide(); 17679 } 17680 17681 done(); 17682 } 17683 17684 function done() { 17685 if ( typeof complete === "function" ) { 17686 complete.call( elem[ 0 ] ); 17687 } 17688 17689 if ( typeof next === "function" ) { 17690 next(); 17691 } 17692 } 17693 17694 // Override mode option on a per element basis, 17695 // as toggle can be either show or hide depending on element state 17696 args.mode = modes.shift(); 17697 17698 if ( $.uiBackCompat === true && !defaultMode ) { 17699 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 17700 17701 // Call the core method to track "olddisplay" properly 17702 elem[ mode ](); 17703 done(); 17704 } else { 17705 effectMethod.call( elem[ 0 ], args, done ); 17706 } 17707 } else { 17708 if ( args.mode === "none" ) { 17709 17710 // Call the core method to track "olddisplay" properly 17711 elem[ mode ](); 17712 done(); 17713 } else { 17714 effectMethod.call( elem[ 0 ], args, cleanup ); 17715 } 17716 } 17717 } 17718 17719 // Run prefilter on all elements first to ensure that 17720 // any showing or hiding happens before placeholder creation, 17721 // which ensures that any layout changes are correctly captured. 17722 return queue === false ? 17723 this.each( prefilter ).each( run ) : 17724 this.queue( queueName, prefilter ).queue( queueName, run ); 17725 }, 17726 17727 show: ( function( orig ) { 17728 return function( option ) { 17729 if ( standardAnimationOption( option ) ) { 17730 return orig.apply( this, arguments ); 17731 } else { 17732 var args = _normalizeArguments.apply( this, arguments ); 17733 args.mode = "show"; 17734 return this.effect.call( this, args ); 17735 } 17736 }; 17737 } )( $.fn.show ), 17738 17739 hide: ( function( orig ) { 17740 return function( option ) { 17741 if ( standardAnimationOption( option ) ) { 17742 return orig.apply( this, arguments ); 17743 } else { 17744 var args = _normalizeArguments.apply( this, arguments ); 17745 args.mode = "hide"; 17746 return this.effect.call( this, args ); 17747 } 17748 }; 17749 } )( $.fn.hide ), 17750 17751 toggle: ( function( orig ) { 17752 return function( option ) { 17753 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 17754 return orig.apply( this, arguments ); 17755 } else { 17756 var args = _normalizeArguments.apply( this, arguments ); 17757 args.mode = "toggle"; 17758 return this.effect.call( this, args ); 17759 } 17760 }; 17761 } )( $.fn.toggle ), 17762 17763 cssUnit: function( key ) { 17764 var style = this.css( key ), 17765 val = []; 17766 17767 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 17768 if ( style.indexOf( unit ) > 0 ) { 17769 val = [ parseFloat( style ), unit ]; 17770 } 17771 } ); 17772 return val; 17773 }, 17774 17775 cssClip: function( clipObj ) { 17776 if ( clipObj ) { 17777 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 17778 clipObj.bottom + "px " + clipObj.left + "px)" ); 17779 } 17780 return parseClip( this.css( "clip" ), this ); 17781 }, 17782 17783 transfer: function( options, done ) { 17784 var element = $( this ), 17785 target = $( options.to ), 17786 targetFixed = target.css( "position" ) === "fixed", 17787 body = $( "body" ), 17788 fixTop = targetFixed ? body.scrollTop() : 0, 17789 fixLeft = targetFixed ? body.scrollLeft() : 0, 17790 endPosition = target.offset(), 17791 animation = { 17792 top: endPosition.top - fixTop, 17793 left: endPosition.left - fixLeft, 17794 height: target.innerHeight(), 17795 width: target.innerWidth() 17796 }, 17797 startPosition = element.offset(), 17798 transfer = $( "<div class='ui-effects-transfer'></div>" ); 17799 17800 transfer 17801 .appendTo( "body" ) 17802 .addClass( options.className ) 17803 .css( { 17804 top: startPosition.top - fixTop, 17805 left: startPosition.left - fixLeft, 17806 height: element.innerHeight(), 17807 width: element.innerWidth(), 17808 position: targetFixed ? "fixed" : "absolute" 17809 } ) 17810 .animate( animation, options.duration, options.easing, function() { 17811 transfer.remove(); 17812 if ( typeof done === "function" ) { 17813 done(); 17814 } 17815 } ); 17816 } 17817} ); 17818 17819function parseClip( str, element ) { 17820 var outerWidth = element.outerWidth(), 17821 outerHeight = element.outerHeight(), 17822 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, 17823 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 17824 17825 return { 17826 top: parseFloat( values[ 1 ] ) || 0, 17827 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 17828 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 17829 left: parseFloat( values[ 4 ] ) || 0 17830 }; 17831} 17832 17833$.fx.step.clip = function( fx ) { 17834 if ( !fx.clipInit ) { 17835 fx.start = $( fx.elem ).cssClip(); 17836 if ( typeof fx.end === "string" ) { 17837 fx.end = parseClip( fx.end, fx.elem ); 17838 } 17839 fx.clipInit = true; 17840 } 17841 17842 $( fx.elem ).cssClip( { 17843 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 17844 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 17845 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 17846 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 17847 } ); 17848}; 17849 17850} )(); 17851 17852/******************************************************************************/ 17853/*********************************** EASING ***********************************/ 17854/******************************************************************************/ 17855 17856( function() { 17857 17858// Based on easing equations from Robert Penner (http://robertpenner.com/easing) 17859 17860var baseEasings = {}; 17861 17862$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 17863 baseEasings[ name ] = function( p ) { 17864 return Math.pow( p, i + 2 ); 17865 }; 17866} ); 17867 17868$.extend( baseEasings, { 17869 Sine: function( p ) { 17870 return 1 - Math.cos( p * Math.PI / 2 ); 17871 }, 17872 Circ: function( p ) { 17873 return 1 - Math.sqrt( 1 - p * p ); 17874 }, 17875 Elastic: function( p ) { 17876 return p === 0 || p === 1 ? p : 17877 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 17878 }, 17879 Back: function( p ) { 17880 return p * p * ( 3 * p - 2 ); 17881 }, 17882 Bounce: function( p ) { 17883 var pow2, 17884 bounce = 4; 17885 17886 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 17887 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 17888 } 17889} ); 17890 17891$.each( baseEasings, function( name, easeIn ) { 17892 $.easing[ "easeIn" + name ] = easeIn; 17893 $.easing[ "easeOut" + name ] = function( p ) { 17894 return 1 - easeIn( 1 - p ); 17895 }; 17896 $.easing[ "easeInOut" + name ] = function( p ) { 17897 return p < 0.5 ? 17898 easeIn( p * 2 ) / 2 : 17899 1 - easeIn( p * -2 + 2 ) / 2; 17900 }; 17901} ); 17902 17903} )(); 17904 17905var effect = $.effects; 17906 17907 17908/*! 17909 * jQuery UI Effects Blind 1.14.2 17910 * https://jqueryui.com 17911 * 17912 * Copyright OpenJS Foundation and other contributors 17913 * Released under the MIT license. 17914 * https://jquery.org/license 17915 */ 17916 17917//>>label: Blind Effect 17918//>>group: Effects 17919//>>description: Blinds the element. 17920//>>docs: https://api.jqueryui.com/blind-effect/ 17921//>>demos: https://jqueryui.com/effect/ 17922 17923 17924var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 17925 var map = { 17926 up: [ "bottom", "top" ], 17927 vertical: [ "bottom", "top" ], 17928 down: [ "top", "bottom" ], 17929 left: [ "right", "left" ], 17930 horizontal: [ "right", "left" ], 17931 right: [ "left", "right" ] 17932 }, 17933 element = $( this ), 17934 direction = options.direction || "up", 17935 start = element.cssClip(), 17936 animate = { clip: $.extend( {}, start ) }, 17937 placeholder = $.effects.createPlaceholder( element ); 17938 17939 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 17940 17941 if ( options.mode === "show" ) { 17942 element.cssClip( animate.clip ); 17943 if ( placeholder ) { 17944 placeholder.css( $.effects.clipToBox( animate ) ); 17945 } 17946 17947 animate.clip = start; 17948 } 17949 17950 if ( placeholder ) { 17951 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 17952 } 17953 17954 element.animate( animate, { 17955 queue: false, 17956 duration: options.duration, 17957 easing: options.easing, 17958 complete: done 17959 } ); 17960} ); 17961 17962 17963/*! 17964 * jQuery UI Effects Bounce 1.14.2 17965 * https://jqueryui.com 17966 * 17967 * Copyright OpenJS Foundation and other contributors 17968 * Released under the MIT license. 17969 * https://jquery.org/license 17970 */ 17971 17972//>>label: Bounce Effect 17973//>>group: Effects 17974//>>description: Bounces an element horizontally or vertically n times. 17975//>>docs: https://api.jqueryui.com/bounce-effect/ 17976//>>demos: https://jqueryui.com/effect/ 17977 17978 17979var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 17980 var upAnim, downAnim, refValue, 17981 element = $( this ), 17982 17983 // Defaults: 17984 mode = options.mode, 17985 hide = mode === "hide", 17986 show = mode === "show", 17987 direction = options.direction || "up", 17988 distance = options.distance, 17989 times = options.times || 5, 17990 17991 // Number of internal animations 17992 anims = times * 2 + ( show || hide ? 1 : 0 ), 17993 speed = options.duration / anims, 17994 easing = options.easing, 17995 17996 // Utility: 17997 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17998 motion = ( direction === "up" || direction === "left" ), 17999 i = 0, 18000 18001 queuelen = element.queue().length; 18002 18003 $.effects.createPlaceholder( element ); 18004 18005 refValue = element.css( ref ); 18006 18007 // Default distance for the BIGGEST bounce is the outer Distance / 3 18008 if ( !distance ) { 18009 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 18010 } 18011 18012 if ( show ) { 18013 downAnim = { opacity: 1 }; 18014 downAnim[ ref ] = refValue; 18015 18016 // If we are showing, force opacity 0 and set the initial position 18017 // then do the "first" animation 18018 element 18019 .css( "opacity", 0 ) 18020 .css( ref, motion ? -distance * 2 : distance * 2 ) 18021 .animate( downAnim, speed, easing ); 18022 } 18023 18024 // Start at the smallest distance if we are hiding 18025 if ( hide ) { 18026 distance = distance / Math.pow( 2, times - 1 ); 18027 } 18028 18029 downAnim = {}; 18030 downAnim[ ref ] = refValue; 18031 18032 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 18033 for ( ; i < times; i++ ) { 18034 upAnim = {}; 18035 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 18036 18037 element 18038 .animate( upAnim, speed, easing ) 18039 .animate( downAnim, speed, easing ); 18040 18041 distance = hide ? distance * 2 : distance / 2; 18042 } 18043 18044 // Last Bounce when Hiding 18045 if ( hide ) { 18046 upAnim = { opacity: 0 }; 18047 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 18048 18049 element.animate( upAnim, speed, easing ); 18050 } 18051 18052 element.queue( done ); 18053 18054 $.effects.unshift( element, queuelen, anims + 1 ); 18055} ); 18056 18057 18058/*! 18059 * jQuery UI Effects Clip 1.14.2 18060 * https://jqueryui.com 18061 * 18062 * Copyright OpenJS Foundation and other contributors 18063 * Released under the MIT license. 18064 * https://jquery.org/license 18065 */ 18066 18067//>>label: Clip Effect 18068//>>group: Effects 18069//>>description: Clips the element on and off like an old TV. 18070//>>docs: https://api.jqueryui.com/clip-effect/ 18071//>>demos: https://jqueryui.com/effect/ 18072 18073 18074var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 18075 var start, 18076 animate = {}, 18077 element = $( this ), 18078 direction = options.direction || "vertical", 18079 both = direction === "both", 18080 horizontal = both || direction === "horizontal", 18081 vertical = both || direction === "vertical"; 18082 18083 start = element.cssClip(); 18084 animate.clip = { 18085 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 18086 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 18087 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 18088 left: horizontal ? ( start.right - start.left ) / 2 : start.left 18089 }; 18090 18091 $.effects.createPlaceholder( element ); 18092 18093 if ( options.mode === "show" ) { 18094 element.cssClip( animate.clip ); 18095 animate.clip = start; 18096 } 18097 18098 element.animate( animate, { 18099 queue: false, 18100 duration: options.duration, 18101 easing: options.easing, 18102 complete: done 18103 } ); 18104 18105} ); 18106 18107 18108/*! 18109 * jQuery UI Effects Drop 1.14.2 18110 * https://jqueryui.com 18111 * 18112 * Copyright OpenJS Foundation and other contributors 18113 * Released under the MIT license. 18114 * https://jquery.org/license 18115 */ 18116 18117//>>label: Drop Effect 18118//>>group: Effects 18119//>>description: Moves an element in one direction and hides it at the same time. 18120//>>docs: https://api.jqueryui.com/drop-effect/ 18121//>>demos: https://jqueryui.com/effect/ 18122 18123 18124var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 18125 18126 var distance, 18127 element = $( this ), 18128 mode = options.mode, 18129 show = mode === "show", 18130 direction = options.direction || "left", 18131 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18132 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 18133 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 18134 animation = { 18135 opacity: 0 18136 }; 18137 18138 $.effects.createPlaceholder( element ); 18139 18140 distance = options.distance || 18141 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 18142 18143 animation[ ref ] = motion + distance; 18144 18145 if ( show ) { 18146 element.css( animation ); 18147 18148 animation[ ref ] = oppositeMotion + distance; 18149 animation.opacity = 1; 18150 } 18151 18152 // Animate 18153 element.animate( animation, { 18154 queue: false, 18155 duration: options.duration, 18156 easing: options.easing, 18157 complete: done 18158 } ); 18159} ); 18160 18161 18162/*! 18163 * jQuery UI Effects Explode 1.14.2 18164 * https://jqueryui.com 18165 * 18166 * Copyright OpenJS Foundation and other contributors 18167 * Released under the MIT license. 18168 * https://jquery.org/license 18169 */ 18170 18171//>>label: Explode Effect 18172//>>group: Effects 18173//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 18174//>>docs: https://api.jqueryui.com/explode-effect/ 18175//>>demos: https://jqueryui.com/effect/ 18176 18177 18178var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 18179 18180 var i, j, left, top, mx, my, 18181 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 18182 cells = rows, 18183 element = $( this ), 18184 mode = options.mode, 18185 show = mode === "show", 18186 18187 // Show and then visibility:hidden the element before calculating offset 18188 offset = element.show().css( "visibility", "hidden" ).offset(), 18189 18190 // Width and height of a piece 18191 width = Math.ceil( element.outerWidth() / cells ), 18192 height = Math.ceil( element.outerHeight() / rows ), 18193 pieces = []; 18194 18195 // Children animate complete: 18196 function childComplete() { 18197 pieces.push( this ); 18198 if ( pieces.length === rows * cells ) { 18199 animComplete(); 18200 } 18201 } 18202 18203 // Clone the element for each row and cell. 18204 for ( i = 0; i < rows; i++ ) { // ===> 18205 top = offset.top + i * height; 18206 my = i - ( rows - 1 ) / 2; 18207 18208 for ( j = 0; j < cells; j++ ) { // ||| 18209 left = offset.left + j * width; 18210 mx = j - ( cells - 1 ) / 2; 18211 18212 // Create a clone of the now hidden main element that will be absolute positioned 18213 // within a wrapper div off the -left and -top equal to size of our pieces 18214 element 18215 .clone() 18216 .appendTo( "body" ) 18217 .wrap( "<div></div>" ) 18218 .css( { 18219 position: "absolute", 18220 visibility: "visible", 18221 left: -j * width, 18222 top: -i * height 18223 } ) 18224 18225 // Select the wrapper - make it overflow: hidden and absolute positioned based on 18226 // where the original was located +left and +top equal to the size of pieces 18227 .parent() 18228 .addClass( "ui-effects-explode" ) 18229 .css( { 18230 position: "absolute", 18231 overflow: "hidden", 18232 width: width, 18233 height: height, 18234 left: left + ( show ? mx * width : 0 ), 18235 top: top + ( show ? my * height : 0 ), 18236 opacity: show ? 0 : 1 18237 } ) 18238 .animate( { 18239 left: left + ( show ? 0 : mx * width ), 18240 top: top + ( show ? 0 : my * height ), 18241 opacity: show ? 1 : 0 18242 }, options.duration || 500, options.easing, childComplete ); 18243 } 18244 } 18245 18246 function animComplete() { 18247 element.css( { 18248 visibility: "visible" 18249 } ); 18250 $( pieces ).remove(); 18251 done(); 18252 } 18253} ); 18254 18255 18256/*! 18257 * jQuery UI Effects Fade 1.14.2 18258 * https://jqueryui.com 18259 * 18260 * Copyright OpenJS Foundation and other contributors 18261 * Released under the MIT license. 18262 * https://jquery.org/license 18263 */ 18264 18265//>>label: Fade Effect 18266//>>group: Effects 18267//>>description: Fades the element. 18268//>>docs: https://api.jqueryui.com/fade-effect/ 18269//>>demos: https://jqueryui.com/effect/ 18270 18271 18272var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 18273 var show = options.mode === "show"; 18274 18275 $( this ) 18276 .css( "opacity", show ? 0 : 1 ) 18277 .animate( { 18278 opacity: show ? 1 : 0 18279 }, { 18280 queue: false, 18281 duration: options.duration, 18282 easing: options.easing, 18283 complete: done 18284 } ); 18285} ); 18286 18287 18288/*! 18289 * jQuery UI Effects Fold 1.14.2 18290 * https://jqueryui.com 18291 * 18292 * Copyright OpenJS Foundation and other contributors 18293 * Released under the MIT license. 18294 * https://jquery.org/license 18295 */ 18296 18297//>>label: Fold Effect 18298//>>group: Effects 18299//>>description: Folds an element first horizontally and then vertically. 18300//>>docs: https://api.jqueryui.com/fold-effect/ 18301//>>demos: https://jqueryui.com/effect/ 18302 18303 18304var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 18305 18306 // Create element 18307 var element = $( this ), 18308 mode = options.mode, 18309 show = mode === "show", 18310 hide = mode === "hide", 18311 size = options.size || 15, 18312 percent = /([0-9]+)%/.exec( size ), 18313 horizFirst = !!options.horizFirst, 18314 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 18315 duration = options.duration / 2, 18316 18317 placeholder = $.effects.createPlaceholder( element ), 18318 18319 start = element.cssClip(), 18320 animation1 = { clip: $.extend( {}, start ) }, 18321 animation2 = { clip: $.extend( {}, start ) }, 18322 18323 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 18324 18325 queuelen = element.queue().length; 18326 18327 if ( percent ) { 18328 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 18329 } 18330 animation1.clip[ ref[ 0 ] ] = size; 18331 animation2.clip[ ref[ 0 ] ] = size; 18332 animation2.clip[ ref[ 1 ] ] = 0; 18333 18334 if ( show ) { 18335 element.cssClip( animation2.clip ); 18336 if ( placeholder ) { 18337 placeholder.css( $.effects.clipToBox( animation2 ) ); 18338 } 18339 18340 animation2.clip = start; 18341 } 18342 18343 // Animate 18344 element 18345 .queue( function( next ) { 18346 if ( placeholder ) { 18347 placeholder 18348 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 18349 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 18350 } 18351 18352 next(); 18353 } ) 18354 .animate( animation1, duration, options.easing ) 18355 .animate( animation2, duration, options.easing ) 18356 .queue( done ); 18357 18358 $.effects.unshift( element, queuelen, 4 ); 18359} ); 18360 18361 18362/*! 18363 * jQuery UI Effects Highlight 1.14.2 18364 * https://jqueryui.com 18365 * 18366 * Copyright OpenJS Foundation and other contributors 18367 * Released under the MIT license. 18368 * https://jquery.org/license 18369 */ 18370 18371//>>label: Highlight Effect 18372//>>group: Effects 18373//>>description: Highlights the background of an element in a defined color for a custom duration. 18374//>>docs: https://api.jqueryui.com/highlight-effect/ 18375//>>demos: https://jqueryui.com/effect/ 18376 18377 18378var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 18379 var element = $( this ), 18380 animation = { 18381 backgroundColor: element.css( "backgroundColor" ) 18382 }; 18383 18384 if ( options.mode === "hide" ) { 18385 animation.opacity = 0; 18386 } 18387 18388 $.effects.saveStyle( element ); 18389 18390 element 18391 .css( { 18392 backgroundImage: "none", 18393 backgroundColor: options.color || "#ffff99" 18394 } ) 18395 .animate( animation, { 18396 queue: false, 18397 duration: options.duration, 18398 easing: options.easing, 18399 complete: done 18400 } ); 18401} ); 18402 18403 18404/*! 18405 * jQuery UI Effects Size 1.14.2 18406 * https://jqueryui.com 18407 * 18408 * Copyright OpenJS Foundation and other contributors 18409 * Released under the MIT license. 18410 * https://jquery.org/license 18411 */ 18412 18413//>>label: Size Effect 18414//>>group: Effects 18415//>>description: Resize an element to a specified width and height. 18416//>>docs: https://api.jqueryui.com/size-effect/ 18417//>>demos: https://jqueryui.com/effect/ 18418 18419 18420var effectsEffectSize = $.effects.define( "size", function( options, done ) { 18421 18422 // Create element 18423 var baseline, factor, temp, 18424 element = $( this ), 18425 18426 // Copy for children 18427 cProps = [ "fontSize" ], 18428 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 18429 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 18430 18431 // Set options 18432 mode = options.mode, 18433 restore = mode !== "effect", 18434 scale = options.scale || "both", 18435 origin = options.origin || [ "middle", "center" ], 18436 position = element.css( "position" ), 18437 pos = element.position(), 18438 original = $.effects.scaledDimensions( element ), 18439 from = options.from || original, 18440 to = options.to || $.effects.scaledDimensions( element, 0 ); 18441 18442 $.effects.createPlaceholder( element ); 18443 18444 if ( mode === "show" ) { 18445 temp = from; 18446 from = to; 18447 to = temp; 18448 } 18449 18450 // Set scaling factor 18451 factor = { 18452 from: { 18453 y: from.height / original.height, 18454 x: from.width / original.width 18455 }, 18456 to: { 18457 y: to.height / original.height, 18458 x: to.width / original.width 18459 } 18460 }; 18461 18462 // Scale the css box 18463 if ( scale === "box" || scale === "both" ) { 18464 18465 // Vertical props scaling 18466 if ( factor.from.y !== factor.to.y ) { 18467 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 18468 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 18469 } 18470 18471 // Horizontal props scaling 18472 if ( factor.from.x !== factor.to.x ) { 18473 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 18474 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 18475 } 18476 } 18477 18478 // Scale the content 18479 if ( scale === "content" || scale === "both" ) { 18480 18481 // Vertical props scaling 18482 if ( factor.from.y !== factor.to.y ) { 18483 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 18484 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 18485 } 18486 } 18487 18488 // Adjust the position properties based on the provided origin points 18489 if ( origin ) { 18490 baseline = $.effects.getBaseline( origin, original ); 18491 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 18492 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 18493 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 18494 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 18495 } 18496 delete from.outerHeight; 18497 delete from.outerWidth; 18498 element.css( from ); 18499 18500 // Animate the children if desired 18501 if ( scale === "content" || scale === "both" ) { 18502 18503 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 18504 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 18505 18506 // Only animate children with width attributes specified 18507 // TODO: is this right? should we include anything with css width specified as well 18508 element.find( "*[width]" ).each( function() { 18509 var child = $( this ), 18510 childOriginal = $.effects.scaledDimensions( child ), 18511 childFrom = { 18512 height: childOriginal.height * factor.from.y, 18513 width: childOriginal.width * factor.from.x, 18514 outerHeight: childOriginal.outerHeight * factor.from.y, 18515 outerWidth: childOriginal.outerWidth * factor.from.x 18516 }, 18517 childTo = { 18518 height: childOriginal.height * factor.to.y, 18519 width: childOriginal.width * factor.to.x, 18520 outerHeight: childOriginal.height * factor.to.y, 18521 outerWidth: childOriginal.width * factor.to.x 18522 }; 18523 18524 // Vertical props scaling 18525 if ( factor.from.y !== factor.to.y ) { 18526 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 18527 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 18528 } 18529 18530 // Horizontal props scaling 18531 if ( factor.from.x !== factor.to.x ) { 18532 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 18533 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 18534 } 18535 18536 if ( restore ) { 18537 $.effects.saveStyle( child ); 18538 } 18539 18540 // Animate children 18541 child.css( childFrom ); 18542 child.animate( childTo, options.duration, options.easing, function() { 18543 18544 // Restore children 18545 if ( restore ) { 18546 $.effects.restoreStyle( child ); 18547 } 18548 } ); 18549 } ); 18550 } 18551 18552 // Animate 18553 element.animate( to, { 18554 queue: false, 18555 duration: options.duration, 18556 easing: options.easing, 18557 complete: function() { 18558 18559 var offset = element.offset(); 18560 18561 if ( to.opacity === 0 ) { 18562 element.css( "opacity", from.opacity ); 18563 } 18564 18565 if ( !restore ) { 18566 element 18567 .css( "position", position === "static" ? "relative" : position ) 18568 .offset( offset ); 18569 18570 // Need to save style here so that automatic style restoration 18571 // doesn't restore to the original styles from before the animation. 18572 $.effects.saveStyle( element ); 18573 } 18574 18575 done(); 18576 } 18577 } ); 18578 18579} ); 18580 18581 18582/*! 18583 * jQuery UI Effects Scale 1.14.2 18584 * https://jqueryui.com 18585 * 18586 * Copyright OpenJS Foundation and other contributors 18587 * Released under the MIT license. 18588 * https://jquery.org/license 18589 */ 18590 18591//>>label: Scale Effect 18592//>>group: Effects 18593//>>description: Grows or shrinks an element and its content. 18594//>>docs: https://api.jqueryui.com/scale-effect/ 18595//>>demos: https://jqueryui.com/effect/ 18596 18597 18598var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 18599 18600 // Create element 18601 var el = $( this ), 18602 mode = options.mode, 18603 percent = parseInt( options.percent, 10 ) || 18604 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 18605 18606 newOptions = $.extend( true, { 18607 from: $.effects.scaledDimensions( el ), 18608 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 18609 origin: options.origin || [ "middle", "center" ] 18610 }, options ); 18611 18612 // Fade option to support puff 18613 if ( options.fade ) { 18614 newOptions.from.opacity = 1; 18615 newOptions.to.opacity = 0; 18616 } 18617 18618 $.effects.effect.size.call( this, newOptions, done ); 18619} ); 18620 18621 18622/*! 18623 * jQuery UI Effects Puff 1.14.2 18624 * https://jqueryui.com 18625 * 18626 * Copyright OpenJS Foundation and other contributors 18627 * Released under the MIT license. 18628 * https://jquery.org/license 18629 */ 18630 18631//>>label: Puff Effect 18632//>>group: Effects 18633//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 18634//>>docs: https://api.jqueryui.com/puff-effect/ 18635//>>demos: https://jqueryui.com/effect/ 18636 18637 18638var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 18639 var newOptions = $.extend( true, {}, options, { 18640 fade: true, 18641 percent: parseInt( options.percent, 10 ) || 150 18642 } ); 18643 18644 $.effects.effect.scale.call( this, newOptions, done ); 18645} ); 18646 18647 18648/*! 18649 * jQuery UI Effects Pulsate 1.14.2 18650 * https://jqueryui.com 18651 * 18652 * Copyright OpenJS Foundation and other contributors 18653 * Released under the MIT license. 18654 * https://jquery.org/license 18655 */ 18656 18657//>>label: Pulsate Effect 18658//>>group: Effects 18659//>>description: Pulsates an element n times by changing the opacity to zero and back. 18660//>>docs: https://api.jqueryui.com/pulsate-effect/ 18661//>>demos: https://jqueryui.com/effect/ 18662 18663 18664var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 18665 var element = $( this ), 18666 mode = options.mode, 18667 show = mode === "show", 18668 hide = mode === "hide", 18669 showhide = show || hide, 18670 18671 // Showing or hiding leaves off the "last" animation 18672 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 18673 duration = options.duration / anims, 18674 animateTo = 0, 18675 i = 1, 18676 queuelen = element.queue().length; 18677 18678 if ( show || !element.is( ":visible" ) ) { 18679 element.css( "opacity", 0 ).show(); 18680 animateTo = 1; 18681 } 18682 18683 // Anims - 1 opacity "toggles" 18684 for ( ; i < anims; i++ ) { 18685 element.animate( { opacity: animateTo }, duration, options.easing ); 18686 animateTo = 1 - animateTo; 18687 } 18688 18689 element.animate( { opacity: animateTo }, duration, options.easing ); 18690 18691 element.queue( done ); 18692 18693 $.effects.unshift( element, queuelen, anims + 1 ); 18694} ); 18695 18696 18697/*! 18698 * jQuery UI Effects Shake 1.14.2 18699 * https://jqueryui.com 18700 * 18701 * Copyright OpenJS Foundation and other contributors 18702 * Released under the MIT license. 18703 * https://jquery.org/license 18704 */ 18705 18706//>>label: Shake Effect 18707//>>group: Effects 18708//>>description: Shakes an element horizontally or vertically n times. 18709//>>docs: https://api.jqueryui.com/shake-effect/ 18710//>>demos: https://jqueryui.com/effect/ 18711 18712 18713var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 18714 18715 var i = 1, 18716 element = $( this ), 18717 direction = options.direction || "left", 18718 distance = options.distance || 20, 18719 times = options.times || 3, 18720 anims = times * 2 + 1, 18721 speed = Math.round( options.duration / anims ), 18722 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18723 positiveMotion = ( direction === "up" || direction === "left" ), 18724 animation = {}, 18725 animation1 = {}, 18726 animation2 = {}, 18727 18728 queuelen = element.queue().length; 18729 18730 $.effects.createPlaceholder( element ); 18731 18732 // Animation 18733 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 18734 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 18735 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 18736 18737 // Animate 18738 element.animate( animation, speed, options.easing ); 18739 18740 // Shakes 18741 for ( ; i < times; i++ ) { 18742 element 18743 .animate( animation1, speed, options.easing ) 18744 .animate( animation2, speed, options.easing ); 18745 } 18746 18747 element 18748 .animate( animation1, speed, options.easing ) 18749 .animate( animation, speed / 2, options.easing ) 18750 .queue( done ); 18751 18752 $.effects.unshift( element, queuelen, anims + 1 ); 18753} ); 18754 18755 18756/*! 18757 * jQuery UI Effects Slide 1.14.2 18758 * https://jqueryui.com 18759 * 18760 * Copyright OpenJS Foundation and other contributors 18761 * Released under the MIT license. 18762 * https://jquery.org/license 18763 */ 18764 18765//>>label: Slide Effect 18766//>>group: Effects 18767//>>description: Slides an element in and out of the viewport. 18768//>>docs: https://api.jqueryui.com/slide-effect/ 18769//>>demos: https://jqueryui.com/effect/ 18770 18771 18772var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 18773 var startClip, startRef, 18774 element = $( this ), 18775 map = { 18776 up: [ "bottom", "top" ], 18777 down: [ "top", "bottom" ], 18778 left: [ "right", "left" ], 18779 right: [ "left", "right" ] 18780 }, 18781 mode = options.mode, 18782 direction = options.direction || "left", 18783 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18784 positiveMotion = ( direction === "up" || direction === "left" ), 18785 distance = options.distance || 18786 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 18787 animation = {}; 18788 18789 $.effects.createPlaceholder( element ); 18790 18791 startClip = element.cssClip(); 18792 startRef = element.position()[ ref ]; 18793 18794 // Define hide animation 18795 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 18796 animation.clip = element.cssClip(); 18797 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 18798 18799 // Reverse the animation if we're showing 18800 if ( mode === "show" ) { 18801 element.cssClip( animation.clip ); 18802 element.css( ref, animation[ ref ] ); 18803 animation.clip = startClip; 18804 animation[ ref ] = startRef; 18805 } 18806 18807 // Actually animate 18808 element.animate( animation, { 18809 queue: false, 18810 duration: options.duration, 18811 easing: options.easing, 18812 complete: done 18813 } ); 18814} ); 18815 18816 18817/*! 18818 * jQuery UI Effects Transfer 1.14.2 18819 * https://jqueryui.com 18820 * 18821 * Copyright OpenJS Foundation and other contributors 18822 * Released under the MIT license. 18823 * https://jquery.org/license 18824 */ 18825 18826//>>label: Transfer Effect 18827//>>group: Effects 18828//>>description: Displays a transfer effect from one element to another. 18829//>>docs: https://api.jqueryui.com/transfer-effect/ 18830//>>demos: https://jqueryui.com/effect/ 18831 18832 18833var effect; 18834if ( $.uiBackCompat === true ) { 18835 effect = $.effects.define( "transfer", function( options, done ) { 18836 $( this ).transfer( options, done ); 18837 } ); 18838} 18839var effectsEffectTransfer = effect; 18840 18841
18842 18843 18844} );
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.