1/*! jQuery UI - v1.14.1 - 2025-07-25 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.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.1"; 24 25 26/*! 27 * jQuery UI Widget 1.14.1
vendor: 20,126 bytes, lines 27-772
27 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.
vendor: 3,861 bytes, lines 772-915
7721 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 ),
vendor: 10,992 bytes, lines 916-1269
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 ] ) ? 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 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.1
12694.1 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
vendor: 16,263 bytes, lines 1278-1934
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.1 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 1326/*! 1327 * jQuery UI Focusable 1.14.1 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.1 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.1 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.1 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.1 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.1 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.1 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.1 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} ); 1676 1677 1678/*! 1679 * jQuery UI Mouse 1.14.1 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.1", 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.1 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.1
vendor: 34,659 bytes, lines 1934-3152
1934", 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 ) { 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 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
3152Droppable 1.14.1 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.1
vendor: 12,166 bytes, lines 3168-3635
3168", 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
vendor: 1,378 bytes, lines 3635-3700
3635Resizable 1.14.1 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.1", 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 (
vendor: 29,920 bytes, lines 3719-4889
3719e ) { 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: 11,334 bytes, lines 4889-5343
4889Selectable 1.14.1 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.1", 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.1 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 = $.widget( "ui.sortable", $.ui.mouse, { 5204 version: "1.14.1", 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;
vendor: 9,308 bytes, lines 5344-5662
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,368 bytes, lines 6486-6746
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;
vendor: 16,605 bytes, lines 6747-7395
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 6772 6773/*! 6774 * jQuery UI Accordion 1.14.1 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/* eslint-disable max-len */ 6785//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 6786/* eslint-enable max-len */ 6787//>>docs: https://api.jqueryui.com/accordion/ 6788//>>demos: https://jqueryui.com/accordion/ 6789//>>css.structure: ../../themes/base/core.css 6790//>>css.structure: ../../themes/base/accordion.css 6791//>>css.theme: ../../themes/base/theme.css 6792 6793 6794var widgetsAccordion = $.widget( "ui.accordion", { 6795 version: "1.14.1", 6796 options: { 6797 active: 0, 6798 animate: {}, 6799 classes: { 6800 "ui-accordion-header": "ui-corner-top", 6801 "ui-accordion-header-collapsed": "ui-corner-all", 6802 "ui-accordion-content": "ui-corner-bottom" 6803 }, 6804 collapsible: false, 6805 event: "click", 6806 header: function( elem ) { 6807 return elem 6808 .find( "> li > :first-child" ) 6809 .add( 6810 elem.find( "> :not(li)" ) 6811 6812 // Support: jQuery <3.5 only 6813 // We could use `.even()` but that's unavailable in older jQuery. 6814 .filter( function( i ) { 6815 return i % 2 === 0; 6816 } ) 6817 ); 6818 }, 6819 heightStyle: "auto", 6820 icons: { 6821 activeHeader: "ui-icon-triangle-1-s", 6822 header: "ui-icon-triangle-1-e" 6823 }, 6824 6825 // Callbacks 6826 activate: null, 6827 beforeActivate: null 6828 }, 6829 6830 hideProps: { 6831 borderTopWidth: "hide", 6832 borderBottomWidth: "hide", 6833 paddingTop: "hide", 6834 paddingBottom: "hide", 6835 height: "hide" 6836 }, 6837 6838 showProps: { 6839 borderTopWidth: "show", 6840 borderBottomWidth: "show", 6841 paddingTop: "show", 6842 paddingBottom: "show", 6843 height: "show" 6844 }, 6845 6846 _create: function() { 6847 var options = this.options; 6848 6849 this.prevShow = this.prevHide = $(); 6850 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 6851 this.element.attr( "role", "tablist" ); 6852 6853 // Don't allow collapsible: false and active: false / null 6854 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 6855 options.active = 0; 6856 } 6857 6858 this._processPanels(); 6859 6860 // handle negative values 6861 if ( options.active < 0 ) { 6862 options.active += this.headers.length; 6863 } 6864 this._refresh(); 6865 }, 6866 6867 _getCreateEventData: function() { 6868 return { 6869 header: this.active, 6870 panel: !this.active.length ? $() : this.active.next() 6871 }; 6872 }, 6873 6874 _createIcons: function() { 6875 var icon, children, 6876 icons = this.options.icons; 6877 6878 if ( icons ) { 6879 icon = $( "<span>" ); 6880 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 6881 icon.prependTo( this.headers ); 6882 children = this.active.children( ".ui-accordion-header-icon" ); 6883 this._removeClass( children, icons.header ) 6884 ._addClass( children, null, icons.activeHeader ) 6885 ._addClass( this.headers, "ui-accordion-icons" ); 6886 } 6887 }, 6888 6889 _destroyIcons: function() { 6890 this._removeClass( this.headers, "ui-accordion-icons" ); 6891 this.headers.children( ".ui-accordion-header-icon" ).remove(); 6892 }, 6893 6894 _destroy: function() { 6895 var contents; 6896 6897 // Clean up main element 6898 this.element.removeAttr( "role" ); 6899 6900 // Clean up headers 6901 this.headers 6902 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 6903 .removeUniqueId(); 6904 6905 this._destroyIcons(); 6906 6907 // Clean up content panels 6908 contents = this.headers.next() 6909 .css( "display", "" ) 6910 .removeAttr( "role aria-hidden aria-labelledby" ) 6911 .removeUniqueId(); 6912 6913 if ( this.options.heightStyle !== "content" ) { 6914 contents.css( "height", "" ); 6915 } 6916 }, 6917 6918 _setOption: function( key, value ) { 6919 if ( key === "active" ) { 6920 6921 // _activate() will handle invalid values and update this.options 6922 this._activate( value ); 6923 return; 6924 } 6925 6926 if ( key === "event" ) { 6927 if ( this.options.event ) { 6928 this._off( this.headers, this.options.event ); 6929 } 6930 this._setupEvents( value ); 6931 } 6932 6933 this._super( key, value ); 6934 6935 // Setting collapsible: false while collapsed; open first panel 6936 if ( key === "collapsible" && !value && this.options.active === false ) { 6937 this._activate( 0 ); 6938 } 6939 6940 if ( key === "icons" ) { 6941 this._destroyIcons(); 6942 if ( value ) { 6943 this._createIcons(); 6944 } 6945 } 6946 }, 6947 6948 _setOptionDisabled: function( value ) { 6949 this._super( value ); 6950 6951 this.element.attr( "aria-disabled", value ); 6952 this._toggleClass( null, "ui-state-disabled", !!value ); 6953 }, 6954 6955 _keydown: function( event ) { 6956 if ( event.altKey || event.ctrlKey ) { 6957 return; 6958 } 6959 6960 var keyCode = $.ui.keyCode, 6961 length = this.headers.length, 6962 currentIndex = this.headers.index( event.target ), 6963 toFocus = false; 6964 6965 switch ( event.keyCode ) { 6966 case keyCode.RIGHT: 6967 case keyCode.DOWN: 6968 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6969 break; 6970 case keyCode.LEFT: 6971 case keyCode.UP: 6972 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6973 break; 6974 case keyCode.SPACE: 6975 case keyCode.ENTER: 6976 this._eventHandler( event ); 6977 break; 6978 case keyCode.HOME: 6979 toFocus = this.headers[ 0 ]; 6980 break; 6981 case keyCode.END: 6982 toFocus = this.headers[ length - 1 ]; 6983 break; 6984 } 6985 6986 if ( toFocus ) { 6987 $( event.target ).attr( "tabIndex", -1 ); 6988 $( toFocus ).attr( "tabIndex", 0 ); 6989 $( toFocus ).trigger( "focus" ); 6990 event.preventDefault(); 6991 } 6992 }, 6993 6994 _panelKeyDown: function( event ) { 6995 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6996 $( event.currentTarget ).prev().trigger( "focus" ); 6997 } 6998 }, 6999 7000 refresh: function() { 7001 var options = this.options; 7002 this._processPanels(); 7003 7004 // Was collapsed or no panel 7005 if ( ( options.active === false && options.collapsible === true ) || 7006 !this.headers.length ) { 7007 options.active = false; 7008 this.active = $(); 7009 7010 // active false only when collapsible is true 7011 } else if ( options.active === false ) { 7012 this._activate( 0 ); 7013 7014 // was active, but active panel is gone 7015 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 7016 7017 // all remaining panel are disabled 7018 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 7019 options.active = false; 7020 this.active = $(); 7021 7022 // activate previous panel 7023 } else { 7024 this._activate( Math.max( 0, options.active - 1 ) ); 7025 } 7026 7027 // was active, active panel still exists 7028 } else { 7029 7030 // make sure active index is correct 7031 options.active = this.headers.index( this.active ); 7032 } 7033 7034 this._destroyIcons(); 7035 7036 this._refresh(); 7037 }, 7038 7039 _processPanels: function() { 7040 var prevHeaders = this.headers, 7041 prevPanels = this.panels; 7042 7043 if ( typeof this.options.header === "function" ) { 7044 this.headers = this.options.header( this.element ); 7045 } else { 7046 this.headers = this.element.find( this.options.header ); 7047 } 7048 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 7049 "ui-state-default" ); 7050 7051 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 7052 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 7053 7054 // Avoid memory leaks (#10056) 7055 if ( prevPanels ) { 7056 this._off( prevHeaders.not( this.headers ) ); 7057 this._off( prevPanels.not( this.panels ) ); 7058 } 7059 }, 7060 7061 _refresh: function() { 7062 var maxHeight, 7063 options = this.options, 7064 heightStyle = options.heightStyle, 7065 parent = this.element.parent(); 7066 7067 this.active = this._findActive( options.active ); 7068 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 7069 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 7070 this._addClass( this.active.next(), "ui-accordion-content-active" ); 7071 this.active.next().show(); 7072 7073 this.headers 7074 .attr( "role", "tab" ) 7075 .each( function() { 7076 var header = $( this ), 7077 headerId = header.uniqueId().attr( "id" ), 7078 panel = header.next(), 7079 panelId = panel.uniqueId().attr( "id" ); 7080 header.attr( "aria-controls", panelId ); 7081 panel.attr( "aria-labelledby", headerId ); 7082 } ) 7083 .next() 7084 .attr( "role", "tabpanel" ); 7085 7086 this.headers 7087 .not( this.active ) 7088 .attr( { 7089 "aria-selected": "false", 7090 "aria-expanded": "false", 7091 tabIndex: -1 7092 } ) 7093 .next() 7094 .attr( { 7095 "aria-hidden": "true" 7096 } ) 7097 .hide(); 7098 7099 // Make sure at least one header is in the tab order 7100 if ( !this.active.length ) { 7101 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 7102 } else { 7103 this.active.attr( { 7104 "aria-selected": "true", 7105 "aria-expanded": "true", 7106 tabIndex: 0 7107 } ) 7108 .next() 7109 .attr( { 7110 "aria-hidden": "false" 7111 } ); 7112 } 7113 7114 this._createIcons(); 7115 7116 this._setupEvents( options.event ); 7117 7118 if ( heightStyle === "fill" ) { 7119 maxHeight = parent.height(); 7120 this.element.siblings( ":visible" ).each( function() { 7121 var elem = $( this ), 7122 position = elem.css( "position" ); 7123 7124 if ( position === "absolute" || position === "fixed" ) { 7125 return; 7126 } 7127 maxHeight -= elem.outerHeight( true ); 7128 } ); 7129 7130 this.headers.each( function() { 7131 maxHeight -= $( this ).outerHeight( true ); 7132 } ); 7133 7134 this.headers.next() 7135 .each( function() { 7136 $( this ).height( Math.max( 0, maxHeight - 7137 $( this ).innerHeight() + $( this ).height() ) ); 7138 } ) 7139 .css( "overflow", "auto" ); 7140 } else if ( heightStyle === "auto" ) { 7141 maxHeight = 0; 7142 this.headers.next() 7143 .each( function() { 7144 var isVisible = $( this ).is( ":visible" ); 7145 if ( !isVisible ) { 7146 $( this ).show(); 7147 } 7148 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 7149 if ( !isVisible ) { 7150 $( this ).hide(); 7151 } 7152 } ) 7153 .height( maxHeight ); 7154 } 7155 }, 7156 7157 _activate: function( index ) { 7158 var active = this._findActive( index )[ 0 ]; 7159 7160 // Trying to activate the already active panel 7161 if ( active === this.active[ 0 ] ) { 7162 return; 7163 } 7164 7165 // Trying to collapse, simulate a click on the currently active header 7166 active = active || this.active[ 0 ]; 7167 7168 this._eventHandler( { 7169 target: active, 7170 currentTarget: active, 7171 preventDefault: $.noop 7172 } ); 7173 }, 7174 7175 _findActive: function( selector ) { 7176 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 7177 }, 7178 7179 _setupEvents: function( event ) { 7180 var events = { 7181 keydown: "_keydown" 7182 }; 7183 if ( event ) { 7184 $.each( event.split( " " ), function( index, eventName ) { 7185 events[ eventName ] = "_eventHandler"; 7186 } ); 7187 } 7188 7189 this._off( this.headers.add( this.headers.next() ) ); 7190 this._on( this.headers, events ); 7191 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 7192 this._hoverable( this.headers ); 7193 this._focusable( this.headers ); 7194 }, 7195 7196 _eventHandler: function( event ) { 7197 var activeChildren, clickedChildren, 7198 options = this.options, 7199 active = this.active, 7200 clicked = $( event.currentTarget ), 7201 clickedIsActive = clicked[ 0 ] === active[ 0 ], 7202 collapsing = clickedIsActive && options.collapsible, 7203 toShow = collapsing ? $() : clicked.next(), 7204 toHide = active.next(), 7205 eventData = { 7206 oldHeader: active, 7207 oldPanel: toHide, 7208 newHeader: collapsing ? $() : clicked, 7209 newPanel: toShow 7210 }; 7211 7212 event.preventDefault(); 7213 7214 if ( 7215 7216 // click on active header, but not collapsible 7217 ( clickedIsActive && !options.collapsible ) || 7218 7219 // allow canceling activation 7220 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 7221 return; 7222 } 7223 7224 options.active = collapsing ? false : this.headers.index( clicked ); 7225 7226 // When the call to ._toggle() comes after the class changes 7227 // it causes a very odd bug in IE 8 (see #6720) 7228 this.active = clickedIsActive ? $() : clicked; 7229 this._toggle( eventData ); 7230 7231 // Switch classes 7232 // corner classes on the previously active header stay after the animation 7233 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 7234 if ( options.icons ) { 7235 activeChildren = active.children( ".ui-accordion-header-icon" ); 7236 this._removeClass( activeChildren, null, options.icons.activeHeader ) 7237 ._addClass( activeChildren, null, options.icons.header ); 7238 } 7239 7240 if ( !clickedIsActive ) { 7241 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 7242 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 7243 if ( options.icons ) { 7244 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 7245 this._removeClass( clickedChildren, null, options.icons.header ) 7246 ._addClass( clickedChildren, null, options.icons.activeHeader ); 7247 } 7248 7249 this._addClass( clicked.next(), "ui-accordion-content-active" ); 7250 } 7251 }, 7252 7253 _toggle: function( data ) { 7254 var toShow = data.newPanel, 7255 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 7256 7257 // Handle activating a panel during the animation for another activation 7258 this.prevShow.add( this.prevHide ).stop( true, true ); 7259 this.prevShow = toShow; 7260 this.prevHide = toHide; 7261 7262 if ( this.options.animate ) { 7263 this._animate( toShow, toHide, data ); 7264 } else { 7265 toHide.hide(); 7266 toShow.show(); 7267 this._toggleComplete( data ); 7268 } 7269 7270 toHide.attr( { 7271 "aria-hidden": "true" 7272 } ); 7273 toHide.prev().attr( { 7274 "aria-selected": "false", 7275 "aria-expanded": "false" 7276 } ); 7277 7278 // if we're switching panels, remove the old header from the tab order 7279 // if we're opening from collapsed state, remove the previous header from the tab order 7280 // if we're collapsing, then keep the collapsing header in the tab order 7281 if ( toShow.length && toHide.length ) { 7282 toHide.prev().attr( { 7283 "tabIndex": -1, 7284 "aria-expanded": "false" 7285 } ); 7286 } else if ( toShow.length ) { 7287 this.headers.filter( function() { 7288 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 7289 } ) 7290 .attr( "tabIndex", -1 ); 7291 } 7292 7293 toShow 7294 .attr( "aria-hidden", "false" ) 7295 .prev() 7296 .attr( { 7297 "aria-selected": "true", 7298 "aria-expanded": "true", 7299 tabIndex: 0 7300 } ); 7301 }, 7302 7303 _animate: function( toShow, toHide, data ) { 7304 var total, easing, duration, 7305 that = this, 7306 adjust = 0, 7307 boxSizing = toShow.css( "box-sizing" ), 7308 down = toShow.length && 7309 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 7310 animate = this.options.animate || {}, 7311 options = down && animate.down || animate, 7312 complete = function() { 7313 that._toggleComplete( data ); 7314 }; 7315 7316 if ( typeof options === "number" ) { 7317 duration = options; 7318 } 7319 if ( typeof options === "string" ) { 7320 easing = options; 7321 } 7322 7323 // fall back from options to animation in case of partial down settings 7324 easing = easing || options.easing || animate.easing; 7325 duration = duration || options.duration || animate.duration; 7326 7327 if ( !toHide.length ) { 7328 return toShow.animate( this.showProps, duration, easing, complete ); 7329 } 7330 if ( !toShow.length ) { 7331 return toHide.animate( this.hideProps, duration, easing, complete ); 7332 } 7333 7334 total = toShow.show().outerHeight(); 7335 toHide.animate( this.hideProps, { 7336 duration: duration, 7337 easing: easing, 7338 step: function( now, fx ) { 7339 fx.now = Math.round( now ); 7340 } 7341 } ); 7342 toShow 7343 .hide() 7344 .animate( this.showProps, { 7345 duration: duration, 7346 easing: easing, 7347 complete: complete, 7348 step: function( now, fx ) { 7349 fx.now = Math.round( now ); 7350 if ( fx.prop !== "height" ) { 7351 if ( boxSizing === "content-box" ) { 7352 adjust += fx.now; 7353 } 7354 } else if ( that.options.heightStyle !== "content" ) { 7355 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 7356 adjust = 0; 7357 } 7358 } 7359 } ); 7360 }, 7361 7362 _toggleComplete: function( data ) { 7363 var toHide = data.oldPanel, 7364 prev = toHide.prev(); 7365 7366 this._removeClass( toHide, "ui-accordion-content-active" ); 7367 this._removeClass( prev, "ui-accordion-header-active" ) 7368 ._addClass( prev, "ui-accordion-header-collapsed" ); 7369 7370 this._trigger( "activate", null, data ); 7371 } 7372} ); 7373 7374 7375/*! 7376 * jQuery UI Menu 1.14.1 7377 * https://jqueryui.com 7378 * 7379 * Copyright OpenJS Foundation and other contributors 7380 * Released under the MIT license. 7381 * https://jquery.org/license 7382 */ 7383 7384//>>label: Menu 7385//>>group: Widgets 7386//>>description: Creates nestable menus. 7387//>>docs: https://api.jqueryui.com/menu/ 7388//>>demos: https://jqueryui.com/menu/ 7389//>>css.structure: ../../themes/base/core.css 7390//>>css.structure: ../../themes/base/menu.css 7391//>>css.theme: ../../themes/base/theme.css 7392 7393 7394var widgetsMenu = $.widget( "ui.menu", { 7395 version: "1.14.1
vendor: 5,700 bytes, lines 7395-7614
7395", 7396 defaultElement: "<ul>", 7397 delay: 300, 7398 options: { 7399 icons: { 7400 submenu: "ui-icon-caret-1-e" 7401 }, 7402 items: "> *", 7403 menus: "ul", 7404 position: { 7405 my: "left top", 7406 at: "right top" 7407 }, 7408 role: "menu", 7409 7410 // Callbacks 7411 blur: null, 7412 focus: null, 7413 select: null 7414 }, 7415 7416 _create: function() { 7417 this.activeMenu = this.element; 7418 7419 // Flag used to prevent firing of the click handler 7420 // as the event bubbles up through nested menus 7421 this.mouseHandled = false; 7422 this.lastMousePosition = { x: null, y: null }; 7423 this.element 7424 .uniqueId() 7425 .attr( { 7426 role: this.options.role, 7427 tabIndex: 0 7428 } ); 7429 7430 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 7431 this._on( { 7432 7433 // Prevent focus from sticking to links inside menu after clicking 7434 // them (focus should always stay on UL during navigation). 7435 "mousedown .ui-menu-item": function( event ) { 7436 event.preventDefault(); 7437 7438 this._activateItem( event ); 7439 }, 7440 "click .ui-menu-item": function( event ) { 7441 var target = $( event.target ); 7442 var active = $( this.document[ 0 ].activeElement ); 7443 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 7444 this.select( event ); 7445 7446 // Only set the mouseHandled flag if the event will bubble, see #9469. 7447 if ( !event.isPropagationStopped() ) { 7448 this.mouseHandled = true; 7449 } 7450 7451 // Open submenu on click 7452 if ( target.has( ".ui-menu" ).length ) { 7453 this.expand( event ); 7454 } else if ( !this.element.is( ":focus" ) && 7455 active.closest( ".ui-menu" ).length ) { 7456 7457 // Redirect focus to the menu 7458 this.element.trigger( "focus", [ true ] ); 7459 7460 // If the active item is on the top level, let it stay active. 7461 // Otherwise, blur the active item since it is no longer visible. 7462 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 7463 clearTimeout( this.timer ); 7464 } 7465 } 7466 } 7467 }, 7468 "mouseenter .ui-menu-item": "_activateItem", 7469 "mousemove .ui-menu-item": "_activateItem", 7470 mouseleave: "collapseAll", 7471 "mouseleave .ui-menu": "collapseAll", 7472 focus: function( event, keepActiveItem ) { 7473 7474 // If there's already an active item, keep it active 7475 // If not, activate the first item 7476 var item = this.active || this._menuItems().first(); 7477 7478 if ( !keepActiveItem ) { 7479 this.focus( event, item ); 7480 } 7481 }, 7482 blur: function( event ) { 7483 this._delay( function() { 7484 var notContained = !$.contains( 7485 this.element[ 0 ], 7486 this.document[ 0 ].activeElement 7487 ); 7488 if ( notContained ) { 7489 this.collapseAll( event ); 7490 } 7491 } ); 7492 }, 7493 keydown: "_keydown" 7494 } ); 7495 7496 this.refresh(); 7497 7498 // Clicks outside of a menu collapse any open menus 7499 this._on( this.document, { 7500 click: function( event ) { 7501 if ( this._closeOnDocumentClick( event ) ) { 7502 this.collapseAll( event, true ); 7503 } 7504 7505 // Reset the mouseHandled flag 7506 this.mouseHandled = false; 7507 } 7508 } ); 7509 }, 7510 7511 _activateItem: function( event ) { 7512 7513 // Ignore mouse events while typeahead is active, see #10458. 7514 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 7515 // is over an item in the menu 7516 if ( this.previousFilter ) { 7517 return; 7518 } 7519 7520 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 7521 if ( event.clientX === this.lastMousePosition.x && 7522 event.clientY === this.lastMousePosition.y ) { 7523 return; 7524 } 7525 7526 this.lastMousePosition = { 7527 x: event.clientX, 7528 y: event.clientY 7529 }; 7530 7531 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 7532 target = $( event.currentTarget ); 7533 7534 // Ignore bubbled events on parent items, see #11641 7535 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 7536 return; 7537 } 7538 7539 // If the item is already active, there's nothing to do 7540 if ( target.is( ".ui-state-active" ) ) { 7541 return; 7542 } 7543 7544 // Remove ui-state-active class from siblings of the newly focused menu item 7545 // to avoid a jump caused by adjacent elements both having a class with a border 7546 this._removeClass( target.siblings().children( ".ui-state-active" ), 7547 null, "ui-state-active" ); 7548 this.focus( event, target ); 7549 }, 7550 7551 _destroy: function() { 7552 var items = this.element.find( ".ui-menu-item" ) 7553 .removeAttr( "role aria-disabled" ), 7554 submenus = items.children( ".ui-menu-item-wrapper" ) 7555 .removeUniqueId() 7556 .removeAttr( "tabIndex role aria-haspopup" ); 7557 7558 // Destroy (sub)menus 7559 this.element 7560 .removeAttr( "aria-activedescendant" ) 7561 .find( ".ui-menu" ).addBack() 7562 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 7563 "tabIndex" ) 7564 .removeUniqueId() 7565 .show(); 7566 7567 submenus.children().each( function() { 7568 var elem = $( this ); 7569 if ( elem.data( "ui-menu-submenu-caret" ) ) { 7570 elem.remove(); 7571 } 7572 } ); 7573 }, 7574 7575 _keydown: function( event ) { 7576 var match, prev, character, skip, 7577 preventDefault = true; 7578 7579 switch ( event.keyCode ) { 7580 case $.ui.keyCode.PAGE_UP: 7581 this.previousPage( event ); 7582 break; 7583 case $.ui.keyCode.PAGE_DOWN: 7584 this.nextPage( event ); 7585 break; 7586 case $.ui.keyCode.HOME: 7587 this._move( "first", "first", event ); 7588 break; 7589 case $.ui.keyCode.END: 7590 this._move( "last", "last", event ); 7591 break; 7592 case $.ui.keyCode.UP: 7593 this.previous( event ); 7594 break; 7595 case $.ui.keyCode.DOWN: 7596 this.next( event ); 7597 break; 7598 case $.ui.keyCode.LEFT: 7599 this.collapse( event ); 7600 break; 7601 case $.ui.keyCode.RIGHT: 7602 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7603 this.expand( event ); 7604 } 7605 break; 7606 case $.ui.keyCode.ENTER: 7607 case $.ui.keyCode.SPACE: 7608 this._activate( event ); 7609 break; 7610 case $.ui.keyCode.ESCAPE: 7611 this.collapse( event ); 7612 break; 7613 default: 7614 preventDefault = false;
vendor: 6,930 bytes, lines 7615-7863
7615 prev = this.previousFilter || ""; 7616 skip = false; 7617 7618 // Support number pad values 7619 character = event.keyCode >= 96 && event.keyCode <= 105 ? 7620 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 7621 7622 clearTimeout( this.filterTimer ); 7623 7624 if ( character === prev ) { 7625 skip = true; 7626 } else { 7627 character = prev + character; 7628 } 7629 7630 match = this._filterMenuItems( character ); 7631 match = skip && match.index( this.active.next() ) !== -1 ? 7632 this.active.nextAll( ".ui-menu-item" ) : 7633 match; 7634 7635 // If no matches on the current filter, reset to the last character pressed 7636 // to move down the menu to the first item that starts with that character 7637 if ( !match.length ) { 7638 character = String.fromCharCode( event.keyCode ); 7639 match = this._filterMenuItems( character ); 7640 } 7641 7642 if ( match.length ) { 7643 this.focus( event, match ); 7644 this.previousFilter = character; 7645 this.filterTimer = this._delay( function() { 7646 delete this.previousFilter; 7647 }, 1000 ); 7648 } else { 7649 delete this.previousFilter; 7650 } 7651 } 7652 7653 if ( preventDefault ) { 7654 event.preventDefault(); 7655 } 7656 }, 7657 7658 _activate: function( event ) { 7659 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7660 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 7661 this.expand( event ); 7662 } else { 7663 this.select( event ); 7664 } 7665 } 7666 }, 7667 7668 refresh: function() { 7669 var menus, items, newSubmenus, newItems, newWrappers, 7670 that = this, 7671 icon = this.options.icons.submenu, 7672 submenus = this.element.find( this.options.menus ); 7673 7674 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 7675 7676 // Initialize nested menus 7677 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 7678 .hide() 7679 .attr( { 7680 role: this.options.role, 7681 "aria-hidden": "true", 7682 "aria-expanded": "false" 7683 } ) 7684 .each( function() { 7685 var menu = $( this ), 7686 item = menu.prev(), 7687 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 7688 7689 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 7690 item 7691 .attr( "aria-haspopup", "true" ) 7692 .prepend( submenuCaret ); 7693 menu.attr( "aria-labelledby", item.attr( "id" ) ); 7694 } ); 7695 7696 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 7697 7698 menus = submenus.add( this.element ); 7699 items = menus.find( this.options.items ); 7700 7701 // Initialize menu-items containing spaces and/or dashes only as dividers 7702 items.not( ".ui-menu-item" ).each( function() { 7703 var item = $( this ); 7704 if ( that._isDivider( item ) ) { 7705 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 7706 } 7707 } ); 7708 7709 // Don't refresh list items that are already adapted 7710 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 7711 newWrappers = newItems.children() 7712 .not( ".ui-menu" ) 7713 .uniqueId() 7714 .attr( { 7715 tabIndex: -1, 7716 role: this._itemRole() 7717 } ); 7718 this._addClass( newItems, "ui-menu-item" ) 7719 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 7720 7721 // Add aria-disabled attribute to any disabled menu item 7722 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 7723 7724 // If the active item has been removed, blur the menu 7725 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 7726 this.blur(); 7727 } 7728 }, 7729 7730 _itemRole: function() { 7731 return { 7732 menu: "menuitem", 7733 listbox: "option" 7734 }[ this.options.role ]; 7735 }, 7736 7737 _setOption: function( key, value ) { 7738 if ( key === "icons" ) { 7739 var icons = this.element.find( ".ui-menu-icon" ); 7740 this._removeClass( icons, null, this.options.icons.submenu ) 7741 ._addClass( icons, null, value.submenu ); 7742 } 7743 this._super( key, value ); 7744 }, 7745 7746 _setOptionDisabled: function( value ) { 7747 this._super( value ); 7748 7749 this.element.attr( "aria-disabled", String( value ) ); 7750 this._toggleClass( null, "ui-state-disabled", !!value ); 7751 }, 7752 7753 focus: function( event, item ) { 7754 var nested, focused, activeParent; 7755 this.blur( event, event && event.type === "focus" ); 7756 7757 this._scrollIntoView( item ); 7758 7759 this.active = item.first(); 7760 7761 focused = this.active.children( ".ui-menu-item-wrapper" ); 7762 this._addClass( focused, null, "ui-state-active" ); 7763 7764 // Only update aria-activedescendant if there's a role 7765 // otherwise we assume focus is managed elsewhere 7766 if ( this.options.role ) { 7767 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 7768 } 7769 7770 // Highlight active parent menu item, if any 7771 activeParent = this.active 7772 .parent() 7773 .closest( ".ui-menu-item" ) 7774 .children( ".ui-menu-item-wrapper" ); 7775 this._addClass( activeParent, null, "ui-state-active" ); 7776 7777 if ( event && event.type === "keydown" ) { 7778 this._close(); 7779 } else { 7780 this.timer = this._delay( function() { 7781 this._close(); 7782 }, this.delay ); 7783 } 7784 7785 nested = item.children( ".ui-menu" ); 7786 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 7787 this._startOpening( nested ); 7788 } 7789 this.activeMenu = item.parent(); 7790 7791 this._trigger( "focus", event, { item: item } ); 7792 }, 7793 7794 _scrollIntoView: function( item ) { 7795 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 7796 if ( this._hasScroll() ) { 7797 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 7798 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 7799 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 7800 scroll = this.activeMenu.scrollTop(); 7801 elementHeight = this.activeMenu.height(); 7802 itemHeight = item.outerHeight(); 7803 7804 if ( offset < 0 ) { 7805 this.activeMenu.scrollTop( scroll + offset ); 7806 } else if ( offset + itemHeight > elementHeight ) { 7807 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 7808 } 7809 } 7810 }, 7811 7812 blur: function( event, fromFocus ) { 7813 if ( !fromFocus ) { 7814 clearTimeout( this.timer ); 7815 } 7816 7817 if ( !this.active ) { 7818 return; 7819 } 7820 7821 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 7822 null, "ui-state-active" ); 7823 7824 this._trigger( "blur", event, { item: this.active } ); 7825 this.active = null; 7826 }, 7827 7828 _startOpening: function( submenu ) { 7829 clearTimeout( this.timer ); 7830 7831 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 7832 // shift in the submenu position when mousing over the caret icon 7833 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 7834 return; 7835 } 7836 7837 this.timer = this._delay( function() { 7838 this._close(); 7839 this._open( submenu ); 7840 }, this.delay ); 7841 }, 7842 7843 _open: function( submenu ) { 7844 var position = $.extend( { 7845 of: this.active 7846 }, this.options.position ); 7847 7848 clearTimeout( this.timer ); 7849 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 7850 .hide() 7851 .attr( "aria-hidden", "true" ); 7852 7853 submenu 7854 .show() 7855 .removeAttr( "aria-hidden" ) 7856 .attr( "aria-expanded", "true" ) 7857 .position( position ); 7858 }, 7859 7860 collapseAll: function( event, all ) { 7861 clearTimeout( this.timer ); 7862 this.timer = this._delay( function() { 7863
vendor: 5,434 bytes, lines 7864-8067
7864 // If we were passed an event, look for the submenu that contains the event 7865 var currentMenu = all ? this.element : 7866 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 7867 7868 // If we found no valid submenu ancestor, use the main menu to close all 7869 // sub menus anyway 7870 if ( !currentMenu.length ) { 7871 currentMenu = this.element; 7872 } 7873 7874 this._close( currentMenu ); 7875 7876 this.blur( event ); 7877 7878 // Work around active item staying active after menu is blurred 7879 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 7880 7881 this.activeMenu = currentMenu; 7882 }, all ? 0 : this.delay ); 7883 }, 7884 7885 // With no arguments, closes the currently active menu - if nothing is active 7886 // it closes all menus. If passed an argument, it will search for menus BELOW 7887 _close: function( startMenu ) { 7888 if ( !startMenu ) { 7889 startMenu = this.active ? this.active.parent() : this.element; 7890 } 7891 7892 startMenu.find( ".ui-menu" ) 7893 .hide() 7894 .attr( "aria-hidden", "true" ) 7895 .attr( "aria-expanded", "false" ); 7896 }, 7897 7898 _closeOnDocumentClick: function( event ) { 7899 return !$( event.target ).closest( ".ui-menu" ).length; 7900 }, 7901 7902 _isDivider: function( item ) { 7903 7904 // Match hyphen, em dash, en dash 7905 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 7906 }, 7907 7908 collapse: function( event ) { 7909 var newItem = this.active && 7910 this.active.parent().closest( ".ui-menu-item", this.element ); 7911 if ( newItem && newItem.length ) { 7912 this._close(); 7913 this.focus( event, newItem ); 7914 } 7915 }, 7916 7917 expand: function( event ) { 7918 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 7919 7920 if ( newItem && newItem.length ) { 7921 this._open( newItem.parent() ); 7922 7923 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 7924 this._delay( function() { 7925 this.focus( event, newItem ); 7926 } ); 7927 } 7928 }, 7929 7930 next: function( event ) { 7931 this._move( "next", "first", event ); 7932 }, 7933 7934 previous: function( event ) { 7935 this._move( "prev", "last", event ); 7936 }, 7937 7938 isFirstItem: function() { 7939 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 7940 }, 7941 7942 isLastItem: function() { 7943 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 7944 }, 7945 7946 _menuItems: function( menu ) { 7947 return ( menu || this.element ) 7948 .find( this.options.items ) 7949 .filter( ".ui-menu-item" ); 7950 }, 7951 7952 _move: function( direction, filter, event ) { 7953 var next; 7954 if ( this.active ) { 7955 if ( direction === "first" || direction === "last" ) { 7956 next = this.active 7957 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 7958 .last(); 7959 } else { 7960 next = this.active 7961 [ direction + "All" ]( ".ui-menu-item" ) 7962 .first(); 7963 } 7964 } 7965 if ( !next || !next.length || !this.active ) { 7966 next = this._menuItems( this.activeMenu )[ filter ](); 7967 } 7968 7969 this.focus( event, next ); 7970 }, 7971 7972 nextPage: function( event ) { 7973 var item, base, height; 7974 7975 if ( !this.active ) { 7976 this.next( event ); 7977 return; 7978 } 7979 if ( this.isLastItem() ) { 7980 return; 7981 } 7982 if ( this._hasScroll() ) { 7983 base = this.active.offset().top; 7984 height = this.element.innerHeight(); 7985 7986 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 7987 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 7988 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 7989 } 7990 7991 this.active.nextAll( ".ui-menu-item" ).each( function() { 7992 item = $( this ); 7993 return item.offset().top - base - height < 0; 7994 } ); 7995 7996 this.focus( event, item ); 7997 } else { 7998 this.focus( event, this._menuItems( this.activeMenu ) 7999 [ !this.active ? "first" : "last" ]() ); 8000 } 8001 }, 8002 8003 previousPage: function( event ) { 8004 var item, base, height; 8005 if ( !this.active ) { 8006 this.next( event ); 8007 return; 8008 } 8009 if ( this.isFirstItem() ) { 8010 return; 8011 } 8012 if ( this._hasScroll() ) { 8013 base = this.active.offset().top; 8014 height = this.element.innerHeight(); 8015 8016 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 8017 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 8018 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 8019 } 8020 8021 this.active.prevAll( ".ui-menu-item" ).each( function() { 8022 item = $( this ); 8023 return item.offset().top - base + height > 0; 8024 } ); 8025 8026 this.focus( event, item ); 8027 } else { 8028 this.focus( event, this._menuItems( this.activeMenu ).first() ); 8029 } 8030 }, 8031 8032 _hasScroll: function() { 8033 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 8034 }, 8035 8036 select: function( event ) { 8037 8038 // TODO: It should never be possible to not have an active item at this 8039 // point, but the tests don't trigger mouseenter before click. 8040 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 8041 var ui = { item: this.active }; 8042 if ( !this.active.has( ".ui-menu" ).length ) { 8043 this.collapseAll( event, true ); 8044 } 8045 this._trigger( "select", event, ui ); 8046 }, 8047 8048 _filterMenuItems: function( character ) { 8049 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 8050 regex = new RegExp( "^" + escapedCharacter, "i" ); 8051 8052 return this.activeMenu 8053 .find( this.options.items ) 8054 8055 // Only match on items, not dividers or other content (#10571) 8056 .filter( ".ui-menu-item" ) 8057 .filter( function() { 8058 return regex.test( 8059 String.prototype.trim.call( 8060 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 8061 } ); 8062 } 8063} ); 8064 8065 8066/*! 8067 * jQuery UI Autocomplete 1.14.
80671 8068 * https://jqueryui.com 8069 * 8070 * Copyright OpenJS Foundation and other contributors 8071 * Released under the MIT license. 8072 * https://jquery.org/license 8073 */ 8074 8075//>>label: Autocomplete 8076//>>group: Widgets 8077//>>description: Lists suggested words as the user is typing. 8078//>>docs: https://api.jqueryui.com/autocomplete/ 8079//>>demos: https://jqueryui.com/autocomplete/ 8080//>>css.structure: ../../themes/base/core.css 8081//>>css.structure: ../../themes/base/autocomplete.css 8082//>>css.theme: ../../themes/base/theme.css 8083 8084 8085$.widget( "ui.autocomplete", { 8086 version: "1.14.1
vendor: 15,301 bytes, lines 8086-8686
8086", 8087 defaultElement: "<input>", 8088 options: { 8089 appendTo: null, 8090 autoFocus: false, 8091 delay: 300, 8092 minLength: 1, 8093 position: { 8094 my: "left top", 8095 at: "left bottom", 8096 collision: "none" 8097 }, 8098 source: null, 8099 8100 // Callbacks 8101 change: null, 8102 close: null, 8103 focus: null, 8104 open: null, 8105 response: null, 8106 search: null, 8107 select: null 8108 }, 8109 8110 requestIndex: 0, 8111 pending: 0, 8112 liveRegionTimer: null, 8113 8114 _create: function() { 8115 8116 // Some browsers only repeat keydown events, not keypress events, 8117 // so we use the suppressKeyPress flag to determine if we've already 8118 // handled the keydown event. #7269 8119 // Unfortunately the code for & in keypress is the same as the up arrow, 8120 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 8121 // events when we know the keydown event was used to modify the 8122 // search term. #7799 8123 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 8124 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 8125 isTextarea = nodeName === "textarea", 8126 isInput = nodeName === "input"; 8127 8128 // Textareas are always multi-line 8129 // Inputs are always single-line, even if inside a contentEditable element 8130 // All other element types are determined by whether they're contentEditable 8131 this.isMultiLine = isTextarea || 8132 !isInput && this.element.prop( "contentEditable" ) === "true"; 8133 8134 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 8135 this.isNewMenu = true; 8136 8137 this._addClass( "ui-autocomplete-input" ); 8138 this.element.attr( "autocomplete", "off" ); 8139 8140 this._on( this.element, { 8141 keydown: function( event ) { 8142 if ( this.element.prop( "readOnly" ) ) { 8143 suppressKeyPress = true; 8144 suppressInput = true; 8145 suppressKeyPressRepeat = true; 8146 return; 8147 } 8148 8149 suppressKeyPress = false; 8150 suppressInput = false; 8151 suppressKeyPressRepeat = false; 8152 var keyCode = $.ui.keyCode; 8153 switch ( event.keyCode ) { 8154 case keyCode.PAGE_UP: 8155 suppressKeyPress = true; 8156 this._move( "previousPage", event ); 8157 break; 8158 case keyCode.PAGE_DOWN: 8159 suppressKeyPress = true; 8160 this._move( "nextPage", event ); 8161 break; 8162 case keyCode.UP: 8163 suppressKeyPress = true; 8164 this._keyEvent( "previous", event ); 8165 break; 8166 case keyCode.DOWN: 8167 suppressKeyPress = true; 8168 this._keyEvent( "next", event ); 8169 break; 8170 case keyCode.ENTER: 8171 8172 // when menu is open and has focus 8173 if ( this.menu.active ) { 8174 8175 // #6055 - Opera still allows the keypress to occur 8176 // which causes forms to submit 8177 suppressKeyPress = true; 8178 event.preventDefault(); 8179 this.menu.select( event ); 8180 } 8181 break; 8182 case keyCode.TAB: 8183 if ( this.menu.active ) { 8184 this.menu.select( event ); 8185 } 8186 break; 8187 case keyCode.ESCAPE: 8188 if ( this.menu.element.is( ":visible" ) ) { 8189 if ( !this.isMultiLine ) { 8190 this._value( this.term ); 8191 } 8192 this.close( event ); 8193 8194 // Different browsers have different default behavior for escape 8195 // Single press can mean undo or clear 8196 event.preventDefault(); 8197 } 8198 break; 8199 default: 8200 suppressKeyPressRepeat = true; 8201 8202 // search timeout should be triggered before the input value is changed 8203 this._searchTimeout( event ); 8204 break; 8205 } 8206 }, 8207 keypress: function( event ) { 8208 if ( suppressKeyPress ) { 8209 suppressKeyPress = false; 8210 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8211 event.preventDefault(); 8212 } 8213 return; 8214 } 8215 if ( suppressKeyPressRepeat ) { 8216 return; 8217 } 8218 8219 // Replicate some key handlers to allow them to repeat in Firefox and Opera 8220 var keyCode = $.ui.keyCode; 8221 switch ( event.keyCode ) { 8222 case keyCode.PAGE_UP: 8223 this._move( "previousPage", event ); 8224 break; 8225 case keyCode.PAGE_DOWN: 8226 this._move( "nextPage", event ); 8227 break; 8228 case keyCode.UP: 8229 this._keyEvent( "previous", event ); 8230 break; 8231 case keyCode.DOWN: 8232 this._keyEvent( "next", event ); 8233 break; 8234 } 8235 }, 8236 input: function( event ) { 8237 if ( suppressInput ) { 8238 suppressInput = false; 8239 event.preventDefault(); 8240 return; 8241 } 8242 this._searchTimeout( event ); 8243 }, 8244 focus: function() { 8245 this.selectedItem = null; 8246 this.previous = this._value(); 8247 }, 8248 blur: function( event ) { 8249 clearTimeout( this.searching ); 8250 this.close( event ); 8251 this._change( event ); 8252 } 8253 } ); 8254 8255 this._initSource(); 8256 this.menu = $( "<ul>" ) 8257 .appendTo( this._appendTo() ) 8258 .menu( { 8259 8260 // disable ARIA support, the live region takes care of that 8261 role: null 8262 } ) 8263 .hide() 8264 .menu( "instance" ); 8265 8266 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 8267 this._on( this.menu.element, { 8268 mousedown: function( event ) { 8269 8270 // Prevent moving focus out of the text field 8271 event.preventDefault(); 8272 }, 8273 menufocus: function( event, ui ) { 8274 var label, item; 8275 8276 // Support: Firefox 8277 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 8278 if ( this.isNewMenu ) { 8279 this.isNewMenu = false; 8280 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 8281 this.menu.blur(); 8282 8283 this.document.one( "mousemove", function() { 8284 $( event.target ).trigger( event.originalEvent ); 8285 } ); 8286 8287 return; 8288 } 8289 } 8290 8291 item = ui.item.data( "ui-autocomplete-item" ); 8292 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 8293 8294 // use value to match what will end up in the input, if it was a key event 8295 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 8296 this._value( item.value ); 8297 } 8298 } 8299 8300 // Announce the value in the liveRegion 8301 label = ui.item.attr( "aria-label" ) || item.value; 8302 if ( label && String.prototype.trim.call( label ).length ) { 8303 clearTimeout( this.liveRegionTimer ); 8304 this.liveRegionTimer = this._delay( function() { 8305 this.liveRegion.html( $( "<div>" ).text( label ) ); 8306 }, 100 ); 8307 } 8308 }, 8309 menuselect: function( event, ui ) { 8310 var item = ui.item.data( "ui-autocomplete-item" ), 8311 previous = this.previous; 8312 8313 // Only trigger when focus was lost (click on menu) 8314 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 8315 this.element.trigger( "focus" ); 8316 this.previous = previous; 8317 } 8318 8319 if ( false !== this._trigger( "select", event, { item: item } ) ) { 8320 this._value( item.value ); 8321 } 8322 8323 // reset the term after the select event 8324 // this allows custom select handling to work properly 8325 this.term = this._value(); 8326 8327 this.close( event ); 8328 this.selectedItem = item; 8329 } 8330 } ); 8331 8332 this.liveRegion = $( "<div>", { 8333 role: "status", 8334 "aria-live": "assertive", 8335 "aria-relevant": "additions" 8336 } ) 8337 .appendTo( this.document[ 0 ].body ); 8338 8339 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 8340 8341 // Turning off autocomplete prevents the browser from remembering the 8342 // value when navigating through history, so we re-enable autocomplete 8343 // if the page is unloaded before the widget is destroyed. #7790 8344 this._on( this.window, { 8345 beforeunload: function() { 8346 this.element.removeAttr( "autocomplete" ); 8347 } 8348 } ); 8349 }, 8350 8351 _destroy: function() { 8352 clearTimeout( this.searching ); 8353 this.element.removeAttr( "autocomplete" ); 8354 this.menu.element.remove(); 8355 this.liveRegion.remove(); 8356 }, 8357 8358 _setOption: function( key, value ) { 8359 this._super( key, value ); 8360 if ( key === "source" ) { 8361 this._initSource(); 8362 } 8363 if ( key === "appendTo" ) { 8364 this.menu.element.appendTo( this._appendTo() ); 8365 } 8366 if ( key === "disabled" && value && this.xhr ) { 8367 this.xhr.abort(); 8368 } 8369 }, 8370 8371 _isEventTargetInWidget: function( event ) { 8372 var menuElement = this.menu.element[ 0 ]; 8373 8374 return event.target === this.element[ 0 ] || 8375 event.target === menuElement || 8376 $.contains( menuElement, event.target ); 8377 }, 8378 8379 _closeOnClickOutside: function( event ) { 8380 if ( !this._isEventTargetInWidget( event ) ) { 8381 this.close(); 8382 } 8383 }, 8384 8385 _appendTo: function() { 8386 var element = this.options.appendTo; 8387 8388 if ( element ) { 8389 element = element.jquery || element.nodeType ? 8390 $( element ) : 8391 this.document.find( element ).eq( 0 ); 8392 } 8393 8394 if ( !element || !element[ 0 ] ) { 8395 element = this.element.closest( ".ui-front, dialog" ); 8396 } 8397 8398 if ( !element.length ) { 8399 element = this.document[ 0 ].body; 8400 } 8401 8402 return element; 8403 }, 8404 8405 _initSource: function() { 8406 var array, url, 8407 that = this; 8408 if ( Array.isArray( this.options.source ) ) { 8409 array = this.options.source; 8410 this.source = function( request, response ) { 8411 response( $.ui.autocomplete.filter( array, request.term ) ); 8412 }; 8413 } else if ( typeof this.options.source === "string" ) { 8414 url = this.options.source; 8415 this.source = function( request, response ) { 8416 if ( that.xhr ) { 8417 that.xhr.abort(); 8418 } 8419 that.xhr = $.ajax( { 8420 url: url, 8421 data: request, 8422 dataType: "json", 8423 success: function( data ) { 8424 response( data ); 8425 }, 8426 error: function() { 8427 response( [] ); 8428 } 8429 } ); 8430 }; 8431 } else { 8432 this.source = this.options.source; 8433 } 8434 }, 8435 8436 _searchTimeout: function( event ) { 8437 clearTimeout( this.searching ); 8438 this.searching = this._delay( function() { 8439 8440 // Search if the value has changed, or if the user retypes the same value (see #7434) 8441 var equalValues = this.term === this._value(), 8442 menuVisible = this.menu.element.is( ":visible" ), 8443 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 8444 8445 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 8446 this.selectedItem = null; 8447 this.search( null, event ); 8448 } 8449 }, this.options.delay ); 8450 }, 8451 8452 search: function( value, event ) { 8453 value = value != null ? value : this._value(); 8454 8455 // Always save the actual value, not the one passed as an argument 8456 this.term = this._value(); 8457 8458 if ( value.length < this.options.minLength ) { 8459 return this.close( event ); 8460 } 8461 8462 if ( this._trigger( "search", event ) === false ) { 8463 return; 8464 } 8465 8466 return this._search( value ); 8467 }, 8468 8469 _search: function( value ) { 8470 this.pending++; 8471 this._addClass( "ui-autocomplete-loading" ); 8472 this.cancelSearch = false; 8473 8474 this.source( { term: value }, this._response() ); 8475 }, 8476 8477 _response: function() { 8478 var index = ++this.requestIndex; 8479 8480 return function( content ) { 8481 if ( index === this.requestIndex ) { 8482 this.__response( content ); 8483 } 8484 8485 this.pending--; 8486 if ( !this.pending ) { 8487 this._removeClass( "ui-autocomplete-loading" ); 8488 } 8489 }.bind( this ); 8490 }, 8491 8492 __response: function( content ) { 8493 if ( content ) { 8494 content = this._normalize( content ); 8495 } 8496 this._trigger( "response", null, { content: content } ); 8497 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 8498 this._suggest( content ); 8499 this._trigger( "open" ); 8500 } else { 8501 8502 // use ._close() instead of .close() so we don't cancel future searches 8503 this._close(); 8504 } 8505 }, 8506 8507 close: function( event ) { 8508 this.cancelSearch = true; 8509 this._close( event ); 8510 }, 8511 8512 _close: function( event ) { 8513 8514 // Remove the handler that closes the menu on outside clicks 8515 this._off( this.document, "mousedown" ); 8516 8517 if ( this.menu.element.is( ":visible" ) ) { 8518 this.menu.element.hide(); 8519 this.menu.blur(); 8520 this.isNewMenu = true; 8521 this._trigger( "close", event ); 8522 } 8523 }, 8524 8525 _change: function( event ) { 8526 if ( this.previous !== this._value() ) { 8527 this._trigger( "change", event, { item: this.selectedItem } ); 8528 } 8529 }, 8530 8531 _normalize: function( items ) { 8532 8533 // assume all items have the right format when the first item is complete 8534 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 8535 return items; 8536 } 8537 return $.map( items, function( item ) { 8538 if ( typeof item === "string" ) { 8539 return { 8540 label: item, 8541 value: item 8542 }; 8543 } 8544 return $.extend( {}, item, { 8545 label: item.label || item.value, 8546 value: item.value || item.label 8547 } ); 8548 } ); 8549 }, 8550 8551 _suggest: function( items ) { 8552 var ul = this.menu.element.empty(); 8553 this._renderMenu( ul, items ); 8554 this.isNewMenu = true; 8555 this.menu.refresh(); 8556 8557 // Size and position menu 8558 ul.show(); 8559 this._resizeMenu(); 8560 ul.position( $.extend( { 8561 of: this.element 8562 }, this.options.position ) ); 8563 8564 if ( this.options.autoFocus ) { 8565 this.menu.next(); 8566 } 8567 8568 // Listen for interactions outside of the widget (#6642) 8569 this._on( this.document, { 8570 mousedown: "_closeOnClickOutside" 8571 } ); 8572 }, 8573 8574 _resizeMenu: function() { 8575 var ul = this.menu.element; 8576 ul.outerWidth( Math.max( 8577 8578 // Firefox wraps long text (possibly a rounding bug) 8579 // so we add 1px to avoid the wrapping (#7513) 8580 ul.width( "" ).outerWidth() + 1, 8581 this.element.outerWidth() 8582 ) ); 8583 }, 8584 8585 _renderMenu: function( ul, items ) { 8586 var that = this; 8587 $.each( items, function( index, item ) { 8588 that._renderItemData( ul, item ); 8589 } ); 8590 }, 8591 8592 _renderItemData: function( ul, item ) { 8593 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 8594 }, 8595 8596 _renderItem: function( ul, item ) { 8597 return $( "<li>" ) 8598 .append( $( "<div>" ).text( item.label ) ) 8599 .appendTo( ul ); 8600 }, 8601 8602 _move: function( direction, event ) { 8603 if ( !this.menu.element.is( ":visible" ) ) { 8604 this.search( null, event ); 8605 return; 8606 } 8607 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 8608 this.menu.isLastItem() && /^next/.test( direction ) ) { 8609 8610 if ( !this.isMultiLine ) { 8611 this._value( this.term ); 8612 } 8613 8614 this.menu.blur(); 8615 return; 8616 } 8617 this.menu[ direction ]( event ); 8618 }, 8619 8620 widget: function() { 8621 return this.menu.element; 8622 }, 8623 8624 _value: function() { 8625 return this.valueMethod.apply( this.element, arguments ); 8626 }, 8627 8628 _keyEvent: function( keyEvent, event ) { 8629 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8630 this._move( keyEvent, event ); 8631 8632 // Prevents moving cursor to beginning/end of the text field in some browsers 8633 event.preventDefault(); 8634 } 8635 } 8636} ); 8637 8638$.extend( $.ui.autocomplete, { 8639 escapeRegex: function( value ) { 8640 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 8641 }, 8642 filter: function( array, term ) { 8643 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 8644 return $.grep( array, function( value ) { 8645 return matcher.test( value.label || value.value || value ); 8646 } ); 8647 } 8648} ); 8649 8650// Live region extension, adding a `messages` option 8651// NOTE: This is an experimental API. We are still investigating 8652// a full solution for string manipulation and internationalization. 8653$.widget( "ui.autocomplete", $.ui.autocomplete, { 8654 options: { 8655 messages: { 8656 noResults: "No search results.", 8657 results: function( amount ) { 8658 return amount + ( amount > 1 ? " results are" : " result is" ) + 8659 " available, use up and down arrow keys to navigate."; 8660 } 8661 } 8662 }, 8663 8664 __response: function( content ) { 8665 var message; 8666 this._superApply( arguments ); 8667 if ( this.options.disabled || this.cancelSearch ) { 8668 return; 8669 } 8670 if ( content && content.length ) { 8671 message = this.options.messages.results( content.length ); 8672 } else { 8673 message = this.options.messages.noResults; 8674 } 8675 clearTimeout( this.liveRegionTimer ); 8676 this.liveRegionTimer = this._delay( function() { 8677 this.liveRegion.html( $( "<div>" ).text( message ) ); 8678 }, 100 ); 8679 } 8680} ); 8681 8682var widgetsAutocomplete = $.ui.autocomplete; 8683 8684 8685/*! 8686 * jQuery UI Controlgroup 1.14.
86861 8687 * https://jqueryui.com 8688 * 8689 * Copyright OpenJS Foundation and other contributors 8690 * Released under the MIT license. 8691 * https://jquery.org/license 8692 */ 8693 8694//>>label: Controlgroup 8695//>>group: Widgets 8696//>>description: Visually groups form control widgets 8697//>>docs: https://api.jqueryui.com/controlgroup/ 8698//>>demos: https://jqueryui.com/controlgroup/ 8699//>>css.structure: ../../themes/base/core.css 8700//>>css.structure: ../../themes/base/controlgroup.css 8701//>>css.theme: ../../themes/base/theme.css 8702 8703 8704var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 8705 8706var widgetsControlgroup = $.widget( "ui.controlgroup", { 8707 version: "1.14.1
vendor: 7,736 bytes, lines 8707-8971
8707", 8708 defaultElement: "<div>", 8709 options: { 8710 direction: "horizontal", 8711 disabled: null, 8712 onlyVisible: true, 8713 items: { 8714 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 8715 "controlgroupLabel": ".ui-controlgroup-label", 8716 "checkboxradio": "input[type='checkbox'], input[type='radio']", 8717 "selectmenu": "select", 8718 "spinner": ".ui-spinner-input" 8719 } 8720 }, 8721 8722 _create: function() { 8723 this._enhance(); 8724 }, 8725 8726 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 8727 _enhance: function() { 8728 this.element.attr( "role", "toolbar" ); 8729 this.refresh(); 8730 }, 8731 8732 _destroy: function() { 8733 this._callChildMethod( "destroy" ); 8734 this.childWidgets.removeData( "ui-controlgroup-data" ); 8735 this.element.removeAttr( "role" ); 8736 if ( this.options.items.controlgroupLabel ) { 8737 this.element 8738 .find( this.options.items.controlgroupLabel ) 8739 .find( ".ui-controlgroup-label-contents" ) 8740 .contents().unwrap(); 8741 } 8742 }, 8743 8744 _initWidgets: function() { 8745 var that = this, 8746 childWidgets = []; 8747 8748 // First we iterate over each of the items options 8749 $.each( this.options.items, function( widget, selector ) { 8750 var labels; 8751 var options = {}; 8752 8753 // Make sure the widget has a selector set 8754 if ( !selector ) { 8755 return; 8756 } 8757 8758 if ( widget === "controlgroupLabel" ) { 8759 labels = that.element.find( selector ); 8760 labels.each( function() { 8761 var element = $( this ); 8762 8763 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 8764 return; 8765 } 8766 element.contents() 8767 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 8768 } ); 8769 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 8770 childWidgets = childWidgets.concat( labels.get() ); 8771 return; 8772 } 8773 8774 // Make sure the widget actually exists 8775 if ( !$.fn[ widget ] ) { 8776 return; 8777 } 8778 8779 // We assume everything is in the middle to start because we can't determine 8780 // first / last elements until all enhancments are done. 8781 if ( that[ "_" + widget + "Options" ] ) { 8782 options = that[ "_" + widget + "Options" ]( "middle" ); 8783 } else { 8784 options = { classes: {} }; 8785 } 8786 8787 // Find instances of this widget inside controlgroup and init them 8788 that.element 8789 .find( selector ) 8790 .each( function() { 8791 var element = $( this ); 8792 var instance = element[ widget ]( "instance" ); 8793 8794 // We need to clone the default options for this type of widget to avoid 8795 // polluting the variable options which has a wider scope than a single widget. 8796 var instanceOptions = $.widget.extend( {}, options ); 8797 8798 // If the button is the child of a spinner ignore it 8799 // TODO: Find a more generic solution 8800 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 8801 return; 8802 } 8803 8804 // Create the widget if it doesn't exist 8805 if ( !instance ) { 8806 instance = element[ widget ]()[ widget ]( "instance" ); 8807 } 8808 if ( instance ) { 8809 instanceOptions.classes = 8810 that._resolveClassesValues( instanceOptions.classes, instance ); 8811 } 8812 element[ widget ]( instanceOptions ); 8813 8814 // Store an instance of the controlgroup to be able to reference 8815 // from the outermost element for changing options and refresh 8816 var widgetElement = element[ widget ]( "widget" ); 8817 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 8818 instance ? instance : element[ widget ]( "instance" ) ); 8819 8820 childWidgets.push( widgetElement[ 0 ] ); 8821 } ); 8822 } ); 8823 8824 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 8825 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 8826 }, 8827 8828 _callChildMethod: function( method ) { 8829 this.childWidgets.each( function() { 8830 var element = $( this ), 8831 data = element.data( "ui-controlgroup-data" ); 8832 if ( data && data[ method ] ) { 8833 data[ method ](); 8834 } 8835 } ); 8836 }, 8837 8838 _updateCornerClass: function( element, position ) { 8839 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 8840 var add = this._buildSimpleOptions( position, "label" ).classes.label; 8841 8842 this._removeClass( element, null, remove ); 8843 this._addClass( element, null, add ); 8844 }, 8845 8846 _buildSimpleOptions: function( position, key ) { 8847 var direction = this.options.direction === "vertical"; 8848 var result = { 8849 classes: {} 8850 }; 8851 result.classes[ key ] = { 8852 "middle": "", 8853 "first": "ui-corner-" + ( direction ? "top" : "left" ), 8854 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 8855 "only": "ui-corner-all" 8856 }[ position ]; 8857 8858 return result; 8859 }, 8860 8861 _spinnerOptions: function( position ) { 8862 var options = this._buildSimpleOptions( position, "ui-spinner" ); 8863 8864 options.classes[ "ui-spinner-up" ] = ""; 8865 options.classes[ "ui-spinner-down" ] = ""; 8866 8867 return options; 8868 }, 8869 8870 _buttonOptions: function( position ) { 8871 return this._buildSimpleOptions( position, "ui-button" ); 8872 }, 8873 8874 _checkboxradioOptions: function( position ) { 8875 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 8876 }, 8877 8878 _selectmenuOptions: function( position ) { 8879 var direction = this.options.direction === "vertical"; 8880 return { 8881 width: direction ? "auto" : false, 8882 classes: { 8883 middle: { 8884 "ui-selectmenu-button-open": "", 8885 "ui-selectmenu-button-closed": "" 8886 }, 8887 first: { 8888 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 8889 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 8890 }, 8891 last: { 8892 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 8893 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 8894 }, 8895 only: { 8896 "ui-selectmenu-button-open": "ui-corner-top", 8897 "ui-selectmenu-button-closed": "ui-corner-all" 8898 } 8899 8900 }[ position ] 8901 }; 8902 }, 8903 8904 _resolveClassesValues: function( classes, instance ) { 8905 var result = {}; 8906 $.each( classes, function( key ) { 8907 var current = instance.options.classes[ key ] || ""; 8908 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 8909 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 8910 } ); 8911 return result; 8912 }, 8913 8914 _setOption: function( key, value ) { 8915 if ( key === "direction" ) { 8916 this._removeClass( "ui-controlgroup-" + this.options.direction ); 8917 } 8918 8919 this._super( key, value ); 8920 if ( key === "disabled" ) { 8921 this._callChildMethod( value ? "disable" : "enable" ); 8922 return; 8923 } 8924 8925 this.refresh(); 8926 }, 8927 8928 refresh: function() { 8929 var children, 8930 that = this; 8931 8932 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 8933 8934 if ( this.options.direction === "horizontal" ) { 8935 this._addClass( null, "ui-helper-clearfix" ); 8936 } 8937 this._initWidgets(); 8938 8939 children = this.childWidgets; 8940 8941 // We filter here because we need to track all childWidgets not just the visible ones 8942 if ( this.options.onlyVisible ) { 8943 children = children.filter( ":visible" ); 8944 } 8945 8946 if ( children.length ) { 8947 8948 // We do this last because we need to make sure all enhancment is done 8949 // before determining first and last 8950 $.each( [ "first", "last" ], function( index, value ) { 8951 var instance = children[ value ]().data( "ui-controlgroup-data" ); 8952 8953 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 8954 var options = that[ "_" + instance.widgetName + "Options" ]( 8955 children.length === 1 ? "only" : value 8956 ); 8957 options.classes = that._resolveClassesValues( options.classes, instance ); 8958 instance.element[ instance.widgetName ]( options ); 8959 } else { 8960 that._updateCornerClass( children[ value ](), value ); 8961 } 8962 } ); 8963 8964 // Finally call the refresh method on each of the child widgets. 8965 this._callChildMethod( "refresh" ); 8966 } 8967 } 8968} ); 8969 8970/*! 8971 * jQuery UI Checkboxradio 1.14.
vendor: 7,789 bytes, lines 8971-9261
89711 8972 * https://jqueryui.com 8973 * 8974 * Copyright OpenJS Foundation and other contributors 8975 * Released under the MIT license. 8976 * https://jquery.org/license 8977 */ 8978 8979//>>label: Checkboxradio 8980//>>group: Widgets 8981//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 8982//>>docs: https://api.jqueryui.com/checkboxradio/ 8983//>>demos: https://jqueryui.com/checkboxradio/ 8984//>>css.structure: ../../themes/base/core.css 8985//>>css.structure: ../../themes/base/button.css 8986//>>css.structure: ../../themes/base/checkboxradio.css 8987//>>css.theme: ../../themes/base/theme.css 8988 8989 8990$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 8991 version: "1.14.1", 8992 options: { 8993 disabled: null, 8994 label: null, 8995 icon: true, 8996 classes: { 8997 "ui-checkboxradio-label": "ui-corner-all", 8998 "ui-checkboxradio-icon": "ui-corner-all" 8999 } 9000 }, 9001 9002 _getCreateOptions: function() { 9003 var disabled, labels, labelContents; 9004 var options = this._super() || {}; 9005 9006 // We read the type here, because it makes more sense to throw a element type error first, 9007 // rather then the error for lack of a label. Often if its the wrong type, it 9008 // won't have a label (e.g. calling on a div, btn, etc) 9009 this._readType(); 9010 9011 labels = this.element.labels(); 9012 9013 // If there are multiple labels, use the last one 9014 this.label = $( labels[ labels.length - 1 ] ); 9015 if ( !this.label.length ) { 9016 $.error( "No label found for checkboxradio widget" ); 9017 } 9018 9019 this.originalLabel = ""; 9020 9021 // We need to get the label text but this may also need to make sure it does not contain the 9022 // input itself. 9023 // The label contents could be text, html, or a mix. We wrap all elements 9024 // and read the wrapper's `innerHTML` to get a string representation of 9025 // the label, without the input as part of it. 9026 labelContents = this.label.contents().not( this.element[ 0 ] ); 9027 9028 if ( labelContents.length ) { 9029 this.originalLabel += labelContents 9030 .clone() 9031 .wrapAll( "<div></div>" ) 9032 .parent() 9033 .html(); 9034 } 9035 9036 // Set the label option if we found label text 9037 if ( this.originalLabel ) { 9038 options.label = this.originalLabel; 9039 } 9040 9041 disabled = this.element[ 0 ].disabled; 9042 if ( disabled != null ) { 9043 options.disabled = disabled; 9044 } 9045 return options; 9046 }, 9047 9048 _create: function() { 9049 var checked = this.element[ 0 ].checked; 9050 9051 this._bindFormResetHandler(); 9052 9053 if ( this.options.disabled == null ) { 9054 this.options.disabled = this.element[ 0 ].disabled; 9055 } 9056 9057 this._setOption( "disabled", this.options.disabled ); 9058 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 9059 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 9060 9061 if ( this.type === "radio" ) { 9062 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 9063 } 9064 9065 if ( this.options.label && this.options.label !== this.originalLabel ) { 9066 this._updateLabel(); 9067 } else if ( this.originalLabel ) { 9068 this.options.label = this.originalLabel; 9069 } 9070 9071 this._enhance(); 9072 9073 if ( checked ) { 9074 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 9075 } 9076 9077 this._on( { 9078 change: "_toggleClasses", 9079 focus: function() { 9080 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9081 }, 9082 blur: function() { 9083 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9084 } 9085 } ); 9086 }, 9087 9088 _readType: function() { 9089 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 9090 this.type = this.element[ 0 ].type; 9091 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 9092 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 9093 " and element.type=" + this.type ); 9094 } 9095 }, 9096 9097 // Support jQuery Mobile enhanced option 9098 _enhance: function() { 9099 this._updateIcon( this.element[ 0 ].checked ); 9100 }, 9101 9102 widget: function() { 9103 return this.label; 9104 }, 9105 9106 _getRadioGroup: function() { 9107 var group; 9108 var name = this.element[ 0 ].name; 9109 var nameSelector = "input[name='" + CSS.escape( name ) + "']"; 9110 9111 if ( !name ) { 9112 return $( [] ); 9113 } 9114 9115 if ( this.form.length ) { 9116 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 9117 } else { 9118 9119 // Not inside a form, check all inputs that also are not inside a form 9120 group = $( nameSelector ).filter( function() { 9121 return $( $( this ).prop( "form" ) ).length === 0; 9122 } ); 9123 } 9124 9125 return group.not( this.element ); 9126 }, 9127 9128 _toggleClasses: function() { 9129 var checked = this.element[ 0 ].checked; 9130 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9131 9132 if ( this.options.icon && this.type === "checkbox" ) { 9133 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 9134 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 9135 } 9136 9137 if ( this.type === "radio" ) { 9138 this._getRadioGroup() 9139 .each( function() { 9140 var instance = $( this ).checkboxradio( "instance" ); 9141 9142 if ( instance ) { 9143 instance._removeClass( instance.label, 9144 "ui-checkboxradio-checked", "ui-state-active" ); 9145 } 9146 } ); 9147 } 9148 }, 9149 9150 _destroy: function() { 9151 this._unbindFormResetHandler(); 9152 9153 if ( this.icon ) { 9154 this.icon.remove(); 9155 this.iconSpace.remove(); 9156 } 9157 }, 9158 9159 _setOption: function( key, value ) { 9160 9161 // We don't allow the value to be set to nothing 9162 if ( key === "label" && !value ) { 9163 return; 9164 } 9165 9166 this._super( key, value ); 9167 9168 if ( key === "disabled" ) { 9169 this._toggleClass( this.label, null, "ui-state-disabled", value ); 9170 this.element[ 0 ].disabled = value; 9171 9172 // Don't refresh when setting disabled 9173 return; 9174 } 9175 this.refresh(); 9176 }, 9177 9178 _updateIcon: function( checked ) { 9179 var toAdd = "ui-icon ui-icon-background "; 9180 9181 if ( this.options.icon ) { 9182 if ( !this.icon ) { 9183 this.icon = $( "<span>" ); 9184 this.iconSpace = $( "<span> </span>" ); 9185 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 9186 } 9187 9188 if ( this.type === "checkbox" ) { 9189 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 9190 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 9191 } else { 9192 toAdd += "ui-icon-blank"; 9193 } 9194 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 9195 if ( !checked ) { 9196 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 9197 } 9198 this.icon.prependTo( this.label ).after( this.iconSpace ); 9199 } else if ( this.icon !== undefined ) { 9200 this.icon.remove(); 9201 this.iconSpace.remove(); 9202 delete this.icon; 9203 } 9204 }, 9205 9206 _updateLabel: function() { 9207 9208 // Remove the contents of the label ( minus the icon, icon space, and input ) 9209 var contents = this.label.contents().not( this.element[ 0 ] ); 9210 if ( this.icon ) { 9211 contents = contents.not( this.icon[ 0 ] ); 9212 } 9213 if ( this.iconSpace ) { 9214 contents = contents.not( this.iconSpace[ 0 ] ); 9215 } 9216 contents.remove(); 9217 9218 this.label.append( this.options.label ); 9219 }, 9220 9221 refresh: function() { 9222 var checked = this.element[ 0 ].checked, 9223 isDisabled = this.element[ 0 ].disabled; 9224 9225 this._updateIcon( checked ); 9226 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9227 if ( this.options.label !== null ) { 9228 this._updateLabel(); 9229 } 9230 9231 if ( isDisabled !== this.options.disabled ) { 9232 this._setOptions( { "disabled": isDisabled } ); 9233 } 9234 } 9235 9236} ] ); 9237 9238var widgetsCheckboxradio = $.ui.checkboxradio; 9239 9240 9241/*! 9242 * jQuery UI Button 1.14.1 9243 * https://jqueryui.com 9244 * 9245 * Copyright OpenJS Foundation and other contributors 9246 * Released under the MIT license. 9247 * https://jquery.org/license 9248 */ 9249 9250//>>label: Button 9251//>>group: Widgets 9252//>>description: Enhances a form with themeable buttons. 9253//>>docs: https://api.jqueryui.com/button/ 9254//>>demos: https://jqueryui.com/button/ 9255//>>css.structure: ../../themes/base/core.css 9256//>>css.structure: ../../themes/base/button.css 9257//>>css.theme: ../../themes/base/theme.css 9258 9259 9260$.widget( "ui.button", { 9261 version: "1.14.1
vendor: 10,754 bytes, lines 9261-9666
9261", 9262 defaultElement: "<button>", 9263 options: { 9264 classes: { 9265 "ui-button": "ui-corner-all" 9266 }, 9267 disabled: null, 9268 icon: null, 9269 iconPosition: "beginning", 9270 label: null, 9271 showLabel: true 9272 }, 9273 9274 _getCreateOptions: function() { 9275 var disabled, 9276 9277 // This is to support cases like in jQuery Mobile where the base widget does have 9278 // an implementation of _getCreateOptions 9279 options = this._super() || {}; 9280 9281 this.isInput = this.element.is( "input" ); 9282 9283 disabled = this.element[ 0 ].disabled; 9284 if ( disabled != null ) { 9285 options.disabled = disabled; 9286 } 9287 9288 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 9289 if ( this.originalLabel ) { 9290 options.label = this.originalLabel; 9291 } 9292 9293 return options; 9294 }, 9295 9296 _create: function() { 9297 if ( !this.option.showLabel & !this.options.icon ) { 9298 this.options.showLabel = true; 9299 } 9300 9301 // We have to check the option again here even though we did in _getCreateOptions, 9302 // because null may have been passed on init which would override what was set in 9303 // _getCreateOptions 9304 if ( this.options.disabled == null ) { 9305 this.options.disabled = this.element[ 0 ].disabled || false; 9306 } 9307 9308 this.hasTitle = !!this.element.attr( "title" ); 9309 9310 // Check to see if the label needs to be set or if its already correct 9311 if ( this.options.label && this.options.label !== this.originalLabel ) { 9312 if ( this.isInput ) { 9313 this.element.val( this.options.label ); 9314 } else { 9315 this.element.html( this.options.label ); 9316 } 9317 } 9318 this._addClass( "ui-button", "ui-widget" ); 9319 this._setOption( "disabled", this.options.disabled ); 9320 this._enhance(); 9321 9322 if ( this.element.is( "a" ) ) { 9323 this._on( { 9324 "keyup": function( event ) { 9325 if ( event.keyCode === $.ui.keyCode.SPACE ) { 9326 event.preventDefault(); 9327 9328 // If a native click is available use it, so we 9329 // actually cause navigation. Otherwise, just trigger 9330 // a click event. 9331 if ( this.element[ 0 ].click ) { 9332 this.element[ 0 ].click(); 9333 } else { 9334 this.element.trigger( "click" ); 9335 } 9336 } 9337 } 9338 } ); 9339 } 9340 }, 9341 9342 _enhance: function() { 9343 if ( !this.element.is( "button" ) ) { 9344 this.element.attr( "role", "button" ); 9345 } 9346 9347 if ( this.options.icon ) { 9348 this._updateIcon( "icon", this.options.icon ); 9349 this._updateTooltip(); 9350 } 9351 }, 9352 9353 _updateTooltip: function() { 9354 this.title = this.element.attr( "title" ); 9355 9356 if ( !this.options.showLabel && !this.title ) { 9357 this.element.attr( "title", this.options.label ); 9358 } 9359 }, 9360 9361 _updateIcon: function( option, value ) { 9362 var icon = option !== "iconPosition", 9363 position = icon ? this.options.iconPosition : value, 9364 displayBlock = position === "top" || position === "bottom"; 9365 9366 // Create icon 9367 if ( !this.icon ) { 9368 this.icon = $( "<span>" ); 9369 9370 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 9371 9372 if ( !this.options.showLabel ) { 9373 this._addClass( "ui-button-icon-only" ); 9374 } 9375 } else if ( icon ) { 9376 9377 // If we are updating the icon remove the old icon class 9378 this._removeClass( this.icon, null, this.options.icon ); 9379 } 9380 9381 // If we are updating the icon add the new icon class 9382 if ( icon ) { 9383 this._addClass( this.icon, null, value ); 9384 } 9385 9386 this._attachIcon( position ); 9387 9388 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 9389 // the iconSpace if there is one. 9390 if ( displayBlock ) { 9391 this._addClass( this.icon, null, "ui-widget-icon-block" ); 9392 if ( this.iconSpace ) { 9393 this.iconSpace.remove(); 9394 } 9395 } else { 9396 9397 // Position is beginning or end so remove the ui-widget-icon-block class and add the 9398 // space if it does not exist 9399 if ( !this.iconSpace ) { 9400 this.iconSpace = $( "<span> </span>" ); 9401 this._addClass( this.iconSpace, "ui-button-icon-space" ); 9402 } 9403 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 9404 this._attachIconSpace( position ); 9405 } 9406 }, 9407 9408 _destroy: function() { 9409 this.element.removeAttr( "role" ); 9410 9411 if ( this.icon ) { 9412 this.icon.remove(); 9413 } 9414 if ( this.iconSpace ) { 9415 this.iconSpace.remove(); 9416 } 9417 if ( !this.hasTitle ) { 9418 this.element.removeAttr( "title" ); 9419 } 9420 }, 9421 9422 _attachIconSpace: function( iconPosition ) { 9423 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 9424 }, 9425 9426 _attachIcon: function( iconPosition ) { 9427 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 9428 }, 9429 9430 _setOptions: function( options ) { 9431 var newShowLabel = options.showLabel === undefined ? 9432 this.options.showLabel : 9433 options.showLabel, 9434 newIcon = options.icon === undefined ? this.options.icon : options.icon; 9435 9436 if ( !newShowLabel && !newIcon ) { 9437 options.showLabel = true; 9438 } 9439 this._super( options ); 9440 }, 9441 9442 _setOption: function( key, value ) { 9443 if ( key === "icon" ) { 9444 if ( value ) { 9445 this._updateIcon( key, value ); 9446 } else if ( this.icon ) { 9447 this.icon.remove(); 9448 if ( this.iconSpace ) { 9449 this.iconSpace.remove(); 9450 } 9451 } 9452 } 9453 9454 if ( key === "iconPosition" ) { 9455 this._updateIcon( key, value ); 9456 } 9457 9458 // Make sure we can't end up with a button that has neither text nor icon 9459 if ( key === "showLabel" ) { 9460 this._toggleClass( "ui-button-icon-only", null, !value ); 9461 this._updateTooltip(); 9462 } 9463 9464 if ( key === "label" ) { 9465 if ( this.isInput ) { 9466 this.element.val( value ); 9467 } else { 9468 9469 // If there is an icon, append it, else nothing then append the value 9470 // this avoids removal of the icon when setting label text 9471 this.element.html( value ); 9472 if ( this.icon ) { 9473 this._attachIcon( this.options.iconPosition ); 9474 this._attachIconSpace( this.options.iconPosition ); 9475 } 9476 } 9477 } 9478 9479 this._super( key, value ); 9480 9481 if ( key === "disabled" ) { 9482 this._toggleClass( null, "ui-state-disabled", value ); 9483 this.element[ 0 ].disabled = value; 9484 if ( value ) { 9485 this.element.trigger( "blur" ); 9486 } 9487 } 9488 }, 9489 9490 refresh: function() { 9491 9492 // Make sure to only check disabled if its an element that supports this otherwise 9493 // check for the disabled class to determine state 9494 var isDisabled = this.element.is( "input, button" ) ? 9495 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 9496 9497 if ( isDisabled !== this.options.disabled ) { 9498 this._setOptions( { disabled: isDisabled } ); 9499 } 9500 9501 this._updateTooltip(); 9502 } 9503} ); 9504 9505// DEPRECATED 9506if ( $.uiBackCompat === true ) { 9507 9508 // Text and Icons options 9509 $.widget( "ui.button", $.ui.button, { 9510 options: { 9511 text: true, 9512 icons: { 9513 primary: null, 9514 secondary: null 9515 } 9516 }, 9517 9518 _create: function() { 9519 if ( this.options.showLabel && !this.options.text ) { 9520 this.options.showLabel = this.options.text; 9521 } 9522 if ( !this.options.showLabel && this.options.text ) { 9523 this.options.text = this.options.showLabel; 9524 } 9525 if ( !this.options.icon && ( this.options.icons.primary || 9526 this.options.icons.secondary ) ) { 9527 if ( this.options.icons.primary ) { 9528 this.options.icon = this.options.icons.primary; 9529 } else { 9530 this.options.icon = this.options.icons.secondary; 9531 this.options.iconPosition = "end"; 9532 } 9533 } else if ( this.options.icon ) { 9534 this.options.icons.primary = this.options.icon; 9535 } 9536 this._super(); 9537 }, 9538 9539 _setOption: function( key, value ) { 9540 if ( key === "text" ) { 9541 this._super( "showLabel", value ); 9542 return; 9543 } 9544 if ( key === "showLabel" ) { 9545 this.options.text = value; 9546 } 9547 if ( key === "icon" ) { 9548 this.options.icons.primary = value; 9549 } 9550 if ( key === "icons" ) { 9551 if ( value.primary ) { 9552 this._super( "icon", value.primary ); 9553 this._super( "iconPosition", "beginning" ); 9554 } else if ( value.secondary ) { 9555 this._super( "icon", value.secondary ); 9556 this._super( "iconPosition", "end" ); 9557 } 9558 } 9559 this._superApply( arguments ); 9560 } 9561 } ); 9562 9563 $.fn.button = ( function( orig ) { 9564 return function( options ) { 9565 var isMethodCall = typeof options === "string"; 9566 var args = Array.prototype.slice.call( arguments, 1 ); 9567 var returnValue = this; 9568 9569 if ( isMethodCall ) { 9570 9571 // If this is an empty collection, we need to have the instance method 9572 // return undefined instead of the jQuery instance 9573 if ( !this.length && options === "instance" ) { 9574 returnValue = undefined; 9575 } else { 9576 this.each( function() { 9577 var methodValue; 9578 var type = $( this ).attr( "type" ); 9579 var name = type !== "checkbox" && type !== "radio" ? 9580 "button" : 9581 "checkboxradio"; 9582 var instance = $.data( this, "ui-" + name ); 9583 9584 if ( options === "instance" ) { 9585 returnValue = instance; 9586 return false; 9587 } 9588 9589 if ( !instance ) { 9590 return $.error( "cannot call methods on button" + 9591 " prior to initialization; " + 9592 "attempted to call method '" + options + "'" ); 9593 } 9594 9595 if ( typeof instance[ options ] !== "function" || 9596 options.charAt( 0 ) === "_" ) { 9597 return $.error( "no such method '" + options + "' for button" + 9598 " widget instance" ); 9599 } 9600 9601 methodValue = instance[ options ].apply( instance, args ); 9602 9603 if ( methodValue !== instance && methodValue !== undefined ) { 9604 returnValue = methodValue && methodValue.jquery ? 9605 returnValue.pushStack( methodValue.get() ) : 9606 methodValue; 9607 return false; 9608 } 9609 } ); 9610 } 9611 } else { 9612 9613 // Allow multiple hashes to be passed on init 9614 if ( args.length ) { 9615 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 9616 } 9617 9618 this.each( function() { 9619 var type = $( this ).attr( "type" ); 9620 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 9621 var instance = $.data( this, "ui-" + name ); 9622 9623 if ( instance ) { 9624 instance.option( options || {} ); 9625 if ( instance._init ) { 9626 instance._init(); 9627 } 9628 } else { 9629 if ( name === "button" ) { 9630 orig.call( $( this ), options ); 9631 return; 9632 } 9633 9634 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 9635 } 9636 } ); 9637 } 9638 9639 return returnValue; 9640 }; 9641 } )( $.fn.button ); 9642 9643 $.fn.buttonset = function() { 9644 if ( !$.ui.controlgroup ) { 9645 $.error( "Controlgroup widget missing" ); 9646 } 9647 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 9648 return this.controlgroup.apply( this, 9649 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 9650 } 9651 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 9652 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 9653 } 9654 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 9655 arguments[ 0 ].items = { 9656 button: arguments[ 0 ].items 9657 }; 9658 } 9659 return this.controlgroup.apply( this, arguments ); 9660 }; 9661} 9662 9663var widgetsButton = $.ui.button; 9664 9665 9666/* eslint-disable max-len
9666, camelcase */ 9667/*! 9668 * jQuery UI Datepicker 1.14.1 9669 * https://jqueryui.com 9670 * 9671 * Copyright OpenJS Foundation and other contributors 9672 * Released under the MIT license. 9673 * https://jquery.org/license 9674 */ 9675 9676//>>label: Datepicker 9677//>>group: Widgets 9678//>>description: Displays a calendar from an input or inline for selecting dates. 9679//>>docs: https://api.jqueryui.com/datepicker/ 9680//>>demos: https://jqueryui.com/datepicker/ 9681//>>css.structure: ../../themes/base/core.css 9682//>>css.structure: ../../themes/base/datepicker.css 9683//>>css.theme: ../../themes/base/theme.css 9684 9685 9686$.extend( $.ui, { datepicker: { version: "1.14.1
vendor: 20,464 bytes, lines 9686-10185
9686" } } ); 9687 9688var datepicker_instActive; 9689 9690function datepicker_getZindex( elem ) { 9691 var position, value; 9692 while ( elem.length && elem[ 0 ] !== document ) { 9693 9694 // Ignore z-index if position is set to a value where z-index is ignored by the browser 9695 // This makes behavior of this function consistent across browsers 9696 // WebKit always returns auto if the element is positioned 9697 position = elem.css( "position" ); 9698 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 9699 9700 // IE returns 0 when zIndex is not specified 9701 // other browsers return a string 9702 // we ignore the case of nested elements with an explicit value of 0 9703 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 9704 value = parseInt( elem.css( "zIndex" ), 10 ); 9705 if ( !isNaN( value ) && value !== 0 ) { 9706 return value; 9707 } 9708 } 9709 elem = elem.parent(); 9710 } 9711 9712 return 0; 9713} 9714 9715/* Date picker manager. 9716 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 9717 Settings for (groups of) date pickers are maintained in an instance object, 9718 allowing multiple different settings on the same page. */ 9719 9720function Datepicker() { 9721 this._curInst = null; // The current instance in use 9722 this._keyEvent = false; // If the last event was a key event 9723 this._disabledInputs = []; // List of date picker inputs that have been disabled 9724 this._datepickerShowing = false; // True if the popup picker is showing , false if not 9725 this._inDialog = false; // True if showing within a "dialog", false if not 9726 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 9727 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 9728 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 9729 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 9730 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 9731 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 9732 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 9733 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 9734 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 9735 this.regional = []; // Available regional settings, indexed by language code 9736 this.regional[ "" ] = { // Default regional settings 9737 closeText: "Done", // Display text for close link 9738 prevText: "Prev", // Display text for previous month link 9739 nextText: "Next", // Display text for next month link 9740 currentText: "Today", // Display text for current month link 9741 monthNames: [ "January", "February", "March", "April", "May", "June", 9742 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 9743 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 9744 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 9745 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 9746 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 9747 weekHeader: "Wk", // Column header for week of the year 9748 dateFormat: "mm/dd/yy", // See format options on parseDate 9749 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 9750 isRTL: false, // True if right-to-left language, false if left-to-right 9751 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 9752 yearSuffix: "", // Additional text to append to the year in the month headers, 9753 selectMonthLabel: "Select month", // Invisible label for month selector 9754 selectYearLabel: "Select year" // Invisible label for year selector 9755 }; 9756 this._defaults = { // Global defaults for all the date picker instances 9757 showOn: "focus", // "focus" for popup on focus, 9758 // "button" for trigger button, or "both" for either 9759 showAnim: "fadeIn", // Name of jQuery animation for popup 9760 showOptions: {}, // Options for enhanced animations 9761 defaultDate: null, // Used when field is blank: actual date, 9762 // +/-number for offset from today, null for today 9763 appendText: "", // Display text following the input box, e.g. showing the format 9764 buttonText: "...", // Text for trigger button 9765 buttonImage: "", // URL for trigger button image 9766 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 9767 hideIfNoPrevNext: false, // True to hide next/previous month links 9768 // if not applicable, false to just disable them 9769 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 9770 gotoCurrent: false, // True if today link goes back to current selection instead 9771 changeMonth: false, // True if month can be selected directly, false if only prev/next 9772 changeYear: false, // True if year can be selected directly, false if only prev/next 9773 yearRange: "c-10:c+10", // Range of years to display in drop-down, 9774 // either relative to today's year (-nn:+nn), relative to currently displayed year 9775 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 9776 showOtherMonths: false, // True to show dates in other months, false to leave blank 9777 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 9778 showWeek: false, // True to show week of the year, false to not show it 9779 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 9780 // takes a Date and returns the number of the week for it 9781 shortYearCutoff: "+10", // Short year values < this are in the current century, 9782 // > this are in the previous century, 9783 // string value starting with "+" for current year + value 9784 minDate: null, // The earliest selectable date, or null for no limit 9785 maxDate: null, // The latest selectable date, or null for no limit 9786 duration: "fast", // Duration of display/closure 9787 beforeShowDay: null, // Function that takes a date and returns an array with 9788 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 9789 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 9790 beforeShow: null, // Function that takes an input field and 9791 // returns a set of custom settings for the date picker 9792 onSelect: null, // Define a callback function when a date is selected 9793 onChangeMonthYear: null, // Define a callback function when the month or year is changed 9794 onClose: null, // Define a callback function when the datepicker is closed 9795 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 9796 numberOfMonths: 1, // Number of months to show at a time 9797 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 9798 stepMonths: 1, // Number of months to step back/forward 9799 stepBigMonths: 12, // Number of months to step back/forward for the big links 9800 altField: "", // Selector for an alternate field to store selected dates into 9801 altFormat: "", // The date format to use for the alternate field 9802 constrainInput: true, // The input is constrained by the current date format 9803 showButtonPanel: false, // True to show button panel, false to not show it 9804 autoSize: false, // True to size the input for the date format, false to leave as is 9805 disabled: false // The initial disabled state 9806 }; 9807 $.extend( this._defaults, this.regional[ "" ] ); 9808 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 9809 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 9810 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 9811} 9812 9813$.extend( Datepicker.prototype, { 9814 9815 /* Class name added to elements to indicate already configured with a date picker. */ 9816 markerClassName: "hasDatepicker", 9817 9818 //Keep track of the maximum number of rows displayed (see #7043) 9819 maxRows: 4, 9820 9821 // TODO rename to "widget" when switching to widget factory 9822 _widgetDatepicker: function() { 9823 return this.dpDiv; 9824 }, 9825 9826 /* Override the default settings for all instances of the date picker. 9827 * @param settings object - the new settings to use as defaults (anonymous object) 9828 * @return the manager object 9829 */ 9830 setDefaults: function( settings ) { 9831 datepicker_extendRemove( this._defaults, settings || {} ); 9832 return this; 9833 }, 9834 9835 /* Attach the date picker to a jQuery selection. 9836 * @param target element - the target input field or division or span 9837 * @param settings object - the new settings to use for this date picker instance (anonymous) 9838 */ 9839 _attachDatepicker: function( target, settings ) { 9840 var nodeName, inline, inst; 9841 nodeName = target.nodeName.toLowerCase(); 9842 inline = ( nodeName === "div" || nodeName === "span" ); 9843 if ( !target.id ) { 9844 this.uuid += 1; 9845 target.id = "dp" + this.uuid; 9846 } 9847 inst = this._newInst( $( target ), inline ); 9848 inst.settings = $.extend( {}, settings || {} ); 9849 if ( nodeName === "input" ) { 9850 this._connectDatepicker( target, inst ); 9851 } else if ( inline ) { 9852 this._inlineDatepicker( target, inst ); 9853 } 9854 }, 9855 9856 /* Create a new instance object. */ 9857 _newInst: function( target, inline ) { 9858 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 9859 return { id: id, input: target, // associated target 9860 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 9861 drawMonth: 0, drawYear: 0, // month being drawn 9862 inline: inline, // is datepicker inline or not 9863 dpDiv: ( !inline ? this.dpDiv : // presentation div 9864 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 9865 }, 9866 9867 /* Attach the date picker to an input field. */ 9868 _connectDatepicker: function( target, inst ) { 9869 var input = $( target ); 9870 inst.append = $( [] ); 9871 inst.trigger = $( [] ); 9872 if ( input.hasClass( this.markerClassName ) ) { 9873 return; 9874 } 9875 this._attachments( input, inst ); 9876 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 9877 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 9878 this._autoSize( inst ); 9879 $.data( target, "datepicker", inst ); 9880 9881 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 9882 if ( inst.settings.disabled ) { 9883 this._disableDatepicker( target ); 9884 } 9885 }, 9886 9887 /* Make attachments based on settings. */ 9888 _attachments: function( input, inst ) { 9889 var showOn, buttonText, buttonImage, 9890 appendText = this._get( inst, "appendText" ), 9891 isRTL = this._get( inst, "isRTL" ); 9892 9893 if ( inst.append ) { 9894 inst.append.remove(); 9895 } 9896 if ( appendText ) { 9897 inst.append = $( "<span>" ) 9898 .addClass( this._appendClass ) 9899 .text( appendText ); 9900 input[ isRTL ? "before" : "after" ]( inst.append ); 9901 } 9902 9903 input.off( "focus", this._showDatepicker ); 9904 9905 if ( inst.trigger ) { 9906 inst.trigger.remove(); 9907 } 9908 9909 showOn = this._get( inst, "showOn" ); 9910 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 9911 input.on( "focus", this._showDatepicker ); 9912 } 9913 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 9914 buttonText = this._get( inst, "buttonText" ); 9915 buttonImage = this._get( inst, "buttonImage" ); 9916 9917 if ( this._get( inst, "buttonImageOnly" ) ) { 9918 inst.trigger = $( "<img>" ) 9919 .addClass( this._triggerClass ) 9920 .attr( { 9921 src: buttonImage, 9922 alt: buttonText, 9923 title: buttonText 9924 } ); 9925 } else { 9926 inst.trigger = $( "<button type='button'>" ) 9927 .addClass( this._triggerClass ); 9928 if ( buttonImage ) { 9929 inst.trigger.html( 9930 $( "<img>" ) 9931 .attr( { 9932 src: buttonImage, 9933 alt: buttonText, 9934 title: buttonText 9935 } ) 9936 ); 9937 } else { 9938 inst.trigger.text( buttonText ); 9939 } 9940 } 9941 9942 input[ isRTL ? "before" : "after" ]( inst.trigger ); 9943 inst.trigger.on( "click", function() { 9944 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 9945 $.datepicker._hideDatepicker(); 9946 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 9947 $.datepicker._hideDatepicker(); 9948 $.datepicker._showDatepicker( input[ 0 ] ); 9949 } else { 9950 $.datepicker._showDatepicker( input[ 0 ] ); 9951 } 9952 return false; 9953 } ); 9954 } 9955 }, 9956 9957 /* Apply the maximum length for the date format. */ 9958 _autoSize: function( inst ) { 9959 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 9960 var findMax, max, maxI, i, 9961 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 9962 dateFormat = this._get( inst, "dateFormat" ); 9963 9964 if ( dateFormat.match( /[DM]/ ) ) { 9965 findMax = function( names ) { 9966 max = 0; 9967 maxI = 0; 9968 for ( i = 0; i < names.length; i++ ) { 9969 if ( names[ i ].length > max ) { 9970 max = names[ i ].length; 9971 maxI = i; 9972 } 9973 } 9974 return maxI; 9975 }; 9976 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 9977 "monthNames" : "monthNamesShort" ) ) ) ); 9978 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 9979 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 9980 } 9981 inst.input.attr( "size", this._formatDate( inst, date ).length ); 9982 } 9983 }, 9984 9985 /* Attach an inline date picker to a div. */ 9986 _inlineDatepicker: function( target, inst ) { 9987 var divSpan = $( target ); 9988 if ( divSpan.hasClass( this.markerClassName ) ) { 9989 return; 9990 } 9991 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 9992 $.data( target, "datepicker", inst ); 9993 this._setDate( inst, this._getDefaultDate( inst ), true ); 9994 this._updateDatepicker( inst ); 9995 this._updateAlternate( inst ); 9996 9997 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 9998 if ( inst.settings.disabled ) { 9999 this._disableDatepicker( target ); 10000 } 10001 10002 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 10003 // https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 10004 inst.dpDiv.css( "display", "block" ); 10005 }, 10006 10007 /* Pop-up the date picker in a "dialog" box. 10008 * @param input element - ignored 10009 * @param date string or Date - the initial date to display 10010 * @param onSelect function - the function to call when a date is selected 10011 * @param settings object - update the dialog date picker instance's settings (anonymous object) 10012 * @param pos int[2] - coordinates for the dialog's position within the screen or 10013 * event - with x/y coordinates or 10014 * leave empty for default (screen centre) 10015 * @return the manager object 10016 */ 10017 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 10018 var id, browserWidth, browserHeight, scrollX, scrollY, 10019 inst = this._dialogInst; // internal instance 10020 10021 if ( !inst ) { 10022 this.uuid += 1; 10023 id = "dp" + this.uuid; 10024 this._dialogInput = $( "<input type='text' id='" + id + 10025 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 10026 this._dialogInput.on( "keydown", this._doKeyDown ); 10027 $( "body" ).append( this._dialogInput ); 10028 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 10029 inst.settings = {}; 10030 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 10031 } 10032 datepicker_extendRemove( inst.settings, settings || {} ); 10033 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 10034 this._dialogInput.val( date ); 10035 10036 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 10037 if ( !this._pos ) { 10038 browserWidth = document.documentElement.clientWidth; 10039 browserHeight = document.documentElement.clientHeight; 10040 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 10041 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 10042 this._pos = // should use actual width/height below 10043 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 10044 } 10045 10046 // Move input on screen for focus, but hidden behind dialog 10047 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 10048 inst.settings.onSelect = onSelect; 10049 this._inDialog = true; 10050 this.dpDiv.addClass( this._dialogClass ); 10051 this._showDatepicker( this._dialogInput[ 0 ] ); 10052 if ( $.blockUI ) { 10053 $.blockUI( this.dpDiv ); 10054 } 10055 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 10056 return this; 10057 }, 10058 10059 /* Detach a datepicker from its control. 10060 * @param target element - the target input field or division or span 10061 */ 10062 _destroyDatepicker: function( target ) { 10063 var nodeName, 10064 $target = $( target ), 10065 inst = $.data( target, "datepicker" ); 10066 10067 if ( !$target.hasClass( this.markerClassName ) ) { 10068 return; 10069 } 10070 10071 nodeName = target.nodeName.toLowerCase(); 10072 $.removeData( target, "datepicker" ); 10073 if ( nodeName === "input" ) { 10074 inst.append.remove(); 10075 inst.trigger.remove(); 10076 $target.removeClass( this.markerClassName ). 10077 off( "focus", this._showDatepicker ). 10078 off( "keydown", this._doKeyDown ). 10079 off( "keypress", this._doKeyPress ). 10080 off( "keyup", this._doKeyUp ); 10081 } else if ( nodeName === "div" || nodeName === "span" ) { 10082 $target.removeClass( this.markerClassName ).empty(); 10083 } 10084 10085 $.datepicker._hideDatepicker(); 10086 if ( datepicker_instActive === inst ) { 10087 datepicker_instActive = null; 10088 this._curInst = null; 10089 } 10090 }, 10091 10092 /* Enable the date picker to a jQuery selection. 10093 * @param target element - the target input field or division or span 10094 */ 10095 _enableDatepicker: function( target ) { 10096 var nodeName, inline, 10097 $target = $( target ), 10098 inst = $.data( target, "datepicker" ); 10099 10100 if ( !$target.hasClass( this.markerClassName ) ) { 10101 return; 10102 } 10103 10104 nodeName = target.nodeName.toLowerCase(); 10105 if ( nodeName === "input" ) { 10106 target.disabled = false; 10107 inst.trigger.filter( "button" ). 10108 each( function() { 10109 this.disabled = false; 10110 } ).end(). 10111 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 10112 } else if ( nodeName === "div" || nodeName === "span" ) { 10113 inline = $target.children( "." + this._inlineClass ); 10114 inline.children().removeClass( "ui-state-disabled" ); 10115 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 10116 prop( "disabled", false ); 10117 } 10118 this._disabledInputs = $.map( this._disabledInputs, 10119 10120 // Delete entry 10121 function( value ) { 10122 return ( value === target ? null : value ); 10123 } ); 10124 }, 10125 10126 /* Disable the date picker to a jQuery selection. 10127 * @param target element - the target input field or division or span 10128 */ 10129 _disableDatepicker: function( target ) { 10130 var nodeName, inline, 10131 $target = $( target ), 10132 inst = $.data( target, "datepicker" ); 10133 10134 if ( !$target.hasClass( this.markerClassName ) ) { 10135 return; 10136 } 10137 10138 nodeName = target.nodeName.toLowerCase(); 10139 if ( nodeName === "input" ) { 10140 target.disabled = true; 10141 inst.trigger.filter( "button" ). 10142 each( function() { 10143 this.disabled = true; 10144 } ).end(). 10145 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 10146 } else if ( nodeName === "div" || nodeName === "span" ) { 10147 inline = $target.children( "." + this._inlineClass ); 10148 inline.children().addClass( "ui-state-disabled" ); 10149 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 10150 prop( "disabled", true ); 10151 } 10152 this._disabledInputs = $.map( this._disabledInputs, 10153 10154 // Delete entry 10155 function( value ) { 10156 return ( value === target ? null : value ); 10157 } ); 10158 this._disabledInputs[ this._disabledInputs.length ] = target; 10159 }, 10160 10161 /* Is the first field in a jQuery collection disabled as a datepicker? 10162 * @param target element - the target input field or division or span 10163 * @return boolean - true if disabled, false if enabled 10164 */ 10165 _isDisabledDatepicker: function( target ) { 10166 if ( !target ) { 10167 return false; 10168 } 10169 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 10170 if ( this._disabledInputs[ i ] === target ) { 10171 return true; 10172 } 10173 } 10174 return false; 10175 }, 10176 10177 /* Retrieve the instance data for the target control. 10178 * @param target element - the target input field or division or span 10179 * @return object - the associated instance data 10180 * @throws error if a jQuery problem getting data 10181 */ 10182 _getInst: function( target ) { 10183 try { 10184 return $.data( target, "datepicker" ); 10185 } catch (
vendor: 8,426 bytes, lines 10185-10426
10185err ) { 10186 throw "Missing instance data for this datepicker"; 10187 } 10188 }, 10189 10190 /* Update or retrieve the settings for a date picker attached to an input field or division. 10191 * @param target element - the target input field or division or span 10192 * @param name object - the new settings to update or 10193 * string - the name of the setting to change or retrieve, 10194 * when retrieving also "all" for all instance settings or 10195 * "defaults" for all global defaults 10196 * @param value any - the new value for the setting 10197 * (omit if above is an object or to retrieve a value) 10198 */ 10199 _optionDatepicker: function( target, name, value ) { 10200 var settings, date, minDate, maxDate, 10201 inst = this._getInst( target ); 10202 10203 if ( arguments.length === 2 && typeof name === "string" ) { 10204 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 10205 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 10206 this._get( inst, name ) ) : null ) ); 10207 } 10208 10209 settings = name || {}; 10210 if ( typeof name === "string" ) { 10211 settings = {}; 10212 settings[ name ] = value; 10213 } 10214 10215 if ( inst ) { 10216 if ( this._curInst === inst ) { 10217 this._hideDatepicker(); 10218 } 10219 10220 date = this._getDateDatepicker( target, true ); 10221 minDate = this._getMinMaxDate( inst, "min" ); 10222 maxDate = this._getMinMaxDate( inst, "max" ); 10223 datepicker_extendRemove( inst.settings, settings ); 10224 10225 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 10226 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 10227 inst.settings.minDate = this._formatDate( inst, minDate ); 10228 } 10229 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 10230 inst.settings.maxDate = this._formatDate( inst, maxDate ); 10231 } 10232 if ( "disabled" in settings ) { 10233 if ( settings.disabled ) { 10234 this._disableDatepicker( target ); 10235 } else { 10236 this._enableDatepicker( target ); 10237 } 10238 } 10239 this._attachments( $( target ), inst ); 10240 this._autoSize( inst ); 10241 this._setDate( inst, date ); 10242 this._updateAlternate( inst ); 10243 this._updateDatepicker( inst ); 10244 } 10245 }, 10246 10247 // Change method deprecated 10248 _changeDatepicker: function( target, name, value ) { 10249 this._optionDatepicker( target, name, value ); 10250 }, 10251 10252 /* Redraw the date picker attached to an input field or division. 10253 * @param target element - the target input field or division or span 10254 */ 10255 _refreshDatepicker: function( target ) { 10256 var inst = this._getInst( target ); 10257 if ( inst ) { 10258 this._updateDatepicker( inst ); 10259 } 10260 }, 10261 10262 /* Set the dates for a jQuery selection. 10263 * @param target element - the target input field or division or span 10264 * @param date Date - the new date 10265 */ 10266 _setDateDatepicker: function( target, date ) { 10267 var inst = this._getInst( target ); 10268 if ( inst ) { 10269 this._setDate( inst, date ); 10270 this._updateDatepicker( inst ); 10271 this._updateAlternate( inst ); 10272 } 10273 }, 10274 10275 /* Get the date(s) for the first entry in a jQuery selection. 10276 * @param target element - the target input field or division or span 10277 * @param noDefault boolean - true if no default date is to be used 10278 * @return Date - the current date 10279 */ 10280 _getDateDatepicker: function( target, noDefault ) { 10281 var inst = this._getInst( target ); 10282 if ( inst && !inst.inline ) { 10283 this._setDateFromField( inst, noDefault ); 10284 } 10285 return ( inst ? this._getDate( inst ) : null ); 10286 }, 10287 10288 /* Handle keystrokes. */ 10289 _doKeyDown: function( event ) { 10290 var onSelect, dateStr, sel, 10291 inst = $.datepicker._getInst( event.target ), 10292 handled = true, 10293 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 10294 10295 inst._keyEvent = true; 10296 if ( $.datepicker._datepickerShowing ) { 10297 switch ( event.keyCode ) { 10298 case 9: $.datepicker._hideDatepicker(); 10299 handled = false; 10300 break; // hide on tab out 10301 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 10302 $.datepicker._currentClass + ")", inst.dpDiv ); 10303 if ( sel[ 0 ] ) { 10304 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 10305 } 10306 10307 onSelect = $.datepicker._get( inst, "onSelect" ); 10308 if ( onSelect ) { 10309 dateStr = $.datepicker._formatDate( inst ); 10310 10311 // Trigger custom callback 10312 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 10313 } else { 10314 $.datepicker._hideDatepicker(); 10315 } 10316 10317 return false; // don't submit the form 10318 case 27: $.datepicker._hideDatepicker(); 10319 break; // hide on escape 10320 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10321 -$.datepicker._get( inst, "stepBigMonths" ) : 10322 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10323 break; // previous month/year on page up/+ ctrl 10324 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10325 +$.datepicker._get( inst, "stepBigMonths" ) : 10326 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10327 break; // next month/year on page down/+ ctrl 10328 case 35: if ( event.ctrlKey || event.metaKey ) { 10329 $.datepicker._clearDate( event.target ); 10330 } 10331 handled = event.ctrlKey || event.metaKey; 10332 break; // clear on ctrl or command +end 10333 case 36: if ( event.ctrlKey || event.metaKey ) { 10334 $.datepicker._gotoToday( event.target ); 10335 } 10336 handled = event.ctrlKey || event.metaKey; 10337 break; // current on ctrl or command +home 10338 case 37: if ( event.ctrlKey || event.metaKey ) { 10339 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 10340 } 10341 handled = event.ctrlKey || event.metaKey; 10342 10343 // -1 day on ctrl or command +left 10344 if ( event.originalEvent.altKey ) { 10345 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10346 -$.datepicker._get( inst, "stepBigMonths" ) : 10347 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10348 } 10349 10350 // next month/year on alt +left on Mac 10351 break; 10352 case 38: if ( event.ctrlKey || event.metaKey ) { 10353 $.datepicker._adjustDate( event.target, -7, "D" ); 10354 } 10355 handled = event.ctrlKey || event.metaKey; 10356 break; // -1 week on ctrl or command +up 10357 case 39: if ( event.ctrlKey || event.metaKey ) { 10358 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 10359 } 10360 handled = event.ctrlKey || event.metaKey; 10361 10362 // +1 day on ctrl or command +right 10363 if ( event.originalEvent.altKey ) { 10364 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10365 +$.datepicker._get( inst, "stepBigMonths" ) : 10366 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10367 } 10368 10369 // next month/year on alt +right 10370 break; 10371 case 40: if ( event.ctrlKey || event.metaKey ) { 10372 $.datepicker._adjustDate( event.target, +7, "D" ); 10373 } 10374 handled = event.ctrlKey || event.metaKey; 10375 break; // +1 week on ctrl or command +down 10376 default: handled = false; 10377 } 10378 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 10379 $.datepicker._showDatepicker( this ); 10380 } else { 10381 handled = false; 10382 } 10383 10384 if ( handled ) { 10385 event.preventDefault(); 10386 event.stopPropagation(); 10387 } 10388 }, 10389 10390 /* Filter entered characters - based on date format. */ 10391 _doKeyPress: function( event ) { 10392 var chars, chr, 10393 inst = $.datepicker._getInst( event.target ); 10394 10395 if ( $.datepicker._get( inst, "constrainInput" ) ) { 10396 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 10397 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 10398 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 10399 } 10400 }, 10401 10402 /* Synchronise manual entry and field/alternate field. */ 10403 _doKeyUp: function( event ) { 10404 var date, 10405 inst = $.datepicker._getInst( event.target ); 10406 10407 if ( inst.input.val() !== inst.lastVal ) { 10408 try { 10409 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 10410 ( inst.input ? inst.input.val() : null ), 10411 $.datepicker._getFormatConfig( inst ) ); 10412 10413 if ( date ) { // only if valid 10414 $.datepicker._setDateFromField( inst ); 10415 $.datepicker._updateAlternate( inst ); 10416 $.datepicker._updateDatepicker( inst ); 10417 } 10418 } catch ( err ) { 10419 } 10420 } 10421 return true; 10422 }, 10423 10424 /* Pop-up the date picker for a given input field. 10425 * If false returned from beforeShow event handler do not show. 10426 * @param input element - the input field attached to the date picker or
vendor: 14,198 bytes, lines 10427-10836
10427 * event - if triggered by focus 10428 */ 10429 _showDatepicker: function( input ) { 10430 input = input.target || input; 10431 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 10432 input = $( "input", input.parentNode )[ 0 ]; 10433 } 10434 10435 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 10436 return; 10437 } 10438 10439 var inst, beforeShow, beforeShowSettings, isFixed, 10440 offset, showAnim, duration; 10441 10442 inst = $.datepicker._getInst( input ); 10443 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 10444 $.datepicker._curInst.dpDiv.stop( true, true ); 10445 if ( inst && $.datepicker._datepickerShowing ) { 10446 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 10447 } 10448 } 10449 10450 beforeShow = $.datepicker._get( inst, "beforeShow" ); 10451 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 10452 if ( beforeShowSettings === false ) { 10453 return; 10454 } 10455 datepicker_extendRemove( inst.settings, beforeShowSettings ); 10456 10457 inst.lastVal = null; 10458 $.datepicker._lastInput = input; 10459 $.datepicker._setDateFromField( inst ); 10460 10461 if ( $.datepicker._inDialog ) { // hide cursor 10462 input.value = ""; 10463 } 10464 if ( !$.datepicker._pos ) { // position below input 10465 $.datepicker._pos = $.datepicker._findPos( input ); 10466 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 10467 } 10468 10469 isFixed = false; 10470 $( input ).parents().each( function() { 10471 isFixed |= $( this ).css( "position" ) === "fixed"; 10472 return !isFixed; 10473 } ); 10474 10475 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 10476 $.datepicker._pos = null; 10477 10478 //to avoid flashes on Firefox 10479 inst.dpDiv.empty(); 10480 10481 // determine sizing offscreen 10482 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 10483 $.datepicker._updateDatepicker( inst ); 10484 10485 // fix width for dynamic number of date pickers 10486 // and adjust position before showing 10487 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 10488 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 10489 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 10490 left: offset.left + "px", top: offset.top + "px" } ); 10491 10492 if ( !inst.inline ) { 10493 showAnim = $.datepicker._get( inst, "showAnim" ); 10494 duration = $.datepicker._get( inst, "duration" ); 10495 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 10496 $.datepicker._datepickerShowing = true; 10497 10498 if ( $.effects && $.effects.effect[ showAnim ] ) { 10499 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 10500 } else { 10501 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 10502 } 10503 10504 if ( $.datepicker._shouldFocusInput( inst ) ) { 10505 inst.input.trigger( "focus" ); 10506 } 10507 10508 $.datepicker._curInst = inst; 10509 } 10510 }, 10511 10512 /* Generate the date picker content. */ 10513 _updateDatepicker: function( inst ) { 10514 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 10515 datepicker_instActive = inst; // for delegate hover events 10516 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 10517 this._attachHandlers( inst ); 10518 10519 var origyearshtml, 10520 numMonths = this._getNumberOfMonths( inst ), 10521 cols = numMonths[ 1 ], 10522 width = 17, 10523 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 10524 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 10525 10526 if ( activeCell.length > 0 ) { 10527 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 10528 } 10529 10530 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 10531 if ( cols > 1 ) { 10532 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 10533 } 10534 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 10535 "Class" ]( "ui-datepicker-multi" ); 10536 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 10537 "Class" ]( "ui-datepicker-rtl" ); 10538 10539 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 10540 inst.input.trigger( "focus" ); 10541 } 10542 10543 // Deffered render of the years select (to avoid flashes on Firefox) 10544 if ( inst.yearshtml ) { 10545 origyearshtml = inst.yearshtml; 10546 setTimeout( function() { 10547 10548 //assure that inst.yearshtml didn't change. 10549 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 10550 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 10551 } 10552 origyearshtml = inst.yearshtml = null; 10553 }, 0 ); 10554 } 10555 10556 if ( onUpdateDatepicker ) { 10557 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 10558 } 10559 }, 10560 10561 _shouldFocusInput: function( inst ) { 10562 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ); 10563 }, 10564 10565 /* Check positioning to remain on screen. */ 10566 _checkOffset: function( inst, offset, isFixed ) { 10567 var dpWidth = inst.dpDiv.outerWidth(), 10568 dpHeight = inst.dpDiv.outerHeight(), 10569 inputWidth = inst.input ? inst.input.outerWidth() : 0, 10570 inputHeight = inst.input ? inst.input.outerHeight() : 0, 10571 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 10572 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 10573 10574 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 10575 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 10576 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 10577 10578 // Now check if datepicker is showing outside window viewport - move to a better place if so. 10579 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 10580 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 10581 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 10582 Math.abs( dpHeight + inputHeight ) : 0 ); 10583 10584 return offset; 10585 }, 10586 10587 /* Find an object's position on the screen. */ 10588 _findPos: function( obj ) { 10589 var position, 10590 inst = this._getInst( obj ), 10591 isRTL = this._get( inst, "isRTL" ); 10592 10593 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 10594 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 10595 } 10596 10597 position = $( obj ).offset(); 10598 return [ position.left, position.top ]; 10599 }, 10600 10601 /* Hide the date picker from view. 10602 * @param input element - the input field attached to the date picker 10603 */ 10604 _hideDatepicker: function( input ) { 10605 var showAnim, duration, postProcess, onClose, 10606 inst = this._curInst; 10607 10608 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 10609 return; 10610 } 10611 10612 if ( this._datepickerShowing ) { 10613 showAnim = this._get( inst, "showAnim" ); 10614 duration = this._get( inst, "duration" ); 10615 postProcess = function() { 10616 $.datepicker._tidyDialog( inst ); 10617 }; 10618 10619 if ( $.effects && ( $.effects.effect[ showAnim ] ) ) { 10620 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 10621 } else { 10622 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 10623 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 10624 } 10625 10626 if ( !showAnim ) { 10627 postProcess(); 10628 } 10629 this._datepickerShowing = false; 10630 10631 onClose = this._get( inst, "onClose" ); 10632 if ( onClose ) { 10633 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 10634 } 10635 10636 this._lastInput = null; 10637 if ( this._inDialog ) { 10638 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 10639 if ( $.blockUI ) { 10640 $.unblockUI(); 10641 $( "body" ).append( this.dpDiv ); 10642 } 10643 } 10644 this._inDialog = false; 10645 } 10646 }, 10647 10648 /* Tidy up after a dialog display. */ 10649 _tidyDialog: function( inst ) { 10650 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 10651 }, 10652 10653 /* Close date picker if clicked elsewhere. */ 10654 _checkExternalClick: function( event ) { 10655 if ( !$.datepicker._curInst ) { 10656 return; 10657 } 10658 10659 var $target = $( event.target ), 10660 inst = $.datepicker._getInst( $target[ 0 ] ); 10661 10662 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 10663 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 10664 !$target.hasClass( $.datepicker.markerClassName ) && 10665 !$target.closest( "." + $.datepicker._triggerClass ).length && 10666 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 10667 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 10668 $.datepicker._hideDatepicker(); 10669 } 10670 }, 10671 10672 /* Adjust one of the date sub-fields. */ 10673 _adjustDate: function( id, offset, period ) { 10674 var target = $( id ), 10675 inst = this._getInst( target[ 0 ] ); 10676 10677 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 10678 return; 10679 } 10680 this._adjustInstDate( inst, offset, period ); 10681 this._updateDatepicker( inst ); 10682 }, 10683 10684 /* Action for current link. */ 10685 _gotoToday: function( id ) { 10686 var date, 10687 target = $( id ), 10688 inst = this._getInst( target[ 0 ] ); 10689 10690 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 10691 inst.selectedDay = inst.currentDay; 10692 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 10693 inst.drawYear = inst.selectedYear = inst.currentYear; 10694 } else { 10695 date = new Date(); 10696 inst.selectedDay = date.getDate(); 10697 inst.drawMonth = inst.selectedMonth = date.getMonth(); 10698 inst.drawYear = inst.selectedYear = date.getFullYear(); 10699 } 10700 this._notifyChange( inst ); 10701 this._adjustDate( target ); 10702 }, 10703 10704 /* Action for selecting a new month/year. */ 10705 _selectMonthYear: function( id, select, period ) { 10706 var target = $( id ), 10707 inst = this._getInst( target[ 0 ] ); 10708 10709 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 10710 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 10711 parseInt( select.options[ select.selectedIndex ].value, 10 ); 10712 10713 this._notifyChange( inst ); 10714 this._adjustDate( target ); 10715 }, 10716 10717 /* Action for selecting a day. */ 10718 _selectDay: function( id, month, year, td ) { 10719 var inst, 10720 target = $( id ); 10721 10722 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 10723 return; 10724 } 10725 10726 inst = this._getInst( target[ 0 ] ); 10727 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 10728 inst.selectedMonth = inst.currentMonth = month; 10729 inst.selectedYear = inst.currentYear = year; 10730 this._selectDate( id, this._formatDate( inst, 10731 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 10732 }, 10733 10734 /* Erase the input field and hide the date picker. */ 10735 _clearDate: function( id ) { 10736 var target = $( id ); 10737 this._selectDate( target, "" ); 10738 }, 10739 10740 /* Update the input field with the selected date. */ 10741 _selectDate: function( id, dateStr ) { 10742 var onSelect, 10743 target = $( id ), 10744 inst = this._getInst( target[ 0 ] ); 10745 10746 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 10747 if ( inst.input ) { 10748 inst.input.val( dateStr ); 10749 } 10750 this._updateAlternate( inst ); 10751 10752 onSelect = this._get( inst, "onSelect" ); 10753 if ( onSelect ) { 10754 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 10755 } else if ( inst.input ) { 10756 inst.input.trigger( "change" ); // fire the change event 10757 } 10758 10759 if ( inst.inline ) { 10760 this._updateDatepicker( inst ); 10761 } else { 10762 this._hideDatepicker(); 10763 this._lastInput = inst.input[ 0 ]; 10764 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 10765 inst.input.trigger( "focus" ); // restore focus 10766 } 10767 this._lastInput = null; 10768 } 10769 }, 10770 10771 /* Update any alternate field to synchronise with the main field. */ 10772 _updateAlternate: function( inst ) { 10773 var altFormat, date, dateStr, 10774 altField = this._get( inst, "altField" ); 10775 10776 if ( altField ) { // update alternate field too 10777 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 10778 date = this._getDate( inst ); 10779 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 10780 $( document ).find( altField ).val( dateStr ); 10781 } 10782 }, 10783 10784 /* Set as beforeShowDay function to prevent selection of weekends. 10785 * @param date Date - the date to customise 10786 * @return [boolean, string] - is this date selectable?, what is its CSS class? 10787 */ 10788 noWeekends: function( date ) { 10789 var day = date.getDay(); 10790 return [ ( day > 0 && day < 6 ), "" ]; 10791 }, 10792 10793 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 10794 * @param date Date - the date to get the week for 10795 * @return number - the number of the week within the year that contains this date 10796 */ 10797 iso8601Week: function( date ) { 10798 var time, 10799 checkDate = new Date( date.getTime() ); 10800 10801 // Find Thursday of this week starting on Monday 10802 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 10803 10804 time = checkDate.getTime(); 10805 checkDate.setMonth( 0 ); // Compare with Jan 1 10806 checkDate.setDate( 1 ); 10807 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 10808 }, 10809 10810 /* Parse a string value into a date object. 10811 * See formatDate below for the possible formats. 10812 * 10813 * @param format string - the expected format of the date 10814 * @param value string - the date in the above format 10815 * @param settings Object - attributes include: 10816 * shortYearCutoff number - the cutoff year for determining the century (optional) 10817 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 10818 * dayNames string[7] - names of the days from Sunday (optional) 10819 * monthNamesShort string[12] - abbreviated names of the months (optional) 10820 * monthNames string[12] - names of the months (optional) 10821 * @return Date - the extracted date value or null if value is blank 10822 */ 10823 parseDate: function( format, value, settings ) { 10824 if ( format == null || value == null ) { 10825 throw "Invalid arguments"; 10826 } 10827 10828 value = ( typeof value === "object" ? value.toString() : value + "" ); 10829 if ( value === "" ) { 10830 return null; 10831 } 10832 10833 var iFormat, dim, extra, 10834 iValue = 0, 10835 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 10836 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,431 bytes, lines 10836-11026
10836: 10837 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 10838 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 10839 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 10840 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 10841 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 10842 year = -1, 10843 month = -1, 10844 day = -1, 10845 doy = -1, 10846 literal = false, 10847 date, 10848 10849 // Check whether a format character is doubled 10850 lookAhead = function( match ) { 10851 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 10852 if ( matches ) { 10853 iFormat++; 10854 } 10855 return matches; 10856 }, 10857 10858 // Extract a number from the string value 10859 getNumber = function( match ) { 10860 var isDoubled = lookAhead( match ), 10861 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 10862 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 10863 minSize = ( match === "y" ? size : 1 ), 10864 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 10865 num = value.substring( iValue ).match( digits ); 10866 if ( !num ) { 10867 throw "Missing number at position " + iValue; 10868 } 10869 iValue += num[ 0 ].length; 10870 return parseInt( num[ 0 ], 10 ); 10871 }, 10872 10873 // Extract a name from the string value and convert to an index 10874 getName = function( match, shortNames, longNames ) { 10875 var index = -1, 10876 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 10877 return [ [ k, v ] ]; 10878 } ).sort( function( a, b ) { 10879 return -( a[ 1 ].length - b[ 1 ].length ); 10880 } ); 10881 10882 $.each( names, function( i, pair ) { 10883 var name = pair[ 1 ]; 10884 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 10885 index = pair[ 0 ]; 10886 iValue += name.length; 10887 return false; 10888 } 10889 } ); 10890 if ( index !== -1 ) { 10891 return index + 1; 10892 } else { 10893 throw "Unknown name at position " + iValue; 10894 } 10895 }, 10896 10897 // Confirm that a literal character matches the string value 10898 checkLiteral = function() { 10899 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 10900 throw "Unexpected literal at position " + iValue; 10901 } 10902 iValue++; 10903 }; 10904 10905 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 10906 if ( literal ) { 10907 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 10908 literal = false; 10909 } else { 10910 checkLiteral(); 10911 } 10912 } else { 10913 switch ( format.charAt( iFormat ) ) { 10914 case "d": 10915 day = getNumber( "d" ); 10916 break; 10917 case "D": 10918 getName( "D", dayNamesShort, dayNames ); 10919 break; 10920 case "o": 10921 doy = getNumber( "o" ); 10922 break; 10923 case "m": 10924 month = getNumber( "m" ); 10925 break; 10926 case "M": 10927 month = getName( "M", monthNamesShort, monthNames ); 10928 break; 10929 case "y": 10930 year = getNumber( "y" ); 10931 break; 10932 case "@": 10933 date = new Date( getNumber( "@" ) ); 10934 year = date.getFullYear(); 10935 month = date.getMonth() + 1; 10936 day = date.getDate(); 10937 break; 10938 case "!": 10939 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 10940 year = date.getFullYear(); 10941 month = date.getMonth() + 1; 10942 day = date.getDate(); 10943 break; 10944 case "'": 10945 if ( lookAhead( "'" ) ) { 10946 checkLiteral(); 10947 } else { 10948 literal = true; 10949 } 10950 break; 10951 default: 10952 checkLiteral(); 10953 } 10954 } 10955 } 10956 10957 if ( iValue < value.length ) { 10958 extra = value.substr( iValue ); 10959 if ( !/^\s+/.test( extra ) ) { 10960 throw "Extra/unparsed characters found in date: " + extra; 10961 } 10962 } 10963 10964 if ( year === -1 ) { 10965 year = new Date().getFullYear(); 10966 } else if ( year < 100 ) { 10967 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 10968 ( year <= shortYearCutoff ? 0 : -100 ); 10969 } 10970 10971 if ( doy > -1 ) { 10972 month = 1; 10973 day = doy; 10974 do { 10975 dim = this._getDaysInMonth( year, month - 1 ); 10976 if ( day <= dim ) { 10977 break; 10978 } 10979 month++; 10980 day -= dim; 10981 } while ( true ); 10982 } 10983 10984 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 10985 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 10986 throw "Invalid date"; // E.g. 31/02/00 10987 } 10988 return date; 10989 }, 10990 10991 /* Standard date formats. */ 10992 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 10993 COOKIE: "D, dd M yy", 10994 ISO_8601: "yy-mm-dd", 10995 RFC_822: "D, d M y", 10996 RFC_850: "DD, dd-M-y", 10997 RFC_1036: "D, d M y", 10998 RFC_1123: "D, d M yy", 10999 RFC_2822: "D, d M yy", 11000 RSS: "D, d M y", // RFC 822 11001 TICKS: "!", 11002 TIMESTAMP: "@", 11003 W3C: "yy-mm-dd", // ISO 8601 11004 11005 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 11006 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 11007 11008 /* Format a date object into a string value. 11009 * The format can be combinations of the following: 11010 * d - day of month (no leading zero) 11011 * dd - day of month (two digit) 11012 * o - day of year (no leading zeros) 11013 * oo - day of year (three digit) 11014 * D - day name short 11015 * DD - day name long 11016 * m - month of year (no leading zero) 11017 * mm - month of year (two digit) 11018 * M - month name short 11019 * MM - month name long 11020 * y - year (two digit) 11021 * yy - year (four digit) 11022 * @ - Unix timestamp (ms since 01/01/1970) 11023 * ! - Windows ticks (100ns since 01/01/0001) 11024 * "..." - literal text 11025 * '' - single quote 11026 *
vendor: 6,198 bytes, lines 11027-11226
11027 * @param format string - the desired format of the date 11028 * @param date Date - the date value to format 11029 * @param settings Object - attributes include: 11030 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11031 * dayNames string[7] - names of the days from Sunday (optional) 11032 * monthNamesShort string[12] - abbreviated names of the months (optional) 11033 * monthNames string[12] - names of the months (optional) 11034 * @return string - the date in the above format 11035 */ 11036 formatDate: function( format, date, settings ) { 11037 if ( !date ) { 11038 return ""; 11039 } 11040 11041 var iFormat, 11042 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 11043 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 11044 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 11045 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 11046 11047 // Check whether a format character is doubled 11048 lookAhead = function( match ) { 11049 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 11050 if ( matches ) { 11051 iFormat++; 11052 } 11053 return matches; 11054 }, 11055 11056 // Format a number, with leading zero if necessary 11057 formatNumber = function( match, value, len ) { 11058 var num = "" + value; 11059 if ( lookAhead( match ) ) { 11060 while ( num.length < len ) { 11061 num = "0" + num; 11062 } 11063 } 11064 return num; 11065 }, 11066 11067 // Format a name, short or long as requested 11068 formatName = function( match, value, shortNames, longNames ) { 11069 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 11070 }, 11071 output = "", 11072 literal = false; 11073 11074 if ( date ) { 11075 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 11076 if ( literal ) { 11077 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 11078 literal = false; 11079 } else { 11080 output += format.charAt( iFormat ); 11081 } 11082 } else { 11083 switch ( format.charAt( iFormat ) ) { 11084 case "d": 11085 output += formatNumber( "d", date.getDate(), 2 ); 11086 break; 11087 case "D": 11088 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 11089 break; 11090 case "o": 11091 output += formatNumber( "o", 11092 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 11093 break; 11094 case "m": 11095 output += formatNumber( "m", date.getMonth() + 1, 2 ); 11096 break; 11097 case "M": 11098 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 11099 break; 11100 case "y": 11101 output += ( lookAhead( "y" ) ? date.getFullYear() : 11102 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 11103 break; 11104 case "@": 11105 output += date.getTime(); 11106 break; 11107 case "!": 11108 output += date.getTime() * 10000 + this._ticksTo1970; 11109 break; 11110 case "'": 11111 if ( lookAhead( "'" ) ) { 11112 output += "'"; 11113 } else { 11114 literal = true; 11115 } 11116 break; 11117 default: 11118 output += format.charAt( iFormat ); 11119 } 11120 } 11121 } 11122 } 11123 return output; 11124 }, 11125 11126 /* Extract all possible characters from the date format. */ 11127 _possibleChars: function( format ) { 11128 var iFormat, 11129 chars = "", 11130 literal = false, 11131 11132 // Check whether a format character is doubled 11133 lookAhead = function( match ) { 11134 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 11135 if ( matches ) { 11136 iFormat++; 11137 } 11138 return matches; 11139 }; 11140 11141 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 11142 if ( literal ) { 11143 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 11144 literal = false; 11145 } else { 11146 chars += format.charAt( iFormat ); 11147 } 11148 } else { 11149 switch ( format.charAt( iFormat ) ) { 11150 case "d": case "m": case "y": case "@": 11151 chars += "0123456789"; 11152 break; 11153 case "D": case "M": 11154 return null; // Accept anything 11155 case "'": 11156 if ( lookAhead( "'" ) ) { 11157 chars += "'"; 11158 } else { 11159 literal = true; 11160 } 11161 break; 11162 default: 11163 chars += format.charAt( iFormat ); 11164 } 11165 } 11166 } 11167 return chars; 11168 }, 11169 11170 /* Get a setting value, defaulting if necessary. */ 11171 _get: function( inst, name ) { 11172 return inst.settings[ name ] !== undefined ? 11173 inst.settings[ name ] : this._defaults[ name ]; 11174 }, 11175 11176 /* Parse existing date and initialise date picker. */ 11177 _setDateFromField: function( inst, noDefault ) { 11178 if ( inst.input.val() === inst.lastVal ) { 11179 return; 11180 } 11181 11182 var dateFormat = this._get( inst, "dateFormat" ), 11183 dates = inst.lastVal = inst.input ? inst.input.val() : null, 11184 defaultDate = this._getDefaultDate( inst ), 11185 date = defaultDate, 11186 settings = this._getFormatConfig( inst ); 11187 11188 try { 11189 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 11190 } catch ( event ) { 11191 dates = ( noDefault ? "" : dates ); 11192 } 11193 inst.selectedDay = date.getDate(); 11194 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11195 inst.drawYear = inst.selectedYear = date.getFullYear(); 11196 inst.currentDay = ( dates ? date.getDate() : 0 ); 11197 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 11198 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 11199 this._adjustInstDate( inst ); 11200 }, 11201 11202 /* Retrieve the default date shown on opening. */ 11203 _getDefaultDate: function( inst ) { 11204 return this._restrictMinMax( inst, 11205 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 11206 }, 11207 11208 /* A date may be specified as an exact value or a relative one. */ 11209 _determineDate: function( inst, date, defaultDate ) { 11210 var offsetNumeric = function( offset ) { 11211 var date = new Date(); 11212 date.setDate( date.getDate() + offset ); 11213 return date; 11214 }, 11215 offsetString = function( offset ) { 11216 try { 11217 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 11218 offset, $.datepicker._getFormatConfig( inst ) ); 11219 } catch ( e ) { 11220 11221 // Ignore 11222 } 11223 11224 var date = ( offset.toLowerCase().match( /^c/ ) ? 11225 $.datepicker._getDate( inst ) : null ) || new Date(), 11226 year = date.getFullYear(),
vendor: 5,359 bytes, lines 11227-11365
11227 month = date.getMonth(), 11228 day = date.getDate(), 11229 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 11230 matches = pattern.exec( offset ); 11231 11232 while ( matches ) { 11233 switch ( matches[ 2 ] || "d" ) { 11234 case "d" : case "D" : 11235 day += parseInt( matches[ 1 ], 10 ); break; 11236 case "w" : case "W" : 11237 day += parseInt( matches[ 1 ], 10 ) * 7; break; 11238 case "m" : case "M" : 11239 month += parseInt( matches[ 1 ], 10 ); 11240 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11241 break; 11242 case "y": case "Y" : 11243 year += parseInt( matches[ 1 ], 10 ); 11244 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11245 break; 11246 } 11247 matches = pattern.exec( offset ); 11248 } 11249 return new Date( year, month, day ); 11250 }, 11251 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 11252 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 11253 11254 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 11255 if ( newDate ) { 11256 newDate.setHours( 0 ); 11257 newDate.setMinutes( 0 ); 11258 newDate.setSeconds( 0 ); 11259 newDate.setMilliseconds( 0 ); 11260 } 11261 return this._daylightSavingAdjust( newDate ); 11262 }, 11263 11264 /* Handle switch to/from daylight saving. 11265 * Hours may be non-zero on daylight saving cut-over: 11266 * > 12 when midnight changeover, but then cannot generate 11267 * midnight datetime, so jump to 1AM, otherwise reset. 11268 * @param date (Date) the date to check 11269 * @return (Date) the corrected date 11270 */ 11271 _daylightSavingAdjust: function( date ) { 11272 if ( !date ) { 11273 return null; 11274 } 11275 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 11276 return date; 11277 }, 11278 11279 /* Set the date(s) directly. */ 11280 _setDate: function( inst, date, noChange ) { 11281 var clear = !date, 11282 origMonth = inst.selectedMonth, 11283 origYear = inst.selectedYear, 11284 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 11285 11286 inst.selectedDay = inst.currentDay = newDate.getDate(); 11287 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 11288 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 11289 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 11290 this._notifyChange( inst ); 11291 } 11292 this._adjustInstDate( inst ); 11293 if ( inst.input ) { 11294 inst.input.val( clear ? "" : this._formatDate( inst ) ); 11295 } 11296 }, 11297 11298 /* Retrieve the date(s) directly. */ 11299 _getDate: function( inst ) { 11300 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 11301 this._daylightSavingAdjust( new Date( 11302 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11303 return startDate; 11304 }, 11305 11306 /* Attach the onxxx handlers. These are declared statically so 11307 * they work with static code transformers like Caja. 11308 */ 11309 _attachHandlers: function( inst ) { 11310 var stepMonths = this._get( inst, "stepMonths" ), 11311 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 11312 inst.dpDiv.find( "[data-handler]" ).map( function() { 11313 var handler = { 11314 prev: function() { 11315 $.datepicker._adjustDate( id, -stepMonths, "M" ); 11316 }, 11317 next: function() { 11318 $.datepicker._adjustDate( id, +stepMonths, "M" ); 11319 }, 11320 hide: function() { 11321 $.datepicker._hideDatepicker(); 11322 }, 11323 today: function() { 11324 $.datepicker._gotoToday( id ); 11325 }, 11326 selectDay: function() { 11327 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 11328 return false; 11329 }, 11330 selectMonth: function() { 11331 $.datepicker._selectMonthYear( id, this, "M" ); 11332 return false; 11333 }, 11334 selectYear: function() { 11335 $.datepicker._selectMonthYear( id, this, "Y" ); 11336 return false; 11337 } 11338 }; 11339 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 11340 } ); 11341 }, 11342 11343 /* Generate the HTML for the current state of the date picker. */ 11344 _generateHTML: function( inst ) { 11345 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 11346 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 11347 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 11348 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 11349 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 11350 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 11351 tempDate = new Date(), 11352 today = this._daylightSavingAdjust( 11353 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 11354 isRTL = this._get( inst, "isRTL" ), 11355 showButtonPanel = this._get( inst, "showButtonPanel" ), 11356 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 11357 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 11358 numMonths = this._getNumberOfMonths( inst ), 11359 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 11360 stepMonths = this._get( inst, "stepMonths" ), 11361 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 11362 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 11363 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 11364 minDate = this._getMinMaxDate( inst, "min" ), 11365 maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,259 bytes, lines 11366-11880
11366 drawMonth = inst.drawMonth - showCurrentAtPos, 11367 drawYear = inst.drawYear; 11368 11369 if ( drawMonth < 0 ) { 11370 drawMonth += 12; 11371 drawYear--; 11372 } 11373 if ( maxDate ) { 11374 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 11375 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 11376 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 11377 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 11378 drawMonth--; 11379 if ( drawMonth < 0 ) { 11380 drawMonth = 11; 11381 drawYear--; 11382 } 11383 } 11384 } 11385 inst.drawMonth = drawMonth; 11386 inst.drawYear = drawYear; 11387 11388 prevText = this._get( inst, "prevText" ); 11389 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 11390 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 11391 this._getFormatConfig( inst ) ) ); 11392 11393 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 11394 prev = $( "<a>" ) 11395 .attr( { 11396 "class": "ui-datepicker-prev ui-corner-all", 11397 "data-handler": "prev", 11398 "data-event": "click", 11399 title: prevText 11400 } ) 11401 .append( 11402 $( "<span>" ) 11403 .addClass( "ui-icon ui-icon-circle-triangle-" + 11404 ( isRTL ? "e" : "w" ) ) 11405 .text( prevText ) 11406 )[ 0 ].outerHTML; 11407 } else if ( hideIfNoPrevNext ) { 11408 prev = ""; 11409 } else { 11410 prev = $( "<a>" ) 11411 .attr( { 11412 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 11413 title: prevText 11414 } ) 11415 .append( 11416 $( "<span>" ) 11417 .addClass( "ui-icon ui-icon-circle-triangle-" + 11418 ( isRTL ? "e" : "w" ) ) 11419 .text( prevText ) 11420 )[ 0 ].outerHTML; 11421 } 11422 11423 nextText = this._get( inst, "nextText" ); 11424 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 11425 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 11426 this._getFormatConfig( inst ) ) ); 11427 11428 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 11429 next = $( "<a>" ) 11430 .attr( { 11431 "class": "ui-datepicker-next ui-corner-all", 11432 "data-handler": "next", 11433 "data-event": "click", 11434 title: nextText 11435 } ) 11436 .append( 11437 $( "<span>" ) 11438 .addClass( "ui-icon ui-icon-circle-triangle-" + 11439 ( isRTL ? "w" : "e" ) ) 11440 .text( nextText ) 11441 )[ 0 ].outerHTML; 11442 } else if ( hideIfNoPrevNext ) { 11443 next = ""; 11444 } else { 11445 next = $( "<a>" ) 11446 .attr( { 11447 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 11448 title: nextText 11449 } ) 11450 .append( 11451 $( "<span>" ) 11452 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 11453 ( isRTL ? "w" : "e" ) ) 11454 .text( nextText ) 11455 )[ 0 ].outerHTML; 11456 } 11457 11458 currentText = this._get( inst, "currentText" ); 11459 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 11460 currentText = ( !navigationAsDateFormat ? currentText : 11461 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 11462 11463 controls = ""; 11464 if ( !inst.inline ) { 11465 controls = $( "<button>" ) 11466 .attr( { 11467 type: "button", 11468 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 11469 "data-handler": "hide", 11470 "data-event": "click" 11471 } ) 11472 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 11473 } 11474 11475 buttonPanel = ""; 11476 if ( showButtonPanel ) { 11477 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 11478 .append( isRTL ? controls : "" ) 11479 .append( this._isInRange( inst, gotoDate ) ? 11480 $( "<button>" ) 11481 .attr( { 11482 type: "button", 11483 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 11484 "data-handler": "today", 11485 "data-event": "click" 11486 } ) 11487 .text( currentText ) : 11488 "" ) 11489 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 11490 } 11491 11492 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 11493 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 11494 11495 showWeek = this._get( inst, "showWeek" ); 11496 dayNames = this._get( inst, "dayNames" ); 11497 dayNamesMin = this._get( inst, "dayNamesMin" ); 11498 monthNames = this._get( inst, "monthNames" ); 11499 monthNamesShort = this._get( inst, "monthNamesShort" ); 11500 beforeShowDay = this._get( inst, "beforeShowDay" ); 11501 showOtherMonths = this._get( inst, "showOtherMonths" ); 11502 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 11503 defaultDate = this._getDefaultDate( inst ); 11504 html = ""; 11505 11506 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 11507 group = ""; 11508 this.maxRows = 4; 11509 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 11510 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 11511 cornerClass = " ui-corner-all"; 11512 calender = ""; 11513 if ( isMultiMonth ) { 11514 calender += "<div class='ui-datepicker-group"; 11515 if ( numMonths[ 1 ] > 1 ) { 11516 switch ( col ) { 11517 case 0: calender += " ui-datepicker-group-first"; 11518 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 11519 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 11520 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 11521 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 11522 } 11523 } 11524 calender += "'>"; 11525 } 11526 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 11527 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 11528 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 11529 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 11530 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 11531 "</div><table class='ui-datepicker-calendar'><thead>" + 11532 "<tr>"; 11533 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 11534 for ( dow = 0; dow < 7; dow++ ) { // days of the week 11535 day = ( dow + firstDay ) % 7; 11536 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 11537 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 11538 } 11539 calender += thead + "</tr></thead><tbody>"; 11540 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 11541 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 11542 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 11543 } 11544 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 11545 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 11546 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 11547 this.maxRows = numRows; 11548 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 11549 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 11550 calender += "<tr>"; 11551 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 11552 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 11553 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 11554 daySettings = ( beforeShowDay ? 11555 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 11556 otherMonth = ( printDate.getMonth() !== drawMonth ); 11557 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 11558 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 11559 tbody += "<td class='" + 11560 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 11561 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 11562 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 11563 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 11564 11565 // or defaultDate is current printedDate and defaultDate is selectedDate 11566 " " + this._dayOverClass : "" ) + // highlight selected day 11567 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 11568 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 11569 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 11570 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 11571 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 11572 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 11573 ( otherMonth && !showOtherMonths ? " " : // display for other months 11574 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 11575 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 11576 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 11577 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 11578 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 11579 "' data-date='" + printDate.getDate() + // store date as data 11580 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 11581 printDate.setDate( printDate.getDate() + 1 ); 11582 printDate = this._daylightSavingAdjust( printDate ); 11583 } 11584 calender += tbody + "</tr>"; 11585 } 11586 drawMonth++; 11587 if ( drawMonth > 11 ) { 11588 drawMonth = 0; 11589 drawYear++; 11590 } 11591 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 11592 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 11593 group += calender; 11594 } 11595 html += group; 11596 } 11597 html += buttonPanel; 11598 inst._keyEvent = false; 11599 return html; 11600 }, 11601 11602 /* Generate the month and year header. */ 11603 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 11604 secondary, monthNames, monthNamesShort ) { 11605 11606 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 11607 changeMonth = this._get( inst, "changeMonth" ), 11608 changeYear = this._get( inst, "changeYear" ), 11609 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 11610 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 11611 selectYearLabel = this._get( inst, "selectYearLabel" ), 11612 html = "<div class='ui-datepicker-title'>", 11613 monthHtml = ""; 11614 11615 // Month selection 11616 if ( secondary || !changeMonth ) { 11617 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 11618 } else { 11619 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 11620 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 11621 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 11622 for ( month = 0; month < 12; month++ ) { 11623 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 11624 monthHtml += "<option value='" + month + "'" + 11625 ( month === drawMonth ? " selected='selected'" : "" ) + 11626 ">" + monthNamesShort[ month ] + "</option>"; 11627 } 11628 } 11629 monthHtml += "</select>"; 11630 } 11631 11632 if ( !showMonthAfterYear ) { 11633 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 11634 } 11635 11636 // Year selection 11637 if ( !inst.yearshtml ) { 11638 inst.yearshtml = ""; 11639 if ( secondary || !changeYear ) { 11640 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 11641 } else { 11642 11643 // determine range of years to display 11644 years = this._get( inst, "yearRange" ).split( ":" ); 11645 thisYear = new Date().getFullYear(); 11646 determineYear = function( value ) { 11647 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 11648 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 11649 parseInt( value, 10 ) ) ); 11650 return ( isNaN( year ) ? thisYear : year ); 11651 }; 11652 year = determineYear( years[ 0 ] ); 11653 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 11654 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 11655 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 11656 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 11657 for ( ; year <= endYear; year++ ) { 11658 inst.yearshtml += "<option value='" + year + "'" + 11659 ( year === drawYear ? " selected='selected'" : "" ) + 11660 ">" + year + "</option>"; 11661 } 11662 inst.yearshtml += "</select>"; 11663 11664 html += inst.yearshtml; 11665 inst.yearshtml = null; 11666 } 11667 } 11668 11669 html += this._get( inst, "yearSuffix" ); 11670 if ( showMonthAfterYear ) { 11671 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 11672 } 11673 html += "</div>"; // Close datepicker_header 11674 return html; 11675 }, 11676 11677 /* Adjust one of the date sub-fields. */ 11678 _adjustInstDate: function( inst, offset, period ) { 11679 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 11680 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 11681 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 11682 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 11683 11684 inst.selectedDay = date.getDate(); 11685 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11686 inst.drawYear = inst.selectedYear = date.getFullYear(); 11687 if ( period === "M" || period === "Y" ) { 11688 this._notifyChange( inst ); 11689 } 11690 }, 11691 11692 /* Ensure a date is within any min/max bounds. */ 11693 _restrictMinMax: function( inst, date ) { 11694 var minDate = this._getMinMaxDate( inst, "min" ), 11695 maxDate = this._getMinMaxDate( inst, "max" ), 11696 newDate = ( minDate && date < minDate ? minDate : date ); 11697 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 11698 }, 11699 11700 /* Notify change of month/year. */ 11701 _notifyChange: function( inst ) { 11702 var onChange = this._get( inst, "onChangeMonthYear" ); 11703 if ( onChange ) { 11704 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 11705 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 11706 } 11707 }, 11708 11709 /* Determine the number of months to show. */ 11710 _getNumberOfMonths: function( inst ) { 11711 var numMonths = this._get( inst, "numberOfMonths" ); 11712 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 11713 }, 11714 11715 /* Determine the current maximum date - ensure no time components are set. */ 11716 _getMinMaxDate: function( inst, minMax ) { 11717 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 11718 }, 11719 11720 /* Find the number of days in a given month. */ 11721 _getDaysInMonth: function( year, month ) { 11722 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 11723 }, 11724 11725 /* Find the day of the week of the first of a month. */ 11726 _getFirstDayOfMonth: function( year, month ) { 11727 return new Date( year, month, 1 ).getDay(); 11728 }, 11729 11730 /* Determines if we should allow a "next/prev" month display change. */ 11731 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 11732 var numMonths = this._getNumberOfMonths( inst ), 11733 date = this._daylightSavingAdjust( new Date( curYear, 11734 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 11735 11736 if ( offset < 0 ) { 11737 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 11738 } 11739 return this._isInRange( inst, date ); 11740 }, 11741 11742 /* Is the given date in the accepted range? */ 11743 _isInRange: function( inst, date ) { 11744 var yearSplit, currentYear, 11745 minDate = this._getMinMaxDate( inst, "min" ), 11746 maxDate = this._getMinMaxDate( inst, "max" ), 11747 minYear = null, 11748 maxYear = null, 11749 years = this._get( inst, "yearRange" ); 11750 if ( years ) { 11751 yearSplit = years.split( ":" ); 11752 currentYear = new Date().getFullYear(); 11753 minYear = parseInt( yearSplit[ 0 ], 10 ); 11754 maxYear = parseInt( yearSplit[ 1 ], 10 ); 11755 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 11756 minYear += currentYear; 11757 } 11758 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 11759 maxYear += currentYear; 11760 } 11761 } 11762 11763 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 11764 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 11765 ( !minYear || date.getFullYear() >= minYear ) && 11766 ( !maxYear || date.getFullYear() <= maxYear ) ); 11767 }, 11768 11769 /* Provide the configuration settings for formatting/parsing. */ 11770 _getFormatConfig: function( inst ) { 11771 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 11772 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 11773 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 11774 return { shortYearCutoff: shortYearCutoff, 11775 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 11776 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 11777 }, 11778 11779 /* Format the given date for display. */ 11780 _formatDate: function( inst, day, month, year ) { 11781 if ( !day ) { 11782 inst.currentDay = inst.selectedDay; 11783 inst.currentMonth = inst.selectedMonth; 11784 inst.currentYear = inst.selectedYear; 11785 } 11786 var date = ( day ? ( typeof day === "object" ? day : 11787 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 11788 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11789 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 11790 } 11791} ); 11792 11793/* 11794 * Bind hover events for datepicker elements. 11795 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 11796 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 11797 */ 11798function datepicker_bindHover( dpDiv ) { 11799 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 11800 return dpDiv.on( "mouseout", selector, function() { 11801 $( this ).removeClass( "ui-state-hover" ); 11802 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11803 $( this ).removeClass( "ui-datepicker-prev-hover" ); 11804 } 11805 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11806 $( this ).removeClass( "ui-datepicker-next-hover" ); 11807 } 11808 } ) 11809 .on( "mouseover", selector, datepicker_handleMouseover ); 11810} 11811 11812function datepicker_handleMouseover() { 11813 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 11814 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 11815 $( this ).addClass( "ui-state-hover" ); 11816 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11817 $( this ).addClass( "ui-datepicker-prev-hover" ); 11818 } 11819 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11820 $( this ).addClass( "ui-datepicker-next-hover" ); 11821 } 11822 } 11823} 11824 11825/* jQuery extend now ignores nulls! */ 11826function datepicker_extendRemove( target, props ) { 11827 $.extend( target, props ); 11828 for ( var name in props ) { 11829 if ( props[ name ] == null ) { 11830 target[ name ] = props[ name ]; 11831 } 11832 } 11833 return target; 11834} 11835 11836/* Invoke the datepicker functionality. 11837 @param options string - a command, optionally followed by additional parameters or 11838 Object - settings for attaching new datepicker functionality 11839 @return jQuery object */ 11840$.fn.datepicker = function( options ) { 11841 11842 /* Verify an empty collection wasn't passed - Fixes #6976 */ 11843 if ( !this.length ) { 11844 return this; 11845 } 11846 11847 /* Initialise the date picker. */ 11848 if ( !$.datepicker.initialized ) { 11849 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 11850 $.datepicker.initialized = true; 11851 } 11852 11853 /* Append datepicker main container to body if not exist. */ 11854 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 11855 $( "body" ).append( $.datepicker.dpDiv ); 11856 } 11857 11858 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 11859 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 11860 return $.datepicker[ "_" + options + "Datepicker" ]. 11861 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11862 } 11863 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 11864 return $.datepicker[ "_" + options + "Datepicker" ]. 11865 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11866 } 11867 return this.each( function() { 11868 if ( typeof options === "string" ) { 11869 $.datepicker[ "_" + options + "Datepicker" ] 11870 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 11871 } else { 11872 $.datepicker._attachDatepicker( this, options ); 11873 } 11874 } ); 11875}; 11876 11877$.datepicker = new Datepicker(); // singleton instance 11878$.datepicker.initialized = false; 11879$.datepicker.uuid = new Date().getTime(); 11880$.datepicker.version = "1.14.
118801"; 11881 11882var widgetsDatepicker = $.datepicker; 11883 11884 11885/*! 11886 * jQuery UI Dialog 1.14.1 11887 * https://jqueryui.com 11888 * 11889 * Copyright OpenJS Foundation and other contributors 11890 * Released under the MIT license. 11891 * https://jquery.org/license 11892 */ 11893 11894//>>label: Dialog 11895//>>group: Widgets 11896//>>description: Displays customizable dialog windows. 11897//>>docs: https://api.jqueryui.com/dialog/ 11898//>>demos: https://jqueryui.com/dialog/ 11899//>>css.structure: ../../themes/base/core.css 11900//>>css.structure: ../../themes/base/dialog.css 11901//>>css.theme: ../../themes/base/theme.css 11902 11903 11904$.widget( "ui.dialog", { 11905 version: "1.14.1
vendor: 22,369 bytes, lines 11905-12804
11905", 11906 options: { 11907 appendTo: "body", 11908 autoOpen: true, 11909 buttons: [], 11910 classes: { 11911 "ui-dialog": "ui-corner-all", 11912 "ui-dialog-titlebar": "ui-corner-all" 11913 }, 11914 closeOnEscape: true, 11915 closeText: "Close", 11916 draggable: true, 11917 hide: null, 11918 height: "auto", 11919 maxHeight: null, 11920 maxWidth: null, 11921 minHeight: 150, 11922 minWidth: 150, 11923 modal: false, 11924 position: { 11925 my: "center", 11926 at: "center", 11927 of: window, 11928 collision: "fit", 11929 11930 // Ensure the titlebar is always visible 11931 using: function( pos ) { 11932 var topOffset = $( this ).css( pos ).offset().top; 11933 if ( topOffset < 0 ) { 11934 $( this ).css( "top", pos.top - topOffset ); 11935 } 11936 } 11937 }, 11938 resizable: true, 11939 show: null, 11940 title: null, 11941 uiDialogTitleHeadingLevel: 0, 11942 width: 300, 11943 11944 // Callbacks 11945 beforeClose: null, 11946 close: null, 11947 drag: null, 11948 dragStart: null, 11949 dragStop: null, 11950 focus: null, 11951 open: null, 11952 resize: null, 11953 resizeStart: null, 11954 resizeStop: null 11955 }, 11956 11957 sizeRelatedOptions: { 11958 buttons: true, 11959 height: true, 11960 maxHeight: true, 11961 maxWidth: true, 11962 minHeight: true, 11963 minWidth: true, 11964 width: true 11965 }, 11966 11967 resizableRelatedOptions: { 11968 maxHeight: true, 11969 maxWidth: true, 11970 minHeight: true, 11971 minWidth: true 11972 }, 11973 11974 _create: function() { 11975 this.originalCss = { 11976 display: this.element[ 0 ].style.display, 11977 width: this.element[ 0 ].style.width, 11978 minHeight: this.element[ 0 ].style.minHeight, 11979 maxHeight: this.element[ 0 ].style.maxHeight, 11980 height: this.element[ 0 ].style.height 11981 }; 11982 this.originalPosition = { 11983 parent: this.element.parent(), 11984 index: this.element.parent().children().index( this.element ) 11985 }; 11986 this.originalTitle = this.element.attr( "title" ); 11987 if ( this.options.title == null && this.originalTitle != null ) { 11988 this.options.title = this.originalTitle; 11989 } 11990 11991 // Dialogs can't be disabled 11992 if ( this.options.disabled ) { 11993 this.options.disabled = false; 11994 } 11995 11996 this._createWrapper(); 11997 11998 this.element 11999 .show() 12000 .removeAttr( "title" ) 12001 .appendTo( this.uiDialog ); 12002 12003 this._addClass( "ui-dialog-content", "ui-widget-content" ); 12004 12005 this._createTitlebar(); 12006 this._createButtonPane(); 12007 12008 if ( this.options.draggable && $.fn.draggable ) { 12009 this._makeDraggable(); 12010 } 12011 if ( this.options.resizable && $.fn.resizable ) { 12012 this._makeResizable(); 12013 } 12014 12015 this._isOpen = false; 12016 12017 this._trackFocus(); 12018 }, 12019 12020 _init: function() { 12021 if ( this.options.autoOpen ) { 12022 this.open(); 12023 } 12024 }, 12025 12026 _appendTo: function() { 12027 var element = this.options.appendTo; 12028 if ( element && ( element.jquery || element.nodeType ) ) { 12029 return $( element ); 12030 } 12031 return this.document.find( element || "body" ).eq( 0 ); 12032 }, 12033 12034 _destroy: function() { 12035 var next, 12036 originalPosition = this.originalPosition; 12037 12038 this._untrackInstance(); 12039 this._destroyOverlay(); 12040 12041 this.element 12042 .removeUniqueId() 12043 .css( this.originalCss ) 12044 12045 // Without detaching first, the following becomes really slow 12046 .detach(); 12047 12048 this.uiDialog.remove(); 12049 12050 if ( this.originalTitle ) { 12051 this.element.attr( "title", this.originalTitle ); 12052 } 12053 12054 next = originalPosition.parent.children().eq( originalPosition.index ); 12055 12056 // Don't try to place the dialog next to itself (#8613) 12057 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 12058 next.before( this.element ); 12059 } else { 12060 originalPosition.parent.append( this.element ); 12061 } 12062 }, 12063 12064 widget: function() { 12065 return this.uiDialog; 12066 }, 12067 12068 disable: $.noop, 12069 enable: $.noop, 12070 12071 close: function( event ) { 12072 var that = this; 12073 12074 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 12075 return; 12076 } 12077 12078 this._isOpen = false; 12079 this._focusedElement = null; 12080 this._destroyOverlay(); 12081 this._untrackInstance(); 12082 12083 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 12084 12085 // Hiding a focused element doesn't trigger blur in WebKit 12086 // so in case we have nothing to focus on, explicitly blur the active element 12087 // https://bugs.webkit.org/show_bug.cgi?id=47182 12088 $( this.document[ 0 ].activeElement ).trigger( "blur" ); 12089 } 12090 12091 this._hide( this.uiDialog, this.options.hide, function() { 12092 that._trigger( "close", event ); 12093 } ); 12094 }, 12095 12096 isOpen: function() { 12097 return this._isOpen; 12098 }, 12099 12100 moveToTop: function() { 12101 this._moveToTop(); 12102 }, 12103 12104 _moveToTop: function( event, silent ) { 12105 var moved = false, 12106 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 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: 4,772 bytes, lines 12804-12988
12804Progressbar 1.14.1 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/* eslint-disable max-len */ 12815//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 12816/* eslint-enable max-len */ 12817//>>docs: https://api.jqueryui.com/progressbar/ 12818//>>demos: https://jqueryui.com/progressbar/ 12819//>>css.structure: ../../themes/base/core.css 12820//>>css.structure: ../../themes/base/progressbar.css 12821//>>css.theme: ../../themes/base/theme.css 12822 12823 12824var widgetsProgressbar = $.widget( "ui.progressbar", { 12825 version: "1.14.1", 12826 options: { 12827 classes: { 12828 "ui-progressbar": "ui-corner-all", 12829 "ui-progressbar-value": "ui-corner-left", 12830 "ui-progressbar-complete": "ui-corner-right" 12831 }, 12832 max: 100, 12833 value: 0, 12834 12835 change: null, 12836 complete: null 12837 }, 12838 12839 min: 0, 12840 12841 _create: function() { 12842 12843 // Constrain initial value 12844 this.oldValue = this.options.value = this._constrainedValue(); 12845 12846 this.element.attr( { 12847 12848 // Only set static values; aria-valuenow and aria-valuemax are 12849 // set inside _refreshValue() 12850 role: "progressbar", 12851 "aria-valuemin": this.min 12852 } ); 12853 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 12854 12855 this.valueDiv = $( "<div>" ).appendTo( this.element ); 12856 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 12857 this._refreshValue(); 12858 }, 12859 12860 _destroy: function() { 12861 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 12862 12863 this.valueDiv.remove(); 12864 }, 12865 12866 value: function( newValue ) { 12867 if ( newValue === undefined ) { 12868 return this.options.value; 12869 } 12870 12871 this.options.value = this._constrainedValue( newValue ); 12872 this._refreshValue(); 12873 }, 12874 12875 _constrainedValue: function( newValue ) { 12876 if ( newValue === undefined ) { 12877 newValue = this.options.value; 12878 } 12879 12880 this.indeterminate = newValue === false; 12881 12882 // Sanitize value 12883 if ( typeof newValue !== "number" ) { 12884 newValue = 0; 12885 } 12886 12887 return this.indeterminate ? false : 12888 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12889 }, 12890 12891 _setOptions: function( options ) { 12892 12893 // Ensure "value" option is set after other values (like max) 12894 var value = options.value; 12895 delete options.value; 12896 12897 this._super( options ); 12898 12899 this.options.value = this._constrainedValue( value ); 12900 this._refreshValue(); 12901 }, 12902 12903 _setOption: function( key, value ) { 12904 if ( key === "max" ) { 12905 12906 // Don't allow a max less than min 12907 value = Math.max( this.min, value ); 12908 } 12909 this._super( key, value ); 12910 }, 12911 12912 _setOptionDisabled: function( value ) { 12913 this._super( value ); 12914 12915 this.element.attr( "aria-disabled", value ); 12916 this._toggleClass( null, "ui-state-disabled", !!value ); 12917 }, 12918 12919 _percentage: function() { 12920 return this.indeterminate ? 12921 100 : 12922 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12923 }, 12924 12925 _refreshValue: function() { 12926 var value = this.options.value, 12927 percentage = this._percentage(); 12928 12929 this.valueDiv 12930 .toggle( this.indeterminate || value > this.min ) 12931 .width( percentage.toFixed( 0 ) + "%" ); 12932 12933 this 12934 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 12935 value === this.options.max ) 12936 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 12937 12938 if ( this.indeterminate ) { 12939 this.element.removeAttr( "aria-valuenow" ); 12940 if ( !this.overlayDiv ) { 12941 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 12942 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 12943 } 12944 } else { 12945 this.element.attr( { 12946 "aria-valuemax": this.options.max, 12947 "aria-valuenow": value 12948 } ); 12949 if ( this.overlayDiv ) { 12950 this.overlayDiv.remove(); 12951 this.overlayDiv = null; 12952 } 12953 } 12954 12955 if ( this.oldValue !== value ) { 12956 this.oldValue = value; 12957 this._trigger( "change" ); 12958 } 12959 if ( value === this.options.max ) { 12960 this._trigger( "complete" ); 12961 } 12962 } 12963} ); 12964 12965 12966/*! 12967 * jQuery UI Selectmenu 1.14.1 12968 * https://jqueryui.com 12969 * 12970 * Copyright OpenJS Foundation and other contributors 12971 * Released under the MIT license. 12972 * https://jquery.org/license 12973 */ 12974 12975//>>label: Selectmenu 12976//>>group: Widgets 12977/* eslint-disable max-len */ 12978//>>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. 12979/* eslint-enable max-len */ 12980//>>docs: https://api.jqueryui.com/selectmenu/ 12981//>>demos: https://jqueryui.com/selectmenu/ 12982//>>css.structure: ../../themes/base/core.css 12983//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 12984//>>css.theme: ../../themes/base/theme.css 12985 12986 12987var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 12988 version: "1.14.1
vendor: 14,466 bytes, lines 12988-13609
12988", 12989 defaultElement: "<select>", 12990 options: { 12991 appendTo: null, 12992 classes: { 12993 "ui-selectmenu-button-open": "ui-corner-top", 12994 "ui-selectmenu-button-closed": "ui-corner-all" 12995 }, 12996 disabled: null, 12997 icons: { 12998 button: "ui-icon-triangle-1-s" 12999 }, 13000 position: { 13001 my: "left top", 13002 at: "left bottom", 13003 collision: "none" 13004 }, 13005 width: false, 13006 13007 // Callbacks 13008 change: null, 13009 close: null, 13010 focus: null, 13011 open: null, 13012 select: null 13013 }, 13014 13015 _create: function() { 13016 var selectmenuId = this.element.uniqueId().attr( "id" ); 13017 this.ids = { 13018 element: selectmenuId, 13019 button: selectmenuId + "-button", 13020 menu: selectmenuId + "-menu" 13021 }; 13022 13023 this._drawButton(); 13024 this._drawMenu(); 13025 this._bindFormResetHandler(); 13026 13027 this._rendered = false; 13028 this.menuItems = $(); 13029 }, 13030 13031 _drawButton: function() { 13032 var icon, 13033 that = this, 13034 item = this._parseOption( 13035 this.element.find( "option:selected" ), 13036 this.element[ 0 ].selectedIndex 13037 ); 13038 13039 // Associate existing label with the new button 13040 this.labels = this.element.labels().attr( "for", this.ids.button ); 13041 this._on( this.labels, { 13042 click: function( event ) { 13043 this.button.trigger( "focus" ); 13044 event.preventDefault(); 13045 } 13046 } ); 13047 13048 // Hide original select element 13049 this.element.hide(); 13050 13051 // Create button 13052 this.button = $( "<span>", { 13053 tabindex: this.options.disabled ? -1 : 0, 13054 id: this.ids.button, 13055 role: "combobox", 13056 "aria-expanded": "false", 13057 "aria-autocomplete": "list", 13058 "aria-owns": this.ids.menu, 13059 "aria-haspopup": "true", 13060 title: this.element.attr( "title" ) 13061 } ) 13062 .insertAfter( this.element ); 13063 13064 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 13065 "ui-button ui-widget" ); 13066 13067 icon = $( "<span>" ).appendTo( this.button ); 13068 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 13069 this.buttonItem = this._renderButtonItem( item ) 13070 .appendTo( this.button ); 13071 13072 if ( this.options.width !== false ) { 13073 this._resizeButton(); 13074 } 13075 13076 this._on( this.button, this._buttonEvents ); 13077 this.button.one( "focusin", function() { 13078 13079 // Delay rendering the menu items until the button receives focus. 13080 // The menu may have already been rendered via a programmatic open. 13081 if ( !that._rendered ) { 13082 that._refreshMenu(); 13083 } 13084 } ); 13085 }, 13086 13087 _drawMenu: function() { 13088 var that = this; 13089 13090 // Create menu 13091 this.menu = $( "<ul>", { 13092 "aria-hidden": "true", 13093 "aria-labelledby": this.ids.button, 13094 id: this.ids.menu 13095 } ); 13096 13097 // Wrap menu 13098 this.menuWrap = $( "<div>" ).append( this.menu ); 13099 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 13100 this.menuWrap.appendTo( this._appendTo() ); 13101 13102 // Initialize menu widget 13103 this.menuInstance = this.menu 13104 .menu( { 13105 classes: { 13106 "ui-menu": "ui-corner-bottom" 13107 }, 13108 role: "listbox", 13109 select: function( event, ui ) { 13110 event.preventDefault(); 13111 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 13112 }, 13113 focus: function( event, ui ) { 13114 var item = ui.item.data( "ui-selectmenu-item" ); 13115 13116 // Prevent inital focus from firing and check if its a newly focused item 13117 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 13118 that._trigger( "focus", event, { item: item } ); 13119 if ( !that.isOpen ) { 13120 that._select( item, event ); 13121 } 13122 } 13123 that.focusIndex = item.index; 13124 13125 that.button.attr( "aria-activedescendant", 13126 that.menuItems.eq( item.index ).attr( "id" ) ); 13127 } 13128 } ) 13129 .menu( "instance" ); 13130 13131 // Don't close the menu on mouseleave 13132 this.menuInstance._off( this.menu, "mouseleave" ); 13133 13134 // Cancel the menu's collapseAll on document click 13135 this.menuInstance._closeOnDocumentClick = function() { 13136 return false; 13137 }; 13138 13139 // Selects often contain empty items, but never contain dividers 13140 this.menuInstance._isDivider = function() { 13141 return false; 13142 }; 13143 }, 13144 13145 refresh: function() { 13146 this._refreshMenu(); 13147 this.buttonItem.replaceWith( 13148 this.buttonItem = this._renderButtonItem( 13149 13150 // Fall back to an empty object in case there are no options 13151 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 13152 ) 13153 ); 13154 if ( this.options.width === null ) { 13155 this._resizeButton(); 13156 } 13157 }, 13158 13159 _refreshMenu: function() { 13160 var item, 13161 options = this.element.find( "option" ); 13162 13163 this.menu.empty(); 13164 13165 this._parseOptions( options ); 13166 this._renderMenu( this.menu, this.items ); 13167 13168 this.menuInstance.refresh(); 13169 this.menuItems = this.menu.find( "li" ) 13170 .not( ".ui-selectmenu-optgroup" ) 13171 .find( ".ui-menu-item-wrapper" ); 13172 13173 this._rendered = true; 13174 13175 if ( !options.length ) { 13176 return; 13177 } 13178 13179 item = this._getSelectedItem(); 13180 13181 // Update the menu to have the correct item focused 13182 this.menuInstance.focus( null, item ); 13183 this._setAria( item.data( "ui-selectmenu-item" ) ); 13184 13185 // Set disabled state 13186 this._setOption( "disabled", this.element.prop( "disabled" ) ); 13187 }, 13188 13189 open: function( event ) { 13190 if ( this.options.disabled ) { 13191 return; 13192 } 13193 13194 // If this is the first time the menu is being opened, render the items 13195 if ( !this._rendered ) { 13196 this._refreshMenu(); 13197 } else { 13198 13199 // Menu clears focus on close, reset focus to selected item 13200 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 13201 this.menuInstance.focus( null, this._getSelectedItem() ); 13202 } 13203 13204 // If there are no options, don't open the menu 13205 if ( !this.menuItems.length ) { 13206 return; 13207 } 13208 13209 this.isOpen = true; 13210 this._toggleAttr(); 13211 this._resizeMenu(); 13212 this._position(); 13213 13214 this._on( this.document, this._documentClick ); 13215 13216 this._trigger( "open", event ); 13217 }, 13218 13219 _position: function() { 13220 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 13221 }, 13222 13223 close: function( event ) { 13224 if ( !this.isOpen ) { 13225 return; 13226 } 13227 13228 this.isOpen = false; 13229 this._toggleAttr(); 13230 13231 this.range = null; 13232 this._off( this.document ); 13233 13234 this._trigger( "close", event ); 13235 }, 13236 13237 widget: function() { 13238 return this.button; 13239 }, 13240 13241 menuWidget: function() { 13242 return this.menu; 13243 }, 13244 13245 _renderButtonItem: function( item ) { 13246 var buttonItem = $( "<span>" ); 13247 13248 this._setText( buttonItem, item.label ); 13249 this._addClass( buttonItem, "ui-selectmenu-text" ); 13250 13251 return buttonItem; 13252 }, 13253 13254 _renderMenu: function( ul, items ) { 13255 var that = this, 13256 currentOptgroup = ""; 13257 13258 $.each( items, function( index, item ) { 13259 var li; 13260 13261 if ( item.optgroup !== currentOptgroup ) { 13262 li = $( "<li>", { 13263 text: item.optgroup 13264 } ); 13265 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 13266 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 13267 " ui-state-disabled" : 13268 "" ) ); 13269 13270 li.appendTo( ul ); 13271 13272 currentOptgroup = item.optgroup; 13273 } 13274 13275 that._renderItemData( ul, item ); 13276 } ); 13277 }, 13278 13279 _renderItemData: function( ul, item ) { 13280 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 13281 }, 13282 13283 _renderItem: function( ul, item ) { 13284 var li = $( "<li>" ), 13285 wrapper = $( "<div>", { 13286 title: item.element.attr( "title" ) 13287 } ); 13288 13289 if ( item.disabled ) { 13290 this._addClass( li, null, "ui-state-disabled" ); 13291 } 13292 13293 if ( item.hidden ) { 13294 li.prop( "hidden", true ); 13295 } else { 13296 this._setText( wrapper, item.label ); 13297 } 13298 13299 return li.append( wrapper ).appendTo( ul ); 13300 }, 13301 13302 _setText: function( element, value ) { 13303 if ( value ) { 13304 element.text( value ); 13305 } else { 13306 element.html( " " ); 13307 } 13308 }, 13309 13310 _move: function( direction, event ) { 13311 var item, next, 13312 filter = ".ui-menu-item"; 13313 13314 if ( this.isOpen ) { 13315 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13316 } else { 13317 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13318 filter += ":not(.ui-state-disabled)"; 13319 } 13320 13321 if ( direction === "first" || direction === "last" ) { 13322 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 13323 } else { 13324 next = item[ direction + "All" ]( filter ).eq( 0 ); 13325 } 13326 13327 if ( next.length ) { 13328 this.menuInstance.focus( event, next ); 13329 } 13330 }, 13331 13332 _getSelectedItem: function() { 13333 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13334 }, 13335 13336 _toggle: function( event ) { 13337 this[ this.isOpen ? "close" : "open" ]( event ); 13338 }, 13339 13340 _setSelection: function() { 13341 var selection; 13342 13343 if ( !this.range ) { 13344 return; 13345 } 13346 13347 selection = window.getSelection(); 13348 selection.removeAllRanges(); 13349 selection.addRange( this.range ); 13350 }, 13351 13352 _documentClick: { 13353 mousedown: function( event ) { 13354 if ( !this.isOpen ) { 13355 return; 13356 } 13357 13358 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 13359 CSS.escape( this.ids.button ) ).length ) { 13360 this.close( event ); 13361 } 13362 } 13363 }, 13364 13365 _buttonEvents: { 13366 13367 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 13368 mousedown: function() { 13369 var selection = window.getSelection(); 13370 if ( selection.rangeCount ) { 13371 this.range = selection.getRangeAt( 0 ); 13372 } 13373 }, 13374 13375 click: function( event ) { 13376 this._setSelection(); 13377 this._toggle( event ); 13378 }, 13379 13380 keydown: function( event ) { 13381 var preventDefault = true; 13382 switch ( event.keyCode ) { 13383 case $.ui.keyCode.TAB: 13384 case $.ui.keyCode.ESCAPE: 13385 this.close( event ); 13386 preventDefault = false; 13387 break; 13388 case $.ui.keyCode.ENTER: 13389 if ( this.isOpen ) { 13390 this._selectFocusedItem( event ); 13391 } 13392 break; 13393 case $.ui.keyCode.UP: 13394 if ( event.altKey ) { 13395 this._toggle( event ); 13396 } else { 13397 this._move( "prev", event ); 13398 } 13399 break; 13400 case $.ui.keyCode.DOWN: 13401 if ( event.altKey ) { 13402 this._toggle( event ); 13403 } else { 13404 this._move( "next", event ); 13405 } 13406 break; 13407 case $.ui.keyCode.SPACE: 13408 if ( this.isOpen ) { 13409 this._selectFocusedItem( event ); 13410 } else { 13411 this._toggle( event ); 13412 } 13413 break; 13414 case $.ui.keyCode.LEFT: 13415 this._move( "prev", event ); 13416 break; 13417 case $.ui.keyCode.RIGHT: 13418 this._move( "next", event ); 13419 break; 13420 case $.ui.keyCode.HOME: 13421 case $.ui.keyCode.PAGE_UP: 13422 this._move( "first", event ); 13423 break; 13424 case $.ui.keyCode.END: 13425 case $.ui.keyCode.PAGE_DOWN: 13426 this._move( "last", event ); 13427 break; 13428 default: 13429 this.menu.trigger( event ); 13430 preventDefault = false; 13431 } 13432 13433 if ( preventDefault ) { 13434 event.preventDefault(); 13435 } 13436 } 13437 }, 13438 13439 _selectFocusedItem: function( event ) { 13440 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13441 if ( !item.hasClass( "ui-state-disabled" ) ) { 13442 this._select( item.data( "ui-selectmenu-item" ), event ); 13443 } 13444 }, 13445 13446 _select: function( item, event ) { 13447 var oldIndex = this.element[ 0 ].selectedIndex; 13448 13449 // Change native select element 13450 this.element[ 0 ].selectedIndex = item.index; 13451 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 13452 this._setAria( item ); 13453 this._trigger( "select", event, { item: item } ); 13454 13455 if ( item.index !== oldIndex ) { 13456 this._trigger( "change", event, { item: item } ); 13457 } 13458 13459 this.close( event ); 13460 }, 13461 13462 _setAria: function( item ) { 13463 var id = this.menuItems.eq( item.index ).attr( "id" ); 13464 13465 this.button.attr( { 13466 "aria-labelledby": id, 13467 "aria-activedescendant": id 13468 } ); 13469 this.menu.attr( "aria-activedescendant", id ); 13470 }, 13471 13472 _setOption: function( key, value ) { 13473 if ( key === "icons" ) { 13474 var icon = this.button.find( "span.ui-icon" ); 13475 this._removeClass( icon, null, this.options.icons.button ) 13476 ._addClass( icon, null, value.button ); 13477 } 13478 13479 this._super( key, value ); 13480 13481 if ( key === "appendTo" ) { 13482 this.menuWrap.appendTo( this._appendTo() ); 13483 } 13484 13485 if ( key === "width" ) { 13486 this._resizeButton(); 13487 } 13488 }, 13489 13490 _setOptionDisabled: function( value ) { 13491 this._super( value ); 13492 13493 this.menuInstance.option( "disabled", value ); 13494 this.button.attr( "aria-disabled", value ); 13495 this._toggleClass( this.button, null, "ui-state-disabled", value ); 13496 13497 this.element.prop( "disabled", value ); 13498 if ( value ) { 13499 this.button.attr( "tabindex", -1 ); 13500 this.close(); 13501 } else { 13502 this.button.attr( "tabindex", 0 ); 13503 } 13504 }, 13505 13506 _appendTo: function() { 13507 var element = this.options.appendTo; 13508 13509 if ( element ) { 13510 element = element.jquery || element.nodeType ? 13511 $( element ) : 13512 this.document.find( element ).eq( 0 ); 13513 } 13514 13515 if ( !element || !element[ 0 ] ) { 13516 element = this.element.closest( ".ui-front, dialog" ); 13517 } 13518 13519 if ( !element.length ) { 13520 element = this.document[ 0 ].body; 13521 } 13522 13523 return element; 13524 }, 13525 13526 _toggleAttr: function() { 13527 this.button.attr( "aria-expanded", this.isOpen ); 13528 13529 // We can't use two _toggleClass() calls here, because we need to make sure 13530 // we always remove classes first and add them second, otherwise if both classes have the 13531 // same theme class, it will be removed after we add it. 13532 this._removeClass( this.button, "ui-selectmenu-button-" + 13533 ( this.isOpen ? "closed" : "open" ) ) 13534 ._addClass( this.button, "ui-selectmenu-button-" + 13535 ( this.isOpen ? "open" : "closed" ) ) 13536 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 13537 13538 this.menu.attr( "aria-hidden", !this.isOpen ); 13539 }, 13540 13541 _resizeButton: function() { 13542 var width = this.options.width; 13543 13544 // For `width: false`, just remove inline style and stop 13545 if ( width === false ) { 13546 this.button.css( "width", "" ); 13547 return; 13548 } 13549 13550 // For `width: null`, match the width of the original element 13551 if ( width === null ) { 13552 width = this.element.show().outerWidth(); 13553 this.element.hide(); 13554 } 13555 13556 this.button.outerWidth( width ); 13557 }, 13558 13559 _resizeMenu: function() { 13560 this.menu.outerWidth( Math.max( 13561 this.button.outerWidth(), 13562 this.menu.width( "" ).outerWidth() 13563 ) ); 13564 }, 13565 13566 _getCreateOptions: function() { 13567 var options = this._super(); 13568 13569 options.disabled = this.element.prop( "disabled" ); 13570 13571 return options; 13572 }, 13573 13574 _parseOptions: function( options ) { 13575 var that = this, 13576 data = []; 13577 options.each( function( index, item ) { 13578 data.push( that._parseOption( $( item ), index ) ); 13579 } ); 13580 this.items = data; 13581 }, 13582 13583 _parseOption: function( option, index ) { 13584 var optgroup = option.parent( "optgroup" ); 13585 13586 return { 13587 element: option, 13588 index: index, 13589 value: option.val(), 13590 label: option.text(), 13591 hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ), 13592 optgroup: optgroup.attr( "label" ) || "", 13593 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 13594 }; 13595 }, 13596 13597 _destroy: function() { 13598 this._unbindFormResetHandler(); 13599 this.menuWrap.remove(); 13600 this.button.remove(); 13601 this.element.show(); 13602 this.element.removeUniqueId(); 13603 this.labels.attr( "for", this.ids.element ); 13604 } 13605} ] ); 13606 13607 13608/*! 13609 * jQuery UI Slider 1.14.
vendor: 2,981 bytes, lines 13609-13725
136091 13610 * https://jqueryui.com 13611 * 13612 * Copyright OpenJS Foundation and other contributors 13613 * Released under the MIT license. 13614 * https://jquery.org/license 13615 */ 13616 13617//>>label: Slider 13618//>>group: Widgets 13619//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 13620//>>docs: https://api.jqueryui.com/slider/ 13621//>>demos: https://jqueryui.com/slider/ 13622//>>css.structure: ../../themes/base/core.css 13623//>>css.structure: ../../themes/base/slider.css 13624//>>css.theme: ../../themes/base/theme.css 13625 13626 13627var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 13628 version: "1.14.1", 13629 widgetEventPrefix: "slide", 13630 13631 options: { 13632 animate: false, 13633 classes: { 13634 "ui-slider": "ui-corner-all", 13635 "ui-slider-handle": "ui-corner-all", 13636 13637 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 13638 // element, but worked best visually with a variety of themes 13639 "ui-slider-range": "ui-corner-all ui-widget-header" 13640 }, 13641 distance: 0, 13642 max: 100, 13643 min: 0, 13644 orientation: "horizontal", 13645 range: false, 13646 step: 1, 13647 value: 0, 13648 values: null, 13649 13650 // Callbacks 13651 change: null, 13652 slide: null, 13653 start: null, 13654 stop: null 13655 }, 13656 13657 // Number of pages in a slider 13658 // (how many times can you page up/down to go through the whole range) 13659 numPages: 5, 13660 13661 _create: function() { 13662 this._keySliding = false; 13663 this._mouseSliding = false; 13664 this._animateOff = true; 13665 this._handleIndex = null; 13666 this._detectOrientation(); 13667 this._mouseInit(); 13668 this._calculateNewMax(); 13669 13670 this._addClass( "ui-slider ui-slider-" + this.orientation, 13671 "ui-widget ui-widget-content" ); 13672 13673 this._refresh(); 13674 13675 this._animateOff = false; 13676 }, 13677 13678 _refresh: function() { 13679 this._createRange(); 13680 this._createHandles(); 13681 this._setupEvents(); 13682 this._refreshValue(); 13683 }, 13684 13685 _createHandles: function() { 13686 var i, handleCount, 13687 options = this.options, 13688 existingHandles = this.element.find( ".ui-slider-handle" ), 13689 handle = "<span tabindex='0'></span>", 13690 handles = []; 13691 13692 handleCount = ( options.values && options.values.length ) || 1; 13693 13694 if ( existingHandles.length > handleCount ) { 13695 existingHandles.slice( handleCount ).remove(); 13696 existingHandles = existingHandles.slice( 0, handleCount ); 13697 } 13698 13699 for ( i = existingHandles.length; i < handleCount; i++ ) { 13700 handles.push( handle ); 13701 } 13702 13703 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13704 13705 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 13706 13707 this.handle = this.handles.eq( 0 ); 13708 13709 this.handles.each( function( i ) { 13710 $( this ) 13711 .data( "ui-slider-handle-index", i ) 13712 .attr( "tabIndex", 0 ); 13713 } ); 13714 }, 13715 13716 _createRange: function() { 13717 var options = this.options; 13718 13719 if ( options.range ) { 13720 if ( options.range === true ) { 13721 if ( !options.values ) { 13722 options.values = [ this._valueMin(), this._valueMin() ]; 13723 } else if ( options.values.length && options.values.length !== 2 ) { 13724 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 13725 } else if ( Array
vendor: 6,343 bytes, lines 13725-13971
13725.isArray( options.values ) ) { 13726 options.values = options.values.slice( 0 ); 13727 } 13728 } 13729 13730 if ( !this.range || !this.range.length ) { 13731 this.range = $( "<div>" ) 13732 .appendTo( this.element ); 13733 13734 this._addClass( this.range, "ui-slider-range" ); 13735 } else { 13736 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 13737 13738 // Handle range switching from true to min/max 13739 this.range.css( { 13740 "left": "", 13741 "bottom": "" 13742 } ); 13743 } 13744 if ( options.range === "min" || options.range === "max" ) { 13745 this._addClass( this.range, "ui-slider-range-" + options.range ); 13746 } 13747 } else { 13748 if ( this.range ) { 13749 this.range.remove(); 13750 } 13751 this.range = null; 13752 } 13753 }, 13754 13755 _setupEvents: function() { 13756 this._off( this.handles ); 13757 this._on( this.handles, this._handleEvents ); 13758 this._hoverable( this.handles ); 13759 this._focusable( this.handles ); 13760 }, 13761 13762 _destroy: function() { 13763 this.handles.remove(); 13764 if ( this.range ) { 13765 this.range.remove(); 13766 } 13767 13768 this._mouseDestroy(); 13769 }, 13770 13771 _mouseCapture: function( event ) { 13772 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 13773 that = this, 13774 o = this.options; 13775 13776 if ( o.disabled ) { 13777 return false; 13778 } 13779 13780 this.elementSize = { 13781 width: this.element.outerWidth(), 13782 height: this.element.outerHeight() 13783 }; 13784 this.elementOffset = this.element.offset(); 13785 13786 position = { x: event.pageX, y: event.pageY }; 13787 normValue = this._normValueFromMouse( position ); 13788 distance = this._valueMax() - this._valueMin() + 1; 13789 this.handles.each( function( i ) { 13790 var thisDistance = Math.abs( normValue - that.values( i ) ); 13791 if ( ( distance > thisDistance ) || 13792 ( distance === thisDistance && 13793 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 13794 distance = thisDistance; 13795 closestHandle = $( this ); 13796 index = i; 13797 } 13798 } ); 13799 13800 allowed = this._start( event, index ); 13801 if ( allowed === false ) { 13802 return false; 13803 } 13804 this._mouseSliding = true; 13805 13806 this._handleIndex = index; 13807 13808 this._addClass( closestHandle, null, "ui-state-active" ); 13809 closestHandle.trigger( "focus" ); 13810 13811 offset = closestHandle.offset(); 13812 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13813 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13814 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13815 top: event.pageY - offset.top - 13816 ( closestHandle.height() / 2 ) - 13817 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 13818 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 13819 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 13820 }; 13821 13822 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13823 this._slide( event, index, normValue ); 13824 } 13825 this._animateOff = true; 13826 return true; 13827 }, 13828 13829 _mouseStart: function() { 13830 return true; 13831 }, 13832 13833 _mouseDrag: function( event ) { 13834 var position = { x: event.pageX, y: event.pageY }, 13835 normValue = this._normValueFromMouse( position ); 13836 13837 this._slide( event, this._handleIndex, normValue ); 13838 13839 return false; 13840 }, 13841 13842 _mouseStop: function( event ) { 13843 this._removeClass( this.handles, null, "ui-state-active" ); 13844 this._mouseSliding = false; 13845 13846 this._stop( event, this._handleIndex ); 13847 this._change( event, this._handleIndex ); 13848 13849 this._handleIndex = null; 13850 this._clickOffset = null; 13851 this._animateOff = false; 13852 13853 return false; 13854 }, 13855 13856 _detectOrientation: function() { 13857 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13858 }, 13859 13860 _normValueFromMouse: function( position ) { 13861 var pixelTotal, 13862 pixelMouse, 13863 percentMouse, 13864 valueTotal, 13865 valueMouse; 13866 13867 if ( this.orientation === "horizontal" ) { 13868 pixelTotal = this.elementSize.width; 13869 pixelMouse = position.x - this.elementOffset.left - 13870 ( this._clickOffset ? this._clickOffset.left : 0 ); 13871 } else { 13872 pixelTotal = this.elementSize.height; 13873 pixelMouse = position.y - this.elementOffset.top - 13874 ( this._clickOffset ? this._clickOffset.top : 0 ); 13875 } 13876 13877 percentMouse = ( pixelMouse / pixelTotal ); 13878 if ( percentMouse > 1 ) { 13879 percentMouse = 1; 13880 } 13881 if ( percentMouse < 0 ) { 13882 percentMouse = 0; 13883 } 13884 if ( this.orientation === "vertical" ) { 13885 percentMouse = 1 - percentMouse; 13886 } 13887 13888 valueTotal = this._valueMax() - this._valueMin(); 13889 valueMouse = this._valueMin() + percentMouse * valueTotal; 13890 13891 return this._trimAlignValue( valueMouse ); 13892 }, 13893 13894 _uiHash: function( index, value, values ) { 13895 var uiHash = { 13896 handle: this.handles[ index ], 13897 handleIndex: index, 13898 value: value !== undefined ? value : this.value() 13899 }; 13900 13901 if ( this._hasMultipleValues() ) { 13902 uiHash.value = value !== undefined ? value : this.values( index ); 13903 uiHash.values = values || this.values(); 13904 } 13905 13906 return uiHash; 13907 }, 13908 13909 _hasMultipleValues: function() { 13910 return this.options.values && this.options.values.length; 13911 }, 13912 13913 _start: function( event, index ) { 13914 return this._trigger( "start", event, this._uiHash( index ) ); 13915 }, 13916 13917 _slide: function( event, index, newVal ) { 13918 var allowed, otherVal, 13919 currentValue = this.value(), 13920 newValues = this.values(); 13921 13922 if ( this._hasMultipleValues() ) { 13923 otherVal = this.values( index ? 0 : 1 ); 13924 currentValue = this.values( index ); 13925 13926 if ( this.options.values.length === 2 && this.options.range === true ) { 13927 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 13928 } 13929 13930 newValues[ index ] = newVal; 13931 } 13932 13933 if ( newVal === currentValue ) { 13934 return; 13935 } 13936 13937 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 13938 13939 // A slide can be canceled by returning false from the slide callback 13940 if ( allowed === false ) { 13941 return; 13942 } 13943 13944 if ( this._hasMultipleValues() ) { 13945 this.values( index, newVal ); 13946 } else { 13947 this.value( newVal ); 13948 } 13949 }, 13950 13951 _stop: function( event, index ) { 13952 this._trigger( "stop", event, this._uiHash( index ) ); 13953 }, 13954 13955 _change: function( event, index ) { 13956 if ( !this._keySliding && !this._mouseSliding ) { 13957 13958 //store the last changed value index for reference when handles overlap 13959 this._lastChangedValue = index; 13960 this._trigger( "change", event, this._uiHash( index ) ); 13961 } 13962 }, 13963 13964 value: function( newValue ) { 13965 if ( arguments.length ) { 13966 this.options.value = this._trimAlignValue( newValue ); 13967 this._refreshValue(); 13968 this._change( null, 0 ); 13969 return; 13970 } 13971
vendor: 4,358 bytes, lines 13972-14144
13972 return this._value(); 13973 }, 13974 13975 values: function( index, newValue ) { 13976 var vals, 13977 newValues, 13978 i; 13979 13980 if ( arguments.length > 1 ) { 13981 this.options.values[ index ] = this._trimAlignValue( newValue ); 13982 this._refreshValue(); 13983 this._change( null, index ); 13984 return; 13985 } 13986 13987 if ( arguments.length ) { 13988 if ( Array.isArray( arguments[ 0 ] ) ) { 13989 vals = this.options.values; 13990 newValues = arguments[ 0 ]; 13991 for ( i = 0; i < vals.length; i += 1 ) { 13992 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13993 this._change( null, i ); 13994 } 13995 this._refreshValue(); 13996 } else { 13997 if ( this._hasMultipleValues() ) { 13998 return this._values( index ); 13999 } else { 14000 return this.value(); 14001 } 14002 } 14003 } else { 14004 return this._values(); 14005 } 14006 }, 14007 14008 _setOption: function( key, value ) { 14009 var i, 14010 valsLength = 0; 14011 14012 if ( key === "range" && this.options.range === true ) { 14013 if ( value === "min" ) { 14014 this.options.value = this._values( 0 ); 14015 this.options.values = null; 14016 } else if ( value === "max" ) { 14017 this.options.value = this._values( this.options.values.length - 1 ); 14018 this.options.values = null; 14019 } 14020 } 14021 14022 if ( Array.isArray( this.options.values ) ) { 14023 valsLength = this.options.values.length; 14024 } 14025 14026 this._super( key, value ); 14027 14028 switch ( key ) { 14029 case "orientation": 14030 this._detectOrientation(); 14031 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 14032 ._addClass( "ui-slider-" + this.orientation ); 14033 this._refreshValue(); 14034 if ( this.options.range ) { 14035 this._refreshRange( value ); 14036 } 14037 14038 // Reset positioning from previous orientation 14039 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 14040 break; 14041 case "value": 14042 this._animateOff = true; 14043 this._refreshValue(); 14044 this._change( null, 0 ); 14045 this._animateOff = false; 14046 break; 14047 case "values": 14048 this._animateOff = true; 14049 this._refreshValue(); 14050 14051 // Start from the last handle to prevent unreachable handles (#9046) 14052 for ( i = valsLength - 1; i >= 0; i-- ) { 14053 this._change( null, i ); 14054 } 14055 this._animateOff = false; 14056 break; 14057 case "step": 14058 case "min": 14059 case "max": 14060 this._animateOff = true; 14061 this._calculateNewMax(); 14062 this._refreshValue(); 14063 this._animateOff = false; 14064 break; 14065 case "range": 14066 this._animateOff = true; 14067 this._refresh(); 14068 this._animateOff = false; 14069 break; 14070 } 14071 }, 14072 14073 _setOptionDisabled: function( value ) { 14074 this._super( value ); 14075 14076 this._toggleClass( null, "ui-state-disabled", !!value ); 14077 }, 14078 14079 //internal value getter 14080 // _value() returns value trimmed by min and max, aligned by step 14081 _value: function() { 14082 var val = this.options.value; 14083 val = this._trimAlignValue( val ); 14084 14085 return val; 14086 }, 14087 14088 //internal values getter 14089 // _values() returns array of values trimmed by min and max, aligned by step 14090 // _values( index ) returns single value trimmed by min and max, aligned by step 14091 _values: function( index ) { 14092 var val, 14093 vals, 14094 i; 14095 14096 if ( arguments.length ) { 14097 val = this.options.values[ index ]; 14098 val = this._trimAlignValue( val ); 14099 14100 return val; 14101 } else if ( this._hasMultipleValues() ) { 14102 14103 // .slice() creates a copy of the array 14104 // this copy gets trimmed by min and max and then returned 14105 vals = this.options.values.slice(); 14106 for ( i = 0; i < vals.length; i += 1 ) { 14107 vals[ i ] = this._trimAlignValue( vals[ i ] ); 14108 } 14109 14110 return vals; 14111 } else { 14112 return []; 14113 } 14114 }, 14115 14116 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 14117 _trimAlignValue: function( val ) { 14118 if ( val <= this._valueMin() ) { 14119 return this._valueMin(); 14120 } 14121 if ( val >= this._valueMax() ) { 14122 return this._valueMax(); 14123 } 14124 var step = ( this.options.step > 0 ) ? this.options.step : 1, 14125 valModStep = ( val - this._valueMin() ) % step, 14126 alignValue = val - valModStep; 14127 14128 if ( Math.abs( valModStep ) * 2 >= step ) { 14129 alignValue += ( valModStep > 0 ) ? step : ( -step ); 14130 } 14131 14132 // Since JavaScript has problems with large floats, round 14133 // the final value to 5 digits after the decimal point (see #4124) 14134 return parseFloat( alignValue.toFixed( 5 ) ); 14135 }, 14136 14137 _calculateNewMax: function() { 14138 var max = this.options.max, 14139 min = this._valueMin(), 14140 step = this.options.step, 14141 aboveMin = Math.round( ( max - min ) / step ) * step; 14142 max = aboveMin + min; 14143 if ( max > this.options.max ) { 14144
vendor: 5,593 bytes, lines 14145-14344
14145 //If max is not divisible by step, rounding off may increase its value 14146 max -= step; 14147 } 14148 this.max = parseFloat( max.toFixed( this._precision() ) ); 14149 }, 14150 14151 _precision: function() { 14152 var precision = this._precisionOf( this.options.step ); 14153 if ( this.options.min !== null ) { 14154 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14155 } 14156 return precision; 14157 }, 14158 14159 _precisionOf: function( num ) { 14160 var str = num.toString(), 14161 decimal = str.indexOf( "." ); 14162 return decimal === -1 ? 0 : str.length - decimal - 1; 14163 }, 14164 14165 _valueMin: function() { 14166 return this.options.min; 14167 }, 14168 14169 _valueMax: function() { 14170 return this.max; 14171 }, 14172 14173 _refreshRange: function( orientation ) { 14174 if ( orientation === "vertical" ) { 14175 this.range.css( { "width": "", "left": "" } ); 14176 } 14177 if ( orientation === "horizontal" ) { 14178 this.range.css( { "height": "", "bottom": "" } ); 14179 } 14180 }, 14181 14182 _refreshValue: function() { 14183 var lastValPercent, valPercent, value, valueMin, valueMax, 14184 oRange = this.options.range, 14185 o = this.options, 14186 that = this, 14187 animate = ( !this._animateOff ) ? o.animate : false, 14188 _set = {}; 14189 14190 if ( this._hasMultipleValues() ) { 14191 this.handles.each( function( i ) { 14192 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 14193 that._valueMin() ) * 100; 14194 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14195 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14196 if ( that.options.range === true ) { 14197 if ( that.orientation === "horizontal" ) { 14198 if ( i === 0 ) { 14199 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14200 left: valPercent + "%" 14201 }, o.animate ); 14202 } 14203 if ( i === 1 ) { 14204 that.range[ animate ? "animate" : "css" ]( { 14205 width: ( valPercent - lastValPercent ) + "%" 14206 }, { 14207 queue: false, 14208 duration: o.animate 14209 } ); 14210 } 14211 } else { 14212 if ( i === 0 ) { 14213 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14214 bottom: ( valPercent ) + "%" 14215 }, o.animate ); 14216 } 14217 if ( i === 1 ) { 14218 that.range[ animate ? "animate" : "css" ]( { 14219 height: ( valPercent - lastValPercent ) + "%" 14220 }, { 14221 queue: false, 14222 duration: o.animate 14223 } ); 14224 } 14225 } 14226 } 14227 lastValPercent = valPercent; 14228 } ); 14229 } else { 14230 value = this.value(); 14231 valueMin = this._valueMin(); 14232 valueMax = this._valueMax(); 14233 valPercent = ( valueMax !== valueMin ) ? 14234 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 14235 0; 14236 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14237 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14238 14239 if ( oRange === "min" && this.orientation === "horizontal" ) { 14240 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14241 width: valPercent + "%" 14242 }, o.animate ); 14243 } 14244 if ( oRange === "max" && this.orientation === "horizontal" ) { 14245 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14246 width: ( 100 - valPercent ) + "%" 14247 }, o.animate ); 14248 } 14249 if ( oRange === "min" && this.orientation === "vertical" ) { 14250 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14251 height: valPercent + "%" 14252 }, o.animate ); 14253 } 14254 if ( oRange === "max" && this.orientation === "vertical" ) { 14255 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14256 height: ( 100 - valPercent ) + "%" 14257 }, o.animate ); 14258 } 14259 } 14260 }, 14261 14262 _handleEvents: { 14263 keydown: function( event ) { 14264 var allowed, curVal, newVal, step, 14265 index = $( event.target ).data( "ui-slider-handle-index" ); 14266 14267 switch ( event.keyCode ) { 14268 case $.ui.keyCode.HOME: 14269 case $.ui.keyCode.END: 14270 case $.ui.keyCode.PAGE_UP: 14271 case $.ui.keyCode.PAGE_DOWN: 14272 case $.ui.keyCode.UP: 14273 case $.ui.keyCode.RIGHT: 14274 case $.ui.keyCode.DOWN: 14275 case $.ui.keyCode.LEFT: 14276 event.preventDefault(); 14277 if ( !this._keySliding ) { 14278 this._keySliding = true; 14279 this._addClass( $( event.target ), null, "ui-state-active" ); 14280 allowed = this._start( event, index ); 14281 if ( allowed === false ) { 14282 return; 14283 } 14284 } 14285 break; 14286 } 14287 14288 step = this.options.step; 14289 if ( this._hasMultipleValues() ) { 14290 curVal = newVal = this.values( index ); 14291 } else { 14292 curVal = newVal = this.value(); 14293 } 14294 14295 switch ( event.keyCode ) { 14296 case $.ui.keyCode.HOME: 14297 newVal = this._valueMin(); 14298 break; 14299 case $.ui.keyCode.END: 14300 newVal = this._valueMax(); 14301 break; 14302 case $.ui.keyCode.PAGE_UP: 14303 newVal = this._trimAlignValue( 14304 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 14305 ); 14306 break; 14307 case $.ui.keyCode.PAGE_DOWN: 14308 newVal = this._trimAlignValue( 14309 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 14310 break; 14311 case $.ui.keyCode.UP: 14312 case $.ui.keyCode.RIGHT: 14313 if ( curVal === this._valueMax() ) { 14314 return; 14315 } 14316 newVal = this._trimAlignValue( curVal + step ); 14317 break; 14318 case $.ui.keyCode.DOWN: 14319 case $.ui.keyCode.LEFT: 14320 if ( curVal === this._valueMin() ) { 14321 return; 14322 } 14323 newVal = this._trimAlignValue( curVal - step ); 14324 break; 14325 } 14326 14327 this._slide( event, index, newVal ); 14328 }, 14329 keyup: function( event ) { 14330 var index = $( event.target ).data( "ui-slider-handle-index" ); 14331 14332 if ( this._keySliding ) { 14333 this._keySliding = false; 14334 this._stop( event, index ); 14335 this._change( event, index ); 14336 this._removeClass( $( event.target ), null, "ui-state-active" ); 14337 } 14338 } 14339 } 14340} ); 14341 14342 14343/*! 14344 * jQuery UI Spinner 1.1
vendor: 3,303 bytes, lines 14344-14481
143444.1 14345 * https://jqueryui.com 14346 * 14347 * Copyright OpenJS Foundation and other contributors 14348 * Released under the MIT license. 14349 * https://jquery.org/license 14350 */ 14351 14352//>>label: Spinner 14353//>>group: Widgets 14354//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 14355//>>docs: https://api.jqueryui.com/spinner/ 14356//>>demos: https://jqueryui.com/spinner/ 14357//>>css.structure: ../../themes/base/core.css 14358//>>css.structure: ../../themes/base/spinner.css 14359//>>css.theme: ../../themes/base/theme.css 14360 14361 14362function spinnerModifier( fn ) { 14363 return function() { 14364 var previous = this.element.val(); 14365 fn.apply( this, arguments ); 14366 this._refresh(); 14367 if ( previous !== this.element.val() ) { 14368 this._trigger( "change" ); 14369 } 14370 }; 14371} 14372 14373$.widget( "ui.spinner", { 14374 version: "1.14.1", 14375 defaultElement: "<input>", 14376 widgetEventPrefix: "spin", 14377 options: { 14378 classes: { 14379 "ui-spinner": "ui-corner-all", 14380 "ui-spinner-down": "ui-corner-br", 14381 "ui-spinner-up": "ui-corner-tr" 14382 }, 14383 culture: null, 14384 icons: { 14385 down: "ui-icon-triangle-1-s", 14386 up: "ui-icon-triangle-1-n" 14387 }, 14388 incremental: true, 14389 max: null, 14390 min: null, 14391 numberFormat: null, 14392 page: 10, 14393 step: 1, 14394 14395 change: null, 14396 spin: null, 14397 start: null, 14398 stop: null 14399 }, 14400 14401 _create: function() { 14402 14403 // handle string values that need to be parsed 14404 this._setOption( "max", this.options.max ); 14405 this._setOption( "min", this.options.min ); 14406 this._setOption( "step", this.options.step ); 14407 14408 // Only format if there is a value, prevents the field from being marked 14409 // as invalid in Firefox, see #9573. 14410 if ( this.value() !== "" ) { 14411 14412 // Format the value, but don't constrain. 14413 this._value( this.element.val(), true ); 14414 } 14415 14416 this._draw(); 14417 this._on( this._events ); 14418 this._refresh(); 14419 14420 // Turning off autocomplete prevents the browser from remembering the 14421 // value when navigating through history, so we re-enable autocomplete 14422 // if the page is unloaded before the widget is destroyed. #7790 14423 this._on( this.window, { 14424 beforeunload: function() { 14425 this.element.removeAttr( "autocomplete" ); 14426 } 14427 } ); 14428 }, 14429 14430 _getCreateOptions: function() { 14431 var options = this._super(); 14432 var element = this.element; 14433 14434 $.each( [ "min", "max", "step" ], function( i, option ) { 14435 var value = element.attr( option ); 14436 if ( value != null && value.length ) { 14437 options[ option ] = value; 14438 } 14439 } ); 14440 14441 return options; 14442 }, 14443 14444 _events: { 14445 keydown: function( event ) { 14446 if ( this._start( event ) && this._keydown( event ) ) { 14447 event.preventDefault(); 14448 } 14449 }, 14450 keyup: "_stop", 14451 focus: function() { 14452 this.previous = this.element.val(); 14453 }, 14454 blur: function( event ) { 14455 this._stop(); 14456 this._refresh(); 14457 if ( this.previous !== this.element.val() ) { 14458 this._trigger( "change", event ); 14459 } 14460 }, 14461 mousewheel: function( event, delta ) { 14462 var activeElement = this.document[ 0 ].activeElement; 14463 var isActive = this.element[ 0 ] === activeElement; 14464 14465 if ( !isActive || !delta ) { 14466 return; 14467 } 14468 14469 if ( !this.spinning && !this._start( event ) ) { 14470 return false; 14471 } 14472 14473 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 14474 clearTimeout( this.mousewheelTimer ); 14475 this.mousewheelTimer = this._delay( function() { 14476 if ( this.spinning ) { 14477 this._stop( event ); 14478 } 14479 }, 100 ); 14480 event.preventDefault(); 14481 },
vendor: 10,099 bytes, lines 14481-14883
14481 14482 "mousedown .ui-spinner-button": function( event ) { 14483 var previous; 14484 14485 // We never want the buttons to have focus; whenever the user is 14486 // interacting with the spinner, the focus should be on the input. 14487 // If the input is focused then this.previous is properly set from 14488 // when the input first received focus. If the input is not focused 14489 // then we need to set this.previous based on the value before spinning. 14490 previous = this.element[ 0 ] === this.document[ 0 ].activeElement ? 14491 this.previous : this.element.val(); 14492 function checkFocus() { 14493 var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement; 14494 if ( !isActive ) { 14495 this.element.trigger( "focus" ); 14496 this.previous = previous; 14497 } 14498 } 14499 14500 // Ensure focus is on (or stays on) the text field 14501 event.preventDefault(); 14502 checkFocus.call( this ); 14503 14504 if ( this._start( event ) === false ) { 14505 return; 14506 } 14507 14508 this._repeat( null, $( event.currentTarget ) 14509 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14510 }, 14511 "mouseup .ui-spinner-button": "_stop", 14512 "mouseenter .ui-spinner-button": function( event ) { 14513 14514 // button will add ui-state-active if mouse was down while mouseleave and kept down 14515 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14516 return; 14517 } 14518 14519 if ( this._start( event ) === false ) { 14520 return false; 14521 } 14522 this._repeat( null, $( event.currentTarget ) 14523 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14524 }, 14525 14526 // TODO: do we really want to consider this a stop? 14527 // shouldn't we just stop the repeater and wait until mouseup before 14528 // we trigger the stop event? 14529 "mouseleave .ui-spinner-button": "_stop" 14530 }, 14531 14532 // Support mobile enhanced option and make backcompat more sane 14533 _enhance: function() { 14534 this.uiSpinner = this.element 14535 .attr( "autocomplete", "off" ) 14536 .wrap( "<span>" ) 14537 .parent() 14538 14539 // Add buttons 14540 .append( 14541 "<a></a><a></a>" 14542 ); 14543 }, 14544 14545 _draw: function() { 14546 this._enhance(); 14547 14548 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 14549 this._addClass( "ui-spinner-input" ); 14550 14551 this.element.attr( "role", "spinbutton" ); 14552 14553 // Button bindings 14554 this.buttons = this.uiSpinner.children( "a" ) 14555 .attr( "tabIndex", -1 ) 14556 .attr( "aria-hidden", true ) 14557 .button( { 14558 classes: { 14559 "ui-button": "" 14560 } 14561 } ); 14562 14563 // TODO: Right now button does not support classes this is already updated in button PR 14564 this._removeClass( this.buttons, "ui-corner-all" ); 14565 14566 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 14567 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 14568 this.buttons.first().button( { 14569 "icon": this.options.icons.up, 14570 "showLabel": false 14571 } ); 14572 this.buttons.last().button( { 14573 "icon": this.options.icons.down, 14574 "showLabel": false 14575 } ); 14576 14577 // IE 6 doesn't understand height: 50% for the buttons 14578 // unless the wrapper has an explicit height 14579 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 14580 this.uiSpinner.height() > 0 ) { 14581 this.uiSpinner.height( this.uiSpinner.height() ); 14582 } 14583 }, 14584 14585 _keydown: function( event ) { 14586 var options = this.options, 14587 keyCode = $.ui.keyCode; 14588 14589 switch ( event.keyCode ) { 14590 case keyCode.UP: 14591 this._repeat( null, 1, event ); 14592 return true; 14593 case keyCode.DOWN: 14594 this._repeat( null, -1, event ); 14595 return true; 14596 case keyCode.PAGE_UP: 14597 this._repeat( null, options.page, event ); 14598 return true; 14599 case keyCode.PAGE_DOWN: 14600 this._repeat( null, -options.page, event ); 14601 return true; 14602 } 14603 14604 return false; 14605 }, 14606 14607 _start: function( event ) { 14608 if ( !this.spinning && this._trigger( "start", event ) === false ) { 14609 return false; 14610 } 14611 14612 if ( !this.counter ) { 14613 this.counter = 1; 14614 } 14615 this.spinning = true; 14616 return true; 14617 }, 14618 14619 _repeat: function( i, steps, event ) { 14620 i = i || 500; 14621 14622 clearTimeout( this.timer ); 14623 this.timer = this._delay( function() { 14624 this._repeat( 40, steps, event ); 14625 }, i ); 14626 14627 this._spin( steps * this.options.step, event ); 14628 }, 14629 14630 _spin: function( step, event ) { 14631 var value = this.value() || 0; 14632 14633 if ( !this.counter ) { 14634 this.counter = 1; 14635 } 14636 14637 value = this._adjustValue( value + step * this._increment( this.counter ) ); 14638 14639 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 14640 this._value( value ); 14641 this.counter++; 14642 } 14643 }, 14644 14645 _increment: function( i ) { 14646 var incremental = this.options.incremental; 14647 14648 if ( incremental ) { 14649 return typeof incremental === "function" ? 14650 incremental( i ) : 14651 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 14652 } 14653 14654 return 1; 14655 }, 14656 14657 _precision: function() { 14658 var precision = this._precisionOf( this.options.step ); 14659 if ( this.options.min !== null ) { 14660 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14661 } 14662 return precision; 14663 }, 14664 14665 _precisionOf: function( num ) { 14666 var str = num.toString(), 14667 decimal = str.indexOf( "." ); 14668 return decimal === -1 ? 0 : str.length - decimal - 1; 14669 }, 14670 14671 _adjustValue: function( value ) { 14672 var base, aboveMin, 14673 options = this.options; 14674 14675 // Make sure we're at a valid step 14676 // - find out where we are relative to the base (min or 0) 14677 base = options.min !== null ? options.min : 0; 14678 aboveMin = value - base; 14679 14680 // - round to the nearest step 14681 aboveMin = Math.round( aboveMin / options.step ) * options.step; 14682 14683 // - rounding is based on 0, so adjust back to our base 14684 value = base + aboveMin; 14685 14686 // Fix precision from bad JS floating point math 14687 value = parseFloat( value.toFixed( this._precision() ) ); 14688 14689 // Clamp the value 14690 if ( options.max !== null && value > options.max ) { 14691 return options.max; 14692 } 14693 if ( options.min !== null && value < options.min ) { 14694 return options.min; 14695 } 14696 14697 return value; 14698 }, 14699 14700 _stop: function( event ) { 14701 if ( !this.spinning ) { 14702 return; 14703 } 14704 14705 clearTimeout( this.timer ); 14706 clearTimeout( this.mousewheelTimer ); 14707 this.counter = 0; 14708 this.spinning = false; 14709 this._trigger( "stop", event ); 14710 }, 14711 14712 _setOption: function( key, value ) { 14713 var prevValue, first, last; 14714 14715 if ( key === "culture" || key === "numberFormat" ) { 14716 prevValue = this._parse( this.element.val() ); 14717 this.options[ key ] = value; 14718 this.element.val( this._format( prevValue ) ); 14719 return; 14720 } 14721 14722 if ( key === "max" || key === "min" || key === "step" ) { 14723 if ( typeof value === "string" ) { 14724 value = this._parse( value ); 14725 } 14726 } 14727 if ( key === "icons" ) { 14728 first = this.buttons.first().find( ".ui-icon" ); 14729 this._removeClass( first, null, this.options.icons.up ); 14730 this._addClass( first, null, value.up ); 14731 last = this.buttons.last().find( ".ui-icon" ); 14732 this._removeClass( last, null, this.options.icons.down ); 14733 this._addClass( last, null, value.down ); 14734 } 14735 14736 this._super( key, value ); 14737 }, 14738 14739 _setOptionDisabled: function( value ) { 14740 this._super( value ); 14741 14742 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 14743 this.element.prop( "disabled", !!value ); 14744 this.buttons.button( value ? "disable" : "enable" ); 14745 }, 14746 14747 _setOptions: spinnerModifier( function( options ) { 14748 this._super( options ); 14749 } ), 14750 14751 _parse: function( val ) { 14752 if ( typeof val === "string" && val !== "" ) { 14753 val = window.Globalize && this.options.numberFormat ? 14754 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 14755 } 14756 return val === "" || isNaN( val ) ? null : val; 14757 }, 14758 14759 _format: function( value ) { 14760 if ( value === "" ) { 14761 return ""; 14762 } 14763 return window.Globalize && this.options.numberFormat ? 14764 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 14765 value; 14766 }, 14767 14768 _refresh: function() { 14769 this.element.attr( { 14770 "aria-valuemin": this.options.min, 14771 "aria-valuemax": this.options.max, 14772 14773 // TODO: what should we do with values that can't be parsed? 14774 "aria-valuenow": this._parse( this.element.val() ) 14775 } ); 14776 }, 14777 14778 isValid: function() { 14779 var value = this.value(); 14780 14781 // Null is invalid 14782 if ( value === null ) { 14783 return false; 14784 } 14785 14786 // If value gets adjusted, it's invalid 14787 return value === this._adjustValue( value ); 14788 }, 14789 14790 // Update the value without triggering change 14791 _value: function( value, allowAny ) { 14792 var parsed; 14793 if ( value !== "" ) { 14794 parsed = this._parse( value ); 14795 if ( parsed !== null ) { 14796 if ( !allowAny ) { 14797 parsed = this._adjustValue( parsed ); 14798 } 14799 value = this._format( parsed ); 14800 } 14801 } 14802 this.element.val( value ); 14803 this._refresh(); 14804 }, 14805 14806 _destroy: function() { 14807 this.element 14808 .prop( "disabled", false ) 14809 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 14810 14811 this.uiSpinner.replaceWith( this.element ); 14812 }, 14813 14814 stepUp: spinnerModifier( function( steps ) { 14815 this._stepUp( steps ); 14816 } ), 14817 _stepUp: function( steps ) { 14818 if ( this._start() ) { 14819 this._spin( ( steps || 1 ) * this.options.step ); 14820 this._stop(); 14821 } 14822 }, 14823 14824 stepDown: spinnerModifier( function( steps ) { 14825 this._stepDown( steps ); 14826 } ), 14827 _stepDown: function( steps ) { 14828 if ( this._start() ) { 14829 this._spin( ( steps || 1 ) * -this.options.step ); 14830 this._stop(); 14831 } 14832 }, 14833 14834 pageUp: spinnerModifier( function( pages ) { 14835 this._stepUp( ( pages || 1 ) * this.options.page ); 14836 } ), 14837 14838 pageDown: spinnerModifier( function( pages ) { 14839 this._stepDown( ( pages || 1 ) * this.options.page ); 14840 } ), 14841 14842 value: function( newVal ) { 14843 if ( !arguments.length ) { 14844 return this._parse( this.element.val() ); 14845 } 14846 spinnerModifier( this._value ).call( this, newVal ); 14847 }, 14848 14849 widget: function() { 14850 return this.uiSpinner; 14851 } 14852} ); 14853 14854// DEPRECATED 14855// TODO: switch return back to widget declaration at top of file when this is removed 14856if ( $.uiBackCompat === true ) { 14857 14858 // Backcompat for spinner html extension points 14859 $.widget( "ui.spinner", $.ui.spinner, { 14860 _enhance: function() { 14861 this.uiSpinner = this.element 14862 .attr( "autocomplete", "off" ) 14863 .wrap( this._uiSpinnerHtml() ) 14864 .parent() 14865 14866 // Add buttons 14867 .append( this._buttonHtml() ); 14868 }, 14869 _uiSpinnerHtml: function() { 14870 return "<span>"; 14871 }, 14872 14873 _buttonHtml: function() { 14874 return "<a></a><a></a>"; 14875 } 14876 } ); 14877} 14878 14879var widgetsSpinner = $.ui.spinner; 14880 14881 14882/*! 14883 * jQuery UI Tabs 1.14.
vendor: 1,533 bytes, lines 14883-14950
148831 14884 * https://jqueryui.com 14885 * 14886 * Copyright OpenJS Foundation and other contributors 14887 * Released under the MIT license. 14888 * https://jquery.org/license 14889 */ 14890 14891//>>label: Tabs 14892//>>group: Widgets 14893//>>description: Transforms a set of container elements into a tab structure. 14894//>>docs: https://api.jqueryui.com/tabs/ 14895//>>demos: https://jqueryui.com/tabs/ 14896//>>css.structure: ../../themes/base/core.css 14897//>>css.structure: ../../themes/base/tabs.css 14898//>>css.theme: ../../themes/base/theme.css 14899 14900 14901$.widget( "ui.tabs", { 14902 version: "1.14.1", 14903 delay: 300, 14904 options: { 14905 active: null, 14906 classes: { 14907 "ui-tabs": "ui-corner-all", 14908 "ui-tabs-nav": "ui-corner-all", 14909 "ui-tabs-panel": "ui-corner-bottom", 14910 "ui-tabs-tab": "ui-corner-top" 14911 }, 14912 collapsible: false, 14913 event: "click", 14914 heightStyle: "content", 14915 hide: null, 14916 show: null, 14917 14918 // Callbacks 14919 activate: null, 14920 beforeActivate: null, 14921 beforeLoad: null, 14922 load: null 14923 }, 14924 14925 _isLocal: ( function() { 14926 var rhash = /#.*$/; 14927 14928 return function( anchor ) { 14929 var anchorUrl, locationUrl; 14930 14931 anchorUrl = anchor.href.replace( rhash, "" ); 14932 locationUrl = location.href.replace( rhash, "" ); 14933 14934 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 14935 try { 14936 anchorUrl = decodeURIComponent( anchorUrl ); 14937 } catch ( error ) {} 14938 try { 14939 locationUrl = decodeURIComponent( locationUrl ); 14940 } catch ( error ) {} 14941 14942 return anchor.hash.length > 1 && anchorUrl === locationUrl; 14943 }; 14944 } )(), 14945 14946 _create: function() { 14947 var that = this, 14948 options = this.options; 14949 14950 this.running = false;
vendor: 10,605 bytes, lines 14951-15351
14951 14952 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 14953 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 14954 14955 this._processTabs(); 14956 options.active = this._initialActive(); 14957 14958 // Take disabling tabs via class attribute from HTML 14959 // into account and update option properly. 14960 if ( Array.isArray( options.disabled ) ) { 14961 options.disabled = $.uniqueSort( options.disabled.concat( 14962 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 14963 return that.tabs.index( li ); 14964 } ) 14965 ) ).sort(); 14966 } 14967 14968 // Check for length avoids error when initializing empty list 14969 if ( this.options.active !== false && this.anchors.length ) { 14970 this.active = this._findActive( options.active ); 14971 } else { 14972 this.active = $(); 14973 } 14974 14975 this._refresh(); 14976 14977 if ( this.active.length ) { 14978 this.load( options.active ); 14979 } 14980 }, 14981 14982 _initialActive: function() { 14983 var active = this.options.active, 14984 collapsible = this.options.collapsible, 14985 locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) ); 14986 14987 if ( active === null ) { 14988 14989 // check the fragment identifier in the URL 14990 if ( locationHashDecoded ) { 14991 this.tabs.each( function( i, tab ) { 14992 if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) { 14993 active = i; 14994 return false; 14995 } 14996 } ); 14997 } 14998 14999 // Check for a tab marked active via a class 15000 if ( active === null ) { 15001 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 15002 } 15003 15004 // No active tab, set to false 15005 if ( active === null || active === -1 ) { 15006 active = this.tabs.length ? 0 : false; 15007 } 15008 } 15009 15010 // Handle numbers: negative, out of range 15011 if ( active !== false ) { 15012 active = this.tabs.index( this.tabs.eq( active ) ); 15013 if ( active === -1 ) { 15014 active = collapsible ? false : 0; 15015 } 15016 } 15017 15018 // Don't allow collapsible: false and active: false 15019 if ( !collapsible && active === false && this.anchors.length ) { 15020 active = 0; 15021 } 15022 15023 return active; 15024 }, 15025 15026 _getCreateEventData: function() { 15027 return { 15028 tab: this.active, 15029 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 15030 }; 15031 }, 15032 15033 _tabKeydown: function( event ) { 15034 var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ), 15035 selectedIndex = this.tabs.index( focusedTab ), 15036 goingForward = true; 15037 15038 if ( this._handlePageNav( event ) ) { 15039 return; 15040 } 15041 15042 switch ( event.keyCode ) { 15043 case $.ui.keyCode.RIGHT: 15044 case $.ui.keyCode.DOWN: 15045 selectedIndex++; 15046 break; 15047 case $.ui.keyCode.UP: 15048 case $.ui.keyCode.LEFT: 15049 goingForward = false; 15050 selectedIndex--; 15051 break; 15052 case $.ui.keyCode.END: 15053 selectedIndex = this.anchors.length - 1; 15054 break; 15055 case $.ui.keyCode.HOME: 15056 selectedIndex = 0; 15057 break; 15058 case $.ui.keyCode.SPACE: 15059 15060 // Activate only, no collapsing 15061 event.preventDefault(); 15062 clearTimeout( this.activating ); 15063 this._activate( selectedIndex ); 15064 return; 15065 case $.ui.keyCode.ENTER: 15066 15067 // Toggle (cancel delayed activation, allow collapsing) 15068 event.preventDefault(); 15069 clearTimeout( this.activating ); 15070 15071 // Determine if we should collapse or activate 15072 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 15073 return; 15074 default: 15075 return; 15076 } 15077 15078 // Focus the appropriate tab, based on which key was pressed 15079 event.preventDefault(); 15080 clearTimeout( this.activating ); 15081 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 15082 15083 // Navigating with control/command key will prevent automatic activation 15084 if ( !event.ctrlKey && !event.metaKey ) { 15085 15086 // Update aria-selected immediately so that AT think the tab is already selected. 15087 // Otherwise AT may confuse the user by stating that they need to activate the tab, 15088 // but the tab will already be activated by the time the announcement finishes. 15089 focusedTab.attr( "aria-selected", "false" ); 15090 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 15091 15092 this.activating = this._delay( function() { 15093 this.option( "active", selectedIndex ); 15094 }, this.delay ); 15095 } 15096 }, 15097 15098 _panelKeydown: function( event ) { 15099 if ( this._handlePageNav( event ) ) { 15100 return; 15101 } 15102 15103 // Ctrl+up moves focus to the current tab 15104 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 15105 event.preventDefault(); 15106 this.active.trigger( "focus" ); 15107 } 15108 }, 15109 15110 // Alt+page up/down moves focus to the previous/next tab (and activates) 15111 _handlePageNav: function( event ) { 15112 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 15113 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 15114 return true; 15115 } 15116 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 15117 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 15118 return true; 15119 } 15120 }, 15121 15122 _findNextTab: function( index, goingForward ) { 15123 var lastTabIndex = this.tabs.length - 1; 15124 15125 function constrain() { 15126 if ( index > lastTabIndex ) { 15127 index = 0; 15128 } 15129 if ( index < 0 ) { 15130 index = lastTabIndex; 15131 } 15132 return index; 15133 } 15134 15135 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 15136 index = goingForward ? index + 1 : index - 1; 15137 } 15138 15139 return index; 15140 }, 15141 15142 _focusNextTab: function( index, goingForward ) { 15143 index = this._findNextTab( index, goingForward ); 15144 this.tabs.eq( index ).trigger( "focus" ); 15145 return index; 15146 }, 15147 15148 _setOption: function( key, value ) { 15149 if ( key === "active" ) { 15150 15151 // _activate() will handle invalid values and update this.options 15152 this._activate( value ); 15153 return; 15154 } 15155 15156 this._super( key, value ); 15157 15158 if ( key === "collapsible" ) { 15159 this._toggleClass( "ui-tabs-collapsible", null, value ); 15160 15161 // Setting collapsible: false while collapsed; open first panel 15162 if ( !value && this.options.active === false ) { 15163 this._activate( 0 ); 15164 } 15165 } 15166 15167 if ( key === "event" ) { 15168 this._setupEvents( value ); 15169 } 15170 15171 if ( key === "heightStyle" ) { 15172 this._setupHeightStyle( value ); 15173 } 15174 }, 15175 15176 refresh: function() { 15177 var options = this.options, 15178 lis = this.tablist.children( ":has(a[href])" ); 15179 15180 // Get disabled tabs from class attribute from HTML 15181 // this will get converted to a boolean if needed in _refresh() 15182 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15183 return lis.index( tab ); 15184 } ); 15185 15186 this._processTabs(); 15187 15188 // Was collapsed or no tabs 15189 if ( options.active === false || !this.anchors.length ) { 15190 options.active = false; 15191 this.active = $(); 15192 15193 // was active, but active tab is gone 15194 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15195 15196 // all remaining tabs are disabled 15197 if ( this.tabs.length === options.disabled.length ) { 15198 options.active = false; 15199 this.active = $(); 15200 15201 // activate previous tab 15202 } else { 15203 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15204 } 15205 15206 // was active, active tab still exists 15207 } else { 15208 15209 // make sure active index is correct 15210 options.active = this.tabs.index( this.active ); 15211 } 15212 15213 this._refresh(); 15214 }, 15215 15216 _refresh: function() { 15217 this._setOptionDisabled( this.options.disabled ); 15218 this._setupEvents( this.options.event ); 15219 this._setupHeightStyle( this.options.heightStyle ); 15220 15221 this.tabs.not( this.active ).attr( { 15222 "aria-selected": "false", 15223 "aria-expanded": "false", 15224 tabIndex: -1 15225 } ); 15226 this.panels.not( this._getPanelForTab( this.active ) ) 15227 .hide() 15228 .attr( { 15229 "aria-hidden": "true" 15230 } ); 15231 15232 // Make sure one tab is in the tab order 15233 if ( !this.active.length ) { 15234 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15235 } else { 15236 this.active 15237 .attr( { 15238 "aria-selected": "true", 15239 "aria-expanded": "true", 15240 tabIndex: 0 15241 } ); 15242 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 15243 this._getPanelForTab( this.active ) 15244 .show() 15245 .attr( { 15246 "aria-hidden": "false" 15247 } ); 15248 } 15249 }, 15250 15251 _processTabs: function() { 15252 var that = this, 15253 prevTabs = this.tabs, 15254 prevAnchors = this.anchors, 15255 prevPanels = this.panels; 15256 15257 this.tablist = this._getList().attr( "role", "tablist" ); 15258 this._addClass( this.tablist, "ui-tabs-nav", 15259 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 15260 15261 // Prevent users from focusing disabled tabs via click 15262 this.tablist 15263 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 15264 if ( $( this ).is( ".ui-state-disabled" ) ) { 15265 event.preventDefault(); 15266 } 15267 } ); 15268 15269 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15270 .attr( { 15271 role: "tab", 15272 tabIndex: -1 15273 } ); 15274 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 15275 15276 this.anchors = this.tabs.map( function() { 15277 return $( "a", this )[ 0 ]; 15278 } ) 15279 .attr( { 15280 tabIndex: -1 15281 } ); 15282 this._addClass( this.anchors, "ui-tabs-anchor" ); 15283 15284 this.panels = $(); 15285 15286 this.anchors.each( function( i, anchor ) { 15287 var selector, panel, panelId, 15288 anchorId = $( anchor ).uniqueId().attr( "id" ), 15289 tab = $( anchor ).closest( "li" ), 15290 originalAriaControls = tab.attr( "aria-controls" ); 15291 15292 // Inline tab 15293 if ( that._isLocal( anchor ) ) { 15294 selector = decodeURIComponent( anchor.hash ); 15295 panelId = selector.substring( 1 ); 15296 panel = that.element.find( "#" + CSS.escape( panelId ) ); 15297 15298 // remote tab 15299 } else { 15300 15301 // If the tab doesn't already have aria-controls, 15302 // generate an id by using a throw-away element 15303 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15304 selector = "#" + panelId; 15305 panel = that.element.find( selector ); 15306 if ( !panel.length ) { 15307 panel = that._createPanel( panelId ); 15308 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15309 } 15310 panel.attr( "aria-live", "polite" ); 15311 } 15312 15313 if ( panel.length ) { 15314 that.panels = that.panels.add( panel ); 15315 } 15316 if ( originalAriaControls ) { 15317 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15318 } 15319 tab.attr( { 15320 "aria-controls": panelId, 15321 "aria-labelledby": anchorId 15322 } ); 15323 panel.attr( "aria-labelledby", anchorId ); 15324 } ); 15325 15326 this.panels.attr( "role", "tabpanel" ); 15327 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 15328 15329 // Avoid memory leaks (#10056) 15330 if ( prevTabs ) { 15331 this._off( prevTabs.not( this.tabs ) ); 15332 this._off( prevAnchors.not( this.anchors ) ); 15333 this._off( prevPanels.not( this.panels ) ); 15334 } 15335 }, 15336 15337 // Allow overriding how to find the list for rare usage scenarios (#7715) 15338 _getList: function() { 15339 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 15340 }, 15341 15342 _createPanel: function( id ) { 15343 return $( "<div>" ) 15344 .attr( "id", id ) 15345 .data( "ui-tabs-destroy", true ); 15346 }, 15347 15348 _setOptionDisabled: function( disabled ) { 15349 var currentItem, li, i; 15350 15351 if ( Array
vendor: 6,222 bytes, lines 15351-15582
15351.isArray( disabled ) ) { 15352 if ( !disabled.length ) { 15353 disabled = false; 15354 } else if ( disabled.length === this.anchors.length ) { 15355 disabled = true; 15356 } 15357 } 15358 15359 // Disable tabs 15360 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 15361 currentItem = $( li ); 15362 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15363 currentItem.attr( "aria-disabled", "true" ); 15364 this._addClass( currentItem, null, "ui-state-disabled" ); 15365 } else { 15366 currentItem.removeAttr( "aria-disabled" ); 15367 this._removeClass( currentItem, null, "ui-state-disabled" ); 15368 } 15369 } 15370 15371 this.options.disabled = disabled; 15372 15373 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 15374 disabled === true ); 15375 }, 15376 15377 _setupEvents: function( event ) { 15378 var events = {}; 15379 if ( event ) { 15380 $.each( event.split( " " ), function( index, eventName ) { 15381 events[ eventName ] = "_eventHandler"; 15382 } ); 15383 } 15384 15385 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15386 15387 // Always prevent the default action, even when disabled 15388 this._on( true, this.anchors, { 15389 click: function( event ) { 15390 event.preventDefault(); 15391 } 15392 } ); 15393 this._on( this.anchors, events ); 15394 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15395 this._on( this.panels, { keydown: "_panelKeydown" } ); 15396 15397 this._focusable( this.tabs ); 15398 this._hoverable( this.tabs ); 15399 }, 15400 15401 _setupHeightStyle: function( heightStyle ) { 15402 var maxHeight, 15403 parent = this.element.parent(); 15404 15405 if ( heightStyle === "fill" ) { 15406 maxHeight = parent.height(); 15407 maxHeight -= this.element.outerHeight() - this.element.height(); 15408 15409 this.element.siblings( ":visible" ).each( function() { 15410 var elem = $( this ), 15411 position = elem.css( "position" ); 15412 15413 if ( position === "absolute" || position === "fixed" ) { 15414 return; 15415 } 15416 maxHeight -= elem.outerHeight( true ); 15417 } ); 15418 15419 this.element.children().not( this.panels ).each( function() { 15420 maxHeight -= $( this ).outerHeight( true ); 15421 } ); 15422 15423 this.panels.each( function() { 15424 $( this ).height( Math.max( 0, maxHeight - 15425 $( this ).innerHeight() + $( this ).height() ) ); 15426 } ) 15427 .css( "overflow", "auto" ); 15428 } else if ( heightStyle === "auto" ) { 15429 maxHeight = 0; 15430 this.panels.each( function() { 15431 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15432 } ).height( maxHeight ); 15433 } 15434 }, 15435 15436 _eventHandler: function( event ) { 15437 var options = this.options, 15438 active = this.active, 15439 anchor = $( event.currentTarget ), 15440 tab = anchor.closest( "li" ), 15441 clickedIsActive = tab[ 0 ] === active[ 0 ], 15442 collapsing = clickedIsActive && options.collapsible, 15443 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15444 toHide = !active.length ? $() : this._getPanelForTab( active ), 15445 eventData = { 15446 oldTab: active, 15447 oldPanel: toHide, 15448 newTab: collapsing ? $() : tab, 15449 newPanel: toShow 15450 }; 15451 15452 event.preventDefault(); 15453 15454 if ( tab.hasClass( "ui-state-disabled" ) || 15455 15456 // tab is already loading 15457 tab.hasClass( "ui-tabs-loading" ) || 15458 15459 // can't switch durning an animation 15460 this.running || 15461 15462 // click on active header, but not collapsible 15463 ( clickedIsActive && !options.collapsible ) || 15464 15465 // allow canceling activation 15466 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15467 return; 15468 } 15469 15470 options.active = collapsing ? false : this.tabs.index( tab ); 15471 15472 this.active = clickedIsActive ? $() : tab; 15473 if ( this.xhr ) { 15474 this.xhr.abort(); 15475 } 15476 15477 if ( !toHide.length && !toShow.length ) { 15478 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15479 } 15480 15481 if ( toShow.length ) { 15482 this.load( this.tabs.index( tab ), event ); 15483 } 15484 this._toggle( event, eventData ); 15485 }, 15486 15487 // Handles show/hide for selecting tabs 15488 _toggle: function( event, eventData ) { 15489 var that = this, 15490 toShow = eventData.newPanel, 15491 toHide = eventData.oldPanel; 15492 15493 this.running = true; 15494 15495 function complete() { 15496 that.running = false; 15497 that._trigger( "activate", event, eventData ); 15498 } 15499 15500 function show() { 15501 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 15502 15503 if ( toShow.length && that.options.show ) { 15504 that._show( toShow, that.options.show, complete ); 15505 } else { 15506 toShow.show(); 15507 complete(); 15508 } 15509 } 15510 15511 // Start out by hiding, then showing, then completing 15512 if ( toHide.length && this.options.hide ) { 15513 this._hide( toHide, this.options.hide, function() { 15514 that._removeClass( eventData.oldTab.closest( "li" ), 15515 "ui-tabs-active", "ui-state-active" ); 15516 show(); 15517 } ); 15518 } else { 15519 this._removeClass( eventData.oldTab.closest( "li" ), 15520 "ui-tabs-active", "ui-state-active" ); 15521 toHide.hide(); 15522 show(); 15523 } 15524 15525 toHide.attr( "aria-hidden", "true" ); 15526 eventData.oldTab.attr( { 15527 "aria-selected": "false", 15528 "aria-expanded": "false" 15529 } ); 15530 15531 // If we're switching tabs, remove the old tab from the tab order. 15532 // If we're opening from collapsed state, remove the previous tab from the tab order. 15533 // If we're collapsing, then keep the collapsing tab in the tab order. 15534 if ( toShow.length && toHide.length ) { 15535 eventData.oldTab.attr( "tabIndex", -1 ); 15536 } else if ( toShow.length ) { 15537 this.tabs.filter( function() { 15538 return $( this ).attr( "tabIndex" ) === 0; 15539 } ) 15540 .attr( "tabIndex", -1 ); 15541 } 15542 15543 toShow.attr( "aria-hidden", "false" ); 15544 eventData.newTab.attr( { 15545 "aria-selected": "true", 15546 "aria-expanded": "true", 15547 tabIndex: 0 15548 } ); 15549 }, 15550 15551 _activate: function( index ) { 15552 var anchor, 15553 active = this._findActive( index ); 15554 15555 // Trying to activate the already active panel 15556 if ( active[ 0 ] === this.active[ 0 ] ) { 15557 return; 15558 } 15559 15560 // Trying to collapse, simulate a click on the current active header 15561 if ( !active.length ) { 15562 active = this.active; 15563 } 15564 15565 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15566 this._eventHandler( { 15567 target: anchor, 15568 currentTarget: anchor, 15569 preventDefault: $.noop 15570 } ); 15571 }, 15572 15573 _findActive: function( index ) { 15574 return index === false ? $() : this.tabs.eq( index ); 15575 }, 15576 15577 _getIndex: function( index ) { 15578 15579 // meta-function to give users option to provide a href string instead of a numerical index. 15580 if ( typeof index === "string" ) { 15581 index = this.anchors.index( this.anchors.filter( "[href$='" + 15582
vendor: 17,737 bytes, lines 15582-16252
15582CSS.escape( index ) + "']" ) ); 15583 } 15584 15585 return index; 15586 }, 15587 15588 _destroy: function() { 15589 if ( this.xhr ) { 15590 this.xhr.abort(); 15591 } 15592 15593 this.tablist 15594 .removeAttr( "role" ) 15595 .off( this.eventNamespace ); 15596 15597 this.anchors 15598 .removeAttr( "role tabIndex" ) 15599 .removeUniqueId(); 15600 15601 this.tabs.add( this.panels ).each( function() { 15602 if ( $.data( this, "ui-tabs-destroy" ) ) { 15603 $( this ).remove(); 15604 } else { 15605 $( this ).removeAttr( "role tabIndex " + 15606 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 15607 } 15608 } ); 15609 15610 this.tabs.each( function() { 15611 var li = $( this ), 15612 prev = li.data( "ui-tabs-aria-controls" ); 15613 if ( prev ) { 15614 li 15615 .attr( "aria-controls", prev ) 15616 .removeData( "ui-tabs-aria-controls" ); 15617 } else { 15618 li.removeAttr( "aria-controls" ); 15619 } 15620 } ); 15621 15622 this.panels.show(); 15623 15624 if ( this.options.heightStyle !== "content" ) { 15625 this.panels.css( "height", "" ); 15626 } 15627 }, 15628 15629 enable: function( index ) { 15630 var disabled = this.options.disabled; 15631 if ( disabled === false ) { 15632 return; 15633 } 15634 15635 if ( index === undefined ) { 15636 disabled = false; 15637 } else { 15638 index = this._getIndex( index ); 15639 if ( Array.isArray( disabled ) ) { 15640 disabled = $.map( disabled, function( num ) { 15641 return num !== index ? num : null; 15642 } ); 15643 } else { 15644 disabled = $.map( this.tabs, function( li, num ) { 15645 return num !== index ? num : null; 15646 } ); 15647 } 15648 } 15649 this._setOptionDisabled( disabled ); 15650 }, 15651 15652 disable: function( index ) { 15653 var disabled = this.options.disabled; 15654 if ( disabled === true ) { 15655 return; 15656 } 15657 15658 if ( index === undefined ) { 15659 disabled = true; 15660 } else { 15661 index = this._getIndex( index ); 15662 if ( $.inArray( index, disabled ) !== -1 ) { 15663 return; 15664 } 15665 if ( Array.isArray( disabled ) ) { 15666 disabled = $.merge( [ index ], disabled ).sort(); 15667 } else { 15668 disabled = [ index ]; 15669 } 15670 } 15671 this._setOptionDisabled( disabled ); 15672 }, 15673 15674 load: function( index, event ) { 15675 index = this._getIndex( index ); 15676 var that = this, 15677 tab = this.tabs.eq( index ), 15678 anchor = tab.find( ".ui-tabs-anchor" ), 15679 panel = this._getPanelForTab( tab ), 15680 eventData = { 15681 tab: tab, 15682 panel: panel 15683 }, 15684 complete = function( jqXHR, status ) { 15685 if ( status === "abort" ) { 15686 that.panels.stop( false, true ); 15687 } 15688 15689 that._removeClass( tab, "ui-tabs-loading" ); 15690 panel.removeAttr( "aria-busy" ); 15691 15692 if ( jqXHR === that.xhr ) { 15693 delete that.xhr; 15694 } 15695 }; 15696 15697 // Not remote 15698 if ( this._isLocal( anchor[ 0 ] ) ) { 15699 return; 15700 } 15701 15702 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 15703 15704 if ( this.xhr.statusText !== "canceled" ) { 15705 this._addClass( tab, "ui-tabs-loading" ); 15706 panel.attr( "aria-busy", "true" ); 15707 15708 this.xhr 15709 .done( function( response, status, jqXHR ) { 15710 panel.html( response ); 15711 that._trigger( "load", event, eventData ); 15712 15713 complete( jqXHR, status ); 15714 } ) 15715 .fail( function( jqXHR, status ) { 15716 complete( jqXHR, status ); 15717 } ); 15718 } 15719 }, 15720 15721 _ajaxSettings: function( anchor, event, eventData ) { 15722 var that = this; 15723 return { 15724 url: anchor.attr( "href" ), 15725 beforeSend: function( jqXHR, settings ) { 15726 return that._trigger( "beforeLoad", event, 15727 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 15728 } 15729 }; 15730 }, 15731 15732 _getPanelForTab: function( tab ) { 15733 var id = $( tab ).attr( "aria-controls" ); 15734 return this.element.find( "#" + CSS.escape( id ) ); 15735 } 15736} ); 15737 15738// DEPRECATED 15739// TODO: Switch return back to widget declaration at top of file when this is removed 15740if ( $.uiBackCompat === true ) { 15741 15742 // Backcompat for ui-tab class (now ui-tabs-tab) 15743 $.widget( "ui.tabs", $.ui.tabs, { 15744 _processTabs: function() { 15745 this._superApply( arguments ); 15746 this._addClass( this.tabs, "ui-tab" ); 15747 } 15748 } ); 15749} 15750 15751var widgetsTabs = $.ui.tabs; 15752 15753 15754/*! 15755 * jQuery UI Tooltip 1.14.1 15756 * https://jqueryui.com 15757 * 15758 * Copyright OpenJS Foundation and other contributors 15759 * Released under the MIT license. 15760 * https://jquery.org/license 15761 */ 15762 15763//>>label: Tooltip 15764//>>group: Widgets 15765//>>description: Shows additional information for any element on hover or focus. 15766//>>docs: https://api.jqueryui.com/tooltip/ 15767//>>demos: https://jqueryui.com/tooltip/ 15768//>>css.structure: ../../themes/base/core.css 15769//>>css.structure: ../../themes/base/tooltip.css 15770//>>css.theme: ../../themes/base/theme.css 15771 15772 15773$.widget( "ui.tooltip", { 15774 version: "1.14.1", 15775 options: { 15776 classes: { 15777 "ui-tooltip": "ui-corner-all ui-widget-shadow" 15778 }, 15779 content: function() { 15780 var title = $( this ).attr( "title" ); 15781 15782 // Escape title, since we're going from an attribute to raw HTML 15783 return $( "<a>" ).text( title ).html(); 15784 }, 15785 hide: true, 15786 15787 // Disabled elements have inconsistent behavior across browsers (#8661) 15788 items: "[title]:not([disabled])", 15789 position: { 15790 my: "left top+15", 15791 at: "left bottom", 15792 collision: "flipfit flip" 15793 }, 15794 show: true, 15795 track: false, 15796 15797 // Callbacks 15798 close: null, 15799 open: null 15800 }, 15801 15802 _addDescribedBy: function( elem, id ) { 15803 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 15804 describedby.push( id ); 15805 elem 15806 .data( "ui-tooltip-id", id ) 15807 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 15808 }, 15809 15810 _removeDescribedBy: function( elem ) { 15811 var id = elem.data( "ui-tooltip-id" ), 15812 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 15813 index = $.inArray( id, describedby ); 15814 15815 if ( index !== -1 ) { 15816 describedby.splice( index, 1 ); 15817 } 15818 15819 elem.removeData( "ui-tooltip-id" ); 15820 describedby = String.prototype.trim.call( describedby.join( " " ) ); 15821 if ( describedby ) { 15822 elem.attr( "aria-describedby", describedby ); 15823 } else { 15824 elem.removeAttr( "aria-describedby" ); 15825 } 15826 }, 15827 15828 _create: function() { 15829 this._on( { 15830 mouseover: "open", 15831 focusin: "open" 15832 } ); 15833 15834 // IDs of generated tooltips, needed for destroy 15835 this.tooltips = {}; 15836 15837 // IDs of parent tooltips where we removed the title attribute 15838 this.parents = {}; 15839 15840 // Append the aria-live region so tooltips announce correctly 15841 this.liveRegion = $( "<div>" ) 15842 .attr( { 15843 role: "log", 15844 "aria-live": "assertive", 15845 "aria-relevant": "additions" 15846 } ) 15847 .appendTo( this.document[ 0 ].body ); 15848 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 15849 15850 this.disabledTitles = $( [] ); 15851 }, 15852 15853 _setOption: function( key, value ) { 15854 var that = this; 15855 15856 this._super( key, value ); 15857 15858 if ( key === "content" ) { 15859 $.each( this.tooltips, function( id, tooltipData ) { 15860 that._updateContent( tooltipData.element ); 15861 } ); 15862 } 15863 }, 15864 15865 _setOptionDisabled: function( value ) { 15866 this[ value ? "_disable" : "_enable" ](); 15867 }, 15868 15869 _disable: function() { 15870 var that = this; 15871 15872 // Close open tooltips 15873 $.each( this.tooltips, function( id, tooltipData ) { 15874 var event = $.Event( "blur" ); 15875 event.target = event.currentTarget = tooltipData.element[ 0 ]; 15876 that.close( event, true ); 15877 } ); 15878 15879 // Remove title attributes to prevent native tooltips 15880 this.disabledTitles = this.disabledTitles.add( 15881 this.element.find( this.options.items ).addBack() 15882 .filter( function() { 15883 var element = $( this ); 15884 if ( element.is( "[title]" ) ) { 15885 return element 15886 .data( "ui-tooltip-title", element.attr( "title" ) ) 15887 .removeAttr( "title" ); 15888 } 15889 } ) 15890 ); 15891 }, 15892 15893 _enable: function() { 15894 15895 // restore title attributes 15896 this.disabledTitles.each( function() { 15897 var element = $( this ); 15898 if ( element.data( "ui-tooltip-title" ) ) { 15899 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15900 } 15901 } ); 15902 this.disabledTitles = $( [] ); 15903 }, 15904 15905 open: function( event ) { 15906 var that = this, 15907 target = $( event ? event.target : this.element ) 15908 15909 // we need closest here due to mouseover bubbling, 15910 // but always pointing at the same event target 15911 .closest( this.options.items ); 15912 15913 // No element to show a tooltip for or the tooltip is already open 15914 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 15915 return; 15916 } 15917 15918 if ( target.attr( "title" ) ) { 15919 target.data( "ui-tooltip-title", target.attr( "title" ) ); 15920 } 15921 15922 target.data( "ui-tooltip-open", true ); 15923 15924 // Kill parent tooltips, custom or native, for hover 15925 if ( event && event.type === "mouseover" ) { 15926 target.parents().each( function() { 15927 var parent = $( this ), 15928 blurEvent; 15929 if ( parent.data( "ui-tooltip-open" ) ) { 15930 blurEvent = $.Event( "blur" ); 15931 blurEvent.target = blurEvent.currentTarget = this; 15932 that.close( blurEvent, true ); 15933 } 15934 if ( parent.attr( "title" ) ) { 15935 parent.uniqueId(); 15936 that.parents[ this.id ] = { 15937 element: this, 15938 title: parent.attr( "title" ) 15939 }; 15940 parent.attr( "title", "" ); 15941 } 15942 } ); 15943 } 15944 15945 this._registerCloseHandlers( event, target ); 15946 this._updateContent( target, event ); 15947 }, 15948 15949 _updateContent: function( target, event ) { 15950 var content, 15951 contentOption = this.options.content, 15952 that = this, 15953 eventType = event ? event.type : null; 15954 15955 if ( typeof contentOption === "string" || contentOption.nodeType || 15956 contentOption.jquery ) { 15957 return this._open( event, target, contentOption ); 15958 } 15959 15960 content = contentOption.call( target[ 0 ], function( response ) { 15961 15962 // Ignore async response if tooltip was closed already 15963 if ( !target.data( "ui-tooltip-open" ) ) { 15964 return; 15965 } 15966 15967 // JQuery creates a special event for focusin when it doesn't 15968 // exist natively. To improve performance, the native event 15969 // object is reused and the type is changed. Therefore, we can't 15970 // rely on the type being correct after the event finished 15971 // bubbling, so we set it back to the previous value. (#8740) 15972 if ( event ) { 15973 event.type = eventType; 15974 } 15975 that._open( event, target, response ); 15976 } ); 15977 if ( content ) { 15978 this._open( event, target, content ); 15979 } 15980 }, 15981 15982 _open: function( event, target, content ) { 15983 var tooltipData, tooltip, delayedShow, a11yContent, 15984 positionOption = $.extend( {}, this.options.position ); 15985 15986 if ( !content ) { 15987 return; 15988 } 15989 15990 // Content can be updated multiple times. If the tooltip already 15991 // exists, then just update the content and bail. 15992 tooltipData = this._find( target ); 15993 if ( tooltipData ) { 15994 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 15995 return; 15996 } 15997 15998 // If we have a title, clear it to prevent the native tooltip 15999 // we have to check first to avoid defining a title if none exists 16000 // (we don't want to cause an element to start matching [title]) 16001 // 16002 // We use removeAttr only for key events, to allow IE to export the correct 16003 // accessible attributes. For mouse events, set to empty string to avoid 16004 // native tooltip showing up (happens only when removing inside mouseover). 16005 if ( target.is( "[title]" ) ) { 16006 if ( event && event.type === "mouseover" ) { 16007 target.attr( "title", "" ); 16008 } else { 16009 target.removeAttr( "title" ); 16010 } 16011 } 16012 16013 tooltipData = this._tooltip( target ); 16014 tooltip = tooltipData.tooltip; 16015 this._addDescribedBy( target, tooltip.attr( "id" ) ); 16016 tooltip.find( ".ui-tooltip-content" ).html( content ); 16017 16018 // Support: Voiceover on OS X, JAWS on IE <= 9 16019 // JAWS announces deletions even when aria-relevant="additions" 16020 // Voiceover will sometimes re-read the entire log region's contents from the beginning 16021 this.liveRegion.children().hide(); 16022 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 16023 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 16024 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 16025 a11yContent.appendTo( this.liveRegion ); 16026 16027 function position( event ) { 16028 positionOption.of = event; 16029 if ( tooltip.is( ":hidden" ) ) { 16030 return; 16031 } 16032 tooltip.position( positionOption ); 16033 } 16034 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 16035 this._on( this.document, { 16036 mousemove: position 16037 } ); 16038 16039 // trigger once to override element-relative positioning 16040 position( event ); 16041 } else { 16042 tooltip.position( $.extend( { 16043 of: target 16044 }, this.options.position ) ); 16045 } 16046 16047 tooltip.hide(); 16048 16049 this._show( tooltip, this.options.show ); 16050 16051 // Handle tracking tooltips that are shown with a delay (#8644). As soon 16052 // as the tooltip is visible, position the tooltip using the most recent 16053 // event. 16054 // Adds the check to add the timers only when both delay and track options are set (#14682) 16055 if ( this.options.track && this.options.show && this.options.show.delay ) { 16056 delayedShow = this.delayedShow = setInterval( function() { 16057 if ( tooltip.is( ":visible" ) ) { 16058 position( positionOption.of ); 16059 clearInterval( delayedShow ); 16060 } 16061 }, 13 ); 16062 } 16063 16064 this._trigger( "open", event, { tooltip: tooltip } ); 16065 }, 16066 16067 _registerCloseHandlers: function( event, target ) { 16068 var events = { 16069 keyup: function( event ) { 16070 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 16071 var fakeEvent = $.Event( event ); 16072 fakeEvent.currentTarget = target[ 0 ]; 16073 this.close( fakeEvent, true ); 16074 } 16075 } 16076 }; 16077 16078 // Only bind remove handler for delegated targets. Non-delegated 16079 // tooltips will handle this in destroy. 16080 if ( target[ 0 ] !== this.element[ 0 ] ) { 16081 events.remove = function() { 16082 var targetElement = this._find( target ); 16083 if ( targetElement ) { 16084 this._removeTooltip( targetElement.tooltip ); 16085 } 16086 }; 16087 } 16088 16089 if ( !event || event.type === "mouseover" ) { 16090 events.mouseleave = "close"; 16091 } 16092 if ( !event || event.type === "focusin" ) { 16093 events.focusout = "close"; 16094 } 16095 this._on( true, target, events ); 16096 }, 16097 16098 close: function( event ) { 16099 var tooltip, 16100 that = this, 16101 target = $( event ? event.currentTarget : this.element ), 16102 tooltipData = this._find( target ); 16103 16104 // The tooltip may already be closed 16105 if ( !tooltipData ) { 16106 16107 // We set ui-tooltip-open immediately upon open (in open()), but only set the 16108 // additional data once there's actually content to show (in _open()). So even if the 16109 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 16110 // the period between open() and _open(). 16111 target.removeData( "ui-tooltip-open" ); 16112 return; 16113 } 16114 16115 tooltip = tooltipData.tooltip; 16116 16117 // Disabling closes the tooltip, so we need to track when we're closing 16118 // to avoid an infinite loop in case the tooltip becomes disabled on close 16119 if ( tooltipData.closing ) { 16120 return; 16121 } 16122 16123 // Clear the interval for delayed tracking tooltips 16124 clearInterval( this.delayedShow ); 16125 16126 // Only set title if we had one before (see comment in _open()) 16127 // If the title attribute has changed since open(), don't restore 16128 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16129 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16130 } 16131 16132 this._removeDescribedBy( target ); 16133 16134 tooltipData.hiding = true; 16135 tooltip.stop( true ); 16136 this._hide( tooltip, this.options.hide, function() { 16137 that._removeTooltip( $( this ) ); 16138 } ); 16139 16140 target.removeData( "ui-tooltip-open" ); 16141 this._off( target, "mouseleave focusout keyup" ); 16142 16143 // Remove 'remove' binding only on delegated targets 16144 if ( target[ 0 ] !== this.element[ 0 ] ) { 16145 this._off( target, "remove" ); 16146 } 16147 this._off( this.document, "mousemove" ); 16148 16149 if ( event && event.type === "mouseleave" ) { 16150 $.each( this.parents, function( id, parent ) { 16151 $( parent.element ).attr( "title", parent.title ); 16152 delete that.parents[ id ]; 16153 } ); 16154 } 16155 16156 tooltipData.closing = true; 16157 this._trigger( "close", event, { tooltip: tooltip } ); 16158 if ( !tooltipData.hiding ) { 16159 tooltipData.closing = false; 16160 } 16161 }, 16162 16163 _tooltip: function( element ) { 16164 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 16165 content = $( "<div>" ).appendTo( tooltip ), 16166 id = tooltip.uniqueId().attr( "id" ); 16167 16168 this._addClass( content, "ui-tooltip-content" ); 16169 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 16170 16171 tooltip.appendTo( this._appendTo( element ) ); 16172 16173 return this.tooltips[ id ] = { 16174 element: element, 16175 tooltip: tooltip 16176 }; 16177 }, 16178 16179 _find: function( target ) { 16180 var id = target.data( "ui-tooltip-id" ); 16181 return id ? this.tooltips[ id ] : null; 16182 }, 16183 16184 _removeTooltip: function( tooltip ) { 16185 16186 // Clear the interval for delayed tracking tooltips 16187 clearInterval( this.delayedShow ); 16188 16189 tooltip.remove(); 16190 delete this.tooltips[ tooltip.attr( "id" ) ]; 16191 }, 16192 16193 _appendTo: function( target ) { 16194 var element = target.closest( ".ui-front, dialog" ); 16195 16196 if ( !element.length ) { 16197 element = this.document[ 0 ].body; 16198 } 16199 16200 return element; 16201 }, 16202 16203 _destroy: function() { 16204 var that = this; 16205 16206 // Close open tooltips 16207 $.each( this.tooltips, function( id, tooltipData ) { 16208 16209 // Delegate to close method to handle common cleanup 16210 var event = $.Event( "blur" ), 16211 element = tooltipData.element; 16212 event.target = event.currentTarget = element[ 0 ]; 16213 that.close( event, true ); 16214 16215 // Remove immediately; destroying an open tooltip doesn't use the 16216 // hide animation 16217 $( "#" + id ).remove(); 16218 16219 // Restore the title 16220 if ( element.data( "ui-tooltip-title" ) ) { 16221 16222 // If the title attribute has changed since open(), don't restore 16223 if ( !element.attr( "title" ) ) { 16224 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16225 } 16226 element.removeData( "ui-tooltip-title" ); 16227 } 16228 } ); 16229 this.liveRegion.remove(); 16230 } 16231} ); 16232 16233// DEPRECATED 16234// TODO: Switch return back to widget declaration at top of file when this is removed 16235if ( $.uiBackCompat === true ) { 16236 16237 // Backcompat for tooltipClass option 16238 $.widget( "ui.tooltip", $.ui.tooltip, { 16239 options: { 16240 tooltipClass: null 16241 }, 16242 _tooltip: function() { 16243 var tooltipData = this._superApply( arguments ); 16244 if ( this.options.tooltipClass ) { 16245 tooltipData.tooltip.addClass( this.options.tooltipClass ); 16246 } 16247 return tooltipData; 16248 } 16249 } ); 16250} 16251 16252var widgetsTooltip = $.ui.tooltip
vendor: 16,220 bytes, lines 16252-16941
16252; 16253 16254 16255 16256// Create a local jQuery because jQuery Color relies on it and the 16257// global may not exist with AMD and a custom build (#10199). 16258// This module is a noop if used as a regular AMD module. 16259// eslint-disable-next-line no-unused-vars 16260var jQuery = $; 16261 16262 16263/*! 16264 * jQuery Color Animations v3.0.0 16265 * https://github.com/jquery/jquery-color 16266 * 16267 * Copyright OpenJS Foundation and other contributors 16268 * Released under the MIT license. 16269 * https://jquery.org/license 16270 * 16271 * Date: Wed May 15 16:49:44 2024 +0200 16272 */ 16273 16274 16275 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 16276 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 16277 16278 class2type = {}, 16279 toString = class2type.toString, 16280 16281 // plusequals test for += 100 -= 100 16282 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 16283 16284 // a set of RE's that can match strings and generate color tuples. 16285 stringParsers = [ { 16286 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16287 parse: function( execResult ) { 16288 return [ 16289 execResult[ 1 ], 16290 execResult[ 2 ], 16291 execResult[ 3 ], 16292 execResult[ 4 ] 16293 ]; 16294 } 16295 }, { 16296 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16297 parse: function( execResult ) { 16298 return [ 16299 execResult[ 1 ] * 2.55, 16300 execResult[ 2 ] * 2.55, 16301 execResult[ 3 ] * 2.55, 16302 execResult[ 4 ] 16303 ]; 16304 } 16305 }, { 16306 16307 // this regex ignores A-F because it's compared against an already lowercased string 16308 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 16309 parse: function( execResult ) { 16310 return [ 16311 parseInt( execResult[ 1 ], 16 ), 16312 parseInt( execResult[ 2 ], 16 ), 16313 parseInt( execResult[ 3 ], 16 ), 16314 execResult[ 4 ] ? 16315 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 16316 1 16317 ]; 16318 } 16319 }, { 16320 16321 // this regex ignores A-F because it's compared against an already lowercased string 16322 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 16323 parse: function( execResult ) { 16324 return [ 16325 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 16326 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 16327 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 16328 execResult[ 4 ] ? 16329 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 16330 .toFixed( 2 ) : 16331 1 16332 ]; 16333 } 16334 }, { 16335 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16336 space: "hsla", 16337 parse: function( execResult ) { 16338 return [ 16339 execResult[ 1 ], 16340 execResult[ 2 ] / 100, 16341 execResult[ 3 ] / 100, 16342 execResult[ 4 ] 16343 ]; 16344 } 16345 } ], 16346 16347 // jQuery.Color( ) 16348 color = jQuery.Color = function( color, green, blue, alpha ) { 16349 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 16350 }, 16351 spaces = { 16352 rgba: { 16353 props: { 16354 red: { 16355 idx: 0, 16356 type: "byte" 16357 }, 16358 green: { 16359 idx: 1, 16360 type: "byte" 16361 }, 16362 blue: { 16363 idx: 2, 16364 type: "byte" 16365 } 16366 } 16367 }, 16368 16369 hsla: { 16370 props: { 16371 hue: { 16372 idx: 0, 16373 type: "degrees" 16374 }, 16375 saturation: { 16376 idx: 1, 16377 type: "percent" 16378 }, 16379 lightness: { 16380 idx: 2, 16381 type: "percent" 16382 } 16383 } 16384 } 16385 }, 16386 propTypes = { 16387 "byte": { 16388 floor: true, 16389 max: 255 16390 }, 16391 "percent": { 16392 max: 1 16393 }, 16394 "degrees": { 16395 mod: 360, 16396 floor: true 16397 } 16398 }, 16399 16400 // colors = jQuery.Color.names 16401 colors, 16402 16403 // local aliases of functions called often 16404 each = jQuery.each; 16405 16406// define cache name and alpha properties 16407// for rgba and hsla spaces 16408each( spaces, function( spaceName, space ) { 16409 space.cache = "_" + spaceName; 16410 space.props.alpha = { 16411 idx: 3, 16412 type: "percent", 16413 def: 1 16414 }; 16415} ); 16416 16417// Populate the class2type map 16418jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 16419 function( _i, name ) { 16420 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 16421 } ); 16422 16423function getType( obj ) { 16424 if ( obj == null ) { 16425 return obj + ""; 16426 } 16427 16428 return typeof obj === "object" ? 16429 class2type[ toString.call( obj ) ] || "object" : 16430 typeof obj; 16431} 16432 16433function clamp( value, prop, allowEmpty ) { 16434 var type = propTypes[ prop.type ] || {}; 16435 16436 if ( value == null ) { 16437 return ( allowEmpty || !prop.def ) ? null : prop.def; 16438 } 16439 16440 // ~~ is an short way of doing floor for positive numbers 16441 value = type.floor ? ~~value : parseFloat( value ); 16442 16443 if ( type.mod ) { 16444 16445 // we add mod before modding to make sure that negatives values 16446 // get converted properly: -10 -> 350 16447 return ( value + type.mod ) % type.mod; 16448 } 16449 16450 // for now all property types without mod have min and max 16451 return Math.min( type.max, Math.max( 0, value ) ); 16452} 16453 16454function stringParse( string ) { 16455 var inst = color(), 16456 rgba = inst._rgba = []; 16457 16458 string = string.toLowerCase(); 16459 16460 each( stringParsers, function( _i, parser ) { 16461 var parsed, 16462 match = parser.re.exec( string ), 16463 values = match && parser.parse( match ), 16464 spaceName = parser.space || "rgba"; 16465 16466 if ( values ) { 16467 parsed = inst[ spaceName ]( values ); 16468 16469 // if this was an rgba parse the assignment might happen twice 16470 // oh well.... 16471 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 16472 rgba = inst._rgba = parsed._rgba; 16473 16474 // exit each( stringParsers ) here because we matched 16475 return false; 16476 } 16477 } ); 16478 16479 // Found a stringParser that handled it 16480 if ( rgba.length ) { 16481 16482 // if this came from a parsed string, force "transparent" when alpha is 0 16483 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 16484 if ( rgba.join() === "0,0,0,0" ) { 16485 jQuery.extend( rgba, colors.transparent ); 16486 } 16487 return inst; 16488 } 16489 16490 // named colors 16491 return colors[ string ]; 16492} 16493 16494color.fn = jQuery.extend( color.prototype, { 16495 parse: function( red, green, blue, alpha ) { 16496 if ( red === undefined ) { 16497 this._rgba = [ null, null, null, null ]; 16498 return this; 16499 } 16500 if ( red.jquery || red.nodeType ) { 16501 red = jQuery( red ).css( green ); 16502 green = undefined; 16503 } 16504 16505 var inst = this, 16506 type = getType( red ), 16507 rgba = this._rgba = []; 16508 16509 // more than 1 argument specified - assume ( red, green, blue, alpha ) 16510 if ( green !== undefined ) { 16511 red = [ red, green, blue, alpha ]; 16512 type = "array"; 16513 } 16514 16515 if ( type === "string" ) { 16516 return this.parse( stringParse( red ) || colors._default ); 16517 } 16518 16519 if ( type === "array" ) { 16520 each( spaces.rgba.props, function( _key, prop ) { 16521 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 16522 } ); 16523 return this; 16524 } 16525 16526 if ( type === "object" ) { 16527 if ( red instanceof color ) { 16528 each( spaces, function( _spaceName, space ) { 16529 if ( red[ space.cache ] ) { 16530 inst[ space.cache ] = red[ space.cache ].slice(); 16531 } 16532 } ); 16533 } else { 16534 each( spaces, function( _spaceName, space ) { 16535 var cache = space.cache; 16536 each( space.props, function( key, prop ) { 16537 16538 // if the cache doesn't exist, and we know how to convert 16539 if ( !inst[ cache ] && space.to ) { 16540 16541 // if the value was null, we don't need to copy it 16542 // if the key was alpha, we don't need to copy it either 16543 if ( key === "alpha" || red[ key ] == null ) { 16544 return; 16545 } 16546 inst[ cache ] = space.to( inst._rgba ); 16547 } 16548 16549 // this is the only case where we allow nulls for ALL properties. 16550 // call clamp with alwaysAllowEmpty 16551 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 16552 } ); 16553 16554 // everything defined but alpha? 16555 if ( inst[ cache ] && jQuery.inArray( 16556 null, 16557 inst[ cache ].slice( 0, 3 ) 16558 ) < 0 ) { 16559 16560 // use the default of 1 16561 if ( inst[ cache ][ 3 ] == null ) { 16562 inst[ cache ][ 3 ] = 1; 16563 } 16564 16565 if ( space.from ) { 16566 inst._rgba = space.from( inst[ cache ] ); 16567 } 16568 } 16569 } ); 16570 } 16571 return this; 16572 } 16573 }, 16574 is: function( compare ) { 16575 var is = color( compare ), 16576 same = true, 16577 inst = this; 16578 16579 each( spaces, function( _, space ) { 16580 var localCache, 16581 isCache = is[ space.cache ]; 16582 if ( isCache ) { 16583 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 16584 each( space.props, function( _, prop ) { 16585 if ( isCache[ prop.idx ] != null ) { 16586 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 16587 return same; 16588 } 16589 } ); 16590 } 16591 return same; 16592 } ); 16593 return same; 16594 }, 16595 _space: function() { 16596 var used = [], 16597 inst = this; 16598 each( spaces, function( spaceName, space ) { 16599 if ( inst[ space.cache ] ) { 16600 used.push( spaceName ); 16601 } 16602 } ); 16603 return used.pop(); 16604 }, 16605 transition: function( other, distance ) { 16606 var end = color( other ), 16607 spaceName = end._space(), 16608 space = spaces[ spaceName ], 16609 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 16610 start = startColor[ space.cache ] || space.to( startColor._rgba ), 16611 result = start.slice(); 16612 16613 end = end[ space.cache ]; 16614 each( space.props, function( _key, prop ) { 16615 var index = prop.idx, 16616 startValue = start[ index ], 16617 endValue = end[ index ], 16618 type = propTypes[ prop.type ] || {}; 16619 16620 // if null, don't override start value 16621 if ( endValue === null ) { 16622 return; 16623 } 16624 16625 // if null - use end 16626 if ( startValue === null ) { 16627 result[ index ] = endValue; 16628 } else { 16629 if ( type.mod ) { 16630 if ( endValue - startValue > type.mod / 2 ) { 16631 startValue += type.mod; 16632 } else if ( startValue - endValue > type.mod / 2 ) { 16633 startValue -= type.mod; 16634 } 16635 } 16636 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 16637 } 16638 } ); 16639 return this[ spaceName ]( result ); 16640 }, 16641 blend: function( opaque ) { 16642 16643 // if we are already opaque - return ourself 16644 if ( this._rgba[ 3 ] === 1 ) { 16645 return this; 16646 } 16647 16648 var rgb = this._rgba.slice(), 16649 a = rgb.pop(), 16650 blend = color( opaque )._rgba; 16651 16652 return color( jQuery.map( rgb, function( v, i ) { 16653 return ( 1 - a ) * blend[ i ] + a * v; 16654 } ) ); 16655 }, 16656 toRgbaString: function() { 16657 var prefix = "rgba(", 16658 rgba = jQuery.map( this._rgba, function( v, i ) { 16659 if ( v != null ) { 16660 return v; 16661 } 16662 return i > 2 ? 1 : 0; 16663 } ); 16664 16665 if ( rgba[ 3 ] === 1 ) { 16666 rgba.pop(); 16667 prefix = "rgb("; 16668 } 16669 16670 return prefix + rgba.join( ", " ) + ")"; 16671 }, 16672 toHslaString: function() { 16673 var prefix = "hsla(", 16674 hsla = jQuery.map( this.hsla(), function( v, i ) { 16675 if ( v == null ) { 16676 v = i > 2 ? 1 : 0; 16677 } 16678 16679 // catch 1 and 2 16680 if ( i && i < 3 ) { 16681 v = Math.round( v * 100 ) + "%"; 16682 } 16683 return v; 16684 } ); 16685 16686 if ( hsla[ 3 ] === 1 ) { 16687 hsla.pop(); 16688 prefix = "hsl("; 16689 } 16690 return prefix + hsla.join( ", " ) + ")"; 16691 }, 16692 toHexString: function( includeAlpha ) { 16693 var rgba = this._rgba.slice(), 16694 alpha = rgba.pop(); 16695 16696 if ( includeAlpha ) { 16697 rgba.push( ~~( alpha * 255 ) ); 16698 } 16699 16700 return "#" + jQuery.map( rgba, function( v ) { 16701 16702 // default to 0 when nulls exist 16703 return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 ); 16704 } ).join( "" ); 16705 }, 16706 toString: function() { 16707 return this.toRgbaString(); 16708 } 16709} ); 16710color.fn.parse.prototype = color.fn; 16711 16712// hsla conversions adapted from: 16713// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 16714 16715function hue2rgb( p, q, h ) { 16716 h = ( h + 1 ) % 1; 16717 if ( h * 6 < 1 ) { 16718 return p + ( q - p ) * h * 6; 16719 } 16720 if ( h * 2 < 1 ) { 16721 return q; 16722 } 16723 if ( h * 3 < 2 ) { 16724 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 16725 } 16726 return p; 16727} 16728 16729spaces.hsla.to = function( rgba ) { 16730 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 16731 return [ null, null, null, rgba[ 3 ] ]; 16732 } 16733 var r = rgba[ 0 ] / 255, 16734 g = rgba[ 1 ] / 255, 16735 b = rgba[ 2 ] / 255, 16736 a = rgba[ 3 ], 16737 max = Math.max( r, g, b ), 16738 min = Math.min( r, g, b ), 16739 diff = max - min, 16740 add = max + min, 16741 l = add * 0.5, 16742 h, s; 16743 16744 if ( min === max ) { 16745 h = 0; 16746 } else if ( r === max ) { 16747 h = ( 60 * ( g - b ) / diff ) + 360; 16748 } else if ( g === max ) { 16749 h = ( 60 * ( b - r ) / diff ) + 120; 16750 } else { 16751 h = ( 60 * ( r - g ) / diff ) + 240; 16752 } 16753 16754 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 16755 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 16756 if ( diff === 0 ) { 16757 s = 0; 16758 } else if ( l <= 0.5 ) { 16759 s = diff / add; 16760 } else { 16761 s = diff / ( 2 - add ); 16762 } 16763 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 16764}; 16765 16766spaces.hsla.from = function( hsla ) { 16767 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 16768 return [ null, null, null, hsla[ 3 ] ]; 16769 } 16770 var h = hsla[ 0 ] / 360, 16771 s = hsla[ 1 ], 16772 l = hsla[ 2 ], 16773 a = hsla[ 3 ], 16774 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 16775 p = 2 * l - q; 16776 16777 return [ 16778 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 16779 Math.round( hue2rgb( p, q, h ) * 255 ), 16780 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 16781 a 16782 ]; 16783}; 16784 16785 16786each( spaces, function( spaceName, space ) { 16787 var props = space.props, 16788 cache = space.cache, 16789 to = space.to, 16790 from = space.from; 16791 16792 // makes rgba() and hsla() 16793 color.fn[ spaceName ] = function( value ) { 16794 16795 // generate a cache for this space if it doesn't exist 16796 if ( to && !this[ cache ] ) { 16797 this[ cache ] = to( this._rgba ); 16798 } 16799 if ( value === undefined ) { 16800 return this[ cache ].slice(); 16801 } 16802 16803 var ret, 16804 type = getType( value ), 16805 arr = ( type === "array" || type === "object" ) ? value : arguments, 16806 local = this[ cache ].slice(); 16807 16808 each( props, function( key, prop ) { 16809 var val = arr[ type === "object" ? key : prop.idx ]; 16810 if ( val == null ) { 16811 val = local[ prop.idx ]; 16812 } 16813 local[ prop.idx ] = clamp( val, prop ); 16814 } ); 16815 16816 if ( from ) { 16817 ret = color( from( local ) ); 16818 ret[ cache ] = local; 16819 return ret; 16820 } else { 16821 return color( local ); 16822 } 16823 }; 16824 16825 // makes red() green() blue() alpha() hue() saturation() lightness() 16826 each( props, function( key, prop ) { 16827 16828 // alpha is included in more than one space 16829 if ( color.fn[ key ] ) { 16830 return; 16831 } 16832 color.fn[ key ] = function( value ) { 16833 var local, cur, match, fn, 16834 vtype = getType( value ); 16835 16836 if ( key === "alpha" ) { 16837 fn = this._hsla ? "hsla" : "rgba"; 16838 } else { 16839 fn = spaceName; 16840 } 16841 local = this[ fn ](); 16842 cur = local[ prop.idx ]; 16843 16844 if ( vtype === "undefined" ) { 16845 return cur; 16846 } 16847 16848 if ( vtype === "function" ) { 16849 value = value.call( this, cur ); 16850 vtype = getType( value ); 16851 } 16852 if ( value == null && prop.empty ) { 16853 return this; 16854 } 16855 if ( vtype === "string" ) { 16856 match = rplusequals.exec( value ); 16857 if ( match ) { 16858 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 16859 } 16860 } 16861 local[ prop.idx ] = value; 16862 return this[ fn ]( local ); 16863 }; 16864 } ); 16865} ); 16866 16867// add cssHook and .fx.step function for each named hook. 16868// accept a space separated string of properties 16869color.hook = function( hook ) { 16870 var hooks = hook.split( " " ); 16871 each( hooks, function( _i, hook ) { 16872 jQuery.cssHooks[ hook ] = { 16873 set: function( elem, value ) { 16874 var parsed; 16875 16876 if ( value !== "transparent" && 16877 ( getType( value ) !== "string" || 16878 ( parsed = stringParse( value ) ) ) ) { 16879 value = color( parsed || value ); 16880 value = value.toRgbaString(); 16881 } 16882 elem.style[ hook ] = value; 16883 } 16884 }; 16885 jQuery.fx.step[ hook ] = function( fx ) { 16886 if ( !fx.colorInit ) { 16887 fx.start = color( fx.elem, hook ); 16888 fx.end = color( fx.end ); 16889 fx.colorInit = true; 16890 } 16891 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 16892 }; 16893 } ); 16894 16895}; 16896 16897color.hook( stepHooks ); 16898 16899jQuery.cssHooks.borderColor = { 16900 expand: function( value ) { 16901 var expanded = {}; 16902 16903 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 16904 expanded[ "border" + part + "Color" ] = value; 16905 } ); 16906 return expanded; 16907 } 16908}; 16909 16910// Basic color names only. 16911// Usage of any of the other color names requires adding yourself or including 16912// jquery.color.svg-names.js. 16913colors = jQuery.Color.names = { 16914 16915 // 4.1. Basic color keywords 16916 aqua: "#00ffff", 16917 black: "#000000", 16918 blue: "#0000ff", 16919 fuchsia: "#ff00ff", 16920 gray: "#808080", 16921 green: "#008000", 16922 lime: "#00ff00", 16923 maroon: "#800000", 16924 navy: "#000080", 16925 olive: "#808000", 16926 purple: "#800080", 16927 red: "#ff0000", 16928 silver: "#c0c0c0", 16929 teal: "#008080", 16930 white: "#ffffff", 16931 yellow: "#ffff00", 16932 16933 // 4.2.3. "transparent" color keyword 16934 transparent: [ null, null, null, 0 ], 16935 16936 _default: "#ffffff" 16937}; 16938 16939 16940/*! 16941 * jQuery UI Effects 1.14.
169411 16942 * https://jqueryui.com 16943 * 16944 * Copyright OpenJS Foundation and other contributors 16945 * Released under the MIT license. 16946 * https://jquery.org/license 16947 */ 16948 16949//>>label: Effects Core 16950//>>group: Effects 16951/* eslint-disable max-len */ 16952//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 16953/* eslint-enable max-len */
vendor: 7,523 bytes, lines 16953-17243
16953 16954//>>docs: https://api.jqueryui.com/category/effects-core/ 16955//>>demos: https://jqueryui.com/effect/ 16956 16957 16958var dataSpace = "ui-effects-", 16959 dataSpaceStyle = "ui-effects-style", 16960 dataSpaceAnimated = "ui-effects-animated"; 16961 16962$.effects = { 16963 effect: {} 16964}; 16965 16966/******************************************************************************/ 16967/****************************** CLASS ANIMATIONS ******************************/ 16968/******************************************************************************/ 16969( function() { 16970 16971var classAnimationActions = [ "add", "remove", "toggle" ], 16972 shorthandStyles = { 16973 border: 1, 16974 borderBottom: 1, 16975 borderColor: 1, 16976 borderLeft: 1, 16977 borderRight: 1, 16978 borderTop: 1, 16979 borderWidth: 1, 16980 margin: 1, 16981 padding: 1 16982 }; 16983 16984$.each( 16985 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 16986 function( _, prop ) { 16987 $.fx.step[ prop ] = function( fx ) { 16988 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 16989 jQuery.style( fx.elem, prop, fx.end ); 16990 fx.setAttr = true; 16991 } 16992 }; 16993 } 16994); 16995 16996function camelCase( string ) { 16997 return string.replace( /-([\da-z])/gi, function( all, letter ) { 16998 return letter.toUpperCase(); 16999 } ); 17000} 17001 17002function getElementStyles( elem ) { 17003 var key, len, 17004 style = elem.ownerDocument.defaultView.getComputedStyle( elem ), 17005 styles = {}; 17006 17007 len = style.length; 17008 while ( len-- ) { 17009 key = style[ len ]; 17010 if ( typeof style[ key ] === "string" ) { 17011 styles[ camelCase( key ) ] = style[ key ]; 17012 } 17013 } 17014 17015 return styles; 17016} 17017 17018function styleDifference( oldStyle, newStyle ) { 17019 var diff = {}, 17020 name, value; 17021 17022 for ( name in newStyle ) { 17023 value = newStyle[ name ]; 17024 if ( oldStyle[ name ] !== value ) { 17025 if ( !shorthandStyles[ name ] ) { 17026 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 17027 diff[ name ] = value; 17028 } 17029 } 17030 } 17031 } 17032 17033 return diff; 17034} 17035 17036$.effects.animateClass = function( value, duration, easing, callback ) { 17037 var o = $.speed( duration, easing, callback ); 17038 17039 return this.queue( function() { 17040 var animated = $( this ), 17041 baseClass = animated.attr( "class" ) || "", 17042 applyClassChange, 17043 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 17044 17045 // Map the animated objects to store the original styles. 17046 allAnimations = allAnimations.map( function() { 17047 var el = $( this ); 17048 return { 17049 el: el, 17050 start: getElementStyles( this ) 17051 }; 17052 } ); 17053 17054 // Apply class change 17055 applyClassChange = function() { 17056 $.each( classAnimationActions, function( i, action ) { 17057 if ( value[ action ] ) { 17058 animated[ action + "Class" ]( value[ action ] ); 17059 } 17060 } ); 17061 }; 17062 applyClassChange(); 17063 17064 // Map all animated objects again - calculate new styles and diff 17065 allAnimations = allAnimations.map( function() { 17066 this.end = getElementStyles( this.el[ 0 ] ); 17067 this.diff = styleDifference( this.start, this.end ); 17068 return this; 17069 } ); 17070 17071 // Apply original class 17072 animated.attr( "class", baseClass ); 17073 17074 // Map all animated objects again - this time collecting a promise 17075 allAnimations = allAnimations.map( function() { 17076 var styleInfo = this, 17077 dfd = $.Deferred(), 17078 opts = $.extend( {}, o, { 17079 queue: false, 17080 complete: function() { 17081 dfd.resolve( styleInfo ); 17082 } 17083 } ); 17084 17085 this.el.animate( this.diff, opts ); 17086 return dfd.promise(); 17087 } ); 17088 17089 // Once all animations have completed: 17090 $.when.apply( $, allAnimations.get() ).done( function() { 17091 17092 // Set the final class 17093 applyClassChange(); 17094 17095 // For each animated element, 17096 // clear all css properties that were animated 17097 $.each( arguments, function() { 17098 var el = this.el; 17099 $.each( this.diff, function( key ) { 17100 el.css( key, "" ); 17101 } ); 17102 } ); 17103 17104 // This is guarnteed to be there if you use jQuery.speed() 17105 // it also handles dequeuing the next anim... 17106 o.complete.call( animated[ 0 ] ); 17107 } ); 17108 } ); 17109}; 17110 17111$.fn.extend( { 17112 addClass: ( function( orig ) { 17113 return function( classNames, speed, easing, callback ) { 17114 return speed ? 17115 $.effects.animateClass.call( this, 17116 { add: classNames }, speed, easing, callback ) : 17117 orig.apply( this, arguments ); 17118 }; 17119 } )( $.fn.addClass ), 17120 17121 removeClass: ( function( orig ) { 17122 return function( classNames, speed, easing, callback ) { 17123 return arguments.length > 1 ? 17124 $.effects.animateClass.call( this, 17125 { remove: classNames }, speed, easing, callback ) : 17126 orig.apply( this, arguments ); 17127 }; 17128 } )( $.fn.removeClass ), 17129 17130 toggleClass: ( function( orig ) { 17131 return function( classNames, force, speed, easing, callback ) { 17132 if ( typeof force === "boolean" || force === undefined ) { 17133 if ( !speed ) { 17134 17135 // Without speed parameter 17136 return orig.apply( this, arguments ); 17137 } else { 17138 return $.effects.animateClass.call( this, 17139 ( force ? { add: classNames } : { remove: classNames } ), 17140 speed, easing, callback ); 17141 } 17142 } else { 17143 17144 // Without force parameter 17145 return $.effects.animateClass.call( this, 17146 { toggle: classNames }, force, speed, easing ); 17147 } 17148 }; 17149 } )( $.fn.toggleClass ), 17150 17151 switchClass: function( remove, add, speed, easing, callback ) { 17152 return $.effects.animateClass.call( this, { 17153 add: add, 17154 remove: remove 17155 }, speed, easing, callback ); 17156 } 17157} ); 17158 17159} )(); 17160 17161/******************************************************************************/ 17162/*********************************** EFFECTS **********************************/ 17163/******************************************************************************/ 17164 17165( function() { 17166 17167if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 17168 $.expr.pseudos.animated = ( function( orig ) { 17169 return function( elem ) { 17170 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 17171 }; 17172 } )( $.expr.pseudos.animated ); 17173} 17174 17175if ( $.uiBackCompat === true ) { 17176 $.extend( $.effects, { 17177 17178 // Saves a set of properties in a data storage 17179 save: function( element, set ) { 17180 var i = 0, length = set.length; 17181 for ( ; i < length; i++ ) { 17182 if ( set[ i ] !== null ) { 17183 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 17184 } 17185 } 17186 }, 17187 17188 // Restores a set of previously saved properties from a data storage 17189 restore: function( element, set ) { 17190 var val, i = 0, length = set.length; 17191 for ( ; i < length; i++ ) { 17192 if ( set[ i ] !== null ) { 17193 val = element.data( dataSpace + set[ i ] ); 17194 element.css( set[ i ], val ); 17195 } 17196 } 17197 }, 17198 17199 setMode: function( el, mode ) { 17200 if ( mode === "toggle" ) { 17201 mode = el.is( ":hidden" ) ? "show" : "hide"; 17202 } 17203 return mode; 17204 }, 17205 17206 // Wraps the element around a wrapper that copies position properties 17207 createWrapper: function( element ) { 17208 17209 // If the element is already wrapped, return it 17210 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17211 return element.parent(); 17212 } 17213 17214 // Wrap the element 17215 var props = { 17216 width: element.outerWidth( true ), 17217 height: element.outerHeight( true ), 17218 "float": element.css( "float" ) 17219 }, 17220 wrapper = $( "<div></div>" ) 17221 .addClass( "ui-effects-wrapper" ) 17222 .css( { 17223 fontSize: "100%", 17224 background: "transparent", 17225 border: "none", 17226 margin: 0, 17227 padding: 0 17228 } ), 17229 17230 // Store the size in case width/height are defined in % - Fixes #5245 17231 size = { 17232 width: element.width(), 17233 height: element.height() 17234 }, 17235 active = document.activeElement; 17236 17237 // Support: Firefox 17238 // Firefox incorrectly exposes anonymous content 17239 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 17240 try { 17241 // eslint-disable-next-line no-unused-expressions 17242 active.id; 17243 } catch (
vendor: 1,550 bytes, lines 17243-17304
17243e ) { 17244 active = document.body; 17245 } 17246 17247 element.wrap( wrapper ); 17248 17249 // Fixes #7595 - Elements lose focus when wrapped. 17250 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17251 $( active ).trigger( "focus" ); 17252 } 17253 17254 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 17255 // lose the reference to the wrapped element 17256 wrapper = element.parent(); 17257 17258 // Transfer positioning properties to the wrapper 17259 if ( element.css( "position" ) === "static" ) { 17260 wrapper.css( { position: "relative" } ); 17261 element.css( { position: "relative" } ); 17262 } else { 17263 $.extend( props, { 17264 position: element.css( "position" ), 17265 zIndex: element.css( "z-index" ) 17266 } ); 17267 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 17268 props[ pos ] = element.css( pos ); 17269 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 17270 props[ pos ] = "auto"; 17271 } 17272 } ); 17273 element.css( { 17274 position: "relative", 17275 top: 0, 17276 left: 0, 17277 right: "auto", 17278 bottom: "auto" 17279 } ); 17280 } 17281 element.css( size ); 17282 17283 return wrapper.css( props ).show(); 17284 }, 17285 17286 removeWrapper: function( element ) { 17287 var active = document.activeElement; 17288 17289 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17290 element.parent().replaceWith( element ); 17291 17292 // Fixes #7595 - Elements lose focus when wrapped. 17293 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17294 $( active ).trigger( "focus" ); 17295 } 17296 } 17297 17298 return element; 17299 } 17300 } ); 17301} 17302 17303$.extend( $.effects, { 17304 version: "1.14.1
vendor: 14,339 bytes, lines 17304-17872
17304", 17305 17306 define: function( name, mode, effect ) { 17307 if ( !effect ) { 17308 effect = mode; 17309 mode = "effect"; 17310 } 17311 17312 $.effects.effect[ name ] = effect; 17313 $.effects.effect[ name ].mode = mode; 17314 17315 return effect; 17316 }, 17317 17318 scaledDimensions: function( element, percent, direction ) { 17319 if ( percent === 0 ) { 17320 return { 17321 height: 0, 17322 width: 0, 17323 outerHeight: 0, 17324 outerWidth: 0 17325 }; 17326 } 17327 17328 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 17329 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 17330 17331 return { 17332 height: element.height() * y, 17333 width: element.width() * x, 17334 outerHeight: element.outerHeight() * y, 17335 outerWidth: element.outerWidth() * x 17336 }; 17337 17338 }, 17339 17340 clipToBox: function( animation ) { 17341 return { 17342 width: animation.clip.right - animation.clip.left, 17343 height: animation.clip.bottom - animation.clip.top, 17344 left: animation.clip.left, 17345 top: animation.clip.top 17346 }; 17347 }, 17348 17349 // Injects recently queued functions to be first in line (after "inprogress") 17350 unshift: function( element, queueLength, count ) { 17351 var queue = element.queue(); 17352 17353 if ( queueLength > 1 ) { 17354 queue.splice.apply( queue, 17355 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 17356 } 17357 element.dequeue(); 17358 }, 17359 17360 saveStyle: function( element ) { 17361 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 17362 }, 17363 17364 restoreStyle: function( element ) { 17365 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 17366 element.removeData( dataSpaceStyle ); 17367 }, 17368 17369 mode: function( element, mode ) { 17370 var hidden = element.is( ":hidden" ); 17371 17372 if ( mode === "toggle" ) { 17373 mode = hidden ? "show" : "hide"; 17374 } 17375 if ( hidden ? mode === "hide" : mode === "show" ) { 17376 mode = "none"; 17377 } 17378 return mode; 17379 }, 17380 17381 // Translates a [top,left] array into a baseline value 17382 getBaseline: function( origin, original ) { 17383 var y, x; 17384 17385 switch ( origin[ 0 ] ) { 17386 case "top": 17387 y = 0; 17388 break; 17389 case "middle": 17390 y = 0.5; 17391 break; 17392 case "bottom": 17393 y = 1; 17394 break; 17395 default: 17396 y = origin[ 0 ] / original.height; 17397 } 17398 17399 switch ( origin[ 1 ] ) { 17400 case "left": 17401 x = 0; 17402 break; 17403 case "center": 17404 x = 0.5; 17405 break; 17406 case "right": 17407 x = 1; 17408 break; 17409 default: 17410 x = origin[ 1 ] / original.width; 17411 } 17412 17413 return { 17414 x: x, 17415 y: y 17416 }; 17417 }, 17418 17419 // Creates a placeholder element so that the original element can be made absolute 17420 createPlaceholder: function( element ) { 17421 var placeholder, 17422 cssPosition = element.css( "position" ), 17423 position = element.position(); 17424 17425 // Lock in margins first to account for form elements, which 17426 // will change margin if you explicitly set height 17427 // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 17428 // Support: Safari 17429 element.css( { 17430 marginTop: element.css( "marginTop" ), 17431 marginBottom: element.css( "marginBottom" ), 17432 marginLeft: element.css( "marginLeft" ), 17433 marginRight: element.css( "marginRight" ) 17434 } ) 17435 .outerWidth( element.outerWidth() ) 17436 .outerHeight( element.outerHeight() ); 17437 17438 if ( /^(static|relative)/.test( cssPosition ) ) { 17439 cssPosition = "absolute"; 17440 17441 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 17442 17443 // Convert inline to inline block to account for inline elements 17444 // that turn to inline block based on content (like img) 17445 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 17446 "inline-block" : 17447 "block", 17448 visibility: "hidden", 17449 17450 // Margins need to be set to account for margin collapse 17451 marginTop: element.css( "marginTop" ), 17452 marginBottom: element.css( "marginBottom" ), 17453 marginLeft: element.css( "marginLeft" ), 17454 marginRight: element.css( "marginRight" ), 17455 "float": element.css( "float" ) 17456 } ) 17457 .outerWidth( element.outerWidth() ) 17458 .outerHeight( element.outerHeight() ) 17459 .addClass( "ui-effects-placeholder" ); 17460 17461 element.data( dataSpace + "placeholder", placeholder ); 17462 } 17463 17464 element.css( { 17465 position: cssPosition, 17466 left: position.left, 17467 top: position.top 17468 } ); 17469 17470 return placeholder; 17471 }, 17472 17473 removePlaceholder: function( element ) { 17474 var dataKey = dataSpace + "placeholder", 17475 placeholder = element.data( dataKey ); 17476 17477 if ( placeholder ) { 17478 placeholder.remove(); 17479 element.removeData( dataKey ); 17480 } 17481 }, 17482 17483 // Removes a placeholder if it exists and restores 17484 // properties that were modified during placeholder creation 17485 cleanUp: function( element ) { 17486 $.effects.restoreStyle( element ); 17487 $.effects.removePlaceholder( element ); 17488 }, 17489 17490 setTransition: function( element, list, factor, value ) { 17491 value = value || {}; 17492 $.each( list, function( i, x ) { 17493 var unit = element.cssUnit( x ); 17494 if ( unit[ 0 ] > 0 ) { 17495 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 17496 } 17497 } ); 17498 return value; 17499 } 17500} ); 17501 17502// Return an effect options object for the given parameters: 17503function _normalizeArguments( effect, options, speed, callback ) { 17504 17505 // Allow passing all options as the first parameter 17506 if ( $.isPlainObject( effect ) ) { 17507 options = effect; 17508 effect = effect.effect; 17509 } 17510 17511 // Convert to an object 17512 effect = { effect: effect }; 17513 17514 // Catch (effect, null, ...) 17515 if ( options == null ) { 17516 options = {}; 17517 } 17518 17519 // Catch (effect, callback) 17520 if ( typeof options === "function" ) { 17521 callback = options; 17522 speed = null; 17523 options = {}; 17524 } 17525 17526 // Catch (effect, speed, ?) 17527 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 17528 callback = speed; 17529 speed = options; 17530 options = {}; 17531 } 17532 17533 // Catch (effect, options, callback) 17534 if ( typeof speed === "function" ) { 17535 callback = speed; 17536 speed = null; 17537 } 17538 17539 // Add options to effect 17540 if ( options ) { 17541 $.extend( effect, options ); 17542 } 17543 17544 speed = speed || options.duration; 17545 effect.duration = $.fx.off ? 0 : 17546 typeof speed === "number" ? speed : 17547 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 17548 $.fx.speeds._default; 17549 17550 effect.complete = callback || options.complete; 17551 17552 return effect; 17553} 17554 17555function standardAnimationOption( option ) { 17556 17557 // Valid standard speeds (nothing, number, named speed) 17558 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 17559 return true; 17560 } 17561 17562 // Invalid strings - treat as "normal" speed 17563 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 17564 return true; 17565 } 17566 17567 // Complete callback 17568 if ( typeof option === "function" ) { 17569 return true; 17570 } 17571 17572 // Options hash (but not naming an effect) 17573 if ( typeof option === "object" && !option.effect ) { 17574 return true; 17575 } 17576 17577 // Didn't match any standard API 17578 return false; 17579} 17580 17581$.fn.extend( { 17582 effect: function( /* effect, options, speed, callback */ ) { 17583 var args = _normalizeArguments.apply( this, arguments ), 17584 effectMethod = $.effects.effect[ args.effect ], 17585 defaultMode = effectMethod.mode, 17586 queue = args.queue, 17587 queueName = queue || "fx", 17588 complete = args.complete, 17589 mode = args.mode, 17590 modes = [], 17591 prefilter = function( next ) { 17592 var el = $( this ), 17593 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 17594 17595 // Sentinel for duck-punching the :animated pseudo-selector 17596 el.data( dataSpaceAnimated, true ); 17597 17598 // Save effect mode for later use, 17599 // we can't just call $.effects.mode again later, 17600 // as the .show() below destroys the initial state 17601 modes.push( normalizedMode ); 17602 17603 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 17604 if ( defaultMode && ( normalizedMode === "show" || 17605 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 17606 el.show(); 17607 } 17608 17609 if ( !defaultMode || normalizedMode !== "none" ) { 17610 $.effects.saveStyle( el ); 17611 } 17612 17613 if ( typeof next === "function" ) { 17614 next(); 17615 } 17616 }; 17617 17618 if ( $.fx.off || !effectMethod ) { 17619 17620 // Delegate to the original method (e.g., .show()) if possible 17621 if ( mode ) { 17622 return this[ mode ]( args.duration, complete ); 17623 } else { 17624 return this.each( function() { 17625 if ( complete ) { 17626 complete.call( this ); 17627 } 17628 } ); 17629 } 17630 } 17631 17632 function run( next ) { 17633 var elem = $( this ); 17634 17635 function cleanup() { 17636 elem.removeData( dataSpaceAnimated ); 17637 17638 $.effects.cleanUp( elem ); 17639 17640 if ( args.mode === "hide" ) { 17641 elem.hide(); 17642 } 17643 17644 done(); 17645 } 17646 17647 function done() { 17648 if ( typeof complete === "function" ) { 17649 complete.call( elem[ 0 ] ); 17650 } 17651 17652 if ( typeof next === "function" ) { 17653 next(); 17654 } 17655 } 17656 17657 // Override mode option on a per element basis, 17658 // as toggle can be either show or hide depending on element state 17659 args.mode = modes.shift(); 17660 17661 if ( $.uiBackCompat === true && !defaultMode ) { 17662 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 17663 17664 // Call the core method to track "olddisplay" properly 17665 elem[ mode ](); 17666 done(); 17667 } else { 17668 effectMethod.call( elem[ 0 ], args, done ); 17669 } 17670 } else { 17671 if ( args.mode === "none" ) { 17672 17673 // Call the core method to track "olddisplay" properly 17674 elem[ mode ](); 17675 done(); 17676 } else { 17677 effectMethod.call( elem[ 0 ], args, cleanup ); 17678 } 17679 } 17680 } 17681 17682 // Run prefilter on all elements first to ensure that 17683 // any showing or hiding happens before placeholder creation, 17684 // which ensures that any layout changes are correctly captured. 17685 return queue === false ? 17686 this.each( prefilter ).each( run ) : 17687 this.queue( queueName, prefilter ).queue( queueName, run ); 17688 }, 17689 17690 show: ( function( orig ) { 17691 return function( option ) { 17692 if ( standardAnimationOption( option ) ) { 17693 return orig.apply( this, arguments ); 17694 } else { 17695 var args = _normalizeArguments.apply( this, arguments ); 17696 args.mode = "show"; 17697 return this.effect.call( this, args ); 17698 } 17699 }; 17700 } )( $.fn.show ), 17701 17702 hide: ( function( orig ) { 17703 return function( option ) { 17704 if ( standardAnimationOption( option ) ) { 17705 return orig.apply( this, arguments ); 17706 } else { 17707 var args = _normalizeArguments.apply( this, arguments ); 17708 args.mode = "hide"; 17709 return this.effect.call( this, args ); 17710 } 17711 }; 17712 } )( $.fn.hide ), 17713 17714 toggle: ( function( orig ) { 17715 return function( option ) { 17716 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 17717 return orig.apply( this, arguments ); 17718 } else { 17719 var args = _normalizeArguments.apply( this, arguments ); 17720 args.mode = "toggle"; 17721 return this.effect.call( this, args ); 17722 } 17723 }; 17724 } )( $.fn.toggle ), 17725 17726 cssUnit: function( key ) { 17727 var style = this.css( key ), 17728 val = []; 17729 17730 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 17731 if ( style.indexOf( unit ) > 0 ) { 17732 val = [ parseFloat( style ), unit ]; 17733 } 17734 } ); 17735 return val; 17736 }, 17737 17738 cssClip: function( clipObj ) { 17739 if ( clipObj ) { 17740 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 17741 clipObj.bottom + "px " + clipObj.left + "px)" ); 17742 } 17743 return parseClip( this.css( "clip" ), this ); 17744 }, 17745 17746 transfer: function( options, done ) { 17747 var element = $( this ), 17748 target = $( options.to ), 17749 targetFixed = target.css( "position" ) === "fixed", 17750 body = $( "body" ), 17751 fixTop = targetFixed ? body.scrollTop() : 0, 17752 fixLeft = targetFixed ? body.scrollLeft() : 0, 17753 endPosition = target.offset(), 17754 animation = { 17755 top: endPosition.top - fixTop, 17756 left: endPosition.left - fixLeft, 17757 height: target.innerHeight(), 17758 width: target.innerWidth() 17759 }, 17760 startPosition = element.offset(), 17761 transfer = $( "<div class='ui-effects-transfer'></div>" ); 17762 17763 transfer 17764 .appendTo( "body" ) 17765 .addClass( options.className ) 17766 .css( { 17767 top: startPosition.top - fixTop, 17768 left: startPosition.left - fixLeft, 17769 height: element.innerHeight(), 17770 width: element.innerWidth(), 17771 position: targetFixed ? "fixed" : "absolute" 17772 } ) 17773 .animate( animation, options.duration, options.easing, function() { 17774 transfer.remove(); 17775 if ( typeof done === "function" ) { 17776 done(); 17777 } 17778 } ); 17779 } 17780} ); 17781 17782function parseClip( str, element ) { 17783 var outerWidth = element.outerWidth(), 17784 outerHeight = element.outerHeight(), 17785 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)\)$/, 17786 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 17787 17788 return { 17789 top: parseFloat( values[ 1 ] ) || 0, 17790 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 17791 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 17792 left: parseFloat( values[ 4 ] ) || 0 17793 }; 17794} 17795 17796$.fx.step.clip = function( fx ) { 17797 if ( !fx.clipInit ) { 17798 fx.start = $( fx.elem ).cssClip(); 17799 if ( typeof fx.end === "string" ) { 17800 fx.end = parseClip( fx.end, fx.elem ); 17801 } 17802 fx.clipInit = true; 17803 } 17804 17805 $( fx.elem ).cssClip( { 17806 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 17807 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 17808 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 17809 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 17810 } ); 17811}; 17812 17813} )(); 17814 17815/******************************************************************************/ 17816/*********************************** EASING ***********************************/ 17817/******************************************************************************/ 17818 17819( function() { 17820 17821// Based on easing equations from Robert Penner (http://robertpenner.com/easing) 17822 17823var baseEasings = {}; 17824 17825$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 17826 baseEasings[ name ] = function( p ) { 17827 return Math.pow( p, i + 2 ); 17828 }; 17829} ); 17830 17831$.extend( baseEasings, { 17832 Sine: function( p ) { 17833 return 1 - Math.cos( p * Math.PI / 2 ); 17834 }, 17835 Circ: function( p ) { 17836 return 1 - Math.sqrt( 1 - p * p ); 17837 }, 17838 Elastic: function( p ) { 17839 return p === 0 || p === 1 ? p : 17840 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 17841 }, 17842 Back: function( p ) { 17843 return p * p * ( 3 * p - 2 ); 17844 }, 17845 Bounce: function( p ) { 17846 var pow2, 17847 bounce = 4; 17848 17849 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 17850 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 17851 } 17852} ); 17853 17854$.each( baseEasings, function( name, easeIn ) { 17855 $.easing[ "easeIn" + name ] = easeIn; 17856 $.easing[ "easeOut" + name ] = function( p ) { 17857 return 1 - easeIn( 1 - p ); 17858 }; 17859 $.easing[ "easeInOut" + name ] = function( p ) { 17860 return p < 0.5 ? 17861 easeIn( p * 2 ) / 2 : 17862 1 - easeIn( p * -2 + 2 ) / 2; 17863 }; 17864} ); 17865 17866} )(); 17867 17868var effect = $.effects; 17869 17870 17871/*! 17872 * jQuery UI Effects Blind 1.14.
vendor: 23,878 bytes, lines 17872-18776
178721 17873 * https://jqueryui.com 17874 * 17875 * Copyright OpenJS Foundation and other contributors 17876 * Released under the MIT license. 17877 * https://jquery.org/license 17878 */ 17879 17880//>>label: Blind Effect 17881//>>group: Effects 17882//>>description: Blinds the element. 17883//>>docs: https://api.jqueryui.com/blind-effect/ 17884//>>demos: https://jqueryui.com/effect/ 17885 17886 17887var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 17888 var map = { 17889 up: [ "bottom", "top" ], 17890 vertical: [ "bottom", "top" ], 17891 down: [ "top", "bottom" ], 17892 left: [ "right", "left" ], 17893 horizontal: [ "right", "left" ], 17894 right: [ "left", "right" ] 17895 }, 17896 element = $( this ), 17897 direction = options.direction || "up", 17898 start = element.cssClip(), 17899 animate = { clip: $.extend( {}, start ) }, 17900 placeholder = $.effects.createPlaceholder( element ); 17901 17902 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 17903 17904 if ( options.mode === "show" ) { 17905 element.cssClip( animate.clip ); 17906 if ( placeholder ) { 17907 placeholder.css( $.effects.clipToBox( animate ) ); 17908 } 17909 17910 animate.clip = start; 17911 } 17912 17913 if ( placeholder ) { 17914 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 17915 } 17916 17917 element.animate( animate, { 17918 queue: false, 17919 duration: options.duration, 17920 easing: options.easing, 17921 complete: done 17922 } ); 17923} ); 17924 17925 17926/*! 17927 * jQuery UI Effects Bounce 1.14.1 17928 * https://jqueryui.com 17929 * 17930 * Copyright OpenJS Foundation and other contributors 17931 * Released under the MIT license. 17932 * https://jquery.org/license 17933 */ 17934 17935//>>label: Bounce Effect 17936//>>group: Effects 17937//>>description: Bounces an element horizontally or vertically n times. 17938//>>docs: https://api.jqueryui.com/bounce-effect/ 17939//>>demos: https://jqueryui.com/effect/ 17940 17941 17942var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 17943 var upAnim, downAnim, refValue, 17944 element = $( this ), 17945 17946 // Defaults: 17947 mode = options.mode, 17948 hide = mode === "hide", 17949 show = mode === "show", 17950 direction = options.direction || "up", 17951 distance = options.distance, 17952 times = options.times || 5, 17953 17954 // Number of internal animations 17955 anims = times * 2 + ( show || hide ? 1 : 0 ), 17956 speed = options.duration / anims, 17957 easing = options.easing, 17958 17959 // Utility: 17960 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17961 motion = ( direction === "up" || direction === "left" ), 17962 i = 0, 17963 17964 queuelen = element.queue().length; 17965 17966 $.effects.createPlaceholder( element ); 17967 17968 refValue = element.css( ref ); 17969 17970 // Default distance for the BIGGEST bounce is the outer Distance / 3 17971 if ( !distance ) { 17972 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 17973 } 17974 17975 if ( show ) { 17976 downAnim = { opacity: 1 }; 17977 downAnim[ ref ] = refValue; 17978 17979 // If we are showing, force opacity 0 and set the initial position 17980 // then do the "first" animation 17981 element 17982 .css( "opacity", 0 ) 17983 .css( ref, motion ? -distance * 2 : distance * 2 ) 17984 .animate( downAnim, speed, easing ); 17985 } 17986 17987 // Start at the smallest distance if we are hiding 17988 if ( hide ) { 17989 distance = distance / Math.pow( 2, times - 1 ); 17990 } 17991 17992 downAnim = {}; 17993 downAnim[ ref ] = refValue; 17994 17995 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 17996 for ( ; i < times; i++ ) { 17997 upAnim = {}; 17998 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 17999 18000 element 18001 .animate( upAnim, speed, easing ) 18002 .animate( downAnim, speed, easing ); 18003 18004 distance = hide ? distance * 2 : distance / 2; 18005 } 18006 18007 // Last Bounce when Hiding 18008 if ( hide ) { 18009 upAnim = { opacity: 0 }; 18010 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 18011 18012 element.animate( upAnim, speed, easing ); 18013 } 18014 18015 element.queue( done ); 18016 18017 $.effects.unshift( element, queuelen, anims + 1 ); 18018} ); 18019 18020 18021/*! 18022 * jQuery UI Effects Clip 1.14.1 18023 * https://jqueryui.com 18024 * 18025 * Copyright OpenJS Foundation and other contributors 18026 * Released under the MIT license. 18027 * https://jquery.org/license 18028 */ 18029 18030//>>label: Clip Effect 18031//>>group: Effects 18032//>>description: Clips the element on and off like an old TV. 18033//>>docs: https://api.jqueryui.com/clip-effect/ 18034//>>demos: https://jqueryui.com/effect/ 18035 18036 18037var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 18038 var start, 18039 animate = {}, 18040 element = $( this ), 18041 direction = options.direction || "vertical", 18042 both = direction === "both", 18043 horizontal = both || direction === "horizontal", 18044 vertical = both || direction === "vertical"; 18045 18046 start = element.cssClip(); 18047 animate.clip = { 18048 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 18049 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 18050 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 18051 left: horizontal ? ( start.right - start.left ) / 2 : start.left 18052 }; 18053 18054 $.effects.createPlaceholder( element ); 18055 18056 if ( options.mode === "show" ) { 18057 element.cssClip( animate.clip ); 18058 animate.clip = start; 18059 } 18060 18061 element.animate( animate, { 18062 queue: false, 18063 duration: options.duration, 18064 easing: options.easing, 18065 complete: done 18066 } ); 18067 18068} ); 18069 18070 18071/*! 18072 * jQuery UI Effects Drop 1.14.1 18073 * https://jqueryui.com 18074 * 18075 * Copyright OpenJS Foundation and other contributors 18076 * Released under the MIT license. 18077 * https://jquery.org/license 18078 */ 18079 18080//>>label: Drop Effect 18081//>>group: Effects 18082//>>description: Moves an element in one direction and hides it at the same time. 18083//>>docs: https://api.jqueryui.com/drop-effect/ 18084//>>demos: https://jqueryui.com/effect/ 18085 18086 18087var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 18088 18089 var distance, 18090 element = $( this ), 18091 mode = options.mode, 18092 show = mode === "show", 18093 direction = options.direction || "left", 18094 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18095 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 18096 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 18097 animation = { 18098 opacity: 0 18099 }; 18100 18101 $.effects.createPlaceholder( element ); 18102 18103 distance = options.distance || 18104 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 18105 18106 animation[ ref ] = motion + distance; 18107 18108 if ( show ) { 18109 element.css( animation ); 18110 18111 animation[ ref ] = oppositeMotion + distance; 18112 animation.opacity = 1; 18113 } 18114 18115 // Animate 18116 element.animate( animation, { 18117 queue: false, 18118 duration: options.duration, 18119 easing: options.easing, 18120 complete: done 18121 } ); 18122} ); 18123 18124 18125/*! 18126 * jQuery UI Effects Explode 1.14.1 18127 * https://jqueryui.com 18128 * 18129 * Copyright OpenJS Foundation and other contributors 18130 * Released under the MIT license. 18131 * https://jquery.org/license 18132 */ 18133 18134//>>label: Explode Effect 18135//>>group: Effects 18136/* eslint-disable max-len */ 18137//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 18138/* eslint-enable max-len */ 18139//>>docs: https://api.jqueryui.com/explode-effect/ 18140//>>demos: https://jqueryui.com/effect/ 18141 18142 18143var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 18144 18145 var i, j, left, top, mx, my, 18146 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 18147 cells = rows, 18148 element = $( this ), 18149 mode = options.mode, 18150 show = mode === "show", 18151 18152 // Show and then visibility:hidden the element before calculating offset 18153 offset = element.show().css( "visibility", "hidden" ).offset(), 18154 18155 // Width and height of a piece 18156 width = Math.ceil( element.outerWidth() / cells ), 18157 height = Math.ceil( element.outerHeight() / rows ), 18158 pieces = []; 18159 18160 // Children animate complete: 18161 function childComplete() { 18162 pieces.push( this ); 18163 if ( pieces.length === rows * cells ) { 18164 animComplete(); 18165 } 18166 } 18167 18168 // Clone the element for each row and cell. 18169 for ( i = 0; i < rows; i++ ) { // ===> 18170 top = offset.top + i * height; 18171 my = i - ( rows - 1 ) / 2; 18172 18173 for ( j = 0; j < cells; j++ ) { // ||| 18174 left = offset.left + j * width; 18175 mx = j - ( cells - 1 ) / 2; 18176 18177 // Create a clone of the now hidden main element that will be absolute positioned 18178 // within a wrapper div off the -left and -top equal to size of our pieces 18179 element 18180 .clone() 18181 .appendTo( "body" ) 18182 .wrap( "<div></div>" ) 18183 .css( { 18184 position: "absolute", 18185 visibility: "visible", 18186 left: -j * width, 18187 top: -i * height 18188 } ) 18189 18190 // Select the wrapper - make it overflow: hidden and absolute positioned based on 18191 // where the original was located +left and +top equal to the size of pieces 18192 .parent() 18193 .addClass( "ui-effects-explode" ) 18194 .css( { 18195 position: "absolute", 18196 overflow: "hidden", 18197 width: width, 18198 height: height, 18199 left: left + ( show ? mx * width : 0 ), 18200 top: top + ( show ? my * height : 0 ), 18201 opacity: show ? 0 : 1 18202 } ) 18203 .animate( { 18204 left: left + ( show ? 0 : mx * width ), 18205 top: top + ( show ? 0 : my * height ), 18206 opacity: show ? 1 : 0 18207 }, options.duration || 500, options.easing, childComplete ); 18208 } 18209 } 18210 18211 function animComplete() { 18212 element.css( { 18213 visibility: "visible" 18214 } ); 18215 $( pieces ).remove(); 18216 done(); 18217 } 18218} ); 18219 18220 18221/*! 18222 * jQuery UI Effects Fade 1.14.1 18223 * https://jqueryui.com 18224 * 18225 * Copyright OpenJS Foundation and other contributors 18226 * Released under the MIT license. 18227 * https://jquery.org/license 18228 */ 18229 18230//>>label: Fade Effect 18231//>>group: Effects 18232//>>description: Fades the element. 18233//>>docs: https://api.jqueryui.com/fade-effect/ 18234//>>demos: https://jqueryui.com/effect/ 18235 18236 18237var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 18238 var show = options.mode === "show"; 18239 18240 $( this ) 18241 .css( "opacity", show ? 0 : 1 ) 18242 .animate( { 18243 opacity: show ? 1 : 0 18244 }, { 18245 queue: false, 18246 duration: options.duration, 18247 easing: options.easing, 18248 complete: done 18249 } ); 18250} ); 18251 18252 18253/*! 18254 * jQuery UI Effects Fold 1.14.1 18255 * https://jqueryui.com 18256 * 18257 * Copyright OpenJS Foundation and other contributors 18258 * Released under the MIT license. 18259 * https://jquery.org/license 18260 */ 18261 18262//>>label: Fold Effect 18263//>>group: Effects 18264//>>description: Folds an element first horizontally and then vertically. 18265//>>docs: https://api.jqueryui.com/fold-effect/ 18266//>>demos: https://jqueryui.com/effect/ 18267 18268 18269var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 18270 18271 // Create element 18272 var element = $( this ), 18273 mode = options.mode, 18274 show = mode === "show", 18275 hide = mode === "hide", 18276 size = options.size || 15, 18277 percent = /([0-9]+)%/.exec( size ), 18278 horizFirst = !!options.horizFirst, 18279 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 18280 duration = options.duration / 2, 18281 18282 placeholder = $.effects.createPlaceholder( element ), 18283 18284 start = element.cssClip(), 18285 animation1 = { clip: $.extend( {}, start ) }, 18286 animation2 = { clip: $.extend( {}, start ) }, 18287 18288 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 18289 18290 queuelen = element.queue().length; 18291 18292 if ( percent ) { 18293 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 18294 } 18295 animation1.clip[ ref[ 0 ] ] = size; 18296 animation2.clip[ ref[ 0 ] ] = size; 18297 animation2.clip[ ref[ 1 ] ] = 0; 18298 18299 if ( show ) { 18300 element.cssClip( animation2.clip ); 18301 if ( placeholder ) { 18302 placeholder.css( $.effects.clipToBox( animation2 ) ); 18303 } 18304 18305 animation2.clip = start; 18306 } 18307 18308 // Animate 18309 element 18310 .queue( function( next ) { 18311 if ( placeholder ) { 18312 placeholder 18313 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 18314 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 18315 } 18316 18317 next(); 18318 } ) 18319 .animate( animation1, duration, options.easing ) 18320 .animate( animation2, duration, options.easing ) 18321 .queue( done ); 18322 18323 $.effects.unshift( element, queuelen, 4 ); 18324} ); 18325 18326 18327/*! 18328 * jQuery UI Effects Highlight 1.14.1 18329 * https://jqueryui.com 18330 * 18331 * Copyright OpenJS Foundation and other contributors 18332 * Released under the MIT license. 18333 * https://jquery.org/license 18334 */ 18335 18336//>>label: Highlight Effect 18337//>>group: Effects 18338//>>description: Highlights the background of an element in a defined color for a custom duration. 18339//>>docs: https://api.jqueryui.com/highlight-effect/ 18340//>>demos: https://jqueryui.com/effect/ 18341 18342 18343var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 18344 var element = $( this ), 18345 animation = { 18346 backgroundColor: element.css( "backgroundColor" ) 18347 }; 18348 18349 if ( options.mode === "hide" ) { 18350 animation.opacity = 0; 18351 } 18352 18353 $.effects.saveStyle( element ); 18354 18355 element 18356 .css( { 18357 backgroundImage: "none", 18358 backgroundColor: options.color || "#ffff99" 18359 } ) 18360 .animate( animation, { 18361 queue: false, 18362 duration: options.duration, 18363 easing: options.easing, 18364 complete: done 18365 } ); 18366} ); 18367 18368 18369/*! 18370 * jQuery UI Effects Size 1.14.1 18371 * https://jqueryui.com 18372 * 18373 * Copyright OpenJS Foundation and other contributors 18374 * Released under the MIT license. 18375 * https://jquery.org/license 18376 */ 18377 18378//>>label: Size Effect 18379//>>group: Effects 18380//>>description: Resize an element to a specified width and height. 18381//>>docs: https://api.jqueryui.com/size-effect/ 18382//>>demos: https://jqueryui.com/effect/ 18383 18384 18385var effectsEffectSize = $.effects.define( "size", function( options, done ) { 18386 18387 // Create element 18388 var baseline, factor, temp, 18389 element = $( this ), 18390 18391 // Copy for children 18392 cProps = [ "fontSize" ], 18393 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 18394 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 18395 18396 // Set options 18397 mode = options.mode, 18398 restore = mode !== "effect", 18399 scale = options.scale || "both", 18400 origin = options.origin || [ "middle", "center" ], 18401 position = element.css( "position" ), 18402 pos = element.position(), 18403 original = $.effects.scaledDimensions( element ), 18404 from = options.from || original, 18405 to = options.to || $.effects.scaledDimensions( element, 0 ); 18406 18407 $.effects.createPlaceholder( element ); 18408 18409 if ( mode === "show" ) { 18410 temp = from; 18411 from = to; 18412 to = temp; 18413 } 18414 18415 // Set scaling factor 18416 factor = { 18417 from: { 18418 y: from.height / original.height, 18419 x: from.width / original.width 18420 }, 18421 to: { 18422 y: to.height / original.height, 18423 x: to.width / original.width 18424 } 18425 }; 18426 18427 // Scale the css box 18428 if ( scale === "box" || scale === "both" ) { 18429 18430 // Vertical props scaling 18431 if ( factor.from.y !== factor.to.y ) { 18432 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 18433 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 18434 } 18435 18436 // Horizontal props scaling 18437 if ( factor.from.x !== factor.to.x ) { 18438 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 18439 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 18440 } 18441 } 18442 18443 // Scale the content 18444 if ( scale === "content" || scale === "both" ) { 18445 18446 // Vertical props scaling 18447 if ( factor.from.y !== factor.to.y ) { 18448 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 18449 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 18450 } 18451 } 18452 18453 // Adjust the position properties based on the provided origin points 18454 if ( origin ) { 18455 baseline = $.effects.getBaseline( origin, original ); 18456 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 18457 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 18458 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 18459 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 18460 } 18461 delete from.outerHeight; 18462 delete from.outerWidth; 18463 element.css( from ); 18464 18465 // Animate the children if desired 18466 if ( scale === "content" || scale === "both" ) { 18467 18468 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 18469 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 18470 18471 // Only animate children with width attributes specified 18472 // TODO: is this right? should we include anything with css width specified as well 18473 element.find( "*[width]" ).each( function() { 18474 var child = $( this ), 18475 childOriginal = $.effects.scaledDimensions( child ), 18476 childFrom = { 18477 height: childOriginal.height * factor.from.y, 18478 width: childOriginal.width * factor.from.x, 18479 outerHeight: childOriginal.outerHeight * factor.from.y, 18480 outerWidth: childOriginal.outerWidth * factor.from.x 18481 }, 18482 childTo = { 18483 height: childOriginal.height * factor.to.y, 18484 width: childOriginal.width * factor.to.x, 18485 outerHeight: childOriginal.height * factor.to.y, 18486 outerWidth: childOriginal.width * factor.to.x 18487 }; 18488 18489 // Vertical props scaling 18490 if ( factor.from.y !== factor.to.y ) { 18491 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 18492 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 18493 } 18494 18495 // Horizontal props scaling 18496 if ( factor.from.x !== factor.to.x ) { 18497 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 18498 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 18499 } 18500 18501 if ( restore ) { 18502 $.effects.saveStyle( child ); 18503 } 18504 18505 // Animate children 18506 child.css( childFrom ); 18507 child.animate( childTo, options.duration, options.easing, function() { 18508 18509 // Restore children 18510 if ( restore ) { 18511 $.effects.restoreStyle( child ); 18512 } 18513 } ); 18514 } ); 18515 } 18516 18517 // Animate 18518 element.animate( to, { 18519 queue: false, 18520 duration: options.duration, 18521 easing: options.easing, 18522 complete: function() { 18523 18524 var offset = element.offset(); 18525 18526 if ( to.opacity === 0 ) { 18527 element.css( "opacity", from.opacity ); 18528 } 18529 18530 if ( !restore ) { 18531 element 18532 .css( "position", position === "static" ? "relative" : position ) 18533 .offset( offset ); 18534 18535 // Need to save style here so that automatic style restoration 18536 // doesn't restore to the original styles from before the animation. 18537 $.effects.saveStyle( element ); 18538 } 18539 18540 done(); 18541 } 18542 } ); 18543 18544} ); 18545 18546 18547/*! 18548 * jQuery UI Effects Scale 1.14.1 18549 * https://jqueryui.com 18550 * 18551 * Copyright OpenJS Foundation and other contributors 18552 * Released under the MIT license. 18553 * https://jquery.org/license 18554 */ 18555 18556//>>label: Scale Effect 18557//>>group: Effects 18558//>>description: Grows or shrinks an element and its content. 18559//>>docs: https://api.jqueryui.com/scale-effect/ 18560//>>demos: https://jqueryui.com/effect/ 18561 18562 18563var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 18564 18565 // Create element 18566 var el = $( this ), 18567 mode = options.mode, 18568 percent = parseInt( options.percent, 10 ) || 18569 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 18570 18571 newOptions = $.extend( true, { 18572 from: $.effects.scaledDimensions( el ), 18573 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 18574 origin: options.origin || [ "middle", "center" ] 18575 }, options ); 18576 18577 // Fade option to support puff 18578 if ( options.fade ) { 18579 newOptions.from.opacity = 1; 18580 newOptions.to.opacity = 0; 18581 } 18582 18583 $.effects.effect.size.call( this, newOptions, done ); 18584} ); 18585 18586 18587/*! 18588 * jQuery UI Effects Puff 1.14.1 18589 * https://jqueryui.com 18590 * 18591 * Copyright OpenJS Foundation and other contributors 18592 * Released under the MIT license. 18593 * https://jquery.org/license 18594 */ 18595 18596//>>label: Puff Effect 18597//>>group: Effects 18598//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 18599//>>docs: https://api.jqueryui.com/puff-effect/ 18600//>>demos: https://jqueryui.com/effect/ 18601 18602 18603var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 18604 var newOptions = $.extend( true, {}, options, { 18605 fade: true, 18606 percent: parseInt( options.percent, 10 ) || 150 18607 } ); 18608 18609 $.effects.effect.scale.call( this, newOptions, done ); 18610} ); 18611 18612 18613/*! 18614 * jQuery UI Effects Pulsate 1.14.1 18615 * https://jqueryui.com 18616 * 18617 * Copyright OpenJS Foundation and other contributors 18618 * Released under the MIT license. 18619 * https://jquery.org/license 18620 */ 18621 18622//>>label: Pulsate Effect 18623//>>group: Effects 18624//>>description: Pulsates an element n times by changing the opacity to zero and back. 18625//>>docs: https://api.jqueryui.com/pulsate-effect/ 18626//>>demos: https://jqueryui.com/effect/ 18627 18628 18629var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 18630 var element = $( this ), 18631 mode = options.mode, 18632 show = mode === "show", 18633 hide = mode === "hide", 18634 showhide = show || hide, 18635 18636 // Showing or hiding leaves off the "last" animation 18637 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 18638 duration = options.duration / anims, 18639 animateTo = 0, 18640 i = 1, 18641 queuelen = element.queue().length; 18642 18643 if ( show || !element.is( ":visible" ) ) { 18644 element.css( "opacity", 0 ).show(); 18645 animateTo = 1; 18646 } 18647 18648 // Anims - 1 opacity "toggles" 18649 for ( ; i < anims; i++ ) { 18650 element.animate( { opacity: animateTo }, duration, options.easing ); 18651 animateTo = 1 - animateTo; 18652 } 18653 18654 element.animate( { opacity: animateTo }, duration, options.easing ); 18655 18656 element.queue( done ); 18657 18658 $.effects.unshift( element, queuelen, anims + 1 ); 18659} ); 18660 18661 18662/*! 18663 * jQuery UI Effects Shake 1.14.1 18664 * https://jqueryui.com 18665 * 18666 * Copyright OpenJS Foundation and other contributors 18667 * Released under the MIT license. 18668 * https://jquery.org/license 18669 */ 18670 18671//>>label: Shake Effect 18672//>>group: Effects 18673//>>description: Shakes an element horizontally or vertically n times. 18674//>>docs: https://api.jqueryui.com/shake-effect/ 18675//>>demos: https://jqueryui.com/effect/ 18676 18677 18678var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 18679 18680 var i = 1, 18681 element = $( this ), 18682 direction = options.direction || "left", 18683 distance = options.distance || 20, 18684 times = options.times || 3, 18685 anims = times * 2 + 1, 18686 speed = Math.round( options.duration / anims ), 18687 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18688 positiveMotion = ( direction === "up" || direction === "left" ), 18689 animation = {}, 18690 animation1 = {}, 18691 animation2 = {}, 18692 18693 queuelen = element.queue().length; 18694 18695 $.effects.createPlaceholder( element ); 18696 18697 // Animation 18698 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 18699 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 18700 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 18701 18702 // Animate 18703 element.animate( animation, speed, options.easing ); 18704 18705 // Shakes 18706 for ( ; i < times; i++ ) { 18707 element 18708 .animate( animation1, speed, options.easing ) 18709 .animate( animation2, speed, options.easing ); 18710 } 18711 18712 element 18713 .animate( animation1, speed, options.easing ) 18714 .animate( animation, speed / 2, options.easing ) 18715 .queue( done ); 18716 18717 $.effects.unshift( element, queuelen, anims + 1 ); 18718} ); 18719 18720 18721/*! 18722 * jQuery UI Effects Slide 1.14.1 18723 * https://jqueryui.com 18724 * 18725 * Copyright OpenJS Foundation and other contributors 18726 * Released under the MIT license. 18727 * https://jquery.org/license 18728 */ 18729 18730//>>label: Slide Effect 18731//>>group: Effects 18732//>>description: Slides an element in and out of the viewport. 18733//>>docs: https://api.jqueryui.com/slide-effect/ 18734//>>demos: https://jqueryui.com/effect/ 18735 18736 18737var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 18738 var startClip, startRef, 18739 element = $( this ), 18740 map = { 18741 up: [ "bottom", "top" ], 18742 down: [ "top", "bottom" ], 18743 left: [ "right", "left" ], 18744 right: [ "left", "right" ] 18745 }, 18746 mode = options.mode, 18747 direction = options.direction || "left", 18748 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18749 positiveMotion = ( direction === "up" || direction === "left" ), 18750 distance = options.distance || 18751 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 18752 animation = {}; 18753 18754 $.effects.createPlaceholder( element ); 18755 18756 startClip = element.cssClip(); 18757 startRef = element.position()[ ref ]; 18758 18759 // Define hide animation 18760 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 18761 animation.clip = element.cssClip(); 18762 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 18763 18764 // Reverse the animation if we're showing 18765 if ( mode === "show" ) { 18766 element.cssClip( animation.clip ); 18767 element.css( ref, animation[ ref ] ); 18768 animation.clip = startClip; 18769 animation[ ref ] = startRef; 18770 } 18771 18772 // Actually animate 18773 element.animate( animation, { 18774 queue: false, 18775 duration: options.duration, 18776 easing: options.easing,
18777 complete: done 18778 } ); 18779} ); 18780 18781 18782/*! 18783 * jQuery UI Effects Transfer 1.14.1 18784 * https://jqueryui.com 18785 * 18786 * Copyright OpenJS Foundation and other contributors 18787 * Released under the MIT license. 18788 * https://jquery.org/license 18789 */ 18790 18791//>>label: Transfer Effect 18792//>>group: Effects 18793//>>description: Displays a transfer effect from one element to another. 18794//>>docs: https://api.jqueryui.com/transfer-effect/ 18795//>>demos: https://jqueryui.com/effect/ 18796 18797 18798var effect; 18799if ( $.uiBackCompat === true ) { 18800 effect = $.effects.define( "transfer", function( options, done ) { 18801 $( this ).transfer( options, done ); 18802 } ); 18803} 18804var effectsEffectTransfer = effect; 18805 18806 18807 18808 18809} );
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.