1/*! jQuery UI - v1.13.2 - 2022-07-14 2* http://jqueryui.com 3* Includes: widget.js, position.js, data.js, disable-selection.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, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js 4* Copyright jQuery 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.13.2"; 24 25 26/*! 27 * jQuery UI Widget 1.13.2 28 * http://jqueryui.com 29 * 30 * Copyright jQuery Foundation and other contributors 31 * Released under the MIT license. 32 * http://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: http://api.jqueryui.com/jQuery.widget/ 39//>>demos: http
vendor: 19,677 bytes, lines 39-769
39://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 var fullName = namespace + "-" + name; 71 72 if ( !prototype ) { 73 prototype = base; 74 base = $.Widget; 75 } 76 77 if ( Array.isArray( prototype ) ) { 78 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 79 } 80 81 // Create selector for plugin 82 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 83 return !!$.data( elem, fullName ); 84 }; 85 86 $[ namespace ] = $[ namespace ] || {}; 87 existingConstructor = $[ namespace ][ name ]; 88 constructor = $[ namespace ][ name ] = function( options, element ) { 89 90 // Allow instantiation without "new" keyword 91 if ( !this || !this._createWidget ) { 92 return new constructor( options, element ); 93 } 94 95 // Allow instantiation without initializing for simple inheritance 96 // must use "new" keyword (the code above always passes args) 97 if ( arguments.length ) { 98 this._createWidget( options, element ); 99 } 100 }; 101 102 // Extend with the existing constructor to carry over any static properties 103 $.extend( constructor, existingConstructor, { 104 version: prototype.version, 105 106 // Copy the object used to create the prototype in case we need to 107 // redefine the widget later 108 _proto: $.extend( {}, prototype ), 109 110 // Track widgets that inherit from this widget in case this widget is 111 // redefined after a widget inherits from it 112 _childConstructors: [] 113 } ); 114 115 basePrototype = new base(); 116 117 // We need to make the options hash a property directly on the new instance 118 // otherwise we'll modify the options hash on the prototype that we're 119 // inheriting from 120 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 121 $.each( prototype, function( prop, value ) { 122 if ( typeof value !== "function" ) { 123 proxiedPrototype[ prop ] = value; 124 return; 125 } 126 proxiedPrototype[ prop ] = ( function() { 127 function _super() { 128 return base.prototype[ prop ].apply( this, arguments ); 129 } 130 131 function _superApply( args ) { 132 return base.prototype[ prop ].apply( this, args ); 133 } 134 135 return function() { 136 var __super = this._super; 137 var __superApply = this._superApply; 138 var returnValue; 139 140 this._super = _super; 141 this._superApply = _superApply; 142 143 returnValue = value.apply( this, arguments ); 144 145 this._super = __super; 146 this._superApply = __superApply; 147 148 return returnValue; 149 }; 150 } )(); 151 } ); 152 constructor.prototype = $.widget.extend( basePrototype, { 153 154 // TODO: remove support for widgetEventPrefix 155 // always use the name + a colon as the prefix, e.g., draggable:start 156 // don't prefix for widgets that aren't DOM-based 157 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 158 }, proxiedPrototype, { 159 constructor: constructor, 160 namespace: namespace, 161 widgetName: name, 162 widgetFullName: fullName 163 } ); 164 165 // If this widget is being redefined then we need to find all widgets that 166 // are inheriting from it and redefine all of them so that they inherit from 167 // the new version of this widget. We're essentially trying to replace one 168 // level in the prototype chain. 169 if ( existingConstructor ) { 170 $.each( existingConstructor._childConstructors, function( i, child ) { 171 var childPrototype = child.prototype; 172 173 // Redefine the child widget using the same prototype that was 174 // originally used, but inherit from the new version of the base 175 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 176 child._proto ); 177 } ); 178 179 // Remove the list of existing child constructors from the old constructor 180 // so the old child constructors can be garbage collected 181 delete existingConstructor._childConstructors; 182 } else { 183 base._childConstructors.push( constructor ); 184 } 185 186 $.widget.bridge( name, constructor ); 187 188 return constructor; 189}; 190 191$.widget.extend = function( target ) { 192 var input = widgetSlice.call( arguments, 1 ); 193 var inputIndex = 0; 194 var inputLength = input.length; 195 var key; 196 var value; 197 198 for ( ; inputIndex < inputLength; inputIndex++ ) { 199 for ( key in input[ inputIndex ] ) { 200 value = input[ inputIndex ][ key ]; 201 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 202 203 // Clone objects 204 if ( $.isPlainObject( value ) ) { 205 target[ key ] = $.isPlainObject( target[ key ] ) ? 206 $.widget.extend( {}, target[ key ], value ) : 207 208 // Don't extend strings, arrays, etc. with objects 209 $.widget.extend( {}, value ); 210 211 // Copy everything else by reference 212 } else { 213 target[ key ] = value; 214 } 215 } 216 } 217 } 218 return target; 219}; 220 221$.widget.bridge = function( name, object ) { 222 var fullName = object.prototype.widgetFullName || name; 223 $.fn[ name ] = function( options ) { 224 var isMethodCall = typeof options === "string"; 225 var args = widgetSlice.call( arguments, 1 ); 226 var returnValue = this; 227 228 if ( isMethodCall ) { 229 230 // If this is an empty collection, we need to have the instance method 231 // return undefined instead of the jQuery instance 232 if ( !this.length && options === "instance" ) { 233 returnValue = undefined; 234 } else { 235 this.each( function() { 236 var methodValue; 237 var instance = $.data( this, fullName ); 238 239 if ( options === "instance" ) { 240 returnValue = instance; 241 return false; 242 } 243 244 if ( !instance ) { 245 return $.error( "cannot call methods on " + name + 246 " prior to initialization; " + 247 "attempted to call method '" + options + "'" ); 248 } 249 250 if ( typeof instance[ options ] !== "function" || 251 options.charAt( 0 ) === "_" ) { 252 return $.error( "no such method '" + options + "' for " + name + 253 " widget instance" ); 254 } 255 256 methodValue = instance[ options ].apply( instance, args ); 257 258 if ( methodValue !== instance && methodValue !== undefined ) { 259 returnValue = methodValue && methodValue.jquery ? 260 returnValue.pushStack( methodValue.get() ) : 261 methodValue; 262 return false; 263 } 264 } ); 265 } 266 } else { 267 268 // Allow multiple hashes to be passed on init 269 if ( args.length ) { 270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 271 } 272 273 this.each( function() { 274 var instance = $.data( this, fullName ); 275 if ( instance ) { 276 instance.option( options || {} ); 277 if ( instance._init ) { 278 instance._init(); 279 } 280 } else { 281 $.data( this, fullName, new object( options, this ) ); 282 } 283 } ); 284 } 285 286 return returnValue; 287 }; 288}; 289 290$.Widget = function( /* options, element */ ) {}; 291$.Widget._childConstructors = []; 292 293$.Widget.prototype = { 294 widgetName: "widget", 295 widgetEventPrefix: "", 296 defaultElement: "<div>", 297 298 options: { 299 classes: {}, 300 disabled: false, 301 302 // Callbacks 303 create: null 304 }, 305 306 _createWidget: function( options, element ) { 307 element = $( element || this.defaultElement || this )[ 0 ]; 308 this.element = $( element ); 309 this.uuid = widgetUuid++; 310 this.eventNamespace = "." + this.widgetName + this.uuid; 311 312 this.bindings = $(); 313 this.hoverable = $(); 314 this.focusable = $(); 315 this.classesElementLookup = {}; 316 317 if ( element !== this ) { 318 $.data( element, this.widgetFullName, this ); 319 this._on( true, this.element, { 320 remove: function( event ) { 321 if ( event.target === element ) { 322 this.destroy(); 323 } 324 } 325 } ); 326 this.document = $( element.style ? 327 328 // Element within the document 329 element.ownerDocument : 330 331 // Element is window or document 332 element.document || element ); 333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 334 } 335 336 this.options = $.widget.extend( {}, 337 this.options, 338 this._getCreateOptions(), 339 options ); 340 341 this._create(); 342 343 if ( this.options.disabled ) { 344 this._setOptionDisabled( this.options.disabled ); 345 } 346 347 this._trigger( "create", null, this._getCreateEventData() ); 348 this._init(); 349 }, 350 351 _getCreateOptions: function() { 352 return {}; 353 }, 354 355 _getCreateEventData: $.noop, 356 357 _create: $.noop, 358 359 _init: $.noop, 360 361 destroy: function() { 362 var that = this; 363 364 this._destroy(); 365 $.each( this.classesElementLookup, function( key, value ) { 366 that._removeClass( value, key ); 367 } ); 368 369 // We can probably remove the unbind calls in 2.0 370 // all event bindings should go through this._on() 371 this.element 372 .off( this.eventNamespace ) 373 .removeData( this.widgetFullName ); 374 this.widget() 375 .off( this.eventNamespace ) 376 .removeAttr( "aria-disabled" ); 377 378 // Clean up events and states 379 this.bindings.off( this.eventNamespace ); 380 }, 381 382 _destroy: $.noop, 383 384 widget: function() { 385 return this.element; 386 }, 387 388 option: function( key, value ) { 389 var options = key; 390 var parts; 391 var curOption; 392 var i; 393 394 if ( arguments.length === 0 ) { 395 396 // Don't return a reference to the internal hash 397 return $.widget.extend( {}, this.options ); 398 } 399 400 if ( typeof key === "string" ) { 401 402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 403 options = {}; 404 parts = key.split( "." ); 405 key = parts.shift(); 406 if ( parts.length ) { 407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 408 for ( i = 0; i < parts.length - 1; i++ ) { 409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 410 curOption = curOption[ parts[ i ] ]; 411 } 412 key = parts.pop(); 413 if ( arguments.length === 1 ) { 414 return curOption[ key ] === undefined ? null : curOption[ key ]; 415 } 416 curOption[ key ] = value; 417 } else { 418 if ( arguments.length === 1 ) { 419 return this.options[ key ] === undefined ? null : this.options[ key ]; 420 } 421 options[ key ] = value; 422 } 423 } 424 425 this._setOptions( options ); 426 427 return this; 428 }, 429 430 _setOptions: function( options ) { 431 var key; 432 433 for ( key in options ) { 434 this._setOption( key, options[ key ] ); 435 } 436 437 return this; 438 }, 439 440 _setOption: function( key, value ) { 441 if ( key === "classes" ) { 442 this._setOptionClasses( value ); 443 } 444 445 this.options[ key ] = value; 446 447 if ( key === "disabled" ) { 448 this._setOptionDisabled( value ); 449 } 450 451 return this; 452 }, 453 454 _setOptionClasses: function( value ) { 455 var classKey, elements, currentElements; 456 457 for ( classKey in value ) { 458 currentElements = this.classesElementLookup[ classKey ]; 459 if ( value[ classKey ] === this.options.classes[ classKey ] || 460 !currentElements || 461 !currentElements.length ) { 462 continue; 463 } 464 465 // We are doing this to create a new jQuery object because the _removeClass() call 466 // on the next line is going to destroy the reference to the current elements being 467 // tracked. We need to save a copy of this collection so that we can add the new classes 468 // below. 469 elements = $( currentElements.get() ); 470 this._removeClass( currentElements, classKey ); 471 472 // We don't use _addClass() here, because that uses this.options.classes 473 // for generating the string of classes. We want to use the value passed in from 474 // _setOption(), this is the new value of the classes option which was passed to 475 // _setOption(). We pass this value directly to _classes(). 476 elements.addClass( this._classes( { 477 element: elements, 478 keys: classKey, 479 classes: value, 480 add: true 481 } ) ); 482 } 483 }, 484 485 _setOptionDisabled: function( value ) { 486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 487 488 // If the widget is becoming disabled, then nothing is interactive 489 if ( value ) { 490 this._removeClass( this.hoverable, null, "ui-state-hover" ); 491 this._removeClass( this.focusable, null, "ui-state-focus" ); 492 } 493 }, 494 495 enable: function() { 496 return this._setOptions( { disabled: false } ); 497 }, 498 499 disable: function() { 500 return this._setOptions( { disabled: true } ); 501 }, 502 503 _classes: function( options ) { 504 var full = []; 505 var that = this; 506 507 options = $.extend( { 508 element: this.element, 509 classes: this.options.classes || {} 510 }, options ); 511 512 function bindRemoveEvent() { 513 var nodesToBind = []; 514 515 options.element.each( function( _, element ) { 516 var isTracked = $.map( that.classesElementLookup, function( elements ) { 517 return elements; 518 } ) 519 .some( function( elements ) { 520 return elements.is( element ); 521 } ); 522 523 if ( !isTracked ) { 524 nodesToBind.push( element ); 525 } 526 } ); 527 528 that._on( $( nodesToBind ), { 529 remove: "_untrackClassesElement" 530 } ); 531 } 532 533 function processClassString( classes, checkOption ) { 534 var current, i; 535 for ( i = 0; i < classes.length; i++ ) { 536 current = that.classesElementLookup[ classes[ i ] ] || $(); 537 if ( options.add ) { 538 bindRemoveEvent(); 539 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 540 } else { 541 current = $( current.not( options.element ).get() ); 542 } 543 that.classesElementLookup[ classes[ i ] ] = current; 544 full.push( classes[ i ] ); 545 if ( checkOption && options.classes[ classes[ i ] ] ) { 546 full.push( options.classes[ classes[ i ] ] ); 547 } 548 } 549 } 550 551 if ( options.keys ) { 552 processClassString( options.keys.match( /\S+/g ) || [], true ); 553 } 554 if ( options.extra ) { 555 processClassString( options.extra.match( /\S+/g ) || [] ); 556 } 557 558 return full.join( " " ); 559 }, 560 561 _untrackClassesElement: function( event ) { 562 var that = this; 563 $.each( that.classesElementLookup, function( key, value ) { 564 if ( $.inArray( event.target, value ) !== -1 ) { 565 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 566 } 567 } ); 568 569 this._off( $( event.target ) ); 570 }, 571 572 _removeClass: function( element, keys, extra ) { 573 return this._toggleClass( element, keys, extra, false ); 574 }, 575 576 _addClass: function( element, keys, extra ) { 577 return this._toggleClass( element, keys, extra, true ); 578 }, 579 580 _toggleClass: function( element, keys, extra, add ) { 581 add = ( typeof add === "boolean" ) ? add : extra; 582 var shift = ( typeof element === "string" || element === null ), 583 options = { 584 extra: shift ? keys : extra, 585 keys: shift ? element : keys, 586 element: shift ? this.element : element, 587 add: add 588 }; 589 options.element.toggleClass( this._classes( options ), add ); 590 return this; 591 }, 592 593 _on: function( suppressDisabledCheck, element, handlers ) { 594 var delegateElement; 595 var instance = this; 596 597 // No suppressDisabledCheck flag, shuffle arguments 598 if ( typeof suppressDisabledCheck !== "boolean" ) { 599 handlers = element; 600 element = suppressDisabledCheck; 601 suppressDisabledCheck = false; 602 } 603 604 // No element argument, shuffle and use this.element 605 if ( !handlers ) { 606 handlers = element; 607 element = this.element; 608 delegateElement = this.widget(); 609 } else { 610 element = delegateElement = $( element ); 611 this.bindings = this.bindings.add( element ); 612 } 613 614 $.each( handlers, function( event, handler ) { 615 function handlerProxy() { 616 617 // Allow widgets to customize the disabled handling 618 // - disabled as an array instead of boolean 619 // - disabled class as method for disabling individual parts 620 if ( !suppressDisabledCheck && 621 ( instance.options.disabled === true || 622 $( this ).hasClass( "ui-state-disabled" ) ) ) { 623 return; 624 } 625 return ( typeof handler === "string" ? instance[ handler ] : handler ) 626 .apply( instance, arguments ); 627 } 628 629 // Copy the guid so direct unbinding works 630 if ( typeof handler !== "string" ) { 631 handlerProxy.guid = handler.guid = 632 handler.guid || handlerProxy.guid || $.guid++; 633 } 634 635 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 636 var eventName = match[ 1 ] + instance.eventNamespace; 637 var selector = match[ 2 ]; 638 639 if ( selector ) { 640 delegateElement.on( eventName, selector, handlerProxy ); 641 } else { 642 element.on( eventName, handlerProxy ); 643 } 644 } ); 645 }, 646 647 _off: function( element, eventName ) { 648 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 649 this.eventNamespace; 650 element.off( eventName ); 651 652 // Clear the stack to avoid memory leaks (#10056) 653 this.bindings = $( this.bindings.not( element ).get() ); 654 this.focusable = $( this.focusable.not( element ).get() ); 655 this.hoverable = $( this.hoverable.not( element ).get() ); 656 }, 657 658 _delay: function( handler, delay ) { 659 function handlerProxy() { 660 return ( typeof handler === "string" ? instance[ handler ] : handler ) 661 .apply( instance, arguments ); 662 } 663 var instance = this; 664 return setTimeout( handlerProxy, delay || 0 ); 665 }, 666 667 _hoverable: function( element ) { 668 this.hoverable = this.hoverable.add( element ); 669 this._on( element, { 670 mouseenter: function( event ) { 671 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 672 }, 673 mouseleave: function( event ) { 674 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 675 } 676 } ); 677 }, 678 679 _focusable: function( element ) { 680 this.focusable = this.focusable.add( element ); 681 this._on( element, { 682 focusin: function( event ) { 683 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 684 }, 685 focusout: function( event ) { 686 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 687 } 688 } ); 689 }, 690 691 _trigger: function( type, event, data ) { 692 var prop, orig; 693 var callback = this.options[ type ]; 694 695 data = data || {}; 696 event = $.Event( event ); 697 event.type = ( type === this.widgetEventPrefix ? 698 type : 699 this.widgetEventPrefix + type ).toLowerCase(); 700 701 // The original event may come from any element 702 // so we need to reset the target on the new event 703 event.target = this.element[ 0 ]; 704 705 // Copy original event properties over to the new event 706 orig = event.originalEvent; 707 if ( orig ) { 708 for ( prop in orig ) { 709 if ( !( prop in event ) ) { 710 event[ prop ] = orig[ prop ]; 711 } 712 } 713 } 714 715 this.element.trigger( event, data ); 716 return !( typeof callback === "function" && 717 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 718 event.isDefaultPrevented() ); 719 } 720}; 721 722$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 723 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 724 if ( typeof options === "string" ) { 725 options = { effect: options }; 726 } 727 728 var hasOptions; 729 var effectName = !options ? 730 method : 731 options === true || typeof options === "number" ? 732 defaultEffect : 733 options.effect || defaultEffect; 734 735 options = options || {}; 736 if ( typeof options === "number" ) { 737 options = { duration: options }; 738 } else if ( options === true ) { 739 options = {}; 740 } 741 742 hasOptions = !$.isEmptyObject( options ); 743 options.complete = callback; 744 745 if ( options.delay ) { 746 element.delay( options.delay ); 747 } 748 749 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 750 element[ method ]( options ); 751 } else if ( effectName !== method && element[ effectName ] ) { 752 element[ effectName ]( options.duration, options.easing, callback ); 753 } else { 754 element.queue( function( next ) { 755 $( this )[ method ](); 756 if ( callback ) { 757 callback.call( element[ 0 ] ); 758 } 759 next(); 760 } ); 761 } 762 }; 763} ); 764 765var widget = $.widget; 766 767 768/*! 769 * jQuery UI Position 1.13.
7692 770 * http://jqueryui.com 771 * 772 * Copyright jQuery Foundation and other contributors 773 * Released under the MIT license. 774 * http://jquery.org/license 775 * 776 * http://api.jqueryui.com/position/ 777 */ 778 779//>>label: Position 780//>>group: Core 781//>>description: Positions elements relative to other elements. 782//>>docs: http://api.jqueryui.com/position/ 783//>>demos: http
vendor: 14,500 bytes, lines 783-1266
783://jqueryui.com/position/ 784 785 786( function() { 787var cachedScrollbarWidth, 788 max = Math.max, 789 abs = Math.abs, 790 rhorizontal = /left|center|right/, 791 rvertical = /top|center|bottom/, 792 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 793 rposition = /^\w+/, 794 rpercent = /%$/, 795 _position = $.fn.position; 796 797function getOffsets( offsets, width, height ) { 798 return [ 799 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 800 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 801 ]; 802} 803 804function parseCss( element, property ) { 805 return parseInt( $.css( element, property ), 10 ) || 0; 806} 807 808function isWindow( obj ) { 809 return obj != null && obj === obj.window; 810} 811 812function getDimensions( elem ) { 813 var raw = elem[ 0 ]; 814 if ( raw.nodeType === 9 ) { 815 return { 816 width: elem.width(), 817 height: elem.height(), 818 offset: { top: 0, left: 0 } 819 }; 820 } 821 if ( isWindow( raw ) ) { 822 return { 823 width: elem.width(), 824 height: elem.height(), 825 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 826 }; 827 } 828 if ( raw.preventDefault ) { 829 return { 830 width: 0, 831 height: 0, 832 offset: { top: raw.pageY, left: raw.pageX } 833 }; 834 } 835 return { 836 width: elem.outerWidth(), 837 height: elem.outerHeight(), 838 offset: elem.offset() 839 }; 840} 841 842$.position = { 843 scrollbarWidth: function() { 844 if ( cachedScrollbarWidth !== undefined ) { 845 return cachedScrollbarWidth; 846 } 847 var w1, w2, 848 div = $( "<div style=" + 849 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 850 "<div style='height:300px;width:auto;'></div></div>" ), 851 innerDiv = div.children()[ 0 ]; 852 853 $( "body" ).append( div ); 854 w1 = innerDiv.offsetWidth; 855 div.css( "overflow", "scroll" ); 856 857 w2 = innerDiv.offsetWidth; 858 859 if ( w1 === w2 ) { 860 w2 = div[ 0 ].clientWidth; 861 } 862 863 div.remove(); 864 865 return ( cachedScrollbarWidth = w1 - w2 ); 866 }, 867 getScrollInfo: function( within ) { 868 var overflowX = within.isWindow || within.isDocument ? "" : 869 within.element.css( "overflow-x" ), 870 overflowY = within.isWindow || within.isDocument ? "" : 871 within.element.css( "overflow-y" ), 872 hasOverflowX = overflowX === "scroll" || 873 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 874 hasOverflowY = overflowY === "scroll" || 875 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 876 return { 877 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 878 height: hasOverflowX ? $.position.scrollbarWidth() : 0 879 }; 880 }, 881 getWithinInfo: function( element ) { 882 var withinElement = $( element || window ), 883 isElemWindow = isWindow( withinElement[ 0 ] ), 884 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 885 hasOffset = !isElemWindow && !isDocument; 886 return { 887 element: withinElement, 888 isWindow: isElemWindow, 889 isDocument: isDocument, 890 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 891 scrollLeft: withinElement.scrollLeft(), 892 scrollTop: withinElement.scrollTop(), 893 width: withinElement.outerWidth(), 894 height: withinElement.outerHeight() 895 }; 896 } 897}; 898 899$.fn.position = function( options ) { 900 if ( !options || !options.of ) { 901 return _position.apply( this, arguments ); 902 } 903 904 // Make a copy, we don't want to modify arguments 905 options = $.extend( {}, options ); 906 907 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 908 909 // Make sure string options are treated as CSS selectors 910 target = typeof options.of === "string" ? 911 $( document ).find( options.of ) : 912 $( options.of ), 913 914 within = $.position.getWithinInfo( options.within ), 915 scrollInfo = $.position.getScrollInfo( within ), 916 collision = ( options.collision || "flip" ).split( " " ), 917 offsets = {}; 918 919 dimensions = getDimensions( target ); 920 if ( target[ 0 ].preventDefault ) { 921 922 // Force left top to allow flipping 923 options.at = "left top"; 924 } 925 targetWidth = dimensions.width; 926 targetHeight = dimensions.height; 927 targetOffset = dimensions.offset; 928 929 // Clone to reuse original targetOffset later 930 basePosition = $.extend( {}, targetOffset ); 931 932 // Force my and at to have valid horizontal and vertical positions 933 // if a value is missing or invalid, it will be converted to center 934 $.each( [ "my", "at" ], function() { 935 var pos = ( options[ this ] || "" ).split( " " ), 936 horizontalOffset, 937 verticalOffset; 938 939 if ( pos.length === 1 ) { 940 pos = rhorizontal.test( pos[ 0 ] ) ? 941 pos.concat( [ "center" ] ) : 942 rvertical.test( pos[ 0 ] ) ? 943 [ "center" ].concat( pos ) : 944 [ "center", "center" ]; 945 } 946 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 947 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 948 949 // Calculate offsets 950 horizontalOffset = roffset.exec( pos[ 0 ] ); 951 verticalOffset = roffset.exec( pos[ 1 ] ); 952 offsets[ this ] = [ 953 horizontalOffset ? horizontalOffset[ 0 ] : 0, 954 verticalOffset ? verticalOffset[ 0 ] : 0 955 ]; 956 957 // Reduce to just the positions without the offsets 958 options[ this ] = [ 959 rposition.exec( pos[ 0 ] )[ 0 ], 960 rposition.exec( pos[ 1 ] )[ 0 ] 961 ]; 962 } ); 963 964 // Normalize collision option 965 if ( collision.length === 1 ) { 966 collision[ 1 ] = collision[ 0 ]; 967 } 968 969 if ( options.at[ 0 ] === "right" ) { 970 basePosition.left += targetWidth; 971 } else if ( options.at[ 0 ] === "center" ) { 972 basePosition.left += targetWidth / 2; 973 } 974 975 if ( options.at[ 1 ] === "bottom" ) { 976 basePosition.top += targetHeight; 977 } else if ( options.at[ 1 ] === "center" ) { 978 basePosition.top += targetHeight / 2; 979 } 980 981 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 982 basePosition.left += atOffset[ 0 ]; 983 basePosition.top += atOffset[ 1 ]; 984 985 return this.each( function() { 986 var collisionPosition, using, 987 elem = $( this ), 988 elemWidth = elem.outerWidth(), 989 elemHeight = elem.outerHeight(), 990 marginLeft = parseCss( this, "marginLeft" ), 991 marginTop = parseCss( this, "marginTop" ), 992 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 993 scrollInfo.width, 994 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 995 scrollInfo.height, 996 position = $.extend( {}, basePosition ), 997 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 998 999 if ( options.my[ 0 ] === "right" ) { 1000 position.left -= elemWidth; 1001 } else if ( options.my[ 0 ] === "center" ) { 1002 position.left -= elemWidth / 2; 1003 } 1004 1005 if ( options.my[ 1 ] === "bottom" ) { 1006 position.top -= elemHeight; 1007 } else if ( options.my[ 1 ] === "center" ) { 1008 position.top -= elemHeight / 2; 1009 } 1010 1011 position.left += myOffset[ 0 ]; 1012 position.top += myOffset[ 1 ]; 1013 1014 collisionPosition = { 1015 marginLeft: marginLeft, 1016 marginTop: marginTop 1017 }; 1018 1019 $.each( [ "left", "top" ], function( i, dir ) { 1020 if ( $.ui.position[ collision[ i ] ] ) { 1021 $.ui.position[ collision[ i ] ][ dir ]( position, { 1022 targetWidth: targetWidth, 1023 targetHeight: targetHeight, 1024 elemWidth: elemWidth, 1025 elemHeight: elemHeight, 1026 collisionPosition: collisionPosition, 1027 collisionWidth: collisionWidth, 1028 collisionHeight: collisionHeight, 1029 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1030 my: options.my, 1031 at: options.at, 1032 within: within, 1033 elem: elem 1034 } ); 1035 } 1036 } ); 1037 1038 if ( options.using ) { 1039 1040 // Adds feedback as second argument to using callback, if present 1041 using = function( props ) { 1042 var left = targetOffset.left - position.left, 1043 right = left + targetWidth - elemWidth, 1044 top = targetOffset.top - position.top, 1045 bottom = top + targetHeight - elemHeight, 1046 feedback = { 1047 target: { 1048 element: target, 1049 left: targetOffset.left, 1050 top: targetOffset.top, 1051 width: targetWidth, 1052 height: targetHeight 1053 }, 1054 element: { 1055 element: elem, 1056 left: position.left, 1057 top: position.top, 1058 width: elemWidth, 1059 height: elemHeight 1060 }, 1061 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1062 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1063 }; 1064 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1065 feedback.horizontal = "center"; 1066 } 1067 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1068 feedback.vertical = "middle"; 1069 } 1070 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1071 feedback.important = "horizontal"; 1072 } else { 1073 feedback.important = "vertical"; 1074 } 1075 options.using.call( this, props, feedback ); 1076 }; 1077 } 1078 1079 elem.offset( $.extend( position, { using: using } ) ); 1080 } ); 1081}; 1082 1083$.ui.position = { 1084 fit: { 1085 left: function( position, data ) { 1086 var within = data.within, 1087 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1088 outerWidth = within.width, 1089 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1090 overLeft = withinOffset - collisionPosLeft, 1091 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1092 newOverRight; 1093 1094 // Element is wider than within 1095 if ( data.collisionWidth > outerWidth ) { 1096 1097 // Element is initially over the left side of within 1098 if ( overLeft > 0 && overRight <= 0 ) { 1099 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1100 withinOffset; 1101 position.left += overLeft - newOverRight; 1102 1103 // Element is initially over right side of within 1104 } else if ( overRight > 0 && overLeft <= 0 ) { 1105 position.left = withinOffset; 1106 1107 // Element is initially over both left and right sides of within 1108 } else { 1109 if ( overLeft > overRight ) { 1110 position.left = withinOffset + outerWidth - data.collisionWidth; 1111 } else { 1112 position.left = withinOffset; 1113 } 1114 } 1115 1116 // Too far left -> align with left edge 1117 } else if ( overLeft > 0 ) { 1118 position.left += overLeft; 1119 1120 // Too far right -> align with right edge 1121 } else if ( overRight > 0 ) { 1122 position.left -= overRight; 1123 1124 // Adjust based on position and margin 1125 } else { 1126 position.left = max( position.left - collisionPosLeft, position.left ); 1127 } 1128 }, 1129 top: function( position, data ) { 1130 var within = data.within, 1131 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1132 outerHeight = data.within.height, 1133 collisionPosTop = position.top - data.collisionPosition.marginTop, 1134 overTop = withinOffset - collisionPosTop, 1135 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1136 newOverBottom; 1137 1138 // Element is taller than within 1139 if ( data.collisionHeight > outerHeight ) { 1140 1141 // Element is initially over the top of within 1142 if ( overTop > 0 && overBottom <= 0 ) { 1143 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1144 withinOffset; 1145 position.top += overTop - newOverBottom; 1146 1147 // Element is initially over bottom of within 1148 } else if ( overBottom > 0 && overTop <= 0 ) { 1149 position.top = withinOffset; 1150 1151 // Element is initially over both top and bottom of within 1152 } else { 1153 if ( overTop > overBottom ) { 1154 position.top = withinOffset + outerHeight - data.collisionHeight; 1155 } else { 1156 position.top = withinOffset; 1157 } 1158 } 1159 1160 // Too far up -> align with top 1161 } else if ( overTop > 0 ) { 1162 position.top += overTop; 1163 1164 // Too far down -> align with bottom edge 1165 } else if ( overBottom > 0 ) { 1166 position.top -= overBottom; 1167 1168 // Adjust based on position and margin 1169 } else { 1170 position.top = max( position.top - collisionPosTop, position.top ); 1171 } 1172 } 1173 }, 1174 flip: { 1175 left: function( position, data ) { 1176 var within = data.within, 1177 withinOffset = within.offset.left + within.scrollLeft, 1178 outerWidth = within.width, 1179 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1180 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1181 overLeft = collisionPosLeft - offsetLeft, 1182 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1183 myOffset = data.my[ 0 ] === "left" ? 1184 -data.elemWidth : 1185 data.my[ 0 ] === "right" ? 1186 data.elemWidth : 1187 0, 1188 atOffset = data.at[ 0 ] === "left" ? 1189 data.targetWidth : 1190 data.at[ 0 ] === "right" ? 1191 -data.targetWidth : 1192 0, 1193 offset = -2 * data.offset[ 0 ], 1194 newOverRight, 1195 newOverLeft; 1196 1197 if ( overLeft < 0 ) { 1198 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1199 outerWidth - withinOffset; 1200 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1201 position.left += myOffset + atOffset + offset; 1202 } 1203 } else if ( overRight > 0 ) { 1204 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1205 atOffset + offset - offsetLeft; 1206 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1207 position.left += myOffset + atOffset + offset; 1208 } 1209 } 1210 }, 1211 top: function( position, data ) { 1212 var within = data.within, 1213 withinOffset = within.offset.top + within.scrollTop, 1214 outerHeight = within.height, 1215 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1216 collisionPosTop = position.top - data.collisionPosition.marginTop, 1217 overTop = collisionPosTop - offsetTop, 1218 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1219 top = data.my[ 1 ] === "top", 1220 myOffset = top ? 1221 -data.elemHeight : 1222 data.my[ 1 ] === "bottom" ? 1223 data.elemHeight : 1224 0, 1225 atOffset = data.at[ 1 ] === "top" ? 1226 data.targetHeight : 1227 data.at[ 1 ] === "bottom" ? 1228 -data.targetHeight : 1229 0, 1230 offset = -2 * data.offset[ 1 ], 1231 newOverTop, 1232 newOverBottom; 1233 if ( overTop < 0 ) { 1234 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1235 outerHeight - withinOffset; 1236 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1237 position.top += myOffset + atOffset + offset; 1238 } 1239 } else if ( overBottom > 0 ) { 1240 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1241 offset - offsetTop; 1242 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1243 position.top += myOffset + atOffset + offset; 1244 } 1245 } 1246 } 1247 }, 1248 flipfit: { 1249 left: function() { 1250 $.ui.position.flip.left.apply( this, arguments ); 1251 $.ui.position.fit.left.apply( this, arguments ); 1252 }, 1253 top: function() { 1254 $.ui.position.flip.top.apply( this, arguments ); 1255 $.ui.position.fit.top.apply( this, arguments ); 1256 } 1257 } 1258}; 1259 1260} )(); 1261 1262var position = $.ui.position; 1263 1264 1265/*! 1266 * jQuery UI :data 1.13.
12662 1267 * http://jqueryui.com 1268 * 1269 * Copyright jQuery Foundation and other contributors 1270 * Released under the MIT license. 1271 * http://jquery.org/license 1272 */ 1273 1274//>>label: :data Selector
vendor: 1,696 bytes, lines 1275-1343
1275//>>group: Core 1276//>>description: Selects elements which have data stored under the specified key. 1277//>>docs: http://api.jqueryui.com/data-selector/ 1278 1279 1280var data = $.extend( $.expr.pseudos, { 1281 data: $.expr.createPseudo ? 1282 $.expr.createPseudo( function( dataName ) { 1283 return function( elem ) { 1284 return !!$.data( elem, dataName ); 1285 }; 1286 } ) : 1287 1288 // Support: jQuery <1.8 1289 function( elem, i, match ) { 1290 return !!$.data( elem, match[ 3 ] ); 1291 } 1292} ); 1293 1294/*! 1295 * jQuery UI Disable Selection 1.13.2 1296 * http://jqueryui.com 1297 * 1298 * Copyright jQuery Foundation and other contributors 1299 * Released under the MIT license. 1300 * http://jquery.org/license 1301 */ 1302 1303//>>label: disableSelection 1304//>>group: Core 1305//>>description: Disable selection of text content within the set of matched elements. 1306//>>docs: http://api.jqueryui.com/disableSelection/ 1307 1308// This file is deprecated 1309 1310var disableSelection = $.fn.extend( { 1311 disableSelection: ( function() { 1312 var eventType = "onselectstart" in document.createElement( "div" ) ? 1313 "selectstart" : 1314 "mousedown"; 1315 1316 return function() { 1317 return this.on( eventType + ".ui-disableSelection", function( event ) { 1318 event.preventDefault(); 1319 } ); 1320 }; 1321 } )(), 1322 1323 enableSelection: function() { 1324 return this.off( ".ui-disableSelection" ); 1325 } 1326} ); 1327 1328 1329 1330// Create a local jQuery because jQuery Color relies on it and the 1331// global may not exist with AMD and a custom build (#10199). 1332// This module is a noop if used as a regular AMD module. 1333// eslint-disable-next-line no-unused-vars 1334var jQuery = $; 1335 1336 1337/*! 1338 * jQuery Color Animations v2.2.0 1339 * https://github.com/jquery/jquery-color 1340 * 1341 * Copyright OpenJS Foundation and other contributors 1342 * Released under the MIT license. 1343 * http
vendor: 16,926 bytes, lines 1343-2050
1343://jquery.org/license 1344 * 1345 * Date: Sun May 10 09:02:36 2020 +0200 1346 */ 1347 1348 1349 1350 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 1351 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 1352 1353 class2type = {}, 1354 toString = class2type.toString, 1355 1356 // plusequals test for += 100 -= 100 1357 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 1358 1359 // a set of RE's that can match strings and generate color tuples. 1360 stringParsers = [ { 1361 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 1362 parse: function( execResult ) { 1363 return [ 1364 execResult[ 1 ], 1365 execResult[ 2 ], 1366 execResult[ 3 ], 1367 execResult[ 4 ] 1368 ]; 1369 } 1370 }, { 1371 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 1372 parse: function( execResult ) { 1373 return [ 1374 execResult[ 1 ] * 2.55, 1375 execResult[ 2 ] * 2.55, 1376 execResult[ 3 ] * 2.55, 1377 execResult[ 4 ] 1378 ]; 1379 } 1380 }, { 1381 1382 // this regex ignores A-F because it's compared against an already lowercased string 1383 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 1384 parse: function( execResult ) { 1385 return [ 1386 parseInt( execResult[ 1 ], 16 ), 1387 parseInt( execResult[ 2 ], 16 ), 1388 parseInt( execResult[ 3 ], 16 ), 1389 execResult[ 4 ] ? 1390 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 1391 1 1392 ]; 1393 } 1394 }, { 1395 1396 // this regex ignores A-F because it's compared against an already lowercased string 1397 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 1398 parse: function( execResult ) { 1399 return [ 1400 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 1401 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 1402 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 1403 execResult[ 4 ] ? 1404 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 1405 .toFixed( 2 ) : 1406 1 1407 ]; 1408 } 1409 }, { 1410 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 1411 space: "hsla", 1412 parse: function( execResult ) { 1413 return [ 1414 execResult[ 1 ], 1415 execResult[ 2 ] / 100, 1416 execResult[ 3 ] / 100, 1417 execResult[ 4 ] 1418 ]; 1419 } 1420 } ], 1421 1422 // jQuery.Color( ) 1423 color = jQuery.Color = function( color, green, blue, alpha ) { 1424 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 1425 }, 1426 spaces = { 1427 rgba: { 1428 props: { 1429 red: { 1430 idx: 0, 1431 type: "byte" 1432 }, 1433 green: { 1434 idx: 1, 1435 type: "byte" 1436 }, 1437 blue: { 1438 idx: 2, 1439 type: "byte" 1440 } 1441 } 1442 }, 1443 1444 hsla: { 1445 props: { 1446 hue: { 1447 idx: 0, 1448 type: "degrees" 1449 }, 1450 saturation: { 1451 idx: 1, 1452 type: "percent" 1453 }, 1454 lightness: { 1455 idx: 2, 1456 type: "percent" 1457 } 1458 } 1459 } 1460 }, 1461 propTypes = { 1462 "byte": { 1463 floor: true, 1464 max: 255 1465 }, 1466 "percent": { 1467 max: 1 1468 }, 1469 "degrees": { 1470 mod: 360, 1471 floor: true 1472 } 1473 }, 1474 support = color.support = {}, 1475 1476 // element for support tests 1477 supportElem = jQuery( "<p>" )[ 0 ], 1478 1479 // colors = jQuery.Color.names 1480 colors, 1481 1482 // local aliases of functions called often 1483 each = jQuery.each; 1484 1485// determine rgba support immediately 1486supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 1487support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 1488 1489// define cache name and alpha properties 1490// for rgba and hsla spaces 1491each( spaces, function( spaceName, space ) { 1492 space.cache = "_" + spaceName; 1493 space.props.alpha = { 1494 idx: 3, 1495 type: "percent", 1496 def: 1 1497 }; 1498} ); 1499 1500// Populate the class2type map 1501jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 1502 function( _i, name ) { 1503 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 1504 } ); 1505 1506function getType( obj ) { 1507 if ( obj == null ) { 1508 return obj + ""; 1509 } 1510 1511 return typeof obj === "object" ? 1512 class2type[ toString.call( obj ) ] || "object" : 1513 typeof obj; 1514} 1515 1516function clamp( value, prop, allowEmpty ) { 1517 var type = propTypes[ prop.type ] || {}; 1518 1519 if ( value == null ) { 1520 return ( allowEmpty || !prop.def ) ? null : prop.def; 1521 } 1522 1523 // ~~ is an short way of doing floor for positive numbers 1524 value = type.floor ? ~~value : parseFloat( value ); 1525 1526 // IE will pass in empty strings as value for alpha, 1527 // which will hit this case 1528 if ( isNaN( value ) ) { 1529 return prop.def; 1530 } 1531 1532 if ( type.mod ) { 1533 1534 // we add mod before modding to make sure that negatives values 1535 // get converted properly: -10 -> 350 1536 return ( value + type.mod ) % type.mod; 1537 } 1538 1539 // for now all property types without mod have min and max 1540 return Math.min( type.max, Math.max( 0, value ) ); 1541} 1542 1543function stringParse( string ) { 1544 var inst = color(), 1545 rgba = inst._rgba = []; 1546 1547 string = string.toLowerCase(); 1548 1549 each( stringParsers, function( _i, parser ) { 1550 var parsed, 1551 match = parser.re.exec( string ), 1552 values = match && parser.parse( match ), 1553 spaceName = parser.space || "rgba"; 1554 1555 if ( values ) { 1556 parsed = inst[ spaceName ]( values ); 1557 1558 // if this was an rgba parse the assignment might happen twice 1559 // oh well.... 1560 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 1561 rgba = inst._rgba = parsed._rgba; 1562 1563 // exit each( stringParsers ) here because we matched 1564 return false; 1565 } 1566 } ); 1567 1568 // Found a stringParser that handled it 1569 if ( rgba.length ) { 1570 1571 // if this came from a parsed string, force "transparent" when alpha is 0 1572 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 1573 if ( rgba.join() === "0,0,0,0" ) { 1574 jQuery.extend( rgba, colors.transparent ); 1575 } 1576 return inst; 1577 } 1578 1579 // named colors 1580 return colors[ string ]; 1581} 1582 1583color.fn = jQuery.extend( color.prototype, { 1584 parse: function( red, green, blue, alpha ) { 1585 if ( red === undefined ) { 1586 this._rgba = [ null, null, null, null ]; 1587 return this; 1588 } 1589 if ( red.jquery || red.nodeType ) { 1590 red = jQuery( red ).css( green ); 1591 green = undefined; 1592 } 1593 1594 var inst = this, 1595 type = getType( red ), 1596 rgba = this._rgba = []; 1597 1598 // more than 1 argument specified - assume ( red, green, blue, alpha ) 1599 if ( green !== undefined ) { 1600 red = [ red, green, blue, alpha ]; 1601 type = "array"; 1602 } 1603 1604 if ( type === "string" ) { 1605 return this.parse( stringParse( red ) || colors._default ); 1606 } 1607 1608 if ( type === "array" ) { 1609 each( spaces.rgba.props, function( _key, prop ) { 1610 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 1611 } ); 1612 return this; 1613 } 1614 1615 if ( type === "object" ) { 1616 if ( red instanceof color ) { 1617 each( spaces, function( _spaceName, space ) { 1618 if ( red[ space.cache ] ) { 1619 inst[ space.cache ] = red[ space.cache ].slice(); 1620 } 1621 } ); 1622 } else { 1623 each( spaces, function( _spaceName, space ) { 1624 var cache = space.cache; 1625 each( space.props, function( key, prop ) { 1626 1627 // if the cache doesn't exist, and we know how to convert 1628 if ( !inst[ cache ] && space.to ) { 1629 1630 // if the value was null, we don't need to copy it 1631 // if the key was alpha, we don't need to copy it either 1632 if ( key === "alpha" || red[ key ] == null ) { 1633 return; 1634 } 1635 inst[ cache ] = space.to( inst._rgba ); 1636 } 1637 1638 // this is the only case where we allow nulls for ALL properties. 1639 // call clamp with alwaysAllowEmpty 1640 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 1641 } ); 1642 1643 // everything defined but alpha? 1644 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 1645 1646 // use the default of 1 1647 if ( inst[ cache ][ 3 ] == null ) { 1648 inst[ cache ][ 3 ] = 1; 1649 } 1650 1651 if ( space.from ) { 1652 inst._rgba = space.from( inst[ cache ] ); 1653 } 1654 } 1655 } ); 1656 } 1657 return this; 1658 } 1659 }, 1660 is: function( compare ) { 1661 var is = color( compare ), 1662 same = true, 1663 inst = this; 1664 1665 each( spaces, function( _, space ) { 1666 var localCache, 1667 isCache = is[ space.cache ]; 1668 if ( isCache ) { 1669 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 1670 each( space.props, function( _, prop ) { 1671 if ( isCache[ prop.idx ] != null ) { 1672 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 1673 return same; 1674 } 1675 } ); 1676 } 1677 return same; 1678 } ); 1679 return same; 1680 }, 1681 _space: function() { 1682 var used = [], 1683 inst = this; 1684 each( spaces, function( spaceName, space ) { 1685 if ( inst[ space.cache ] ) { 1686 used.push( spaceName ); 1687 } 1688 } ); 1689 return used.pop(); 1690 }, 1691 transition: function( other, distance ) { 1692 var end = color( other ), 1693 spaceName = end._space(), 1694 space = spaces[ spaceName ], 1695 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 1696 start = startColor[ space.cache ] || space.to( startColor._rgba ), 1697 result = start.slice(); 1698 1699 end = end[ space.cache ]; 1700 each( space.props, function( _key, prop ) { 1701 var index = prop.idx, 1702 startValue = start[ index ], 1703 endValue = end[ index ], 1704 type = propTypes[ prop.type ] || {}; 1705 1706 // if null, don't override start value 1707 if ( endValue === null ) { 1708 return; 1709 } 1710 1711 // if null - use end 1712 if ( startValue === null ) { 1713 result[ index ] = endValue; 1714 } else { 1715 if ( type.mod ) { 1716 if ( endValue - startValue > type.mod / 2 ) { 1717 startValue += type.mod; 1718 } else if ( startValue - endValue > type.mod / 2 ) { 1719 startValue -= type.mod; 1720 } 1721 } 1722 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 1723 } 1724 } ); 1725 return this[ spaceName ]( result ); 1726 }, 1727 blend: function( opaque ) { 1728 1729 // if we are already opaque - return ourself 1730 if ( this._rgba[ 3 ] === 1 ) { 1731 return this; 1732 } 1733 1734 var rgb = this._rgba.slice(), 1735 a = rgb.pop(), 1736 blend = color( opaque )._rgba; 1737 1738 return color( jQuery.map( rgb, function( v, i ) { 1739 return ( 1 - a ) * blend[ i ] + a * v; 1740 } ) ); 1741 }, 1742 toRgbaString: function() { 1743 var prefix = "rgba(", 1744 rgba = jQuery.map( this._rgba, function( v, i ) { 1745 if ( v != null ) { 1746 return v; 1747 } 1748 return i > 2 ? 1 : 0; 1749 } ); 1750 1751 if ( rgba[ 3 ] === 1 ) { 1752 rgba.pop(); 1753 prefix = "rgb("; 1754 } 1755 1756 return prefix + rgba.join() + ")"; 1757 }, 1758 toHslaString: function() { 1759 var prefix = "hsla(", 1760 hsla = jQuery.map( this.hsla(), function( v, i ) { 1761 if ( v == null ) { 1762 v = i > 2 ? 1 : 0; 1763 } 1764 1765 // catch 1 and 2 1766 if ( i && i < 3 ) { 1767 v = Math.round( v * 100 ) + "%"; 1768 } 1769 return v; 1770 } ); 1771 1772 if ( hsla[ 3 ] === 1 ) { 1773 hsla.pop(); 1774 prefix = "hsl("; 1775 } 1776 return prefix + hsla.join() + ")"; 1777 }, 1778 toHexString: function( includeAlpha ) { 1779 var rgba = this._rgba.slice(), 1780 alpha = rgba.pop(); 1781 1782 if ( includeAlpha ) { 1783 rgba.push( ~~( alpha * 255 ) ); 1784 } 1785 1786 return "#" + jQuery.map( rgba, function( v ) { 1787 1788 // default to 0 when nulls exist 1789 v = ( v || 0 ).toString( 16 ); 1790 return v.length === 1 ? "0" + v : v; 1791 } ).join( "" ); 1792 }, 1793 toString: function() { 1794 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 1795 } 1796} ); 1797color.fn.parse.prototype = color.fn; 1798 1799// hsla conversions adapted from: 1800// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 1801 1802function hue2rgb( p, q, h ) { 1803 h = ( h + 1 ) % 1; 1804 if ( h * 6 < 1 ) { 1805 return p + ( q - p ) * h * 6; 1806 } 1807 if ( h * 2 < 1 ) { 1808 return q; 1809 } 1810 if ( h * 3 < 2 ) { 1811 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 1812 } 1813 return p; 1814} 1815 1816spaces.hsla.to = function( rgba ) { 1817 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 1818 return [ null, null, null, rgba[ 3 ] ]; 1819 } 1820 var r = rgba[ 0 ] / 255, 1821 g = rgba[ 1 ] / 255, 1822 b = rgba[ 2 ] / 255, 1823 a = rgba[ 3 ], 1824 max = Math.max( r, g, b ), 1825 min = Math.min( r, g, b ), 1826 diff = max - min, 1827 add = max + min, 1828 l = add * 0.5, 1829 h, s; 1830 1831 if ( min === max ) { 1832 h = 0; 1833 } else if ( r === max ) { 1834 h = ( 60 * ( g - b ) / diff ) + 360; 1835 } else if ( g === max ) { 1836 h = ( 60 * ( b - r ) / diff ) + 120; 1837 } else { 1838 h = ( 60 * ( r - g ) / diff ) + 240; 1839 } 1840 1841 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 1842 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 1843 if ( diff === 0 ) { 1844 s = 0; 1845 } else if ( l <= 0.5 ) { 1846 s = diff / add; 1847 } else { 1848 s = diff / ( 2 - add ); 1849 } 1850 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 1851}; 1852 1853spaces.hsla.from = function( hsla ) { 1854 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 1855 return [ null, null, null, hsla[ 3 ] ]; 1856 } 1857 var h = hsla[ 0 ] / 360, 1858 s = hsla[ 1 ], 1859 l = hsla[ 2 ], 1860 a = hsla[ 3 ], 1861 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 1862 p = 2 * l - q; 1863 1864 return [ 1865 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 1866 Math.round( hue2rgb( p, q, h ) * 255 ), 1867 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 1868 a 1869 ]; 1870}; 1871 1872 1873each( spaces, function( spaceName, space ) { 1874 var props = space.props, 1875 cache = space.cache, 1876 to = space.to, 1877 from = space.from; 1878 1879 // makes rgba() and hsla() 1880 color.fn[ spaceName ] = function( value ) { 1881 1882 // generate a cache for this space if it doesn't exist 1883 if ( to && !this[ cache ] ) { 1884 this[ cache ] = to( this._rgba ); 1885 } 1886 if ( value === undefined ) { 1887 return this[ cache ].slice(); 1888 } 1889 1890 var ret, 1891 type = getType( value ), 1892 arr = ( type === "array" || type === "object" ) ? value : arguments, 1893 local = this[ cache ].slice(); 1894 1895 each( props, function( key, prop ) { 1896 var val = arr[ type === "object" ? key : prop.idx ]; 1897 if ( val == null ) { 1898 val = local[ prop.idx ]; 1899 } 1900 local[ prop.idx ] = clamp( val, prop ); 1901 } ); 1902 1903 if ( from ) { 1904 ret = color( from( local ) ); 1905 ret[ cache ] = local; 1906 return ret; 1907 } else { 1908 return color( local ); 1909 } 1910 }; 1911 1912 // makes red() green() blue() alpha() hue() saturation() lightness() 1913 each( props, function( key, prop ) { 1914 1915 // alpha is included in more than one space 1916 if ( color.fn[ key ] ) { 1917 return; 1918 } 1919 color.fn[ key ] = function( value ) { 1920 var local, cur, match, fn, 1921 vtype = getType( value ); 1922 1923 if ( key === "alpha" ) { 1924 fn = this._hsla ? "hsla" : "rgba"; 1925 } else { 1926 fn = spaceName; 1927 } 1928 local = this[ fn ](); 1929 cur = local[ prop.idx ]; 1930 1931 if ( vtype === "undefined" ) { 1932 return cur; 1933 } 1934 1935 if ( vtype === "function" ) { 1936 value = value.call( this, cur ); 1937 vtype = getType( value ); 1938 } 1939 if ( value == null && prop.empty ) { 1940 return this; 1941 } 1942 if ( vtype === "string" ) { 1943 match = rplusequals.exec( value ); 1944 if ( match ) { 1945 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 1946 } 1947 } 1948 local[ prop.idx ] = value; 1949 return this[ fn ]( local ); 1950 }; 1951 } ); 1952} ); 1953 1954// add cssHook and .fx.step function for each named hook. 1955// accept a space separated string of properties 1956color.hook = function( hook ) { 1957 var hooks = hook.split( " " ); 1958 each( hooks, function( _i, hook ) { 1959 jQuery.cssHooks[ hook ] = { 1960 set: function( elem, value ) { 1961 var parsed, curElem, 1962 backgroundColor = ""; 1963 1964 if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 1965 value = color( parsed || value ); 1966 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 1967 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 1968 while ( 1969 ( backgroundColor === "" || backgroundColor === "transparent" ) && 1970 curElem && curElem.style 1971 ) { 1972 try { 1973 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 1974 curElem = curElem.parentNode; 1975 } catch ( e ) { 1976 } 1977 } 1978 1979 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 1980 backgroundColor : 1981 "_default" ); 1982 } 1983 1984 value = value.toRgbaString(); 1985 } 1986 try { 1987 elem.style[ hook ] = value; 1988 } catch ( e ) { 1989 1990 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 1991 } 1992 } 1993 }; 1994 jQuery.fx.step[ hook ] = function( fx ) { 1995 if ( !fx.colorInit ) { 1996 fx.start = color( fx.elem, hook ); 1997 fx.end = color( fx.end ); 1998 fx.colorInit = true; 1999 } 2000 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 2001 }; 2002 } ); 2003 2004}; 2005 2006color.hook( stepHooks ); 2007 2008jQuery.cssHooks.borderColor = { 2009 expand: function( value ) { 2010 var expanded = {}; 2011 2012 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 2013 expanded[ "border" + part + "Color" ] = value; 2014 } ); 2015 return expanded; 2016 } 2017}; 2018 2019// Basic color names only. 2020// Usage of any of the other color names requires adding yourself or including 2021// jquery.color.svg-names.js. 2022colors = jQuery.Color.names = { 2023 2024 // 4.1. Basic color keywords 2025 aqua: "#00ffff", 2026 black: "#000000", 2027 blue: "#0000ff", 2028 fuchsia: "#ff00ff", 2029 gray: "#808080", 2030 green: "#008000", 2031 lime: "#00ff00", 2032 maroon: "#800000", 2033 navy: "#000080", 2034 olive: "#808000", 2035 purple: "#800080", 2036 red: "#ff0000", 2037 silver: "#c0c0c0", 2038 teal: "#008080", 2039 white: "#ffffff", 2040 yellow: "#ffff00", 2041 2042 // 4.2.3. "transparent" color keyword 2043 transparent: [ null, null, null, 0 ], 2044 2045 _default: "#ffffff" 2046}; 2047 2048 2049/*! 2050 * jQuery UI Effects 1.13.
20502 2051 * http://jqueryui.com 2052 * 2053 * Copyright jQuery Foundation and other contributors 2054 * Released under the MIT license. 2055 * http://jquery.org/license 2056 */ 2057 2058//>>label: Effects Core 2059//>>group: Effects 2060/* eslint-disable max-len */ 2061//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 2062/* eslint-enable max-len */ 2063//>>docs: http://api.jqueryui.com/category/effects-core/ 2064//>>demos: http
vendor: 9,484 bytes, lines 2064-2434
2064://jqueryui.com/effect/ 2065 2066 2067var dataSpace = "ui-effects-", 2068 dataSpaceStyle = "ui-effects-style", 2069 dataSpaceAnimated = "ui-effects-animated"; 2070 2071$.effects = { 2072 effect: {} 2073}; 2074 2075/******************************************************************************/ 2076/****************************** CLASS ANIMATIONS ******************************/ 2077/******************************************************************************/ 2078( function() { 2079 2080var classAnimationActions = [ "add", "remove", "toggle" ], 2081 shorthandStyles = { 2082 border: 1, 2083 borderBottom: 1, 2084 borderColor: 1, 2085 borderLeft: 1, 2086 borderRight: 1, 2087 borderTop: 1, 2088 borderWidth: 1, 2089 margin: 1, 2090 padding: 1 2091 }; 2092 2093$.each( 2094 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 2095 function( _, prop ) { 2096 $.fx.step[ prop ] = function( fx ) { 2097 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 2098 jQuery.style( fx.elem, prop, fx.end ); 2099 fx.setAttr = true; 2100 } 2101 }; 2102 } 2103); 2104 2105function camelCase( string ) { 2106 return string.replace( /-([\da-z])/gi, function( all, letter ) { 2107 return letter.toUpperCase(); 2108 } ); 2109} 2110 2111function getElementStyles( elem ) { 2112 var key, len, 2113 style = elem.ownerDocument.defaultView ? 2114 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 2115 elem.currentStyle, 2116 styles = {}; 2117 2118 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 2119 len = style.length; 2120 while ( len-- ) { 2121 key = style[ len ]; 2122 if ( typeof style[ key ] === "string" ) { 2123 styles[ camelCase( key ) ] = style[ key ]; 2124 } 2125 } 2126 2127 // Support: Opera, IE <9 2128 } else { 2129 for ( key in style ) { 2130 if ( typeof style[ key ] === "string" ) { 2131 styles[ key ] = style[ key ]; 2132 } 2133 } 2134 } 2135 2136 return styles; 2137} 2138 2139function styleDifference( oldStyle, newStyle ) { 2140 var diff = {}, 2141 name, value; 2142 2143 for ( name in newStyle ) { 2144 value = newStyle[ name ]; 2145 if ( oldStyle[ name ] !== value ) { 2146 if ( !shorthandStyles[ name ] ) { 2147 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 2148 diff[ name ] = value; 2149 } 2150 } 2151 } 2152 } 2153 2154 return diff; 2155} 2156 2157// Support: jQuery <1.8 2158if ( !$.fn.addBack ) { 2159 $.fn.addBack = function( selector ) { 2160 return this.add( selector == null ? 2161 this.prevObject : this.prevObject.filter( selector ) 2162 ); 2163 }; 2164} 2165 2166$.effects.animateClass = function( value, duration, easing, callback ) { 2167 var o = $.speed( duration, easing, callback ); 2168 2169 return this.queue( function() { 2170 var animated = $( this ), 2171 baseClass = animated.attr( "class" ) || "", 2172 applyClassChange, 2173 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 2174 2175 // Map the animated objects to store the original styles. 2176 allAnimations = allAnimations.map( function() { 2177 var el = $( this ); 2178 return { 2179 el: el, 2180 start: getElementStyles( this ) 2181 }; 2182 } ); 2183 2184 // Apply class change 2185 applyClassChange = function() { 2186 $.each( classAnimationActions, function( i, action ) { 2187 if ( value[ action ] ) { 2188 animated[ action + "Class" ]( value[ action ] ); 2189 } 2190 } ); 2191 }; 2192 applyClassChange(); 2193 2194 // Map all animated objects again - calculate new styles and diff 2195 allAnimations = allAnimations.map( function() { 2196 this.end = getElementStyles( this.el[ 0 ] ); 2197 this.diff = styleDifference( this.start, this.end ); 2198 return this; 2199 } ); 2200 2201 // Apply original class 2202 animated.attr( "class", baseClass ); 2203 2204 // Map all animated objects again - this time collecting a promise 2205 allAnimations = allAnimations.map( function() { 2206 var styleInfo = this, 2207 dfd = $.Deferred(), 2208 opts = $.extend( {}, o, { 2209 queue: false, 2210 complete: function() { 2211 dfd.resolve( styleInfo ); 2212 } 2213 } ); 2214 2215 this.el.animate( this.diff, opts ); 2216 return dfd.promise(); 2217 } ); 2218 2219 // Once all animations have completed: 2220 $.when.apply( $, allAnimations.get() ).done( function() { 2221 2222 // Set the final class 2223 applyClassChange(); 2224 2225 // For each animated element, 2226 // clear all css properties that were animated 2227 $.each( arguments, function() { 2228 var el = this.el; 2229 $.each( this.diff, function( key ) { 2230 el.css( key, "" ); 2231 } ); 2232 } ); 2233 2234 // This is guarnteed to be there if you use jQuery.speed() 2235 // it also handles dequeuing the next anim... 2236 o.complete.call( animated[ 0 ] ); 2237 } ); 2238 } ); 2239}; 2240 2241$.fn.extend( { 2242 addClass: ( function( orig ) { 2243 return function( classNames, speed, easing, callback ) { 2244 return speed ? 2245 $.effects.animateClass.call( this, 2246 { add: classNames }, speed, easing, callback ) : 2247 orig.apply( this, arguments ); 2248 }; 2249 } )( $.fn.addClass ), 2250 2251 removeClass: ( function( orig ) { 2252 return function( classNames, speed, easing, callback ) { 2253 return arguments.length > 1 ? 2254 $.effects.animateClass.call( this, 2255 { remove: classNames }, speed, easing, callback ) : 2256 orig.apply( this, arguments ); 2257 }; 2258 } )( $.fn.removeClass ), 2259 2260 toggleClass: ( function( orig ) { 2261 return function( classNames, force, speed, easing, callback ) { 2262 if ( typeof force === "boolean" || force === undefined ) { 2263 if ( !speed ) { 2264 2265 // Without speed parameter 2266 return orig.apply( this, arguments ); 2267 } else { 2268 return $.effects.animateClass.call( this, 2269 ( force ? { add: classNames } : { remove: classNames } ), 2270 speed, easing, callback ); 2271 } 2272 } else { 2273 2274 // Without force parameter 2275 return $.effects.animateClass.call( this, 2276 { toggle: classNames }, force, speed, easing ); 2277 } 2278 }; 2279 } )( $.fn.toggleClass ), 2280 2281 switchClass: function( remove, add, speed, easing, callback ) { 2282 return $.effects.animateClass.call( this, { 2283 add: add, 2284 remove: remove 2285 }, speed, easing, callback ); 2286 } 2287} ); 2288 2289} )(); 2290 2291/******************************************************************************/ 2292/*********************************** EFFECTS **********************************/ 2293/******************************************************************************/ 2294 2295( function() { 2296 2297if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 2298 $.expr.pseudos.animated = ( function( orig ) { 2299 return function( elem ) { 2300 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 2301 }; 2302 } )( $.expr.pseudos.animated ); 2303} 2304 2305if ( $.uiBackCompat !== false ) { 2306 $.extend( $.effects, { 2307 2308 // Saves a set of properties in a data storage 2309 save: function( element, set ) { 2310 var i = 0, length = set.length; 2311 for ( ; i < length; i++ ) { 2312 if ( set[ i ] !== null ) { 2313 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 2314 } 2315 } 2316 }, 2317 2318 // Restores a set of previously saved properties from a data storage 2319 restore: function( element, set ) { 2320 var val, i = 0, length = set.length; 2321 for ( ; i < length; i++ ) { 2322 if ( set[ i ] !== null ) { 2323 val = element.data( dataSpace + set[ i ] ); 2324 element.css( set[ i ], val ); 2325 } 2326 } 2327 }, 2328 2329 setMode: function( el, mode ) { 2330 if ( mode === "toggle" ) { 2331 mode = el.is( ":hidden" ) ? "show" : "hide"; 2332 } 2333 return mode; 2334 }, 2335 2336 // Wraps the element around a wrapper that copies position properties 2337 createWrapper: function( element ) { 2338 2339 // If the element is already wrapped, return it 2340 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 2341 return element.parent(); 2342 } 2343 2344 // Wrap the element 2345 var props = { 2346 width: element.outerWidth( true ), 2347 height: element.outerHeight( true ), 2348 "float": element.css( "float" ) 2349 }, 2350 wrapper = $( "<div></div>" ) 2351 .addClass( "ui-effects-wrapper" ) 2352 .css( { 2353 fontSize: "100%", 2354 background: "transparent", 2355 border: "none", 2356 margin: 0, 2357 padding: 0 2358 } ), 2359 2360 // Store the size in case width/height are defined in % - Fixes #5245 2361 size = { 2362 width: element.width(), 2363 height: element.height() 2364 }, 2365 active = document.activeElement; 2366 2367 // Support: Firefox 2368 // Firefox incorrectly exposes anonymous content 2369 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 2370 try { 2371 // eslint-disable-next-line no-unused-expressions 2372 active.id; 2373 } catch ( e ) { 2374 active = document.body; 2375 } 2376 2377 element.wrap( wrapper ); 2378 2379 // Fixes #7595 - Elements lose focus when wrapped. 2380 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 2381 $( active ).trigger( "focus" ); 2382 } 2383 2384 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 2385 // lose the reference to the wrapped element 2386 wrapper = element.parent(); 2387 2388 // Transfer positioning properties to the wrapper 2389 if ( element.css( "position" ) === "static" ) { 2390 wrapper.css( { position: "relative" } ); 2391 element.css( { position: "relative" } ); 2392 } else { 2393 $.extend( props, { 2394 position: element.css( "position" ), 2395 zIndex: element.css( "z-index" ) 2396 } ); 2397 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 2398 props[ pos ] = element.css( pos ); 2399 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 2400 props[ pos ] = "auto"; 2401 } 2402 } ); 2403 element.css( { 2404 position: "relative", 2405 top: 0, 2406 left: 0, 2407 right: "auto", 2408 bottom: "auto" 2409 } ); 2410 } 2411 element.css( size ); 2412 2413 return wrapper.css( props ).show(); 2414 }, 2415 2416 removeWrapper: function( element ) { 2417 var active = document.activeElement; 2418 2419 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 2420 element.parent().replaceWith( element ); 2421 2422 // Fixes #7595 - Elements lose focus when wrapped. 2423 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 2424 $( active ).trigger( "focus" ); 2425 } 2426 } 2427 2428 return element; 2429 } 2430 } ); 2431} 2432 2433$.extend( $.effects, { 2434 version: "1.13.
vendor: 2,055 bytes, lines 2434-2529
24342", 2435 2436 define: function( name, mode, effect ) { 2437 if ( !effect ) { 2438 effect = mode; 2439 mode = "effect"; 2440 } 2441 2442 $.effects.effect[ name ] = effect; 2443 $.effects.effect[ name ].mode = mode; 2444 2445 return effect; 2446 }, 2447 2448 scaledDimensions: function( element, percent, direction ) { 2449 if ( percent === 0 ) { 2450 return { 2451 height: 0, 2452 width: 0, 2453 outerHeight: 0, 2454 outerWidth: 0 2455 }; 2456 } 2457 2458 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 2459 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 2460 2461 return { 2462 height: element.height() * y, 2463 width: element.width() * x, 2464 outerHeight: element.outerHeight() * y, 2465 outerWidth: element.outerWidth() * x 2466 }; 2467 2468 }, 2469 2470 clipToBox: function( animation ) { 2471 return { 2472 width: animation.clip.right - animation.clip.left, 2473 height: animation.clip.bottom - animation.clip.top, 2474 left: animation.clip.left, 2475 top: animation.clip.top 2476 }; 2477 }, 2478 2479 // Injects recently queued functions to be first in line (after "inprogress") 2480 unshift: function( element, queueLength, count ) { 2481 var queue = element.queue(); 2482 2483 if ( queueLength > 1 ) { 2484 queue.splice.apply( queue, 2485 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 2486 } 2487 element.dequeue(); 2488 }, 2489 2490 saveStyle: function( element ) { 2491 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 2492 }, 2493 2494 restoreStyle: function( element ) { 2495 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 2496 element.removeData( dataSpaceStyle ); 2497 }, 2498 2499 mode: function( element, mode ) { 2500 var hidden = element.is( ":hidden" ); 2501 2502 if ( mode === "toggle" ) { 2503 mode = hidden ? "show" : "hide"; 2504 } 2505 if ( hidden ? mode === "hide" : mode === "show" ) { 2506 mode = "none"; 2507 } 2508 return mode; 2509 }, 2510 2511 // Translates a [top,left] array into a baseline value 2512 getBaseline: function( origin, original ) { 2513 var y, x; 2514 2515 switch ( origin[ 0 ] ) { 2516 case "top": 2517 y = 0; 2518 break; 2519 case "middle": 2520 y = 0.5; 2521 break; 2522 case "bottom": 2523 y = 1; 2524 break; 2525 default: 2526 y = origin[ 0 ] / original.height; 2527 } 2528 2529 switch ( origin[ 1 ] ) {
2530 case "left": 2531 x = 0; 2532 break; 2533 case "center": 2534 x = 0.5; 2535 break; 2536 case "right": 2537 x = 1; 2538 break; 2539 default: 2540 x = origin[ 1 ] / original.width; 2541 } 2542 2543 return { 2544 x: x, 2545 y: y 2546 }; 2547 }, 2548 2549 // Creates a placeholder element so that the original element can be made absolute 2550 createPlaceholder: function( element ) { 2551 var placeholder, 2552 cssPosition = element.css( "position" ), 2553 position = element.position(); 2554 2555 // Lock in margins first to account for form elements, which 2556 // will change margin if you explicitly set height 2557 // see: http
vendor: 10,558 bytes, lines 2557-2951
2557://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 2558 // Support: Safari 2559 element.css( { 2560 marginTop: element.css( "marginTop" ), 2561 marginBottom: element.css( "marginBottom" ), 2562 marginLeft: element.css( "marginLeft" ), 2563 marginRight: element.css( "marginRight" ) 2564 } ) 2565 .outerWidth( element.outerWidth() ) 2566 .outerHeight( element.outerHeight() ); 2567 2568 if ( /^(static|relative)/.test( cssPosition ) ) { 2569 cssPosition = "absolute"; 2570 2571 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 2572 2573 // Convert inline to inline block to account for inline elements 2574 // that turn to inline block based on content (like img) 2575 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 2576 "inline-block" : 2577 "block", 2578 visibility: "hidden", 2579 2580 // Margins need to be set to account for margin collapse 2581 marginTop: element.css( "marginTop" ), 2582 marginBottom: element.css( "marginBottom" ), 2583 marginLeft: element.css( "marginLeft" ), 2584 marginRight: element.css( "marginRight" ), 2585 "float": element.css( "float" ) 2586 } ) 2587 .outerWidth( element.outerWidth() ) 2588 .outerHeight( element.outerHeight() ) 2589 .addClass( "ui-effects-placeholder" ); 2590 2591 element.data( dataSpace + "placeholder", placeholder ); 2592 } 2593 2594 element.css( { 2595 position: cssPosition, 2596 left: position.left, 2597 top: position.top 2598 } ); 2599 2600 return placeholder; 2601 }, 2602 2603 removePlaceholder: function( element ) { 2604 var dataKey = dataSpace + "placeholder", 2605 placeholder = element.data( dataKey ); 2606 2607 if ( placeholder ) { 2608 placeholder.remove(); 2609 element.removeData( dataKey ); 2610 } 2611 }, 2612 2613 // Removes a placeholder if it exists and restores 2614 // properties that were modified during placeholder creation 2615 cleanUp: function( element ) { 2616 $.effects.restoreStyle( element ); 2617 $.effects.removePlaceholder( element ); 2618 }, 2619 2620 setTransition: function( element, list, factor, value ) { 2621 value = value || {}; 2622 $.each( list, function( i, x ) { 2623 var unit = element.cssUnit( x ); 2624 if ( unit[ 0 ] > 0 ) { 2625 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 2626 } 2627 } ); 2628 return value; 2629 } 2630} ); 2631 2632// Return an effect options object for the given parameters: 2633function _normalizeArguments( effect, options, speed, callback ) { 2634 2635 // Allow passing all options as the first parameter 2636 if ( $.isPlainObject( effect ) ) { 2637 options = effect; 2638 effect = effect.effect; 2639 } 2640 2641 // Convert to an object 2642 effect = { effect: effect }; 2643 2644 // Catch (effect, null, ...) 2645 if ( options == null ) { 2646 options = {}; 2647 } 2648 2649 // Catch (effect, callback) 2650 if ( typeof options === "function" ) { 2651 callback = options; 2652 speed = null; 2653 options = {}; 2654 } 2655 2656 // Catch (effect, speed, ?) 2657 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 2658 callback = speed; 2659 speed = options; 2660 options = {}; 2661 } 2662 2663 // Catch (effect, options, callback) 2664 if ( typeof speed === "function" ) { 2665 callback = speed; 2666 speed = null; 2667 } 2668 2669 // Add options to effect 2670 if ( options ) { 2671 $.extend( effect, options ); 2672 } 2673 2674 speed = speed || options.duration; 2675 effect.duration = $.fx.off ? 0 : 2676 typeof speed === "number" ? speed : 2677 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 2678 $.fx.speeds._default; 2679 2680 effect.complete = callback || options.complete; 2681 2682 return effect; 2683} 2684 2685function standardAnimationOption( option ) { 2686 2687 // Valid standard speeds (nothing, number, named speed) 2688 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 2689 return true; 2690 } 2691 2692 // Invalid strings - treat as "normal" speed 2693 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 2694 return true; 2695 } 2696 2697 // Complete callback 2698 if ( typeof option === "function" ) { 2699 return true; 2700 } 2701 2702 // Options hash (but not naming an effect) 2703 if ( typeof option === "object" && !option.effect ) { 2704 return true; 2705 } 2706 2707 // Didn't match any standard API 2708 return false; 2709} 2710 2711$.fn.extend( { 2712 effect: function( /* effect, options, speed, callback */ ) { 2713 var args = _normalizeArguments.apply( this, arguments ), 2714 effectMethod = $.effects.effect[ args.effect ], 2715 defaultMode = effectMethod.mode, 2716 queue = args.queue, 2717 queueName = queue || "fx", 2718 complete = args.complete, 2719 mode = args.mode, 2720 modes = [], 2721 prefilter = function( next ) { 2722 var el = $( this ), 2723 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 2724 2725 // Sentinel for duck-punching the :animated pseudo-selector 2726 el.data( dataSpaceAnimated, true ); 2727 2728 // Save effect mode for later use, 2729 // we can't just call $.effects.mode again later, 2730 // as the .show() below destroys the initial state 2731 modes.push( normalizedMode ); 2732 2733 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 2734 if ( defaultMode && ( normalizedMode === "show" || 2735 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 2736 el.show(); 2737 } 2738 2739 if ( !defaultMode || normalizedMode !== "none" ) { 2740 $.effects.saveStyle( el ); 2741 } 2742 2743 if ( typeof next === "function" ) { 2744 next(); 2745 } 2746 }; 2747 2748 if ( $.fx.off || !effectMethod ) { 2749 2750 // Delegate to the original method (e.g., .show()) if possible 2751 if ( mode ) { 2752 return this[ mode ]( args.duration, complete ); 2753 } else { 2754 return this.each( function() { 2755 if ( complete ) { 2756 complete.call( this ); 2757 } 2758 } ); 2759 } 2760 } 2761 2762 function run( next ) { 2763 var elem = $( this ); 2764 2765 function cleanup() { 2766 elem.removeData( dataSpaceAnimated ); 2767 2768 $.effects.cleanUp( elem ); 2769 2770 if ( args.mode === "hide" ) { 2771 elem.hide(); 2772 } 2773 2774 done(); 2775 } 2776 2777 function done() { 2778 if ( typeof complete === "function" ) { 2779 complete.call( elem[ 0 ] ); 2780 } 2781 2782 if ( typeof next === "function" ) { 2783 next(); 2784 } 2785 } 2786 2787 // Override mode option on a per element basis, 2788 // as toggle can be either show or hide depending on element state 2789 args.mode = modes.shift(); 2790 2791 if ( $.uiBackCompat !== false && !defaultMode ) { 2792 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 2793 2794 // Call the core method to track "olddisplay" properly 2795 elem[ mode ](); 2796 done(); 2797 } else { 2798 effectMethod.call( elem[ 0 ], args, done ); 2799 } 2800 } else { 2801 if ( args.mode === "none" ) { 2802 2803 // Call the core method to track "olddisplay" properly 2804 elem[ mode ](); 2805 done(); 2806 } else { 2807 effectMethod.call( elem[ 0 ], args, cleanup ); 2808 } 2809 } 2810 } 2811 2812 // Run prefilter on all elements first to ensure that 2813 // any showing or hiding happens before placeholder creation, 2814 // which ensures that any layout changes are correctly captured. 2815 return queue === false ? 2816 this.each( prefilter ).each( run ) : 2817 this.queue( queueName, prefilter ).queue( queueName, run ); 2818 }, 2819 2820 show: ( function( orig ) { 2821 return function( option ) { 2822 if ( standardAnimationOption( option ) ) { 2823 return orig.apply( this, arguments ); 2824 } else { 2825 var args = _normalizeArguments.apply( this, arguments ); 2826 args.mode = "show"; 2827 return this.effect.call( this, args ); 2828 } 2829 }; 2830 } )( $.fn.show ), 2831 2832 hide: ( function( orig ) { 2833 return function( option ) { 2834 if ( standardAnimationOption( option ) ) { 2835 return orig.apply( this, arguments ); 2836 } else { 2837 var args = _normalizeArguments.apply( this, arguments ); 2838 args.mode = "hide"; 2839 return this.effect.call( this, args ); 2840 } 2841 }; 2842 } )( $.fn.hide ), 2843 2844 toggle: ( function( orig ) { 2845 return function( option ) { 2846 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 2847 return orig.apply( this, arguments ); 2848 } else { 2849 var args = _normalizeArguments.apply( this, arguments ); 2850 args.mode = "toggle"; 2851 return this.effect.call( this, args ); 2852 } 2853 }; 2854 } )( $.fn.toggle ), 2855 2856 cssUnit: function( key ) { 2857 var style = this.css( key ), 2858 val = []; 2859 2860 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 2861 if ( style.indexOf( unit ) > 0 ) { 2862 val = [ parseFloat( style ), unit ]; 2863 } 2864 } ); 2865 return val; 2866 }, 2867 2868 cssClip: function( clipObj ) { 2869 if ( clipObj ) { 2870 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 2871 clipObj.bottom + "px " + clipObj.left + "px)" ); 2872 } 2873 return parseClip( this.css( "clip" ), this ); 2874 }, 2875 2876 transfer: function( options, done ) { 2877 var element = $( this ), 2878 target = $( options.to ), 2879 targetFixed = target.css( "position" ) === "fixed", 2880 body = $( "body" ), 2881 fixTop = targetFixed ? body.scrollTop() : 0, 2882 fixLeft = targetFixed ? body.scrollLeft() : 0, 2883 endPosition = target.offset(), 2884 animation = { 2885 top: endPosition.top - fixTop, 2886 left: endPosition.left - fixLeft, 2887 height: target.innerHeight(), 2888 width: target.innerWidth() 2889 }, 2890 startPosition = element.offset(), 2891 transfer = $( "<div class='ui-effects-transfer'></div>" ); 2892 2893 transfer 2894 .appendTo( "body" ) 2895 .addClass( options.className ) 2896 .css( { 2897 top: startPosition.top - fixTop, 2898 left: startPosition.left - fixLeft, 2899 height: element.innerHeight(), 2900 width: element.innerWidth(), 2901 position: targetFixed ? "fixed" : "absolute" 2902 } ) 2903 .animate( animation, options.duration, options.easing, function() { 2904 transfer.remove(); 2905 if ( typeof done === "function" ) { 2906 done(); 2907 } 2908 } ); 2909 } 2910} ); 2911 2912function parseClip( str, element ) { 2913 var outerWidth = element.outerWidth(), 2914 outerHeight = element.outerHeight(), 2915 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)\)$/, 2916 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 2917 2918 return { 2919 top: parseFloat( values[ 1 ] ) || 0, 2920 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 2921 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 2922 left: parseFloat( values[ 4 ] ) || 0 2923 }; 2924} 2925 2926$.fx.step.clip = function( fx ) { 2927 if ( !fx.clipInit ) { 2928 fx.start = $( fx.elem ).cssClip(); 2929 if ( typeof fx.end === "string" ) { 2930 fx.end = parseClip( fx.end, fx.elem ); 2931 } 2932 fx.clipInit = true; 2933 } 2934 2935 $( fx.elem ).cssClip( { 2936 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 2937 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 2938 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 2939 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 2940 } ); 2941}; 2942 2943} )(); 2944 2945/******************************************************************************/ 2946/*********************************** EASING ***********************************/ 2947/******************************************************************************/ 2948 2949( function() { 2950 2951// Based on easing equations from Robert Penner (http://
vendor: 24,998 bytes, lines 2951-3906
2951www.robertpenner.com/easing) 2952 2953var baseEasings = {}; 2954 2955$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 2956 baseEasings[ name ] = function( p ) { 2957 return Math.pow( p, i + 2 ); 2958 }; 2959} ); 2960 2961$.extend( baseEasings, { 2962 Sine: function( p ) { 2963 return 1 - Math.cos( p * Math.PI / 2 ); 2964 }, 2965 Circ: function( p ) { 2966 return 1 - Math.sqrt( 1 - p * p ); 2967 }, 2968 Elastic: function( p ) { 2969 return p === 0 || p === 1 ? p : 2970 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 2971 }, 2972 Back: function( p ) { 2973 return p * p * ( 3 * p - 2 ); 2974 }, 2975 Bounce: function( p ) { 2976 var pow2, 2977 bounce = 4; 2978 2979 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 2980 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 2981 } 2982} ); 2983 2984$.each( baseEasings, function( name, easeIn ) { 2985 $.easing[ "easeIn" + name ] = easeIn; 2986 $.easing[ "easeOut" + name ] = function( p ) { 2987 return 1 - easeIn( 1 - p ); 2988 }; 2989 $.easing[ "easeInOut" + name ] = function( p ) { 2990 return p < 0.5 ? 2991 easeIn( p * 2 ) / 2 : 2992 1 - easeIn( p * -2 + 2 ) / 2; 2993 }; 2994} ); 2995 2996} )(); 2997 2998var effect = $.effects; 2999 3000 3001/*! 3002 * jQuery UI Effects Blind 1.13.2 3003 * http://jqueryui.com 3004 * 3005 * Copyright jQuery Foundation and other contributors 3006 * Released under the MIT license. 3007 * http://jquery.org/license 3008 */ 3009 3010//>>label: Blind Effect 3011//>>group: Effects 3012//>>description: Blinds the element. 3013//>>docs: http://api.jqueryui.com/blind-effect/ 3014//>>demos: http://jqueryui.com/effect/ 3015 3016 3017var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 3018 var map = { 3019 up: [ "bottom", "top" ], 3020 vertical: [ "bottom", "top" ], 3021 down: [ "top", "bottom" ], 3022 left: [ "right", "left" ], 3023 horizontal: [ "right", "left" ], 3024 right: [ "left", "right" ] 3025 }, 3026 element = $( this ), 3027 direction = options.direction || "up", 3028 start = element.cssClip(), 3029 animate = { clip: $.extend( {}, start ) }, 3030 placeholder = $.effects.createPlaceholder( element ); 3031 3032 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 3033 3034 if ( options.mode === "show" ) { 3035 element.cssClip( animate.clip ); 3036 if ( placeholder ) { 3037 placeholder.css( $.effects.clipToBox( animate ) ); 3038 } 3039 3040 animate.clip = start; 3041 } 3042 3043 if ( placeholder ) { 3044 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 3045 } 3046 3047 element.animate( animate, { 3048 queue: false, 3049 duration: options.duration, 3050 easing: options.easing, 3051 complete: done 3052 } ); 3053} ); 3054 3055 3056/*! 3057 * jQuery UI Effects Bounce 1.13.2 3058 * http://jqueryui.com 3059 * 3060 * Copyright jQuery Foundation and other contributors 3061 * Released under the MIT license. 3062 * http://jquery.org/license 3063 */ 3064 3065//>>label: Bounce Effect 3066//>>group: Effects 3067//>>description: Bounces an element horizontally or vertically n times. 3068//>>docs: http://api.jqueryui.com/bounce-effect/ 3069//>>demos: http://jqueryui.com/effect/ 3070 3071 3072var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 3073 var upAnim, downAnim, refValue, 3074 element = $( this ), 3075 3076 // Defaults: 3077 mode = options.mode, 3078 hide = mode === "hide", 3079 show = mode === "show", 3080 direction = options.direction || "up", 3081 distance = options.distance, 3082 times = options.times || 5, 3083 3084 // Number of internal animations 3085 anims = times * 2 + ( show || hide ? 1 : 0 ), 3086 speed = options.duration / anims, 3087 easing = options.easing, 3088 3089 // Utility: 3090 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 3091 motion = ( direction === "up" || direction === "left" ), 3092 i = 0, 3093 3094 queuelen = element.queue().length; 3095 3096 $.effects.createPlaceholder( element ); 3097 3098 refValue = element.css( ref ); 3099 3100 // Default distance for the BIGGEST bounce is the outer Distance / 3 3101 if ( !distance ) { 3102 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 3103 } 3104 3105 if ( show ) { 3106 downAnim = { opacity: 1 }; 3107 downAnim[ ref ] = refValue; 3108 3109 // If we are showing, force opacity 0 and set the initial position 3110 // then do the "first" animation 3111 element 3112 .css( "opacity", 0 ) 3113 .css( ref, motion ? -distance * 2 : distance * 2 ) 3114 .animate( downAnim, speed, easing ); 3115 } 3116 3117 // Start at the smallest distance if we are hiding 3118 if ( hide ) { 3119 distance = distance / Math.pow( 2, times - 1 ); 3120 } 3121 3122 downAnim = {}; 3123 downAnim[ ref ] = refValue; 3124 3125 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 3126 for ( ; i < times; i++ ) { 3127 upAnim = {}; 3128 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 3129 3130 element 3131 .animate( upAnim, speed, easing ) 3132 .animate( downAnim, speed, easing ); 3133 3134 distance = hide ? distance * 2 : distance / 2; 3135 } 3136 3137 // Last Bounce when Hiding 3138 if ( hide ) { 3139 upAnim = { opacity: 0 }; 3140 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 3141 3142 element.animate( upAnim, speed, easing ); 3143 } 3144 3145 element.queue( done ); 3146 3147 $.effects.unshift( element, queuelen, anims + 1 ); 3148} ); 3149 3150 3151/*! 3152 * jQuery UI Effects Clip 1.13.2 3153 * http://jqueryui.com 3154 * 3155 * Copyright jQuery Foundation and other contributors 3156 * Released under the MIT license. 3157 * http://jquery.org/license 3158 */ 3159 3160//>>label: Clip Effect 3161//>>group: Effects 3162//>>description: Clips the element on and off like an old TV. 3163//>>docs: http://api.jqueryui.com/clip-effect/ 3164//>>demos: http://jqueryui.com/effect/ 3165 3166 3167var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 3168 var start, 3169 animate = {}, 3170 element = $( this ), 3171 direction = options.direction || "vertical", 3172 both = direction === "both", 3173 horizontal = both || direction === "horizontal", 3174 vertical = both || direction === "vertical"; 3175 3176 start = element.cssClip(); 3177 animate.clip = { 3178 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 3179 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 3180 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 3181 left: horizontal ? ( start.right - start.left ) / 2 : start.left 3182 }; 3183 3184 $.effects.createPlaceholder( element ); 3185 3186 if ( options.mode === "show" ) { 3187 element.cssClip( animate.clip ); 3188 animate.clip = start; 3189 } 3190 3191 element.animate( animate, { 3192 queue: false, 3193 duration: options.duration, 3194 easing: options.easing, 3195 complete: done 3196 } ); 3197 3198} ); 3199 3200 3201/*! 3202 * jQuery UI Effects Drop 1.13.2 3203 * http://jqueryui.com 3204 * 3205 * Copyright jQuery Foundation and other contributors 3206 * Released under the MIT license. 3207 * http://jquery.org/license 3208 */ 3209 3210//>>label: Drop Effect 3211//>>group: Effects 3212//>>description: Moves an element in one direction and hides it at the same time. 3213//>>docs: http://api.jqueryui.com/drop-effect/ 3214//>>demos: http://jqueryui.com/effect/ 3215 3216 3217var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 3218 3219 var distance, 3220 element = $( this ), 3221 mode = options.mode, 3222 show = mode === "show", 3223 direction = options.direction || "left", 3224 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 3225 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 3226 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 3227 animation = { 3228 opacity: 0 3229 }; 3230 3231 $.effects.createPlaceholder( element ); 3232 3233 distance = options.distance || 3234 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 3235 3236 animation[ ref ] = motion + distance; 3237 3238 if ( show ) { 3239 element.css( animation ); 3240 3241 animation[ ref ] = oppositeMotion + distance; 3242 animation.opacity = 1; 3243 } 3244 3245 // Animate 3246 element.animate( animation, { 3247 queue: false, 3248 duration: options.duration, 3249 easing: options.easing, 3250 complete: done 3251 } ); 3252} ); 3253 3254 3255/*! 3256 * jQuery UI Effects Explode 1.13.2 3257 * http://jqueryui.com 3258 * 3259 * Copyright jQuery Foundation and other contributors 3260 * Released under the MIT license. 3261 * http://jquery.org/license 3262 */ 3263 3264//>>label: Explode Effect 3265//>>group: Effects 3266/* eslint-disable max-len */ 3267//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 3268/* eslint-enable max-len */ 3269//>>docs: http://api.jqueryui.com/explode-effect/ 3270//>>demos: http://jqueryui.com/effect/ 3271 3272 3273var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 3274 3275 var i, j, left, top, mx, my, 3276 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 3277 cells = rows, 3278 element = $( this ), 3279 mode = options.mode, 3280 show = mode === "show", 3281 3282 // Show and then visibility:hidden the element before calculating offset 3283 offset = element.show().css( "visibility", "hidden" ).offset(), 3284 3285 // Width and height of a piece 3286 width = Math.ceil( element.outerWidth() / cells ), 3287 height = Math.ceil( element.outerHeight() / rows ), 3288 pieces = []; 3289 3290 // Children animate complete: 3291 function childComplete() { 3292 pieces.push( this ); 3293 if ( pieces.length === rows * cells ) { 3294 animComplete(); 3295 } 3296 } 3297 3298 // Clone the element for each row and cell. 3299 for ( i = 0; i < rows; i++ ) { // ===> 3300 top = offset.top + i * height; 3301 my = i - ( rows - 1 ) / 2; 3302 3303 for ( j = 0; j < cells; j++ ) { // ||| 3304 left = offset.left + j * width; 3305 mx = j - ( cells - 1 ) / 2; 3306 3307 // Create a clone of the now hidden main element that will be absolute positioned 3308 // within a wrapper div off the -left and -top equal to size of our pieces 3309 element 3310 .clone() 3311 .appendTo( "body" ) 3312 .wrap( "<div></div>" ) 3313 .css( { 3314 position: "absolute", 3315 visibility: "visible", 3316 left: -j * width, 3317 top: -i * height 3318 } ) 3319 3320 // Select the wrapper - make it overflow: hidden and absolute positioned based on 3321 // where the original was located +left and +top equal to the size of pieces 3322 .parent() 3323 .addClass( "ui-effects-explode" ) 3324 .css( { 3325 position: "absolute", 3326 overflow: "hidden", 3327 width: width, 3328 height: height, 3329 left: left + ( show ? mx * width : 0 ), 3330 top: top + ( show ? my * height : 0 ), 3331 opacity: show ? 0 : 1 3332 } ) 3333 .animate( { 3334 left: left + ( show ? 0 : mx * width ), 3335 top: top + ( show ? 0 : my * height ), 3336 opacity: show ? 1 : 0 3337 }, options.duration || 500, options.easing, childComplete ); 3338 } 3339 } 3340 3341 function animComplete() { 3342 element.css( { 3343 visibility: "visible" 3344 } ); 3345 $( pieces ).remove(); 3346 done(); 3347 } 3348} ); 3349 3350 3351/*! 3352 * jQuery UI Effects Fade 1.13.2 3353 * http://jqueryui.com 3354 * 3355 * Copyright jQuery Foundation and other contributors 3356 * Released under the MIT license. 3357 * http://jquery.org/license 3358 */ 3359 3360//>>label: Fade Effect 3361//>>group: Effects 3362//>>description: Fades the element. 3363//>>docs: http://api.jqueryui.com/fade-effect/ 3364//>>demos: http://jqueryui.com/effect/ 3365 3366 3367var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 3368 var show = options.mode === "show"; 3369 3370 $( this ) 3371 .css( "opacity", show ? 0 : 1 ) 3372 .animate( { 3373 opacity: show ? 1 : 0 3374 }, { 3375 queue: false, 3376 duration: options.duration, 3377 easing: options.easing, 3378 complete: done 3379 } ); 3380} ); 3381 3382 3383/*! 3384 * jQuery UI Effects Fold 1.13.2 3385 * http://jqueryui.com 3386 * 3387 * Copyright jQuery Foundation and other contributors 3388 * Released under the MIT license. 3389 * http://jquery.org/license 3390 */ 3391 3392//>>label: Fold Effect 3393//>>group: Effects 3394//>>description: Folds an element first horizontally and then vertically. 3395//>>docs: http://api.jqueryui.com/fold-effect/ 3396//>>demos: http://jqueryui.com/effect/ 3397 3398 3399var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 3400 3401 // Create element 3402 var element = $( this ), 3403 mode = options.mode, 3404 show = mode === "show", 3405 hide = mode === "hide", 3406 size = options.size || 15, 3407 percent = /([0-9]+)%/.exec( size ), 3408 horizFirst = !!options.horizFirst, 3409 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 3410 duration = options.duration / 2, 3411 3412 placeholder = $.effects.createPlaceholder( element ), 3413 3414 start = element.cssClip(), 3415 animation1 = { clip: $.extend( {}, start ) }, 3416 animation2 = { clip: $.extend( {}, start ) }, 3417 3418 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 3419 3420 queuelen = element.queue().length; 3421 3422 if ( percent ) { 3423 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 3424 } 3425 animation1.clip[ ref[ 0 ] ] = size; 3426 animation2.clip[ ref[ 0 ] ] = size; 3427 animation2.clip[ ref[ 1 ] ] = 0; 3428 3429 if ( show ) { 3430 element.cssClip( animation2.clip ); 3431 if ( placeholder ) { 3432 placeholder.css( $.effects.clipToBox( animation2 ) ); 3433 } 3434 3435 animation2.clip = start; 3436 } 3437 3438 // Animate 3439 element 3440 .queue( function( next ) { 3441 if ( placeholder ) { 3442 placeholder 3443 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 3444 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 3445 } 3446 3447 next(); 3448 } ) 3449 .animate( animation1, duration, options.easing ) 3450 .animate( animation2, duration, options.easing ) 3451 .queue( done ); 3452 3453 $.effects.unshift( element, queuelen, 4 ); 3454} ); 3455 3456 3457/*! 3458 * jQuery UI Effects Highlight 1.13.2 3459 * http://jqueryui.com 3460 * 3461 * Copyright jQuery Foundation and other contributors 3462 * Released under the MIT license. 3463 * http://jquery.org/license 3464 */ 3465 3466//>>label: Highlight Effect 3467//>>group: Effects 3468//>>description: Highlights the background of an element in a defined color for a custom duration. 3469//>>docs: http://api.jqueryui.com/highlight-effect/ 3470//>>demos: http://jqueryui.com/effect/ 3471 3472 3473var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 3474 var element = $( this ), 3475 animation = { 3476 backgroundColor: element.css( "backgroundColor" ) 3477 }; 3478 3479 if ( options.mode === "hide" ) { 3480 animation.opacity = 0; 3481 } 3482 3483 $.effects.saveStyle( element ); 3484 3485 element 3486 .css( { 3487 backgroundImage: "none", 3488 backgroundColor: options.color || "#ffff99" 3489 } ) 3490 .animate( animation, { 3491 queue: false, 3492 duration: options.duration, 3493 easing: options.easing, 3494 complete: done 3495 } ); 3496} ); 3497 3498 3499/*! 3500 * jQuery UI Effects Size 1.13.2 3501 * http://jqueryui.com 3502 * 3503 * Copyright jQuery Foundation and other contributors 3504 * Released under the MIT license. 3505 * http://jquery.org/license 3506 */ 3507 3508//>>label: Size Effect 3509//>>group: Effects 3510//>>description: Resize an element to a specified width and height. 3511//>>docs: http://api.jqueryui.com/size-effect/ 3512//>>demos: http://jqueryui.com/effect/ 3513 3514 3515var effectsEffectSize = $.effects.define( "size", function( options, done ) { 3516 3517 // Create element 3518 var baseline, factor, temp, 3519 element = $( this ), 3520 3521 // Copy for children 3522 cProps = [ "fontSize" ], 3523 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 3524 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 3525 3526 // Set options 3527 mode = options.mode, 3528 restore = mode !== "effect", 3529 scale = options.scale || "both", 3530 origin = options.origin || [ "middle", "center" ], 3531 position = element.css( "position" ), 3532 pos = element.position(), 3533 original = $.effects.scaledDimensions( element ), 3534 from = options.from || original, 3535 to = options.to || $.effects.scaledDimensions( element, 0 ); 3536 3537 $.effects.createPlaceholder( element ); 3538 3539 if ( mode === "show" ) { 3540 temp = from; 3541 from = to; 3542 to = temp; 3543 } 3544 3545 // Set scaling factor 3546 factor = { 3547 from: { 3548 y: from.height / original.height, 3549 x: from.width / original.width 3550 }, 3551 to: { 3552 y: to.height / original.height, 3553 x: to.width / original.width 3554 } 3555 }; 3556 3557 // Scale the css box 3558 if ( scale === "box" || scale === "both" ) { 3559 3560 // Vertical props scaling 3561 if ( factor.from.y !== factor.to.y ) { 3562 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 3563 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 3564 } 3565 3566 // Horizontal props scaling 3567 if ( factor.from.x !== factor.to.x ) { 3568 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 3569 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 3570 } 3571 } 3572 3573 // Scale the content 3574 if ( scale === "content" || scale === "both" ) { 3575 3576 // Vertical props scaling 3577 if ( factor.from.y !== factor.to.y ) { 3578 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 3579 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 3580 } 3581 } 3582 3583 // Adjust the position properties based on the provided origin points 3584 if ( origin ) { 3585 baseline = $.effects.getBaseline( origin, original ); 3586 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 3587 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 3588 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 3589 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 3590 } 3591 delete from.outerHeight; 3592 delete from.outerWidth; 3593 element.css( from ); 3594 3595 // Animate the children if desired 3596 if ( scale === "content" || scale === "both" ) { 3597 3598 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 3599 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 3600 3601 // Only animate children with width attributes specified 3602 // TODO: is this right? should we include anything with css width specified as well 3603 element.find( "*[width]" ).each( function() { 3604 var child = $( this ), 3605 childOriginal = $.effects.scaledDimensions( child ), 3606 childFrom = { 3607 height: childOriginal.height * factor.from.y, 3608 width: childOriginal.width * factor.from.x, 3609 outerHeight: childOriginal.outerHeight * factor.from.y, 3610 outerWidth: childOriginal.outerWidth * factor.from.x 3611 }, 3612 childTo = { 3613 height: childOriginal.height * factor.to.y, 3614 width: childOriginal.width * factor.to.x, 3615 outerHeight: childOriginal.height * factor.to.y, 3616 outerWidth: childOriginal.width * factor.to.x 3617 }; 3618 3619 // Vertical props scaling 3620 if ( factor.from.y !== factor.to.y ) { 3621 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 3622 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 3623 } 3624 3625 // Horizontal props scaling 3626 if ( factor.from.x !== factor.to.x ) { 3627 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 3628 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 3629 } 3630 3631 if ( restore ) { 3632 $.effects.saveStyle( child ); 3633 } 3634 3635 // Animate children 3636 child.css( childFrom ); 3637 child.animate( childTo, options.duration, options.easing, function() { 3638 3639 // Restore children 3640 if ( restore ) { 3641 $.effects.restoreStyle( child ); 3642 } 3643 } ); 3644 } ); 3645 } 3646 3647 // Animate 3648 element.animate( to, { 3649 queue: false, 3650 duration: options.duration, 3651 easing: options.easing, 3652 complete: function() { 3653 3654 var offset = element.offset(); 3655 3656 if ( to.opacity === 0 ) { 3657 element.css( "opacity", from.opacity ); 3658 } 3659 3660 if ( !restore ) { 3661 element 3662 .css( "position", position === "static" ? "relative" : position ) 3663 .offset( offset ); 3664 3665 // Need to save style here so that automatic style restoration 3666 // doesn't restore to the original styles from before the animation. 3667 $.effects.saveStyle( element ); 3668 } 3669 3670 done(); 3671 } 3672 } ); 3673 3674} ); 3675 3676 3677/*! 3678 * jQuery UI Effects Scale 1.13.2 3679 * http://jqueryui.com 3680 * 3681 * Copyright jQuery Foundation and other contributors 3682 * Released under the MIT license. 3683 * http://jquery.org/license 3684 */ 3685 3686//>>label: Scale Effect 3687//>>group: Effects 3688//>>description: Grows or shrinks an element and its content. 3689//>>docs: http://api.jqueryui.com/scale-effect/ 3690//>>demos: http://jqueryui.com/effect/ 3691 3692 3693var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 3694 3695 // Create element 3696 var el = $( this ), 3697 mode = options.mode, 3698 percent = parseInt( options.percent, 10 ) || 3699 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 3700 3701 newOptions = $.extend( true, { 3702 from: $.effects.scaledDimensions( el ), 3703 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 3704 origin: options.origin || [ "middle", "center" ] 3705 }, options ); 3706 3707 // Fade option to support puff 3708 if ( options.fade ) { 3709 newOptions.from.opacity = 1; 3710 newOptions.to.opacity = 0; 3711 } 3712 3713 $.effects.effect.size.call( this, newOptions, done ); 3714} ); 3715 3716 3717/*! 3718 * jQuery UI Effects Puff 1.13.2 3719 * http://jqueryui.com 3720 * 3721 * Copyright jQuery Foundation and other contributors 3722 * Released under the MIT license. 3723 * http://jquery.org/license 3724 */ 3725 3726//>>label: Puff Effect 3727//>>group: Effects 3728//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 3729//>>docs: http://api.jqueryui.com/puff-effect/ 3730//>>demos: http://jqueryui.com/effect/ 3731 3732 3733var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 3734 var newOptions = $.extend( true, {}, options, { 3735 fade: true, 3736 percent: parseInt( options.percent, 10 ) || 150 3737 } ); 3738 3739 $.effects.effect.scale.call( this, newOptions, done ); 3740} ); 3741 3742 3743/*! 3744 * jQuery UI Effects Pulsate 1.13.2 3745 * http://jqueryui.com 3746 * 3747 * Copyright jQuery Foundation and other contributors 3748 * Released under the MIT license. 3749 * http://jquery.org/license 3750 */ 3751 3752//>>label: Pulsate Effect 3753//>>group: Effects 3754//>>description: Pulsates an element n times by changing the opacity to zero and back. 3755//>>docs: http://api.jqueryui.com/pulsate-effect/ 3756//>>demos: http://jqueryui.com/effect/ 3757 3758 3759var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 3760 var element = $( this ), 3761 mode = options.mode, 3762 show = mode === "show", 3763 hide = mode === "hide", 3764 showhide = show || hide, 3765 3766 // Showing or hiding leaves off the "last" animation 3767 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 3768 duration = options.duration / anims, 3769 animateTo = 0, 3770 i = 1, 3771 queuelen = element.queue().length; 3772 3773 if ( show || !element.is( ":visible" ) ) { 3774 element.css( "opacity", 0 ).show(); 3775 animateTo = 1; 3776 } 3777 3778 // Anims - 1 opacity "toggles" 3779 for ( ; i < anims; i++ ) { 3780 element.animate( { opacity: animateTo }, duration, options.easing ); 3781 animateTo = 1 - animateTo; 3782 } 3783 3784 element.animate( { opacity: animateTo }, duration, options.easing ); 3785 3786 element.queue( done ); 3787 3788 $.effects.unshift( element, queuelen, anims + 1 ); 3789} ); 3790 3791 3792/*! 3793 * jQuery UI Effects Shake 1.13.2 3794 * http://jqueryui.com 3795 * 3796 * Copyright jQuery Foundation and other contributors 3797 * Released under the MIT license. 3798 * http://jquery.org/license 3799 */ 3800 3801//>>label: Shake Effect 3802//>>group: Effects 3803//>>description: Shakes an element horizontally or vertically n times. 3804//>>docs: http://api.jqueryui.com/shake-effect/ 3805//>>demos: http://jqueryui.com/effect/ 3806 3807 3808var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 3809 3810 var i = 1, 3811 element = $( this ), 3812 direction = options.direction || "left", 3813 distance = options.distance || 20, 3814 times = options.times || 3, 3815 anims = times * 2 + 1, 3816 speed = Math.round( options.duration / anims ), 3817 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 3818 positiveMotion = ( direction === "up" || direction === "left" ), 3819 animation = {}, 3820 animation1 = {}, 3821 animation2 = {}, 3822 3823 queuelen = element.queue().length; 3824 3825 $.effects.createPlaceholder( element ); 3826 3827 // Animation 3828 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 3829 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 3830 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 3831 3832 // Animate 3833 element.animate( animation, speed, options.easing ); 3834 3835 // Shakes 3836 for ( ; i < times; i++ ) { 3837 element 3838 .animate( animation1, speed, options.easing ) 3839 .animate( animation2, speed, options.easing ); 3840 } 3841 3842 element 3843 .animate( animation1, speed, options.easing ) 3844 .animate( animation, speed / 2, options.easing ) 3845 .queue( done ); 3846 3847 $.effects.unshift( element, queuelen, anims + 1 ); 3848} ); 3849 3850 3851/*! 3852 * jQuery UI Effects Slide 1.13.2 3853 * http://jqueryui.com 3854 * 3855 * Copyright jQuery Foundation and other contributors 3856 * Released under the MIT license. 3857 * http://jquery.org/license 3858 */ 3859 3860//>>label: Slide Effect 3861//>>group: Effects 3862//>>description: Slides an element in and out of the viewport. 3863//>>docs: http://api.jqueryui.com/slide-effect/ 3864//>>demos: http://jqueryui.com/effect/ 3865 3866 3867var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 3868 var startClip, startRef, 3869 element = $( this ), 3870 map = { 3871 up: [ "bottom", "top" ], 3872 down: [ "top", "bottom" ], 3873 left: [ "right", "left" ], 3874 right: [ "left", "right" ] 3875 }, 3876 mode = options.mode, 3877 direction = options.direction || "left", 3878 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 3879 positiveMotion = ( direction === "up" || direction === "left" ), 3880 distance = options.distance || 3881 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 3882 animation = {}; 3883 3884 $.effects.createPlaceholder( element ); 3885 3886 startClip = element.cssClip(); 3887 startRef = element.position()[ ref ]; 3888 3889 // Define hide animation 3890 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 3891 animation.clip = element.cssClip(); 3892 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 3893 3894 // Reverse the animation if we're showing 3895 if ( mode === "show" ) { 3896 element.cssClip( animation.clip ); 3897 element.css( ref, animation[ ref ] ); 3898 animation.clip = startClip; 3899 animation[ ref ] = startRef; 3900 } 3901 3902 // Actually animate 3903 element.animate( animation, { 3904 queue: false, 3905 duration: options.duration, 3906 easing: options.easing,
vendor: 9,661 bytes, lines 3907-4289
3907 complete: done 3908 } ); 3909} ); 3910 3911 3912/*! 3913 * jQuery UI Effects Transfer 1.13.2 3914 * http://jqueryui.com 3915 * 3916 * Copyright jQuery Foundation and other contributors 3917 * Released under the MIT license. 3918 * http://jquery.org/license 3919 */ 3920 3921//>>label: Transfer Effect 3922//>>group: Effects 3923//>>description: Displays a transfer effect from one element to another. 3924//>>docs: http://api.jqueryui.com/transfer-effect/ 3925//>>demos: http://jqueryui.com/effect/ 3926 3927 3928var effect; 3929if ( $.uiBackCompat !== false ) { 3930 effect = $.effects.define( "transfer", function( options, done ) { 3931 $( this ).transfer( options, done ); 3932 } ); 3933} 3934var effectsEffectTransfer = effect; 3935 3936 3937/*! 3938 * jQuery UI Focusable 1.13.2 3939 * http://jqueryui.com 3940 * 3941 * Copyright jQuery Foundation and other contributors 3942 * Released under the MIT license. 3943 * http://jquery.org/license 3944 */ 3945 3946//>>label: :focusable Selector 3947//>>group: Core 3948//>>description: Selects elements which can be focused. 3949//>>docs: http://api.jqueryui.com/focusable-selector/ 3950 3951 3952// Selectors 3953$.ui.focusable = function( element, hasTabindex ) { 3954 var map, mapName, img, focusableIfVisible, fieldset, 3955 nodeName = element.nodeName.toLowerCase(); 3956 3957 if ( "area" === nodeName ) { 3958 map = element.parentNode; 3959 mapName = map.name; 3960 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 3961 return false; 3962 } 3963 img = $( "img[usemap='#" + mapName + "']" ); 3964 return img.length > 0 && img.is( ":visible" ); 3965 } 3966 3967 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 3968 focusableIfVisible = !element.disabled; 3969 3970 if ( focusableIfVisible ) { 3971 3972 // Form controls within a disabled fieldset are disabled. 3973 // However, controls within the fieldset's legend do not get disabled. 3974 // Since controls generally aren't placed inside legends, we skip 3975 // this portion of the check. 3976 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 3977 if ( fieldset ) { 3978 focusableIfVisible = !fieldset.disabled; 3979 } 3980 } 3981 } else if ( "a" === nodeName ) { 3982 focusableIfVisible = element.href || hasTabindex; 3983 } else { 3984 focusableIfVisible = hasTabindex; 3985 } 3986 3987 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 3988}; 3989 3990// Support: IE 8 only 3991// IE 8 doesn't resolve inherit to visible/hidden for computed values 3992function visible( element ) { 3993 var visibility = element.css( "visibility" ); 3994 while ( visibility === "inherit" ) { 3995 element = element.parent(); 3996 visibility = element.css( "visibility" ); 3997 } 3998 return visibility === "visible"; 3999} 4000 4001$.extend( $.expr.pseudos, { 4002 focusable: function( element ) { 4003 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 4004 } 4005} ); 4006 4007var focusable = $.ui.focusable; 4008 4009 4010 4011// Support: IE8 Only 4012// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 4013// with a string, so we need to find the proper form. 4014var form = $.fn._form = function() { 4015 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 4016}; 4017 4018 4019/*! 4020 * jQuery UI Form Reset Mixin 1.13.2 4021 * http://jqueryui.com 4022 * 4023 * Copyright jQuery Foundation and other contributors 4024 * Released under the MIT license. 4025 * http://jquery.org/license 4026 */ 4027 4028//>>label: Form Reset Mixin 4029//>>group: Core 4030//>>description: Refresh input widgets when their form is reset 4031//>>docs: http://api.jqueryui.com/form-reset-mixin/ 4032 4033 4034var formResetMixin = $.ui.formResetMixin = { 4035 _formResetHandler: function() { 4036 var form = $( this ); 4037 4038 // Wait for the form reset to actually happen before refreshing 4039 setTimeout( function() { 4040 var instances = form.data( "ui-form-reset-instances" ); 4041 $.each( instances, function() { 4042 this.refresh(); 4043 } ); 4044 } ); 4045 }, 4046 4047 _bindFormResetHandler: function() { 4048 this.form = this.element._form(); 4049 if ( !this.form.length ) { 4050 return; 4051 } 4052 4053 var instances = this.form.data( "ui-form-reset-instances" ) || []; 4054 if ( !instances.length ) { 4055 4056 // We don't use _on() here because we use a single event handler per form 4057 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 4058 } 4059 instances.push( this ); 4060 this.form.data( "ui-form-reset-instances", instances ); 4061 }, 4062 4063 _unbindFormResetHandler: function() { 4064 if ( !this.form.length ) { 4065 return; 4066 } 4067 4068 var instances = this.form.data( "ui-form-reset-instances" ); 4069 instances.splice( $.inArray( this, instances ), 1 ); 4070 if ( instances.length ) { 4071 this.form.data( "ui-form-reset-instances", instances ); 4072 } else { 4073 this.form 4074 .removeData( "ui-form-reset-instances" ) 4075 .off( "reset.ui-form-reset" ); 4076 } 4077 } 4078}; 4079 4080 4081/*! 4082 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 4083 * http://jqueryui.com 4084 * 4085 * Copyright jQuery Foundation and other contributors 4086 * Released under the MIT license. 4087 * http://jquery.org/license 4088 * 4089 */ 4090 4091//>>label: jQuery 1.8+ Support 4092//>>group: Core 4093//>>description: Support version 1.8.x and newer of jQuery core 4094 4095 4096// Support: jQuery 1.9.x or older 4097// $.expr[ ":" ] is deprecated. 4098if ( !$.expr.pseudos ) { 4099 $.expr.pseudos = $.expr[ ":" ]; 4100} 4101 4102// Support: jQuery 1.11.x or older 4103// $.unique has been renamed to $.uniqueSort 4104if ( !$.uniqueSort ) { 4105 $.uniqueSort = $.unique; 4106} 4107 4108// Support: jQuery 2.2.x or older. 4109// This method has been defined in jQuery 3.0.0. 4110// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 4111if ( !$.escapeSelector ) { 4112 4113 // CSS string/identifier serialization 4114 // https://drafts.csswg.org/cssom/#common-serializing-idioms 4115 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 4116 4117 var fcssescape = function( ch, asCodePoint ) { 4118 if ( asCodePoint ) { 4119 4120 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 4121 if ( ch === "\0" ) { 4122 return "\uFFFD"; 4123 } 4124 4125 // Control characters and (dependent upon position) numbers get escaped as code points 4126 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 4127 } 4128 4129 // Other potentially-special ASCII characters get backslash-escaped 4130 return "\\" + ch; 4131 }; 4132 4133 $.escapeSelector = function( sel ) { 4134 return ( sel + "" ).replace( rcssescape, fcssescape ); 4135 }; 4136} 4137 4138// Support: jQuery 3.4.x or older 4139// These methods have been defined in jQuery 3.5.0. 4140if ( !$.fn.even || !$.fn.odd ) { 4141 $.fn.extend( { 4142 even: function() { 4143 return this.filter( function( i ) { 4144 return i % 2 === 0; 4145 } ); 4146 }, 4147 odd: function() { 4148 return this.filter( function( i ) { 4149 return i % 2 === 1; 4150 } ); 4151 } 4152 } ); 4153} 4154 4155; 4156/*! 4157 * jQuery UI Keycode 1.13.2 4158 * http://jqueryui.com 4159 * 4160 * Copyright jQuery Foundation and other contributors 4161 * Released under the MIT license. 4162 * http://jquery.org/license 4163 */ 4164 4165//>>label: Keycode 4166//>>group: Core 4167//>>description: Provide keycodes as keynames 4168//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 4169 4170 4171var keycode = $.ui.keyCode = { 4172 BACKSPACE: 8, 4173 COMMA: 188, 4174 DELETE: 46, 4175 DOWN: 40, 4176 END: 35, 4177 ENTER: 13, 4178 ESCAPE: 27, 4179 HOME: 36, 4180 LEFT: 37, 4181 PAGE_DOWN: 34, 4182 PAGE_UP: 33, 4183 PERIOD: 190, 4184 RIGHT: 39, 4185 SPACE: 32, 4186 TAB: 9, 4187 UP: 38 4188}; 4189 4190 4191/*! 4192 * jQuery UI Labels 1.13.2 4193 * http://jqueryui.com 4194 * 4195 * Copyright jQuery Foundation and other contributors 4196 * Released under the MIT license. 4197 * http://jquery.org/license 4198 */ 4199 4200//>>label: labels 4201//>>group: Core 4202//>>description: Find all the labels associated with a given input 4203//>>docs: http://api.jqueryui.com/labels/ 4204 4205 4206var labels = $.fn.labels = function() { 4207 var ancestor, selector, id, labels, ancestors; 4208 4209 if ( !this.length ) { 4210 return this.pushStack( [] ); 4211 } 4212 4213 // Check control.labels first 4214 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 4215 return this.pushStack( this[ 0 ].labels ); 4216 } 4217 4218 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 4219 // Above browsers do not support control.labels. Everything below is to support them 4220 // as well as document fragments. control.labels does not work on document fragments 4221 labels = this.eq( 0 ).parents( "label" ); 4222 4223 // Look for the label based on the id 4224 id = this.attr( "id" ); 4225 if ( id ) { 4226 4227 // We don't search against the document in case the element 4228 // is disconnected from the DOM 4229 ancestor = this.eq( 0 ).parents().last(); 4230 4231 // Get a full set of top level ancestors 4232 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 4233 4234 // Create a selector for the label based on the id 4235 selector = "label[for='" + $.escapeSelector( id ) + "']"; 4236 4237 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 4238 4239 } 4240 4241 // Return whatever we have found for labels 4242 return this.pushStack( labels ); 4243}; 4244 4245 4246/*! 4247 * jQuery UI Scroll Parent 1.13.2 4248 * http://jqueryui.com 4249 * 4250 * Copyright jQuery Foundation and other contributors 4251 * Released under the MIT license. 4252 * http://jquery.org/license 4253 */ 4254 4255//>>label: scrollParent 4256//>>group: Core 4257//>>description: Get the closest ancestor element that is scrollable. 4258//>>docs: http://api.jqueryui.com/scrollParent/ 4259 4260 4261var scrollParent = $.fn.scrollParent = function( includeHidden ) { 4262 var position = this.css( "position" ), 4263 excludeStaticParent = position === "absolute", 4264 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 4265 scrollParent = this.parents().filter( function() { 4266 var parent = $( this ); 4267 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 4268 return false; 4269 } 4270 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 4271 parent.css( "overflow-x" ) ); 4272 } ).eq( 0 ); 4273 4274 return position === "fixed" || !scrollParent.length ? 4275 $( this[ 0 ].ownerDocument || document ) : 4276 scrollParent; 4277}; 4278 4279 4280/*! 4281 * jQuery UI Tabbable 1.13.2 4282 * http://jqueryui.com 4283 * 4284 * Copyright jQuery Foundation and other contributors 4285 * Released under the MIT license. 4286 * http://jquery.org/license 4287 */ 4288 4289//>>label: :tabbable Selector
vendor: 1,775 bytes, lines 4290-4364
4290//>>group: Core 4291//>>description: Selects elements which can be tabbed to. 4292//>>docs: http://api.jqueryui.com/tabbable-selector/ 4293 4294 4295var tabbable = $.extend( $.expr.pseudos, { 4296 tabbable: function( element ) { 4297 var tabIndex = $.attr( element, "tabindex" ), 4298 hasTabindex = tabIndex != null; 4299 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 4300 } 4301} ); 4302 4303 4304/*! 4305 * jQuery UI Unique ID 1.13.2 4306 * http://jqueryui.com 4307 * 4308 * Copyright jQuery Foundation and other contributors 4309 * Released under the MIT license. 4310 * http://jquery.org/license 4311 */ 4312 4313//>>label: uniqueId 4314//>>group: Core 4315//>>description: Functions to generate and remove uniqueId's 4316//>>docs: http://api.jqueryui.com/uniqueId/ 4317 4318 4319var uniqueId = $.fn.extend( { 4320 uniqueId: ( function() { 4321 var uuid = 0; 4322 4323 return function() { 4324 return this.each( function() { 4325 if ( !this.id ) { 4326 this.id = "ui-id-" + ( ++uuid ); 4327 } 4328 } ); 4329 }; 4330 } )(), 4331 4332 removeUniqueId: function() { 4333 return this.each( function() { 4334 if ( /^ui-id-\d+$/.test( this.id ) ) { 4335 $( this ).removeAttr( "id" ); 4336 } 4337 } ); 4338 } 4339} ); 4340 4341 4342/*! 4343 * jQuery UI Accordion 1.13.2 4344 * http://jqueryui.com 4345 * 4346 * Copyright jQuery Foundation and other contributors 4347 * Released under the MIT license. 4348 * http://jquery.org/license 4349 */ 4350 4351//>>label: Accordion 4352//>>group: Widgets 4353/* eslint-disable max-len */ 4354//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 4355/* eslint-enable max-len */ 4356//>>docs: http://api.jqueryui.com/accordion/ 4357//>>demos: http://jqueryui.com/accordion/ 4358//>>css.structure: ../../themes/base/core.css 4359//>>css.structure: ../../themes/base/accordion.css 4360//>>css.theme: ../../themes/base/theme.css 4361 4362 4363var widgetsAccordion = $.widget( "ui.accordion", { 4364 version: "1.13.2
vendor: 15,900 bytes, lines 4364-4975
4364", 4365 options: { 4366 active: 0, 4367 animate: {}, 4368 classes: { 4369 "ui-accordion-header": "ui-corner-top", 4370 "ui-accordion-header-collapsed": "ui-corner-all", 4371 "ui-accordion-content": "ui-corner-bottom" 4372 }, 4373 collapsible: false, 4374 event: "click", 4375 header: function( elem ) { 4376 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); 4377 }, 4378 heightStyle: "auto", 4379 icons: { 4380 activeHeader: "ui-icon-triangle-1-s", 4381 header: "ui-icon-triangle-1-e" 4382 }, 4383 4384 // Callbacks 4385 activate: null, 4386 beforeActivate: null 4387 }, 4388 4389 hideProps: { 4390 borderTopWidth: "hide", 4391 borderBottomWidth: "hide", 4392 paddingTop: "hide", 4393 paddingBottom: "hide", 4394 height: "hide" 4395 }, 4396 4397 showProps: { 4398 borderTopWidth: "show", 4399 borderBottomWidth: "show", 4400 paddingTop: "show", 4401 paddingBottom: "show", 4402 height: "show" 4403 }, 4404 4405 _create: function() { 4406 var options = this.options; 4407 4408 this.prevShow = this.prevHide = $(); 4409 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 4410 this.element.attr( "role", "tablist" ); 4411 4412 // Don't allow collapsible: false and active: false / null 4413 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 4414 options.active = 0; 4415 } 4416 4417 this._processPanels(); 4418 4419 // handle negative values 4420 if ( options.active < 0 ) { 4421 options.active += this.headers.length; 4422 } 4423 this._refresh(); 4424 }, 4425 4426 _getCreateEventData: function() { 4427 return { 4428 header: this.active, 4429 panel: !this.active.length ? $() : this.active.next() 4430 }; 4431 }, 4432 4433 _createIcons: function() { 4434 var icon, children, 4435 icons = this.options.icons; 4436 4437 if ( icons ) { 4438 icon = $( "<span>" ); 4439 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 4440 icon.prependTo( this.headers ); 4441 children = this.active.children( ".ui-accordion-header-icon" ); 4442 this._removeClass( children, icons.header ) 4443 ._addClass( children, null, icons.activeHeader ) 4444 ._addClass( this.headers, "ui-accordion-icons" ); 4445 } 4446 }, 4447 4448 _destroyIcons: function() { 4449 this._removeClass( this.headers, "ui-accordion-icons" ); 4450 this.headers.children( ".ui-accordion-header-icon" ).remove(); 4451 }, 4452 4453 _destroy: function() { 4454 var contents; 4455 4456 // Clean up main element 4457 this.element.removeAttr( "role" ); 4458 4459 // Clean up headers 4460 this.headers 4461 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 4462 .removeUniqueId(); 4463 4464 this._destroyIcons(); 4465 4466 // Clean up content panels 4467 contents = this.headers.next() 4468 .css( "display", "" ) 4469 .removeAttr( "role aria-hidden aria-labelledby" ) 4470 .removeUniqueId(); 4471 4472 if ( this.options.heightStyle !== "content" ) { 4473 contents.css( "height", "" ); 4474 } 4475 }, 4476 4477 _setOption: function( key, value ) { 4478 if ( key === "active" ) { 4479 4480 // _activate() will handle invalid values and update this.options 4481 this._activate( value ); 4482 return; 4483 } 4484 4485 if ( key === "event" ) { 4486 if ( this.options.event ) { 4487 this._off( this.headers, this.options.event ); 4488 } 4489 this._setupEvents( value ); 4490 } 4491 4492 this._super( key, value ); 4493 4494 // Setting collapsible: false while collapsed; open first panel 4495 if ( key === "collapsible" && !value && this.options.active === false ) { 4496 this._activate( 0 ); 4497 } 4498 4499 if ( key === "icons" ) { 4500 this._destroyIcons(); 4501 if ( value ) { 4502 this._createIcons(); 4503 } 4504 } 4505 }, 4506 4507 _setOptionDisabled: function( value ) { 4508 this._super( value ); 4509 4510 this.element.attr( "aria-disabled", value ); 4511 4512 // Support: IE8 Only 4513 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE 4514 // so we need to add the disabled class to the headers and panels 4515 this._toggleClass( null, "ui-state-disabled", !!value ); 4516 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", 4517 !!value ); 4518 }, 4519 4520 _keydown: function( event ) { 4521 if ( event.altKey || event.ctrlKey ) { 4522 return; 4523 } 4524 4525 var keyCode = $.ui.keyCode, 4526 length = this.headers.length, 4527 currentIndex = this.headers.index( event.target ), 4528 toFocus = false; 4529 4530 switch ( event.keyCode ) { 4531 case keyCode.RIGHT: 4532 case keyCode.DOWN: 4533 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 4534 break; 4535 case keyCode.LEFT: 4536 case keyCode.UP: 4537 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 4538 break; 4539 case keyCode.SPACE: 4540 case keyCode.ENTER: 4541 this._eventHandler( event ); 4542 break; 4543 case keyCode.HOME: 4544 toFocus = this.headers[ 0 ]; 4545 break; 4546 case keyCode.END: 4547 toFocus = this.headers[ length - 1 ]; 4548 break; 4549 } 4550 4551 if ( toFocus ) { 4552 $( event.target ).attr( "tabIndex", -1 ); 4553 $( toFocus ).attr( "tabIndex", 0 ); 4554 $( toFocus ).trigger( "focus" ); 4555 event.preventDefault(); 4556 } 4557 }, 4558 4559 _panelKeyDown: function( event ) { 4560 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 4561 $( event.currentTarget ).prev().trigger( "focus" ); 4562 } 4563 }, 4564 4565 refresh: function() { 4566 var options = this.options; 4567 this._processPanels(); 4568 4569 // Was collapsed or no panel 4570 if ( ( options.active === false && options.collapsible === true ) || 4571 !this.headers.length ) { 4572 options.active = false; 4573 this.active = $(); 4574 4575 // active false only when collapsible is true 4576 } else if ( options.active === false ) { 4577 this._activate( 0 ); 4578 4579 // was active, but active panel is gone 4580 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 4581 4582 // all remaining panel are disabled 4583 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 4584 options.active = false; 4585 this.active = $(); 4586 4587 // activate previous panel 4588 } else { 4589 this._activate( Math.max( 0, options.active - 1 ) ); 4590 } 4591 4592 // was active, active panel still exists 4593 } else { 4594 4595 // make sure active index is correct 4596 options.active = this.headers.index( this.active ); 4597 } 4598 4599 this._destroyIcons(); 4600 4601 this._refresh(); 4602 }, 4603 4604 _processPanels: function() { 4605 var prevHeaders = this.headers, 4606 prevPanels = this.panels; 4607 4608 if ( typeof this.options.header === "function" ) { 4609 this.headers = this.options.header( this.element ); 4610 } else { 4611 this.headers = this.element.find( this.options.header ); 4612 } 4613 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 4614 "ui-state-default" ); 4615 4616 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 4617 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 4618 4619 // Avoid memory leaks (#10056) 4620 if ( prevPanels ) { 4621 this._off( prevHeaders.not( this.headers ) ); 4622 this._off( prevPanels.not( this.panels ) ); 4623 } 4624 }, 4625 4626 _refresh: function() { 4627 var maxHeight, 4628 options = this.options, 4629 heightStyle = options.heightStyle, 4630 parent = this.element.parent(); 4631 4632 this.active = this._findActive( options.active ); 4633 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 4634 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 4635 this._addClass( this.active.next(), "ui-accordion-content-active" ); 4636 this.active.next().show(); 4637 4638 this.headers 4639 .attr( "role", "tab" ) 4640 .each( function() { 4641 var header = $( this ), 4642 headerId = header.uniqueId().attr( "id" ), 4643 panel = header.next(), 4644 panelId = panel.uniqueId().attr( "id" ); 4645 header.attr( "aria-controls", panelId ); 4646 panel.attr( "aria-labelledby", headerId ); 4647 } ) 4648 .next() 4649 .attr( "role", "tabpanel" ); 4650 4651 this.headers 4652 .not( this.active ) 4653 .attr( { 4654 "aria-selected": "false", 4655 "aria-expanded": "false", 4656 tabIndex: -1 4657 } ) 4658 .next() 4659 .attr( { 4660 "aria-hidden": "true" 4661 } ) 4662 .hide(); 4663 4664 // Make sure at least one header is in the tab order 4665 if ( !this.active.length ) { 4666 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 4667 } else { 4668 this.active.attr( { 4669 "aria-selected": "true", 4670 "aria-expanded": "true", 4671 tabIndex: 0 4672 } ) 4673 .next() 4674 .attr( { 4675 "aria-hidden": "false" 4676 } ); 4677 } 4678 4679 this._createIcons(); 4680 4681 this._setupEvents( options.event ); 4682 4683 if ( heightStyle === "fill" ) { 4684 maxHeight = parent.height(); 4685 this.element.siblings( ":visible" ).each( function() { 4686 var elem = $( this ), 4687 position = elem.css( "position" ); 4688 4689 if ( position === "absolute" || position === "fixed" ) { 4690 return; 4691 } 4692 maxHeight -= elem.outerHeight( true ); 4693 } ); 4694 4695 this.headers.each( function() { 4696 maxHeight -= $( this ).outerHeight( true ); 4697 } ); 4698 4699 this.headers.next() 4700 .each( function() { 4701 $( this ).height( Math.max( 0, maxHeight - 4702 $( this ).innerHeight() + $( this ).height() ) ); 4703 } ) 4704 .css( "overflow", "auto" ); 4705 } else if ( heightStyle === "auto" ) { 4706 maxHeight = 0; 4707 this.headers.next() 4708 .each( function() { 4709 var isVisible = $( this ).is( ":visible" ); 4710 if ( !isVisible ) { 4711 $( this ).show(); 4712 } 4713 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 4714 if ( !isVisible ) { 4715 $( this ).hide(); 4716 } 4717 } ) 4718 .height( maxHeight ); 4719 } 4720 }, 4721 4722 _activate: function( index ) { 4723 var active = this._findActive( index )[ 0 ]; 4724 4725 // Trying to activate the already active panel 4726 if ( active === this.active[ 0 ] ) { 4727 return; 4728 } 4729 4730 // Trying to collapse, simulate a click on the currently active header 4731 active = active || this.active[ 0 ]; 4732 4733 this._eventHandler( { 4734 target: active, 4735 currentTarget: active, 4736 preventDefault: $.noop 4737 } ); 4738 }, 4739 4740 _findActive: function( selector ) { 4741 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 4742 }, 4743 4744 _setupEvents: function( event ) { 4745 var events = { 4746 keydown: "_keydown" 4747 }; 4748 if ( event ) { 4749 $.each( event.split( " " ), function( index, eventName ) { 4750 events[ eventName ] = "_eventHandler"; 4751 } ); 4752 } 4753 4754 this._off( this.headers.add( this.headers.next() ) ); 4755 this._on( this.headers, events ); 4756 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 4757 this._hoverable( this.headers ); 4758 this._focusable( this.headers ); 4759 }, 4760 4761 _eventHandler: function( event ) { 4762 var activeChildren, clickedChildren, 4763 options = this.options, 4764 active = this.active, 4765 clicked = $( event.currentTarget ), 4766 clickedIsActive = clicked[ 0 ] === active[ 0 ], 4767 collapsing = clickedIsActive && options.collapsible, 4768 toShow = collapsing ? $() : clicked.next(), 4769 toHide = active.next(), 4770 eventData = { 4771 oldHeader: active, 4772 oldPanel: toHide, 4773 newHeader: collapsing ? $() : clicked, 4774 newPanel: toShow 4775 }; 4776 4777 event.preventDefault(); 4778 4779 if ( 4780 4781 // click on active header, but not collapsible 4782 ( clickedIsActive && !options.collapsible ) || 4783 4784 // allow canceling activation 4785 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 4786 return; 4787 } 4788 4789 options.active = collapsing ? false : this.headers.index( clicked ); 4790 4791 // When the call to ._toggle() comes after the class changes 4792 // it causes a very odd bug in IE 8 (see #6720) 4793 this.active = clickedIsActive ? $() : clicked; 4794 this._toggle( eventData ); 4795 4796 // Switch classes 4797 // corner classes on the previously active header stay after the animation 4798 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 4799 if ( options.icons ) { 4800 activeChildren = active.children( ".ui-accordion-header-icon" ); 4801 this._removeClass( activeChildren, null, options.icons.activeHeader ) 4802 ._addClass( activeChildren, null, options.icons.header ); 4803 } 4804 4805 if ( !clickedIsActive ) { 4806 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 4807 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 4808 if ( options.icons ) { 4809 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 4810 this._removeClass( clickedChildren, null, options.icons.header ) 4811 ._addClass( clickedChildren, null, options.icons.activeHeader ); 4812 } 4813 4814 this._addClass( clicked.next(), "ui-accordion-content-active" ); 4815 } 4816 }, 4817 4818 _toggle: function( data ) { 4819 var toShow = data.newPanel, 4820 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 4821 4822 // Handle activating a panel during the animation for another activation 4823 this.prevShow.add( this.prevHide ).stop( true, true ); 4824 this.prevShow = toShow; 4825 this.prevHide = toHide; 4826 4827 if ( this.options.animate ) { 4828 this._animate( toShow, toHide, data ); 4829 } else { 4830 toHide.hide(); 4831 toShow.show(); 4832 this._toggleComplete( data ); 4833 } 4834 4835 toHide.attr( { 4836 "aria-hidden": "true" 4837 } ); 4838 toHide.prev().attr( { 4839 "aria-selected": "false", 4840 "aria-expanded": "false" 4841 } ); 4842 4843 // if we're switching panels, remove the old header from the tab order 4844 // if we're opening from collapsed state, remove the previous header from the tab order 4845 // if we're collapsing, then keep the collapsing header in the tab order 4846 if ( toShow.length && toHide.length ) { 4847 toHide.prev().attr( { 4848 "tabIndex": -1, 4849 "aria-expanded": "false" 4850 } ); 4851 } else if ( toShow.length ) { 4852 this.headers.filter( function() { 4853 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 4854 } ) 4855 .attr( "tabIndex", -1 ); 4856 } 4857 4858 toShow 4859 .attr( "aria-hidden", "false" ) 4860 .prev() 4861 .attr( { 4862 "aria-selected": "true", 4863 "aria-expanded": "true", 4864 tabIndex: 0 4865 } ); 4866 }, 4867 4868 _animate: function( toShow, toHide, data ) { 4869 var total, easing, duration, 4870 that = this, 4871 adjust = 0, 4872 boxSizing = toShow.css( "box-sizing" ), 4873 down = toShow.length && 4874 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 4875 animate = this.options.animate || {}, 4876 options = down && animate.down || animate, 4877 complete = function() { 4878 that._toggleComplete( data ); 4879 }; 4880 4881 if ( typeof options === "number" ) { 4882 duration = options; 4883 } 4884 if ( typeof options === "string" ) { 4885 easing = options; 4886 } 4887 4888 // fall back from options to animation in case of partial down settings 4889 easing = easing || options.easing || animate.easing; 4890 duration = duration || options.duration || animate.duration; 4891 4892 if ( !toHide.length ) { 4893 return toShow.animate( this.showProps, duration, easing, complete ); 4894 } 4895 if ( !toShow.length ) { 4896 return toHide.animate( this.hideProps, duration, easing, complete ); 4897 } 4898 4899 total = toShow.show().outerHeight(); 4900 toHide.animate( this.hideProps, { 4901 duration: duration, 4902 easing: easing, 4903 step: function( now, fx ) { 4904 fx.now = Math.round( now ); 4905 } 4906 } ); 4907 toShow 4908 .hide() 4909 .animate( this.showProps, { 4910 duration: duration, 4911 easing: easing, 4912 complete: complete, 4913 step: function( now, fx ) { 4914 fx.now = Math.round( now ); 4915 if ( fx.prop !== "height" ) { 4916 if ( boxSizing === "content-box" ) { 4917 adjust += fx.now; 4918 } 4919 } else if ( that.options.heightStyle !== "content" ) { 4920 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 4921 adjust = 0; 4922 } 4923 } 4924 } ); 4925 }, 4926 4927 _toggleComplete: function( data ) { 4928 var toHide = data.oldPanel, 4929 prev = toHide.prev(); 4930 4931 this._removeClass( toHide, "ui-accordion-content-active" ); 4932 this._removeClass( prev, "ui-accordion-header-active" ) 4933 ._addClass( prev, "ui-accordion-header-collapsed" ); 4934 4935 // Work around for rendering bug in IE (#5421) 4936 if ( toHide.length ) { 4937 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 4938 } 4939 this._trigger( "activate", null, data ); 4940 } 4941} ); 4942 4943 4944 4945var safeActiveElement = $.ui.safeActiveElement = function( document ) { 4946 var activeElement; 4947 4948 // Support: IE 9 only 4949 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 4950 try { 4951 activeElement = document.activeElement; 4952 } catch ( error ) { 4953 activeElement = document.body; 4954 } 4955 4956 // Support: IE 9 - 11 only 4957 // IE may return null instead of an element 4958 // Interestingly, this only seems to occur when NOT in an iframe 4959 if ( !activeElement ) { 4960 activeElement = document.body; 4961 } 4962 4963 // Support: IE 11 only 4964 // IE11 returns a seemingly empty object in some cases when accessing 4965 // document.activeElement from an <iframe> 4966 if ( !activeElement.nodeName ) { 4967 activeElement = document.body; 4968 } 4969 4970 return activeElement; 4971}; 4972 4973 4974/*! 4975 * jQuery UI Menu 1.13.
49752 4976 * http://jqueryui.com 4977 * 4978 * Copyright jQuery Foundation and other contributors 4979 * Released under the MIT license. 4980 * http://jquery.org/license 4981 */ 4982 4983//>>label: Menu 4984//>>group: Widgets 4985//>>description: Creates nestable menus. 4986//>>docs: http://api.jqueryui.com/menu/ 4987//>>demos: http://jqueryui.com/menu/ 4988//>>css.structure: ../../themes/base/core.css 4989//>>css.structure: ../../themes/base/menu.css 4990//>>css.theme: ../../themes/base/theme.css 4991 4992 4993var widgetsMenu = $.widget( "ui.menu", { 4994 version: "1.13.2
vendor: 18,088 bytes, lines 4994-5666
4994", 4995 defaultElement: "<ul>", 4996 delay: 300, 4997 options: { 4998 icons: { 4999 submenu: "ui-icon-caret-1-e" 5000 }, 5001 items: "> *", 5002 menus: "ul", 5003 position: { 5004 my: "left top", 5005 at: "right top" 5006 }, 5007 role: "menu", 5008 5009 // Callbacks 5010 blur: null, 5011 focus: null, 5012 select: null 5013 }, 5014 5015 _create: function() { 5016 this.activeMenu = this.element; 5017 5018 // Flag used to prevent firing of the click handler 5019 // as the event bubbles up through nested menus 5020 this.mouseHandled = false; 5021 this.lastMousePosition = { x: null, y: null }; 5022 this.element 5023 .uniqueId() 5024 .attr( { 5025 role: this.options.role, 5026 tabIndex: 0 5027 } ); 5028 5029 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 5030 this._on( { 5031 5032 // Prevent focus from sticking to links inside menu after clicking 5033 // them (focus should always stay on UL during navigation). 5034 "mousedown .ui-menu-item": function( event ) { 5035 event.preventDefault(); 5036 5037 this._activateItem( event ); 5038 }, 5039 "click .ui-menu-item": function( event ) { 5040 var target = $( event.target ); 5041 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 5042 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 5043 this.select( event ); 5044 5045 // Only set the mouseHandled flag if the event will bubble, see #9469. 5046 if ( !event.isPropagationStopped() ) { 5047 this.mouseHandled = true; 5048 } 5049 5050 // Open submenu on click 5051 if ( target.has( ".ui-menu" ).length ) { 5052 this.expand( event ); 5053 } else if ( !this.element.is( ":focus" ) && 5054 active.closest( ".ui-menu" ).length ) { 5055 5056 // Redirect focus to the menu 5057 this.element.trigger( "focus", [ true ] ); 5058 5059 // If the active item is on the top level, let it stay active. 5060 // Otherwise, blur the active item since it is no longer visible. 5061 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 5062 clearTimeout( this.timer ); 5063 } 5064 } 5065 } 5066 }, 5067 "mouseenter .ui-menu-item": "_activateItem", 5068 "mousemove .ui-menu-item": "_activateItem", 5069 mouseleave: "collapseAll", 5070 "mouseleave .ui-menu": "collapseAll", 5071 focus: function( event, keepActiveItem ) { 5072 5073 // If there's already an active item, keep it active 5074 // If not, activate the first item 5075 var item = this.active || this._menuItems().first(); 5076 5077 if ( !keepActiveItem ) { 5078 this.focus( event, item ); 5079 } 5080 }, 5081 blur: function( event ) { 5082 this._delay( function() { 5083 var notContained = !$.contains( 5084 this.element[ 0 ], 5085 $.ui.safeActiveElement( this.document[ 0 ] ) 5086 ); 5087 if ( notContained ) { 5088 this.collapseAll( event ); 5089 } 5090 } ); 5091 }, 5092 keydown: "_keydown" 5093 } ); 5094 5095 this.refresh(); 5096 5097 // Clicks outside of a menu collapse any open menus 5098 this._on( this.document, { 5099 click: function( event ) { 5100 if ( this._closeOnDocumentClick( event ) ) { 5101 this.collapseAll( event, true ); 5102 } 5103 5104 // Reset the mouseHandled flag 5105 this.mouseHandled = false; 5106 } 5107 } ); 5108 }, 5109 5110 _activateItem: function( event ) { 5111 5112 // Ignore mouse events while typeahead is active, see #10458. 5113 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 5114 // is over an item in the menu 5115 if ( this.previousFilter ) { 5116 return; 5117 } 5118 5119 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 5120 if ( event.clientX === this.lastMousePosition.x && 5121 event.clientY === this.lastMousePosition.y ) { 5122 return; 5123 } 5124 5125 this.lastMousePosition = { 5126 x: event.clientX, 5127 y: event.clientY 5128 }; 5129 5130 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 5131 target = $( event.currentTarget ); 5132 5133 // Ignore bubbled events on parent items, see #11641 5134 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 5135 return; 5136 } 5137 5138 // If the item is already active, there's nothing to do 5139 if ( target.is( ".ui-state-active" ) ) { 5140 return; 5141 } 5142 5143 // Remove ui-state-active class from siblings of the newly focused menu item 5144 // to avoid a jump caused by adjacent elements both having a class with a border 5145 this._removeClass( target.siblings().children( ".ui-state-active" ), 5146 null, "ui-state-active" ); 5147 this.focus( event, target ); 5148 }, 5149 5150 _destroy: function() { 5151 var items = this.element.find( ".ui-menu-item" ) 5152 .removeAttr( "role aria-disabled" ), 5153 submenus = items.children( ".ui-menu-item-wrapper" ) 5154 .removeUniqueId() 5155 .removeAttr( "tabIndex role aria-haspopup" ); 5156 5157 // Destroy (sub)menus 5158 this.element 5159 .removeAttr( "aria-activedescendant" ) 5160 .find( ".ui-menu" ).addBack() 5161 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 5162 "tabIndex" ) 5163 .removeUniqueId() 5164 .show(); 5165 5166 submenus.children().each( function() { 5167 var elem = $( this ); 5168 if ( elem.data( "ui-menu-submenu-caret" ) ) { 5169 elem.remove(); 5170 } 5171 } ); 5172 }, 5173 5174 _keydown: function( event ) { 5175 var match, prev, character, skip, 5176 preventDefault = true; 5177 5178 switch ( event.keyCode ) { 5179 case $.ui.keyCode.PAGE_UP: 5180 this.previousPage( event ); 5181 break; 5182 case $.ui.keyCode.PAGE_DOWN: 5183 this.nextPage( event ); 5184 break; 5185 case $.ui.keyCode.HOME: 5186 this._move( "first", "first", event ); 5187 break; 5188 case $.ui.keyCode.END: 5189 this._move( "last", "last", event ); 5190 break; 5191 case $.ui.keyCode.UP: 5192 this.previous( event ); 5193 break; 5194 case $.ui.keyCode.DOWN: 5195 this.next( event ); 5196 break; 5197 case $.ui.keyCode.LEFT: 5198 this.collapse( event ); 5199 break; 5200 case $.ui.keyCode.RIGHT: 5201 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 5202 this.expand( event ); 5203 } 5204 break; 5205 case $.ui.keyCode.ENTER: 5206 case $.ui.keyCode.SPACE: 5207 this._activate( event ); 5208 break; 5209 case $.ui.keyCode.ESCAPE: 5210 this.collapse( event ); 5211 break; 5212 default: 5213 preventDefault = false; 5214 prev = this.previousFilter || ""; 5215 skip = false; 5216 5217 // Support number pad values 5218 character = event.keyCode >= 96 && event.keyCode <= 105 ? 5219 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 5220 5221 clearTimeout( this.filterTimer ); 5222 5223 if ( character === prev ) { 5224 skip = true; 5225 } else { 5226 character = prev + character; 5227 } 5228 5229 match = this._filterMenuItems( character ); 5230 match = skip && match.index( this.active.next() ) !== -1 ? 5231 this.active.nextAll( ".ui-menu-item" ) : 5232 match; 5233 5234 // If no matches on the current filter, reset to the last character pressed 5235 // to move down the menu to the first item that starts with that character 5236 if ( !match.length ) { 5237 character = String.fromCharCode( event.keyCode ); 5238 match = this._filterMenuItems( character ); 5239 } 5240 5241 if ( match.length ) { 5242 this.focus( event, match ); 5243 this.previousFilter = character; 5244 this.filterTimer = this._delay( function() { 5245 delete this.previousFilter; 5246 }, 1000 ); 5247 } else { 5248 delete this.previousFilter; 5249 } 5250 } 5251 5252 if ( preventDefault ) { 5253 event.preventDefault(); 5254 } 5255 }, 5256 5257 _activate: function( event ) { 5258 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 5259 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 5260 this.expand( event ); 5261 } else { 5262 this.select( event ); 5263 } 5264 } 5265 }, 5266 5267 refresh: function() { 5268 var menus, items, newSubmenus, newItems, newWrappers, 5269 that = this, 5270 icon = this.options.icons.submenu, 5271 submenus = this.element.find( this.options.menus ); 5272 5273 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 5274 5275 // Initialize nested menus 5276 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 5277 .hide() 5278 .attr( { 5279 role: this.options.role, 5280 "aria-hidden": "true", 5281 "aria-expanded": "false" 5282 } ) 5283 .each( function() { 5284 var menu = $( this ), 5285 item = menu.prev(), 5286 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 5287 5288 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 5289 item 5290 .attr( "aria-haspopup", "true" ) 5291 .prepend( submenuCaret ); 5292 menu.attr( "aria-labelledby", item.attr( "id" ) ); 5293 } ); 5294 5295 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 5296 5297 menus = submenus.add( this.element ); 5298 items = menus.find( this.options.items ); 5299 5300 // Initialize menu-items containing spaces and/or dashes only as dividers 5301 items.not( ".ui-menu-item" ).each( function() { 5302 var item = $( this ); 5303 if ( that._isDivider( item ) ) { 5304 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 5305 } 5306 } ); 5307 5308 // Don't refresh list items that are already adapted 5309 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 5310 newWrappers = newItems.children() 5311 .not( ".ui-menu" ) 5312 .uniqueId() 5313 .attr( { 5314 tabIndex: -1, 5315 role: this._itemRole() 5316 } ); 5317 this._addClass( newItems, "ui-menu-item" ) 5318 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 5319 5320 // Add aria-disabled attribute to any disabled menu item 5321 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 5322 5323 // If the active item has been removed, blur the menu 5324 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5325 this.blur(); 5326 } 5327 }, 5328 5329 _itemRole: function() { 5330 return { 5331 menu: "menuitem", 5332 listbox: "option" 5333 }[ this.options.role ]; 5334 }, 5335 5336 _setOption: function( key, value ) { 5337 if ( key === "icons" ) { 5338 var icons = this.element.find( ".ui-menu-icon" ); 5339 this._removeClass( icons, null, this.options.icons.submenu ) 5340 ._addClass( icons, null, value.submenu ); 5341 } 5342 this._super( key, value ); 5343 }, 5344 5345 _setOptionDisabled: function( value ) { 5346 this._super( value ); 5347 5348 this.element.attr( "aria-disabled", String( value ) ); 5349 this._toggleClass( null, "ui-state-disabled", !!value ); 5350 }, 5351 5352 focus: function( event, item ) { 5353 var nested, focused, activeParent; 5354 this.blur( event, event && event.type === "focus" ); 5355 5356 this._scrollIntoView( item ); 5357 5358 this.active = item.first(); 5359 5360 focused = this.active.children( ".ui-menu-item-wrapper" ); 5361 this._addClass( focused, null, "ui-state-active" ); 5362 5363 // Only update aria-activedescendant if there's a role 5364 // otherwise we assume focus is managed elsewhere 5365 if ( this.options.role ) { 5366 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 5367 } 5368 5369 // Highlight active parent menu item, if any 5370 activeParent = this.active 5371 .parent() 5372 .closest( ".ui-menu-item" ) 5373 .children( ".ui-menu-item-wrapper" ); 5374 this._addClass( activeParent, null, "ui-state-active" ); 5375 5376 if ( event && event.type === "keydown" ) { 5377 this._close(); 5378 } else { 5379 this.timer = this._delay( function() { 5380 this._close(); 5381 }, this.delay ); 5382 } 5383 5384 nested = item.children( ".ui-menu" ); 5385 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 5386 this._startOpening( nested ); 5387 } 5388 this.activeMenu = item.parent(); 5389 5390 this._trigger( "focus", event, { item: item } ); 5391 }, 5392 5393 _scrollIntoView: function( item ) { 5394 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 5395 if ( this._hasScroll() ) { 5396 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 5397 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 5398 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 5399 scroll = this.activeMenu.scrollTop(); 5400 elementHeight = this.activeMenu.height(); 5401 itemHeight = item.outerHeight(); 5402 5403 if ( offset < 0 ) { 5404 this.activeMenu.scrollTop( scroll + offset ); 5405 } else if ( offset + itemHeight > elementHeight ) { 5406 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 5407 } 5408 } 5409 }, 5410 5411 blur: function( event, fromFocus ) { 5412 if ( !fromFocus ) { 5413 clearTimeout( this.timer ); 5414 } 5415 5416 if ( !this.active ) { 5417 return; 5418 } 5419 5420 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 5421 null, "ui-state-active" ); 5422 5423 this._trigger( "blur", event, { item: this.active } ); 5424 this.active = null; 5425 }, 5426 5427 _startOpening: function( submenu ) { 5428 clearTimeout( this.timer ); 5429 5430 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 5431 // shift in the submenu position when mousing over the caret icon 5432 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 5433 return; 5434 } 5435 5436 this.timer = this._delay( function() { 5437 this._close(); 5438 this._open( submenu ); 5439 }, this.delay ); 5440 }, 5441 5442 _open: function( submenu ) { 5443 var position = $.extend( { 5444 of: this.active 5445 }, this.options.position ); 5446 5447 clearTimeout( this.timer ); 5448 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 5449 .hide() 5450 .attr( "aria-hidden", "true" ); 5451 5452 submenu 5453 .show() 5454 .removeAttr( "aria-hidden" ) 5455 .attr( "aria-expanded", "true" ) 5456 .position( position ); 5457 }, 5458 5459 collapseAll: function( event, all ) { 5460 clearTimeout( this.timer ); 5461 this.timer = this._delay( function() { 5462 5463 // If we were passed an event, look for the submenu that contains the event 5464 var currentMenu = all ? this.element : 5465 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 5466 5467 // If we found no valid submenu ancestor, use the main menu to close all 5468 // sub menus anyway 5469 if ( !currentMenu.length ) { 5470 currentMenu = this.element; 5471 } 5472 5473 this._close( currentMenu ); 5474 5475 this.blur( event ); 5476 5477 // Work around active item staying active after menu is blurred 5478 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 5479 5480 this.activeMenu = currentMenu; 5481 }, all ? 0 : this.delay ); 5482 }, 5483 5484 // With no arguments, closes the currently active menu - if nothing is active 5485 // it closes all menus. If passed an argument, it will search for menus BELOW 5486 _close: function( startMenu ) { 5487 if ( !startMenu ) { 5488 startMenu = this.active ? this.active.parent() : this.element; 5489 } 5490 5491 startMenu.find( ".ui-menu" ) 5492 .hide() 5493 .attr( "aria-hidden", "true" ) 5494 .attr( "aria-expanded", "false" ); 5495 }, 5496 5497 _closeOnDocumentClick: function( event ) { 5498 return !$( event.target ).closest( ".ui-menu" ).length; 5499 }, 5500 5501 _isDivider: function( item ) { 5502 5503 // Match hyphen, em dash, en dash 5504 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 5505 }, 5506 5507 collapse: function( event ) { 5508 var newItem = this.active && 5509 this.active.parent().closest( ".ui-menu-item", this.element ); 5510 if ( newItem && newItem.length ) { 5511 this._close(); 5512 this.focus( event, newItem ); 5513 } 5514 }, 5515 5516 expand: function( event ) { 5517 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 5518 5519 if ( newItem && newItem.length ) { 5520 this._open( newItem.parent() ); 5521 5522 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 5523 this._delay( function() { 5524 this.focus( event, newItem ); 5525 } ); 5526 } 5527 }, 5528 5529 next: function( event ) { 5530 this._move( "next", "first", event ); 5531 }, 5532 5533 previous: function( event ) { 5534 this._move( "prev", "last", event ); 5535 }, 5536 5537 isFirstItem: function() { 5538 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 5539 }, 5540 5541 isLastItem: function() { 5542 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 5543 }, 5544 5545 _menuItems: function( menu ) { 5546 return ( menu || this.element ) 5547 .find( this.options.items ) 5548 .filter( ".ui-menu-item" ); 5549 }, 5550 5551 _move: function( direction, filter, event ) { 5552 var next; 5553 if ( this.active ) { 5554 if ( direction === "first" || direction === "last" ) { 5555 next = this.active 5556 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 5557 .last(); 5558 } else { 5559 next = this.active 5560 [ direction + "All" ]( ".ui-menu-item" ) 5561 .first(); 5562 } 5563 } 5564 if ( !next || !next.length || !this.active ) { 5565 next = this._menuItems( this.activeMenu )[ filter ](); 5566 } 5567 5568 this.focus( event, next ); 5569 }, 5570 5571 nextPage: function( event ) { 5572 var item, base, height; 5573 5574 if ( !this.active ) { 5575 this.next( event ); 5576 return; 5577 } 5578 if ( this.isLastItem() ) { 5579 return; 5580 } 5581 if ( this._hasScroll() ) { 5582 base = this.active.offset().top; 5583 height = this.element.innerHeight(); 5584 5585 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 5586 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 5587 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 5588 } 5589 5590 this.active.nextAll( ".ui-menu-item" ).each( function() { 5591 item = $( this ); 5592 return item.offset().top - base - height < 0; 5593 } ); 5594 5595 this.focus( event, item ); 5596 } else { 5597 this.focus( event, this._menuItems( this.activeMenu ) 5598 [ !this.active ? "first" : "last" ]() ); 5599 } 5600 }, 5601 5602 previousPage: function( event ) { 5603 var item, base, height; 5604 if ( !this.active ) { 5605 this.next( event ); 5606 return; 5607 } 5608 if ( this.isFirstItem() ) { 5609 return; 5610 } 5611 if ( this._hasScroll() ) { 5612 base = this.active.offset().top; 5613 height = this.element.innerHeight(); 5614 5615 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 5616 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 5617 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 5618 } 5619 5620 this.active.prevAll( ".ui-menu-item" ).each( function() { 5621 item = $( this ); 5622 return item.offset().top - base + height > 0; 5623 } ); 5624 5625 this.focus( event, item ); 5626 } else { 5627 this.focus( event, this._menuItems( this.activeMenu ).first() ); 5628 } 5629 }, 5630 5631 _hasScroll: function() { 5632 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 5633 }, 5634 5635 select: function( event ) { 5636 5637 // TODO: It should never be possible to not have an active item at this 5638 // point, but the tests don't trigger mouseenter before click. 5639 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 5640 var ui = { item: this.active }; 5641 if ( !this.active.has( ".ui-menu" ).length ) { 5642 this.collapseAll( event, true ); 5643 } 5644 this._trigger( "select", event, ui ); 5645 }, 5646 5647 _filterMenuItems: function( character ) { 5648 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 5649 regex = new RegExp( "^" + escapedCharacter, "i" ); 5650 5651 return this.activeMenu 5652 .find( this.options.items ) 5653 5654 // Only match on items, not dividers or other content (#10571) 5655 .filter( ".ui-menu-item" ) 5656 .filter( function() { 5657 return regex.test( 5658 String.prototype.trim.call( 5659 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 5660 } ); 5661 } 5662} ); 5663 5664 5665/*! 5666 * jQuery UI Autocomplete 1.13.
56662 5667 * http://jqueryui.com 5668 * 5669 * Copyright jQuery Foundation and other contributors 5670 * Released under the MIT license. 5671 * http://jquery.org/license 5672 */ 5673 5674//>>label: Autocomplete 5675//>>group: Widgets 5676//>>description: Lists suggested words as the user is typing. 5677//>>docs: http://api.jqueryui.com/autocomplete/ 5678//>>demos: http://jqueryui.com/autocomplete/ 5679//>>css.structure: ../../themes/base/core.css 5680//>>css.structure: ../../themes/base/autocomplete.css 5681//>>css.theme: ../../themes/base/theme.css 5682 5683 5684$.widget( "ui.autocomplete", { 5685 version: "1.13.2
vendor: 16,621 bytes, lines 5685-6322
5685", 5686 defaultElement: "<input>", 5687 options: { 5688 appendTo: null, 5689 autoFocus: false, 5690 delay: 300, 5691 minLength: 1, 5692 position: { 5693 my: "left top", 5694 at: "left bottom", 5695 collision: "none" 5696 }, 5697 source: null, 5698 5699 // Callbacks 5700 change: null, 5701 close: null, 5702 focus: null, 5703 open: null, 5704 response: null, 5705 search: null, 5706 select: null 5707 }, 5708 5709 requestIndex: 0, 5710 pending: 0, 5711 liveRegionTimer: null, 5712 5713 _create: function() { 5714 5715 // Some browsers only repeat keydown events, not keypress events, 5716 // so we use the suppressKeyPress flag to determine if we've already 5717 // handled the keydown event. #7269 5718 // Unfortunately the code for & in keypress is the same as the up arrow, 5719 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 5720 // events when we know the keydown event was used to modify the 5721 // search term. #7799 5722 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 5723 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 5724 isTextarea = nodeName === "textarea", 5725 isInput = nodeName === "input"; 5726 5727 // Textareas are always multi-line 5728 // Inputs are always single-line, even if inside a contentEditable element 5729 // IE also treats inputs as contentEditable 5730 // All other element types are determined by whether or not they're contentEditable 5731 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 5732 5733 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 5734 this.isNewMenu = true; 5735 5736 this._addClass( "ui-autocomplete-input" ); 5737 this.element.attr( "autocomplete", "off" ); 5738 5739 this._on( this.element, { 5740 keydown: function( event ) { 5741 if ( this.element.prop( "readOnly" ) ) { 5742 suppressKeyPress = true; 5743 suppressInput = true; 5744 suppressKeyPressRepeat = true; 5745 return; 5746 } 5747 5748 suppressKeyPress = false; 5749 suppressInput = false; 5750 suppressKeyPressRepeat = false; 5751 var keyCode = $.ui.keyCode; 5752 switch ( event.keyCode ) { 5753 case keyCode.PAGE_UP: 5754 suppressKeyPress = true; 5755 this._move( "previousPage", event ); 5756 break; 5757 case keyCode.PAGE_DOWN: 5758 suppressKeyPress = true; 5759 this._move( "nextPage", event ); 5760 break; 5761 case keyCode.UP: 5762 suppressKeyPress = true; 5763 this._keyEvent( "previous", event ); 5764 break; 5765 case keyCode.DOWN: 5766 suppressKeyPress = true; 5767 this._keyEvent( "next", event ); 5768 break; 5769 case keyCode.ENTER: 5770 5771 // when menu is open and has focus 5772 if ( this.menu.active ) { 5773 5774 // #6055 - Opera still allows the keypress to occur 5775 // which causes forms to submit 5776 suppressKeyPress = true; 5777 event.preventDefault(); 5778 this.menu.select( event ); 5779 } 5780 break; 5781 case keyCode.TAB: 5782 if ( this.menu.active ) { 5783 this.menu.select( event ); 5784 } 5785 break; 5786 case keyCode.ESCAPE: 5787 if ( this.menu.element.is( ":visible" ) ) { 5788 if ( !this.isMultiLine ) { 5789 this._value( this.term ); 5790 } 5791 this.close( event ); 5792 5793 // Different browsers have different default behavior for escape 5794 // Single press can mean undo or clear 5795 // Double press in IE means clear the whole form 5796 event.preventDefault(); 5797 } 5798 break; 5799 default: 5800 suppressKeyPressRepeat = true; 5801 5802 // search timeout should be triggered before the input value is changed 5803 this._searchTimeout( event ); 5804 break; 5805 } 5806 }, 5807 keypress: function( event ) { 5808 if ( suppressKeyPress ) { 5809 suppressKeyPress = false; 5810 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 5811 event.preventDefault(); 5812 } 5813 return; 5814 } 5815 if ( suppressKeyPressRepeat ) { 5816 return; 5817 } 5818 5819 // Replicate some key handlers to allow them to repeat in Firefox and Opera 5820 var keyCode = $.ui.keyCode; 5821 switch ( event.keyCode ) { 5822 case keyCode.PAGE_UP: 5823 this._move( "previousPage", event ); 5824 break; 5825 case keyCode.PAGE_DOWN: 5826 this._move( "nextPage", event ); 5827 break; 5828 case keyCode.UP: 5829 this._keyEvent( "previous", event ); 5830 break; 5831 case keyCode.DOWN: 5832 this._keyEvent( "next", event ); 5833 break; 5834 } 5835 }, 5836 input: function( event ) { 5837 if ( suppressInput ) { 5838 suppressInput = false; 5839 event.preventDefault(); 5840 return; 5841 } 5842 this._searchTimeout( event ); 5843 }, 5844 focus: function() { 5845 this.selectedItem = null; 5846 this.previous = this._value(); 5847 }, 5848 blur: function( event ) { 5849 clearTimeout( this.searching ); 5850 this.close( event ); 5851 this._change( event ); 5852 } 5853 } ); 5854 5855 this._initSource(); 5856 this.menu = $( "<ul>" ) 5857 .appendTo( this._appendTo() ) 5858 .menu( { 5859 5860 // disable ARIA support, the live region takes care of that 5861 role: null 5862 } ) 5863 .hide() 5864 5865 // Support: IE 11 only, Edge <= 14 5866 // For other browsers, we preventDefault() on the mousedown event 5867 // to keep the dropdown from taking focus from the input. This doesn't 5868 // work for IE/Edge, causing problems with selection and scrolling (#9638) 5869 // Happily, IE and Edge support an "unselectable" attribute that 5870 // prevents an element from receiving focus, exactly what we want here. 5871 .attr( { 5872 "unselectable": "on" 5873 } ) 5874 .menu( "instance" ); 5875 5876 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 5877 this._on( this.menu.element, { 5878 mousedown: function( event ) { 5879 5880 // Prevent moving focus out of the text field 5881 event.preventDefault(); 5882 }, 5883 menufocus: function( event, ui ) { 5884 var label, item; 5885 5886 // support: Firefox 5887 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 5888 if ( this.isNewMenu ) { 5889 this.isNewMenu = false; 5890 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 5891 this.menu.blur(); 5892 5893 this.document.one( "mousemove", function() { 5894 $( event.target ).trigger( event.originalEvent ); 5895 } ); 5896 5897 return; 5898 } 5899 } 5900 5901 item = ui.item.data( "ui-autocomplete-item" ); 5902 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 5903 5904 // use value to match what will end up in the input, if it was a key event 5905 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 5906 this._value( item.value ); 5907 } 5908 } 5909 5910 // Announce the value in the liveRegion 5911 label = ui.item.attr( "aria-label" ) || item.value; 5912 if ( label && String.prototype.trim.call( label ).length ) { 5913 clearTimeout( this.liveRegionTimer ); 5914 this.liveRegionTimer = this._delay( function() { 5915 this.liveRegion.html( $( "<div>" ).text( label ) ); 5916 }, 100 ); 5917 } 5918 }, 5919 menuselect: function( event, ui ) { 5920 var item = ui.item.data( "ui-autocomplete-item" ), 5921 previous = this.previous; 5922 5923 // Only trigger when focus was lost (click on menu) 5924 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 5925 this.element.trigger( "focus" ); 5926 this.previous = previous; 5927 5928 // #6109 - IE triggers two focus events and the second 5929 // is asynchronous, so we need to reset the previous 5930 // term synchronously and asynchronously :-( 5931 this._delay( function() { 5932 this.previous = previous; 5933 this.selectedItem = item; 5934 } ); 5935 } 5936 5937 if ( false !== this._trigger( "select", event, { item: item } ) ) { 5938 this._value( item.value ); 5939 } 5940 5941 // reset the term after the select event 5942 // this allows custom select handling to work properly 5943 this.term = this._value(); 5944 5945 this.close( event ); 5946 this.selectedItem = item; 5947 } 5948 } ); 5949 5950 this.liveRegion = $( "<div>", { 5951 role: "status", 5952 "aria-live": "assertive", 5953 "aria-relevant": "additions" 5954 } ) 5955 .appendTo( this.document[ 0 ].body ); 5956 5957 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 5958 5959 // Turning off autocomplete prevents the browser from remembering the 5960 // value when navigating through history, so we re-enable autocomplete 5961 // if the page is unloaded before the widget is destroyed. #7790 5962 this._on( this.window, { 5963 beforeunload: function() { 5964 this.element.removeAttr( "autocomplete" ); 5965 } 5966 } ); 5967 }, 5968 5969 _destroy: function() { 5970 clearTimeout( this.searching ); 5971 this.element.removeAttr( "autocomplete" ); 5972 this.menu.element.remove(); 5973 this.liveRegion.remove(); 5974 }, 5975 5976 _setOption: function( key, value ) { 5977 this._super( key, value ); 5978 if ( key === "source" ) { 5979 this._initSource(); 5980 } 5981 if ( key === "appendTo" ) { 5982 this.menu.element.appendTo( this._appendTo() ); 5983 } 5984 if ( key === "disabled" && value && this.xhr ) { 5985 this.xhr.abort(); 5986 } 5987 }, 5988 5989 _isEventTargetInWidget: function( event ) { 5990 var menuElement = this.menu.element[ 0 ]; 5991 5992 return event.target === this.element[ 0 ] || 5993 event.target === menuElement || 5994 $.contains( menuElement, event.target ); 5995 }, 5996 5997 _closeOnClickOutside: function( event ) { 5998 if ( !this._isEventTargetInWidget( event ) ) { 5999 this.close(); 6000 } 6001 }, 6002 6003 _appendTo: function() { 6004 var element = this.options.appendTo; 6005 6006 if ( element ) { 6007 element = element.jquery || element.nodeType ? 6008 $( element ) : 6009 this.document.find( element ).eq( 0 ); 6010 } 6011 6012 if ( !element || !element[ 0 ] ) { 6013 element = this.element.closest( ".ui-front, dialog" ); 6014 } 6015 6016 if ( !element.length ) { 6017 element = this.document[ 0 ].body; 6018 } 6019 6020 return element; 6021 }, 6022 6023 _initSource: function() { 6024 var array, url, 6025 that = this; 6026 if ( Array.isArray( this.options.source ) ) { 6027 array = this.options.source; 6028 this.source = function( request, response ) { 6029 response( $.ui.autocomplete.filter( array, request.term ) ); 6030 }; 6031 } else if ( typeof this.options.source === "string" ) { 6032 url = this.options.source; 6033 this.source = function( request, response ) { 6034 if ( that.xhr ) { 6035 that.xhr.abort(); 6036 } 6037 that.xhr = $.ajax( { 6038 url: url, 6039 data: request, 6040 dataType: "json", 6041 success: function( data ) { 6042 response( data ); 6043 }, 6044 error: function() { 6045 response( [] ); 6046 } 6047 } ); 6048 }; 6049 } else { 6050 this.source = this.options.source; 6051 } 6052 }, 6053 6054 _searchTimeout: function( event ) { 6055 clearTimeout( this.searching ); 6056 this.searching = this._delay( function() { 6057 6058 // Search if the value has changed, or if the user retypes the same value (see #7434) 6059 var equalValues = this.term === this._value(), 6060 menuVisible = this.menu.element.is( ":visible" ), 6061 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 6062 6063 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 6064 this.selectedItem = null; 6065 this.search( null, event ); 6066 } 6067 }, this.options.delay ); 6068 }, 6069 6070 search: function( value, event ) { 6071 value = value != null ? value : this._value(); 6072 6073 // Always save the actual value, not the one passed as an argument 6074 this.term = this._value(); 6075 6076 if ( value.length < this.options.minLength ) { 6077 return this.close( event ); 6078 } 6079 6080 if ( this._trigger( "search", event ) === false ) { 6081 return; 6082 } 6083 6084 return this._search( value ); 6085 }, 6086 6087 _search: function( value ) { 6088 this.pending++; 6089 this._addClass( "ui-autocomplete-loading" ); 6090 this.cancelSearch = false; 6091 6092 this.source( { term: value }, this._response() ); 6093 }, 6094 6095 _response: function() { 6096 var index = ++this.requestIndex; 6097 6098 return function( content ) { 6099 if ( index === this.requestIndex ) { 6100 this.__response( content ); 6101 } 6102 6103 this.pending--; 6104 if ( !this.pending ) { 6105 this._removeClass( "ui-autocomplete-loading" ); 6106 } 6107 }.bind( this ); 6108 }, 6109 6110 __response: function( content ) { 6111 if ( content ) { 6112 content = this._normalize( content ); 6113 } 6114 this._trigger( "response", null, { content: content } ); 6115 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6116 this._suggest( content ); 6117 this._trigger( "open" ); 6118 } else { 6119 6120 // use ._close() instead of .close() so we don't cancel future searches 6121 this._close(); 6122 } 6123 }, 6124 6125 close: function( event ) { 6126 this.cancelSearch = true; 6127 this._close( event ); 6128 }, 6129 6130 _close: function( event ) { 6131 6132 // Remove the handler that closes the menu on outside clicks 6133 this._off( this.document, "mousedown" ); 6134 6135 if ( this.menu.element.is( ":visible" ) ) { 6136 this.menu.element.hide(); 6137 this.menu.blur(); 6138 this.isNewMenu = true; 6139 this._trigger( "close", event ); 6140 } 6141 }, 6142 6143 _change: function( event ) { 6144 if ( this.previous !== this._value() ) { 6145 this._trigger( "change", event, { item: this.selectedItem } ); 6146 } 6147 }, 6148 6149 _normalize: function( items ) { 6150 6151 // assume all items have the right format when the first item is complete 6152 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 6153 return items; 6154 } 6155 return $.map( items, function( item ) { 6156 if ( typeof item === "string" ) { 6157 return { 6158 label: item, 6159 value: item 6160 }; 6161 } 6162 return $.extend( {}, item, { 6163 label: item.label || item.value, 6164 value: item.value || item.label 6165 } ); 6166 } ); 6167 }, 6168 6169 _suggest: function( items ) { 6170 var ul = this.menu.element.empty(); 6171 this._renderMenu( ul, items ); 6172 this.isNewMenu = true; 6173 this.menu.refresh(); 6174 6175 // Size and position menu 6176 ul.show(); 6177 this._resizeMenu(); 6178 ul.position( $.extend( { 6179 of: this.element 6180 }, this.options.position ) ); 6181 6182 if ( this.options.autoFocus ) { 6183 this.menu.next(); 6184 } 6185 6186 // Listen for interactions outside of the widget (#6642) 6187 this._on( this.document, { 6188 mousedown: "_closeOnClickOutside" 6189 } ); 6190 }, 6191 6192 _resizeMenu: function() { 6193 var ul = this.menu.element; 6194 ul.outerWidth( Math.max( 6195 6196 // Firefox wraps long text (possibly a rounding bug) 6197 // so we add 1px to avoid the wrapping (#7513) 6198 ul.width( "" ).outerWidth() + 1, 6199 this.element.outerWidth() 6200 ) ); 6201 }, 6202 6203 _renderMenu: function( ul, items ) { 6204 var that = this; 6205 $.each( items, function( index, item ) { 6206 that._renderItemData( ul, item ); 6207 } ); 6208 }, 6209 6210 _renderItemData: function( ul, item ) { 6211 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6212 }, 6213 6214 _renderItem: function( ul, item ) { 6215 return $( "<li>" ) 6216 .append( $( "<div>" ).text( item.label ) ) 6217 .appendTo( ul ); 6218 }, 6219 6220 _move: function( direction, event ) { 6221 if ( !this.menu.element.is( ":visible" ) ) { 6222 this.search( null, event ); 6223 return; 6224 } 6225 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6226 this.menu.isLastItem() && /^next/.test( direction ) ) { 6227 6228 if ( !this.isMultiLine ) { 6229 this._value( this.term ); 6230 } 6231 6232 this.menu.blur(); 6233 return; 6234 } 6235 this.menu[ direction ]( event ); 6236 }, 6237 6238 widget: function() { 6239 return this.menu.element; 6240 }, 6241 6242 _value: function() { 6243 return this.valueMethod.apply( this.element, arguments ); 6244 }, 6245 6246 _keyEvent: function( keyEvent, event ) { 6247 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6248 this._move( keyEvent, event ); 6249 6250 // Prevents moving cursor to beginning/end of the text field in some browsers 6251 event.preventDefault(); 6252 } 6253 }, 6254 6255 // Support: Chrome <=50 6256 // We should be able to just use this.element.prop( "isContentEditable" ) 6257 // but hidden elements always report false in Chrome. 6258 // https://code.google.com/p/chromium/issues/detail?id=313082 6259 _isContentEditable: function( element ) { 6260 if ( !element.length ) { 6261 return false; 6262 } 6263 6264 var editable = element.prop( "contentEditable" ); 6265 6266 if ( editable === "inherit" ) { 6267 return this._isContentEditable( element.parent() ); 6268 } 6269 6270 return editable === "true"; 6271 } 6272} ); 6273 6274$.extend( $.ui.autocomplete, { 6275 escapeRegex: function( value ) { 6276 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 6277 }, 6278 filter: function( array, term ) { 6279 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 6280 return $.grep( array, function( value ) { 6281 return matcher.test( value.label || value.value || value ); 6282 } ); 6283 } 6284} ); 6285 6286// Live region extension, adding a `messages` option 6287// NOTE: This is an experimental API. We are still investigating 6288// a full solution for string manipulation and internationalization. 6289$.widget( "ui.autocomplete", $.ui.autocomplete, { 6290 options: { 6291 messages: { 6292 noResults: "No search results.", 6293 results: function( amount ) { 6294 return amount + ( amount > 1 ? " results are" : " result is" ) + 6295 " available, use up and down arrow keys to navigate."; 6296 } 6297 } 6298 }, 6299 6300 __response: function( content ) { 6301 var message; 6302 this._superApply( arguments ); 6303 if ( this.options.disabled || this.cancelSearch ) { 6304 return; 6305 } 6306 if ( content && content.length ) { 6307 message = this.options.messages.results( content.length ); 6308 } else { 6309 message = this.options.messages.noResults; 6310 } 6311 clearTimeout( this.liveRegionTimer ); 6312 this.liveRegionTimer = this._delay( function() { 6313 this.liveRegion.html( $( "<div>" ).text( message ) ); 6314 }, 100 ); 6315 } 6316} ); 6317 6318var widgetsAutocomplete = $.ui.autocomplete; 6319 6320 6321/*! 6322 * jQuery UI Controlgroup 1.13.
63222 6323 * http://jqueryui.com 6324 * 6325 * Copyright jQuery Foundation and other contributors 6326 * Released under the MIT license. 6327 * http://jquery.org/license 6328 */ 6329 6330//>>label: Controlgroup 6331//>>group: Widgets 6332//>>description: Visually groups form control widgets 6333//>>docs: http://api.jqueryui.com/controlgroup/ 6334//>>demos: http://jqueryui.com/controlgroup/ 6335//>>css.structure: ../../themes/base/core.css 6336//>>css.structure: ../../themes/base/controlgroup.css 6337//>>css.theme: ../../themes/base/theme.css 6338 6339 6340var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 6341 6342var widgetsControlgroup = $.widget( "ui.controlgroup", { 6343 version: "1.13.2
vendor: 7,736 bytes, lines 6343-6607
6343", 6344 defaultElement: "<div>", 6345 options: { 6346 direction: "horizontal", 6347 disabled: null, 6348 onlyVisible: true, 6349 items: { 6350 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 6351 "controlgroupLabel": ".ui-controlgroup-label", 6352 "checkboxradio": "input[type='checkbox'], input[type='radio']", 6353 "selectmenu": "select", 6354 "spinner": ".ui-spinner-input" 6355 } 6356 }, 6357 6358 _create: function() { 6359 this._enhance(); 6360 }, 6361 6362 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 6363 _enhance: function() { 6364 this.element.attr( "role", "toolbar" ); 6365 this.refresh(); 6366 }, 6367 6368 _destroy: function() { 6369 this._callChildMethod( "destroy" ); 6370 this.childWidgets.removeData( "ui-controlgroup-data" ); 6371 this.element.removeAttr( "role" ); 6372 if ( this.options.items.controlgroupLabel ) { 6373 this.element 6374 .find( this.options.items.controlgroupLabel ) 6375 .find( ".ui-controlgroup-label-contents" ) 6376 .contents().unwrap(); 6377 } 6378 }, 6379 6380 _initWidgets: function() { 6381 var that = this, 6382 childWidgets = []; 6383 6384 // First we iterate over each of the items options 6385 $.each( this.options.items, function( widget, selector ) { 6386 var labels; 6387 var options = {}; 6388 6389 // Make sure the widget has a selector set 6390 if ( !selector ) { 6391 return; 6392 } 6393 6394 if ( widget === "controlgroupLabel" ) { 6395 labels = that.element.find( selector ); 6396 labels.each( function() { 6397 var element = $( this ); 6398 6399 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 6400 return; 6401 } 6402 element.contents() 6403 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 6404 } ); 6405 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 6406 childWidgets = childWidgets.concat( labels.get() ); 6407 return; 6408 } 6409 6410 // Make sure the widget actually exists 6411 if ( !$.fn[ widget ] ) { 6412 return; 6413 } 6414 6415 // We assume everything is in the middle to start because we can't determine 6416 // first / last elements until all enhancments are done. 6417 if ( that[ "_" + widget + "Options" ] ) { 6418 options = that[ "_" + widget + "Options" ]( "middle" ); 6419 } else { 6420 options = { classes: {} }; 6421 } 6422 6423 // Find instances of this widget inside controlgroup and init them 6424 that.element 6425 .find( selector ) 6426 .each( function() { 6427 var element = $( this ); 6428 var instance = element[ widget ]( "instance" ); 6429 6430 // We need to clone the default options for this type of widget to avoid 6431 // polluting the variable options which has a wider scope than a single widget. 6432 var instanceOptions = $.widget.extend( {}, options ); 6433 6434 // If the button is the child of a spinner ignore it 6435 // TODO: Find a more generic solution 6436 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 6437 return; 6438 } 6439 6440 // Create the widget if it doesn't exist 6441 if ( !instance ) { 6442 instance = element[ widget ]()[ widget ]( "instance" ); 6443 } 6444 if ( instance ) { 6445 instanceOptions.classes = 6446 that._resolveClassesValues( instanceOptions.classes, instance ); 6447 } 6448 element[ widget ]( instanceOptions ); 6449 6450 // Store an instance of the controlgroup to be able to reference 6451 // from the outermost element for changing options and refresh 6452 var widgetElement = element[ widget ]( "widget" ); 6453 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 6454 instance ? instance : element[ widget ]( "instance" ) ); 6455 6456 childWidgets.push( widgetElement[ 0 ] ); 6457 } ); 6458 } ); 6459 6460 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 6461 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 6462 }, 6463 6464 _callChildMethod: function( method ) { 6465 this.childWidgets.each( function() { 6466 var element = $( this ), 6467 data = element.data( "ui-controlgroup-data" ); 6468 if ( data && data[ method ] ) { 6469 data[ method ](); 6470 } 6471 } ); 6472 }, 6473 6474 _updateCornerClass: function( element, position ) { 6475 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 6476 var add = this._buildSimpleOptions( position, "label" ).classes.label; 6477 6478 this._removeClass( element, null, remove ); 6479 this._addClass( element, null, add ); 6480 }, 6481 6482 _buildSimpleOptions: function( position, key ) { 6483 var direction = this.options.direction === "vertical"; 6484 var result = { 6485 classes: {} 6486 }; 6487 result.classes[ key ] = { 6488 "middle": "", 6489 "first": "ui-corner-" + ( direction ? "top" : "left" ), 6490 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 6491 "only": "ui-corner-all" 6492 }[ position ]; 6493 6494 return result; 6495 }, 6496 6497 _spinnerOptions: function( position ) { 6498 var options = this._buildSimpleOptions( position, "ui-spinner" ); 6499 6500 options.classes[ "ui-spinner-up" ] = ""; 6501 options.classes[ "ui-spinner-down" ] = ""; 6502 6503 return options; 6504 }, 6505 6506 _buttonOptions: function( position ) { 6507 return this._buildSimpleOptions( position, "ui-button" ); 6508 }, 6509 6510 _checkboxradioOptions: function( position ) { 6511 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 6512 }, 6513 6514 _selectmenuOptions: function( position ) { 6515 var direction = this.options.direction === "vertical"; 6516 return { 6517 width: direction ? "auto" : false, 6518 classes: { 6519 middle: { 6520 "ui-selectmenu-button-open": "", 6521 "ui-selectmenu-button-closed": "" 6522 }, 6523 first: { 6524 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 6525 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 6526 }, 6527 last: { 6528 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 6529 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 6530 }, 6531 only: { 6532 "ui-selectmenu-button-open": "ui-corner-top", 6533 "ui-selectmenu-button-closed": "ui-corner-all" 6534 } 6535 6536 }[ position ] 6537 }; 6538 }, 6539 6540 _resolveClassesValues: function( classes, instance ) { 6541 var result = {}; 6542 $.each( classes, function( key ) { 6543 var current = instance.options.classes[ key ] || ""; 6544 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 6545 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 6546 } ); 6547 return result; 6548 }, 6549 6550 _setOption: function( key, value ) { 6551 if ( key === "direction" ) { 6552 this._removeClass( "ui-controlgroup-" + this.options.direction ); 6553 } 6554 6555 this._super( key, value ); 6556 if ( key === "disabled" ) { 6557 this._callChildMethod( value ? "disable" : "enable" ); 6558 return; 6559 } 6560 6561 this.refresh(); 6562 }, 6563 6564 refresh: function() { 6565 var children, 6566 that = this; 6567 6568 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 6569 6570 if ( this.options.direction === "horizontal" ) { 6571 this._addClass( null, "ui-helper-clearfix" ); 6572 } 6573 this._initWidgets(); 6574 6575 children = this.childWidgets; 6576 6577 // We filter here because we need to track all childWidgets not just the visible ones 6578 if ( this.options.onlyVisible ) { 6579 children = children.filter( ":visible" ); 6580 } 6581 6582 if ( children.length ) { 6583 6584 // We do this last because we need to make sure all enhancment is done 6585 // before determining first and last 6586 $.each( [ "first", "last" ], function( index, value ) { 6587 var instance = children[ value ]().data( "ui-controlgroup-data" ); 6588 6589 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 6590 var options = that[ "_" + instance.widgetName + "Options" ]( 6591 children.length === 1 ? "only" : value 6592 ); 6593 options.classes = that._resolveClassesValues( options.classes, instance ); 6594 instance.element[ instance.widgetName ]( options ); 6595 } else { 6596 that._updateCornerClass( children[ value ](), value ); 6597 } 6598 } ); 6599 6600 // Finally call the refresh method on each of the child widgets. 6601 this._callChildMethod( "refresh" ); 6602 } 6603 } 6604} ); 6605 6606/*! 6607 * jQuery UI Checkboxradio 1.13.
vendor: 5,067 bytes, lines 6607-6790
66072 6608 * http://jqueryui.com 6609 * 6610 * Copyright jQuery Foundation and other contributors 6611 * Released under the MIT license. 6612 * http://jquery.org/license 6613 */ 6614 6615//>>label: Checkboxradio 6616//>>group: Widgets 6617//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 6618//>>docs: http://api.jqueryui.com/checkboxradio/ 6619//>>demos: http://jqueryui.com/checkboxradio/ 6620//>>css.structure: ../../themes/base/core.css 6621//>>css.structure: ../../themes/base/button.css 6622//>>css.structure: ../../themes/base/checkboxradio.css 6623//>>css.theme: ../../themes/base/theme.css 6624 6625 6626$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 6627 version: "1.13.2", 6628 options: { 6629 disabled: null, 6630 label: null, 6631 icon: true, 6632 classes: { 6633 "ui-checkboxradio-label": "ui-corner-all", 6634 "ui-checkboxradio-icon": "ui-corner-all" 6635 } 6636 }, 6637 6638 _getCreateOptions: function() { 6639 var disabled, labels, labelContents; 6640 var options = this._super() || {}; 6641 6642 // We read the type here, because it makes more sense to throw a element type error first, 6643 // rather then the error for lack of a label. Often if its the wrong type, it 6644 // won't have a label (e.g. calling on a div, btn, etc) 6645 this._readType(); 6646 6647 labels = this.element.labels(); 6648 6649 // If there are multiple labels, use the last one 6650 this.label = $( labels[ labels.length - 1 ] ); 6651 if ( !this.label.length ) { 6652 $.error( "No label found for checkboxradio widget" ); 6653 } 6654 6655 this.originalLabel = ""; 6656 6657 // We need to get the label text but this may also need to make sure it does not contain the 6658 // input itself. 6659 // The label contents could be text, html, or a mix. We wrap all elements 6660 // and read the wrapper's `innerHTML` to get a string representation of 6661 // the label, without the input as part of it. 6662 labelContents = this.label.contents().not( this.element[ 0 ] ); 6663 6664 if ( labelContents.length ) { 6665 this.originalLabel += labelContents 6666 .clone() 6667 .wrapAll( "<div></div>" ) 6668 .parent() 6669 .html(); 6670 } 6671 6672 // Set the label option if we found label text 6673 if ( this.originalLabel ) { 6674 options.label = this.originalLabel; 6675 } 6676 6677 disabled = this.element[ 0 ].disabled; 6678 if ( disabled != null ) { 6679 options.disabled = disabled; 6680 } 6681 return options; 6682 }, 6683 6684 _create: function() { 6685 var checked = this.element[ 0 ].checked; 6686 6687 this._bindFormResetHandler(); 6688 6689 if ( this.options.disabled == null ) { 6690 this.options.disabled = this.element[ 0 ].disabled; 6691 } 6692 6693 this._setOption( "disabled", this.options.disabled ); 6694 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 6695 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 6696 6697 if ( this.type === "radio" ) { 6698 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 6699 } 6700 6701 if ( this.options.label && this.options.label !== this.originalLabel ) { 6702 this._updateLabel(); 6703 } else if ( this.originalLabel ) { 6704 this.options.label = this.originalLabel; 6705 } 6706 6707 this._enhance(); 6708 6709 if ( checked ) { 6710 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 6711 } 6712 6713 this._on( { 6714 change: "_toggleClasses", 6715 focus: function() { 6716 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 6717 }, 6718 blur: function() { 6719 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 6720 } 6721 } ); 6722 }, 6723 6724 _readType: function() { 6725 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 6726 this.type = this.element[ 0 ].type; 6727 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 6728 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 6729 " and element.type=" + this.type ); 6730 } 6731 }, 6732 6733 // Support jQuery Mobile enhanced option 6734 _enhance: function() { 6735 this._updateIcon( this.element[ 0 ].checked ); 6736 }, 6737 6738 widget: function() { 6739 return this.label; 6740 }, 6741 6742 _getRadioGroup: function() { 6743 var group; 6744 var name = this.element[ 0 ].name; 6745 var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; 6746 6747 if ( !name ) { 6748 return $( [] ); 6749 } 6750 6751 if ( this.form.length ) { 6752 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 6753 } else { 6754 6755 // Not inside a form, check all inputs that also are not inside a form 6756 group = $( nameSelector ).filter( function() { 6757 return $( this )._form().length === 0; 6758 } ); 6759 } 6760 6761 return group.not( this.element ); 6762 }, 6763 6764 _toggleClasses: function() { 6765 var checked = this.element[ 0 ].checked; 6766 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 6767 6768 if ( this.options.icon && this.type === "checkbox" ) { 6769 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 6770 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 6771 } 6772 6773 if ( this.type === "radio" ) { 6774 this._getRadioGroup() 6775 .each( function() { 6776 var instance = $( this ).checkboxradio( "instance" ); 6777 6778 if ( instance ) { 6779 instance._removeClass( instance.label, 6780 "ui-checkboxradio-checked", "ui-state-active" ); 6781 } 6782 } ); 6783 } 6784 }, 6785 6786 _destroy: function() { 6787 this._unbindFormResetHandler(); 6788 6789 if ( this.icon ) { 6790 this.icon.remove();
vendor: 2,708 bytes, lines 6791-6897
6791 this.iconSpace.remove(); 6792 } 6793 }, 6794 6795 _setOption: function( key, value ) { 6796 6797 // We don't allow the value to be set to nothing 6798 if ( key === "label" && !value ) { 6799 return; 6800 } 6801 6802 this._super( key, value ); 6803 6804 if ( key === "disabled" ) { 6805 this._toggleClass( this.label, null, "ui-state-disabled", value ); 6806 this.element[ 0 ].disabled = value; 6807 6808 // Don't refresh when setting disabled 6809 return; 6810 } 6811 this.refresh(); 6812 }, 6813 6814 _updateIcon: function( checked ) { 6815 var toAdd = "ui-icon ui-icon-background "; 6816 6817 if ( this.options.icon ) { 6818 if ( !this.icon ) { 6819 this.icon = $( "<span>" ); 6820 this.iconSpace = $( "<span> </span>" ); 6821 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 6822 } 6823 6824 if ( this.type === "checkbox" ) { 6825 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 6826 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 6827 } else { 6828 toAdd += "ui-icon-blank"; 6829 } 6830 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 6831 if ( !checked ) { 6832 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 6833 } 6834 this.icon.prependTo( this.label ).after( this.iconSpace ); 6835 } else if ( this.icon !== undefined ) { 6836 this.icon.remove(); 6837 this.iconSpace.remove(); 6838 delete this.icon; 6839 } 6840 }, 6841 6842 _updateLabel: function() { 6843 6844 // Remove the contents of the label ( minus the icon, icon space, and input ) 6845 var contents = this.label.contents().not( this.element[ 0 ] ); 6846 if ( this.icon ) { 6847 contents = contents.not( this.icon[ 0 ] ); 6848 } 6849 if ( this.iconSpace ) { 6850 contents = contents.not( this.iconSpace[ 0 ] ); 6851 } 6852 contents.remove(); 6853 6854 this.label.append( this.options.label ); 6855 }, 6856 6857 refresh: function() { 6858 var checked = this.element[ 0 ].checked, 6859 isDisabled = this.element[ 0 ].disabled; 6860 6861 this._updateIcon( checked ); 6862 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 6863 if ( this.options.label !== null ) { 6864 this._updateLabel(); 6865 } 6866 6867 if ( isDisabled !== this.options.disabled ) { 6868 this._setOptions( { "disabled": isDisabled } ); 6869 } 6870 } 6871 6872} ] ); 6873 6874var widgetsCheckboxradio = $.ui.checkboxradio; 6875 6876 6877/*! 6878 * jQuery UI Button 1.13.2 6879 * http://jqueryui.com 6880 * 6881 * Copyright jQuery Foundation and other contributors 6882 * Released under the MIT license. 6883 * http://jquery.org/license 6884 */ 6885 6886//>>label: Button 6887//>>group: Widgets 6888//>>description: Enhances a form with themeable buttons. 6889//>>docs: http://api.jqueryui.com/button/ 6890//>>demos: http://jqueryui.com/button/ 6891//>>css.structure: ../../themes/base/core.css 6892//>>css.structure: ../../themes/base/button.css 6893//>>css.theme: ../../themes/base/theme.css 6894 6895 6896$.widget( "ui.button", { 6897 version: "1.13.2
vendor: 10,836 bytes, lines 6897-7304
6897", 6898 defaultElement: "<button>", 6899 options: { 6900 classes: { 6901 "ui-button": "ui-corner-all" 6902 }, 6903 disabled: null, 6904 icon: null, 6905 iconPosition: "beginning", 6906 label: null, 6907 showLabel: true 6908 }, 6909 6910 _getCreateOptions: function() { 6911 var disabled, 6912 6913 // This is to support cases like in jQuery Mobile where the base widget does have 6914 // an implementation of _getCreateOptions 6915 options = this._super() || {}; 6916 6917 this.isInput = this.element.is( "input" ); 6918 6919 disabled = this.element[ 0 ].disabled; 6920 if ( disabled != null ) { 6921 options.disabled = disabled; 6922 } 6923 6924 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 6925 if ( this.originalLabel ) { 6926 options.label = this.originalLabel; 6927 } 6928 6929 return options; 6930 }, 6931 6932 _create: function() { 6933 if ( !this.option.showLabel & !this.options.icon ) { 6934 this.options.showLabel = true; 6935 } 6936 6937 // We have to check the option again here even though we did in _getCreateOptions, 6938 // because null may have been passed on init which would override what was set in 6939 // _getCreateOptions 6940 if ( this.options.disabled == null ) { 6941 this.options.disabled = this.element[ 0 ].disabled || false; 6942 } 6943 6944 this.hasTitle = !!this.element.attr( "title" ); 6945 6946 // Check to see if the label needs to be set or if its already correct 6947 if ( this.options.label && this.options.label !== this.originalLabel ) { 6948 if ( this.isInput ) { 6949 this.element.val( this.options.label ); 6950 } else { 6951 this.element.html( this.options.label ); 6952 } 6953 } 6954 this._addClass( "ui-button", "ui-widget" ); 6955 this._setOption( "disabled", this.options.disabled ); 6956 this._enhance(); 6957 6958 if ( this.element.is( "a" ) ) { 6959 this._on( { 6960 "keyup": function( event ) { 6961 if ( event.keyCode === $.ui.keyCode.SPACE ) { 6962 event.preventDefault(); 6963 6964 // Support: PhantomJS <= 1.9, IE 8 Only 6965 // If a native click is available use it so we actually cause navigation 6966 // otherwise just trigger a click event 6967 if ( this.element[ 0 ].click ) { 6968 this.element[ 0 ].click(); 6969 } else { 6970 this.element.trigger( "click" ); 6971 } 6972 } 6973 } 6974 } ); 6975 } 6976 }, 6977 6978 _enhance: function() { 6979 if ( !this.element.is( "button" ) ) { 6980 this.element.attr( "role", "button" ); 6981 } 6982 6983 if ( this.options.icon ) { 6984 this._updateIcon( "icon", this.options.icon ); 6985 this._updateTooltip(); 6986 } 6987 }, 6988 6989 _updateTooltip: function() { 6990 this.title = this.element.attr( "title" ); 6991 6992 if ( !this.options.showLabel && !this.title ) { 6993 this.element.attr( "title", this.options.label ); 6994 } 6995 }, 6996 6997 _updateIcon: function( option, value ) { 6998 var icon = option !== "iconPosition", 6999 position = icon ? this.options.iconPosition : value, 7000 displayBlock = position === "top" || position === "bottom"; 7001 7002 // Create icon 7003 if ( !this.icon ) { 7004 this.icon = $( "<span>" ); 7005 7006 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 7007 7008 if ( !this.options.showLabel ) { 7009 this._addClass( "ui-button-icon-only" ); 7010 } 7011 } else if ( icon ) { 7012 7013 // If we are updating the icon remove the old icon class 7014 this._removeClass( this.icon, null, this.options.icon ); 7015 } 7016 7017 // If we are updating the icon add the new icon class 7018 if ( icon ) { 7019 this._addClass( this.icon, null, value ); 7020 } 7021 7022 this._attachIcon( position ); 7023 7024 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 7025 // the iconSpace if there is one. 7026 if ( displayBlock ) { 7027 this._addClass( this.icon, null, "ui-widget-icon-block" ); 7028 if ( this.iconSpace ) { 7029 this.iconSpace.remove(); 7030 } 7031 } else { 7032 7033 // Position is beginning or end so remove the ui-widget-icon-block class and add the 7034 // space if it does not exist 7035 if ( !this.iconSpace ) { 7036 this.iconSpace = $( "<span> </span>" ); 7037 this._addClass( this.iconSpace, "ui-button-icon-space" ); 7038 } 7039 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 7040 this._attachIconSpace( position ); 7041 } 7042 }, 7043 7044 _destroy: function() { 7045 this.element.removeAttr( "role" ); 7046 7047 if ( this.icon ) { 7048 this.icon.remove(); 7049 } 7050 if ( this.iconSpace ) { 7051 this.iconSpace.remove(); 7052 } 7053 if ( !this.hasTitle ) { 7054 this.element.removeAttr( "title" ); 7055 } 7056 }, 7057 7058 _attachIconSpace: function( iconPosition ) { 7059 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 7060 }, 7061 7062 _attachIcon: function( iconPosition ) { 7063 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 7064 }, 7065 7066 _setOptions: function( options ) { 7067 var newShowLabel = options.showLabel === undefined ? 7068 this.options.showLabel : 7069 options.showLabel, 7070 newIcon = options.icon === undefined ? this.options.icon : options.icon; 7071 7072 if ( !newShowLabel && !newIcon ) { 7073 options.showLabel = true; 7074 } 7075 this._super( options ); 7076 }, 7077 7078 _setOption: function( key, value ) { 7079 if ( key === "icon" ) { 7080 if ( value ) { 7081 this._updateIcon( key, value ); 7082 } else if ( this.icon ) { 7083 this.icon.remove(); 7084 if ( this.iconSpace ) { 7085 this.iconSpace.remove(); 7086 } 7087 } 7088 } 7089 7090 if ( key === "iconPosition" ) { 7091 this._updateIcon( key, value ); 7092 } 7093 7094 // Make sure we can't end up with a button that has neither text nor icon 7095 if ( key === "showLabel" ) { 7096 this._toggleClass( "ui-button-icon-only", null, !value ); 7097 this._updateTooltip(); 7098 } 7099 7100 if ( key === "label" ) { 7101 if ( this.isInput ) { 7102 this.element.val( value ); 7103 } else { 7104 7105 // If there is an icon, append it, else nothing then append the value 7106 // this avoids removal of the icon when setting label text 7107 this.element.html( value ); 7108 if ( this.icon ) { 7109 this._attachIcon( this.options.iconPosition ); 7110 this._attachIconSpace( this.options.iconPosition ); 7111 } 7112 } 7113 } 7114 7115 this._super( key, value ); 7116 7117 if ( key === "disabled" ) { 7118 this._toggleClass( null, "ui-state-disabled", value ); 7119 this.element[ 0 ].disabled = value; 7120 if ( value ) { 7121 this.element.trigger( "blur" ); 7122 } 7123 } 7124 }, 7125 7126 refresh: function() { 7127 7128 // Make sure to only check disabled if its an element that supports this otherwise 7129 // check for the disabled class to determine state 7130 var isDisabled = this.element.is( "input, button" ) ? 7131 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 7132 7133 if ( isDisabled !== this.options.disabled ) { 7134 this._setOptions( { disabled: isDisabled } ); 7135 } 7136 7137 this._updateTooltip(); 7138 } 7139} ); 7140 7141// DEPRECATED 7142if ( $.uiBackCompat !== false ) { 7143 7144 // Text and Icons options 7145 $.widget( "ui.button", $.ui.button, { 7146 options: { 7147 text: true, 7148 icons: { 7149 primary: null, 7150 secondary: null 7151 } 7152 }, 7153 7154 _create: function() { 7155 if ( this.options.showLabel && !this.options.text ) { 7156 this.options.showLabel = this.options.text; 7157 } 7158 if ( !this.options.showLabel && this.options.text ) { 7159 this.options.text = this.options.showLabel; 7160 } 7161 if ( !this.options.icon && ( this.options.icons.primary || 7162 this.options.icons.secondary ) ) { 7163 if ( this.options.icons.primary ) { 7164 this.options.icon = this.options.icons.primary; 7165 } else { 7166 this.options.icon = this.options.icons.secondary; 7167 this.options.iconPosition = "end"; 7168 } 7169 } else if ( this.options.icon ) { 7170 this.options.icons.primary = this.options.icon; 7171 } 7172 this._super(); 7173 }, 7174 7175 _setOption: function( key, value ) { 7176 if ( key === "text" ) { 7177 this._super( "showLabel", value ); 7178 return; 7179 } 7180 if ( key === "showLabel" ) { 7181 this.options.text = value; 7182 } 7183 if ( key === "icon" ) { 7184 this.options.icons.primary = value; 7185 } 7186 if ( key === "icons" ) { 7187 if ( value.primary ) { 7188 this._super( "icon", value.primary ); 7189 this._super( "iconPosition", "beginning" ); 7190 } else if ( value.secondary ) { 7191 this._super( "icon", value.secondary ); 7192 this._super( "iconPosition", "end" ); 7193 } 7194 } 7195 this._superApply( arguments ); 7196 } 7197 } ); 7198 7199 $.fn.button = ( function( orig ) { 7200 return function( options ) { 7201 var isMethodCall = typeof options === "string"; 7202 var args = Array.prototype.slice.call( arguments, 1 ); 7203 var returnValue = this; 7204 7205 if ( isMethodCall ) { 7206 7207 // If this is an empty collection, we need to have the instance method 7208 // return undefined instead of the jQuery instance 7209 if ( !this.length && options === "instance" ) { 7210 returnValue = undefined; 7211 } else { 7212 this.each( function() { 7213 var methodValue; 7214 var type = $( this ).attr( "type" ); 7215 var name = type !== "checkbox" && type !== "radio" ? 7216 "button" : 7217 "checkboxradio"; 7218 var instance = $.data( this, "ui-" + name ); 7219 7220 if ( options === "instance" ) { 7221 returnValue = instance; 7222 return false; 7223 } 7224 7225 if ( !instance ) { 7226 return $.error( "cannot call methods on button" + 7227 " prior to initialization; " + 7228 "attempted to call method '" + options + "'" ); 7229 } 7230 7231 if ( typeof instance[ options ] !== "function" || 7232 options.charAt( 0 ) === "_" ) { 7233 return $.error( "no such method '" + options + "' for button" + 7234 " widget instance" ); 7235 } 7236 7237 methodValue = instance[ options ].apply( instance, args ); 7238 7239 if ( methodValue !== instance && methodValue !== undefined ) { 7240 returnValue = methodValue && methodValue.jquery ? 7241 returnValue.pushStack( methodValue.get() ) : 7242 methodValue; 7243 return false; 7244 } 7245 } ); 7246 } 7247 } else { 7248 7249 // Allow multiple hashes to be passed on init 7250 if ( args.length ) { 7251 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 7252 } 7253 7254 this.each( function() { 7255 var type = $( this ).attr( "type" ); 7256 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 7257 var instance = $.data( this, "ui-" + name ); 7258 7259 if ( instance ) { 7260 instance.option( options || {} ); 7261 if ( instance._init ) { 7262 instance._init(); 7263 } 7264 } else { 7265 if ( name === "button" ) { 7266 orig.call( $( this ), options ); 7267 return; 7268 } 7269 7270 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 7271 } 7272 } ); 7273 } 7274 7275 return returnValue; 7276 }; 7277 } )( $.fn.button ); 7278 7279 $.fn.buttonset = function() { 7280 if ( !$.ui.controlgroup ) { 7281 $.error( "Controlgroup widget missing" ); 7282 } 7283 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 7284 return this.controlgroup.apply( this, 7285 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 7286 } 7287 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 7288 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 7289 } 7290 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 7291 arguments[ 0 ].items = { 7292 button: arguments[ 0 ].items 7293 }; 7294 } 7295 return this.controlgroup.apply( this, arguments ); 7296 }; 7297} 7298 7299var widgetsButton = $.ui.button; 7300 7301 7302/* eslint-disable max-len, camelcase */ 7303/*! 7304 * jQuery UI Datepicker 1.13.
73042 7305 * http://jqueryui.com 7306 * 7307 * Copyright jQuery Foundation and other contributors 7308 * Released under the MIT license. 7309 * http://jquery.org/license 7310 */ 7311 7312//>>label: Datepicker 7313//>>group: Widgets 7314//>>description: Displays a calendar from an input or inline for selecting dates. 7315//>>docs: http://api.jqueryui.com/datepicker/ 7316//>>demos: http://jqueryui.com/datepicker/ 7317//>>css.structure: ../../themes/base/core.css 7318//>>css.structure: ../../themes/base/datepicker.css 7319//>>css.theme: ../../themes/base/theme.css 7320 7321 7322$.extend( $.ui, { datepicker: { version: "1.13.2
vendor: 81,557 bytes, lines 7322-9519
7322" } } ); 7323 7324var datepicker_instActive; 7325 7326function datepicker_getZindex( elem ) { 7327 var position, value; 7328 while ( elem.length && elem[ 0 ] !== document ) { 7329 7330 // Ignore z-index if position is set to a value where z-index is ignored by the browser 7331 // This makes behavior of this function consistent across browsers 7332 // WebKit always returns auto if the element is positioned 7333 position = elem.css( "position" ); 7334 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 7335 7336 // IE returns 0 when zIndex is not specified 7337 // other browsers return a string 7338 // we ignore the case of nested elements with an explicit value of 0 7339 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 7340 value = parseInt( elem.css( "zIndex" ), 10 ); 7341 if ( !isNaN( value ) && value !== 0 ) { 7342 return value; 7343 } 7344 } 7345 elem = elem.parent(); 7346 } 7347 7348 return 0; 7349} 7350 7351/* Date picker manager. 7352 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7353 Settings for (groups of) date pickers are maintained in an instance object, 7354 allowing multiple different settings on the same page. */ 7355 7356function Datepicker() { 7357 this._curInst = null; // The current instance in use 7358 this._keyEvent = false; // If the last event was a key event 7359 this._disabledInputs = []; // List of date picker inputs that have been disabled 7360 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7361 this._inDialog = false; // True if showing within a "dialog", false if not 7362 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7363 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7364 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7365 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7366 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7367 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7368 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7369 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7370 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7371 this.regional = []; // Available regional settings, indexed by language code 7372 this.regional[ "" ] = { // Default regional settings 7373 closeText: "Done", // Display text for close link 7374 prevText: "Prev", // Display text for previous month link 7375 nextText: "Next", // Display text for next month link 7376 currentText: "Today", // Display text for current month link 7377 monthNames: [ "January", "February", "March", "April", "May", "June", 7378 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 7379 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 7380 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 7381 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 7382 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 7383 weekHeader: "Wk", // Column header for week of the year 7384 dateFormat: "mm/dd/yy", // See format options on parseDate 7385 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7386 isRTL: false, // True if right-to-left language, false if left-to-right 7387 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7388 yearSuffix: "", // Additional text to append to the year in the month headers, 7389 selectMonthLabel: "Select month", // Invisible label for month selector 7390 selectYearLabel: "Select year" // Invisible label for year selector 7391 }; 7392 this._defaults = { // Global defaults for all the date picker instances 7393 showOn: "focus", // "focus" for popup on focus, 7394 // "button" for trigger button, or "both" for either 7395 showAnim: "fadeIn", // Name of jQuery animation for popup 7396 showOptions: {}, // Options for enhanced animations 7397 defaultDate: null, // Used when field is blank: actual date, 7398 // +/-number for offset from today, null for today 7399 appendText: "", // Display text following the input box, e.g. showing the format 7400 buttonText: "...", // Text for trigger button 7401 buttonImage: "", // URL for trigger button image 7402 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7403 hideIfNoPrevNext: false, // True to hide next/previous month links 7404 // if not applicable, false to just disable them 7405 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7406 gotoCurrent: false, // True if today link goes back to current selection instead 7407 changeMonth: false, // True if month can be selected directly, false if only prev/next 7408 changeYear: false, // True if year can be selected directly, false if only prev/next 7409 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7410 // either relative to today's year (-nn:+nn), relative to currently displayed year 7411 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7412 showOtherMonths: false, // True to show dates in other months, false to leave blank 7413 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7414 showWeek: false, // True to show week of the year, false to not show it 7415 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7416 // takes a Date and returns the number of the week for it 7417 shortYearCutoff: "+10", // Short year values < this are in the current century, 7418 // > this are in the previous century, 7419 // string value starting with "+" for current year + value 7420 minDate: null, // The earliest selectable date, or null for no limit 7421 maxDate: null, // The latest selectable date, or null for no limit 7422 duration: "fast", // Duration of display/closure 7423 beforeShowDay: null, // Function that takes a date and returns an array with 7424 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7425 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7426 beforeShow: null, // Function that takes an input field and 7427 // returns a set of custom settings for the date picker 7428 onSelect: null, // Define a callback function when a date is selected 7429 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7430 onClose: null, // Define a callback function when the datepicker is closed 7431 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 7432 numberOfMonths: 1, // Number of months to show at a time 7433 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7434 stepMonths: 1, // Number of months to step back/forward 7435 stepBigMonths: 12, // Number of months to step back/forward for the big links 7436 altField: "", // Selector for an alternate field to store selected dates into 7437 altFormat: "", // The date format to use for the alternate field 7438 constrainInput: true, // The input is constrained by the current date format 7439 showButtonPanel: false, // True to show button panel, false to not show it 7440 autoSize: false, // True to size the input for the date format, false to leave as is 7441 disabled: false // The initial disabled state 7442 }; 7443 $.extend( this._defaults, this.regional[ "" ] ); 7444 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 7445 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 7446 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 7447} 7448 7449$.extend( Datepicker.prototype, { 7450 7451 /* Class name added to elements to indicate already configured with a date picker. */ 7452 markerClassName: "hasDatepicker", 7453 7454 //Keep track of the maximum number of rows displayed (see #7043) 7455 maxRows: 4, 7456 7457 // TODO rename to "widget" when switching to widget factory 7458 _widgetDatepicker: function() { 7459 return this.dpDiv; 7460 }, 7461 7462 /* Override the default settings for all instances of the date picker. 7463 * @param settings object - the new settings to use as defaults (anonymous object) 7464 * @return the manager object 7465 */ 7466 setDefaults: function( settings ) { 7467 datepicker_extendRemove( this._defaults, settings || {} ); 7468 return this; 7469 }, 7470 7471 /* Attach the date picker to a jQuery selection. 7472 * @param target element - the target input field or division or span 7473 * @param settings object - the new settings to use for this date picker instance (anonymous) 7474 */ 7475 _attachDatepicker: function( target, settings ) { 7476 var nodeName, inline, inst; 7477 nodeName = target.nodeName.toLowerCase(); 7478 inline = ( nodeName === "div" || nodeName === "span" ); 7479 if ( !target.id ) { 7480 this.uuid += 1; 7481 target.id = "dp" + this.uuid; 7482 } 7483 inst = this._newInst( $( target ), inline ); 7484 inst.settings = $.extend( {}, settings || {} ); 7485 if ( nodeName === "input" ) { 7486 this._connectDatepicker( target, inst ); 7487 } else if ( inline ) { 7488 this._inlineDatepicker( target, inst ); 7489 } 7490 }, 7491 7492 /* Create a new instance object. */ 7493 _newInst: function( target, inline ) { 7494 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 7495 return { id: id, input: target, // associated target 7496 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7497 drawMonth: 0, drawYear: 0, // month being drawn 7498 inline: inline, // is datepicker inline or not 7499 dpDiv: ( !inline ? this.dpDiv : // presentation div 7500 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 7501 }, 7502 7503 /* Attach the date picker to an input field. */ 7504 _connectDatepicker: function( target, inst ) { 7505 var input = $( target ); 7506 inst.append = $( [] ); 7507 inst.trigger = $( [] ); 7508 if ( input.hasClass( this.markerClassName ) ) { 7509 return; 7510 } 7511 this._attachments( input, inst ); 7512 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 7513 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 7514 this._autoSize( inst ); 7515 $.data( target, "datepicker", inst ); 7516 7517 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7518 if ( inst.settings.disabled ) { 7519 this._disableDatepicker( target ); 7520 } 7521 }, 7522 7523 /* Make attachments based on settings. */ 7524 _attachments: function( input, inst ) { 7525 var showOn, buttonText, buttonImage, 7526 appendText = this._get( inst, "appendText" ), 7527 isRTL = this._get( inst, "isRTL" ); 7528 7529 if ( inst.append ) { 7530 inst.append.remove(); 7531 } 7532 if ( appendText ) { 7533 inst.append = $( "<span>" ) 7534 .addClass( this._appendClass ) 7535 .text( appendText ); 7536 input[ isRTL ? "before" : "after" ]( inst.append ); 7537 } 7538 7539 input.off( "focus", this._showDatepicker ); 7540 7541 if ( inst.trigger ) { 7542 inst.trigger.remove(); 7543 } 7544 7545 showOn = this._get( inst, "showOn" ); 7546 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 7547 input.on( "focus", this._showDatepicker ); 7548 } 7549 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 7550 buttonText = this._get( inst, "buttonText" ); 7551 buttonImage = this._get( inst, "buttonImage" ); 7552 7553 if ( this._get( inst, "buttonImageOnly" ) ) { 7554 inst.trigger = $( "<img>" ) 7555 .addClass( this._triggerClass ) 7556 .attr( { 7557 src: buttonImage, 7558 alt: buttonText, 7559 title: buttonText 7560 } ); 7561 } else { 7562 inst.trigger = $( "<button type='button'>" ) 7563 .addClass( this._triggerClass ); 7564 if ( buttonImage ) { 7565 inst.trigger.html( 7566 $( "<img>" ) 7567 .attr( { 7568 src: buttonImage, 7569 alt: buttonText, 7570 title: buttonText 7571 } ) 7572 ); 7573 } else { 7574 inst.trigger.text( buttonText ); 7575 } 7576 } 7577 7578 input[ isRTL ? "before" : "after" ]( inst.trigger ); 7579 inst.trigger.on( "click", function() { 7580 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 7581 $.datepicker._hideDatepicker(); 7582 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 7583 $.datepicker._hideDatepicker(); 7584 $.datepicker._showDatepicker( input[ 0 ] ); 7585 } else { 7586 $.datepicker._showDatepicker( input[ 0 ] ); 7587 } 7588 return false; 7589 } ); 7590 } 7591 }, 7592 7593 /* Apply the maximum length for the date format. */ 7594 _autoSize: function( inst ) { 7595 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 7596 var findMax, max, maxI, i, 7597 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 7598 dateFormat = this._get( inst, "dateFormat" ); 7599 7600 if ( dateFormat.match( /[DM]/ ) ) { 7601 findMax = function( names ) { 7602 max = 0; 7603 maxI = 0; 7604 for ( i = 0; i < names.length; i++ ) { 7605 if ( names[ i ].length > max ) { 7606 max = names[ i ].length; 7607 maxI = i; 7608 } 7609 } 7610 return maxI; 7611 }; 7612 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 7613 "monthNames" : "monthNamesShort" ) ) ) ); 7614 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 7615 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 7616 } 7617 inst.input.attr( "size", this._formatDate( inst, date ).length ); 7618 } 7619 }, 7620 7621 /* Attach an inline date picker to a div. */ 7622 _inlineDatepicker: function( target, inst ) { 7623 var divSpan = $( target ); 7624 if ( divSpan.hasClass( this.markerClassName ) ) { 7625 return; 7626 } 7627 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 7628 $.data( target, "datepicker", inst ); 7629 this._setDate( inst, this._getDefaultDate( inst ), true ); 7630 this._updateDatepicker( inst ); 7631 this._updateAlternate( inst ); 7632 7633 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7634 if ( inst.settings.disabled ) { 7635 this._disableDatepicker( target ); 7636 } 7637 7638 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7639 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7640 inst.dpDiv.css( "display", "block" ); 7641 }, 7642 7643 /* Pop-up the date picker in a "dialog" box. 7644 * @param input element - ignored 7645 * @param date string or Date - the initial date to display 7646 * @param onSelect function - the function to call when a date is selected 7647 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7648 * @param pos int[2] - coordinates for the dialog's position within the screen or 7649 * event - with x/y coordinates or 7650 * leave empty for default (screen centre) 7651 * @return the manager object 7652 */ 7653 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 7654 var id, browserWidth, browserHeight, scrollX, scrollY, 7655 inst = this._dialogInst; // internal instance 7656 7657 if ( !inst ) { 7658 this.uuid += 1; 7659 id = "dp" + this.uuid; 7660 this._dialogInput = $( "<input type='text' id='" + id + 7661 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 7662 this._dialogInput.on( "keydown", this._doKeyDown ); 7663 $( "body" ).append( this._dialogInput ); 7664 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 7665 inst.settings = {}; 7666 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 7667 } 7668 datepicker_extendRemove( inst.settings, settings || {} ); 7669 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 7670 this._dialogInput.val( date ); 7671 7672 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 7673 if ( !this._pos ) { 7674 browserWidth = document.documentElement.clientWidth; 7675 browserHeight = document.documentElement.clientHeight; 7676 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7677 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7678 this._pos = // should use actual width/height below 7679 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 7680 } 7681 7682 // Move input on screen for focus, but hidden behind dialog 7683 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 7684 inst.settings.onSelect = onSelect; 7685 this._inDialog = true; 7686 this.dpDiv.addClass( this._dialogClass ); 7687 this._showDatepicker( this._dialogInput[ 0 ] ); 7688 if ( $.blockUI ) { 7689 $.blockUI( this.dpDiv ); 7690 } 7691 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 7692 return this; 7693 }, 7694 7695 /* Detach a datepicker from its control. 7696 * @param target element - the target input field or division or span 7697 */ 7698 _destroyDatepicker: function( target ) { 7699 var nodeName, 7700 $target = $( target ), 7701 inst = $.data( target, "datepicker" ); 7702 7703 if ( !$target.hasClass( this.markerClassName ) ) { 7704 return; 7705 } 7706 7707 nodeName = target.nodeName.toLowerCase(); 7708 $.removeData( target, "datepicker" ); 7709 if ( nodeName === "input" ) { 7710 inst.append.remove(); 7711 inst.trigger.remove(); 7712 $target.removeClass( this.markerClassName ). 7713 off( "focus", this._showDatepicker ). 7714 off( "keydown", this._doKeyDown ). 7715 off( "keypress", this._doKeyPress ). 7716 off( "keyup", this._doKeyUp ); 7717 } else if ( nodeName === "div" || nodeName === "span" ) { 7718 $target.removeClass( this.markerClassName ).empty(); 7719 } 7720 7721 if ( datepicker_instActive === inst ) { 7722 datepicker_instActive = null; 7723 this._curInst = null; 7724 } 7725 }, 7726 7727 /* Enable the date picker to a jQuery selection. 7728 * @param target element - the target input field or division or span 7729 */ 7730 _enableDatepicker: function( target ) { 7731 var nodeName, inline, 7732 $target = $( target ), 7733 inst = $.data( target, "datepicker" ); 7734 7735 if ( !$target.hasClass( this.markerClassName ) ) { 7736 return; 7737 } 7738 7739 nodeName = target.nodeName.toLowerCase(); 7740 if ( nodeName === "input" ) { 7741 target.disabled = false; 7742 inst.trigger.filter( "button" ). 7743 each( function() { 7744 this.disabled = false; 7745 } ).end(). 7746 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 7747 } else if ( nodeName === "div" || nodeName === "span" ) { 7748 inline = $target.children( "." + this._inlineClass ); 7749 inline.children().removeClass( "ui-state-disabled" ); 7750 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 7751 prop( "disabled", false ); 7752 } 7753 this._disabledInputs = $.map( this._disabledInputs, 7754 7755 // Delete entry 7756 function( value ) { 7757 return ( value === target ? null : value ); 7758 } ); 7759 }, 7760 7761 /* Disable the date picker to a jQuery selection. 7762 * @param target element - the target input field or division or span 7763 */ 7764 _disableDatepicker: function( target ) { 7765 var nodeName, inline, 7766 $target = $( target ), 7767 inst = $.data( target, "datepicker" ); 7768 7769 if ( !$target.hasClass( this.markerClassName ) ) { 7770 return; 7771 } 7772 7773 nodeName = target.nodeName.toLowerCase(); 7774 if ( nodeName === "input" ) { 7775 target.disabled = true; 7776 inst.trigger.filter( "button" ). 7777 each( function() { 7778 this.disabled = true; 7779 } ).end(). 7780 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 7781 } else if ( nodeName === "div" || nodeName === "span" ) { 7782 inline = $target.children( "." + this._inlineClass ); 7783 inline.children().addClass( "ui-state-disabled" ); 7784 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 7785 prop( "disabled", true ); 7786 } 7787 this._disabledInputs = $.map( this._disabledInputs, 7788 7789 // Delete entry 7790 function( value ) { 7791 return ( value === target ? null : value ); 7792 } ); 7793 this._disabledInputs[ this._disabledInputs.length ] = target; 7794 }, 7795 7796 /* Is the first field in a jQuery collection disabled as a datepicker? 7797 * @param target element - the target input field or division or span 7798 * @return boolean - true if disabled, false if enabled 7799 */ 7800 _isDisabledDatepicker: function( target ) { 7801 if ( !target ) { 7802 return false; 7803 } 7804 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 7805 if ( this._disabledInputs[ i ] === target ) { 7806 return true; 7807 } 7808 } 7809 return false; 7810 }, 7811 7812 /* Retrieve the instance data for the target control. 7813 * @param target element - the target input field or division or span 7814 * @return object - the associated instance data 7815 * @throws error if a jQuery problem getting data 7816 */ 7817 _getInst: function( target ) { 7818 try { 7819 return $.data( target, "datepicker" ); 7820 } catch ( err ) { 7821 throw "Missing instance data for this datepicker"; 7822 } 7823 }, 7824 7825 /* Update or retrieve the settings for a date picker attached to an input field or division. 7826 * @param target element - the target input field or division or span 7827 * @param name object - the new settings to update or 7828 * string - the name of the setting to change or retrieve, 7829 * when retrieving also "all" for all instance settings or 7830 * "defaults" for all global defaults 7831 * @param value any - the new value for the setting 7832 * (omit if above is an object or to retrieve a value) 7833 */ 7834 _optionDatepicker: function( target, name, value ) { 7835 var settings, date, minDate, maxDate, 7836 inst = this._getInst( target ); 7837 7838 if ( arguments.length === 2 && typeof name === "string" ) { 7839 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 7840 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 7841 this._get( inst, name ) ) : null ) ); 7842 } 7843 7844 settings = name || {}; 7845 if ( typeof name === "string" ) { 7846 settings = {}; 7847 settings[ name ] = value; 7848 } 7849 7850 if ( inst ) { 7851 if ( this._curInst === inst ) { 7852 this._hideDatepicker(); 7853 } 7854 7855 date = this._getDateDatepicker( target, true ); 7856 minDate = this._getMinMaxDate( inst, "min" ); 7857 maxDate = this._getMinMaxDate( inst, "max" ); 7858 datepicker_extendRemove( inst.settings, settings ); 7859 7860 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7861 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 7862 inst.settings.minDate = this._formatDate( inst, minDate ); 7863 } 7864 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 7865 inst.settings.maxDate = this._formatDate( inst, maxDate ); 7866 } 7867 if ( "disabled" in settings ) { 7868 if ( settings.disabled ) { 7869 this._disableDatepicker( target ); 7870 } else { 7871 this._enableDatepicker( target ); 7872 } 7873 } 7874 this._attachments( $( target ), inst ); 7875 this._autoSize( inst ); 7876 this._setDate( inst, date ); 7877 this._updateAlternate( inst ); 7878 this._updateDatepicker( inst ); 7879 } 7880 }, 7881 7882 // Change method deprecated 7883 _changeDatepicker: function( target, name, value ) { 7884 this._optionDatepicker( target, name, value ); 7885 }, 7886 7887 /* Redraw the date picker attached to an input field or division. 7888 * @param target element - the target input field or division or span 7889 */ 7890 _refreshDatepicker: function( target ) { 7891 var inst = this._getInst( target ); 7892 if ( inst ) { 7893 this._updateDatepicker( inst ); 7894 } 7895 }, 7896 7897 /* Set the dates for a jQuery selection. 7898 * @param target element - the target input field or division or span 7899 * @param date Date - the new date 7900 */ 7901 _setDateDatepicker: function( target, date ) { 7902 var inst = this._getInst( target ); 7903 if ( inst ) { 7904 this._setDate( inst, date ); 7905 this._updateDatepicker( inst ); 7906 this._updateAlternate( inst ); 7907 } 7908 }, 7909 7910 /* Get the date(s) for the first entry in a jQuery selection. 7911 * @param target element - the target input field or division or span 7912 * @param noDefault boolean - true if no default date is to be used 7913 * @return Date - the current date 7914 */ 7915 _getDateDatepicker: function( target, noDefault ) { 7916 var inst = this._getInst( target ); 7917 if ( inst && !inst.inline ) { 7918 this._setDateFromField( inst, noDefault ); 7919 } 7920 return ( inst ? this._getDate( inst ) : null ); 7921 }, 7922 7923 /* Handle keystrokes. */ 7924 _doKeyDown: function( event ) { 7925 var onSelect, dateStr, sel, 7926 inst = $.datepicker._getInst( event.target ), 7927 handled = true, 7928 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 7929 7930 inst._keyEvent = true; 7931 if ( $.datepicker._datepickerShowing ) { 7932 switch ( event.keyCode ) { 7933 case 9: $.datepicker._hideDatepicker(); 7934 handled = false; 7935 break; // hide on tab out 7936 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 7937 $.datepicker._currentClass + ")", inst.dpDiv ); 7938 if ( sel[ 0 ] ) { 7939 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 7940 } 7941 7942 onSelect = $.datepicker._get( inst, "onSelect" ); 7943 if ( onSelect ) { 7944 dateStr = $.datepicker._formatDate( inst ); 7945 7946 // Trigger custom callback 7947 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 7948 } else { 7949 $.datepicker._hideDatepicker(); 7950 } 7951 7952 return false; // don't submit the form 7953 case 27: $.datepicker._hideDatepicker(); 7954 break; // hide on escape 7955 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 7956 -$.datepicker._get( inst, "stepBigMonths" ) : 7957 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 7958 break; // previous month/year on page up/+ ctrl 7959 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 7960 +$.datepicker._get( inst, "stepBigMonths" ) : 7961 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 7962 break; // next month/year on page down/+ ctrl 7963 case 35: if ( event.ctrlKey || event.metaKey ) { 7964 $.datepicker._clearDate( event.target ); 7965 } 7966 handled = event.ctrlKey || event.metaKey; 7967 break; // clear on ctrl or command +end 7968 case 36: if ( event.ctrlKey || event.metaKey ) { 7969 $.datepicker._gotoToday( event.target ); 7970 } 7971 handled = event.ctrlKey || event.metaKey; 7972 break; // current on ctrl or command +home 7973 case 37: if ( event.ctrlKey || event.metaKey ) { 7974 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 7975 } 7976 handled = event.ctrlKey || event.metaKey; 7977 7978 // -1 day on ctrl or command +left 7979 if ( event.originalEvent.altKey ) { 7980 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 7981 -$.datepicker._get( inst, "stepBigMonths" ) : 7982 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 7983 } 7984 7985 // next month/year on alt +left on Mac 7986 break; 7987 case 38: if ( event.ctrlKey || event.metaKey ) { 7988 $.datepicker._adjustDate( event.target, -7, "D" ); 7989 } 7990 handled = event.ctrlKey || event.metaKey; 7991 break; // -1 week on ctrl or command +up 7992 case 39: if ( event.ctrlKey || event.metaKey ) { 7993 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 7994 } 7995 handled = event.ctrlKey || event.metaKey; 7996 7997 // +1 day on ctrl or command +right 7998 if ( event.originalEvent.altKey ) { 7999 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 8000 +$.datepicker._get( inst, "stepBigMonths" ) : 8001 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 8002 } 8003 8004 // next month/year on alt +right 8005 break; 8006 case 40: if ( event.ctrlKey || event.metaKey ) { 8007 $.datepicker._adjustDate( event.target, +7, "D" ); 8008 } 8009 handled = event.ctrlKey || event.metaKey; 8010 break; // +1 week on ctrl or command +down 8011 default: handled = false; 8012 } 8013 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 8014 $.datepicker._showDatepicker( this ); 8015 } else { 8016 handled = false; 8017 } 8018 8019 if ( handled ) { 8020 event.preventDefault(); 8021 event.stopPropagation(); 8022 } 8023 }, 8024 8025 /* Filter entered characters - based on date format. */ 8026 _doKeyPress: function( event ) { 8027 var chars, chr, 8028 inst = $.datepicker._getInst( event.target ); 8029 8030 if ( $.datepicker._get( inst, "constrainInput" ) ) { 8031 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 8032 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 8033 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 8034 } 8035 }, 8036 8037 /* Synchronise manual entry and field/alternate field. */ 8038 _doKeyUp: function( event ) { 8039 var date, 8040 inst = $.datepicker._getInst( event.target ); 8041 8042 if ( inst.input.val() !== inst.lastVal ) { 8043 try { 8044 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 8045 ( inst.input ? inst.input.val() : null ), 8046 $.datepicker._getFormatConfig( inst ) ); 8047 8048 if ( date ) { // only if valid 8049 $.datepicker._setDateFromField( inst ); 8050 $.datepicker._updateAlternate( inst ); 8051 $.datepicker._updateDatepicker( inst ); 8052 } 8053 } catch ( err ) { 8054 } 8055 } 8056 return true; 8057 }, 8058 8059 /* Pop-up the date picker for a given input field. 8060 * If false returned from beforeShow event handler do not show. 8061 * @param input element - the input field attached to the date picker or 8062 * event - if triggered by focus 8063 */ 8064 _showDatepicker: function( input ) { 8065 input = input.target || input; 8066 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 8067 input = $( "input", input.parentNode )[ 0 ]; 8068 } 8069 8070 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 8071 return; 8072 } 8073 8074 var inst, beforeShow, beforeShowSettings, isFixed, 8075 offset, showAnim, duration; 8076 8077 inst = $.datepicker._getInst( input ); 8078 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 8079 $.datepicker._curInst.dpDiv.stop( true, true ); 8080 if ( inst && $.datepicker._datepickerShowing ) { 8081 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 8082 } 8083 } 8084 8085 beforeShow = $.datepicker._get( inst, "beforeShow" ); 8086 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 8087 if ( beforeShowSettings === false ) { 8088 return; 8089 } 8090 datepicker_extendRemove( inst.settings, beforeShowSettings ); 8091 8092 inst.lastVal = null; 8093 $.datepicker._lastInput = input; 8094 $.datepicker._setDateFromField( inst ); 8095 8096 if ( $.datepicker._inDialog ) { // hide cursor 8097 input.value = ""; 8098 } 8099 if ( !$.datepicker._pos ) { // position below input 8100 $.datepicker._pos = $.datepicker._findPos( input ); 8101 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 8102 } 8103 8104 isFixed = false; 8105 $( input ).parents().each( function() { 8106 isFixed |= $( this ).css( "position" ) === "fixed"; 8107 return !isFixed; 8108 } ); 8109 8110 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 8111 $.datepicker._pos = null; 8112 8113 //to avoid flashes on Firefox 8114 inst.dpDiv.empty(); 8115 8116 // determine sizing offscreen 8117 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 8118 $.datepicker._updateDatepicker( inst ); 8119 8120 // fix width for dynamic number of date pickers 8121 // and adjust position before showing 8122 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 8123 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 8124 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 8125 left: offset.left + "px", top: offset.top + "px" } ); 8126 8127 if ( !inst.inline ) { 8128 showAnim = $.datepicker._get( inst, "showAnim" ); 8129 duration = $.datepicker._get( inst, "duration" ); 8130 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 8131 $.datepicker._datepickerShowing = true; 8132 8133 if ( $.effects && $.effects.effect[ showAnim ] ) { 8134 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 8135 } else { 8136 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 8137 } 8138 8139 if ( $.datepicker._shouldFocusInput( inst ) ) { 8140 inst.input.trigger( "focus" ); 8141 } 8142 8143 $.datepicker._curInst = inst; 8144 } 8145 }, 8146 8147 /* Generate the date picker content. */ 8148 _updateDatepicker: function( inst ) { 8149 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8150 datepicker_instActive = inst; // for delegate hover events 8151 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 8152 this._attachHandlers( inst ); 8153 8154 var origyearshtml, 8155 numMonths = this._getNumberOfMonths( inst ), 8156 cols = numMonths[ 1 ], 8157 width = 17, 8158 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 8159 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 8160 8161 if ( activeCell.length > 0 ) { 8162 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 8163 } 8164 8165 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 8166 if ( cols > 1 ) { 8167 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 8168 } 8169 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 8170 "Class" ]( "ui-datepicker-multi" ); 8171 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 8172 "Class" ]( "ui-datepicker-rtl" ); 8173 8174 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8175 inst.input.trigger( "focus" ); 8176 } 8177 8178 // Deffered render of the years select (to avoid flashes on Firefox) 8179 if ( inst.yearshtml ) { 8180 origyearshtml = inst.yearshtml; 8181 setTimeout( function() { 8182 8183 //assure that inst.yearshtml didn't change. 8184 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 8185 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 8186 } 8187 origyearshtml = inst.yearshtml = null; 8188 }, 0 ); 8189 } 8190 8191 if ( onUpdateDatepicker ) { 8192 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 8193 } 8194 }, 8195 8196 // #6694 - don't focus the input if it's already focused 8197 // this breaks the change event in IE 8198 // Support: IE and jQuery <1.9 8199 _shouldFocusInput: function( inst ) { 8200 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 8201 }, 8202 8203 /* Check positioning to remain on screen. */ 8204 _checkOffset: function( inst, offset, isFixed ) { 8205 var dpWidth = inst.dpDiv.outerWidth(), 8206 dpHeight = inst.dpDiv.outerHeight(), 8207 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8208 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8209 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 8210 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 8211 8212 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 8213 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 8214 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 8215 8216 // Now check if datepicker is showing outside window viewport - move to a better place if so. 8217 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 8218 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 8219 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 8220 Math.abs( dpHeight + inputHeight ) : 0 ); 8221 8222 return offset; 8223 }, 8224 8225 /* Find an object's position on the screen. */ 8226 _findPos: function( obj ) { 8227 var position, 8228 inst = this._getInst( obj ), 8229 isRTL = this._get( inst, "isRTL" ); 8230 8231 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 8232 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 8233 } 8234 8235 position = $( obj ).offset(); 8236 return [ position.left, position.top ]; 8237 }, 8238 8239 /* Hide the date picker from view. 8240 * @param input element - the input field attached to the date picker 8241 */ 8242 _hideDatepicker: function( input ) { 8243 var showAnim, duration, postProcess, onClose, 8244 inst = this._curInst; 8245 8246 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 8247 return; 8248 } 8249 8250 if ( this._datepickerShowing ) { 8251 showAnim = this._get( inst, "showAnim" ); 8252 duration = this._get( inst, "duration" ); 8253 postProcess = function() { 8254 $.datepicker._tidyDialog( inst ); 8255 }; 8256 8257 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8258 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8259 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 8260 } else { 8261 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 8262 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 8263 } 8264 8265 if ( !showAnim ) { 8266 postProcess(); 8267 } 8268 this._datepickerShowing = false; 8269 8270 onClose = this._get( inst, "onClose" ); 8271 if ( onClose ) { 8272 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 8273 } 8274 8275 this._lastInput = null; 8276 if ( this._inDialog ) { 8277 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 8278 if ( $.blockUI ) { 8279 $.unblockUI(); 8280 $( "body" ).append( this.dpDiv ); 8281 } 8282 } 8283 this._inDialog = false; 8284 } 8285 }, 8286 8287 /* Tidy up after a dialog display. */ 8288 _tidyDialog: function( inst ) { 8289 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 8290 }, 8291 8292 /* Close date picker if clicked elsewhere. */ 8293 _checkExternalClick: function( event ) { 8294 if ( !$.datepicker._curInst ) { 8295 return; 8296 } 8297 8298 var $target = $( event.target ), 8299 inst = $.datepicker._getInst( $target[ 0 ] ); 8300 8301 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 8302 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 8303 !$target.hasClass( $.datepicker.markerClassName ) && 8304 !$target.closest( "." + $.datepicker._triggerClass ).length && 8305 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 8306 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 8307 $.datepicker._hideDatepicker(); 8308 } 8309 }, 8310 8311 /* Adjust one of the date sub-fields. */ 8312 _adjustDate: function( id, offset, period ) { 8313 var target = $( id ), 8314 inst = this._getInst( target[ 0 ] ); 8315 8316 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 8317 return; 8318 } 8319 this._adjustInstDate( inst, offset, period ); 8320 this._updateDatepicker( inst ); 8321 }, 8322 8323 /* Action for current link. */ 8324 _gotoToday: function( id ) { 8325 var date, 8326 target = $( id ), 8327 inst = this._getInst( target[ 0 ] ); 8328 8329 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 8330 inst.selectedDay = inst.currentDay; 8331 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8332 inst.drawYear = inst.selectedYear = inst.currentYear; 8333 } else { 8334 date = new Date(); 8335 inst.selectedDay = date.getDate(); 8336 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8337 inst.drawYear = inst.selectedYear = date.getFullYear(); 8338 } 8339 this._notifyChange( inst ); 8340 this._adjustDate( target ); 8341 }, 8342 8343 /* Action for selecting a new month/year. */ 8344 _selectMonthYear: function( id, select, period ) { 8345 var target = $( id ), 8346 inst = this._getInst( target[ 0 ] ); 8347 8348 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 8349 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 8350 parseInt( select.options[ select.selectedIndex ].value, 10 ); 8351 8352 this._notifyChange( inst ); 8353 this._adjustDate( target ); 8354 }, 8355 8356 /* Action for selecting a day. */ 8357 _selectDay: function( id, month, year, td ) { 8358 var inst, 8359 target = $( id ); 8360 8361 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 8362 return; 8363 } 8364 8365 inst = this._getInst( target[ 0 ] ); 8366 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 8367 inst.selectedMonth = inst.currentMonth = month; 8368 inst.selectedYear = inst.currentYear = year; 8369 this._selectDate( id, this._formatDate( inst, 8370 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 8371 }, 8372 8373 /* Erase the input field and hide the date picker. */ 8374 _clearDate: function( id ) { 8375 var target = $( id ); 8376 this._selectDate( target, "" ); 8377 }, 8378 8379 /* Update the input field with the selected date. */ 8380 _selectDate: function( id, dateStr ) { 8381 var onSelect, 8382 target = $( id ), 8383 inst = this._getInst( target[ 0 ] ); 8384 8385 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 8386 if ( inst.input ) { 8387 inst.input.val( dateStr ); 8388 } 8389 this._updateAlternate( inst ); 8390 8391 onSelect = this._get( inst, "onSelect" ); 8392 if ( onSelect ) { 8393 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 8394 } else if ( inst.input ) { 8395 inst.input.trigger( "change" ); // fire the change event 8396 } 8397 8398 if ( inst.inline ) { 8399 this._updateDatepicker( inst ); 8400 } else { 8401 this._hideDatepicker(); 8402 this._lastInput = inst.input[ 0 ]; 8403 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 8404 inst.input.trigger( "focus" ); // restore focus 8405 } 8406 this._lastInput = null; 8407 } 8408 }, 8409 8410 /* Update any alternate field to synchronise with the main field. */ 8411 _updateAlternate: function( inst ) { 8412 var altFormat, date, dateStr, 8413 altField = this._get( inst, "altField" ); 8414 8415 if ( altField ) { // update alternate field too 8416 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 8417 date = this._getDate( inst ); 8418 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 8419 $( document ).find( altField ).val( dateStr ); 8420 } 8421 }, 8422 8423 /* Set as beforeShowDay function to prevent selection of weekends. 8424 * @param date Date - the date to customise 8425 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8426 */ 8427 noWeekends: function( date ) { 8428 var day = date.getDay(); 8429 return [ ( day > 0 && day < 6 ), "" ]; 8430 }, 8431 8432 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8433 * @param date Date - the date to get the week for 8434 * @return number - the number of the week within the year that contains this date 8435 */ 8436 iso8601Week: function( date ) { 8437 var time, 8438 checkDate = new Date( date.getTime() ); 8439 8440 // Find Thursday of this week starting on Monday 8441 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 8442 8443 time = checkDate.getTime(); 8444 checkDate.setMonth( 0 ); // Compare with Jan 1 8445 checkDate.setDate( 1 ); 8446 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 8447 }, 8448 8449 /* Parse a string value into a date object. 8450 * See formatDate below for the possible formats. 8451 * 8452 * @param format string - the expected format of the date 8453 * @param value string - the date in the above format 8454 * @param settings Object - attributes include: 8455 * shortYearCutoff number - the cutoff year for determining the century (optional) 8456 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8457 * dayNames string[7] - names of the days from Sunday (optional) 8458 * monthNamesShort string[12] - abbreviated names of the months (optional) 8459 * monthNames string[12] - names of the months (optional) 8460 * @return Date - the extracted date value or null if value is blank 8461 */ 8462 parseDate: function( format, value, settings ) { 8463 if ( format == null || value == null ) { 8464 throw "Invalid arguments"; 8465 } 8466 8467 value = ( typeof value === "object" ? value.toString() : value + "" ); 8468 if ( value === "" ) { 8469 return null; 8470 } 8471 8472 var iFormat, dim, extra, 8473 iValue = 0, 8474 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 8475 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 8476 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 8477 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 8478 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 8479 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 8480 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 8481 year = -1, 8482 month = -1, 8483 day = -1, 8484 doy = -1, 8485 literal = false, 8486 date, 8487 8488 // Check whether a format character is doubled 8489 lookAhead = function( match ) { 8490 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 8491 if ( matches ) { 8492 iFormat++; 8493 } 8494 return matches; 8495 }, 8496 8497 // Extract a number from the string value 8498 getNumber = function( match ) { 8499 var isDoubled = lookAhead( match ), 8500 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 8501 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 8502 minSize = ( match === "y" ? size : 1 ), 8503 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 8504 num = value.substring( iValue ).match( digits ); 8505 if ( !num ) { 8506 throw "Missing number at position " + iValue; 8507 } 8508 iValue += num[ 0 ].length; 8509 return parseInt( num[ 0 ], 10 ); 8510 }, 8511 8512 // Extract a name from the string value and convert to an index 8513 getName = function( match, shortNames, longNames ) { 8514 var index = -1, 8515 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 8516 return [ [ k, v ] ]; 8517 } ).sort( function( a, b ) { 8518 return -( a[ 1 ].length - b[ 1 ].length ); 8519 } ); 8520 8521 $.each( names, function( i, pair ) { 8522 var name = pair[ 1 ]; 8523 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 8524 index = pair[ 0 ]; 8525 iValue += name.length; 8526 return false; 8527 } 8528 } ); 8529 if ( index !== -1 ) { 8530 return index + 1; 8531 } else { 8532 throw "Unknown name at position " + iValue; 8533 } 8534 }, 8535 8536 // Confirm that a literal character matches the string value 8537 checkLiteral = function() { 8538 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 8539 throw "Unexpected literal at position " + iValue; 8540 } 8541 iValue++; 8542 }; 8543 8544 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 8545 if ( literal ) { 8546 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 8547 literal = false; 8548 } else { 8549 checkLiteral(); 8550 } 8551 } else { 8552 switch ( format.charAt( iFormat ) ) { 8553 case "d": 8554 day = getNumber( "d" ); 8555 break; 8556 case "D": 8557 getName( "D", dayNamesShort, dayNames ); 8558 break; 8559 case "o": 8560 doy = getNumber( "o" ); 8561 break; 8562 case "m": 8563 month = getNumber( "m" ); 8564 break; 8565 case "M": 8566 month = getName( "M", monthNamesShort, monthNames ); 8567 break; 8568 case "y": 8569 year = getNumber( "y" ); 8570 break; 8571 case "@": 8572 date = new Date( getNumber( "@" ) ); 8573 year = date.getFullYear(); 8574 month = date.getMonth() + 1; 8575 day = date.getDate(); 8576 break; 8577 case "!": 8578 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 8579 year = date.getFullYear(); 8580 month = date.getMonth() + 1; 8581 day = date.getDate(); 8582 break; 8583 case "'": 8584 if ( lookAhead( "'" ) ) { 8585 checkLiteral(); 8586 } else { 8587 literal = true; 8588 } 8589 break; 8590 default: 8591 checkLiteral(); 8592 } 8593 } 8594 } 8595 8596 if ( iValue < value.length ) { 8597 extra = value.substr( iValue ); 8598 if ( !/^\s+/.test( extra ) ) { 8599 throw "Extra/unparsed characters found in date: " + extra; 8600 } 8601 } 8602 8603 if ( year === -1 ) { 8604 year = new Date().getFullYear(); 8605 } else if ( year < 100 ) { 8606 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8607 ( year <= shortYearCutoff ? 0 : -100 ); 8608 } 8609 8610 if ( doy > -1 ) { 8611 month = 1; 8612 day = doy; 8613 do { 8614 dim = this._getDaysInMonth( year, month - 1 ); 8615 if ( day <= dim ) { 8616 break; 8617 } 8618 month++; 8619 day -= dim; 8620 } while ( true ); 8621 } 8622 8623 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 8624 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 8625 throw "Invalid date"; // E.g. 31/02/00 8626 } 8627 return date; 8628 }, 8629 8630 /* Standard date formats. */ 8631 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8632 COOKIE: "D, dd M yy", 8633 ISO_8601: "yy-mm-dd", 8634 RFC_822: "D, d M y", 8635 RFC_850: "DD, dd-M-y", 8636 RFC_1036: "D, d M y", 8637 RFC_1123: "D, d M yy", 8638 RFC_2822: "D, d M yy", 8639 RSS: "D, d M y", // RFC 822 8640 TICKS: "!", 8641 TIMESTAMP: "@", 8642 W3C: "yy-mm-dd", // ISO 8601 8643 8644 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 8645 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 8646 8647 /* Format a date object into a string value. 8648 * The format can be combinations of the following: 8649 * d - day of month (no leading zero) 8650 * dd - day of month (two digit) 8651 * o - day of year (no leading zeros) 8652 * oo - day of year (three digit) 8653 * D - day name short 8654 * DD - day name long 8655 * m - month of year (no leading zero) 8656 * mm - month of year (two digit) 8657 * M - month name short 8658 * MM - month name long 8659 * y - year (two digit) 8660 * yy - year (four digit) 8661 * @ - Unix timestamp (ms since 01/01/1970) 8662 * ! - Windows ticks (100ns since 01/01/0001) 8663 * "..." - literal text 8664 * '' - single quote 8665 * 8666 * @param format string - the desired format of the date 8667 * @param date Date - the date value to format 8668 * @param settings Object - attributes include: 8669 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8670 * dayNames string[7] - names of the days from Sunday (optional) 8671 * monthNamesShort string[12] - abbreviated names of the months (optional) 8672 * monthNames string[12] - names of the months (optional) 8673 * @return string - the date in the above format 8674 */ 8675 formatDate: function( format, date, settings ) { 8676 if ( !date ) { 8677 return ""; 8678 } 8679 8680 var iFormat, 8681 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 8682 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 8683 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 8684 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 8685 8686 // Check whether a format character is doubled 8687 lookAhead = function( match ) { 8688 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 8689 if ( matches ) { 8690 iFormat++; 8691 } 8692 return matches; 8693 }, 8694 8695 // Format a number, with leading zero if necessary 8696 formatNumber = function( match, value, len ) { 8697 var num = "" + value; 8698 if ( lookAhead( match ) ) { 8699 while ( num.length < len ) { 8700 num = "0" + num; 8701 } 8702 } 8703 return num; 8704 }, 8705 8706 // Format a name, short or long as requested 8707 formatName = function( match, value, shortNames, longNames ) { 8708 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 8709 }, 8710 output = "", 8711 literal = false; 8712 8713 if ( date ) { 8714 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 8715 if ( literal ) { 8716 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 8717 literal = false; 8718 } else { 8719 output += format.charAt( iFormat ); 8720 } 8721 } else { 8722 switch ( format.charAt( iFormat ) ) { 8723 case "d": 8724 output += formatNumber( "d", date.getDate(), 2 ); 8725 break; 8726 case "D": 8727 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 8728 break; 8729 case "o": 8730 output += formatNumber( "o", 8731 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 8732 break; 8733 case "m": 8734 output += formatNumber( "m", date.getMonth() + 1, 2 ); 8735 break; 8736 case "M": 8737 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 8738 break; 8739 case "y": 8740 output += ( lookAhead( "y" ) ? date.getFullYear() : 8741 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 8742 break; 8743 case "@": 8744 output += date.getTime(); 8745 break; 8746 case "!": 8747 output += date.getTime() * 10000 + this._ticksTo1970; 8748 break; 8749 case "'": 8750 if ( lookAhead( "'" ) ) { 8751 output += "'"; 8752 } else { 8753 literal = true; 8754 } 8755 break; 8756 default: 8757 output += format.charAt( iFormat ); 8758 } 8759 } 8760 } 8761 } 8762 return output; 8763 }, 8764 8765 /* Extract all possible characters from the date format. */ 8766 _possibleChars: function( format ) { 8767 var iFormat, 8768 chars = "", 8769 literal = false, 8770 8771 // Check whether a format character is doubled 8772 lookAhead = function( match ) { 8773 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 8774 if ( matches ) { 8775 iFormat++; 8776 } 8777 return matches; 8778 }; 8779 8780 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 8781 if ( literal ) { 8782 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 8783 literal = false; 8784 } else { 8785 chars += format.charAt( iFormat ); 8786 } 8787 } else { 8788 switch ( format.charAt( iFormat ) ) { 8789 case "d": case "m": case "y": case "@": 8790 chars += "0123456789"; 8791 break; 8792 case "D": case "M": 8793 return null; // Accept anything 8794 case "'": 8795 if ( lookAhead( "'" ) ) { 8796 chars += "'"; 8797 } else { 8798 literal = true; 8799 } 8800 break; 8801 default: 8802 chars += format.charAt( iFormat ); 8803 } 8804 } 8805 } 8806 return chars; 8807 }, 8808 8809 /* Get a setting value, defaulting if necessary. */ 8810 _get: function( inst, name ) { 8811 return inst.settings[ name ] !== undefined ? 8812 inst.settings[ name ] : this._defaults[ name ]; 8813 }, 8814 8815 /* Parse existing date and initialise date picker. */ 8816 _setDateFromField: function( inst, noDefault ) { 8817 if ( inst.input.val() === inst.lastVal ) { 8818 return; 8819 } 8820 8821 var dateFormat = this._get( inst, "dateFormat" ), 8822 dates = inst.lastVal = inst.input ? inst.input.val() : null, 8823 defaultDate = this._getDefaultDate( inst ), 8824 date = defaultDate, 8825 settings = this._getFormatConfig( inst ); 8826 8827 try { 8828 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 8829 } catch ( event ) { 8830 dates = ( noDefault ? "" : dates ); 8831 } 8832 inst.selectedDay = date.getDate(); 8833 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8834 inst.drawYear = inst.selectedYear = date.getFullYear(); 8835 inst.currentDay = ( dates ? date.getDate() : 0 ); 8836 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 8837 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 8838 this._adjustInstDate( inst ); 8839 }, 8840 8841 /* Retrieve the default date shown on opening. */ 8842 _getDefaultDate: function( inst ) { 8843 return this._restrictMinMax( inst, 8844 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 8845 }, 8846 8847 /* A date may be specified as an exact value or a relative one. */ 8848 _determineDate: function( inst, date, defaultDate ) { 8849 var offsetNumeric = function( offset ) { 8850 var date = new Date(); 8851 date.setDate( date.getDate() + offset ); 8852 return date; 8853 }, 8854 offsetString = function( offset ) { 8855 try { 8856 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 8857 offset, $.datepicker._getFormatConfig( inst ) ); 8858 } catch ( e ) { 8859 8860 // Ignore 8861 } 8862 8863 var date = ( offset.toLowerCase().match( /^c/ ) ? 8864 $.datepicker._getDate( inst ) : null ) || new Date(), 8865 year = date.getFullYear(), 8866 month = date.getMonth(), 8867 day = date.getDate(), 8868 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 8869 matches = pattern.exec( offset ); 8870 8871 while ( matches ) { 8872 switch ( matches[ 2 ] || "d" ) { 8873 case "d" : case "D" : 8874 day += parseInt( matches[ 1 ], 10 ); break; 8875 case "w" : case "W" : 8876 day += parseInt( matches[ 1 ], 10 ) * 7; break; 8877 case "m" : case "M" : 8878 month += parseInt( matches[ 1 ], 10 ); 8879 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 8880 break; 8881 case "y": case "Y" : 8882 year += parseInt( matches[ 1 ], 10 ); 8883 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 8884 break; 8885 } 8886 matches = pattern.exec( offset ); 8887 } 8888 return new Date( year, month, day ); 8889 }, 8890 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 8891 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 8892 8893 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 8894 if ( newDate ) { 8895 newDate.setHours( 0 ); 8896 newDate.setMinutes( 0 ); 8897 newDate.setSeconds( 0 ); 8898 newDate.setMilliseconds( 0 ); 8899 } 8900 return this._daylightSavingAdjust( newDate ); 8901 }, 8902 8903 /* Handle switch to/from daylight saving. 8904 * Hours may be non-zero on daylight saving cut-over: 8905 * > 12 when midnight changeover, but then cannot generate 8906 * midnight datetime, so jump to 1AM, otherwise reset. 8907 * @param date (Date) the date to check 8908 * @return (Date) the corrected date 8909 */ 8910 _daylightSavingAdjust: function( date ) { 8911 if ( !date ) { 8912 return null; 8913 } 8914 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 8915 return date; 8916 }, 8917 8918 /* Set the date(s) directly. */ 8919 _setDate: function( inst, date, noChange ) { 8920 var clear = !date, 8921 origMonth = inst.selectedMonth, 8922 origYear = inst.selectedYear, 8923 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 8924 8925 inst.selectedDay = inst.currentDay = newDate.getDate(); 8926 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8927 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8928 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 8929 this._notifyChange( inst ); 8930 } 8931 this._adjustInstDate( inst ); 8932 if ( inst.input ) { 8933 inst.input.val( clear ? "" : this._formatDate( inst ) ); 8934 } 8935 }, 8936 8937 /* Retrieve the date(s) directly. */ 8938 _getDate: function( inst ) { 8939 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 8940 this._daylightSavingAdjust( new Date( 8941 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 8942 return startDate; 8943 }, 8944 8945 /* Attach the onxxx handlers. These are declared statically so 8946 * they work with static code transformers like Caja. 8947 */ 8948 _attachHandlers: function( inst ) { 8949 var stepMonths = this._get( inst, "stepMonths" ), 8950 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 8951 inst.dpDiv.find( "[data-handler]" ).map( function() { 8952 var handler = { 8953 prev: function() { 8954 $.datepicker._adjustDate( id, -stepMonths, "M" ); 8955 }, 8956 next: function() { 8957 $.datepicker._adjustDate( id, +stepMonths, "M" ); 8958 }, 8959 hide: function() { 8960 $.datepicker._hideDatepicker(); 8961 }, 8962 today: function() { 8963 $.datepicker._gotoToday( id ); 8964 }, 8965 selectDay: function() { 8966 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 8967 return false; 8968 }, 8969 selectMonth: function() { 8970 $.datepicker._selectMonthYear( id, this, "M" ); 8971 return false; 8972 }, 8973 selectYear: function() { 8974 $.datepicker._selectMonthYear( id, this, "Y" ); 8975 return false; 8976 } 8977 }; 8978 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 8979 } ); 8980 }, 8981 8982 /* Generate the HTML for the current state of the date picker. */ 8983 _generateHTML: function( inst ) { 8984 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 8985 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 8986 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 8987 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 8988 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 8989 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 8990 tempDate = new Date(), 8991 today = this._daylightSavingAdjust( 8992 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 8993 isRTL = this._get( inst, "isRTL" ), 8994 showButtonPanel = this._get( inst, "showButtonPanel" ), 8995 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 8996 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 8997 numMonths = this._getNumberOfMonths( inst ), 8998 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 8999 stepMonths = this._get( inst, "stepMonths" ), 9000 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 9001 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 9002 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 9003 minDate = this._getMinMaxDate( inst, "min" ), 9004 maxDate = this._getMinMaxDate( inst, "max" ), 9005 drawMonth = inst.drawMonth - showCurrentAtPos, 9006 drawYear = inst.drawYear; 9007 9008 if ( drawMonth < 0 ) { 9009 drawMonth += 12; 9010 drawYear--; 9011 } 9012 if ( maxDate ) { 9013 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 9014 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 9015 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 9016 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 9017 drawMonth--; 9018 if ( drawMonth < 0 ) { 9019 drawMonth = 11; 9020 drawYear--; 9021 } 9022 } 9023 } 9024 inst.drawMonth = drawMonth; 9025 inst.drawYear = drawYear; 9026 9027 prevText = this._get( inst, "prevText" ); 9028 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 9029 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 9030 this._getFormatConfig( inst ) ) ); 9031 9032 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 9033 prev = $( "<a>" ) 9034 .attr( { 9035 "class": "ui-datepicker-prev ui-corner-all", 9036 "data-handler": "prev", 9037 "data-event": "click", 9038 title: prevText 9039 } ) 9040 .append( 9041 $( "<span>" ) 9042 .addClass( "ui-icon ui-icon-circle-triangle-" + 9043 ( isRTL ? "e" : "w" ) ) 9044 .text( prevText ) 9045 )[ 0 ].outerHTML; 9046 } else if ( hideIfNoPrevNext ) { 9047 prev = ""; 9048 } else { 9049 prev = $( "<a>" ) 9050 .attr( { 9051 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 9052 title: prevText 9053 } ) 9054 .append( 9055 $( "<span>" ) 9056 .addClass( "ui-icon ui-icon-circle-triangle-" + 9057 ( isRTL ? "e" : "w" ) ) 9058 .text( prevText ) 9059 )[ 0 ].outerHTML; 9060 } 9061 9062 nextText = this._get( inst, "nextText" ); 9063 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 9064 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 9065 this._getFormatConfig( inst ) ) ); 9066 9067 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 9068 next = $( "<a>" ) 9069 .attr( { 9070 "class": "ui-datepicker-next ui-corner-all", 9071 "data-handler": "next", 9072 "data-event": "click", 9073 title: nextText 9074 } ) 9075 .append( 9076 $( "<span>" ) 9077 .addClass( "ui-icon ui-icon-circle-triangle-" + 9078 ( isRTL ? "w" : "e" ) ) 9079 .text( nextText ) 9080 )[ 0 ].outerHTML; 9081 } else if ( hideIfNoPrevNext ) { 9082 next = ""; 9083 } else { 9084 next = $( "<a>" ) 9085 .attr( { 9086 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 9087 title: nextText 9088 } ) 9089 .append( 9090 $( "<span>" ) 9091 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 9092 ( isRTL ? "w" : "e" ) ) 9093 .text( nextText ) 9094 )[ 0 ].outerHTML; 9095 } 9096 9097 currentText = this._get( inst, "currentText" ); 9098 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 9099 currentText = ( !navigationAsDateFormat ? currentText : 9100 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 9101 9102 controls = ""; 9103 if ( !inst.inline ) { 9104 controls = $( "<button>" ) 9105 .attr( { 9106 type: "button", 9107 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 9108 "data-handler": "hide", 9109 "data-event": "click" 9110 } ) 9111 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 9112 } 9113 9114 buttonPanel = ""; 9115 if ( showButtonPanel ) { 9116 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 9117 .append( isRTL ? controls : "" ) 9118 .append( this._isInRange( inst, gotoDate ) ? 9119 $( "<button>" ) 9120 .attr( { 9121 type: "button", 9122 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 9123 "data-handler": "today", 9124 "data-event": "click" 9125 } ) 9126 .text( currentText ) : 9127 "" ) 9128 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 9129 } 9130 9131 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 9132 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 9133 9134 showWeek = this._get( inst, "showWeek" ); 9135 dayNames = this._get( inst, "dayNames" ); 9136 dayNamesMin = this._get( inst, "dayNamesMin" ); 9137 monthNames = this._get( inst, "monthNames" ); 9138 monthNamesShort = this._get( inst, "monthNamesShort" ); 9139 beforeShowDay = this._get( inst, "beforeShowDay" ); 9140 showOtherMonths = this._get( inst, "showOtherMonths" ); 9141 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 9142 defaultDate = this._getDefaultDate( inst ); 9143 html = ""; 9144 9145 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 9146 group = ""; 9147 this.maxRows = 4; 9148 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 9149 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 9150 cornerClass = " ui-corner-all"; 9151 calender = ""; 9152 if ( isMultiMonth ) { 9153 calender += "<div class='ui-datepicker-group"; 9154 if ( numMonths[ 1 ] > 1 ) { 9155 switch ( col ) { 9156 case 0: calender += " ui-datepicker-group-first"; 9157 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 9158 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 9159 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 9160 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9161 } 9162 } 9163 calender += "'>"; 9164 } 9165 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9166 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 9167 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 9168 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 9169 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 9170 "</div><table class='ui-datepicker-calendar'><thead>" + 9171 "<tr>"; 9172 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 9173 for ( dow = 0; dow < 7; dow++ ) { // days of the week 9174 day = ( dow + firstDay ) % 7; 9175 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 9176 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 9177 } 9178 calender += thead + "</tr></thead><tbody>"; 9179 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 9180 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 9181 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 9182 } 9183 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 9184 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 9185 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 9186 this.maxRows = numRows; 9187 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 9188 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 9189 calender += "<tr>"; 9190 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9191 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 9192 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 9193 daySettings = ( beforeShowDay ? 9194 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 9195 otherMonth = ( printDate.getMonth() !== drawMonth ); 9196 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 9197 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 9198 tbody += "<td class='" + 9199 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 9200 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 9201 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 9202 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 9203 9204 // or defaultDate is current printedDate and defaultDate is selectedDate 9205 " " + this._dayOverClass : "" ) + // highlight selected day 9206 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 9207 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 9208 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 9209 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 9210 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 9211 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 9212 ( otherMonth && !showOtherMonths ? " " : // display for other months 9213 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9214 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 9215 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 9216 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 9217 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 9218 "' data-date='" + printDate.getDate() + // store date as data 9219 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 9220 printDate.setDate( printDate.getDate() + 1 ); 9221 printDate = this._daylightSavingAdjust( printDate ); 9222 } 9223 calender += tbody + "</tr>"; 9224 } 9225 drawMonth++; 9226 if ( drawMonth > 11 ) { 9227 drawMonth = 0; 9228 drawYear++; 9229 } 9230 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 9231 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 9232 group += calender; 9233 } 9234 html += group; 9235 } 9236 html += buttonPanel; 9237 inst._keyEvent = false; 9238 return html; 9239 }, 9240 9241 /* Generate the month and year header. */ 9242 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 9243 secondary, monthNames, monthNamesShort ) { 9244 9245 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9246 changeMonth = this._get( inst, "changeMonth" ), 9247 changeYear = this._get( inst, "changeYear" ), 9248 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 9249 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 9250 selectYearLabel = this._get( inst, "selectYearLabel" ), 9251 html = "<div class='ui-datepicker-title'>", 9252 monthHtml = ""; 9253 9254 // Month selection 9255 if ( secondary || !changeMonth ) { 9256 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 9257 } else { 9258 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 9259 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 9260 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 9261 for ( month = 0; month < 12; month++ ) { 9262 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 9263 monthHtml += "<option value='" + month + "'" + 9264 ( month === drawMonth ? " selected='selected'" : "" ) + 9265 ">" + monthNamesShort[ month ] + "</option>"; 9266 } 9267 } 9268 monthHtml += "</select>"; 9269 } 9270 9271 if ( !showMonthAfterYear ) { 9272 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 9273 } 9274 9275 // Year selection 9276 if ( !inst.yearshtml ) { 9277 inst.yearshtml = ""; 9278 if ( secondary || !changeYear ) { 9279 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9280 } else { 9281 9282 // determine range of years to display 9283 years = this._get( inst, "yearRange" ).split( ":" ); 9284 thisYear = new Date().getFullYear(); 9285 determineYear = function( value ) { 9286 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 9287 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 9288 parseInt( value, 10 ) ) ); 9289 return ( isNaN( year ) ? thisYear : year ); 9290 }; 9291 year = determineYear( years[ 0 ] ); 9292 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 9293 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 9294 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 9295 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 9296 for ( ; year <= endYear; year++ ) { 9297 inst.yearshtml += "<option value='" + year + "'" + 9298 ( year === drawYear ? " selected='selected'" : "" ) + 9299 ">" + year + "</option>"; 9300 } 9301 inst.yearshtml += "</select>"; 9302 9303 html += inst.yearshtml; 9304 inst.yearshtml = null; 9305 } 9306 } 9307 9308 html += this._get( inst, "yearSuffix" ); 9309 if ( showMonthAfterYear ) { 9310 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 9311 } 9312 html += "</div>"; // Close datepicker_header 9313 return html; 9314 }, 9315 9316 /* Adjust one of the date sub-fields. */ 9317 _adjustInstDate: function( inst, offset, period ) { 9318 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 9319 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 9320 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 9321 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 9322 9323 inst.selectedDay = date.getDate(); 9324 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9325 inst.drawYear = inst.selectedYear = date.getFullYear(); 9326 if ( period === "M" || period === "Y" ) { 9327 this._notifyChange( inst ); 9328 } 9329 }, 9330 9331 /* Ensure a date is within any min/max bounds. */ 9332 _restrictMinMax: function( inst, date ) { 9333 var minDate = this._getMinMaxDate( inst, "min" ), 9334 maxDate = this._getMinMaxDate( inst, "max" ), 9335 newDate = ( minDate && date < minDate ? minDate : date ); 9336 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 9337 }, 9338 9339 /* Notify change of month/year. */ 9340 _notifyChange: function( inst ) { 9341 var onChange = this._get( inst, "onChangeMonthYear" ); 9342 if ( onChange ) { 9343 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 9344 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 9345 } 9346 }, 9347 9348 /* Determine the number of months to show. */ 9349 _getNumberOfMonths: function( inst ) { 9350 var numMonths = this._get( inst, "numberOfMonths" ); 9351 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 9352 }, 9353 9354 /* Determine the current maximum date - ensure no time components are set. */ 9355 _getMinMaxDate: function( inst, minMax ) { 9356 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 9357 }, 9358 9359 /* Find the number of days in a given month. */ 9360 _getDaysInMonth: function( year, month ) { 9361 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 9362 }, 9363 9364 /* Find the day of the week of the first of a month. */ 9365 _getFirstDayOfMonth: function( year, month ) { 9366 return new Date( year, month, 1 ).getDay(); 9367 }, 9368 9369 /* Determines if we should allow a "next/prev" month display change. */ 9370 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 9371 var numMonths = this._getNumberOfMonths( inst ), 9372 date = this._daylightSavingAdjust( new Date( curYear, 9373 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 9374 9375 if ( offset < 0 ) { 9376 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 9377 } 9378 return this._isInRange( inst, date ); 9379 }, 9380 9381 /* Is the given date in the accepted range? */ 9382 _isInRange: function( inst, date ) { 9383 var yearSplit, currentYear, 9384 minDate = this._getMinMaxDate( inst, "min" ), 9385 maxDate = this._getMinMaxDate( inst, "max" ), 9386 minYear = null, 9387 maxYear = null, 9388 years = this._get( inst, "yearRange" ); 9389 if ( years ) { 9390 yearSplit = years.split( ":" ); 9391 currentYear = new Date().getFullYear(); 9392 minYear = parseInt( yearSplit[ 0 ], 10 ); 9393 maxYear = parseInt( yearSplit[ 1 ], 10 ); 9394 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 9395 minYear += currentYear; 9396 } 9397 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 9398 maxYear += currentYear; 9399 } 9400 } 9401 9402 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 9403 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 9404 ( !minYear || date.getFullYear() >= minYear ) && 9405 ( !maxYear || date.getFullYear() <= maxYear ) ); 9406 }, 9407 9408 /* Provide the configuration settings for formatting/parsing. */ 9409 _getFormatConfig: function( inst ) { 9410 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 9411 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 9412 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 9413 return { shortYearCutoff: shortYearCutoff, 9414 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 9415 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 9416 }, 9417 9418 /* Format the given date for display. */ 9419 _formatDate: function( inst, day, month, year ) { 9420 if ( !day ) { 9421 inst.currentDay = inst.selectedDay; 9422 inst.currentMonth = inst.selectedMonth; 9423 inst.currentYear = inst.selectedYear; 9424 } 9425 var date = ( day ? ( typeof day === "object" ? day : 9426 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 9427 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 9428 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 9429 } 9430} ); 9431 9432/* 9433 * Bind hover events for datepicker elements. 9434 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9435 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9436 */ 9437function datepicker_bindHover( dpDiv ) { 9438 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9439 return dpDiv.on( "mouseout", selector, function() { 9440 $( this ).removeClass( "ui-state-hover" ); 9441 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 9442 $( this ).removeClass( "ui-datepicker-prev-hover" ); 9443 } 9444 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 9445 $( this ).removeClass( "ui-datepicker-next-hover" ); 9446 } 9447 } ) 9448 .on( "mouseover", selector, datepicker_handleMouseover ); 9449} 9450 9451function datepicker_handleMouseover() { 9452 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 9453 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 9454 $( this ).addClass( "ui-state-hover" ); 9455 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 9456 $( this ).addClass( "ui-datepicker-prev-hover" ); 9457 } 9458 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 9459 $( this ).addClass( "ui-datepicker-next-hover" ); 9460 } 9461 } 9462} 9463 9464/* jQuery extend now ignores nulls! */ 9465function datepicker_extendRemove( target, props ) { 9466 $.extend( target, props ); 9467 for ( var name in props ) { 9468 if ( props[ name ] == null ) { 9469 target[ name ] = props[ name ]; 9470 } 9471 } 9472 return target; 9473} 9474 9475/* Invoke the datepicker functionality. 9476 @param options string - a command, optionally followed by additional parameters or 9477 Object - settings for attaching new datepicker functionality 9478 @return jQuery object */ 9479$.fn.datepicker = function( options ) { 9480 9481 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9482 if ( !this.length ) { 9483 return this; 9484 } 9485 9486 /* Initialise the date picker. */ 9487 if ( !$.datepicker.initialized ) { 9488 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 9489 $.datepicker.initialized = true; 9490 } 9491 9492 /* Append datepicker main container to body if not exist. */ 9493 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 9494 $( "body" ).append( $.datepicker.dpDiv ); 9495 } 9496 9497 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 9498 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 9499 return $.datepicker[ "_" + options + "Datepicker" ]. 9500 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 9501 } 9502 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 9503 return $.datepicker[ "_" + options + "Datepicker" ]. 9504 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 9505 } 9506 return this.each( function() { 9507 if ( typeof options === "string" ) { 9508 $.datepicker[ "_" + options + "Datepicker" ] 9509 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 9510 } else { 9511 $.datepicker._attachDatepicker( this, options ); 9512 } 9513 } ); 9514}; 9515 9516$.datepicker = new Datepicker(); // singleton instance 9517$.datepicker.initialized = false; 9518$.datepicker.uuid = new Date().getTime(); 9519$.datepicker.version = "1.13.
vendor: 7,558 bytes, lines 9519-9808
95192"; 9520 9521var widgetsDatepicker = $.datepicker; 9522 9523 9524 9525// This file is deprecated 9526var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 9527 9528/*! 9529 * jQuery UI Mouse 1.13.2 9530 * http://jqueryui.com 9531 * 9532 * Copyright jQuery Foundation and other contributors 9533 * Released under the MIT license. 9534 * http://jquery.org/license 9535 */ 9536 9537//>>label: Mouse 9538//>>group: Widgets 9539//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 9540//>>docs: http://api.jqueryui.com/mouse/ 9541 9542 9543var mouseHandled = false; 9544$( document ).on( "mouseup", function() { 9545 mouseHandled = false; 9546} ); 9547 9548var widgetsMouse = $.widget( "ui.mouse", { 9549 version: "1.13.2", 9550 options: { 9551 cancel: "input, textarea, button, select, option", 9552 distance: 1, 9553 delay: 0 9554 }, 9555 _mouseInit: function() { 9556 var that = this; 9557 9558 this.element 9559 .on( "mousedown." + this.widgetName, function( event ) { 9560 return that._mouseDown( event ); 9561 } ) 9562 .on( "click." + this.widgetName, function( event ) { 9563 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 9564 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 9565 event.stopImmediatePropagation(); 9566 return false; 9567 } 9568 } ); 9569 9570 this.started = false; 9571 }, 9572 9573 // TODO: make sure destroying one instance of mouse doesn't mess with 9574 // other instances of mouse 9575 _mouseDestroy: function() { 9576 this.element.off( "." + this.widgetName ); 9577 if ( this._mouseMoveDelegate ) { 9578 this.document 9579 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 9580 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 9581 } 9582 }, 9583 9584 _mouseDown: function( event ) { 9585 9586 // don't let more than one widget handle mouseStart 9587 if ( mouseHandled ) { 9588 return; 9589 } 9590 9591 this._mouseMoved = false; 9592 9593 // We may have missed mouseup (out of window) 9594 if ( this._mouseStarted ) { 9595 this._mouseUp( event ); 9596 } 9597 9598 this._mouseDownEvent = event; 9599 9600 var that = this, 9601 btnIsLeft = ( event.which === 1 ), 9602 9603 // event.target.nodeName works around a bug in IE 8 with 9604 // disabled inputs (#7620) 9605 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 9606 $( event.target ).closest( this.options.cancel ).length : false ); 9607 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 9608 return true; 9609 } 9610 9611 this.mouseDelayMet = !this.options.delay; 9612 if ( !this.mouseDelayMet ) { 9613 this._mouseDelayTimer = setTimeout( function() { 9614 that.mouseDelayMet = true; 9615 }, this.options.delay ); 9616 } 9617 9618 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 9619 this._mouseStarted = ( this._mouseStart( event ) !== false ); 9620 if ( !this._mouseStarted ) { 9621 event.preventDefault(); 9622 return true; 9623 } 9624 } 9625 9626 // Click event may never have fired (Gecko & Opera) 9627 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 9628 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 9629 } 9630 9631 // These delegates are required to keep context 9632 this._mouseMoveDelegate = function( event ) { 9633 return that._mouseMove( event ); 9634 }; 9635 this._mouseUpDelegate = function( event ) { 9636 return that._mouseUp( event ); 9637 }; 9638 9639 this.document 9640 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 9641 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 9642 9643 event.preventDefault(); 9644 9645 mouseHandled = true; 9646 return true; 9647 }, 9648 9649 _mouseMove: function( event ) { 9650 9651 // Only check for mouseups outside the document if you've moved inside the document 9652 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 9653 // fire a mousemove event if content is placed under the cursor. See #7778 9654 // Support: IE <9 9655 if ( this._mouseMoved ) { 9656 9657 // IE mouseup check - mouseup happened when mouse was out of window 9658 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 9659 !event.button ) { 9660 return this._mouseUp( event ); 9661 9662 // Iframe mouseup check - mouseup occurred in another document 9663 } else if ( !event.which ) { 9664 9665 // Support: Safari <=8 - 9 9666 // Safari sets which to 0 if you press any of the following keys 9667 // during a drag (#14461) 9668 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 9669 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 9670 this.ignoreMissingWhich = true; 9671 } else if ( !this.ignoreMissingWhich ) { 9672 return this._mouseUp( event ); 9673 } 9674 } 9675 } 9676 9677 if ( event.which || event.button ) { 9678 this._mouseMoved = true; 9679 } 9680 9681 if ( this._mouseStarted ) { 9682 this._mouseDrag( event ); 9683 return event.preventDefault(); 9684 } 9685 9686 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 9687 this._mouseStarted = 9688 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 9689 if ( this._mouseStarted ) { 9690 this._mouseDrag( event ); 9691 } else { 9692 this._mouseUp( event ); 9693 } 9694 } 9695 9696 return !this._mouseStarted; 9697 }, 9698 9699 _mouseUp: function( event ) { 9700 this.document 9701 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 9702 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 9703 9704 if ( this._mouseStarted ) { 9705 this._mouseStarted = false; 9706 9707 if ( event.target === this._mouseDownEvent.target ) { 9708 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 9709 } 9710 9711 this._mouseStop( event ); 9712 } 9713 9714 if ( this._mouseDelayTimer ) { 9715 clearTimeout( this._mouseDelayTimer ); 9716 delete this._mouseDelayTimer; 9717 } 9718 9719 this.ignoreMissingWhich = false; 9720 mouseHandled = false; 9721 event.preventDefault(); 9722 }, 9723 9724 _mouseDistanceMet: function( event ) { 9725 return ( Math.max( 9726 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 9727 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 9728 ) >= this.options.distance 9729 ); 9730 }, 9731 9732 _mouseDelayMet: function( /* event */ ) { 9733 return this.mouseDelayMet; 9734 }, 9735 9736 // These are placeholder methods, to be overriden by extending plugin 9737 _mouseStart: function( /* event */ ) {}, 9738 _mouseDrag: function( /* event */ ) {}, 9739 _mouseStop: function( /* event */ ) {}, 9740 _mouseCapture: function( /* event */ ) { 9741 return true; 9742 } 9743} ); 9744 9745 9746 9747// $.ui.plugin is deprecated. Use $.widget() extensions instead. 9748var plugin = $.ui.plugin = { 9749 add: function( module, option, set ) { 9750 var i, 9751 proto = $.ui[ module ].prototype; 9752 for ( i in set ) { 9753 proto.plugins[ i ] = proto.plugins[ i ] || []; 9754 proto.plugins[ i ].push( [ option, set[ i ] ] ); 9755 } 9756 }, 9757 call: function( instance, name, args, allowDisconnected ) { 9758 var i, 9759 set = instance.plugins[ name ]; 9760 9761 if ( !set ) { 9762 return; 9763 } 9764 9765 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 9766 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 9767 return; 9768 } 9769 9770 for ( i = 0; i < set.length; i++ ) { 9771 if ( instance.options[ set[ i ][ 0 ] ] ) { 9772 set[ i ][ 1 ].apply( instance.element, args ); 9773 } 9774 } 9775 } 9776}; 9777 9778 9779 9780var safeBlur = $.ui.safeBlur = function( element ) { 9781 9782 // Support: IE9 - 10 only 9783 // If the <body> is blurred, IE will switch windows, see #9420 9784 if ( element && element.nodeName.toLowerCase() !== "body" ) { 9785 $( element ).trigger( "blur" ); 9786 } 9787}; 9788 9789 9790/*! 9791 * jQuery UI Draggable 1.13.2 9792 * http://jqueryui.com 9793 * 9794 * Copyright jQuery Foundation and other contributors 9795 * Released under the MIT license. 9796 * http://jquery.org/license 9797 */ 9798 9799//>>label: Draggable 9800//>>group: Interactions 9801//>>description: Enables dragging functionality for any element. 9802//>>docs: http://api.jqueryui.com/draggable/ 9803//>>demos: http://jqueryui.com/draggable/ 9804//>>css.structure: ../../themes/base/draggable.css 9805 9806 9807$.widget( "ui.draggable", $.ui.mouse, { 9808 version: "1.13.2
vendor: 8,684 bytes, lines 9808-10154
9808", 9809 widgetEventPrefix: "drag", 9810 options: { 9811 addClasses: true, 9812 appendTo: "parent", 9813 axis: false, 9814 connectToSortable: false, 9815 containment: false, 9816 cursor: "auto", 9817 cursorAt: false, 9818 grid: false, 9819 handle: false, 9820 helper: "original", 9821 iframeFix: false, 9822 opacity: false, 9823 refreshPositions: false, 9824 revert: false, 9825 revertDuration: 500, 9826 scope: "default", 9827 scroll: true, 9828 scrollSensitivity: 20, 9829 scrollSpeed: 20, 9830 snap: false, 9831 snapMode: "both", 9832 snapTolerance: 20, 9833 stack: false, 9834 zIndex: false, 9835 9836 // Callbacks 9837 drag: null, 9838 start: null, 9839 stop: null 9840 }, 9841 _create: function() { 9842 9843 if ( this.options.helper === "original" ) { 9844 this._setPositionRelative(); 9845 } 9846 if ( this.options.addClasses ) { 9847 this._addClass( "ui-draggable" ); 9848 } 9849 this._setHandleClassName(); 9850 9851 this._mouseInit(); 9852 }, 9853 9854 _setOption: function( key, value ) { 9855 this._super( key, value ); 9856 if ( key === "handle" ) { 9857 this._removeHandleClassName(); 9858 this._setHandleClassName(); 9859 } 9860 }, 9861 9862 _destroy: function() { 9863 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 9864 this.destroyOnClear = true; 9865 return; 9866 } 9867 this._removeHandleClassName(); 9868 this._mouseDestroy(); 9869 }, 9870 9871 _mouseCapture: function( event ) { 9872 var o = this.options; 9873 9874 // Among others, prevent a drag on a resizable-handle 9875 if ( this.helper || o.disabled || 9876 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 9877 return false; 9878 } 9879 9880 //Quit if we're not on a valid handle 9881 this.handle = this._getHandle( event ); 9882 if ( !this.handle ) { 9883 return false; 9884 } 9885 9886 this._blurActiveElement( event ); 9887 9888 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 9889 9890 return true; 9891 9892 }, 9893 9894 _blockFrames: function( selector ) { 9895 this.iframeBlocks = this.document.find( selector ).map( function() { 9896 var iframe = $( this ); 9897 9898 return $( "<div>" ) 9899 .css( "position", "absolute" ) 9900 .appendTo( iframe.parent() ) 9901 .outerWidth( iframe.outerWidth() ) 9902 .outerHeight( iframe.outerHeight() ) 9903 .offset( iframe.offset() )[ 0 ]; 9904 } ); 9905 }, 9906 9907 _unblockFrames: function() { 9908 if ( this.iframeBlocks ) { 9909 this.iframeBlocks.remove(); 9910 delete this.iframeBlocks; 9911 } 9912 }, 9913 9914 _blurActiveElement: function( event ) { 9915 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 9916 target = $( event.target ); 9917 9918 // Don't blur if the event occurred on an element that is within 9919 // the currently focused element 9920 // See #10527, #12472 9921 if ( target.closest( activeElement ).length ) { 9922 return; 9923 } 9924 9925 // Blur any element that currently has focus, see #4261 9926 $.ui.safeBlur( activeElement ); 9927 }, 9928 9929 _mouseStart: function( event ) { 9930 9931 var o = this.options; 9932 9933 //Create and append the visible helper 9934 this.helper = this._createHelper( event ); 9935 9936 this._addClass( this.helper, "ui-draggable-dragging" ); 9937 9938 //Cache the helper size 9939 this._cacheHelperProportions(); 9940 9941 //If ddmanager is used for droppables, set the global draggable 9942 if ( $.ui.ddmanager ) { 9943 $.ui.ddmanager.current = this; 9944 } 9945 9946 /* 9947 * - Position generation - 9948 * This block generates everything position related - it's the core of draggables. 9949 */ 9950 9951 //Cache the margins of the original element 9952 this._cacheMargins(); 9953 9954 //Store the helper's css position 9955 this.cssPosition = this.helper.css( "position" ); 9956 this.scrollParent = this.helper.scrollParent( true ); 9957 this.offsetParent = this.helper.offsetParent(); 9958 this.hasFixedAncestor = this.helper.parents().filter( function() { 9959 return $( this ).css( "position" ) === "fixed"; 9960 } ).length > 0; 9961 9962 //The element's absolute position on the page minus margins 9963 this.positionAbs = this.element.offset(); 9964 this._refreshOffsets( event ); 9965 9966 //Generate the original position 9967 this.originalPosition = this.position = this._generatePosition( event, false ); 9968 this.originalPageX = event.pageX; 9969 this.originalPageY = event.pageY; 9970 9971 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 9972 if ( o.cursorAt ) { 9973 this._adjustOffsetFromHelper( o.cursorAt ); 9974 } 9975 9976 //Set a containment if given in the options 9977 this._setContainment(); 9978 9979 //Trigger event + callbacks 9980 if ( this._trigger( "start", event ) === false ) { 9981 this._clear(); 9982 return false; 9983 } 9984 9985 //Recache the helper size 9986 this._cacheHelperProportions(); 9987 9988 //Prepare the droppable offsets 9989 if ( $.ui.ddmanager && !o.dropBehaviour ) { 9990 $.ui.ddmanager.prepareOffsets( this, event ); 9991 } 9992 9993 // Execute the drag once - this causes the helper not to be visible before getting its 9994 // correct position 9995 this._mouseDrag( event, true ); 9996 9997 // If the ddmanager is used for droppables, inform the manager that dragging has started 9998 // (see #5003) 9999 if ( $.ui.ddmanager ) { 10000 $.ui.ddmanager.dragStart( this, event ); 10001 } 10002 10003 return true; 10004 }, 10005 10006 _refreshOffsets: function( event ) { 10007 this.offset = { 10008 top: this.positionAbs.top - this.margins.top, 10009 left: this.positionAbs.left - this.margins.left, 10010 scroll: false, 10011 parent: this._getParentOffset(), 10012 relative: this._getRelativeOffset() 10013 }; 10014 10015 this.offset.click = { 10016 left: event.pageX - this.offset.left, 10017 top: event.pageY - this.offset.top 10018 }; 10019 }, 10020 10021 _mouseDrag: function( event, noPropagation ) { 10022 10023 // reset any necessary cached properties (see #5009) 10024 if ( this.hasFixedAncestor ) { 10025 this.offset.parent = this._getParentOffset(); 10026 } 10027 10028 //Compute the helpers position 10029 this.position = this._generatePosition( event, true ); 10030 this.positionAbs = this._convertPositionTo( "absolute" ); 10031 10032 //Call plugins and callbacks and use the resulting position if something is returned 10033 if ( !noPropagation ) { 10034 var ui = this._uiHash(); 10035 if ( this._trigger( "drag", event, ui ) === false ) { 10036 this._mouseUp( new $.Event( "mouseup", event ) ); 10037 return false; 10038 } 10039 this.position = ui.position; 10040 } 10041 10042 this.helper[ 0 ].style.left = this.position.left + "px"; 10043 this.helper[ 0 ].style.top = this.position.top + "px"; 10044 10045 if ( $.ui.ddmanager ) { 10046 $.ui.ddmanager.drag( this, event ); 10047 } 10048 10049 return false; 10050 }, 10051 10052 _mouseStop: function( event ) { 10053 10054 //If we are using droppables, inform the manager about the drop 10055 var that = this, 10056 dropped = false; 10057 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 10058 dropped = $.ui.ddmanager.drop( this, event ); 10059 } 10060 10061 //if a drop comes from outside (a sortable) 10062 if ( this.dropped ) { 10063 dropped = this.dropped; 10064 this.dropped = false; 10065 } 10066 10067 if ( ( this.options.revert === "invalid" && !dropped ) || 10068 ( this.options.revert === "valid" && dropped ) || 10069 this.options.revert === true || ( typeof this.options.revert === "function" && 10070 this.options.revert.call( this.element, dropped ) ) 10071 ) { 10072 $( this.helper ).animate( 10073 this.originalPosition, 10074 parseInt( this.options.revertDuration, 10 ), 10075 function() { 10076 if ( that._trigger( "stop", event ) !== false ) { 10077 that._clear(); 10078 } 10079 } 10080 ); 10081 } else { 10082 if ( this._trigger( "stop", event ) !== false ) { 10083 this._clear(); 10084 } 10085 } 10086 10087 return false; 10088 }, 10089 10090 _mouseUp: function( event ) { 10091 this._unblockFrames(); 10092 10093 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 10094 // (see #5003) 10095 if ( $.ui.ddmanager ) { 10096 $.ui.ddmanager.dragStop( this, event ); 10097 } 10098 10099 // Only need to focus if the event occurred on the draggable itself, see #10527 10100 if ( this.handleElement.is( event.target ) ) { 10101 10102 // The interaction is over; whether or not the click resulted in a drag, 10103 // focus the element 10104 this.element.trigger( "focus" ); 10105 } 10106 10107 return $.ui.mouse.prototype._mouseUp.call( this, event ); 10108 }, 10109 10110 cancel: function() { 10111 10112 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 10113 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 10114 } else { 10115 this._clear(); 10116 } 10117 10118 return this; 10119 10120 }, 10121 10122 _getHandle: function( event ) { 10123 return this.options.handle ? 10124 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 10125 true; 10126 }, 10127 10128 _setHandleClassName: function() { 10129 this.handleElement = this.options.handle ? 10130 this.element.find( this.options.handle ) : this.element; 10131 this._addClass( this.handleElement, "ui-draggable-handle" ); 10132 }, 10133 10134 _removeHandleClassName: function() { 10135 this._removeClass( this.handleElement, "ui-draggable-handle" ); 10136 }, 10137 10138 _createHelper: function( event ) { 10139 10140 var o = this.options, 10141 helperIsFunction = typeof o.helper === "function", 10142 helper = helperIsFunction ? 10143 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 10144 ( o.helper === "clone" ? 10145 this.element.clone().removeAttr( "id" ) : 10146 this.element ); 10147 10148 if ( !helper.parents( "body" ).length ) { 10149 helper.appendTo( ( o.appendTo === "parent" ? 10150 this.element[ 0 ].parentNode : 10151 o.appendTo ) ); 10152 } 10153 10154 //
10154Http
vendor: 25,991 bytes, lines 10154-11026
10154://bugs.jqueryui.com/ticket/9446 10155 // a helper function can return the original element 10156 // which wouldn't have been set to relative in _create 10157 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 10158 this._setPositionRelative(); 10159 } 10160 10161 if ( helper[ 0 ] !== this.element[ 0 ] && 10162 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 10163 helper.css( "position", "absolute" ); 10164 } 10165 10166 return helper; 10167 10168 }, 10169 10170 _setPositionRelative: function() { 10171 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 10172 this.element[ 0 ].style.position = "relative"; 10173 } 10174 }, 10175 10176 _adjustOffsetFromHelper: function( obj ) { 10177 if ( typeof obj === "string" ) { 10178 obj = obj.split( " " ); 10179 } 10180 if ( Array.isArray( obj ) ) { 10181 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 10182 } 10183 if ( "left" in obj ) { 10184 this.offset.click.left = obj.left + this.margins.left; 10185 } 10186 if ( "right" in obj ) { 10187 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 10188 } 10189 if ( "top" in obj ) { 10190 this.offset.click.top = obj.top + this.margins.top; 10191 } 10192 if ( "bottom" in obj ) { 10193 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 10194 } 10195 }, 10196 10197 _isRootNode: function( element ) { 10198 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 10199 }, 10200 10201 _getParentOffset: function() { 10202 10203 //Get the offsetParent and cache its position 10204 var po = this.offsetParent.offset(), 10205 document = this.document[ 0 ]; 10206 10207 // This is a special case where we need to modify a offset calculated on start, since the 10208 // following happened: 10209 // 1. The position of the helper is absolute, so it's position is calculated based on the 10210 // next positioned parent 10211 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 10212 // the document, which means that the scroll is included in the initial calculation of the 10213 // offset of the parent, and never recalculated upon drag 10214 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 10215 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 10216 po.left += this.scrollParent.scrollLeft(); 10217 po.top += this.scrollParent.scrollTop(); 10218 } 10219 10220 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 10221 po = { top: 0, left: 0 }; 10222 } 10223 10224 return { 10225 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 10226 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 10227 }; 10228 10229 }, 10230 10231 _getRelativeOffset: function() { 10232 if ( this.cssPosition !== "relative" ) { 10233 return { top: 0, left: 0 }; 10234 } 10235 10236 var p = this.element.position(), 10237 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 10238 10239 return { 10240 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 10241 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 10242 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 10243 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 10244 }; 10245 10246 }, 10247 10248 _cacheMargins: function() { 10249 this.margins = { 10250 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 10251 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 10252 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 10253 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 10254 }; 10255 }, 10256 10257 _cacheHelperProportions: function() { 10258 this.helperProportions = { 10259 width: this.helper.outerWidth(), 10260 height: this.helper.outerHeight() 10261 }; 10262 }, 10263 10264 _setContainment: function() { 10265 10266 var isUserScrollable, c, ce, 10267 o = this.options, 10268 document = this.document[ 0 ]; 10269 10270 this.relativeContainer = null; 10271 10272 if ( !o.containment ) { 10273 this.containment = null; 10274 return; 10275 } 10276 10277 if ( o.containment === "window" ) { 10278 this.containment = [ 10279 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 10280 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 10281 $( window ).scrollLeft() + $( window ).width() - 10282 this.helperProportions.width - this.margins.left, 10283 $( window ).scrollTop() + 10284 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 10285 this.helperProportions.height - this.margins.top 10286 ]; 10287 return; 10288 } 10289 10290 if ( o.containment === "document" ) { 10291 this.containment = [ 10292 0, 10293 0, 10294 $( document ).width() - this.helperProportions.width - this.margins.left, 10295 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 10296 this.helperProportions.height - this.margins.top 10297 ]; 10298 return; 10299 } 10300 10301 if ( o.containment.constructor === Array ) { 10302 this.containment = o.containment; 10303 return; 10304 } 10305 10306 if ( o.containment === "parent" ) { 10307 o.containment = this.helper[ 0 ].parentNode; 10308 } 10309 10310 c = $( o.containment ); 10311 ce = c[ 0 ]; 10312 10313 if ( !ce ) { 10314 return; 10315 } 10316 10317 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 10318 10319 this.containment = [ 10320 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 10321 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 10322 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 10323 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 10324 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 10325 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 10326 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 10327 this.helperProportions.width - 10328 this.margins.left - 10329 this.margins.right, 10330 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 10331 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 10332 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 10333 this.helperProportions.height - 10334 this.margins.top - 10335 this.margins.bottom 10336 ]; 10337 this.relativeContainer = c; 10338 }, 10339 10340 _convertPositionTo: function( d, pos ) { 10341 10342 if ( !pos ) { 10343 pos = this.position; 10344 } 10345 10346 var mod = d === "absolute" ? 1 : -1, 10347 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 10348 10349 return { 10350 top: ( 10351 10352 // The absolute mouse position 10353 pos.top + 10354 10355 // Only for relative positioned nodes: Relative offset from element to offset parent 10356 this.offset.relative.top * mod + 10357 10358 // The offsetParent's offset without borders (offset + border) 10359 this.offset.parent.top * mod - 10360 ( ( this.cssPosition === "fixed" ? 10361 -this.offset.scroll.top : 10362 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 10363 ), 10364 left: ( 10365 10366 // The absolute mouse position 10367 pos.left + 10368 10369 // Only for relative positioned nodes: Relative offset from element to offset parent 10370 this.offset.relative.left * mod + 10371 10372 // The offsetParent's offset without borders (offset + border) 10373 this.offset.parent.left * mod - 10374 ( ( this.cssPosition === "fixed" ? 10375 -this.offset.scroll.left : 10376 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 10377 ) 10378 }; 10379 10380 }, 10381 10382 _generatePosition: function( event, constrainPosition ) { 10383 10384 var containment, co, top, left, 10385 o = this.options, 10386 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 10387 pageX = event.pageX, 10388 pageY = event.pageY; 10389 10390 // Cache the scroll 10391 if ( !scrollIsRootNode || !this.offset.scroll ) { 10392 this.offset.scroll = { 10393 top: this.scrollParent.scrollTop(), 10394 left: this.scrollParent.scrollLeft() 10395 }; 10396 } 10397 10398 /* 10399 * - Position constraining - 10400 * Constrain the position to a mix of grid, containment. 10401 */ 10402 10403 // If we are not dragging yet, we won't check for options 10404 if ( constrainPosition ) { 10405 if ( this.containment ) { 10406 if ( this.relativeContainer ) { 10407 co = this.relativeContainer.offset(); 10408 containment = [ 10409 this.containment[ 0 ] + co.left, 10410 this.containment[ 1 ] + co.top, 10411 this.containment[ 2 ] + co.left, 10412 this.containment[ 3 ] + co.top 10413 ]; 10414 } else { 10415 containment = this.containment; 10416 } 10417 10418 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 10419 pageX = containment[ 0 ] + this.offset.click.left; 10420 } 10421 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 10422 pageY = containment[ 1 ] + this.offset.click.top; 10423 } 10424 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 10425 pageX = containment[ 2 ] + this.offset.click.left; 10426 } 10427 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 10428 pageY = containment[ 3 ] + this.offset.click.top; 10429 } 10430 } 10431 10432 if ( o.grid ) { 10433 10434 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 10435 // argument errors in IE (see ticket #6950) 10436 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 10437 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 10438 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 10439 top - this.offset.click.top > containment[ 3 ] ) ? 10440 top : 10441 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 10442 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 10443 10444 left = o.grid[ 0 ] ? this.originalPageX + 10445 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 10446 this.originalPageX; 10447 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 10448 left - this.offset.click.left > containment[ 2 ] ) ? 10449 left : 10450 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 10451 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 10452 } 10453 10454 if ( o.axis === "y" ) { 10455 pageX = this.originalPageX; 10456 } 10457 10458 if ( o.axis === "x" ) { 10459 pageY = this.originalPageY; 10460 } 10461 } 10462 10463 return { 10464 top: ( 10465 10466 // The absolute mouse position 10467 pageY - 10468 10469 // Click offset (relative to the element) 10470 this.offset.click.top - 10471 10472 // Only for relative positioned nodes: Relative offset from element to offset parent 10473 this.offset.relative.top - 10474 10475 // The offsetParent's offset without borders (offset + border) 10476 this.offset.parent.top + 10477 ( this.cssPosition === "fixed" ? 10478 -this.offset.scroll.top : 10479 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 10480 ), 10481 left: ( 10482 10483 // The absolute mouse position 10484 pageX - 10485 10486 // Click offset (relative to the element) 10487 this.offset.click.left - 10488 10489 // Only for relative positioned nodes: Relative offset from element to offset parent 10490 this.offset.relative.left - 10491 10492 // The offsetParent's offset without borders (offset + border) 10493 this.offset.parent.left + 10494 ( this.cssPosition === "fixed" ? 10495 -this.offset.scroll.left : 10496 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 10497 ) 10498 }; 10499 10500 }, 10501 10502 _clear: function() { 10503 this._removeClass( this.helper, "ui-draggable-dragging" ); 10504 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 10505 this.helper.remove(); 10506 } 10507 this.helper = null; 10508 this.cancelHelperRemoval = false; 10509 if ( this.destroyOnClear ) { 10510 this.destroy(); 10511 } 10512 }, 10513 10514 // From now on bulk stuff - mainly helpers 10515 10516 _trigger: function( type, event, ui ) { 10517 ui = ui || this._uiHash(); 10518 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 10519 10520 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 10521 if ( /^(drag|start|stop)/.test( type ) ) { 10522 this.positionAbs = this._convertPositionTo( "absolute" ); 10523 ui.offset = this.positionAbs; 10524 } 10525 return $.Widget.prototype._trigger.call( this, type, event, ui ); 10526 }, 10527 10528 plugins: {}, 10529 10530 _uiHash: function() { 10531 return { 10532 helper: this.helper, 10533 position: this.position, 10534 originalPosition: this.originalPosition, 10535 offset: this.positionAbs 10536 }; 10537 } 10538 10539} ); 10540 10541$.ui.plugin.add( "draggable", "connectToSortable", { 10542 start: function( event, ui, draggable ) { 10543 var uiSortable = $.extend( {}, ui, { 10544 item: draggable.element 10545 } ); 10546 10547 draggable.sortables = []; 10548 $( draggable.options.connectToSortable ).each( function() { 10549 var sortable = $( this ).sortable( "instance" ); 10550 10551 if ( sortable && !sortable.options.disabled ) { 10552 draggable.sortables.push( sortable ); 10553 10554 // RefreshPositions is called at drag start to refresh the containerCache 10555 // which is used in drag. This ensures it's initialized and synchronized 10556 // with any changes that might have happened on the page since initialization. 10557 sortable.refreshPositions(); 10558 sortable._trigger( "activate", event, uiSortable ); 10559 } 10560 } ); 10561 }, 10562 stop: function( event, ui, draggable ) { 10563 var uiSortable = $.extend( {}, ui, { 10564 item: draggable.element 10565 } ); 10566 10567 draggable.cancelHelperRemoval = false; 10568 10569 $.each( draggable.sortables, function() { 10570 var sortable = this; 10571 10572 if ( sortable.isOver ) { 10573 sortable.isOver = 0; 10574 10575 // Allow this sortable to handle removing the helper 10576 draggable.cancelHelperRemoval = true; 10577 sortable.cancelHelperRemoval = false; 10578 10579 // Use _storedCSS To restore properties in the sortable, 10580 // as this also handles revert (#9675) since the draggable 10581 // may have modified them in unexpected ways (#8809) 10582 sortable._storedCSS = { 10583 position: sortable.placeholder.css( "position" ), 10584 top: sortable.placeholder.css( "top" ), 10585 left: sortable.placeholder.css( "left" ) 10586 }; 10587 10588 sortable._mouseStop( event ); 10589 10590 // Once drag has ended, the sortable should return to using 10591 // its original helper, not the shared helper from draggable 10592 sortable.options.helper = sortable.options._helper; 10593 } else { 10594 10595 // Prevent this Sortable from removing the helper. 10596 // However, don't set the draggable to remove the helper 10597 // either as another connected Sortable may yet handle the removal. 10598 sortable.cancelHelperRemoval = true; 10599 10600 sortable._trigger( "deactivate", event, uiSortable ); 10601 } 10602 } ); 10603 }, 10604 drag: function( event, ui, draggable ) { 10605 $.each( draggable.sortables, function() { 10606 var innermostIntersecting = false, 10607 sortable = this; 10608 10609 // Copy over variables that sortable's _intersectsWith uses 10610 sortable.positionAbs = draggable.positionAbs; 10611 sortable.helperProportions = draggable.helperProportions; 10612 sortable.offset.click = draggable.offset.click; 10613 10614 if ( sortable._intersectsWith( sortable.containerCache ) ) { 10615 innermostIntersecting = true; 10616 10617 $.each( draggable.sortables, function() { 10618 10619 // Copy over variables that sortable's _intersectsWith uses 10620 this.positionAbs = draggable.positionAbs; 10621 this.helperProportions = draggable.helperProportions; 10622 this.offset.click = draggable.offset.click; 10623 10624 if ( this !== sortable && 10625 this._intersectsWith( this.containerCache ) && 10626 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 10627 innermostIntersecting = false; 10628 } 10629 10630 return innermostIntersecting; 10631 } ); 10632 } 10633 10634 if ( innermostIntersecting ) { 10635 10636 // If it intersects, we use a little isOver variable and set it once, 10637 // so that the move-in stuff gets fired only once. 10638 if ( !sortable.isOver ) { 10639 sortable.isOver = 1; 10640 10641 // Store draggable's parent in case we need to reappend to it later. 10642 draggable._parent = ui.helper.parent(); 10643 10644 sortable.currentItem = ui.helper 10645 .appendTo( sortable.element ) 10646 .data( "ui-sortable-item", true ); 10647 10648 // Store helper option to later restore it 10649 sortable.options._helper = sortable.options.helper; 10650 10651 sortable.options.helper = function() { 10652 return ui.helper[ 0 ]; 10653 }; 10654 10655 // Fire the start events of the sortable with our passed browser event, 10656 // and our own helper (so it doesn't create a new one) 10657 event.target = sortable.currentItem[ 0 ]; 10658 sortable._mouseCapture( event, true ); 10659 sortable._mouseStart( event, true, true ); 10660 10661 // Because the browser event is way off the new appended portlet, 10662 // modify necessary variables to reflect the changes 10663 sortable.offset.click.top = draggable.offset.click.top; 10664 sortable.offset.click.left = draggable.offset.click.left; 10665 sortable.offset.parent.left -= draggable.offset.parent.left - 10666 sortable.offset.parent.left; 10667 sortable.offset.parent.top -= draggable.offset.parent.top - 10668 sortable.offset.parent.top; 10669 10670 draggable._trigger( "toSortable", event ); 10671 10672 // Inform draggable that the helper is in a valid drop zone, 10673 // used solely in the revert option to handle "valid/invalid". 10674 draggable.dropped = sortable.element; 10675 10676 // Need to refreshPositions of all sortables in the case that 10677 // adding to one sortable changes the location of the other sortables (#9675) 10678 $.each( draggable.sortables, function() { 10679 this.refreshPositions(); 10680 } ); 10681 10682 // Hack so receive/update callbacks work (mostly) 10683 draggable.currentItem = draggable.element; 10684 sortable.fromOutside = draggable; 10685 } 10686 10687 if ( sortable.currentItem ) { 10688 sortable._mouseDrag( event ); 10689 10690 // Copy the sortable's position because the draggable's can potentially reflect 10691 // a relative position, while sortable is always absolute, which the dragged 10692 // element has now become. (#8809) 10693 ui.position = sortable.position; 10694 } 10695 } else { 10696 10697 // If it doesn't intersect with the sortable, and it intersected before, 10698 // we fake the drag stop of the sortable, but make sure it doesn't remove 10699 // the helper by using cancelHelperRemoval. 10700 if ( sortable.isOver ) { 10701 10702 sortable.isOver = 0; 10703 sortable.cancelHelperRemoval = true; 10704 10705 // Calling sortable's mouseStop would trigger a revert, 10706 // so revert must be temporarily false until after mouseStop is called. 10707 sortable.options._revert = sortable.options.revert; 10708 sortable.options.revert = false; 10709 10710 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 10711 sortable._mouseStop( event, true ); 10712 10713 // Restore sortable behaviors that were modfied 10714 // when the draggable entered the sortable area (#9481) 10715 sortable.options.revert = sortable.options._revert; 10716 sortable.options.helper = sortable.options._helper; 10717 10718 if ( sortable.placeholder ) { 10719 sortable.placeholder.remove(); 10720 } 10721 10722 // Restore and recalculate the draggable's offset considering the sortable 10723 // may have modified them in unexpected ways. (#8809, #10669) 10724 ui.helper.appendTo( draggable._parent ); 10725 draggable._refreshOffsets( event ); 10726 ui.position = draggable._generatePosition( event, true ); 10727 10728 draggable._trigger( "fromSortable", event ); 10729 10730 // Inform draggable that the helper is no longer in a valid drop zone 10731 draggable.dropped = false; 10732 10733 // Need to refreshPositions of all sortables just in case removing 10734 // from one sortable changes the location of other sortables (#9675) 10735 $.each( draggable.sortables, function() { 10736 this.refreshPositions(); 10737 } ); 10738 } 10739 } 10740 } ); 10741 } 10742} ); 10743 10744$.ui.plugin.add( "draggable", "cursor", { 10745 start: function( event, ui, instance ) { 10746 var t = $( "body" ), 10747 o = instance.options; 10748 10749 if ( t.css( "cursor" ) ) { 10750 o._cursor = t.css( "cursor" ); 10751 } 10752 t.css( "cursor", o.cursor ); 10753 }, 10754 stop: function( event, ui, instance ) { 10755 var o = instance.options; 10756 if ( o._cursor ) { 10757 $( "body" ).css( "cursor", o._cursor ); 10758 } 10759 } 10760} ); 10761 10762$.ui.plugin.add( "draggable", "opacity", { 10763 start: function( event, ui, instance ) { 10764 var t = $( ui.helper ), 10765 o = instance.options; 10766 if ( t.css( "opacity" ) ) { 10767 o._opacity = t.css( "opacity" ); 10768 } 10769 t.css( "opacity", o.opacity ); 10770 }, 10771 stop: function( event, ui, instance ) { 10772 var o = instance.options; 10773 if ( o._opacity ) { 10774 $( ui.helper ).css( "opacity", o._opacity ); 10775 } 10776 } 10777} ); 10778 10779$.ui.plugin.add( "draggable", "scroll", { 10780 start: function( event, ui, i ) { 10781 if ( !i.scrollParentNotHidden ) { 10782 i.scrollParentNotHidden = i.helper.scrollParent( false ); 10783 } 10784 10785 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 10786 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 10787 i.overflowOffset = i.scrollParentNotHidden.offset(); 10788 } 10789 }, 10790 drag: function( event, ui, i ) { 10791 10792 var o = i.options, 10793 scrolled = false, 10794 scrollParent = i.scrollParentNotHidden[ 0 ], 10795 document = i.document[ 0 ]; 10796 10797 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 10798 if ( !o.axis || o.axis !== "x" ) { 10799 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 10800 o.scrollSensitivity ) { 10801 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 10802 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 10803 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 10804 } 10805 } 10806 10807 if ( !o.axis || o.axis !== "y" ) { 10808 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 10809 o.scrollSensitivity ) { 10810 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 10811 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 10812 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 10813 } 10814 } 10815 10816 } else { 10817 10818 if ( !o.axis || o.axis !== "x" ) { 10819 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 10820 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 10821 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 10822 o.scrollSensitivity ) { 10823 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 10824 } 10825 } 10826 10827 if ( !o.axis || o.axis !== "y" ) { 10828 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 10829 scrolled = $( document ).scrollLeft( 10830 $( document ).scrollLeft() - o.scrollSpeed 10831 ); 10832 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 10833 o.scrollSensitivity ) { 10834 scrolled = $( document ).scrollLeft( 10835 $( document ).scrollLeft() + o.scrollSpeed 10836 ); 10837 } 10838 } 10839 10840 } 10841 10842 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 10843 $.ui.ddmanager.prepareOffsets( i, event ); 10844 } 10845 10846 } 10847} ); 10848 10849$.ui.plugin.add( "draggable", "snap", { 10850 start: function( event, ui, i ) { 10851 10852 var o = i.options; 10853 10854 i.snapElements = []; 10855 10856 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 10857 .each( function() { 10858 var $t = $( this ), 10859 $o = $t.offset(); 10860 if ( this !== i.element[ 0 ] ) { 10861 i.snapElements.push( { 10862 item: this, 10863 width: $t.outerWidth(), height: $t.outerHeight(), 10864 top: $o.top, left: $o.left 10865 } ); 10866 } 10867 } ); 10868 10869 }, 10870 drag: function( event, ui, inst ) { 10871 10872 var ts, bs, ls, rs, l, r, t, b, i, first, 10873 o = inst.options, 10874 d = o.snapTolerance, 10875 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 10876 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 10877 10878 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 10879 10880 l = inst.snapElements[ i ].left - inst.margins.left; 10881 r = l + inst.snapElements[ i ].width; 10882 t = inst.snapElements[ i ].top - inst.margins.top; 10883 b = t + inst.snapElements[ i ].height; 10884 10885 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 10886 !$.contains( inst.snapElements[ i ].item.ownerDocument, 10887 inst.snapElements[ i ].item ) ) { 10888 if ( inst.snapElements[ i ].snapping ) { 10889 if ( inst.options.snap.release ) { 10890 inst.options.snap.release.call( 10891 inst.element, 10892 event, 10893 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 10894 ); 10895 } 10896 } 10897 inst.snapElements[ i ].snapping = false; 10898 continue; 10899 } 10900 10901 if ( o.snapMode !== "inner" ) { 10902 ts = Math.abs( t - y2 ) <= d; 10903 bs = Math.abs( b - y1 ) <= d; 10904 ls = Math.abs( l - x2 ) <= d; 10905 rs = Math.abs( r - x1 ) <= d; 10906 if ( ts ) { 10907 ui.position.top = inst._convertPositionTo( "relative", { 10908 top: t - inst.helperProportions.height, 10909 left: 0 10910 } ).top; 10911 } 10912 if ( bs ) { 10913 ui.position.top = inst._convertPositionTo( "relative", { 10914 top: b, 10915 left: 0 10916 } ).top; 10917 } 10918 if ( ls ) { 10919 ui.position.left = inst._convertPositionTo( "relative", { 10920 top: 0, 10921 left: l - inst.helperProportions.width 10922 } ).left; 10923 } 10924 if ( rs ) { 10925 ui.position.left = inst._convertPositionTo( "relative", { 10926 top: 0, 10927 left: r 10928 } ).left; 10929 } 10930 } 10931 10932 first = ( ts || bs || ls || rs ); 10933 10934 if ( o.snapMode !== "outer" ) { 10935 ts = Math.abs( t - y1 ) <= d; 10936 bs = Math.abs( b - y2 ) <= d; 10937 ls = Math.abs( l - x1 ) <= d; 10938 rs = Math.abs( r - x2 ) <= d; 10939 if ( ts ) { 10940 ui.position.top = inst._convertPositionTo( "relative", { 10941 top: t, 10942 left: 0 10943 } ).top; 10944 } 10945 if ( bs ) { 10946 ui.position.top = inst._convertPositionTo( "relative", { 10947 top: b - inst.helperProportions.height, 10948 left: 0 10949 } ).top; 10950 } 10951 if ( ls ) { 10952 ui.position.left = inst._convertPositionTo( "relative", { 10953 top: 0, 10954 left: l 10955 } ).left; 10956 } 10957 if ( rs ) { 10958 ui.position.left = inst._convertPositionTo( "relative", { 10959 top: 0, 10960 left: r - inst.helperProportions.width 10961 } ).left; 10962 } 10963 } 10964 10965 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 10966 if ( inst.options.snap.snap ) { 10967 inst.options.snap.snap.call( 10968 inst.element, 10969 event, 10970 $.extend( inst._uiHash(), { 10971 snapItem: inst.snapElements[ i ].item 10972 } ) ); 10973 } 10974 } 10975 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 10976 10977 } 10978 10979 } 10980} ); 10981 10982$.ui.plugin.add( "draggable", "stack", { 10983 start: function( event, ui, instance ) { 10984 var min, 10985 o = instance.options, 10986 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 10987 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 10988 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 10989 } ); 10990 10991 if ( !group.length ) { 10992 return; 10993 } 10994 10995 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 10996 $( group ).each( function( i ) { 10997 $( this ).css( "zIndex", min + i ); 10998 } ); 10999 this.css( "zIndex", ( min + group.length ) ); 11000 } 11001} ); 11002 11003$.ui.plugin.add( "draggable", "zIndex", { 11004 start: function( event, ui, instance ) { 11005 var t = $( ui.helper ), 11006 o = instance.options; 11007 11008 if ( t.css( "zIndex" ) ) { 11009 o._zIndex = t.css( "zIndex" ); 11010 } 11011 t.css( "zIndex", o.zIndex ); 11012 }, 11013 stop: function( event, ui, instance ) { 11014 var o = instance.options; 11015 11016 if ( o._zIndex ) { 11017 $( ui.helper ).css( "zIndex", o._zIndex ); 11018 } 11019 } 11020} ); 11021 11022var widgetsDraggable = $.ui.draggable; 11023 11024 11025/*! 11026 * jQuery UI Resizable 1.13.
110262 11027 * http://jqueryui.com 11028 * 11029 * Copyright jQuery Foundation and other contributors 11030 * Released under the MIT license. 11031 * http://jquery.org/license 11032 */ 11033 11034//>>label: Resizable 11035//>>group: Interactions 11036//>>description: Enables resize functionality for any element. 11037//>>docs: http://api.jqueryui.com/resizable/ 11038//>>demos: http://jqueryui.com/resizable/ 11039//>>css.structure: ../../themes/base/core.css 11040//>>css.structure: ../../themes/base/resizable.css 11041//>>css.theme: ../../themes/base/theme.css 11042 11043 11044$.widget( "ui.resizable", $.ui.mouse, { 11045 version: "1.13.2
vendor: 11,739 bytes, lines 11045-11538
11045", 11046 widgetEventPrefix: "resize", 11047 options: { 11048 alsoResize: false, 11049 animate: false, 11050 animateDuration: "slow", 11051 animateEasing: "swing", 11052 aspectRatio: false, 11053 autoHide: false, 11054 classes: { 11055 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 11056 }, 11057 containment: false, 11058 ghost: false, 11059 grid: false, 11060 handles: "e,s,se", 11061 helper: false, 11062 maxHeight: null, 11063 maxWidth: null, 11064 minHeight: 10, 11065 minWidth: 10, 11066 11067 // See #7960 11068 zIndex: 90, 11069 11070 // Callbacks 11071 resize: null, 11072 start: null, 11073 stop: null 11074 }, 11075 11076 _num: function( value ) { 11077 return parseFloat( value ) || 0; 11078 }, 11079 11080 _isNumber: function( value ) { 11081 return !isNaN( parseFloat( value ) ); 11082 }, 11083 11084 _hasScroll: function( el, a ) { 11085 11086 if ( $( el ).css( "overflow" ) === "hidden" ) { 11087 return false; 11088 } 11089 11090 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 11091 has = false; 11092 11093 if ( el[ scroll ] > 0 ) { 11094 return true; 11095 } 11096 11097 // TODO: determine which cases actually cause this to happen 11098 // if the element doesn't have the scroll set, see if it's possible to 11099 // set the scroll 11100 try { 11101 el[ scroll ] = 1; 11102 has = ( el[ scroll ] > 0 ); 11103 el[ scroll ] = 0; 11104 } catch ( e ) { 11105 11106 // `el` might be a string, then setting `scroll` will throw 11107 // an error in strict mode; ignore it. 11108 } 11109 return has; 11110 }, 11111 11112 _create: function() { 11113 11114 var margins, 11115 o = this.options, 11116 that = this; 11117 this._addClass( "ui-resizable" ); 11118 11119 $.extend( this, { 11120 _aspectRatio: !!( o.aspectRatio ), 11121 aspectRatio: o.aspectRatio, 11122 originalElement: this.element, 11123 _proportionallyResizeElements: [], 11124 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 11125 } ); 11126 11127 // Wrap the element if it cannot hold child nodes 11128 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 11129 11130 this.element.wrap( 11131 $( "<div class='ui-wrapper'></div>" ).css( { 11132 overflow: "hidden", 11133 position: this.element.css( "position" ), 11134 width: this.element.outerWidth(), 11135 height: this.element.outerHeight(), 11136 top: this.element.css( "top" ), 11137 left: this.element.css( "left" ) 11138 } ) 11139 ); 11140 11141 this.element = this.element.parent().data( 11142 "ui-resizable", this.element.resizable( "instance" ) 11143 ); 11144 11145 this.elementIsWrapper = true; 11146 11147 margins = { 11148 marginTop: this.originalElement.css( "marginTop" ), 11149 marginRight: this.originalElement.css( "marginRight" ), 11150 marginBottom: this.originalElement.css( "marginBottom" ), 11151 marginLeft: this.originalElement.css( "marginLeft" ) 11152 }; 11153 11154 this.element.css( margins ); 11155 this.originalElement.css( "margin", 0 ); 11156 11157 // support: Safari 11158 // Prevent Safari textarea resize 11159 this.originalResizeStyle = this.originalElement.css( "resize" ); 11160 this.originalElement.css( "resize", "none" ); 11161 11162 this._proportionallyResizeElements.push( this.originalElement.css( { 11163 position: "static", 11164 zoom: 1, 11165 display: "block" 11166 } ) ); 11167 11168 // Support: IE9 11169 // avoid IE jump (hard set the margin) 11170 this.originalElement.css( margins ); 11171 11172 this._proportionallyResize(); 11173 } 11174 11175 this._setupHandles(); 11176 11177 if ( o.autoHide ) { 11178 $( this.element ) 11179 .on( "mouseenter", function() { 11180 if ( o.disabled ) { 11181 return; 11182 } 11183 that._removeClass( "ui-resizable-autohide" ); 11184 that._handles.show(); 11185 } ) 11186 .on( "mouseleave", function() { 11187 if ( o.disabled ) { 11188 return; 11189 } 11190 if ( !that.resizing ) { 11191 that._addClass( "ui-resizable-autohide" ); 11192 that._handles.hide(); 11193 } 11194 } ); 11195 } 11196 11197 this._mouseInit(); 11198 }, 11199 11200 _destroy: function() { 11201 11202 this._mouseDestroy(); 11203 this._addedHandles.remove(); 11204 11205 var wrapper, 11206 _destroy = function( exp ) { 11207 $( exp ) 11208 .removeData( "resizable" ) 11209 .removeData( "ui-resizable" ) 11210 .off( ".resizable" ); 11211 }; 11212 11213 // TODO: Unwrap at same DOM position 11214 if ( this.elementIsWrapper ) { 11215 _destroy( this.element ); 11216 wrapper = this.element; 11217 this.originalElement.css( { 11218 position: wrapper.css( "position" ), 11219 width: wrapper.outerWidth(), 11220 height: wrapper.outerHeight(), 11221 top: wrapper.css( "top" ), 11222 left: wrapper.css( "left" ) 11223 } ).insertAfter( wrapper ); 11224 wrapper.remove(); 11225 } 11226 11227 this.originalElement.css( "resize", this.originalResizeStyle ); 11228 _destroy( this.originalElement ); 11229 11230 return this; 11231 }, 11232 11233 _setOption: function( key, value ) { 11234 this._super( key, value ); 11235 11236 switch ( key ) { 11237 case "handles": 11238 this._removeHandles(); 11239 this._setupHandles(); 11240 break; 11241 case "aspectRatio": 11242 this._aspectRatio = !!value; 11243 break; 11244 default: 11245 break; 11246 } 11247 }, 11248 11249 _setupHandles: function() { 11250 var o = this.options, handle, i, n, hname, axis, that = this; 11251 this.handles = o.handles || 11252 ( !$( ".ui-resizable-handle", this.element ).length ? 11253 "e,s,se" : { 11254 n: ".ui-resizable-n", 11255 e: ".ui-resizable-e", 11256 s: ".ui-resizable-s", 11257 w: ".ui-resizable-w", 11258 se: ".ui-resizable-se", 11259 sw: ".ui-resizable-sw", 11260 ne: ".ui-resizable-ne", 11261 nw: ".ui-resizable-nw" 11262 } ); 11263 11264 this._handles = $(); 11265 this._addedHandles = $(); 11266 if ( this.handles.constructor === String ) { 11267 11268 if ( this.handles === "all" ) { 11269 this.handles = "n,e,s,w,se,sw,ne,nw"; 11270 } 11271 11272 n = this.handles.split( "," ); 11273 this.handles = {}; 11274 11275 for ( i = 0; i < n.length; i++ ) { 11276 11277 handle = String.prototype.trim.call( n[ i ] ); 11278 hname = "ui-resizable-" + handle; 11279 axis = $( "<div>" ); 11280 this._addClass( axis, "ui-resizable-handle " + hname ); 11281 11282 axis.css( { zIndex: o.zIndex } ); 11283 11284 this.handles[ handle ] = ".ui-resizable-" + handle; 11285 if ( !this.element.children( this.handles[ handle ] ).length ) { 11286 this.element.append( axis ); 11287 this._addedHandles = this._addedHandles.add( axis ); 11288 } 11289 } 11290 11291 } 11292 11293 this._renderAxis = function( target ) { 11294 11295 var i, axis, padPos, padWrapper; 11296 11297 target = target || this.element; 11298 11299 for ( i in this.handles ) { 11300 11301 if ( this.handles[ i ].constructor === String ) { 11302 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 11303 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 11304 this.handles[ i ] = $( this.handles[ i ] ); 11305 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 11306 } 11307 11308 if ( this.elementIsWrapper && 11309 this.originalElement[ 0 ] 11310 .nodeName 11311 .match( /^(textarea|input|select|button)$/i ) ) { 11312 axis = $( this.handles[ i ], this.element ); 11313 11314 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 11315 axis.outerHeight() : 11316 axis.outerWidth(); 11317 11318 padPos = [ "padding", 11319 /ne|nw|n/.test( i ) ? "Top" : 11320 /se|sw|s/.test( i ) ? "Bottom" : 11321 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 11322 11323 target.css( padPos, padWrapper ); 11324 11325 this._proportionallyResize(); 11326 } 11327 11328 this._handles = this._handles.add( this.handles[ i ] ); 11329 } 11330 }; 11331 11332 // TODO: make renderAxis a prototype function 11333 this._renderAxis( this.element ); 11334 11335 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 11336 this._handles.disableSelection(); 11337 11338 this._handles.on( "mouseover", function() { 11339 if ( !that.resizing ) { 11340 if ( this.className ) { 11341 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 11342 } 11343 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 11344 } 11345 } ); 11346 11347 if ( o.autoHide ) { 11348 this._handles.hide(); 11349 this._addClass( "ui-resizable-autohide" ); 11350 } 11351 }, 11352 11353 _removeHandles: function() { 11354 this._addedHandles.remove(); 11355 }, 11356 11357 _mouseCapture: function( event ) { 11358 var i, handle, 11359 capture = false; 11360 11361 for ( i in this.handles ) { 11362 handle = $( this.handles[ i ] )[ 0 ]; 11363 if ( handle === event.target || $.contains( handle, event.target ) ) { 11364 capture = true; 11365 } 11366 } 11367 11368 return !this.options.disabled && capture; 11369 }, 11370 11371 _mouseStart: function( event ) { 11372 11373 var curleft, curtop, cursor, 11374 o = this.options, 11375 el = this.element; 11376 11377 this.resizing = true; 11378 11379 this._renderProxy(); 11380 11381 curleft = this._num( this.helper.css( "left" ) ); 11382 curtop = this._num( this.helper.css( "top" ) ); 11383 11384 if ( o.containment ) { 11385 curleft += $( o.containment ).scrollLeft() || 0; 11386 curtop += $( o.containment ).scrollTop() || 0; 11387 } 11388 11389 this.offset = this.helper.offset(); 11390 this.position = { left: curleft, top: curtop }; 11391 11392 this.size = this._helper ? { 11393 width: this.helper.width(), 11394 height: this.helper.height() 11395 } : { 11396 width: el.width(), 11397 height: el.height() 11398 }; 11399 11400 this.originalSize = this._helper ? { 11401 width: el.outerWidth(), 11402 height: el.outerHeight() 11403 } : { 11404 width: el.width(), 11405 height: el.height() 11406 }; 11407 11408 this.sizeDiff = { 11409 width: el.outerWidth() - el.width(), 11410 height: el.outerHeight() - el.height() 11411 }; 11412 11413 this.originalPosition = { left: curleft, top: curtop }; 11414 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 11415 11416 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 11417 o.aspectRatio : 11418 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 11419 11420 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 11421 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 11422 11423 this._addClass( "ui-resizable-resizing" ); 11424 this._propagate( "start", event ); 11425 return true; 11426 }, 11427 11428 _mouseDrag: function( event ) { 11429 11430 var data, props, 11431 smp = this.originalMousePosition, 11432 a = this.axis, 11433 dx = ( event.pageX - smp.left ) || 0, 11434 dy = ( event.pageY - smp.top ) || 0, 11435 trigger = this._change[ a ]; 11436 11437 this._updatePrevProperties(); 11438 11439 if ( !trigger ) { 11440 return false; 11441 } 11442 11443 data = trigger.apply( this, [ event, dx, dy ] ); 11444 11445 this._updateVirtualBoundaries( event.shiftKey ); 11446 if ( this._aspectRatio || event.shiftKey ) { 11447 data = this._updateRatio( data, event ); 11448 } 11449 11450 data = this._respectSize( data, event ); 11451 11452 this._updateCache( data ); 11453 11454 this._propagate( "resize", event ); 11455 11456 props = this._applyChanges(); 11457 11458 if ( !this._helper && this._proportionallyResizeElements.length ) { 11459 this._proportionallyResize(); 11460 } 11461 11462 if ( !$.isEmptyObject( props ) ) { 11463 this._updatePrevProperties(); 11464 this._trigger( "resize", event, this.ui() ); 11465 this._applyChanges(); 11466 } 11467 11468 return false; 11469 }, 11470 11471 _mouseStop: function( event ) { 11472 11473 this.resizing = false; 11474 var pr, ista, soffseth, soffsetw, s, left, top, 11475 o = this.options, that = this; 11476 11477 if ( this._helper ) { 11478 11479 pr = this._proportionallyResizeElements; 11480 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 11481 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 11482 soffsetw = ista ? 0 : that.sizeDiff.width; 11483 11484 s = { 11485 width: ( that.helper.width() - soffsetw ), 11486 height: ( that.helper.height() - soffseth ) 11487 }; 11488 left = ( parseFloat( that.element.css( "left" ) ) + 11489 ( that.position.left - that.originalPosition.left ) ) || null; 11490 top = ( parseFloat( that.element.css( "top" ) ) + 11491 ( that.position.top - that.originalPosition.top ) ) || null; 11492 11493 if ( !o.animate ) { 11494 this.element.css( $.extend( s, { top: top, left: left } ) ); 11495 } 11496 11497 that.helper.height( that.size.height ); 11498 that.helper.width( that.size.width ); 11499 11500 if ( this._helper && !o.animate ) { 11501 this._proportionallyResize(); 11502 } 11503 } 11504 11505 $( "body" ).css( "cursor", "auto" ); 11506 11507 this._removeClass( "ui-resizable-resizing" ); 11508 11509 this._propagate( "stop", event ); 11510 11511 if ( this._helper ) { 11512 this.helper.remove(); 11513 } 11514 11515 return false; 11516 11517 }, 11518 11519 _updatePrevProperties: function() { 11520 this.prevPosition = { 11521 top: this.position.top, 11522 left: this.position.left 11523 }; 11524 this.prevSize = { 11525 width: this.size.width, 11526 height: this.size.height 11527 }; 11528 }, 11529 11530 _applyChanges: function() { 11531 var props = {}; 11532 11533 if ( this.position.top !== this.prevPosition.top ) { 11534 props.top = this.position.top + "px"; 11535 } 11536 if ( this.position.left !== this.prevPosition.left ) { 11537 props.left = this.position.left + "px"; 11538 }
vendor: 15,404 bytes, lines 11539-12131
11539 if ( this.size.width !== this.prevSize.width ) { 11540 props.width = this.size.width + "px"; 11541 } 11542 if ( this.size.height !== this.prevSize.height ) { 11543 props.height = this.size.height + "px"; 11544 } 11545 11546 this.helper.css( props ); 11547 11548 return props; 11549 }, 11550 11551 _updateVirtualBoundaries: function( forceAspectRatio ) { 11552 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 11553 o = this.options; 11554 11555 b = { 11556 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 11557 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 11558 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 11559 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 11560 }; 11561 11562 if ( this._aspectRatio || forceAspectRatio ) { 11563 pMinWidth = b.minHeight * this.aspectRatio; 11564 pMinHeight = b.minWidth / this.aspectRatio; 11565 pMaxWidth = b.maxHeight * this.aspectRatio; 11566 pMaxHeight = b.maxWidth / this.aspectRatio; 11567 11568 if ( pMinWidth > b.minWidth ) { 11569 b.minWidth = pMinWidth; 11570 } 11571 if ( pMinHeight > b.minHeight ) { 11572 b.minHeight = pMinHeight; 11573 } 11574 if ( pMaxWidth < b.maxWidth ) { 11575 b.maxWidth = pMaxWidth; 11576 } 11577 if ( pMaxHeight < b.maxHeight ) { 11578 b.maxHeight = pMaxHeight; 11579 } 11580 } 11581 this._vBoundaries = b; 11582 }, 11583 11584 _updateCache: function( data ) { 11585 this.offset = this.helper.offset(); 11586 if ( this._isNumber( data.left ) ) { 11587 this.position.left = data.left; 11588 } 11589 if ( this._isNumber( data.top ) ) { 11590 this.position.top = data.top; 11591 } 11592 if ( this._isNumber( data.height ) ) { 11593 this.size.height = data.height; 11594 } 11595 if ( this._isNumber( data.width ) ) { 11596 this.size.width = data.width; 11597 } 11598 }, 11599 11600 _updateRatio: function( data ) { 11601 11602 var cpos = this.position, 11603 csize = this.size, 11604 a = this.axis; 11605 11606 if ( this._isNumber( data.height ) ) { 11607 data.width = ( data.height * this.aspectRatio ); 11608 } else if ( this._isNumber( data.width ) ) { 11609 data.height = ( data.width / this.aspectRatio ); 11610 } 11611 11612 if ( a === "sw" ) { 11613 data.left = cpos.left + ( csize.width - data.width ); 11614 data.top = null; 11615 } 11616 if ( a === "nw" ) { 11617 data.top = cpos.top + ( csize.height - data.height ); 11618 data.left = cpos.left + ( csize.width - data.width ); 11619 } 11620 11621 return data; 11622 }, 11623 11624 _respectSize: function( data ) { 11625 11626 var o = this._vBoundaries, 11627 a = this.axis, 11628 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 11629 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 11630 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 11631 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 11632 dw = this.originalPosition.left + this.originalSize.width, 11633 dh = this.originalPosition.top + this.originalSize.height, 11634 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 11635 if ( isminw ) { 11636 data.width = o.minWidth; 11637 } 11638 if ( isminh ) { 11639 data.height = o.minHeight; 11640 } 11641 if ( ismaxw ) { 11642 data.width = o.maxWidth; 11643 } 11644 if ( ismaxh ) { 11645 data.height = o.maxHeight; 11646 } 11647 11648 if ( isminw && cw ) { 11649 data.left = dw - o.minWidth; 11650 } 11651 if ( ismaxw && cw ) { 11652 data.left = dw - o.maxWidth; 11653 } 11654 if ( isminh && ch ) { 11655 data.top = dh - o.minHeight; 11656 } 11657 if ( ismaxh && ch ) { 11658 data.top = dh - o.maxHeight; 11659 } 11660 11661 // Fixing jump error on top/left - bug #2330 11662 if ( !data.width && !data.height && !data.left && data.top ) { 11663 data.top = null; 11664 } else if ( !data.width && !data.height && !data.top && data.left ) { 11665 data.left = null; 11666 } 11667 11668 return data; 11669 }, 11670 11671 _getPaddingPlusBorderDimensions: function( element ) { 11672 var i = 0, 11673 widths = [], 11674 borders = [ 11675 element.css( "borderTopWidth" ), 11676 element.css( "borderRightWidth" ), 11677 element.css( "borderBottomWidth" ), 11678 element.css( "borderLeftWidth" ) 11679 ], 11680 paddings = [ 11681 element.css( "paddingTop" ), 11682 element.css( "paddingRight" ), 11683 element.css( "paddingBottom" ), 11684 element.css( "paddingLeft" ) 11685 ]; 11686 11687 for ( ; i < 4; i++ ) { 11688 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 11689 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 11690 } 11691 11692 return { 11693 height: widths[ 0 ] + widths[ 2 ], 11694 width: widths[ 1 ] + widths[ 3 ] 11695 }; 11696 }, 11697 11698 _proportionallyResize: function() { 11699 11700 if ( !this._proportionallyResizeElements.length ) { 11701 return; 11702 } 11703 11704 var prel, 11705 i = 0, 11706 element = this.helper || this.element; 11707 11708 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 11709 11710 prel = this._proportionallyResizeElements[ i ]; 11711 11712 // TODO: Seems like a bug to cache this.outerDimensions 11713 // considering that we are in a loop. 11714 if ( !this.outerDimensions ) { 11715 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 11716 } 11717 11718 prel.css( { 11719 height: ( element.height() - this.outerDimensions.height ) || 0, 11720 width: ( element.width() - this.outerDimensions.width ) || 0 11721 } ); 11722 11723 } 11724 11725 }, 11726 11727 _renderProxy: function() { 11728 11729 var el = this.element, o = this.options; 11730 this.elementOffset = el.offset(); 11731 11732 if ( this._helper ) { 11733 11734 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); 11735 11736 this._addClass( this.helper, this._helper ); 11737 this.helper.css( { 11738 width: this.element.outerWidth(), 11739 height: this.element.outerHeight(), 11740 position: "absolute", 11741 left: this.elementOffset.left + "px", 11742 top: this.elementOffset.top + "px", 11743 zIndex: ++o.zIndex //TODO: Don't modify option 11744 } ); 11745 11746 this.helper 11747 .appendTo( "body" ) 11748 .disableSelection(); 11749 11750 } else { 11751 this.helper = this.element; 11752 } 11753 11754 }, 11755 11756 _change: { 11757 e: function( event, dx ) { 11758 return { width: this.originalSize.width + dx }; 11759 }, 11760 w: function( event, dx ) { 11761 var cs = this.originalSize, sp = this.originalPosition; 11762 return { left: sp.left + dx, width: cs.width - dx }; 11763 }, 11764 n: function( event, dx, dy ) { 11765 var cs = this.originalSize, sp = this.originalPosition; 11766 return { top: sp.top + dy, height: cs.height - dy }; 11767 }, 11768 s: function( event, dx, dy ) { 11769 return { height: this.originalSize.height + dy }; 11770 }, 11771 se: function( event, dx, dy ) { 11772 return $.extend( this._change.s.apply( this, arguments ), 11773 this._change.e.apply( this, [ event, dx, dy ] ) ); 11774 }, 11775 sw: function( event, dx, dy ) { 11776 return $.extend( this._change.s.apply( this, arguments ), 11777 this._change.w.apply( this, [ event, dx, dy ] ) ); 11778 }, 11779 ne: function( event, dx, dy ) { 11780 return $.extend( this._change.n.apply( this, arguments ), 11781 this._change.e.apply( this, [ event, dx, dy ] ) ); 11782 }, 11783 nw: function( event, dx, dy ) { 11784 return $.extend( this._change.n.apply( this, arguments ), 11785 this._change.w.apply( this, [ event, dx, dy ] ) ); 11786 } 11787 }, 11788 11789 _propagate: function( n, event ) { 11790 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 11791 if ( n !== "resize" ) { 11792 this._trigger( n, event, this.ui() ); 11793 } 11794 }, 11795 11796 plugins: {}, 11797 11798 ui: function() { 11799 return { 11800 originalElement: this.originalElement, 11801 element: this.element, 11802 helper: this.helper, 11803 position: this.position, 11804 size: this.size, 11805 originalSize: this.originalSize, 11806 originalPosition: this.originalPosition 11807 }; 11808 } 11809 11810} ); 11811 11812/* 11813 * Resizable Extensions 11814 */ 11815 11816$.ui.plugin.add( "resizable", "animate", { 11817 11818 stop: function( event ) { 11819 var that = $( this ).resizable( "instance" ), 11820 o = that.options, 11821 pr = that._proportionallyResizeElements, 11822 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 11823 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 11824 soffsetw = ista ? 0 : that.sizeDiff.width, 11825 style = { 11826 width: ( that.size.width - soffsetw ), 11827 height: ( that.size.height - soffseth ) 11828 }, 11829 left = ( parseFloat( that.element.css( "left" ) ) + 11830 ( that.position.left - that.originalPosition.left ) ) || null, 11831 top = ( parseFloat( that.element.css( "top" ) ) + 11832 ( that.position.top - that.originalPosition.top ) ) || null; 11833 11834 that.element.animate( 11835 $.extend( style, top && left ? { top: top, left: left } : {} ), { 11836 duration: o.animateDuration, 11837 easing: o.animateEasing, 11838 step: function() { 11839 11840 var data = { 11841 width: parseFloat( that.element.css( "width" ) ), 11842 height: parseFloat( that.element.css( "height" ) ), 11843 top: parseFloat( that.element.css( "top" ) ), 11844 left: parseFloat( that.element.css( "left" ) ) 11845 }; 11846 11847 if ( pr && pr.length ) { 11848 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 11849 } 11850 11851 // Propagating resize, and updating values for each animation step 11852 that._updateCache( data ); 11853 that._propagate( "resize", event ); 11854 11855 } 11856 } 11857 ); 11858 } 11859 11860} ); 11861 11862$.ui.plugin.add( "resizable", "containment", { 11863 11864 start: function() { 11865 var element, p, co, ch, cw, width, height, 11866 that = $( this ).resizable( "instance" ), 11867 o = that.options, 11868 el = that.element, 11869 oc = o.containment, 11870 ce = ( oc instanceof $ ) ? 11871 oc.get( 0 ) : 11872 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 11873 11874 if ( !ce ) { 11875 return; 11876 } 11877 11878 that.containerElement = $( ce ); 11879 11880 if ( /document/.test( oc ) || oc === document ) { 11881 that.containerOffset = { 11882 left: 0, 11883 top: 0 11884 }; 11885 that.containerPosition = { 11886 left: 0, 11887 top: 0 11888 }; 11889 11890 that.parentData = { 11891 element: $( document ), 11892 left: 0, 11893 top: 0, 11894 width: $( document ).width(), 11895 height: $( document ).height() || document.body.parentNode.scrollHeight 11896 }; 11897 } else { 11898 element = $( ce ); 11899 p = []; 11900 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 11901 p[ i ] = that._num( element.css( "padding" + name ) ); 11902 } ); 11903 11904 that.containerOffset = element.offset(); 11905 that.containerPosition = element.position(); 11906 that.containerSize = { 11907 height: ( element.innerHeight() - p[ 3 ] ), 11908 width: ( element.innerWidth() - p[ 1 ] ) 11909 }; 11910 11911 co = that.containerOffset; 11912 ch = that.containerSize.height; 11913 cw = that.containerSize.width; 11914 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); 11915 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); 11916 11917 that.parentData = { 11918 element: ce, 11919 left: co.left, 11920 top: co.top, 11921 width: width, 11922 height: height 11923 }; 11924 } 11925 }, 11926 11927 resize: function( event ) { 11928 var woset, hoset, isParent, isOffsetRelative, 11929 that = $( this ).resizable( "instance" ), 11930 o = that.options, 11931 co = that.containerOffset, 11932 cp = that.position, 11933 pRatio = that._aspectRatio || event.shiftKey, 11934 cop = { 11935 top: 0, 11936 left: 0 11937 }, 11938 ce = that.containerElement, 11939 continueResize = true; 11940 11941 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 11942 cop = co; 11943 } 11944 11945 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 11946 that.size.width = that.size.width + 11947 ( that._helper ? 11948 ( that.position.left - co.left ) : 11949 ( that.position.left - cop.left ) ); 11950 11951 if ( pRatio ) { 11952 that.size.height = that.size.width / that.aspectRatio; 11953 continueResize = false; 11954 } 11955 that.position.left = o.helper ? co.left : 0; 11956 } 11957 11958 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 11959 that.size.height = that.size.height + 11960 ( that._helper ? 11961 ( that.position.top - co.top ) : 11962 that.position.top ); 11963 11964 if ( pRatio ) { 11965 that.size.width = that.size.height * that.aspectRatio; 11966 continueResize = false; 11967 } 11968 that.position.top = that._helper ? co.top : 0; 11969 } 11970 11971 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 11972 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 11973 11974 if ( isParent && isOffsetRelative ) { 11975 that.offset.left = that.parentData.left + that.position.left; 11976 that.offset.top = that.parentData.top + that.position.top; 11977 } else { 11978 that.offset.left = that.element.offset().left; 11979 that.offset.top = that.element.offset().top; 11980 } 11981 11982 woset = Math.abs( that.sizeDiff.width + 11983 ( that._helper ? 11984 that.offset.left - cop.left : 11985 ( that.offset.left - co.left ) ) ); 11986 11987 hoset = Math.abs( that.sizeDiff.height + 11988 ( that._helper ? 11989 that.offset.top - cop.top : 11990 ( that.offset.top - co.top ) ) ); 11991 11992 if ( woset + that.size.width >= that.parentData.width ) { 11993 that.size.width = that.parentData.width - woset; 11994 if ( pRatio ) { 11995 that.size.height = that.size.width / that.aspectRatio; 11996 continueResize = false; 11997 } 11998 } 11999 12000 if ( hoset + that.size.height >= that.parentData.height ) { 12001 that.size.height = that.parentData.height - hoset; 12002 if ( pRatio ) { 12003 that.size.width = that.size.height * that.aspectRatio; 12004 continueResize = false; 12005 } 12006 } 12007 12008 if ( !continueResize ) { 12009 that.position.left = that.prevPosition.left; 12010 that.position.top = that.prevPosition.top; 12011 that.size.width = that.prevSize.width; 12012 that.size.height = that.prevSize.height; 12013 } 12014 }, 12015 12016 stop: function() { 12017 var that = $( this ).resizable( "instance" ), 12018 o = that.options, 12019 co = that.containerOffset, 12020 cop = that.containerPosition, 12021 ce = that.containerElement, 12022 helper = $( that.helper ), 12023 ho = helper.offset(), 12024 w = helper.outerWidth() - that.sizeDiff.width, 12025 h = helper.outerHeight() - that.sizeDiff.height; 12026 12027 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 12028 $( this ).css( { 12029 left: ho.left - cop.left - co.left, 12030 width: w, 12031 height: h 12032 } ); 12033 } 12034 12035 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 12036 $( this ).css( { 12037 left: ho.left - cop.left - co.left, 12038 width: w, 12039 height: h 12040 } ); 12041 } 12042 } 12043} ); 12044 12045$.ui.plugin.add( "resizable", "alsoResize", { 12046 12047 start: function() { 12048 var that = $( this ).resizable( "instance" ), 12049 o = that.options; 12050 12051 $( o.alsoResize ).each( function() { 12052 var el = $( this ); 12053 el.data( "ui-resizable-alsoresize", { 12054 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 12055 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 12056 } ); 12057 } ); 12058 }, 12059 12060 resize: function( event, ui ) { 12061 var that = $( this ).resizable( "instance" ), 12062 o = that.options, 12063 os = that.originalSize, 12064 op = that.originalPosition, 12065 delta = { 12066 height: ( that.size.height - os.height ) || 0, 12067 width: ( that.size.width - os.width ) || 0, 12068 top: ( that.position.top - op.top ) || 0, 12069 left: ( that.position.left - op.left ) || 0 12070 }; 12071 12072 $( o.alsoResize ).each( function() { 12073 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 12074 css = el.parents( ui.originalElement[ 0 ] ).length ? 12075 [ "width", "height" ] : 12076 [ "width", "height", "top", "left" ]; 12077 12078 $.each( css, function( i, prop ) { 12079 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 12080 if ( sum && sum >= 0 ) { 12081 style[ prop ] = sum || null; 12082 } 12083 } ); 12084 12085 el.css( style ); 12086 } ); 12087 }, 12088 12089 stop: function() { 12090 $( this ).removeData( "ui-resizable-alsoresize" ); 12091 } 12092} ); 12093 12094$.ui.plugin.add( "resizable", "ghost", { 12095 12096 start: function() { 12097 12098 var that = $( this ).resizable( "instance" ), cs = that.size; 12099 12100 that.ghost = that.originalElement.clone(); 12101 that.ghost.css( { 12102 opacity: 0.25, 12103 display: "block", 12104 position: "relative", 12105 height: cs.height, 12106 width: cs.width, 12107 margin: 0, 12108 left: 0, 12109 top: 0 12110 } ); 12111 12112 that._addClass( that.ghost, "ui-resizable-ghost" ); 12113 12114 // DEPRECATED 12115 // TODO: remove after 1.12 12116 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 12117 12118 // Ghost option 12119 that.ghost.addClass( this.options.ghost ); 12120 } 12121 12122 that.ghost.appendTo( that.helper ); 12123 12124 }, 12125 12126 resize: function() { 12127 var that = $( this ).resizable( "instance" ); 12128 if ( that.ghost ) { 12129 that.ghost.css( { 12130 position: "relative", 12131 height: that.size.height,
vendor: 2,863 bytes, lines 12132-12243
12132 width: that.size.width 12133 } ); 12134 } 12135 }, 12136 12137 stop: function() { 12138 var that = $( this ).resizable( "instance" ); 12139 if ( that.ghost && that.helper ) { 12140 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 12141 } 12142 } 12143 12144} ); 12145 12146$.ui.plugin.add( "resizable", "grid", { 12147 12148 resize: function() { 12149 var outerDimensions, 12150 that = $( this ).resizable( "instance" ), 12151 o = that.options, 12152 cs = that.size, 12153 os = that.originalSize, 12154 op = that.originalPosition, 12155 a = that.axis, 12156 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 12157 gridX = ( grid[ 0 ] || 1 ), 12158 gridY = ( grid[ 1 ] || 1 ), 12159 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 12160 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 12161 newWidth = os.width + ox, 12162 newHeight = os.height + oy, 12163 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 12164 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 12165 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 12166 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 12167 12168 o.grid = grid; 12169 12170 if ( isMinWidth ) { 12171 newWidth += gridX; 12172 } 12173 if ( isMinHeight ) { 12174 newHeight += gridY; 12175 } 12176 if ( isMaxWidth ) { 12177 newWidth -= gridX; 12178 } 12179 if ( isMaxHeight ) { 12180 newHeight -= gridY; 12181 } 12182 12183 if ( /^(se|s|e)$/.test( a ) ) { 12184 that.size.width = newWidth; 12185 that.size.height = newHeight; 12186 } else if ( /^(ne)$/.test( a ) ) { 12187 that.size.width = newWidth; 12188 that.size.height = newHeight; 12189 that.position.top = op.top - oy; 12190 } else if ( /^(sw)$/.test( a ) ) { 12191 that.size.width = newWidth; 12192 that.size.height = newHeight; 12193 that.position.left = op.left - ox; 12194 } else { 12195 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 12196 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 12197 } 12198 12199 if ( newHeight - gridY > 0 ) { 12200 that.size.height = newHeight; 12201 that.position.top = op.top - oy; 12202 } else { 12203 newHeight = gridY - outerDimensions.height; 12204 that.size.height = newHeight; 12205 that.position.top = op.top + os.height - newHeight; 12206 } 12207 if ( newWidth - gridX > 0 ) { 12208 that.size.width = newWidth; 12209 that.position.left = op.left - ox; 12210 } else { 12211 newWidth = gridX - outerDimensions.width; 12212 that.size.width = newWidth; 12213 that.position.left = op.left + os.width - newWidth; 12214 } 12215 } 12216 } 12217 12218} ); 12219 12220var widgetsResizable = $.ui.resizable; 12221 12222 12223/*! 12224 * jQuery UI Dialog 1.13.2 12225 * http://jqueryui.com 12226 * 12227 * Copyright jQuery Foundation and other contributors 12228 * Released under the MIT license. 12229 * http://jquery.org/license 12230 */ 12231 12232//>>label: Dialog 12233//>>group: Widgets 12234//>>description: Displays customizable dialog windows. 12235//>>docs: http://api.jqueryui.com/dialog/ 12236//>>demos: http://jqueryui.com/dialog/ 12237//>>css.structure: ../../themes/base/core.css 12238//>>css.structure: ../../themes/base/dialog.css 12239//>>css.theme: ../../themes/base/theme.css 12240 12241 12242$.widget( "ui.dialog", { 12243 version: "1.13.2
vendor: 20,928 bytes, lines 12243-13077
12243", 12244 options: { 12245 appendTo: "body", 12246 autoOpen: true, 12247 buttons: [], 12248 classes: { 12249 "ui-dialog": "ui-corner-all", 12250 "ui-dialog-titlebar": "ui-corner-all" 12251 }, 12252 closeOnEscape: true, 12253 closeText: "Close", 12254 draggable: true, 12255 hide: null, 12256 height: "auto", 12257 maxHeight: null, 12258 maxWidth: null, 12259 minHeight: 150, 12260 minWidth: 150, 12261 modal: false, 12262 position: { 12263 my: "center", 12264 at: "center", 12265 of: window, 12266 collision: "fit", 12267 12268 // Ensure the titlebar is always visible 12269 using: function( pos ) { 12270 var topOffset = $( this ).css( pos ).offset().top; 12271 if ( topOffset < 0 ) { 12272 $( this ).css( "top", pos.top - topOffset ); 12273 } 12274 } 12275 }, 12276 resizable: true, 12277 show: null, 12278 title: null, 12279 width: 300, 12280 12281 // Callbacks 12282 beforeClose: null, 12283 close: null, 12284 drag: null, 12285 dragStart: null, 12286 dragStop: null, 12287 focus: null, 12288 open: null, 12289 resize: null, 12290 resizeStart: null, 12291 resizeStop: null 12292 }, 12293 12294 sizeRelatedOptions: { 12295 buttons: true, 12296 height: true, 12297 maxHeight: true, 12298 maxWidth: true, 12299 minHeight: true, 12300 minWidth: true, 12301 width: true 12302 }, 12303 12304 resizableRelatedOptions: { 12305 maxHeight: true, 12306 maxWidth: true, 12307 minHeight: true, 12308 minWidth: true 12309 }, 12310 12311 _create: function() { 12312 this.originalCss = { 12313 display: this.element[ 0 ].style.display, 12314 width: this.element[ 0 ].style.width, 12315 minHeight: this.element[ 0 ].style.minHeight, 12316 maxHeight: this.element[ 0 ].style.maxHeight, 12317 height: this.element[ 0 ].style.height 12318 }; 12319 this.originalPosition = { 12320 parent: this.element.parent(), 12321 index: this.element.parent().children().index( this.element ) 12322 }; 12323 this.originalTitle = this.element.attr( "title" ); 12324 if ( this.options.title == null && this.originalTitle != null ) { 12325 this.options.title = this.originalTitle; 12326 } 12327 12328 // Dialogs can't be disabled 12329 if ( this.options.disabled ) { 12330 this.options.disabled = false; 12331 } 12332 12333 this._createWrapper(); 12334 12335 this.element 12336 .show() 12337 .removeAttr( "title" ) 12338 .appendTo( this.uiDialog ); 12339 12340 this._addClass( "ui-dialog-content", "ui-widget-content" ); 12341 12342 this._createTitlebar(); 12343 this._createButtonPane(); 12344 12345 if ( this.options.draggable && $.fn.draggable ) { 12346 this._makeDraggable(); 12347 } 12348 if ( this.options.resizable && $.fn.resizable ) { 12349 this._makeResizable(); 12350 } 12351 12352 this._isOpen = false; 12353 12354 this._trackFocus(); 12355 }, 12356 12357 _init: function() { 12358 if ( this.options.autoOpen ) { 12359 this.open(); 12360 } 12361 }, 12362 12363 _appendTo: function() { 12364 var element = this.options.appendTo; 12365 if ( element && ( element.jquery || element.nodeType ) ) { 12366 return $( element ); 12367 } 12368 return this.document.find( element || "body" ).eq( 0 ); 12369 }, 12370 12371 _destroy: function() { 12372 var next, 12373 originalPosition = this.originalPosition; 12374 12375 this._untrackInstance(); 12376 this._destroyOverlay(); 12377 12378 this.element 12379 .removeUniqueId() 12380 .css( this.originalCss ) 12381 12382 // Without detaching first, the following becomes really slow 12383 .detach(); 12384 12385 this.uiDialog.remove(); 12386 12387 if ( this.originalTitle ) { 12388 this.element.attr( "title", this.originalTitle ); 12389 } 12390 12391 next = originalPosition.parent.children().eq( originalPosition.index ); 12392 12393 // Don't try to place the dialog next to itself (#8613) 12394 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 12395 next.before( this.element ); 12396 } else { 12397 originalPosition.parent.append( this.element ); 12398 } 12399 }, 12400 12401 widget: function() { 12402 return this.uiDialog; 12403 }, 12404 12405 disable: $.noop, 12406 enable: $.noop, 12407 12408 close: function( event ) { 12409 var that = this; 12410 12411 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 12412 return; 12413 } 12414 12415 this._isOpen = false; 12416 this._focusedElement = null; 12417 this._destroyOverlay(); 12418 this._untrackInstance(); 12419 12420 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 12421 12422 // Hiding a focused element doesn't trigger blur in WebKit 12423 // so in case we have nothing to focus on, explicitly blur the active element 12424 // https://bugs.webkit.org/show_bug.cgi?id=47182 12425 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); 12426 } 12427 12428 this._hide( this.uiDialog, this.options.hide, function() { 12429 that._trigger( "close", event ); 12430 } ); 12431 }, 12432 12433 isOpen: function() { 12434 return this._isOpen; 12435 }, 12436 12437 moveToTop: function() { 12438 this._moveToTop(); 12439 }, 12440 12441 _moveToTop: function( event, silent ) { 12442 var moved = false, 12443 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 12444 return +$( this ).css( "z-index" ); 12445 } ).get(), 12446 zIndexMax = Math.max.apply( null, zIndices ); 12447 12448 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 12449 this.uiDialog.css( "z-index", zIndexMax + 1 ); 12450 moved = true; 12451 } 12452 12453 if ( moved && !silent ) { 12454 this._trigger( "focus", event ); 12455 } 12456 return moved; 12457 }, 12458 12459 open: function() { 12460 var that = this; 12461 if ( this._isOpen ) { 12462 if ( this._moveToTop() ) { 12463 this._focusTabbable(); 12464 } 12465 return; 12466 } 12467 12468 this._isOpen = true; 12469 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 12470 12471 this._size(); 12472 this._position(); 12473 this._createOverlay(); 12474 this._moveToTop( null, true ); 12475 12476 // Ensure the overlay is moved to the top with the dialog, but only when 12477 // opening. The overlay shouldn't move after the dialog is open so that 12478 // modeless dialogs opened after the modal dialog stack properly. 12479 if ( this.overlay ) { 12480 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 12481 } 12482 12483 this._show( this.uiDialog, this.options.show, function() { 12484 that._focusTabbable(); 12485 that._trigger( "focus" ); 12486 } ); 12487 12488 // Track the dialog immediately upon opening in case a focus event 12489 // somehow occurs outside of the dialog before an element inside the 12490 // dialog is focused (#10152) 12491 this._makeFocusTarget(); 12492 12493 this._trigger( "open" ); 12494 }, 12495 12496 _focusTabbable: function() { 12497 12498 // Set focus to the first match: 12499 // 1. An element that was focused previously 12500 // 2. First element inside the dialog matching [autofocus] 12501 // 3. Tabbable element inside the content element 12502 // 4. Tabbable element inside the buttonpane 12503 // 5. The close button 12504 // 6. The dialog itself 12505 var hasFocus = this._focusedElement; 12506 if ( !hasFocus ) { 12507 hasFocus = this.element.find( "[autofocus]" ); 12508 } 12509 if ( !hasFocus.length ) { 12510 hasFocus = this.element.find( ":tabbable" ); 12511 } 12512 if ( !hasFocus.length ) { 12513 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 12514 } 12515 if ( !hasFocus.length ) { 12516 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 12517 } 12518 if ( !hasFocus.length ) { 12519 hasFocus = this.uiDialog; 12520 } 12521 hasFocus.eq( 0 ).trigger( "focus" ); 12522 }, 12523 12524 _restoreTabbableFocus: function() { 12525 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 12526 isActive = this.uiDialog[ 0 ] === activeElement || 12527 $.contains( this.uiDialog[ 0 ], activeElement ); 12528 if ( !isActive ) { 12529 this._focusTabbable(); 12530 } 12531 }, 12532 12533 _keepFocus: function( event ) { 12534 event.preventDefault(); 12535 this._restoreTabbableFocus(); 12536 12537 // support: IE 12538 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 12539 // so we check again later 12540 this._delay( this._restoreTabbableFocus ); 12541 }, 12542 12543 _createWrapper: function() { 12544 this.uiDialog = $( "<div>" ) 12545 .hide() 12546 .attr( { 12547 12548 // Setting tabIndex makes the div focusable 12549 tabIndex: -1, 12550 role: "dialog" 12551 } ) 12552 .appendTo( this._appendTo() ); 12553 12554 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 12555 this._on( this.uiDialog, { 12556 keydown: function( event ) { 12557 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 12558 event.keyCode === $.ui.keyCode.ESCAPE ) { 12559 event.preventDefault(); 12560 this.close( event ); 12561 return; 12562 } 12563 12564 // Prevent tabbing out of dialogs 12565 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 12566 return; 12567 } 12568 var tabbables = this.uiDialog.find( ":tabbable" ), 12569 first = tabbables.first(), 12570 last = tabbables.last(); 12571 12572 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 12573 !event.shiftKey ) { 12574 this._delay( function() { 12575 first.trigger( "focus" ); 12576 } ); 12577 event.preventDefault(); 12578 } else if ( ( event.target === first[ 0 ] || 12579 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 12580 this._delay( function() { 12581 last.trigger( "focus" ); 12582 } ); 12583 event.preventDefault(); 12584 } 12585 }, 12586 mousedown: function( event ) { 12587 if ( this._moveToTop( event ) ) { 12588 this._focusTabbable(); 12589 } 12590 } 12591 } ); 12592 12593 // We assume that any existing aria-describedby attribute means 12594 // that the dialog content is marked up properly 12595 // otherwise we brute force the content as the description 12596 if ( !this.element.find( "[aria-describedby]" ).length ) { 12597 this.uiDialog.attr( { 12598 "aria-describedby": this.element.uniqueId().attr( "id" ) 12599 } ); 12600 } 12601 }, 12602 12603 _createTitlebar: function() { 12604 var uiDialogTitle; 12605 12606 this.uiDialogTitlebar = $( "<div>" ); 12607 this._addClass( this.uiDialogTitlebar, 12608 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 12609 this._on( this.uiDialogTitlebar, { 12610 mousedown: function( event ) { 12611 12612 // Don't prevent click on close button (#8838) 12613 // Focusing a dialog that is partially scrolled out of view 12614 // causes the browser to scroll it into view, preventing the click event 12615 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 12616 12617 // Dialog isn't getting focus when dragging (#8063) 12618 this.uiDialog.trigger( "focus" ); 12619 } 12620 } 12621 } ); 12622 12623 // Support: IE 12624 // Use type="button" to prevent enter keypresses in textboxes from closing the 12625 // dialog in IE (#9312) 12626 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 12627 .button( { 12628 label: $( "<a>" ).text( this.options.closeText ).html(), 12629 icon: "ui-icon-closethick", 12630 showLabel: false 12631 } ) 12632 .appendTo( this.uiDialogTitlebar ); 12633 12634 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 12635 this._on( this.uiDialogTitlebarClose, { 12636 click: function( event ) { 12637 event.preventDefault(); 12638 this.close( event ); 12639 } 12640 } ); 12641 12642 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); 12643 this._addClass( uiDialogTitle, "ui-dialog-title" ); 12644 this._title( uiDialogTitle ); 12645 12646 this.uiDialogTitlebar.prependTo( this.uiDialog ); 12647 12648 this.uiDialog.attr( { 12649 "aria-labelledby": uiDialogTitle.attr( "id" ) 12650 } ); 12651 }, 12652 12653 _title: function( title ) { 12654 if ( this.options.title ) { 12655 title.text( this.options.title ); 12656 } else { 12657 title.html( " " ); 12658 } 12659 }, 12660 12661 _createButtonPane: function() { 12662 this.uiDialogButtonPane = $( "<div>" ); 12663 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 12664 "ui-widget-content ui-helper-clearfix" ); 12665 12666 this.uiButtonSet = $( "<div>" ) 12667 .appendTo( this.uiDialogButtonPane ); 12668 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 12669 12670 this._createButtons(); 12671 }, 12672 12673 _createButtons: function() { 12674 var that = this, 12675 buttons = this.options.buttons; 12676 12677 // If we already have a button pane, remove it 12678 this.uiDialogButtonPane.remove(); 12679 this.uiButtonSet.empty(); 12680 12681 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { 12682 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 12683 return; 12684 } 12685 12686 $.each( buttons, function( name, props ) { 12687 var click, buttonOptions; 12688 props = typeof props === "function" ? 12689 { click: props, text: name } : 12690 props; 12691 12692 // Default to a non-submitting button 12693 props = $.extend( { type: "button" }, props ); 12694 12695 // Change the context for the click callback to be the main element 12696 click = props.click; 12697 buttonOptions = { 12698 icon: props.icon, 12699 iconPosition: props.iconPosition, 12700 showLabel: props.showLabel, 12701 12702 // Deprecated options 12703 icons: props.icons, 12704 text: props.text 12705 }; 12706 12707 delete props.click; 12708 delete props.icon; 12709 delete props.iconPosition; 12710 delete props.showLabel; 12711 12712 // Deprecated options 12713 delete props.icons; 12714 if ( typeof props.text === "boolean" ) { 12715 delete props.text; 12716 } 12717 12718 $( "<button></button>", props ) 12719 .button( buttonOptions ) 12720 .appendTo( that.uiButtonSet ) 12721 .on( "click", function() { 12722 click.apply( that.element[ 0 ], arguments ); 12723 } ); 12724 } ); 12725 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 12726 this.uiDialogButtonPane.appendTo( this.uiDialog ); 12727 }, 12728 12729 _makeDraggable: function() { 12730 var that = this, 12731 options = this.options; 12732 12733 function filteredUi( ui ) { 12734 return { 12735 position: ui.position, 12736 offset: ui.offset 12737 }; 12738 } 12739 12740 this.uiDialog.draggable( { 12741 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 12742 handle: ".ui-dialog-titlebar", 12743 containment: "document", 12744 start: function( event, ui ) { 12745 that._addClass( $( this ), "ui-dialog-dragging" ); 12746 that._blockFrames(); 12747 that._trigger( "dragStart", event, filteredUi( ui ) ); 12748 }, 12749 drag: function( event, ui ) { 12750 that._trigger( "drag", event, filteredUi( ui ) ); 12751 }, 12752 stop: function( event, ui ) { 12753 var left = ui.offset.left - that.document.scrollLeft(), 12754 top = ui.offset.top - that.document.scrollTop(); 12755 12756 options.position = { 12757 my: "left top", 12758 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12759 "top" + ( top >= 0 ? "+" : "" ) + top, 12760 of: that.window 12761 }; 12762 that._removeClass( $( this ), "ui-dialog-dragging" ); 12763 that._unblockFrames(); 12764 that._trigger( "dragStop", event, filteredUi( ui ) ); 12765 } 12766 } ); 12767 }, 12768 12769 _makeResizable: function() { 12770 var that = this, 12771 options = this.options, 12772 handles = options.resizable, 12773 12774 // .ui-resizable has position: relative defined in the stylesheet 12775 // but dialogs have to use absolute or fixed positioning 12776 position = this.uiDialog.css( "position" ), 12777 resizeHandles = typeof handles === "string" ? 12778 handles : 12779 "n,e,s,w,se,sw,ne,nw"; 12780 12781 function filteredUi( ui ) { 12782 return { 12783 originalPosition: ui.originalPosition, 12784 originalSize: ui.originalSize, 12785 position: ui.position, 12786 size: ui.size 12787 }; 12788 } 12789 12790 this.uiDialog.resizable( { 12791 cancel: ".ui-dialog-content", 12792 containment: "document", 12793 alsoResize: this.element, 12794 maxWidth: options.maxWidth, 12795 maxHeight: options.maxHeight, 12796 minWidth: options.minWidth, 12797 minHeight: this._minHeight(), 12798 handles: resizeHandles, 12799 start: function( event, ui ) { 12800 that._addClass( $( this ), "ui-dialog-resizing" ); 12801 that._blockFrames(); 12802 that._trigger( "resizeStart", event, filteredUi( ui ) ); 12803 }, 12804 resize: function( event, ui ) { 12805 that._trigger( "resize", event, filteredUi( ui ) ); 12806 }, 12807 stop: function( event, ui ) { 12808 var offset = that.uiDialog.offset(), 12809 left = offset.left - that.document.scrollLeft(), 12810 top = offset.top - that.document.scrollTop(); 12811 12812 options.height = that.uiDialog.height(); 12813 options.width = that.uiDialog.width(); 12814 options.position = { 12815 my: "left top", 12816 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12817 "top" + ( top >= 0 ? "+" : "" ) + top, 12818 of: that.window 12819 }; 12820 that._removeClass( $( this ), "ui-dialog-resizing" ); 12821 that._unblockFrames(); 12822 that._trigger( "resizeStop", event, filteredUi( ui ) ); 12823 } 12824 } ) 12825 .css( "position", position ); 12826 }, 12827 12828 _trackFocus: function() { 12829 this._on( this.widget(), { 12830 focusin: function( event ) { 12831 this._makeFocusTarget(); 12832 this._focusedElement = $( event.target ); 12833 } 12834 } ); 12835 }, 12836 12837 _makeFocusTarget: function() { 12838 this._untrackInstance(); 12839 this._trackingInstances().unshift( this ); 12840 }, 12841 12842 _untrackInstance: function() { 12843 var instances = this._trackingInstances(), 12844 exists = $.inArray( this, instances ); 12845 if ( exists !== -1 ) { 12846 instances.splice( exists, 1 ); 12847 } 12848 }, 12849 12850 _trackingInstances: function() { 12851 var instances = this.document.data( "ui-dialog-instances" ); 12852 if ( !instances ) { 12853 instances = []; 12854 this.document.data( "ui-dialog-instances", instances ); 12855 } 12856 return instances; 12857 }, 12858 12859 _minHeight: function() { 12860 var options = this.options; 12861 12862 return options.height === "auto" ? 12863 options.minHeight : 12864 Math.min( options.minHeight, options.height ); 12865 }, 12866 12867 _position: function() { 12868 12869 // Need to show the dialog to get the actual offset in the position plugin 12870 var isVisible = this.uiDialog.is( ":visible" ); 12871 if ( !isVisible ) { 12872 this.uiDialog.show(); 12873 } 12874 this.uiDialog.position( this.options.position ); 12875 if ( !isVisible ) { 12876 this.uiDialog.hide(); 12877 } 12878 }, 12879 12880 _setOptions: function( options ) { 12881 var that = this, 12882 resize = false, 12883 resizableOptions = {}; 12884 12885 $.each( options, function( key, value ) { 12886 that._setOption( key, value ); 12887 12888 if ( key in that.sizeRelatedOptions ) { 12889 resize = true; 12890 } 12891 if ( key in that.resizableRelatedOptions ) { 12892 resizableOptions[ key ] = value; 12893 } 12894 } ); 12895 12896 if ( resize ) { 12897 this._size(); 12898 this._position(); 12899 } 12900 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 12901 this.uiDialog.resizable( "option", resizableOptions ); 12902 } 12903 }, 12904 12905 _setOption: function( key, value ) { 12906 var isDraggable, isResizable, 12907 uiDialog = this.uiDialog; 12908 12909 if ( key === "disabled" ) { 12910 return; 12911 } 12912 12913 this._super( key, value ); 12914 12915 if ( key === "appendTo" ) { 12916 this.uiDialog.appendTo( this._appendTo() ); 12917 } 12918 12919 if ( key === "buttons" ) { 12920 this._createButtons(); 12921 } 12922 12923 if ( key === "closeText" ) { 12924 this.uiDialogTitlebarClose.button( { 12925 12926 // Ensure that we always pass a string 12927 label: $( "<a>" ).text( "" + this.options.closeText ).html() 12928 } ); 12929 } 12930 12931 if ( key === "draggable" ) { 12932 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 12933 if ( isDraggable && !value ) { 12934 uiDialog.draggable( "destroy" ); 12935 } 12936 12937 if ( !isDraggable && value ) { 12938 this._makeDraggable(); 12939 } 12940 } 12941 12942 if ( key === "position" ) { 12943 this._position(); 12944 } 12945 12946 if ( key === "resizable" ) { 12947 12948 // currently resizable, becoming non-resizable 12949 isResizable = uiDialog.is( ":data(ui-resizable)" ); 12950 if ( isResizable && !value ) { 12951 uiDialog.resizable( "destroy" ); 12952 } 12953 12954 // Currently resizable, changing handles 12955 if ( isResizable && typeof value === "string" ) { 12956 uiDialog.resizable( "option", "handles", value ); 12957 } 12958 12959 // Currently non-resizable, becoming resizable 12960 if ( !isResizable && value !== false ) { 12961 this._makeResizable(); 12962 } 12963 } 12964 12965 if ( key === "title" ) { 12966 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 12967 } 12968 }, 12969 12970 _size: function() { 12971 12972 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 12973 // divs will both have width and height set, so we need to reset them 12974 var nonContentHeight, minContentHeight, maxContentHeight, 12975 options = this.options; 12976 12977 // Reset content sizing 12978 this.element.show().css( { 12979 width: "auto", 12980 minHeight: 0, 12981 maxHeight: "none", 12982 height: 0 12983 } ); 12984 12985 if ( options.minWidth > options.width ) { 12986 options.width = options.minWidth; 12987 } 12988 12989 // Reset wrapper sizing 12990 // determine the height of all the non-content elements 12991 nonContentHeight = this.uiDialog.css( { 12992 height: "auto", 12993 width: options.width 12994 } ) 12995 .outerHeight(); 12996 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 12997 maxContentHeight = typeof options.maxHeight === "number" ? 12998 Math.max( 0, options.maxHeight - nonContentHeight ) : 12999 "none"; 13000 13001 if ( options.height === "auto" ) { 13002 this.element.css( { 13003 minHeight: minContentHeight, 13004 maxHeight: maxContentHeight, 13005 height: "auto" 13006 } ); 13007 } else { 13008 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 13009 } 13010 13011 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 13012 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 13013 } 13014 }, 13015 13016 _blockFrames: function() { 13017 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 13018 var iframe = $( this ); 13019 13020 return $( "<div>" ) 13021 .css( { 13022 position: "absolute", 13023 width: iframe.outerWidth(), 13024 height: iframe.outerHeight() 13025 } ) 13026 .appendTo( iframe.parent() ) 13027 .offset( iframe.offset() )[ 0 ]; 13028 } ); 13029 }, 13030 13031 _unblockFrames: function() { 13032 if ( this.iframeBlocks ) { 13033 this.iframeBlocks.remove(); 13034 delete this.iframeBlocks; 13035 } 13036 }, 13037 13038 _allowInteraction: function( event ) { 13039 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 13040 return true; 13041 } 13042 13043 // TODO: Remove hack when datepicker implements 13044 // the .ui-front logic (#8989) 13045 return !!$( event.target ).closest( ".ui-datepicker" ).length; 13046 }, 13047 13048 _createOverlay: function() { 13049 if ( !this.options.modal ) { 13050 return; 13051 } 13052 13053 var jqMinor = $.fn.jquery.substring( 0, 4 ); 13054 13055 // We use a delay in case the overlay is created from an 13056 // event that we're going to be cancelling (#2804) 13057 var isOpening = true; 13058 this._delay( function() { 13059 isOpening = false; 13060 } ); 13061 13062 if ( !this.document.data( "ui-dialog-overlays" ) ) { 13063 13064 // Prevent use of anchors and inputs 13065 // This doesn't use `_on()` because it is a shared event handler 13066 // across all open modal dialogs. 13067 this.document.on( "focusin.ui-dialog", function( event ) { 13068 if ( isOpening ) { 13069 return; 13070 } 13071 13072 var instance = this._trackingInstances()[ 0 ]; 13073 if ( !instance._allowInteraction( event ) ) { 13074 event.preventDefault(); 13075 instance._focusTabbable(); 13076 13077 // Support: jQuery >=3.4 <3.
vendor: 2,204 bytes, lines 13077-13165
130776 only 13078 // Focus re-triggering in jQuery 3.4/3.5 makes the original element 13079 // have its focus event propagated last, breaking the re-targeting. 13080 // Trigger focus in a delay in addition if needed to avoid the issue 13081 // See https://github.com/jquery/jquery/issues/4382 13082 if ( jqMinor === "3.4." || jqMinor === "3.5." ) { 13083 instance._delay( instance._restoreTabbableFocus ); 13084 } 13085 } 13086 }.bind( this ) ); 13087 } 13088 13089 this.overlay = $( "<div>" ) 13090 .appendTo( this._appendTo() ); 13091 13092 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 13093 this._on( this.overlay, { 13094 mousedown: "_keepFocus" 13095 } ); 13096 this.document.data( "ui-dialog-overlays", 13097 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 13098 }, 13099 13100 _destroyOverlay: function() { 13101 if ( !this.options.modal ) { 13102 return; 13103 } 13104 13105 if ( this.overlay ) { 13106 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 13107 13108 if ( !overlays ) { 13109 this.document.off( "focusin.ui-dialog" ); 13110 this.document.removeData( "ui-dialog-overlays" ); 13111 } else { 13112 this.document.data( "ui-dialog-overlays", overlays ); 13113 } 13114 13115 this.overlay.remove(); 13116 this.overlay = null; 13117 } 13118 } 13119} ); 13120 13121// DEPRECATED 13122// TODO: switch return back to widget declaration at top of file when this is removed 13123if ( $.uiBackCompat !== false ) { 13124 13125 // Backcompat for dialogClass option 13126 $.widget( "ui.dialog", $.ui.dialog, { 13127 options: { 13128 dialogClass: "" 13129 }, 13130 _createWrapper: function() { 13131 this._super(); 13132 this.uiDialog.addClass( this.options.dialogClass ); 13133 }, 13134 _setOption: function( key, value ) { 13135 if ( key === "dialogClass" ) { 13136 this.uiDialog 13137 .removeClass( this.options.dialogClass ) 13138 .addClass( value ); 13139 } 13140 this._superApply( arguments ); 13141 } 13142 } ); 13143} 13144 13145var widgetsDialog = $.ui.dialog; 13146 13147 13148/*! 13149 * jQuery UI Droppable 1.13.2 13150 * http://jqueryui.com 13151 * 13152 * Copyright jQuery Foundation and other contributors 13153 * Released under the MIT license. 13154 * http://jquery.org/license 13155 */ 13156 13157//>>label: Droppable 13158//>>group: Interactions 13159//>>description: Enables drop targets for draggable elements. 13160//>>docs: http://api.jqueryui.com/droppable/ 13161//>>demos: http://jqueryui.com/droppable/ 13162 13163 13164$.widget( "ui.droppable", { 13165 version: "1.13.2
vendor: 12,184 bytes, lines 13165-13632
13165", 13166 widgetEventPrefix: "drop", 13167 options: { 13168 accept: "*", 13169 addClasses: true, 13170 greedy: false, 13171 scope: "default", 13172 tolerance: "intersect", 13173 13174 // Callbacks 13175 activate: null, 13176 deactivate: null, 13177 drop: null, 13178 out: null, 13179 over: null 13180 }, 13181 _create: function() { 13182 13183 var proportions, 13184 o = this.options, 13185 accept = o.accept; 13186 13187 this.isover = false; 13188 this.isout = true; 13189 13190 this.accept = typeof accept === "function" ? accept : function( d ) { 13191 return d.is( accept ); 13192 }; 13193 13194 this.proportions = function( /* valueToWrite */ ) { 13195 if ( arguments.length ) { 13196 13197 // Store the droppable's proportions 13198 proportions = arguments[ 0 ]; 13199 } else { 13200 13201 // Retrieve or derive the droppable's proportions 13202 return proportions ? 13203 proportions : 13204 proportions = { 13205 width: this.element[ 0 ].offsetWidth, 13206 height: this.element[ 0 ].offsetHeight 13207 }; 13208 } 13209 }; 13210 13211 this._addToManager( o.scope ); 13212 13213 if ( o.addClasses ) { 13214 this._addClass( "ui-droppable" ); 13215 } 13216 13217 }, 13218 13219 _addToManager: function( scope ) { 13220 13221 // Add the reference and positions to the manager 13222 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 13223 $.ui.ddmanager.droppables[ scope ].push( this ); 13224 }, 13225 13226 _splice: function( drop ) { 13227 var i = 0; 13228 for ( ; i < drop.length; i++ ) { 13229 if ( drop[ i ] === this ) { 13230 drop.splice( i, 1 ); 13231 } 13232 } 13233 }, 13234 13235 _destroy: function() { 13236 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 13237 13238 this._splice( drop ); 13239 }, 13240 13241 _setOption: function( key, value ) { 13242 13243 if ( key === "accept" ) { 13244 this.accept = typeof value === "function" ? value : function( d ) { 13245 return d.is( value ); 13246 }; 13247 } else if ( key === "scope" ) { 13248 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 13249 13250 this._splice( drop ); 13251 this._addToManager( value ); 13252 } 13253 13254 this._super( key, value ); 13255 }, 13256 13257 _activate: function( event ) { 13258 var draggable = $.ui.ddmanager.current; 13259 13260 this._addActiveClass(); 13261 if ( draggable ) { 13262 this._trigger( "activate", event, this.ui( draggable ) ); 13263 } 13264 }, 13265 13266 _deactivate: function( event ) { 13267 var draggable = $.ui.ddmanager.current; 13268 13269 this._removeActiveClass(); 13270 if ( draggable ) { 13271 this._trigger( "deactivate", event, this.ui( draggable ) ); 13272 } 13273 }, 13274 13275 _over: function( event ) { 13276 13277 var draggable = $.ui.ddmanager.current; 13278 13279 // Bail if draggable and droppable are same element 13280 if ( !draggable || ( draggable.currentItem || 13281 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13282 return; 13283 } 13284 13285 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 13286 draggable.element ) ) ) { 13287 this._addHoverClass(); 13288 this._trigger( "over", event, this.ui( draggable ) ); 13289 } 13290 13291 }, 13292 13293 _out: function( event ) { 13294 13295 var draggable = $.ui.ddmanager.current; 13296 13297 // Bail if draggable and droppable are same element 13298 if ( !draggable || ( draggable.currentItem || 13299 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13300 return; 13301 } 13302 13303 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 13304 draggable.element ) ) ) { 13305 this._removeHoverClass(); 13306 this._trigger( "out", event, this.ui( draggable ) ); 13307 } 13308 13309 }, 13310 13311 _drop: function( event, custom ) { 13312 13313 var draggable = custom || $.ui.ddmanager.current, 13314 childrenIntersection = false; 13315 13316 // Bail if draggable and droppable are same element 13317 if ( !draggable || ( draggable.currentItem || 13318 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13319 return false; 13320 } 13321 13322 this.element 13323 .find( ":data(ui-droppable)" ) 13324 .not( ".ui-draggable-dragging" ) 13325 .each( function() { 13326 var inst = $( this ).droppable( "instance" ); 13327 if ( 13328 inst.options.greedy && 13329 !inst.options.disabled && 13330 inst.options.scope === draggable.options.scope && 13331 inst.accept.call( 13332 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 13333 ) && 13334 $.ui.intersect( 13335 draggable, 13336 $.extend( inst, { offset: inst.element.offset() } ), 13337 inst.options.tolerance, event 13338 ) 13339 ) { 13340 childrenIntersection = true; 13341 return false; 13342 } 13343 } ); 13344 if ( childrenIntersection ) { 13345 return false; 13346 } 13347 13348 if ( this.accept.call( this.element[ 0 ], 13349 ( draggable.currentItem || draggable.element ) ) ) { 13350 this._removeActiveClass(); 13351 this._removeHoverClass(); 13352 13353 this._trigger( "drop", event, this.ui( draggable ) ); 13354 return this.element; 13355 } 13356 13357 return false; 13358 13359 }, 13360 13361 ui: function( c ) { 13362 return { 13363 draggable: ( c.currentItem || c.element ), 13364 helper: c.helper, 13365 position: c.position, 13366 offset: c.positionAbs 13367 }; 13368 }, 13369 13370 // Extension points just to make backcompat sane and avoid duplicating logic 13371 // TODO: Remove in 1.14 along with call to it below 13372 _addHoverClass: function() { 13373 this._addClass( "ui-droppable-hover" ); 13374 }, 13375 13376 _removeHoverClass: function() { 13377 this._removeClass( "ui-droppable-hover" ); 13378 }, 13379 13380 _addActiveClass: function() { 13381 this._addClass( "ui-droppable-active" ); 13382 }, 13383 13384 _removeActiveClass: function() { 13385 this._removeClass( "ui-droppable-active" ); 13386 } 13387} ); 13388 13389$.ui.intersect = ( function() { 13390 function isOverAxis( x, reference, size ) { 13391 return ( x >= reference ) && ( x < ( reference + size ) ); 13392 } 13393 13394 return function( draggable, droppable, toleranceMode, event ) { 13395 13396 if ( !droppable.offset ) { 13397 return false; 13398 } 13399 13400 var x1 = ( draggable.positionAbs || 13401 draggable.position.absolute ).left + draggable.margins.left, 13402 y1 = ( draggable.positionAbs || 13403 draggable.position.absolute ).top + draggable.margins.top, 13404 x2 = x1 + draggable.helperProportions.width, 13405 y2 = y1 + draggable.helperProportions.height, 13406 l = droppable.offset.left, 13407 t = droppable.offset.top, 13408 r = l + droppable.proportions().width, 13409 b = t + droppable.proportions().height; 13410 13411 switch ( toleranceMode ) { 13412 case "fit": 13413 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 13414 case "intersect": 13415 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 13416 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 13417 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 13418 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 13419 case "pointer": 13420 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 13421 isOverAxis( event.pageX, l, droppable.proportions().width ); 13422 case "touch": 13423 return ( 13424 ( y1 >= t && y1 <= b ) || // Top edge touching 13425 ( y2 >= t && y2 <= b ) || // Bottom edge touching 13426 ( y1 < t && y2 > b ) // Surrounded vertically 13427 ) && ( 13428 ( x1 >= l && x1 <= r ) || // Left edge touching 13429 ( x2 >= l && x2 <= r ) || // Right edge touching 13430 ( x1 < l && x2 > r ) // Surrounded horizontally 13431 ); 13432 default: 13433 return false; 13434 } 13435 }; 13436} )(); 13437 13438/* 13439 This manager tracks offsets of draggables and droppables 13440*/ 13441$.ui.ddmanager = { 13442 current: null, 13443 droppables: { "default": [] }, 13444 prepareOffsets: function( t, event ) { 13445 13446 var i, j, 13447 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 13448 type = event ? event.type : null, // workaround for #2317 13449 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 13450 13451 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 13452 13453 // No disabled and non-accepted 13454 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 13455 ( t.currentItem || t.element ) ) ) ) { 13456 continue; 13457 } 13458 13459 // Filter out elements in the current dragged item 13460 for ( j = 0; j < list.length; j++ ) { 13461 if ( list[ j ] === m[ i ].element[ 0 ] ) { 13462 m[ i ].proportions().height = 0; 13463 continue droppablesLoop; 13464 } 13465 } 13466 13467 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 13468 if ( !m[ i ].visible ) { 13469 continue; 13470 } 13471 13472 // Activate the droppable if used directly from draggables 13473 if ( type === "mousedown" ) { 13474 m[ i ]._activate.call( m[ i ], event ); 13475 } 13476 13477 m[ i ].offset = m[ i ].element.offset(); 13478 m[ i ].proportions( { 13479 width: m[ i ].element[ 0 ].offsetWidth, 13480 height: m[ i ].element[ 0 ].offsetHeight 13481 } ); 13482 13483 } 13484 13485 }, 13486 drop: function( draggable, event ) { 13487 13488 var dropped = false; 13489 13490 // Create a copy of the droppables in case the list changes during the drop (#9116) 13491 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 13492 13493 if ( !this.options ) { 13494 return; 13495 } 13496 if ( !this.options.disabled && this.visible && 13497 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 13498 dropped = this._drop.call( this, event ) || dropped; 13499 } 13500 13501 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 13502 ( draggable.currentItem || draggable.element ) ) ) { 13503 this.isout = true; 13504 this.isover = false; 13505 this._deactivate.call( this, event ); 13506 } 13507 13508 } ); 13509 return dropped; 13510 13511 }, 13512 dragStart: function( draggable, event ) { 13513 13514 // Listen for scrolling so that if the dragging causes scrolling the position of the 13515 // droppables can be recalculated (see #5003) 13516 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 13517 if ( !draggable.options.refreshPositions ) { 13518 $.ui.ddmanager.prepareOffsets( draggable, event ); 13519 } 13520 } ); 13521 }, 13522 drag: function( draggable, event ) { 13523 13524 // If you have a highly dynamic page, you might try this option. It renders positions 13525 // every time you move the mouse. 13526 if ( draggable.options.refreshPositions ) { 13527 $.ui.ddmanager.prepareOffsets( draggable, event ); 13528 } 13529 13530 // Run through all droppables and check their positions based on specific tolerance options 13531 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 13532 13533 if ( this.options.disabled || this.greedyChild || !this.visible ) { 13534 return; 13535 } 13536 13537 var parentInstance, scope, parent, 13538 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 13539 c = !intersects && this.isover ? 13540 "isout" : 13541 ( intersects && !this.isover ? "isover" : null ); 13542 if ( !c ) { 13543 return; 13544 } 13545 13546 if ( this.options.greedy ) { 13547 13548 // find droppable parents with same scope 13549 scope = this.options.scope; 13550 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 13551 return $( this ).droppable( "instance" ).options.scope === scope; 13552 } ); 13553 13554 if ( parent.length ) { 13555 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 13556 parentInstance.greedyChild = ( c === "isover" ); 13557 } 13558 } 13559 13560 // We just moved into a greedy child 13561 if ( parentInstance && c === "isover" ) { 13562 parentInstance.isover = false; 13563 parentInstance.isout = true; 13564 parentInstance._out.call( parentInstance, event ); 13565 } 13566 13567 this[ c ] = true; 13568 this[ c === "isout" ? "isover" : "isout" ] = false; 13569 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 13570 13571 // We just moved out of a greedy child 13572 if ( parentInstance && c === "isout" ) { 13573 parentInstance.isout = false; 13574 parentInstance.isover = true; 13575 parentInstance._over.call( parentInstance, event ); 13576 } 13577 } ); 13578 13579 }, 13580 dragStop: function( draggable, event ) { 13581 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 13582 13583 // Call prepareOffsets one final time since IE does not fire return scroll events when 13584 // overflow was caused by drag (see #5003) 13585 if ( !draggable.options.refreshPositions ) { 13586 $.ui.ddmanager.prepareOffsets( draggable, event ); 13587 } 13588 } 13589}; 13590 13591// DEPRECATED 13592// TODO: switch return back to widget declaration at top of file when this is removed 13593if ( $.uiBackCompat !== false ) { 13594 13595 // Backcompat for activeClass and hoverClass options 13596 $.widget( "ui.droppable", $.ui.droppable, { 13597 options: { 13598 hoverClass: false, 13599 activeClass: false 13600 }, 13601 _addActiveClass: function() { 13602 this._super(); 13603 if ( this.options.activeClass ) { 13604 this.element.addClass( this.options.activeClass ); 13605 } 13606 }, 13607 _removeActiveClass: function() { 13608 this._super(); 13609 if ( this.options.activeClass ) { 13610 this.element.removeClass( this.options.activeClass ); 13611 } 13612 }, 13613 _addHoverClass: function() { 13614 this._super(); 13615 if ( this.options.hoverClass ) { 13616 this.element.addClass( this.options.hoverClass ); 13617 } 13618 }, 13619 _removeHoverClass: function() { 13620 this._super(); 13621 if ( this.options.hoverClass ) { 13622 this.element.removeClass( this.options.hoverClass ); 13623 } 13624 } 13625 } ); 13626} 13627 13628var widgetsDroppable = $.ui.droppable; 13629 13630 13631/*! 13632 * jQuery UI Progressbar 1.13.
136322 13633 * http://jqueryui.com 13634 * 13635 * Copyright jQuery Foundation and other contributors 13636 * Released under the MIT license. 13637 * http://jquery.org/license 13638 */ 13639 13640//>>label: Progressbar 13641//>>group: Widgets 13642/* eslint-disable max-len */ 13643//>>
vendor: 4,217 bytes, lines 13643-13812
13643description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 13644/* eslint-enable max-len */ 13645//>>docs: http://api.jqueryui.com/progressbar/ 13646//>>demos: http://jqueryui.com/progressbar/ 13647//>>css.structure: ../../themes/base/core.css 13648//>>css.structure: ../../themes/base/progressbar.css 13649//>>css.theme: ../../themes/base/theme.css 13650 13651 13652var widgetsProgressbar = $.widget( "ui.progressbar", { 13653 version: "1.13.2", 13654 options: { 13655 classes: { 13656 "ui-progressbar": "ui-corner-all", 13657 "ui-progressbar-value": "ui-corner-left", 13658 "ui-progressbar-complete": "ui-corner-right" 13659 }, 13660 max: 100, 13661 value: 0, 13662 13663 change: null, 13664 complete: null 13665 }, 13666 13667 min: 0, 13668 13669 _create: function() { 13670 13671 // Constrain initial value 13672 this.oldValue = this.options.value = this._constrainedValue(); 13673 13674 this.element.attr( { 13675 13676 // Only set static values; aria-valuenow and aria-valuemax are 13677 // set inside _refreshValue() 13678 role: "progressbar", 13679 "aria-valuemin": this.min 13680 } ); 13681 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 13682 13683 this.valueDiv = $( "<div>" ).appendTo( this.element ); 13684 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 13685 this._refreshValue(); 13686 }, 13687 13688 _destroy: function() { 13689 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 13690 13691 this.valueDiv.remove(); 13692 }, 13693 13694 value: function( newValue ) { 13695 if ( newValue === undefined ) { 13696 return this.options.value; 13697 } 13698 13699 this.options.value = this._constrainedValue( newValue ); 13700 this._refreshValue(); 13701 }, 13702 13703 _constrainedValue: function( newValue ) { 13704 if ( newValue === undefined ) { 13705 newValue = this.options.value; 13706 } 13707 13708 this.indeterminate = newValue === false; 13709 13710 // Sanitize value 13711 if ( typeof newValue !== "number" ) { 13712 newValue = 0; 13713 } 13714 13715 return this.indeterminate ? false : 13716 Math.min( this.options.max, Math.max( this.min, newValue ) ); 13717 }, 13718 13719 _setOptions: function( options ) { 13720 13721 // Ensure "value" option is set after other values (like max) 13722 var value = options.value; 13723 delete options.value; 13724 13725 this._super( options ); 13726 13727 this.options.value = this._constrainedValue( value ); 13728 this._refreshValue(); 13729 }, 13730 13731 _setOption: function( key, value ) { 13732 if ( key === "max" ) { 13733 13734 // Don't allow a max less than min 13735 value = Math.max( this.min, value ); 13736 } 13737 this._super( key, value ); 13738 }, 13739 13740 _setOptionDisabled: function( value ) { 13741 this._super( value ); 13742 13743 this.element.attr( "aria-disabled", value ); 13744 this._toggleClass( null, "ui-state-disabled", !!value ); 13745 }, 13746 13747 _percentage: function() { 13748 return this.indeterminate ? 13749 100 : 13750 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 13751 }, 13752 13753 _refreshValue: function() { 13754 var value = this.options.value, 13755 percentage = this._percentage(); 13756 13757 this.valueDiv 13758 .toggle( this.indeterminate || value > this.min ) 13759 .width( percentage.toFixed( 0 ) + "%" ); 13760 13761 this 13762 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 13763 value === this.options.max ) 13764 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 13765 13766 if ( this.indeterminate ) { 13767 this.element.removeAttr( "aria-valuenow" ); 13768 if ( !this.overlayDiv ) { 13769 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 13770 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 13771 } 13772 } else { 13773 this.element.attr( { 13774 "aria-valuemax": this.options.max, 13775 "aria-valuenow": value 13776 } ); 13777 if ( this.overlayDiv ) { 13778 this.overlayDiv.remove(); 13779 this.overlayDiv = null; 13780 } 13781 } 13782 13783 if ( this.oldValue !== value ) { 13784 this.oldValue = value; 13785 this._trigger( "change" ); 13786 } 13787 if ( value === this.options.max ) { 13788 this._trigger( "complete" ); 13789 } 13790 } 13791} ); 13792 13793 13794/*! 13795 * jQuery UI Selectable 1.13.2 13796 * http://jqueryui.com 13797 * 13798 * Copyright jQuery Foundation and other contributors 13799 * Released under the MIT license. 13800 * http://jquery.org/license 13801 */ 13802 13803//>>label: Selectable 13804//>>group: Interactions 13805//>>description: Allows groups of elements to be selected with the mouse. 13806//>>docs: http://api.jqueryui.com/selectable/ 13807//>>demos: http://jqueryui.com/selectable/ 13808//>>css.structure: ../../themes/base/selectable.css 13809 13810 13811var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 13812 version: "1.13.2
vendor: 7,327 bytes, lines 13812-14093
13812", 13813 options: { 13814 appendTo: "body", 13815 autoRefresh: true, 13816 distance: 0, 13817 filter: "*", 13818 tolerance: "touch", 13819 13820 // Callbacks 13821 selected: null, 13822 selecting: null, 13823 start: null, 13824 stop: null, 13825 unselected: null, 13826 unselecting: null 13827 }, 13828 _create: function() { 13829 var that = this; 13830 13831 this._addClass( "ui-selectable" ); 13832 13833 this.dragged = false; 13834 13835 // Cache selectee children based on filter 13836 this.refresh = function() { 13837 that.elementPos = $( that.element[ 0 ] ).offset(); 13838 that.selectees = $( that.options.filter, that.element[ 0 ] ); 13839 that._addClass( that.selectees, "ui-selectee" ); 13840 that.selectees.each( function() { 13841 var $this = $( this ), 13842 selecteeOffset = $this.offset(), 13843 pos = { 13844 left: selecteeOffset.left - that.elementPos.left, 13845 top: selecteeOffset.top - that.elementPos.top 13846 }; 13847 $.data( this, "selectable-item", { 13848 element: this, 13849 $element: $this, 13850 left: pos.left, 13851 top: pos.top, 13852 right: pos.left + $this.outerWidth(), 13853 bottom: pos.top + $this.outerHeight(), 13854 startselected: false, 13855 selected: $this.hasClass( "ui-selected" ), 13856 selecting: $this.hasClass( "ui-selecting" ), 13857 unselecting: $this.hasClass( "ui-unselecting" ) 13858 } ); 13859 } ); 13860 }; 13861 this.refresh(); 13862 13863 this._mouseInit(); 13864 13865 this.helper = $( "<div>" ); 13866 this._addClass( this.helper, "ui-selectable-helper" ); 13867 }, 13868 13869 _destroy: function() { 13870 this.selectees.removeData( "selectable-item" ); 13871 this._mouseDestroy(); 13872 }, 13873 13874 _mouseStart: function( event ) { 13875 var that = this, 13876 options = this.options; 13877 13878 this.opos = [ event.pageX, event.pageY ]; 13879 this.elementPos = $( this.element[ 0 ] ).offset(); 13880 13881 if ( this.options.disabled ) { 13882 return; 13883 } 13884 13885 this.selectees = $( options.filter, this.element[ 0 ] ); 13886 13887 this._trigger( "start", event ); 13888 13889 $( options.appendTo ).append( this.helper ); 13890 13891 // position helper (lasso) 13892 this.helper.css( { 13893 "left": event.pageX, 13894 "top": event.pageY, 13895 "width": 0, 13896 "height": 0 13897 } ); 13898 13899 if ( options.autoRefresh ) { 13900 this.refresh(); 13901 } 13902 13903 this.selectees.filter( ".ui-selected" ).each( function() { 13904 var selectee = $.data( this, "selectable-item" ); 13905 selectee.startselected = true; 13906 if ( !event.metaKey && !event.ctrlKey ) { 13907 that._removeClass( selectee.$element, "ui-selected" ); 13908 selectee.selected = false; 13909 that._addClass( selectee.$element, "ui-unselecting" ); 13910 selectee.unselecting = true; 13911 13912 // selectable UNSELECTING callback 13913 that._trigger( "unselecting", event, { 13914 unselecting: selectee.element 13915 } ); 13916 } 13917 } ); 13918 13919 $( event.target ).parents().addBack().each( function() { 13920 var doSelect, 13921 selectee = $.data( this, "selectable-item" ); 13922 if ( selectee ) { 13923 doSelect = ( !event.metaKey && !event.ctrlKey ) || 13924 !selectee.$element.hasClass( "ui-selected" ); 13925 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 13926 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 13927 selectee.unselecting = !doSelect; 13928 selectee.selecting = doSelect; 13929 selectee.selected = doSelect; 13930 13931 // selectable (UN)SELECTING callback 13932 if ( doSelect ) { 13933 that._trigger( "selecting", event, { 13934 selecting: selectee.element 13935 } ); 13936 } else { 13937 that._trigger( "unselecting", event, { 13938 unselecting: selectee.element 13939 } ); 13940 } 13941 return false; 13942 } 13943 } ); 13944 13945 }, 13946 13947 _mouseDrag: function( event ) { 13948 13949 this.dragged = true; 13950 13951 if ( this.options.disabled ) { 13952 return; 13953 } 13954 13955 var tmp, 13956 that = this, 13957 options = this.options, 13958 x1 = this.opos[ 0 ], 13959 y1 = this.opos[ 1 ], 13960 x2 = event.pageX, 13961 y2 = event.pageY; 13962 13963 if ( x1 > x2 ) { 13964 tmp = x2; x2 = x1; x1 = tmp; 13965 } 13966 if ( y1 > y2 ) { 13967 tmp = y2; y2 = y1; y1 = tmp; 13968 } 13969 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 13970 13971 this.selectees.each( function() { 13972 var selectee = $.data( this, "selectable-item" ), 13973 hit = false, 13974 offset = {}; 13975 13976 //prevent helper from being selected if appendTo: selectable 13977 if ( !selectee || selectee.element === that.element[ 0 ] ) { 13978 return; 13979 } 13980 13981 offset.left = selectee.left + that.elementPos.left; 13982 offset.right = selectee.right + that.elementPos.left; 13983 offset.top = selectee.top + that.elementPos.top; 13984 offset.bottom = selectee.bottom + that.elementPos.top; 13985 13986 if ( options.tolerance === "touch" ) { 13987 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 13988 offset.bottom < y1 ) ); 13989 } else if ( options.tolerance === "fit" ) { 13990 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 13991 offset.bottom < y2 ); 13992 } 13993 13994 if ( hit ) { 13995 13996 // SELECT 13997 if ( selectee.selected ) { 13998 that._removeClass( selectee.$element, "ui-selected" ); 13999 selectee.selected = false; 14000 } 14001 if ( selectee.unselecting ) { 14002 that._removeClass( selectee.$element, "ui-unselecting" ); 14003 selectee.unselecting = false; 14004 } 14005 if ( !selectee.selecting ) { 14006 that._addClass( selectee.$element, "ui-selecting" ); 14007 selectee.selecting = true; 14008 14009 // selectable SELECTING callback 14010 that._trigger( "selecting", event, { 14011 selecting: selectee.element 14012 } ); 14013 } 14014 } else { 14015 14016 // UNSELECT 14017 if ( selectee.selecting ) { 14018 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 14019 that._removeClass( selectee.$element, "ui-selecting" ); 14020 selectee.selecting = false; 14021 that._addClass( selectee.$element, "ui-selected" ); 14022 selectee.selected = true; 14023 } else { 14024 that._removeClass( selectee.$element, "ui-selecting" ); 14025 selectee.selecting = false; 14026 if ( selectee.startselected ) { 14027 that._addClass( selectee.$element, "ui-unselecting" ); 14028 selectee.unselecting = true; 14029 } 14030 14031 // selectable UNSELECTING callback 14032 that._trigger( "unselecting", event, { 14033 unselecting: selectee.element 14034 } ); 14035 } 14036 } 14037 if ( selectee.selected ) { 14038 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 14039 that._removeClass( selectee.$element, "ui-selected" ); 14040 selectee.selected = false; 14041 14042 that._addClass( selectee.$element, "ui-unselecting" ); 14043 selectee.unselecting = true; 14044 14045 // selectable UNSELECTING callback 14046 that._trigger( "unselecting", event, { 14047 unselecting: selectee.element 14048 } ); 14049 } 14050 } 14051 } 14052 } ); 14053 14054 return false; 14055 }, 14056 14057 _mouseStop: function( event ) { 14058 var that = this; 14059 14060 this.dragged = false; 14061 14062 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 14063 var selectee = $.data( this, "selectable-item" ); 14064 that._removeClass( selectee.$element, "ui-unselecting" ); 14065 selectee.unselecting = false; 14066 selectee.startselected = false; 14067 that._trigger( "unselected", event, { 14068 unselected: selectee.element 14069 } ); 14070 } ); 14071 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 14072 var selectee = $.data( this, "selectable-item" ); 14073 that._removeClass( selectee.$element, "ui-selecting" ) 14074 ._addClass( selectee.$element, "ui-selected" ); 14075 selectee.selecting = false; 14076 selectee.selected = true; 14077 selectee.startselected = true; 14078 that._trigger( "selected", event, { 14079 selected: selectee.element 14080 } ); 14081 } ); 14082 this._trigger( "stop", event ); 14083 14084 this.helper.remove(); 14085 14086 return false; 14087 } 14088 14089} ); 14090 14091 14092/*! 14093 * jQuery UI Selectmenu 1.13.
vendor: 8,061 bytes, lines 14093-14424
140932 14094 * http://jqueryui.com 14095 * 14096 * Copyright jQuery Foundation and other contributors 14097 * Released under the MIT license. 14098 * http://jquery.org/license 14099 */ 14100 14101//>>label: Selectmenu 14102//>>group: Widgets 14103/* eslint-disable max-len */ 14104//>>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. 14105/* eslint-enable max-len */ 14106//>>docs: http://api.jqueryui.com/selectmenu/ 14107//>>demos: http://jqueryui.com/selectmenu/ 14108//>>css.structure: ../../themes/base/core.css 14109//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 14110//>>css.theme: ../../themes/base/theme.css 14111 14112 14113var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 14114 version: "1.13.2", 14115 defaultElement: "<select>", 14116 options: { 14117 appendTo: null, 14118 classes: { 14119 "ui-selectmenu-button-open": "ui-corner-top", 14120 "ui-selectmenu-button-closed": "ui-corner-all" 14121 }, 14122 disabled: null, 14123 icons: { 14124 button: "ui-icon-triangle-1-s" 14125 }, 14126 position: { 14127 my: "left top", 14128 at: "left bottom", 14129 collision: "none" 14130 }, 14131 width: false, 14132 14133 // Callbacks 14134 change: null, 14135 close: null, 14136 focus: null, 14137 open: null, 14138 select: null 14139 }, 14140 14141 _create: function() { 14142 var selectmenuId = this.element.uniqueId().attr( "id" ); 14143 this.ids = { 14144 element: selectmenuId, 14145 button: selectmenuId + "-button", 14146 menu: selectmenuId + "-menu" 14147 }; 14148 14149 this._drawButton(); 14150 this._drawMenu(); 14151 this._bindFormResetHandler(); 14152 14153 this._rendered = false; 14154 this.menuItems = $(); 14155 }, 14156 14157 _drawButton: function() { 14158 var icon, 14159 that = this, 14160 item = this._parseOption( 14161 this.element.find( "option:selected" ), 14162 this.element[ 0 ].selectedIndex 14163 ); 14164 14165 // Associate existing label with the new button 14166 this.labels = this.element.labels().attr( "for", this.ids.button ); 14167 this._on( this.labels, { 14168 click: function( event ) { 14169 this.button.trigger( "focus" ); 14170 event.preventDefault(); 14171 } 14172 } ); 14173 14174 // Hide original select element 14175 this.element.hide(); 14176 14177 // Create button 14178 this.button = $( "<span>", { 14179 tabindex: this.options.disabled ? -1 : 0, 14180 id: this.ids.button, 14181 role: "combobox", 14182 "aria-expanded": "false", 14183 "aria-autocomplete": "list", 14184 "aria-owns": this.ids.menu, 14185 "aria-haspopup": "true", 14186 title: this.element.attr( "title" ) 14187 } ) 14188 .insertAfter( this.element ); 14189 14190 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 14191 "ui-button ui-widget" ); 14192 14193 icon = $( "<span>" ).appendTo( this.button ); 14194 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 14195 this.buttonItem = this._renderButtonItem( item ) 14196 .appendTo( this.button ); 14197 14198 if ( this.options.width !== false ) { 14199 this._resizeButton(); 14200 } 14201 14202 this._on( this.button, this._buttonEvents ); 14203 this.button.one( "focusin", function() { 14204 14205 // Delay rendering the menu items until the button receives focus. 14206 // The menu may have already been rendered via a programmatic open. 14207 if ( !that._rendered ) { 14208 that._refreshMenu(); 14209 } 14210 } ); 14211 }, 14212 14213 _drawMenu: function() { 14214 var that = this; 14215 14216 // Create menu 14217 this.menu = $( "<ul>", { 14218 "aria-hidden": "true", 14219 "aria-labelledby": this.ids.button, 14220 id: this.ids.menu 14221 } ); 14222 14223 // Wrap menu 14224 this.menuWrap = $( "<div>" ).append( this.menu ); 14225 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 14226 this.menuWrap.appendTo( this._appendTo() ); 14227 14228 // Initialize menu widget 14229 this.menuInstance = this.menu 14230 .menu( { 14231 classes: { 14232 "ui-menu": "ui-corner-bottom" 14233 }, 14234 role: "listbox", 14235 select: function( event, ui ) { 14236 event.preventDefault(); 14237 14238 // Support: IE8 14239 // If the item was selected via a click, the text selection 14240 // will be destroyed in IE 14241 that._setSelection(); 14242 14243 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 14244 }, 14245 focus: function( event, ui ) { 14246 var item = ui.item.data( "ui-selectmenu-item" ); 14247 14248 // Prevent inital focus from firing and check if its a newly focused item 14249 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 14250 that._trigger( "focus", event, { item: item } ); 14251 if ( !that.isOpen ) { 14252 that._select( item, event ); 14253 } 14254 } 14255 that.focusIndex = item.index; 14256 14257 that.button.attr( "aria-activedescendant", 14258 that.menuItems.eq( item.index ).attr( "id" ) ); 14259 } 14260 } ) 14261 .menu( "instance" ); 14262 14263 // Don't close the menu on mouseleave 14264 this.menuInstance._off( this.menu, "mouseleave" ); 14265 14266 // Cancel the menu's collapseAll on document click 14267 this.menuInstance._closeOnDocumentClick = function() { 14268 return false; 14269 }; 14270 14271 // Selects often contain empty items, but never contain dividers 14272 this.menuInstance._isDivider = function() { 14273 return false; 14274 }; 14275 }, 14276 14277 refresh: function() { 14278 this._refreshMenu(); 14279 this.buttonItem.replaceWith( 14280 this.buttonItem = this._renderButtonItem( 14281 14282 // Fall back to an empty object in case there are no options 14283 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 14284 ) 14285 ); 14286 if ( this.options.width === null ) { 14287 this._resizeButton(); 14288 } 14289 }, 14290 14291 _refreshMenu: function() { 14292 var item, 14293 options = this.element.find( "option" ); 14294 14295 this.menu.empty(); 14296 14297 this._parseOptions( options ); 14298 this._renderMenu( this.menu, this.items ); 14299 14300 this.menuInstance.refresh(); 14301 this.menuItems = this.menu.find( "li" ) 14302 .not( ".ui-selectmenu-optgroup" ) 14303 .find( ".ui-menu-item-wrapper" ); 14304 14305 this._rendered = true; 14306 14307 if ( !options.length ) { 14308 return; 14309 } 14310 14311 item = this._getSelectedItem(); 14312 14313 // Update the menu to have the correct item focused 14314 this.menuInstance.focus( null, item ); 14315 this._setAria( item.data( "ui-selectmenu-item" ) ); 14316 14317 // Set disabled state 14318 this._setOption( "disabled", this.element.prop( "disabled" ) ); 14319 }, 14320 14321 open: function( event ) { 14322 if ( this.options.disabled ) { 14323 return; 14324 } 14325 14326 // If this is the first time the menu is being opened, render the items 14327 if ( !this._rendered ) { 14328 this._refreshMenu(); 14329 } else { 14330 14331 // Menu clears focus on close, reset focus to selected item 14332 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 14333 this.menuInstance.focus( null, this._getSelectedItem() ); 14334 } 14335 14336 // If there are no options, don't open the menu 14337 if ( !this.menuItems.length ) { 14338 return; 14339 } 14340 14341 this.isOpen = true; 14342 this._toggleAttr(); 14343 this._resizeMenu(); 14344 this._position(); 14345 14346 this._on( this.document, this._documentClick ); 14347 14348 this._trigger( "open", event ); 14349 }, 14350 14351 _position: function() { 14352 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 14353 }, 14354 14355 close: function( event ) { 14356 if ( !this.isOpen ) { 14357 return; 14358 } 14359 14360 this.isOpen = false; 14361 this._toggleAttr(); 14362 14363 this.range = null; 14364 this._off( this.document ); 14365 14366 this._trigger( "close", event ); 14367 }, 14368 14369 widget: function() { 14370 return this.button; 14371 }, 14372 14373 menuWidget: function() { 14374 return this.menu; 14375 }, 14376 14377 _renderButtonItem: function( item ) { 14378 var buttonItem = $( "<span>" ); 14379 14380 this._setText( buttonItem, item.label ); 14381 this._addClass( buttonItem, "ui-selectmenu-text" ); 14382 14383 return buttonItem; 14384 }, 14385 14386 _renderMenu: function( ul, items ) { 14387 var that = this, 14388 currentOptgroup = ""; 14389 14390 $.each( items, function( index, item ) { 14391 var li; 14392 14393 if ( item.optgroup !== currentOptgroup ) { 14394 li = $( "<li>", { 14395 text: item.optgroup 14396 } ); 14397 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 14398 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 14399 " ui-state-disabled" : 14400 "" ) ); 14401 14402 li.appendTo( ul ); 14403 14404 currentOptgroup = item.optgroup; 14405 } 14406 14407 that._renderItemData( ul, item ); 14408 } ); 14409 }, 14410 14411 _renderItemData: function( ul, item ) { 14412 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 14413 }, 14414 14415 _renderItem: function( ul, item ) { 14416 var li = $( "<li>" ), 14417 wrapper = $( "<div>", { 14418 title: item.element.attr( "title" ) 14419 } ); 14420 14421 if ( item.disabled ) { 14422 this._addClass( li, null, "ui-state-disabled" ); 14423 } 14424 this._setText( wrapper, item.label );
vendor: 7,096 bytes, lines 14424-14728
14424 14425 14426 return li.append( wrapper ).appendTo( ul ); 14427 }, 14428 14429 _setText: function( element, value ) { 14430 if ( value ) { 14431 element.text( value ); 14432 } else { 14433 element.html( " " ); 14434 } 14435 }, 14436 14437 _move: function( direction, event ) { 14438 var item, next, 14439 filter = ".ui-menu-item"; 14440 14441 if ( this.isOpen ) { 14442 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 14443 } else { 14444 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 14445 filter += ":not(.ui-state-disabled)"; 14446 } 14447 14448 if ( direction === "first" || direction === "last" ) { 14449 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 14450 } else { 14451 next = item[ direction + "All" ]( filter ).eq( 0 ); 14452 } 14453 14454 if ( next.length ) { 14455 this.menuInstance.focus( event, next ); 14456 } 14457 }, 14458 14459 _getSelectedItem: function() { 14460 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 14461 }, 14462 14463 _toggle: function( event ) { 14464 this[ this.isOpen ? "close" : "open" ]( event ); 14465 }, 14466 14467 _setSelection: function() { 14468 var selection; 14469 14470 if ( !this.range ) { 14471 return; 14472 } 14473 14474 if ( window.getSelection ) { 14475 selection = window.getSelection(); 14476 selection.removeAllRanges(); 14477 selection.addRange( this.range ); 14478 14479 // Support: IE8 14480 } else { 14481 this.range.select(); 14482 } 14483 14484 // Support: IE 14485 // Setting the text selection kills the button focus in IE, but 14486 // restoring the focus doesn't kill the selection. 14487 this.button.trigger( "focus" ); 14488 }, 14489 14490 _documentClick: { 14491 mousedown: function( event ) { 14492 if ( !this.isOpen ) { 14493 return; 14494 } 14495 14496 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 14497 $.escapeSelector( this.ids.button ) ).length ) { 14498 this.close( event ); 14499 } 14500 } 14501 }, 14502 14503 _buttonEvents: { 14504 14505 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 14506 mousedown: function() { 14507 var selection; 14508 14509 if ( window.getSelection ) { 14510 selection = window.getSelection(); 14511 if ( selection.rangeCount ) { 14512 this.range = selection.getRangeAt( 0 ); 14513 } 14514 14515 // Support: IE8 14516 } else { 14517 this.range = document.selection.createRange(); 14518 } 14519 }, 14520 14521 click: function( event ) { 14522 this._setSelection(); 14523 this._toggle( event ); 14524 }, 14525 14526 keydown: function( event ) { 14527 var preventDefault = true; 14528 switch ( event.keyCode ) { 14529 case $.ui.keyCode.TAB: 14530 case $.ui.keyCode.ESCAPE: 14531 this.close( event ); 14532 preventDefault = false; 14533 break; 14534 case $.ui.keyCode.ENTER: 14535 if ( this.isOpen ) { 14536 this._selectFocusedItem( event ); 14537 } 14538 break; 14539 case $.ui.keyCode.UP: 14540 if ( event.altKey ) { 14541 this._toggle( event ); 14542 } else { 14543 this._move( "prev", event ); 14544 } 14545 break; 14546 case $.ui.keyCode.DOWN: 14547 if ( event.altKey ) { 14548 this._toggle( event ); 14549 } else { 14550 this._move( "next", event ); 14551 } 14552 break; 14553 case $.ui.keyCode.SPACE: 14554 if ( this.isOpen ) { 14555 this._selectFocusedItem( event ); 14556 } else { 14557 this._toggle( event ); 14558 } 14559 break; 14560 case $.ui.keyCode.LEFT: 14561 this._move( "prev", event ); 14562 break; 14563 case $.ui.keyCode.RIGHT: 14564 this._move( "next", event ); 14565 break; 14566 case $.ui.keyCode.HOME: 14567 case $.ui.keyCode.PAGE_UP: 14568 this._move( "first", event ); 14569 break; 14570 case $.ui.keyCode.END: 14571 case $.ui.keyCode.PAGE_DOWN: 14572 this._move( "last", event ); 14573 break; 14574 default: 14575 this.menu.trigger( event ); 14576 preventDefault = false; 14577 } 14578 14579 if ( preventDefault ) { 14580 event.preventDefault(); 14581 } 14582 } 14583 }, 14584 14585 _selectFocusedItem: function( event ) { 14586 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 14587 if ( !item.hasClass( "ui-state-disabled" ) ) { 14588 this._select( item.data( "ui-selectmenu-item" ), event ); 14589 } 14590 }, 14591 14592 _select: function( item, event ) { 14593 var oldIndex = this.element[ 0 ].selectedIndex; 14594 14595 // Change native select element 14596 this.element[ 0 ].selectedIndex = item.index; 14597 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 14598 this._setAria( item ); 14599 this._trigger( "select", event, { item: item } ); 14600 14601 if ( item.index !== oldIndex ) { 14602 this._trigger( "change", event, { item: item } ); 14603 } 14604 14605 this.close( event ); 14606 }, 14607 14608 _setAria: function( item ) { 14609 var id = this.menuItems.eq( item.index ).attr( "id" ); 14610 14611 this.button.attr( { 14612 "aria-labelledby": id, 14613 "aria-activedescendant": id 14614 } ); 14615 this.menu.attr( "aria-activedescendant", id ); 14616 }, 14617 14618 _setOption: function( key, value ) { 14619 if ( key === "icons" ) { 14620 var icon = this.button.find( "span.ui-icon" ); 14621 this._removeClass( icon, null, this.options.icons.button ) 14622 ._addClass( icon, null, value.button ); 14623 } 14624 14625 this._super( key, value ); 14626 14627 if ( key === "appendTo" ) { 14628 this.menuWrap.appendTo( this._appendTo() ); 14629 } 14630 14631 if ( key === "width" ) { 14632 this._resizeButton(); 14633 } 14634 }, 14635 14636 _setOptionDisabled: function( value ) { 14637 this._super( value ); 14638 14639 this.menuInstance.option( "disabled", value ); 14640 this.button.attr( "aria-disabled", value ); 14641 this._toggleClass( this.button, null, "ui-state-disabled", value ); 14642 14643 this.element.prop( "disabled", value ); 14644 if ( value ) { 14645 this.button.attr( "tabindex", -1 ); 14646 this.close(); 14647 } else { 14648 this.button.attr( "tabindex", 0 ); 14649 } 14650 }, 14651 14652 _appendTo: function() { 14653 var element = this.options.appendTo; 14654 14655 if ( element ) { 14656 element = element.jquery || element.nodeType ? 14657 $( element ) : 14658 this.document.find( element ).eq( 0 ); 14659 } 14660 14661 if ( !element || !element[ 0 ] ) { 14662 element = this.element.closest( ".ui-front, dialog" ); 14663 } 14664 14665 if ( !element.length ) { 14666 element = this.document[ 0 ].body; 14667 } 14668 14669 return element; 14670 }, 14671 14672 _toggleAttr: function() { 14673 this.button.attr( "aria-expanded", this.isOpen ); 14674 14675 // We can't use two _toggleClass() calls here, because we need to make sure 14676 // we always remove classes first and add them second, otherwise if both classes have the 14677 // same theme class, it will be removed after we add it. 14678 this._removeClass( this.button, "ui-selectmenu-button-" + 14679 ( this.isOpen ? "closed" : "open" ) ) 14680 ._addClass( this.button, "ui-selectmenu-button-" + 14681 ( this.isOpen ? "open" : "closed" ) ) 14682 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 14683 14684 this.menu.attr( "aria-hidden", !this.isOpen ); 14685 }, 14686 14687 _resizeButton: function() { 14688 var width = this.options.width; 14689 14690 // For `width: false`, just remove inline style and stop 14691 if ( width === false ) { 14692 this.button.css( "width", "" ); 14693 return; 14694 } 14695 14696 // For `width: null`, match the width of the original element 14697 if ( width === null ) { 14698 width = this.element.show().outerWidth(); 14699 this.element.hide(); 14700 } 14701 14702 this.button.outerWidth( width ); 14703 }, 14704 14705 _resizeMenu: function() { 14706 this.menu.outerWidth( Math.max( 14707 this.button.outerWidth(), 14708 14709 // Support: IE10 14710 // IE10 wraps long text (possibly a rounding bug) 14711 // so we add 1px to avoid the wrapping 14712 this.menu.width( "" ).outerWidth() + 1 14713 ) ); 14714 }, 14715 14716 _getCreateOptions: function() { 14717 var options = this._super(); 14718 14719 options.disabled = this.element.prop( "disabled" ); 14720 14721 return options; 14722 }, 14723 14724 _parseOptions: function( options ) { 14725 var that = this, 14726 data = []; 14727 options.each( function( index, item ) { 14728
vendor: 1,261 bytes, lines 14728-14781
14728if ( item.hidden ) { 14729 return; 14730 } 14731 14732 data.push( that._parseOption( $( item ), index ) ); 14733 } ); 14734 this.items = data; 14735 }, 14736 14737 _parseOption: function( option, index ) { 14738 var optgroup = option.parent( "optgroup" ); 14739 14740 return { 14741 element: option, 14742 index: index, 14743 value: option.val(), 14744 label: option.text(), 14745 optgroup: optgroup.attr( "label" ) || "", 14746 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 14747 }; 14748 }, 14749 14750 _destroy: function() { 14751 this._unbindFormResetHandler(); 14752 this.menuWrap.remove(); 14753 this.button.remove(); 14754 this.element.show(); 14755 this.element.removeUniqueId(); 14756 this.labels.attr( "for", this.ids.element ); 14757 } 14758} ] ); 14759 14760 14761/*! 14762 * jQuery UI Slider 1.13.2 14763 * http://jqueryui.com 14764 * 14765 * Copyright jQuery Foundation and other contributors 14766 * Released under the MIT license. 14767 * http://jquery.org/license 14768 */ 14769 14770//>>label: Slider 14771//>>group: Widgets 14772//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 14773//>>docs: http://api.jqueryui.com/slider/ 14774//>>demos: http://jqueryui.com/slider/ 14775//>>css.structure: ../../themes/base/core.css 14776//>>css.structure: ../../themes/base/slider.css 14777//>>css.theme: ../../themes/base/theme.css 14778 14779 14780var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 14781 version: "1.13.2
vendor: 18,704 bytes, lines 14781-15497
14781", 14782 widgetEventPrefix: "slide", 14783 14784 options: { 14785 animate: false, 14786 classes: { 14787 "ui-slider": "ui-corner-all", 14788 "ui-slider-handle": "ui-corner-all", 14789 14790 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 14791 // element, but worked best visually with a variety of themes 14792 "ui-slider-range": "ui-corner-all ui-widget-header" 14793 }, 14794 distance: 0, 14795 max: 100, 14796 min: 0, 14797 orientation: "horizontal", 14798 range: false, 14799 step: 1, 14800 value: 0, 14801 values: null, 14802 14803 // Callbacks 14804 change: null, 14805 slide: null, 14806 start: null, 14807 stop: null 14808 }, 14809 14810 // Number of pages in a slider 14811 // (how many times can you page up/down to go through the whole range) 14812 numPages: 5, 14813 14814 _create: function() { 14815 this._keySliding = false; 14816 this._mouseSliding = false; 14817 this._animateOff = true; 14818 this._handleIndex = null; 14819 this._detectOrientation(); 14820 this._mouseInit(); 14821 this._calculateNewMax(); 14822 14823 this._addClass( "ui-slider ui-slider-" + this.orientation, 14824 "ui-widget ui-widget-content" ); 14825 14826 this._refresh(); 14827 14828 this._animateOff = false; 14829 }, 14830 14831 _refresh: function() { 14832 this._createRange(); 14833 this._createHandles(); 14834 this._setupEvents(); 14835 this._refreshValue(); 14836 }, 14837 14838 _createHandles: function() { 14839 var i, handleCount, 14840 options = this.options, 14841 existingHandles = this.element.find( ".ui-slider-handle" ), 14842 handle = "<span tabindex='0'></span>", 14843 handles = []; 14844 14845 handleCount = ( options.values && options.values.length ) || 1; 14846 14847 if ( existingHandles.length > handleCount ) { 14848 existingHandles.slice( handleCount ).remove(); 14849 existingHandles = existingHandles.slice( 0, handleCount ); 14850 } 14851 14852 for ( i = existingHandles.length; i < handleCount; i++ ) { 14853 handles.push( handle ); 14854 } 14855 14856 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 14857 14858 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 14859 14860 this.handle = this.handles.eq( 0 ); 14861 14862 this.handles.each( function( i ) { 14863 $( this ) 14864 .data( "ui-slider-handle-index", i ) 14865 .attr( "tabIndex", 0 ); 14866 } ); 14867 }, 14868 14869 _createRange: function() { 14870 var options = this.options; 14871 14872 if ( options.range ) { 14873 if ( options.range === true ) { 14874 if ( !options.values ) { 14875 options.values = [ this._valueMin(), this._valueMin() ]; 14876 } else if ( options.values.length && options.values.length !== 2 ) { 14877 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 14878 } else if ( Array.isArray( options.values ) ) { 14879 options.values = options.values.slice( 0 ); 14880 } 14881 } 14882 14883 if ( !this.range || !this.range.length ) { 14884 this.range = $( "<div>" ) 14885 .appendTo( this.element ); 14886 14887 this._addClass( this.range, "ui-slider-range" ); 14888 } else { 14889 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 14890 14891 // Handle range switching from true to min/max 14892 this.range.css( { 14893 "left": "", 14894 "bottom": "" 14895 } ); 14896 } 14897 if ( options.range === "min" || options.range === "max" ) { 14898 this._addClass( this.range, "ui-slider-range-" + options.range ); 14899 } 14900 } else { 14901 if ( this.range ) { 14902 this.range.remove(); 14903 } 14904 this.range = null; 14905 } 14906 }, 14907 14908 _setupEvents: function() { 14909 this._off( this.handles ); 14910 this._on( this.handles, this._handleEvents ); 14911 this._hoverable( this.handles ); 14912 this._focusable( this.handles ); 14913 }, 14914 14915 _destroy: function() { 14916 this.handles.remove(); 14917 if ( this.range ) { 14918 this.range.remove(); 14919 } 14920 14921 this._mouseDestroy(); 14922 }, 14923 14924 _mouseCapture: function( event ) { 14925 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 14926 that = this, 14927 o = this.options; 14928 14929 if ( o.disabled ) { 14930 return false; 14931 } 14932 14933 this.elementSize = { 14934 width: this.element.outerWidth(), 14935 height: this.element.outerHeight() 14936 }; 14937 this.elementOffset = this.element.offset(); 14938 14939 position = { x: event.pageX, y: event.pageY }; 14940 normValue = this._normValueFromMouse( position ); 14941 distance = this._valueMax() - this._valueMin() + 1; 14942 this.handles.each( function( i ) { 14943 var thisDistance = Math.abs( normValue - that.values( i ) ); 14944 if ( ( distance > thisDistance ) || 14945 ( distance === thisDistance && 14946 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 14947 distance = thisDistance; 14948 closestHandle = $( this ); 14949 index = i; 14950 } 14951 } ); 14952 14953 allowed = this._start( event, index ); 14954 if ( allowed === false ) { 14955 return false; 14956 } 14957 this._mouseSliding = true; 14958 14959 this._handleIndex = index; 14960 14961 this._addClass( closestHandle, null, "ui-state-active" ); 14962 closestHandle.trigger( "focus" ); 14963 14964 offset = closestHandle.offset(); 14965 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 14966 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 14967 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 14968 top: event.pageY - offset.top - 14969 ( closestHandle.height() / 2 ) - 14970 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 14971 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 14972 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 14973 }; 14974 14975 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 14976 this._slide( event, index, normValue ); 14977 } 14978 this._animateOff = true; 14979 return true; 14980 }, 14981 14982 _mouseStart: function() { 14983 return true; 14984 }, 14985 14986 _mouseDrag: function( event ) { 14987 var position = { x: event.pageX, y: event.pageY }, 14988 normValue = this._normValueFromMouse( position ); 14989 14990 this._slide( event, this._handleIndex, normValue ); 14991 14992 return false; 14993 }, 14994 14995 _mouseStop: function( event ) { 14996 this._removeClass( this.handles, null, "ui-state-active" ); 14997 this._mouseSliding = false; 14998 14999 this._stop( event, this._handleIndex ); 15000 this._change( event, this._handleIndex ); 15001 15002 this._handleIndex = null; 15003 this._clickOffset = null; 15004 this._animateOff = false; 15005 15006 return false; 15007 }, 15008 15009 _detectOrientation: function() { 15010 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 15011 }, 15012 15013 _normValueFromMouse: function( position ) { 15014 var pixelTotal, 15015 pixelMouse, 15016 percentMouse, 15017 valueTotal, 15018 valueMouse; 15019 15020 if ( this.orientation === "horizontal" ) { 15021 pixelTotal = this.elementSize.width; 15022 pixelMouse = position.x - this.elementOffset.left - 15023 ( this._clickOffset ? this._clickOffset.left : 0 ); 15024 } else { 15025 pixelTotal = this.elementSize.height; 15026 pixelMouse = position.y - this.elementOffset.top - 15027 ( this._clickOffset ? this._clickOffset.top : 0 ); 15028 } 15029 15030 percentMouse = ( pixelMouse / pixelTotal ); 15031 if ( percentMouse > 1 ) { 15032 percentMouse = 1; 15033 } 15034 if ( percentMouse < 0 ) { 15035 percentMouse = 0; 15036 } 15037 if ( this.orientation === "vertical" ) { 15038 percentMouse = 1 - percentMouse; 15039 } 15040 15041 valueTotal = this._valueMax() - this._valueMin(); 15042 valueMouse = this._valueMin() + percentMouse * valueTotal; 15043 15044 return this._trimAlignValue( valueMouse ); 15045 }, 15046 15047 _uiHash: function( index, value, values ) { 15048 var uiHash = { 15049 handle: this.handles[ index ], 15050 handleIndex: index, 15051 value: value !== undefined ? value : this.value() 15052 }; 15053 15054 if ( this._hasMultipleValues() ) { 15055 uiHash.value = value !== undefined ? value : this.values( index ); 15056 uiHash.values = values || this.values(); 15057 } 15058 15059 return uiHash; 15060 }, 15061 15062 _hasMultipleValues: function() { 15063 return this.options.values && this.options.values.length; 15064 }, 15065 15066 _start: function( event, index ) { 15067 return this._trigger( "start", event, this._uiHash( index ) ); 15068 }, 15069 15070 _slide: function( event, index, newVal ) { 15071 var allowed, otherVal, 15072 currentValue = this.value(), 15073 newValues = this.values(); 15074 15075 if ( this._hasMultipleValues() ) { 15076 otherVal = this.values( index ? 0 : 1 ); 15077 currentValue = this.values( index ); 15078 15079 if ( this.options.values.length === 2 && this.options.range === true ) { 15080 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 15081 } 15082 15083 newValues[ index ] = newVal; 15084 } 15085 15086 if ( newVal === currentValue ) { 15087 return; 15088 } 15089 15090 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 15091 15092 // A slide can be canceled by returning false from the slide callback 15093 if ( allowed === false ) { 15094 return; 15095 } 15096 15097 if ( this._hasMultipleValues() ) { 15098 this.values( index, newVal ); 15099 } else { 15100 this.value( newVal ); 15101 } 15102 }, 15103 15104 _stop: function( event, index ) { 15105 this._trigger( "stop", event, this._uiHash( index ) ); 15106 }, 15107 15108 _change: function( event, index ) { 15109 if ( !this._keySliding && !this._mouseSliding ) { 15110 15111 //store the last changed value index for reference when handles overlap 15112 this._lastChangedValue = index; 15113 this._trigger( "change", event, this._uiHash( index ) ); 15114 } 15115 }, 15116 15117 value: function( newValue ) { 15118 if ( arguments.length ) { 15119 this.options.value = this._trimAlignValue( newValue ); 15120 this._refreshValue(); 15121 this._change( null, 0 ); 15122 return; 15123 } 15124 15125 return this._value(); 15126 }, 15127 15128 values: function( index, newValue ) { 15129 var vals, 15130 newValues, 15131 i; 15132 15133 if ( arguments.length > 1 ) { 15134 this.options.values[ index ] = this._trimAlignValue( newValue ); 15135 this._refreshValue(); 15136 this._change( null, index ); 15137 return; 15138 } 15139 15140 if ( arguments.length ) { 15141 if ( Array.isArray( arguments[ 0 ] ) ) { 15142 vals = this.options.values; 15143 newValues = arguments[ 0 ]; 15144 for ( i = 0; i < vals.length; i += 1 ) { 15145 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 15146 this._change( null, i ); 15147 } 15148 this._refreshValue(); 15149 } else { 15150 if ( this._hasMultipleValues() ) { 15151 return this._values( index ); 15152 } else { 15153 return this.value(); 15154 } 15155 } 15156 } else { 15157 return this._values(); 15158 } 15159 }, 15160 15161 _setOption: function( key, value ) { 15162 var i, 15163 valsLength = 0; 15164 15165 if ( key === "range" && this.options.range === true ) { 15166 if ( value === "min" ) { 15167 this.options.value = this._values( 0 ); 15168 this.options.values = null; 15169 } else if ( value === "max" ) { 15170 this.options.value = this._values( this.options.values.length - 1 ); 15171 this.options.values = null; 15172 } 15173 } 15174 15175 if ( Array.isArray( this.options.values ) ) { 15176 valsLength = this.options.values.length; 15177 } 15178 15179 this._super( key, value ); 15180 15181 switch ( key ) { 15182 case "orientation": 15183 this._detectOrientation(); 15184 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 15185 ._addClass( "ui-slider-" + this.orientation ); 15186 this._refreshValue(); 15187 if ( this.options.range ) { 15188 this._refreshRange( value ); 15189 } 15190 15191 // Reset positioning from previous orientation 15192 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 15193 break; 15194 case "value": 15195 this._animateOff = true; 15196 this._refreshValue(); 15197 this._change( null, 0 ); 15198 this._animateOff = false; 15199 break; 15200 case "values": 15201 this._animateOff = true; 15202 this._refreshValue(); 15203 15204 // Start from the last handle to prevent unreachable handles (#9046) 15205 for ( i = valsLength - 1; i >= 0; i-- ) { 15206 this._change( null, i ); 15207 } 15208 this._animateOff = false; 15209 break; 15210 case "step": 15211 case "min": 15212 case "max": 15213 this._animateOff = true; 15214 this._calculateNewMax(); 15215 this._refreshValue(); 15216 this._animateOff = false; 15217 break; 15218 case "range": 15219 this._animateOff = true; 15220 this._refresh(); 15221 this._animateOff = false; 15222 break; 15223 } 15224 }, 15225 15226 _setOptionDisabled: function( value ) { 15227 this._super( value ); 15228 15229 this._toggleClass( null, "ui-state-disabled", !!value ); 15230 }, 15231 15232 //internal value getter 15233 // _value() returns value trimmed by min and max, aligned by step 15234 _value: function() { 15235 var val = this.options.value; 15236 val = this._trimAlignValue( val ); 15237 15238 return val; 15239 }, 15240 15241 //internal values getter 15242 // _values() returns array of values trimmed by min and max, aligned by step 15243 // _values( index ) returns single value trimmed by min and max, aligned by step 15244 _values: function( index ) { 15245 var val, 15246 vals, 15247 i; 15248 15249 if ( arguments.length ) { 15250 val = this.options.values[ index ]; 15251 val = this._trimAlignValue( val ); 15252 15253 return val; 15254 } else if ( this._hasMultipleValues() ) { 15255 15256 // .slice() creates a copy of the array 15257 // this copy gets trimmed by min and max and then returned 15258 vals = this.options.values.slice(); 15259 for ( i = 0; i < vals.length; i += 1 ) { 15260 vals[ i ] = this._trimAlignValue( vals[ i ] ); 15261 } 15262 15263 return vals; 15264 } else { 15265 return []; 15266 } 15267 }, 15268 15269 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 15270 _trimAlignValue: function( val ) { 15271 if ( val <= this._valueMin() ) { 15272 return this._valueMin(); 15273 } 15274 if ( val >= this._valueMax() ) { 15275 return this._valueMax(); 15276 } 15277 var step = ( this.options.step > 0 ) ? this.options.step : 1, 15278 valModStep = ( val - this._valueMin() ) % step, 15279 alignValue = val - valModStep; 15280 15281 if ( Math.abs( valModStep ) * 2 >= step ) { 15282 alignValue += ( valModStep > 0 ) ? step : ( -step ); 15283 } 15284 15285 // Since JavaScript has problems with large floats, round 15286 // the final value to 5 digits after the decimal point (see #4124) 15287 return parseFloat( alignValue.toFixed( 5 ) ); 15288 }, 15289 15290 _calculateNewMax: function() { 15291 var max = this.options.max, 15292 min = this._valueMin(), 15293 step = this.options.step, 15294 aboveMin = Math.round( ( max - min ) / step ) * step; 15295 max = aboveMin + min; 15296 if ( max > this.options.max ) { 15297 15298 //If max is not divisible by step, rounding off may increase its value 15299 max -= step; 15300 } 15301 this.max = parseFloat( max.toFixed( this._precision() ) ); 15302 }, 15303 15304 _precision: function() { 15305 var precision = this._precisionOf( this.options.step ); 15306 if ( this.options.min !== null ) { 15307 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15308 } 15309 return precision; 15310 }, 15311 15312 _precisionOf: function( num ) { 15313 var str = num.toString(), 15314 decimal = str.indexOf( "." ); 15315 return decimal === -1 ? 0 : str.length - decimal - 1; 15316 }, 15317 15318 _valueMin: function() { 15319 return this.options.min; 15320 }, 15321 15322 _valueMax: function() { 15323 return this.max; 15324 }, 15325 15326 _refreshRange: function( orientation ) { 15327 if ( orientation === "vertical" ) { 15328 this.range.css( { "width": "", "left": "" } ); 15329 } 15330 if ( orientation === "horizontal" ) { 15331 this.range.css( { "height": "", "bottom": "" } ); 15332 } 15333 }, 15334 15335 _refreshValue: function() { 15336 var lastValPercent, valPercent, value, valueMin, valueMax, 15337 oRange = this.options.range, 15338 o = this.options, 15339 that = this, 15340 animate = ( !this._animateOff ) ? o.animate : false, 15341 _set = {}; 15342 15343 if ( this._hasMultipleValues() ) { 15344 this.handles.each( function( i ) { 15345 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 15346 that._valueMin() ) * 100; 15347 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 15348 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 15349 if ( that.options.range === true ) { 15350 if ( that.orientation === "horizontal" ) { 15351 if ( i === 0 ) { 15352 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15353 left: valPercent + "%" 15354 }, o.animate ); 15355 } 15356 if ( i === 1 ) { 15357 that.range[ animate ? "animate" : "css" ]( { 15358 width: ( valPercent - lastValPercent ) + "%" 15359 }, { 15360 queue: false, 15361 duration: o.animate 15362 } ); 15363 } 15364 } else { 15365 if ( i === 0 ) { 15366 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15367 bottom: ( valPercent ) + "%" 15368 }, o.animate ); 15369 } 15370 if ( i === 1 ) { 15371 that.range[ animate ? "animate" : "css" ]( { 15372 height: ( valPercent - lastValPercent ) + "%" 15373 }, { 15374 queue: false, 15375 duration: o.animate 15376 } ); 15377 } 15378 } 15379 } 15380 lastValPercent = valPercent; 15381 } ); 15382 } else { 15383 value = this.value(); 15384 valueMin = this._valueMin(); 15385 valueMax = this._valueMax(); 15386 valPercent = ( valueMax !== valueMin ) ? 15387 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 15388 0; 15389 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 15390 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 15391 15392 if ( oRange === "min" && this.orientation === "horizontal" ) { 15393 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15394 width: valPercent + "%" 15395 }, o.animate ); 15396 } 15397 if ( oRange === "max" && this.orientation === "horizontal" ) { 15398 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15399 width: ( 100 - valPercent ) + "%" 15400 }, o.animate ); 15401 } 15402 if ( oRange === "min" && this.orientation === "vertical" ) { 15403 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15404 height: valPercent + "%" 15405 }, o.animate ); 15406 } 15407 if ( oRange === "max" && this.orientation === "vertical" ) { 15408 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 15409 height: ( 100 - valPercent ) + "%" 15410 }, o.animate ); 15411 } 15412 } 15413 }, 15414 15415 _handleEvents: { 15416 keydown: function( event ) { 15417 var allowed, curVal, newVal, step, 15418 index = $( event.target ).data( "ui-slider-handle-index" ); 15419 15420 switch ( event.keyCode ) { 15421 case $.ui.keyCode.HOME: 15422 case $.ui.keyCode.END: 15423 case $.ui.keyCode.PAGE_UP: 15424 case $.ui.keyCode.PAGE_DOWN: 15425 case $.ui.keyCode.UP: 15426 case $.ui.keyCode.RIGHT: 15427 case $.ui.keyCode.DOWN: 15428 case $.ui.keyCode.LEFT: 15429 event.preventDefault(); 15430 if ( !this._keySliding ) { 15431 this._keySliding = true; 15432 this._addClass( $( event.target ), null, "ui-state-active" ); 15433 allowed = this._start( event, index ); 15434 if ( allowed === false ) { 15435 return; 15436 } 15437 } 15438 break; 15439 } 15440 15441 step = this.options.step; 15442 if ( this._hasMultipleValues() ) { 15443 curVal = newVal = this.values( index ); 15444 } else { 15445 curVal = newVal = this.value(); 15446 } 15447 15448 switch ( event.keyCode ) { 15449 case $.ui.keyCode.HOME: 15450 newVal = this._valueMin(); 15451 break; 15452 case $.ui.keyCode.END: 15453 newVal = this._valueMax(); 15454 break; 15455 case $.ui.keyCode.PAGE_UP: 15456 newVal = this._trimAlignValue( 15457 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 15458 ); 15459 break; 15460 case $.ui.keyCode.PAGE_DOWN: 15461 newVal = this._trimAlignValue( 15462 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 15463 break; 15464 case $.ui.keyCode.UP: 15465 case $.ui.keyCode.RIGHT: 15466 if ( curVal === this._valueMax() ) { 15467 return; 15468 } 15469 newVal = this._trimAlignValue( curVal + step ); 15470 break; 15471 case $.ui.keyCode.DOWN: 15472 case $.ui.keyCode.LEFT: 15473 if ( curVal === this._valueMin() ) { 15474 return; 15475 } 15476 newVal = this._trimAlignValue( curVal - step ); 15477 break; 15478 } 15479 15480 this._slide( event, index, newVal ); 15481 }, 15482 keyup: function( event ) { 15483 var index = $( event.target ).data( "ui-slider-handle-index" ); 15484 15485 if ( this._keySliding ) { 15486 this._keySliding = false; 15487 this._stop( event, index ); 15488 this._change( event, index ); 15489 this._removeClass( $( event.target ), null, "ui-state-active" ); 15490 } 15491 } 15492 } 15493} ); 15494 15495 15496/*! 15497 * jQuery UI Sortable 1.13.
154972 15498 * http://jqueryui.com 15499 * 15500 * Copyright jQuery Foundation and other contributors 15501 * Released under the MIT license. 15502 * http://jquery.org/license 15503 */ 15504 15505//>>label: Sortable 15506//>>group: Interactions 15507//>>description: Enables items in a list to be sorted using the mouse. 15508//>>docs: http://api.jqueryui.com/sortable/ 15509//>>demos: http://jqueryui.com/sortable/ 15510//>>css.structure: ../../themes/base/sortable.css 15511 15512 15513var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { 15514 version: "1.13.2
vendor: 46,802 bytes, lines 15514-17090
15514", 15515 widgetEventPrefix: "sort", 15516 ready: false, 15517 options: { 15518 appendTo: "parent", 15519 axis: false, 15520 connectWith: false, 15521 containment: false, 15522 cursor: "auto", 15523 cursorAt: false, 15524 dropOnEmpty: true, 15525 forcePlaceholderSize: false, 15526 forceHelperSize: false, 15527 grid: false, 15528 handle: false, 15529 helper: "original", 15530 items: "> *", 15531 opacity: false, 15532 placeholder: false, 15533 revert: false, 15534 scroll: true, 15535 scrollSensitivity: 20, 15536 scrollSpeed: 20, 15537 scope: "default", 15538 tolerance: "intersect", 15539 zIndex: 1000, 15540 15541 // Callbacks 15542 activate: null, 15543 beforeStop: null, 15544 change: null, 15545 deactivate: null, 15546 out: null, 15547 over: null, 15548 receive: null, 15549 remove: null, 15550 sort: null, 15551 start: null, 15552 stop: null, 15553 update: null 15554 }, 15555 15556 _isOverAxis: function( x, reference, size ) { 15557 return ( x >= reference ) && ( x < ( reference + size ) ); 15558 }, 15559 15560 _isFloating: function( item ) { 15561 return ( /left|right/ ).test( item.css( "float" ) ) || 15562 ( /inline|table-cell/ ).test( item.css( "display" ) ); 15563 }, 15564 15565 _create: function() { 15566 this.containerCache = {}; 15567 this._addClass( "ui-sortable" ); 15568 15569 //Get the items 15570 this.refresh(); 15571 15572 //Let's determine the parent's offset 15573 this.offset = this.element.offset(); 15574 15575 //Initialize mouse events for interaction 15576 this._mouseInit(); 15577 15578 this._setHandleClassName(); 15579 15580 //We're ready to go 15581 this.ready = true; 15582 15583 }, 15584 15585 _setOption: function( key, value ) { 15586 this._super( key, value ); 15587 15588 if ( key === "handle" ) { 15589 this._setHandleClassName(); 15590 } 15591 }, 15592 15593 _setHandleClassName: function() { 15594 var that = this; 15595 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 15596 $.each( this.items, function() { 15597 that._addClass( 15598 this.instance.options.handle ? 15599 this.item.find( this.instance.options.handle ) : 15600 this.item, 15601 "ui-sortable-handle" 15602 ); 15603 } ); 15604 }, 15605 15606 _destroy: function() { 15607 this._mouseDestroy(); 15608 15609 for ( var i = this.items.length - 1; i >= 0; i-- ) { 15610 this.items[ i ].item.removeData( this.widgetName + "-item" ); 15611 } 15612 15613 return this; 15614 }, 15615 15616 _mouseCapture: function( event, overrideHandle ) { 15617 var currentItem = null, 15618 validHandle = false, 15619 that = this; 15620 15621 if ( this.reverting ) { 15622 return false; 15623 } 15624 15625 if ( this.options.disabled || this.options.type === "static" ) { 15626 return false; 15627 } 15628 15629 //We have to refresh the items data once first 15630 this._refreshItems( event ); 15631 15632 //Find out if the clicked node (or one of its parents) is a actual item in this.items 15633 $( event.target ).parents().each( function() { 15634 if ( $.data( this, that.widgetName + "-item" ) === that ) { 15635 currentItem = $( this ); 15636 return false; 15637 } 15638 } ); 15639 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 15640 currentItem = $( event.target ); 15641 } 15642 15643 if ( !currentItem ) { 15644 return false; 15645 } 15646 if ( this.options.handle && !overrideHandle ) { 15647 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 15648 if ( this === event.target ) { 15649 validHandle = true; 15650 } 15651 } ); 15652 if ( !validHandle ) { 15653 return false; 15654 } 15655 } 15656 15657 this.currentItem = currentItem; 15658 this._removeCurrentsFromItems(); 15659 return true; 15660 15661 }, 15662 15663 _mouseStart: function( event, overrideHandle, noActivation ) { 15664 15665 var i, body, 15666 o = this.options; 15667 15668 this.currentContainer = this; 15669 15670 //We only need to call refreshPositions, because the refreshItems call has been moved to 15671 // mouseCapture 15672 this.refreshPositions(); 15673 15674 //Prepare the dragged items parent 15675 this.appendTo = $( o.appendTo !== "parent" ? 15676 o.appendTo : 15677 this.currentItem.parent() ); 15678 15679 //Create and append the visible helper 15680 this.helper = this._createHelper( event ); 15681 15682 //Cache the helper size 15683 this._cacheHelperProportions(); 15684 15685 /* 15686 * - Position generation - 15687 * This block generates everything position related - it's the core of draggables. 15688 */ 15689 15690 //Cache the margins of the original element 15691 this._cacheMargins(); 15692 15693 //The element's absolute position on the page minus margins 15694 this.offset = this.currentItem.offset(); 15695 this.offset = { 15696 top: this.offset.top - this.margins.top, 15697 left: this.offset.left - this.margins.left 15698 }; 15699 15700 $.extend( this.offset, { 15701 click: { //Where the click happened, relative to the element 15702 left: event.pageX - this.offset.left, 15703 top: event.pageY - this.offset.top 15704 }, 15705 15706 // This is a relative to absolute position minus the actual position calculation - 15707 // only used for relative positioned helper 15708 relative: this._getRelativeOffset() 15709 } ); 15710 15711 // After we get the helper offset, but before we get the parent offset we can 15712 // change the helper's position to absolute 15713 // TODO: Still need to figure out a way to make relative sorting possible 15714 this.helper.css( "position", "absolute" ); 15715 this.cssPosition = this.helper.css( "position" ); 15716 15717 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 15718 if ( o.cursorAt ) { 15719 this._adjustOffsetFromHelper( o.cursorAt ); 15720 } 15721 15722 //Cache the former DOM position 15723 this.domPosition = { 15724 prev: this.currentItem.prev()[ 0 ], 15725 parent: this.currentItem.parent()[ 0 ] 15726 }; 15727 15728 // If the helper is not the original, hide the original so it's not playing any role during 15729 // the drag, won't cause anything bad this way 15730 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 15731 this.currentItem.hide(); 15732 } 15733 15734 //Create the placeholder 15735 this._createPlaceholder(); 15736 15737 //Get the next scrolling parent 15738 this.scrollParent = this.placeholder.scrollParent(); 15739 15740 $.extend( this.offset, { 15741 parent: this._getParentOffset() 15742 } ); 15743 15744 //Set a containment if given in the options 15745 if ( o.containment ) { 15746 this._setContainment(); 15747 } 15748 15749 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 15750 body = this.document.find( "body" ); 15751 15752 // Support: IE 15753 this.storedCursor = body.css( "cursor" ); 15754 body.css( "cursor", o.cursor ); 15755 15756 this.storedStylesheet = 15757 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 15758 } 15759 15760 // We need to make sure to grab the zIndex before setting the 15761 // opacity, because setting the opacity to anything lower than 1 15762 // causes the zIndex to change from "auto" to 0. 15763 if ( o.zIndex ) { // zIndex option 15764 if ( this.helper.css( "zIndex" ) ) { 15765 this._storedZIndex = this.helper.css( "zIndex" ); 15766 } 15767 this.helper.css( "zIndex", o.zIndex ); 15768 } 15769 15770 if ( o.opacity ) { // opacity option 15771 if ( this.helper.css( "opacity" ) ) { 15772 this._storedOpacity = this.helper.css( "opacity" ); 15773 } 15774 this.helper.css( "opacity", o.opacity ); 15775 } 15776 15777 //Prepare scrolling 15778 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 15779 this.scrollParent[ 0 ].tagName !== "HTML" ) { 15780 this.overflowOffset = this.scrollParent.offset(); 15781 } 15782 15783 //Call callbacks 15784 this._trigger( "start", event, this._uiHash() ); 15785 15786 //Recache the helper size 15787 if ( !this._preserveHelperProportions ) { 15788 this._cacheHelperProportions(); 15789 } 15790 15791 //Post "activate" events to possible containers 15792 if ( !noActivation ) { 15793 for ( i = this.containers.length - 1; i >= 0; i-- ) { 15794 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 15795 } 15796 } 15797 15798 //Prepare possible droppables 15799 if ( $.ui.ddmanager ) { 15800 $.ui.ddmanager.current = this; 15801 } 15802 15803 if ( $.ui.ddmanager && !o.dropBehaviour ) { 15804 $.ui.ddmanager.prepareOffsets( this, event ); 15805 } 15806 15807 this.dragging = true; 15808 15809 this._addClass( this.helper, "ui-sortable-helper" ); 15810 15811 //Move the helper, if needed 15812 if ( !this.helper.parent().is( this.appendTo ) ) { 15813 this.helper.detach().appendTo( this.appendTo ); 15814 15815 //Update position 15816 this.offset.parent = this._getParentOffset(); 15817 } 15818 15819 //Generate the original position 15820 this.position = this.originalPosition = this._generatePosition( event ); 15821 this.originalPageX = event.pageX; 15822 this.originalPageY = event.pageY; 15823 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); 15824 15825 this._mouseDrag( event ); 15826 15827 return true; 15828 15829 }, 15830 15831 _scroll: function( event ) { 15832 var o = this.options, 15833 scrolled = false; 15834 15835 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 15836 this.scrollParent[ 0 ].tagName !== "HTML" ) { 15837 15838 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 15839 event.pageY < o.scrollSensitivity ) { 15840 this.scrollParent[ 0 ].scrollTop = 15841 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 15842 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 15843 this.scrollParent[ 0 ].scrollTop = 15844 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 15845 } 15846 15847 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 15848 event.pageX < o.scrollSensitivity ) { 15849 this.scrollParent[ 0 ].scrollLeft = scrolled = 15850 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 15851 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 15852 this.scrollParent[ 0 ].scrollLeft = scrolled = 15853 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 15854 } 15855 15856 } else { 15857 15858 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 15859 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 15860 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 15861 o.scrollSensitivity ) { 15862 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 15863 } 15864 15865 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 15866 scrolled = this.document.scrollLeft( 15867 this.document.scrollLeft() - o.scrollSpeed 15868 ); 15869 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 15870 o.scrollSensitivity ) { 15871 scrolled = this.document.scrollLeft( 15872 this.document.scrollLeft() + o.scrollSpeed 15873 ); 15874 } 15875 15876 } 15877 15878 return scrolled; 15879 }, 15880 15881 _mouseDrag: function( event ) { 15882 var i, item, itemElement, intersection, 15883 o = this.options; 15884 15885 //Compute the helpers position 15886 this.position = this._generatePosition( event ); 15887 this.positionAbs = this._convertPositionTo( "absolute" ); 15888 15889 //Set the helper position 15890 if ( !this.options.axis || this.options.axis !== "y" ) { 15891 this.helper[ 0 ].style.left = this.position.left + "px"; 15892 } 15893 if ( !this.options.axis || this.options.axis !== "x" ) { 15894 this.helper[ 0 ].style.top = this.position.top + "px"; 15895 } 15896 15897 //Do scrolling 15898 if ( o.scroll ) { 15899 if ( this._scroll( event ) !== false ) { 15900 15901 //Update item positions used in position checks 15902 this._refreshItemPositions( true ); 15903 15904 if ( $.ui.ddmanager && !o.dropBehaviour ) { 15905 $.ui.ddmanager.prepareOffsets( this, event ); 15906 } 15907 } 15908 } 15909 15910 this.dragDirection = { 15911 vertical: this._getDragVerticalDirection(), 15912 horizontal: this._getDragHorizontalDirection() 15913 }; 15914 15915 //Rearrange 15916 for ( i = this.items.length - 1; i >= 0; i-- ) { 15917 15918 //Cache variables and intersection, continue if no intersection 15919 item = this.items[ i ]; 15920 itemElement = item.item[ 0 ]; 15921 intersection = this._intersectsWithPointer( item ); 15922 if ( !intersection ) { 15923 continue; 15924 } 15925 15926 // Only put the placeholder inside the current Container, skip all 15927 // items from other containers. This works because when moving 15928 // an item from one container to another the 15929 // currentContainer is switched before the placeholder is moved. 15930 // 15931 // Without this, moving items in "sub-sortables" can cause 15932 // the placeholder to jitter between the outer and inner container. 15933 if ( item.instance !== this.currentContainer ) { 15934 continue; 15935 } 15936 15937 // Cannot intersect with itself 15938 // no useless actions that have been done before 15939 // no action if the item moved is the parent of the item checked 15940 if ( itemElement !== this.currentItem[ 0 ] && 15941 this.placeholder[ intersection === 1 ? 15942 "next" : "prev" ]()[ 0 ] !== itemElement && 15943 !$.contains( this.placeholder[ 0 ], itemElement ) && 15944 ( this.options.type === "semi-dynamic" ? 15945 !$.contains( this.element[ 0 ], itemElement ) : 15946 true 15947 ) 15948 ) { 15949 15950 this.direction = intersection === 1 ? "down" : "up"; 15951 15952 if ( this.options.tolerance === "pointer" || 15953 this._intersectsWithSides( item ) ) { 15954 this._rearrange( event, item ); 15955 } else { 15956 break; 15957 } 15958 15959 this._trigger( "change", event, this._uiHash() ); 15960 break; 15961 } 15962 } 15963 15964 //Post events to containers 15965 this._contactContainers( event ); 15966 15967 //Interconnect with droppables 15968 if ( $.ui.ddmanager ) { 15969 $.ui.ddmanager.drag( this, event ); 15970 } 15971 15972 //Call callbacks 15973 this._trigger( "sort", event, this._uiHash() ); 15974 15975 this.lastPositionAbs = this.positionAbs; 15976 return false; 15977 15978 }, 15979 15980 _mouseStop: function( event, noPropagation ) { 15981 15982 if ( !event ) { 15983 return; 15984 } 15985 15986 //If we are using droppables, inform the manager about the drop 15987 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 15988 $.ui.ddmanager.drop( this, event ); 15989 } 15990 15991 if ( this.options.revert ) { 15992 var that = this, 15993 cur = this.placeholder.offset(), 15994 axis = this.options.axis, 15995 animation = {}; 15996 15997 if ( !axis || axis === "x" ) { 15998 animation.left = cur.left - this.offset.parent.left - this.margins.left + 15999 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 16000 0 : 16001 this.offsetParent[ 0 ].scrollLeft 16002 ); 16003 } 16004 if ( !axis || axis === "y" ) { 16005 animation.top = cur.top - this.offset.parent.top - this.margins.top + 16006 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 16007 0 : 16008 this.offsetParent[ 0 ].scrollTop 16009 ); 16010 } 16011 this.reverting = true; 16012 $( this.helper ).animate( 16013 animation, 16014 parseInt( this.options.revert, 10 ) || 500, 16015 function() { 16016 that._clear( event ); 16017 } 16018 ); 16019 } else { 16020 this._clear( event, noPropagation ); 16021 } 16022 16023 return false; 16024 16025 }, 16026 16027 cancel: function() { 16028 16029 if ( this.dragging ) { 16030 16031 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 16032 16033 if ( this.options.helper === "original" ) { 16034 this.currentItem.css( this._storedCSS ); 16035 this._removeClass( this.currentItem, "ui-sortable-helper" ); 16036 } else { 16037 this.currentItem.show(); 16038 } 16039 16040 //Post deactivating events to containers 16041 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 16042 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 16043 if ( this.containers[ i ].containerCache.over ) { 16044 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 16045 this.containers[ i ].containerCache.over = 0; 16046 } 16047 } 16048 16049 } 16050 16051 if ( this.placeholder ) { 16052 16053 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 16054 // it unbinds ALL events from the original node! 16055 if ( this.placeholder[ 0 ].parentNode ) { 16056 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 16057 } 16058 if ( this.options.helper !== "original" && this.helper && 16059 this.helper[ 0 ].parentNode ) { 16060 this.helper.remove(); 16061 } 16062 16063 $.extend( this, { 16064 helper: null, 16065 dragging: false, 16066 reverting: false, 16067 _noFinalSort: null 16068 } ); 16069 16070 if ( this.domPosition.prev ) { 16071 $( this.domPosition.prev ).after( this.currentItem ); 16072 } else { 16073 $( this.domPosition.parent ).prepend( this.currentItem ); 16074 } 16075 } 16076 16077 return this; 16078 16079 }, 16080 16081 serialize: function( o ) { 16082 16083 var items = this._getItemsAsjQuery( o && o.connected ), 16084 str = []; 16085 o = o || {}; 16086 16087 $( items ).each( function() { 16088 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 16089 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 16090 if ( res ) { 16091 str.push( 16092 ( o.key || res[ 1 ] + "[]" ) + 16093 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 16094 } 16095 } ); 16096 16097 if ( !str.length && o.key ) { 16098 str.push( o.key + "=" ); 16099 } 16100 16101 return str.join( "&" ); 16102 16103 }, 16104 16105 toArray: function( o ) { 16106 16107 var items = this._getItemsAsjQuery( o && o.connected ), 16108 ret = []; 16109 16110 o = o || {}; 16111 16112 items.each( function() { 16113 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 16114 } ); 16115 return ret; 16116 16117 }, 16118 16119 /* Be careful with the following core functions */ 16120 _intersectsWith: function( item ) { 16121 16122 var x1 = this.positionAbs.left, 16123 x2 = x1 + this.helperProportions.width, 16124 y1 = this.positionAbs.top, 16125 y2 = y1 + this.helperProportions.height, 16126 l = item.left, 16127 r = l + item.width, 16128 t = item.top, 16129 b = t + item.height, 16130 dyClick = this.offset.click.top, 16131 dxClick = this.offset.click.left, 16132 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 16133 ( y1 + dyClick ) < b ), 16134 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 16135 ( x1 + dxClick ) < r ), 16136 isOverElement = isOverElementHeight && isOverElementWidth; 16137 16138 if ( this.options.tolerance === "pointer" || 16139 this.options.forcePointerForContainers || 16140 ( this.options.tolerance !== "pointer" && 16141 this.helperProportions[ this.floating ? "width" : "height" ] > 16142 item[ this.floating ? "width" : "height" ] ) 16143 ) { 16144 return isOverElement; 16145 } else { 16146 16147 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 16148 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 16149 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 16150 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 16151 16152 } 16153 }, 16154 16155 _intersectsWithPointer: function( item ) { 16156 var verticalDirection, horizontalDirection, 16157 isOverElementHeight = ( this.options.axis === "x" ) || 16158 this._isOverAxis( 16159 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 16160 isOverElementWidth = ( this.options.axis === "y" ) || 16161 this._isOverAxis( 16162 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 16163 isOverElement = isOverElementHeight && isOverElementWidth; 16164 16165 if ( !isOverElement ) { 16166 return false; 16167 } 16168 16169 verticalDirection = this.dragDirection.vertical; 16170 horizontalDirection = this.dragDirection.horizontal; 16171 16172 return this.floating ? 16173 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : 16174 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 16175 16176 }, 16177 16178 _intersectsWithSides: function( item ) { 16179 16180 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 16181 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 16182 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 16183 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 16184 verticalDirection = this.dragDirection.vertical, 16185 horizontalDirection = this.dragDirection.horizontal; 16186 16187 if ( this.floating && horizontalDirection ) { 16188 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 16189 ( horizontalDirection === "left" && !isOverRightHalf ) ); 16190 } else { 16191 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 16192 ( verticalDirection === "up" && !isOverBottomHalf ) ); 16193 } 16194 16195 }, 16196 16197 _getDragVerticalDirection: function() { 16198 var delta = this.positionAbs.top - this.lastPositionAbs.top; 16199 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 16200 }, 16201 16202 _getDragHorizontalDirection: function() { 16203 var delta = this.positionAbs.left - this.lastPositionAbs.left; 16204 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 16205 }, 16206 16207 refresh: function( event ) { 16208 this._refreshItems( event ); 16209 this._setHandleClassName(); 16210 this.refreshPositions(); 16211 return this; 16212 }, 16213 16214 _connectWith: function() { 16215 var options = this.options; 16216 return options.connectWith.constructor === String ? 16217 [ options.connectWith ] : 16218 options.connectWith; 16219 }, 16220 16221 _getItemsAsjQuery: function( connected ) { 16222 16223 var i, j, cur, inst, 16224 items = [], 16225 queries = [], 16226 connectWith = this._connectWith(); 16227 16228 if ( connectWith && connected ) { 16229 for ( i = connectWith.length - 1; i >= 0; i-- ) { 16230 cur = $( connectWith[ i ], this.document[ 0 ] ); 16231 for ( j = cur.length - 1; j >= 0; j-- ) { 16232 inst = $.data( cur[ j ], this.widgetFullName ); 16233 if ( inst && inst !== this && !inst.options.disabled ) { 16234 queries.push( [ typeof inst.options.items === "function" ? 16235 inst.options.items.call( inst.element ) : 16236 $( inst.options.items, inst.element ) 16237 .not( ".ui-sortable-helper" ) 16238 .not( ".ui-sortable-placeholder" ), inst ] ); 16239 } 16240 } 16241 } 16242 } 16243 16244 queries.push( [ typeof this.options.items === "function" ? 16245 this.options.items 16246 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 16247 $( this.options.items, this.element ) 16248 .not( ".ui-sortable-helper" ) 16249 .not( ".ui-sortable-placeholder" ), this ] ); 16250 16251 function addItems() { 16252 items.push( this ); 16253 } 16254 for ( i = queries.length - 1; i >= 0; i-- ) { 16255 queries[ i ][ 0 ].each( addItems ); 16256 } 16257 16258 return $( items ); 16259 16260 }, 16261 16262 _removeCurrentsFromItems: function() { 16263 16264 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 16265 16266 this.items = $.grep( this.items, function( item ) { 16267 for ( var j = 0; j < list.length; j++ ) { 16268 if ( list[ j ] === item.item[ 0 ] ) { 16269 return false; 16270 } 16271 } 16272 return true; 16273 } ); 16274 16275 }, 16276 16277 _refreshItems: function( event ) { 16278 16279 this.items = []; 16280 this.containers = [ this ]; 16281 16282 var i, j, cur, inst, targetData, _queries, item, queriesLength, 16283 items = this.items, 16284 queries = [ [ typeof this.options.items === "function" ? 16285 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 16286 $( this.options.items, this.element ), this ] ], 16287 connectWith = this._connectWith(); 16288 16289 //Shouldn't be run the first time through due to massive slow-down 16290 if ( connectWith && this.ready ) { 16291 for ( i = connectWith.length - 1; i >= 0; i-- ) { 16292 cur = $( connectWith[ i ], this.document[ 0 ] ); 16293 for ( j = cur.length - 1; j >= 0; j-- ) { 16294 inst = $.data( cur[ j ], this.widgetFullName ); 16295 if ( inst && inst !== this && !inst.options.disabled ) { 16296 queries.push( [ typeof inst.options.items === "function" ? 16297 inst.options.items 16298 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 16299 $( inst.options.items, inst.element ), inst ] ); 16300 this.containers.push( inst ); 16301 } 16302 } 16303 } 16304 } 16305 16306 for ( i = queries.length - 1; i >= 0; i-- ) { 16307 targetData = queries[ i ][ 1 ]; 16308 _queries = queries[ i ][ 0 ]; 16309 16310 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 16311 item = $( _queries[ j ] ); 16312 16313 // Data for target checking (mouse manager) 16314 item.data( this.widgetName + "-item", targetData ); 16315 16316 items.push( { 16317 item: item, 16318 instance: targetData, 16319 width: 0, height: 0, 16320 left: 0, top: 0 16321 } ); 16322 } 16323 } 16324 16325 }, 16326 16327 _refreshItemPositions: function( fast ) { 16328 var i, item, t, p; 16329 16330 for ( i = this.items.length - 1; i >= 0; i-- ) { 16331 item = this.items[ i ]; 16332 16333 //We ignore calculating positions of all connected containers when we're not over them 16334 if ( this.currentContainer && item.instance !== this.currentContainer && 16335 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 16336 continue; 16337 } 16338 16339 t = this.options.toleranceElement ? 16340 $( this.options.toleranceElement, item.item ) : 16341 item.item; 16342 16343 if ( !fast ) { 16344 item.width = t.outerWidth(); 16345 item.height = t.outerHeight(); 16346 } 16347 16348 p = t.offset(); 16349 item.left = p.left; 16350 item.top = p.top; 16351 } 16352 }, 16353 16354 refreshPositions: function( fast ) { 16355 16356 // Determine whether items are being displayed horizontally 16357 this.floating = this.items.length ? 16358 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 16359 false; 16360 16361 // This has to be redone because due to the item being moved out/into the offsetParent, 16362 // the offsetParent's position will change 16363 if ( this.offsetParent && this.helper ) { 16364 this.offset.parent = this._getParentOffset(); 16365 } 16366 16367 this._refreshItemPositions( fast ); 16368 16369 var i, p; 16370 16371 if ( this.options.custom && this.options.custom.refreshContainers ) { 16372 this.options.custom.refreshContainers.call( this ); 16373 } else { 16374 for ( i = this.containers.length - 1; i >= 0; i-- ) { 16375 p = this.containers[ i ].element.offset(); 16376 this.containers[ i ].containerCache.left = p.left; 16377 this.containers[ i ].containerCache.top = p.top; 16378 this.containers[ i ].containerCache.width = 16379 this.containers[ i ].element.outerWidth(); 16380 this.containers[ i ].containerCache.height = 16381 this.containers[ i ].element.outerHeight(); 16382 } 16383 } 16384 16385 return this; 16386 }, 16387 16388 _createPlaceholder: function( that ) { 16389 that = that || this; 16390 var className, nodeName, 16391 o = that.options; 16392 16393 if ( !o.placeholder || o.placeholder.constructor === String ) { 16394 className = o.placeholder; 16395 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); 16396 o.placeholder = { 16397 element: function() { 16398 16399 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); 16400 16401 that._addClass( element, "ui-sortable-placeholder", 16402 className || that.currentItem[ 0 ].className ) 16403 ._removeClass( element, "ui-sortable-helper" ); 16404 16405 if ( nodeName === "tbody" ) { 16406 that._createTrPlaceholder( 16407 that.currentItem.find( "tr" ).eq( 0 ), 16408 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 16409 ); 16410 } else if ( nodeName === "tr" ) { 16411 that._createTrPlaceholder( that.currentItem, element ); 16412 } else if ( nodeName === "img" ) { 16413 element.attr( "src", that.currentItem.attr( "src" ) ); 16414 } 16415 16416 if ( !className ) { 16417 element.css( "visibility", "hidden" ); 16418 } 16419 16420 return element; 16421 }, 16422 update: function( container, p ) { 16423 16424 // 1. If a className is set as 'placeholder option, we don't force sizes - 16425 // the class is responsible for that 16426 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 16427 // class name is specified 16428 if ( className && !o.forcePlaceholderSize ) { 16429 return; 16430 } 16431 16432 // If the element doesn't have a actual height or width by itself (without 16433 // styles coming from a stylesheet), it receives the inline height and width 16434 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height 16435 // anyway since we're populating them with <td>s above, but they're unlikely to 16436 // be the correct height on their own if the row heights are dynamic, so we'll 16437 // always assign the height of the dragged item given forcePlaceholderSize 16438 // is true. 16439 if ( !p.height() || ( o.forcePlaceholderSize && 16440 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { 16441 p.height( 16442 that.currentItem.innerHeight() - 16443 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 16444 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 16445 } 16446 if ( !p.width() ) { 16447 p.width( 16448 that.currentItem.innerWidth() - 16449 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 16450 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 16451 } 16452 } 16453 }; 16454 } 16455 16456 //Create the placeholder 16457 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 16458 16459 //Append it after the actual current item 16460 that.currentItem.after( that.placeholder ); 16461 16462 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 16463 o.placeholder.update( that, that.placeholder ); 16464 16465 }, 16466 16467 _createTrPlaceholder: function( sourceTr, targetTr ) { 16468 var that = this; 16469 16470 sourceTr.children().each( function() { 16471 $( "<td> </td>", that.document[ 0 ] ) 16472 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 16473 .appendTo( targetTr ); 16474 } ); 16475 }, 16476 16477 _contactContainers: function( event ) { 16478 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 16479 floating, axis, 16480 innermostContainer = null, 16481 innermostIndex = null; 16482 16483 // Get innermost container that intersects with item 16484 for ( i = this.containers.length - 1; i >= 0; i-- ) { 16485 16486 // Never consider a container that's located within the item itself 16487 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 16488 continue; 16489 } 16490 16491 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 16492 16493 // If we've already found a container and it's more "inner" than this, then continue 16494 if ( innermostContainer && 16495 $.contains( 16496 this.containers[ i ].element[ 0 ], 16497 innermostContainer.element[ 0 ] ) ) { 16498 continue; 16499 } 16500 16501 innermostContainer = this.containers[ i ]; 16502 innermostIndex = i; 16503 16504 } else { 16505 16506 // container doesn't intersect. trigger "out" event if necessary 16507 if ( this.containers[ i ].containerCache.over ) { 16508 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 16509 this.containers[ i ].containerCache.over = 0; 16510 } 16511 } 16512 16513 } 16514 16515 // If no intersecting containers found, return 16516 if ( !innermostContainer ) { 16517 return; 16518 } 16519 16520 // Move the item into the container if it's not there already 16521 if ( this.containers.length === 1 ) { 16522 if ( !this.containers[ innermostIndex ].containerCache.over ) { 16523 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 16524 this.containers[ innermostIndex ].containerCache.over = 1; 16525 } 16526 } else { 16527 16528 // When entering a new container, we will find the item with the least distance and 16529 // append our item near it 16530 dist = 10000; 16531 itemWithLeastDistance = null; 16532 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 16533 posProperty = floating ? "left" : "top"; 16534 sizeProperty = floating ? "width" : "height"; 16535 axis = floating ? "pageX" : "pageY"; 16536 16537 for ( j = this.items.length - 1; j >= 0; j-- ) { 16538 if ( !$.contains( 16539 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 16540 ) { 16541 continue; 16542 } 16543 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 16544 continue; 16545 } 16546 16547 cur = this.items[ j ].item.offset()[ posProperty ]; 16548 nearBottom = false; 16549 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 16550 nearBottom = true; 16551 } 16552 16553 if ( Math.abs( event[ axis ] - cur ) < dist ) { 16554 dist = Math.abs( event[ axis ] - cur ); 16555 itemWithLeastDistance = this.items[ j ]; 16556 this.direction = nearBottom ? "up" : "down"; 16557 } 16558 } 16559 16560 //Check if dropOnEmpty is enabled 16561 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 16562 return; 16563 } 16564 16565 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 16566 if ( !this.currentContainer.containerCache.over ) { 16567 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 16568 this.currentContainer.containerCache.over = 1; 16569 } 16570 return; 16571 } 16572 16573 if ( itemWithLeastDistance ) { 16574 this._rearrange( event, itemWithLeastDistance, null, true ); 16575 } else { 16576 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 16577 } 16578 this._trigger( "change", event, this._uiHash() ); 16579 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 16580 this.currentContainer = this.containers[ innermostIndex ]; 16581 16582 //Update the placeholder 16583 this.options.placeholder.update( this.currentContainer, this.placeholder ); 16584 16585 //Update scrollParent 16586 this.scrollParent = this.placeholder.scrollParent(); 16587 16588 //Update overflowOffset 16589 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16590 this.scrollParent[ 0 ].tagName !== "HTML" ) { 16591 this.overflowOffset = this.scrollParent.offset(); 16592 } 16593 16594 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 16595 this.containers[ innermostIndex ].containerCache.over = 1; 16596 } 16597 16598 }, 16599 16600 _createHelper: function( event ) { 16601 16602 var o = this.options, 16603 helper = typeof o.helper === "function" ? 16604 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 16605 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 16606 16607 //Add the helper to the DOM if that didn't happen already 16608 if ( !helper.parents( "body" ).length ) { 16609 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); 16610 } 16611 16612 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 16613 this._storedCSS = { 16614 width: this.currentItem[ 0 ].style.width, 16615 height: this.currentItem[ 0 ].style.height, 16616 position: this.currentItem.css( "position" ), 16617 top: this.currentItem.css( "top" ), 16618 left: this.currentItem.css( "left" ) 16619 }; 16620 } 16621 16622 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 16623 helper.width( this.currentItem.width() ); 16624 } 16625 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 16626 helper.height( this.currentItem.height() ); 16627 } 16628 16629 return helper; 16630 16631 }, 16632 16633 _adjustOffsetFromHelper: function( obj ) { 16634 if ( typeof obj === "string" ) { 16635 obj = obj.split( " " ); 16636 } 16637 if ( Array.isArray( obj ) ) { 16638 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 16639 } 16640 if ( "left" in obj ) { 16641 this.offset.click.left = obj.left + this.margins.left; 16642 } 16643 if ( "right" in obj ) { 16644 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 16645 } 16646 if ( "top" in obj ) { 16647 this.offset.click.top = obj.top + this.margins.top; 16648 } 16649 if ( "bottom" in obj ) { 16650 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 16651 } 16652 }, 16653 16654 _getParentOffset: function() { 16655 16656 //Get the offsetParent and cache its position 16657 this.offsetParent = this.helper.offsetParent(); 16658 var po = this.offsetParent.offset(); 16659 16660 // This is a special case where we need to modify a offset calculated on start, since the 16661 // following happened: 16662 // 1. The position of the helper is absolute, so it's position is calculated based on the 16663 // next positioned parent 16664 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 16665 // the document, which means that the scroll is included in the initial calculation of the 16666 // offset of the parent, and never recalculated upon drag 16667 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 16668 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 16669 po.left += this.scrollParent.scrollLeft(); 16670 po.top += this.scrollParent.scrollTop(); 16671 } 16672 16673 // This needs to be actually done for all browsers, since pageX/pageY includes this 16674 // information with an ugly IE fix 16675 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || 16676 ( this.offsetParent[ 0 ].tagName && 16677 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { 16678 po = { top: 0, left: 0 }; 16679 } 16680 16681 return { 16682 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 16683 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 16684 }; 16685 16686 }, 16687 16688 _getRelativeOffset: function() { 16689 16690 if ( this.cssPosition === "relative" ) { 16691 var p = this.currentItem.position(); 16692 return { 16693 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 16694 this.scrollParent.scrollTop(), 16695 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 16696 this.scrollParent.scrollLeft() 16697 }; 16698 } else { 16699 return { top: 0, left: 0 }; 16700 } 16701 16702 }, 16703 16704 _cacheMargins: function() { 16705 this.margins = { 16706 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 16707 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 16708 }; 16709 }, 16710 16711 _cacheHelperProportions: function() { 16712 this.helperProportions = { 16713 width: this.helper.outerWidth(), 16714 height: this.helper.outerHeight() 16715 }; 16716 }, 16717 16718 _setContainment: function() { 16719 16720 var ce, co, over, 16721 o = this.options; 16722 if ( o.containment === "parent" ) { 16723 o.containment = this.helper[ 0 ].parentNode; 16724 } 16725 if ( o.containment === "document" || o.containment === "window" ) { 16726 this.containment = [ 16727 0 - this.offset.relative.left - this.offset.parent.left, 16728 0 - this.offset.relative.top - this.offset.parent.top, 16729 o.containment === "document" ? 16730 this.document.width() : 16731 this.window.width() - this.helperProportions.width - this.margins.left, 16732 ( o.containment === "document" ? 16733 ( this.document.height() || document.body.parentNode.scrollHeight ) : 16734 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 16735 ) - this.helperProportions.height - this.margins.top 16736 ]; 16737 } 16738 16739 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 16740 ce = $( o.containment )[ 0 ]; 16741 co = $( o.containment ).offset(); 16742 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 16743 16744 this.containment = [ 16745 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 16746 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 16747 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 16748 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 16749 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 16750 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 16751 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 16752 this.helperProportions.width - this.margins.left, 16753 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 16754 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 16755 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 16756 this.helperProportions.height - this.margins.top 16757 ]; 16758 } 16759 16760 }, 16761 16762 _convertPositionTo: function( d, pos ) { 16763 16764 if ( !pos ) { 16765 pos = this.position; 16766 } 16767 var mod = d === "absolute" ? 1 : -1, 16768 scroll = this.cssPosition === "absolute" && 16769 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16770 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 16771 this.offsetParent : 16772 this.scrollParent, 16773 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 16774 16775 return { 16776 top: ( 16777 16778 // The absolute mouse position 16779 pos.top + 16780 16781 // Only for relative positioned nodes: Relative offset from element to offset parent 16782 this.offset.relative.top * mod + 16783 16784 // The offsetParent's offset without borders (offset + border) 16785 this.offset.parent.top * mod - 16786 ( ( this.cssPosition === "fixed" ? 16787 -this.scrollParent.scrollTop() : 16788 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 16789 ), 16790 left: ( 16791 16792 // The absolute mouse position 16793 pos.left + 16794 16795 // Only for relative positioned nodes: Relative offset from element to offset parent 16796 this.offset.relative.left * mod + 16797 16798 // The offsetParent's offset without borders (offset + border) 16799 this.offset.parent.left * mod - 16800 ( ( this.cssPosition === "fixed" ? 16801 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : 16802 scroll.scrollLeft() ) * mod ) 16803 ) 16804 }; 16805 16806 }, 16807 16808 _generatePosition: function( event ) { 16809 16810 var top, left, 16811 o = this.options, 16812 pageX = event.pageX, 16813 pageY = event.pageY, 16814 scroll = this.cssPosition === "absolute" && 16815 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16816 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 16817 this.offsetParent : 16818 this.scrollParent, 16819 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 16820 16821 // This is another very weird special case that only happens for relative elements: 16822 // 1. If the css position is relative 16823 // 2. and the scroll parent is the document or similar to the offset parent 16824 // we have to refresh the relative offset during the scroll so there are no jumps 16825 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16826 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 16827 this.offset.relative = this._getRelativeOffset(); 16828 } 16829 16830 /* 16831 * - Position constraining - 16832 * Constrain the position to a mix of grid, containment. 16833 */ 16834 16835 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 16836 16837 if ( this.containment ) { 16838 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 16839 pageX = this.containment[ 0 ] + this.offset.click.left; 16840 } 16841 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 16842 pageY = this.containment[ 1 ] + this.offset.click.top; 16843 } 16844 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 16845 pageX = this.containment[ 2 ] + this.offset.click.left; 16846 } 16847 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 16848 pageY = this.containment[ 3 ] + this.offset.click.top; 16849 } 16850 } 16851 16852 if ( o.grid ) { 16853 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 16854 o.grid[ 1 ] ) * o.grid[ 1 ]; 16855 pageY = this.containment ? 16856 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 16857 top - this.offset.click.top <= this.containment[ 3 ] ) ? 16858 top : 16859 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 16860 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 16861 top; 16862 16863 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 16864 o.grid[ 0 ] ) * o.grid[ 0 ]; 16865 pageX = this.containment ? 16866 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 16867 left - this.offset.click.left <= this.containment[ 2 ] ) ? 16868 left : 16869 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 16870 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 16871 left; 16872 } 16873 16874 } 16875 16876 return { 16877 top: ( 16878 16879 // The absolute mouse position 16880 pageY - 16881 16882 // Click offset (relative to the element) 16883 this.offset.click.top - 16884 16885 // Only for relative positioned nodes: Relative offset from element to offset parent 16886 this.offset.relative.top - 16887 16888 // The offsetParent's offset without borders (offset + border) 16889 this.offset.parent.top + 16890 ( ( this.cssPosition === "fixed" ? 16891 -this.scrollParent.scrollTop() : 16892 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 16893 ), 16894 left: ( 16895 16896 // The absolute mouse position 16897 pageX - 16898 16899 // Click offset (relative to the element) 16900 this.offset.click.left - 16901 16902 // Only for relative positioned nodes: Relative offset from element to offset parent 16903 this.offset.relative.left - 16904 16905 // The offsetParent's offset without borders (offset + border) 16906 this.offset.parent.left + 16907 ( ( this.cssPosition === "fixed" ? 16908 -this.scrollParent.scrollLeft() : 16909 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 16910 ) 16911 }; 16912 16913 }, 16914 16915 _rearrange: function( event, i, a, hardRefresh ) { 16916 16917 if ( a ) { 16918 a[ 0 ].appendChild( this.placeholder[ 0 ] ); 16919 } else { 16920 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 16921 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 16922 } 16923 16924 //Various things done here to improve the performance: 16925 // 1. we create a setTimeout, that calls refreshPositions 16926 // 2. on the instance, we have a counter variable, that get's higher after every append 16927 // 3. on the local scope, we copy the counter variable, and check in the timeout, 16928 // if it's still the same 16929 // 4. this lets only the last addition to the timeout stack through 16930 this.counter = this.counter ? ++this.counter : 1; 16931 var counter = this.counter; 16932 16933 this._delay( function() { 16934 if ( counter === this.counter ) { 16935 16936 //Precompute after each DOM insertion, NOT on mousemove 16937 this.refreshPositions( !hardRefresh ); 16938 } 16939 } ); 16940 16941 }, 16942 16943 _clear: function( event, noPropagation ) { 16944 16945 this.reverting = false; 16946 16947 // We delay all events that have to be triggered to after the point where the placeholder 16948 // has been removed and everything else normalized again 16949 var i, 16950 delayedTriggers = []; 16951 16952 // We first have to update the dom position of the actual currentItem 16953 // Note: don't do it if the current item is already removed (by a user), or it gets 16954 // reappended (see #4088) 16955 if ( !this._noFinalSort && this.currentItem.parent().length ) { 16956 this.placeholder.before( this.currentItem ); 16957 } 16958 this._noFinalSort = null; 16959 16960 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 16961 for ( i in this._storedCSS ) { 16962 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 16963 this._storedCSS[ i ] = ""; 16964 } 16965 } 16966 this.currentItem.css( this._storedCSS ); 16967 this._removeClass( this.currentItem, "ui-sortable-helper" ); 16968 } else { 16969 this.currentItem.show(); 16970 } 16971 16972 if ( this.fromOutside && !noPropagation ) { 16973 delayedTriggers.push( function( event ) { 16974 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 16975 } ); 16976 } 16977 if ( ( this.fromOutside || 16978 this.domPosition.prev !== 16979 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 16980 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 16981 16982 // Trigger update callback if the DOM position has changed 16983 delayedTriggers.push( function( event ) { 16984 this._trigger( "update", event, this._uiHash() ); 16985 } ); 16986 } 16987 16988 // Check if the items Container has Changed and trigger appropriate 16989 // events. 16990 if ( this !== this.currentContainer ) { 16991 if ( !noPropagation ) { 16992 delayedTriggers.push( function( event ) { 16993 this._trigger( "remove", event, this._uiHash() ); 16994 } ); 16995 delayedTriggers.push( ( function( c ) { 16996 return function( event ) { 16997 c._trigger( "receive", event, this._uiHash( this ) ); 16998 }; 16999 } ).call( this, this.currentContainer ) ); 17000 delayedTriggers.push( ( function( c ) { 17001 return function( event ) { 17002 c._trigger( "update", event, this._uiHash( this ) ); 17003 }; 17004 } ).call( this, this.currentContainer ) ); 17005 } 17006 } 17007 17008 //Post events to containers 17009 function delayEvent( type, instance, container ) { 17010 return function( event ) { 17011 container._trigger( type, event, instance._uiHash( instance ) ); 17012 }; 17013 } 17014 for ( i = this.containers.length - 1; i >= 0; i-- ) { 17015 if ( !noPropagation ) { 17016 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 17017 } 17018 if ( this.containers[ i ].containerCache.over ) { 17019 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 17020 this.containers[ i ].containerCache.over = 0; 17021 } 17022 } 17023 17024 //Do what was originally in plugins 17025 if ( this.storedCursor ) { 17026 this.document.find( "body" ).css( "cursor", this.storedCursor ); 17027 this.storedStylesheet.remove(); 17028 } 17029 if ( this._storedOpacity ) { 17030 this.helper.css( "opacity", this._storedOpacity ); 17031 } 17032 if ( this._storedZIndex ) { 17033 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 17034 } 17035 17036 this.dragging = false; 17037 17038 if ( !noPropagation ) { 17039 this._trigger( "beforeStop", event, this._uiHash() ); 17040 } 17041 17042 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 17043 // it unbinds ALL events from the original node! 17044 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 17045 17046 if ( !this.cancelHelperRemoval ) { 17047 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 17048 this.helper.remove(); 17049 } 17050 this.helper = null; 17051 } 17052 17053 if ( !noPropagation ) { 17054 for ( i = 0; i < delayedTriggers.length; i++ ) { 17055 17056 // Trigger all delayed events 17057 delayedTriggers[ i ].call( this, event ); 17058 } 17059 this._trigger( "stop", event, this._uiHash() ); 17060 } 17061 17062 this.fromOutside = false; 17063 return !this.cancelHelperRemoval; 17064 17065 }, 17066 17067 _trigger: function() { 17068 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 17069 this.cancel(); 17070 } 17071 }, 17072 17073 _uiHash: function( _inst ) { 17074 var inst = _inst || this; 17075 return { 17076 helper: inst.helper, 17077 placeholder: inst.placeholder || $( [] ), 17078 position: inst.position, 17079 originalPosition: inst.originalPosition, 17080 offset: inst.positionAbs, 17081 item: inst.currentItem, 17082 sender: _inst ? _inst.element : null 17083 }; 17084 } 17085 17086} ); 17087 17088 17089/*! 17090 * jQuery UI Spinner 1.13.
170902 17091 * http://jqueryui.com 17092 * 17093 * Copyright jQuery Foundation and other contributors 17094 * Released under the MIT license. 17095 * http://jquery.org/license 17096 */ 17097 17098//>>label: Spinner 17099//>>group: Widgets 17100//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 17101//>>docs: http://api.jqueryui.com/spinner/ 17102//>>demos: http://jqueryui.com/spinner/ 17103//>>css.structure: ../../themes/base/core.css 17104//>>css.structure: ../../themes/base/spinner.css 17105//>>css.theme: ../../themes/base/theme.css 17106 17107 17108function spinnerModifier( fn ) { 17109 return function() { 17110 var previous = this.element.val(); 17111 fn.apply( this, arguments ); 17112 this._refresh(); 17113 if ( previous !== this.element.val() ) { 17114 this._trigger( "change" ); 17115 } 17116 }; 17117} 17118 17119$.widget( "ui.spinner", { 17120 version: "1.13.2
vendor: 13,310 bytes, lines 17120-17651
17120", 17121 defaultElement: "<input>", 17122 widgetEventPrefix: "spin", 17123 options: { 17124 classes: { 17125 "ui-spinner": "ui-corner-all", 17126 "ui-spinner-down": "ui-corner-br", 17127 "ui-spinner-up": "ui-corner-tr" 17128 }, 17129 culture: null, 17130 icons: { 17131 down: "ui-icon-triangle-1-s", 17132 up: "ui-icon-triangle-1-n" 17133 }, 17134 incremental: true, 17135 max: null, 17136 min: null, 17137 numberFormat: null, 17138 page: 10, 17139 step: 1, 17140 17141 change: null, 17142 spin: null, 17143 start: null, 17144 stop: null 17145 }, 17146 17147 _create: function() { 17148 17149 // handle string values that need to be parsed 17150 this._setOption( "max", this.options.max ); 17151 this._setOption( "min", this.options.min ); 17152 this._setOption( "step", this.options.step ); 17153 17154 // Only format if there is a value, prevents the field from being marked 17155 // as invalid in Firefox, see #9573. 17156 if ( this.value() !== "" ) { 17157 17158 // Format the value, but don't constrain. 17159 this._value( this.element.val(), true ); 17160 } 17161 17162 this._draw(); 17163 this._on( this._events ); 17164 this._refresh(); 17165 17166 // Turning off autocomplete prevents the browser from remembering the 17167 // value when navigating through history, so we re-enable autocomplete 17168 // if the page is unloaded before the widget is destroyed. #7790 17169 this._on( this.window, { 17170 beforeunload: function() { 17171 this.element.removeAttr( "autocomplete" ); 17172 } 17173 } ); 17174 }, 17175 17176 _getCreateOptions: function() { 17177 var options = this._super(); 17178 var element = this.element; 17179 17180 $.each( [ "min", "max", "step" ], function( i, option ) { 17181 var value = element.attr( option ); 17182 if ( value != null && value.length ) { 17183 options[ option ] = value; 17184 } 17185 } ); 17186 17187 return options; 17188 }, 17189 17190 _events: { 17191 keydown: function( event ) { 17192 if ( this._start( event ) && this._keydown( event ) ) { 17193 event.preventDefault(); 17194 } 17195 }, 17196 keyup: "_stop", 17197 focus: function() { 17198 this.previous = this.element.val(); 17199 }, 17200 blur: function( event ) { 17201 if ( this.cancelBlur ) { 17202 delete this.cancelBlur; 17203 return; 17204 } 17205 17206 this._stop(); 17207 this._refresh(); 17208 if ( this.previous !== this.element.val() ) { 17209 this._trigger( "change", event ); 17210 } 17211 }, 17212 mousewheel: function( event, delta ) { 17213 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); 17214 var isActive = this.element[ 0 ] === activeElement; 17215 17216 if ( !isActive || !delta ) { 17217 return; 17218 } 17219 17220 if ( !this.spinning && !this._start( event ) ) { 17221 return false; 17222 } 17223 17224 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 17225 clearTimeout( this.mousewheelTimer ); 17226 this.mousewheelTimer = this._delay( function() { 17227 if ( this.spinning ) { 17228 this._stop( event ); 17229 } 17230 }, 100 ); 17231 event.preventDefault(); 17232 }, 17233 "mousedown .ui-spinner-button": function( event ) { 17234 var previous; 17235 17236 // We never want the buttons to have focus; whenever the user is 17237 // interacting with the spinner, the focus should be on the input. 17238 // If the input is focused then this.previous is properly set from 17239 // when the input first received focus. If the input is not focused 17240 // then we need to set this.previous based on the value before spinning. 17241 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? 17242 this.previous : this.element.val(); 17243 function checkFocus() { 17244 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); 17245 if ( !isActive ) { 17246 this.element.trigger( "focus" ); 17247 this.previous = previous; 17248 17249 // support: IE 17250 // IE sets focus asynchronously, so we need to check if focus 17251 // moved off of the input because the user clicked on the button. 17252 this._delay( function() { 17253 this.previous = previous; 17254 } ); 17255 } 17256 } 17257 17258 // Ensure focus is on (or stays on) the text field 17259 event.preventDefault(); 17260 checkFocus.call( this ); 17261 17262 // Support: IE 17263 // IE doesn't prevent moving focus even with event.preventDefault() 17264 // so we set a flag to know when we should ignore the blur event 17265 // and check (again) if focus moved off of the input. 17266 this.cancelBlur = true; 17267 this._delay( function() { 17268 delete this.cancelBlur; 17269 checkFocus.call( this ); 17270 } ); 17271 17272 if ( this._start( event ) === false ) { 17273 return; 17274 } 17275 17276 this._repeat( null, $( event.currentTarget ) 17277 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 17278 }, 17279 "mouseup .ui-spinner-button": "_stop", 17280 "mouseenter .ui-spinner-button": function( event ) { 17281 17282 // button will add ui-state-active if mouse was down while mouseleave and kept down 17283 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 17284 return; 17285 } 17286 17287 if ( this._start( event ) === false ) { 17288 return false; 17289 } 17290 this._repeat( null, $( event.currentTarget ) 17291 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 17292 }, 17293 17294 // TODO: do we really want to consider this a stop? 17295 // shouldn't we just stop the repeater and wait until mouseup before 17296 // we trigger the stop event? 17297 "mouseleave .ui-spinner-button": "_stop" 17298 }, 17299 17300 // Support mobile enhanced option and make backcompat more sane 17301 _enhance: function() { 17302 this.uiSpinner = this.element 17303 .attr( "autocomplete", "off" ) 17304 .wrap( "<span>" ) 17305 .parent() 17306 17307 // Add buttons 17308 .append( 17309 "<a></a><a></a>" 17310 ); 17311 }, 17312 17313 _draw: function() { 17314 this._enhance(); 17315 17316 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 17317 this._addClass( "ui-spinner-input" ); 17318 17319 this.element.attr( "role", "spinbutton" ); 17320 17321 // Button bindings 17322 this.buttons = this.uiSpinner.children( "a" ) 17323 .attr( "tabIndex", -1 ) 17324 .attr( "aria-hidden", true ) 17325 .button( { 17326 classes: { 17327 "ui-button": "" 17328 } 17329 } ); 17330 17331 // TODO: Right now button does not support classes this is already updated in button PR 17332 this._removeClass( this.buttons, "ui-corner-all" ); 17333 17334 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 17335 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 17336 this.buttons.first().button( { 17337 "icon": this.options.icons.up, 17338 "showLabel": false 17339 } ); 17340 this.buttons.last().button( { 17341 "icon": this.options.icons.down, 17342 "showLabel": false 17343 } ); 17344 17345 // IE 6 doesn't understand height: 50% for the buttons 17346 // unless the wrapper has an explicit height 17347 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 17348 this.uiSpinner.height() > 0 ) { 17349 this.uiSpinner.height( this.uiSpinner.height() ); 17350 } 17351 }, 17352 17353 _keydown: function( event ) { 17354 var options = this.options, 17355 keyCode = $.ui.keyCode; 17356 17357 switch ( event.keyCode ) { 17358 case keyCode.UP: 17359 this._repeat( null, 1, event ); 17360 return true; 17361 case keyCode.DOWN: 17362 this._repeat( null, -1, event ); 17363 return true; 17364 case keyCode.PAGE_UP: 17365 this._repeat( null, options.page, event ); 17366 return true; 17367 case keyCode.PAGE_DOWN: 17368 this._repeat( null, -options.page, event ); 17369 return true; 17370 } 17371 17372 return false; 17373 }, 17374 17375 _start: function( event ) { 17376 if ( !this.spinning && this._trigger( "start", event ) === false ) { 17377 return false; 17378 } 17379 17380 if ( !this.counter ) { 17381 this.counter = 1; 17382 } 17383 this.spinning = true; 17384 return true; 17385 }, 17386 17387 _repeat: function( i, steps, event ) { 17388 i = i || 500; 17389 17390 clearTimeout( this.timer ); 17391 this.timer = this._delay( function() { 17392 this._repeat( 40, steps, event ); 17393 }, i ); 17394 17395 this._spin( steps * this.options.step, event ); 17396 }, 17397 17398 _spin: function( step, event ) { 17399 var value = this.value() || 0; 17400 17401 if ( !this.counter ) { 17402 this.counter = 1; 17403 } 17404 17405 value = this._adjustValue( value + step * this._increment( this.counter ) ); 17406 17407 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 17408 this._value( value ); 17409 this.counter++; 17410 } 17411 }, 17412 17413 _increment: function( i ) { 17414 var incremental = this.options.incremental; 17415 17416 if ( incremental ) { 17417 return typeof incremental === "function" ? 17418 incremental( i ) : 17419 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 17420 } 17421 17422 return 1; 17423 }, 17424 17425 _precision: function() { 17426 var precision = this._precisionOf( this.options.step ); 17427 if ( this.options.min !== null ) { 17428 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 17429 } 17430 return precision; 17431 }, 17432 17433 _precisionOf: function( num ) { 17434 var str = num.toString(), 17435 decimal = str.indexOf( "." ); 17436 return decimal === -1 ? 0 : str.length - decimal - 1; 17437 }, 17438 17439 _adjustValue: function( value ) { 17440 var base, aboveMin, 17441 options = this.options; 17442 17443 // Make sure we're at a valid step 17444 // - find out where we are relative to the base (min or 0) 17445 base = options.min !== null ? options.min : 0; 17446 aboveMin = value - base; 17447 17448 // - round to the nearest step 17449 aboveMin = Math.round( aboveMin / options.step ) * options.step; 17450 17451 // - rounding is based on 0, so adjust back to our base 17452 value = base + aboveMin; 17453 17454 // Fix precision from bad JS floating point math 17455 value = parseFloat( value.toFixed( this._precision() ) ); 17456 17457 // Clamp the value 17458 if ( options.max !== null && value > options.max ) { 17459 return options.max; 17460 } 17461 if ( options.min !== null && value < options.min ) { 17462 return options.min; 17463 } 17464 17465 return value; 17466 }, 17467 17468 _stop: function( event ) { 17469 if ( !this.spinning ) { 17470 return; 17471 } 17472 17473 clearTimeout( this.timer ); 17474 clearTimeout( this.mousewheelTimer ); 17475 this.counter = 0; 17476 this.spinning = false; 17477 this._trigger( "stop", event ); 17478 }, 17479 17480 _setOption: function( key, value ) { 17481 var prevValue, first, last; 17482 17483 if ( key === "culture" || key === "numberFormat" ) { 17484 prevValue = this._parse( this.element.val() ); 17485 this.options[ key ] = value; 17486 this.element.val( this._format( prevValue ) ); 17487 return; 17488 } 17489 17490 if ( key === "max" || key === "min" || key === "step" ) { 17491 if ( typeof value === "string" ) { 17492 value = this._parse( value ); 17493 } 17494 } 17495 if ( key === "icons" ) { 17496 first = this.buttons.first().find( ".ui-icon" ); 17497 this._removeClass( first, null, this.options.icons.up ); 17498 this._addClass( first, null, value.up ); 17499 last = this.buttons.last().find( ".ui-icon" ); 17500 this._removeClass( last, null, this.options.icons.down ); 17501 this._addClass( last, null, value.down ); 17502 } 17503 17504 this._super( key, value ); 17505 }, 17506 17507 _setOptionDisabled: function( value ) { 17508 this._super( value ); 17509 17510 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 17511 this.element.prop( "disabled", !!value ); 17512 this.buttons.button( value ? "disable" : "enable" ); 17513 }, 17514 17515 _setOptions: spinnerModifier( function( options ) { 17516 this._super( options ); 17517 } ), 17518 17519 _parse: function( val ) { 17520 if ( typeof val === "string" && val !== "" ) { 17521 val = window.Globalize && this.options.numberFormat ? 17522 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 17523 } 17524 return val === "" || isNaN( val ) ? null : val; 17525 }, 17526 17527 _format: function( value ) { 17528 if ( value === "" ) { 17529 return ""; 17530 } 17531 return window.Globalize && this.options.numberFormat ? 17532 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 17533 value; 17534 }, 17535 17536 _refresh: function() { 17537 this.element.attr( { 17538 "aria-valuemin": this.options.min, 17539 "aria-valuemax": this.options.max, 17540 17541 // TODO: what should we do with values that can't be parsed? 17542 "aria-valuenow": this._parse( this.element.val() ) 17543 } ); 17544 }, 17545 17546 isValid: function() { 17547 var value = this.value(); 17548 17549 // Null is invalid 17550 if ( value === null ) { 17551 return false; 17552 } 17553 17554 // If value gets adjusted, it's invalid 17555 return value === this._adjustValue( value ); 17556 }, 17557 17558 // Update the value without triggering change 17559 _value: function( value, allowAny ) { 17560 var parsed; 17561 if ( value !== "" ) { 17562 parsed = this._parse( value ); 17563 if ( parsed !== null ) { 17564 if ( !allowAny ) { 17565 parsed = this._adjustValue( parsed ); 17566 } 17567 value = this._format( parsed ); 17568 } 17569 } 17570 this.element.val( value ); 17571 this._refresh(); 17572 }, 17573 17574 _destroy: function() { 17575 this.element 17576 .prop( "disabled", false ) 17577 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 17578 17579 this.uiSpinner.replaceWith( this.element ); 17580 }, 17581 17582 stepUp: spinnerModifier( function( steps ) { 17583 this._stepUp( steps ); 17584 } ), 17585 _stepUp: function( steps ) { 17586 if ( this._start() ) { 17587 this._spin( ( steps || 1 ) * this.options.step ); 17588 this._stop(); 17589 } 17590 }, 17591 17592 stepDown: spinnerModifier( function( steps ) { 17593 this._stepDown( steps ); 17594 } ), 17595 _stepDown: function( steps ) { 17596 if ( this._start() ) { 17597 this._spin( ( steps || 1 ) * -this.options.step ); 17598 this._stop(); 17599 } 17600 }, 17601 17602 pageUp: spinnerModifier( function( pages ) { 17603 this._stepUp( ( pages || 1 ) * this.options.page ); 17604 } ), 17605 17606 pageDown: spinnerModifier( function( pages ) { 17607 this._stepDown( ( pages || 1 ) * this.options.page ); 17608 } ), 17609 17610 value: function( newVal ) { 17611 if ( !arguments.length ) { 17612 return this._parse( this.element.val() ); 17613 } 17614 spinnerModifier( this._value ).call( this, newVal ); 17615 }, 17616 17617 widget: function() { 17618 return this.uiSpinner; 17619 } 17620} ); 17621 17622// DEPRECATED 17623// TODO: switch return back to widget declaration at top of file when this is removed 17624if ( $.uiBackCompat !== false ) { 17625 17626 // Backcompat for spinner html extension points 17627 $.widget( "ui.spinner", $.ui.spinner, { 17628 _enhance: function() { 17629 this.uiSpinner = this.element 17630 .attr( "autocomplete", "off" ) 17631 .wrap( this._uiSpinnerHtml() ) 17632 .parent() 17633 17634 // Add buttons 17635 .append( this._buttonHtml() ); 17636 }, 17637 _uiSpinnerHtml: function() { 17638 return "<span>"; 17639 }, 17640 17641 _buttonHtml: function() { 17642 return "<a></a><a></a>"; 17643 } 17644 } ); 17645} 17646 17647var widgetsSpinner = $.ui.spinner; 17648 17649 17650/*! 17651 * jQuery UI Tabs 1.13.
176512 17652 * http://jqueryui.com 17653 * 17654 * Copyright jQuery Foundation and other contributors 17655 * Released under the MIT license. 17656 * http://jquery.org/license 17657 */ 17658 17659//>>label: Tabs 17660//>>group: Widgets 17661//>>description: Transforms a set of container elements into a tab structure. 17662//>>docs: http://api.jqueryui.com/tabs/ 17663//>>demos: http://jqueryui.com/tabs/ 17664//>>css.structure: ../../themes/base/core.css 17665//>>css.structure: ../../themes/base/tabs.css 17666//>>css.theme: ../../themes/base/theme.css 17667 17668 17669$.widget( "ui.tabs", { 17670 version: "1.13.2
vendor: 21,408 bytes, lines 17670-18499
17670", 17671 delay: 300, 17672 options: { 17673 active: null, 17674 classes: { 17675 "ui-tabs": "ui-corner-all", 17676 "ui-tabs-nav": "ui-corner-all", 17677 "ui-tabs-panel": "ui-corner-bottom", 17678 "ui-tabs-tab": "ui-corner-top" 17679 }, 17680 collapsible: false, 17681 event: "click", 17682 heightStyle: "content", 17683 hide: null, 17684 show: null, 17685 17686 // Callbacks 17687 activate: null, 17688 beforeActivate: null, 17689 beforeLoad: null, 17690 load: null 17691 }, 17692 17693 _isLocal: ( function() { 17694 var rhash = /#.*$/; 17695 17696 return function( anchor ) { 17697 var anchorUrl, locationUrl; 17698 17699 anchorUrl = anchor.href.replace( rhash, "" ); 17700 locationUrl = location.href.replace( rhash, "" ); 17701 17702 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 17703 try { 17704 anchorUrl = decodeURIComponent( anchorUrl ); 17705 } catch ( error ) {} 17706 try { 17707 locationUrl = decodeURIComponent( locationUrl ); 17708 } catch ( error ) {} 17709 17710 return anchor.hash.length > 1 && anchorUrl === locationUrl; 17711 }; 17712 } )(), 17713 17714 _create: function() { 17715 var that = this, 17716 options = this.options; 17717 17718 this.running = false; 17719 17720 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 17721 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 17722 17723 this._processTabs(); 17724 options.active = this._initialActive(); 17725 17726 // Take disabling tabs via class attribute from HTML 17727 // into account and update option properly. 17728 if ( Array.isArray( options.disabled ) ) { 17729 options.disabled = $.uniqueSort( options.disabled.concat( 17730 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 17731 return that.tabs.index( li ); 17732 } ) 17733 ) ).sort(); 17734 } 17735 17736 // Check for length avoids error when initializing empty list 17737 if ( this.options.active !== false && this.anchors.length ) { 17738 this.active = this._findActive( options.active ); 17739 } else { 17740 this.active = $(); 17741 } 17742 17743 this._refresh(); 17744 17745 if ( this.active.length ) { 17746 this.load( options.active ); 17747 } 17748 }, 17749 17750 _initialActive: function() { 17751 var active = this.options.active, 17752 collapsible = this.options.collapsible, 17753 locationHash = location.hash.substring( 1 ); 17754 17755 if ( active === null ) { 17756 17757 // check the fragment identifier in the URL 17758 if ( locationHash ) { 17759 this.tabs.each( function( i, tab ) { 17760 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 17761 active = i; 17762 return false; 17763 } 17764 } ); 17765 } 17766 17767 // Check for a tab marked active via a class 17768 if ( active === null ) { 17769 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 17770 } 17771 17772 // No active tab, set to false 17773 if ( active === null || active === -1 ) { 17774 active = this.tabs.length ? 0 : false; 17775 } 17776 } 17777 17778 // Handle numbers: negative, out of range 17779 if ( active !== false ) { 17780 active = this.tabs.index( this.tabs.eq( active ) ); 17781 if ( active === -1 ) { 17782 active = collapsible ? false : 0; 17783 } 17784 } 17785 17786 // Don't allow collapsible: false and active: false 17787 if ( !collapsible && active === false && this.anchors.length ) { 17788 active = 0; 17789 } 17790 17791 return active; 17792 }, 17793 17794 _getCreateEventData: function() { 17795 return { 17796 tab: this.active, 17797 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 17798 }; 17799 }, 17800 17801 _tabKeydown: function( event ) { 17802 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), 17803 selectedIndex = this.tabs.index( focusedTab ), 17804 goingForward = true; 17805 17806 if ( this._handlePageNav( event ) ) { 17807 return; 17808 } 17809 17810 switch ( event.keyCode ) { 17811 case $.ui.keyCode.RIGHT: 17812 case $.ui.keyCode.DOWN: 17813 selectedIndex++; 17814 break; 17815 case $.ui.keyCode.UP: 17816 case $.ui.keyCode.LEFT: 17817 goingForward = false; 17818 selectedIndex--; 17819 break; 17820 case $.ui.keyCode.END: 17821 selectedIndex = this.anchors.length - 1; 17822 break; 17823 case $.ui.keyCode.HOME: 17824 selectedIndex = 0; 17825 break; 17826 case $.ui.keyCode.SPACE: 17827 17828 // Activate only, no collapsing 17829 event.preventDefault(); 17830 clearTimeout( this.activating ); 17831 this._activate( selectedIndex ); 17832 return; 17833 case $.ui.keyCode.ENTER: 17834 17835 // Toggle (cancel delayed activation, allow collapsing) 17836 event.preventDefault(); 17837 clearTimeout( this.activating ); 17838 17839 // Determine if we should collapse or activate 17840 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 17841 return; 17842 default: 17843 return; 17844 } 17845 17846 // Focus the appropriate tab, based on which key was pressed 17847 event.preventDefault(); 17848 clearTimeout( this.activating ); 17849 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 17850 17851 // Navigating with control/command key will prevent automatic activation 17852 if ( !event.ctrlKey && !event.metaKey ) { 17853 17854 // Update aria-selected immediately so that AT think the tab is already selected. 17855 // Otherwise AT may confuse the user by stating that they need to activate the tab, 17856 // but the tab will already be activated by the time the announcement finishes. 17857 focusedTab.attr( "aria-selected", "false" ); 17858 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 17859 17860 this.activating = this._delay( function() { 17861 this.option( "active", selectedIndex ); 17862 }, this.delay ); 17863 } 17864 }, 17865 17866 _panelKeydown: function( event ) { 17867 if ( this._handlePageNav( event ) ) { 17868 return; 17869 } 17870 17871 // Ctrl+up moves focus to the current tab 17872 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 17873 event.preventDefault(); 17874 this.active.trigger( "focus" ); 17875 } 17876 }, 17877 17878 // Alt+page up/down moves focus to the previous/next tab (and activates) 17879 _handlePageNav: function( event ) { 17880 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 17881 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 17882 return true; 17883 } 17884 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 17885 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 17886 return true; 17887 } 17888 }, 17889 17890 _findNextTab: function( index, goingForward ) { 17891 var lastTabIndex = this.tabs.length - 1; 17892 17893 function constrain() { 17894 if ( index > lastTabIndex ) { 17895 index = 0; 17896 } 17897 if ( index < 0 ) { 17898 index = lastTabIndex; 17899 } 17900 return index; 17901 } 17902 17903 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 17904 index = goingForward ? index + 1 : index - 1; 17905 } 17906 17907 return index; 17908 }, 17909 17910 _focusNextTab: function( index, goingForward ) { 17911 index = this._findNextTab( index, goingForward ); 17912 this.tabs.eq( index ).trigger( "focus" ); 17913 return index; 17914 }, 17915 17916 _setOption: function( key, value ) { 17917 if ( key === "active" ) { 17918 17919 // _activate() will handle invalid values and update this.options 17920 this._activate( value ); 17921 return; 17922 } 17923 17924 this._super( key, value ); 17925 17926 if ( key === "collapsible" ) { 17927 this._toggleClass( "ui-tabs-collapsible", null, value ); 17928 17929 // Setting collapsible: false while collapsed; open first panel 17930 if ( !value && this.options.active === false ) { 17931 this._activate( 0 ); 17932 } 17933 } 17934 17935 if ( key === "event" ) { 17936 this._setupEvents( value ); 17937 } 17938 17939 if ( key === "heightStyle" ) { 17940 this._setupHeightStyle( value ); 17941 } 17942 }, 17943 17944 _sanitizeSelector: function( hash ) { 17945 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 17946 }, 17947 17948 refresh: function() { 17949 var options = this.options, 17950 lis = this.tablist.children( ":has(a[href])" ); 17951 17952 // Get disabled tabs from class attribute from HTML 17953 // this will get converted to a boolean if needed in _refresh() 17954 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 17955 return lis.index( tab ); 17956 } ); 17957 17958 this._processTabs(); 17959 17960 // Was collapsed or no tabs 17961 if ( options.active === false || !this.anchors.length ) { 17962 options.active = false; 17963 this.active = $(); 17964 17965 // was active, but active tab is gone 17966 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 17967 17968 // all remaining tabs are disabled 17969 if ( this.tabs.length === options.disabled.length ) { 17970 options.active = false; 17971 this.active = $(); 17972 17973 // activate previous tab 17974 } else { 17975 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 17976 } 17977 17978 // was active, active tab still exists 17979 } else { 17980 17981 // make sure active index is correct 17982 options.active = this.tabs.index( this.active ); 17983 } 17984 17985 this._refresh(); 17986 }, 17987 17988 _refresh: function() { 17989 this._setOptionDisabled( this.options.disabled ); 17990 this._setupEvents( this.options.event ); 17991 this._setupHeightStyle( this.options.heightStyle ); 17992 17993 this.tabs.not( this.active ).attr( { 17994 "aria-selected": "false", 17995 "aria-expanded": "false", 17996 tabIndex: -1 17997 } ); 17998 this.panels.not( this._getPanelForTab( this.active ) ) 17999 .hide() 18000 .attr( { 18001 "aria-hidden": "true" 18002 } ); 18003 18004 // Make sure one tab is in the tab order 18005 if ( !this.active.length ) { 18006 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 18007 } else { 18008 this.active 18009 .attr( { 18010 "aria-selected": "true", 18011 "aria-expanded": "true", 18012 tabIndex: 0 18013 } ); 18014 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 18015 this._getPanelForTab( this.active ) 18016 .show() 18017 .attr( { 18018 "aria-hidden": "false" 18019 } ); 18020 } 18021 }, 18022 18023 _processTabs: function() { 18024 var that = this, 18025 prevTabs = this.tabs, 18026 prevAnchors = this.anchors, 18027 prevPanels = this.panels; 18028 18029 this.tablist = this._getList().attr( "role", "tablist" ); 18030 this._addClass( this.tablist, "ui-tabs-nav", 18031 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 18032 18033 // Prevent users from focusing disabled tabs via click 18034 this.tablist 18035 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 18036 if ( $( this ).is( ".ui-state-disabled" ) ) { 18037 event.preventDefault(); 18038 } 18039 } ) 18040 18041 // Support: IE <9 18042 // Preventing the default action in mousedown doesn't prevent IE 18043 // from focusing the element, so if the anchor gets focused, blur. 18044 // We don't have to worry about focusing the previously focused 18045 // element since clicking on a non-focusable element should focus 18046 // the body anyway. 18047 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { 18048 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 18049 this.blur(); 18050 } 18051 } ); 18052 18053 this.tabs = this.tablist.find( "> li:has(a[href])" ) 18054 .attr( { 18055 role: "tab", 18056 tabIndex: -1 18057 } ); 18058 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 18059 18060 this.anchors = this.tabs.map( function() { 18061 return $( "a", this )[ 0 ]; 18062 } ) 18063 .attr( { 18064 tabIndex: -1 18065 } ); 18066 this._addClass( this.anchors, "ui-tabs-anchor" ); 18067 18068 this.panels = $(); 18069 18070 this.anchors.each( function( i, anchor ) { 18071 var selector, panel, panelId, 18072 anchorId = $( anchor ).uniqueId().attr( "id" ), 18073 tab = $( anchor ).closest( "li" ), 18074 originalAriaControls = tab.attr( "aria-controls" ); 18075 18076 // Inline tab 18077 if ( that._isLocal( anchor ) ) { 18078 selector = anchor.hash; 18079 panelId = selector.substring( 1 ); 18080 panel = that.element.find( that._sanitizeSelector( selector ) ); 18081 18082 // remote tab 18083 } else { 18084 18085 // If the tab doesn't already have aria-controls, 18086 // generate an id by using a throw-away element 18087 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 18088 selector = "#" + panelId; 18089 panel = that.element.find( selector ); 18090 if ( !panel.length ) { 18091 panel = that._createPanel( panelId ); 18092 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 18093 } 18094 panel.attr( "aria-live", "polite" ); 18095 } 18096 18097 if ( panel.length ) { 18098 that.panels = that.panels.add( panel ); 18099 } 18100 if ( originalAriaControls ) { 18101 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 18102 } 18103 tab.attr( { 18104 "aria-controls": panelId, 18105 "aria-labelledby": anchorId 18106 } ); 18107 panel.attr( "aria-labelledby", anchorId ); 18108 } ); 18109 18110 this.panels.attr( "role", "tabpanel" ); 18111 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 18112 18113 // Avoid memory leaks (#10056) 18114 if ( prevTabs ) { 18115 this._off( prevTabs.not( this.tabs ) ); 18116 this._off( prevAnchors.not( this.anchors ) ); 18117 this._off( prevPanels.not( this.panels ) ); 18118 } 18119 }, 18120 18121 // Allow overriding how to find the list for rare usage scenarios (#7715) 18122 _getList: function() { 18123 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 18124 }, 18125 18126 _createPanel: function( id ) { 18127 return $( "<div>" ) 18128 .attr( "id", id ) 18129 .data( "ui-tabs-destroy", true ); 18130 }, 18131 18132 _setOptionDisabled: function( disabled ) { 18133 var currentItem, li, i; 18134 18135 if ( Array.isArray( disabled ) ) { 18136 if ( !disabled.length ) { 18137 disabled = false; 18138 } else if ( disabled.length === this.anchors.length ) { 18139 disabled = true; 18140 } 18141 } 18142 18143 // Disable tabs 18144 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 18145 currentItem = $( li ); 18146 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 18147 currentItem.attr( "aria-disabled", "true" ); 18148 this._addClass( currentItem, null, "ui-state-disabled" ); 18149 } else { 18150 currentItem.removeAttr( "aria-disabled" ); 18151 this._removeClass( currentItem, null, "ui-state-disabled" ); 18152 } 18153 } 18154 18155 this.options.disabled = disabled; 18156 18157 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 18158 disabled === true ); 18159 }, 18160 18161 _setupEvents: function( event ) { 18162 var events = {}; 18163 if ( event ) { 18164 $.each( event.split( " " ), function( index, eventName ) { 18165 events[ eventName ] = "_eventHandler"; 18166 } ); 18167 } 18168 18169 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 18170 18171 // Always prevent the default action, even when disabled 18172 this._on( true, this.anchors, { 18173 click: function( event ) { 18174 event.preventDefault(); 18175 } 18176 } ); 18177 this._on( this.anchors, events ); 18178 this._on( this.tabs, { keydown: "_tabKeydown" } ); 18179 this._on( this.panels, { keydown: "_panelKeydown" } ); 18180 18181 this._focusable( this.tabs ); 18182 this._hoverable( this.tabs ); 18183 }, 18184 18185 _setupHeightStyle: function( heightStyle ) { 18186 var maxHeight, 18187 parent = this.element.parent(); 18188 18189 if ( heightStyle === "fill" ) { 18190 maxHeight = parent.height(); 18191 maxHeight -= this.element.outerHeight() - this.element.height(); 18192 18193 this.element.siblings( ":visible" ).each( function() { 18194 var elem = $( this ), 18195 position = elem.css( "position" ); 18196 18197 if ( position === "absolute" || position === "fixed" ) { 18198 return; 18199 } 18200 maxHeight -= elem.outerHeight( true ); 18201 } ); 18202 18203 this.element.children().not( this.panels ).each( function() { 18204 maxHeight -= $( this ).outerHeight( true ); 18205 } ); 18206 18207 this.panels.each( function() { 18208 $( this ).height( Math.max( 0, maxHeight - 18209 $( this ).innerHeight() + $( this ).height() ) ); 18210 } ) 18211 .css( "overflow", "auto" ); 18212 } else if ( heightStyle === "auto" ) { 18213 maxHeight = 0; 18214 this.panels.each( function() { 18215 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 18216 } ).height( maxHeight ); 18217 } 18218 }, 18219 18220 _eventHandler: function( event ) { 18221 var options = this.options, 18222 active = this.active, 18223 anchor = $( event.currentTarget ), 18224 tab = anchor.closest( "li" ), 18225 clickedIsActive = tab[ 0 ] === active[ 0 ], 18226 collapsing = clickedIsActive && options.collapsible, 18227 toShow = collapsing ? $() : this._getPanelForTab( tab ), 18228 toHide = !active.length ? $() : this._getPanelForTab( active ), 18229 eventData = { 18230 oldTab: active, 18231 oldPanel: toHide, 18232 newTab: collapsing ? $() : tab, 18233 newPanel: toShow 18234 }; 18235 18236 event.preventDefault(); 18237 18238 if ( tab.hasClass( "ui-state-disabled" ) || 18239 18240 // tab is already loading 18241 tab.hasClass( "ui-tabs-loading" ) || 18242 18243 // can't switch durning an animation 18244 this.running || 18245 18246 // click on active header, but not collapsible 18247 ( clickedIsActive && !options.collapsible ) || 18248 18249 // allow canceling activation 18250 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 18251 return; 18252 } 18253 18254 options.active = collapsing ? false : this.tabs.index( tab ); 18255 18256 this.active = clickedIsActive ? $() : tab; 18257 if ( this.xhr ) { 18258 this.xhr.abort(); 18259 } 18260 18261 if ( !toHide.length && !toShow.length ) { 18262 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 18263 } 18264 18265 if ( toShow.length ) { 18266 this.load( this.tabs.index( tab ), event ); 18267 } 18268 this._toggle( event, eventData ); 18269 }, 18270 18271 // Handles show/hide for selecting tabs 18272 _toggle: function( event, eventData ) { 18273 var that = this, 18274 toShow = eventData.newPanel, 18275 toHide = eventData.oldPanel; 18276 18277 this.running = true; 18278 18279 function complete() { 18280 that.running = false; 18281 that._trigger( "activate", event, eventData ); 18282 } 18283 18284 function show() { 18285 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 18286 18287 if ( toShow.length && that.options.show ) { 18288 that._show( toShow, that.options.show, complete ); 18289 } else { 18290 toShow.show(); 18291 complete(); 18292 } 18293 } 18294 18295 // Start out by hiding, then showing, then completing 18296 if ( toHide.length && this.options.hide ) { 18297 this._hide( toHide, this.options.hide, function() { 18298 that._removeClass( eventData.oldTab.closest( "li" ), 18299 "ui-tabs-active", "ui-state-active" ); 18300 show(); 18301 } ); 18302 } else { 18303 this._removeClass( eventData.oldTab.closest( "li" ), 18304 "ui-tabs-active", "ui-state-active" ); 18305 toHide.hide(); 18306 show(); 18307 } 18308 18309 toHide.attr( "aria-hidden", "true" ); 18310 eventData.oldTab.attr( { 18311 "aria-selected": "false", 18312 "aria-expanded": "false" 18313 } ); 18314 18315 // If we're switching tabs, remove the old tab from the tab order. 18316 // If we're opening from collapsed state, remove the previous tab from the tab order. 18317 // If we're collapsing, then keep the collapsing tab in the tab order. 18318 if ( toShow.length && toHide.length ) { 18319 eventData.oldTab.attr( "tabIndex", -1 ); 18320 } else if ( toShow.length ) { 18321 this.tabs.filter( function() { 18322 return $( this ).attr( "tabIndex" ) === 0; 18323 } ) 18324 .attr( "tabIndex", -1 ); 18325 } 18326 18327 toShow.attr( "aria-hidden", "false" ); 18328 eventData.newTab.attr( { 18329 "aria-selected": "true", 18330 "aria-expanded": "true", 18331 tabIndex: 0 18332 } ); 18333 }, 18334 18335 _activate: function( index ) { 18336 var anchor, 18337 active = this._findActive( index ); 18338 18339 // Trying to activate the already active panel 18340 if ( active[ 0 ] === this.active[ 0 ] ) { 18341 return; 18342 } 18343 18344 // Trying to collapse, simulate a click on the current active header 18345 if ( !active.length ) { 18346 active = this.active; 18347 } 18348 18349 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 18350 this._eventHandler( { 18351 target: anchor, 18352 currentTarget: anchor, 18353 preventDefault: $.noop 18354 } ); 18355 }, 18356 18357 _findActive: function( index ) { 18358 return index === false ? $() : this.tabs.eq( index ); 18359 }, 18360 18361 _getIndex: function( index ) { 18362 18363 // meta-function to give users option to provide a href string instead of a numerical index. 18364 if ( typeof index === "string" ) { 18365 index = this.anchors.index( this.anchors.filter( "[href$='" + 18366 $.escapeSelector( index ) + "']" ) ); 18367 } 18368 18369 return index; 18370 }, 18371 18372 _destroy: function() { 18373 if ( this.xhr ) { 18374 this.xhr.abort(); 18375 } 18376 18377 this.tablist 18378 .removeAttr( "role" ) 18379 .off( this.eventNamespace ); 18380 18381 this.anchors 18382 .removeAttr( "role tabIndex" ) 18383 .removeUniqueId(); 18384 18385 this.tabs.add( this.panels ).each( function() { 18386 if ( $.data( this, "ui-tabs-destroy" ) ) { 18387 $( this ).remove(); 18388 } else { 18389 $( this ).removeAttr( "role tabIndex " + 18390 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 18391 } 18392 } ); 18393 18394 this.tabs.each( function() { 18395 var li = $( this ), 18396 prev = li.data( "ui-tabs-aria-controls" ); 18397 if ( prev ) { 18398 li 18399 .attr( "aria-controls", prev ) 18400 .removeData( "ui-tabs-aria-controls" ); 18401 } else { 18402 li.removeAttr( "aria-controls" ); 18403 } 18404 } ); 18405 18406 this.panels.show(); 18407 18408 if ( this.options.heightStyle !== "content" ) { 18409 this.panels.css( "height", "" ); 18410 } 18411 }, 18412 18413 enable: function( index ) { 18414 var disabled = this.options.disabled; 18415 if ( disabled === false ) { 18416 return; 18417 } 18418 18419 if ( index === undefined ) { 18420 disabled = false; 18421 } else { 18422 index = this._getIndex( index ); 18423 if ( Array.isArray( disabled ) ) { 18424 disabled = $.map( disabled, function( num ) { 18425 return num !== index ? num : null; 18426 } ); 18427 } else { 18428 disabled = $.map( this.tabs, function( li, num ) { 18429 return num !== index ? num : null; 18430 } ); 18431 } 18432 } 18433 this._setOptionDisabled( disabled ); 18434 }, 18435 18436 disable: function( index ) { 18437 var disabled = this.options.disabled; 18438 if ( disabled === true ) { 18439 return; 18440 } 18441 18442 if ( index === undefined ) { 18443 disabled = true; 18444 } else { 18445 index = this._getIndex( index ); 18446 if ( $.inArray( index, disabled ) !== -1 ) { 18447 return; 18448 } 18449 if ( Array.isArray( disabled ) ) { 18450 disabled = $.merge( [ index ], disabled ).sort(); 18451 } else { 18452 disabled = [ index ]; 18453 } 18454 } 18455 this._setOptionDisabled( disabled ); 18456 }, 18457 18458 load: function( index, event ) { 18459 index = this._getIndex( index ); 18460 var that = this, 18461 tab = this.tabs.eq( index ), 18462 anchor = tab.find( ".ui-tabs-anchor" ), 18463 panel = this._getPanelForTab( tab ), 18464 eventData = { 18465 tab: tab, 18466 panel: panel 18467 }, 18468 complete = function( jqXHR, status ) { 18469 if ( status === "abort" ) { 18470 that.panels.stop( false, true ); 18471 } 18472 18473 that._removeClass( tab, "ui-tabs-loading" ); 18474 panel.removeAttr( "aria-busy" ); 18475 18476 if ( jqXHR === that.xhr ) { 18477 delete that.xhr; 18478 } 18479 }; 18480 18481 // Not remote 18482 if ( this._isLocal( anchor[ 0 ] ) ) { 18483 return; 18484 } 18485 18486 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 18487 18488 // Support: jQuery <1.8 18489 // jQuery <1.8 returns false if the request is canceled in beforeSend, 18490 // but as of 1.8, $.ajax() always returns a jqXHR object. 18491 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 18492 this._addClass( tab, "ui-tabs-loading" ); 18493 panel.attr( "aria-busy", "true" ); 18494 18495 this.xhr 18496 .done( function( response, status, jqXHR ) { 18497 18498 // support: jQuery <1.8 18499 // http
18499://bugs.jquery.com/ticket/11778 18500 setTimeout( function() { 18501 panel.html( response ); 18502 that._trigger( "load", event, eventData ); 18503 18504 complete( jqXHR, status ); 18505 }, 1 ); 18506 } ) 18507 .fail( function( jqXHR, status ) { 18508 18509 // support: jQuery <1.8 18510 // http://bugs.jquery.com/ticket/11778 18511 setTimeout( function() { 18512 complete( jqXHR, status ); 18513 }, 1 ); 18514 } ); 18515 } 18516 }, 18517 18518 _ajaxSettings: function( anchor, event, eventData ) { 18519 var that = this; 18520 return { 18521
vendor: 1,423 bytes, lines 18522-18574
18522 // Support: IE <11 only 18523 // Strip any hash that exists to prevent errors with the Ajax request 18524 url: anchor.attr( "href" ).replace( /#.*$/, "" ), 18525 beforeSend: function( jqXHR, settings ) { 18526 return that._trigger( "beforeLoad", event, 18527 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 18528 } 18529 }; 18530 }, 18531 18532 _getPanelForTab: function( tab ) { 18533 var id = $( tab ).attr( "aria-controls" ); 18534 return this.element.find( this._sanitizeSelector( "#" + id ) ); 18535 } 18536} ); 18537 18538// DEPRECATED 18539// TODO: Switch return back to widget declaration at top of file when this is removed 18540if ( $.uiBackCompat !== false ) { 18541 18542 // Backcompat for ui-tab class (now ui-tabs-tab) 18543 $.widget( "ui.tabs", $.ui.tabs, { 18544 _processTabs: function() { 18545 this._superApply( arguments ); 18546 this._addClass( this.tabs, "ui-tab" ); 18547 } 18548 } ); 18549} 18550 18551var widgetsTabs = $.ui.tabs; 18552 18553 18554/*! 18555 * jQuery UI Tooltip 1.13.2 18556 * http://jqueryui.com 18557 * 18558 * Copyright jQuery Foundation and other contributors 18559 * Released under the MIT license. 18560 * http://jquery.org/license 18561 */ 18562 18563//>>label: Tooltip 18564//>>group: Widgets 18565//>>description: Shows additional information for any element on hover or focus. 18566//>>docs: http://api.jqueryui.com/tooltip/ 18567//>>demos: http://jqueryui.com/tooltip/ 18568//>>css.structure: ../../themes/base/core.css 18569//>>css.structure: ../../themes/base/tooltip.css 18570//>>css.theme: ../../themes/base/theme.css 18571 18572 18573$.widget( "ui.tooltip", { 18574 version: "1.13.2
vendor: 13,567 bytes, lines 18574-19062
18574", 18575 options: { 18576 classes: { 18577 "ui-tooltip": "ui-corner-all ui-widget-shadow" 18578 }, 18579 content: function() { 18580 var title = $( this ).attr( "title" ); 18581 18582 // Escape title, since we're going from an attribute to raw HTML 18583 return $( "<a>" ).text( title ).html(); 18584 }, 18585 hide: true, 18586 18587 // Disabled elements have inconsistent behavior across browsers (#8661) 18588 items: "[title]:not([disabled])", 18589 position: { 18590 my: "left top+15", 18591 at: "left bottom", 18592 collision: "flipfit flip" 18593 }, 18594 show: true, 18595 track: false, 18596 18597 // Callbacks 18598 close: null, 18599 open: null 18600 }, 18601 18602 _addDescribedBy: function( elem, id ) { 18603 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 18604 describedby.push( id ); 18605 elem 18606 .data( "ui-tooltip-id", id ) 18607 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 18608 }, 18609 18610 _removeDescribedBy: function( elem ) { 18611 var id = elem.data( "ui-tooltip-id" ), 18612 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 18613 index = $.inArray( id, describedby ); 18614 18615 if ( index !== -1 ) { 18616 describedby.splice( index, 1 ); 18617 } 18618 18619 elem.removeData( "ui-tooltip-id" ); 18620 describedby = String.prototype.trim.call( describedby.join( " " ) ); 18621 if ( describedby ) { 18622 elem.attr( "aria-describedby", describedby ); 18623 } else { 18624 elem.removeAttr( "aria-describedby" ); 18625 } 18626 }, 18627 18628 _create: function() { 18629 this._on( { 18630 mouseover: "open", 18631 focusin: "open" 18632 } ); 18633 18634 // IDs of generated tooltips, needed for destroy 18635 this.tooltips = {}; 18636 18637 // IDs of parent tooltips where we removed the title attribute 18638 this.parents = {}; 18639 18640 // Append the aria-live region so tooltips announce correctly 18641 this.liveRegion = $( "<div>" ) 18642 .attr( { 18643 role: "log", 18644 "aria-live": "assertive", 18645 "aria-relevant": "additions" 18646 } ) 18647 .appendTo( this.document[ 0 ].body ); 18648 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 18649 18650 this.disabledTitles = $( [] ); 18651 }, 18652 18653 _setOption: function( key, value ) { 18654 var that = this; 18655 18656 this._super( key, value ); 18657 18658 if ( key === "content" ) { 18659 $.each( this.tooltips, function( id, tooltipData ) { 18660 that._updateContent( tooltipData.element ); 18661 } ); 18662 } 18663 }, 18664 18665 _setOptionDisabled: function( value ) { 18666 this[ value ? "_disable" : "_enable" ](); 18667 }, 18668 18669 _disable: function() { 18670 var that = this; 18671 18672 // Close open tooltips 18673 $.each( this.tooltips, function( id, tooltipData ) { 18674 var event = $.Event( "blur" ); 18675 event.target = event.currentTarget = tooltipData.element[ 0 ]; 18676 that.close( event, true ); 18677 } ); 18678 18679 // Remove title attributes to prevent native tooltips 18680 this.disabledTitles = this.disabledTitles.add( 18681 this.element.find( this.options.items ).addBack() 18682 .filter( function() { 18683 var element = $( this ); 18684 if ( element.is( "[title]" ) ) { 18685 return element 18686 .data( "ui-tooltip-title", element.attr( "title" ) ) 18687 .removeAttr( "title" ); 18688 } 18689 } ) 18690 ); 18691 }, 18692 18693 _enable: function() { 18694 18695 // restore title attributes 18696 this.disabledTitles.each( function() { 18697 var element = $( this ); 18698 if ( element.data( "ui-tooltip-title" ) ) { 18699 element.attr( "title", element.data( "ui-tooltip-title" ) ); 18700 } 18701 } ); 18702 this.disabledTitles = $( [] ); 18703 }, 18704 18705 open: function( event ) { 18706 var that = this, 18707 target = $( event ? event.target : this.element ) 18708 18709 // we need closest here due to mouseover bubbling, 18710 // but always pointing at the same event target 18711 .closest( this.options.items ); 18712 18713 // No element to show a tooltip for or the tooltip is already open 18714 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 18715 return; 18716 } 18717 18718 if ( target.attr( "title" ) ) { 18719 target.data( "ui-tooltip-title", target.attr( "title" ) ); 18720 } 18721 18722 target.data( "ui-tooltip-open", true ); 18723 18724 // Kill parent tooltips, custom or native, for hover 18725 if ( event && event.type === "mouseover" ) { 18726 target.parents().each( function() { 18727 var parent = $( this ), 18728 blurEvent; 18729 if ( parent.data( "ui-tooltip-open" ) ) { 18730 blurEvent = $.Event( "blur" ); 18731 blurEvent.target = blurEvent.currentTarget = this; 18732 that.close( blurEvent, true ); 18733 } 18734 if ( parent.attr( "title" ) ) { 18735 parent.uniqueId(); 18736 that.parents[ this.id ] = { 18737 element: this, 18738 title: parent.attr( "title" ) 18739 }; 18740 parent.attr( "title", "" ); 18741 } 18742 } ); 18743 } 18744 18745 this._registerCloseHandlers( event, target ); 18746 this._updateContent( target, event ); 18747 }, 18748 18749 _updateContent: function( target, event ) { 18750 var content, 18751 contentOption = this.options.content, 18752 that = this, 18753 eventType = event ? event.type : null; 18754 18755 if ( typeof contentOption === "string" || contentOption.nodeType || 18756 contentOption.jquery ) { 18757 return this._open( event, target, contentOption ); 18758 } 18759 18760 content = contentOption.call( target[ 0 ], function( response ) { 18761 18762 // IE may instantly serve a cached response for ajax requests 18763 // delay this call to _open so the other call to _open runs first 18764 that._delay( function() { 18765 18766 // Ignore async response if tooltip was closed already 18767 if ( !target.data( "ui-tooltip-open" ) ) { 18768 return; 18769 } 18770 18771 // JQuery creates a special event for focusin when it doesn't 18772 // exist natively. To improve performance, the native event 18773 // object is reused and the type is changed. Therefore, we can't 18774 // rely on the type being correct after the event finished 18775 // bubbling, so we set it back to the previous value. (#8740) 18776 if ( event ) { 18777 event.type = eventType; 18778 } 18779 this._open( event, target, response ); 18780 } ); 18781 } ); 18782 if ( content ) { 18783 this._open( event, target, content ); 18784 } 18785 }, 18786 18787 _open: function( event, target, content ) { 18788 var tooltipData, tooltip, delayedShow, a11yContent, 18789 positionOption = $.extend( {}, this.options.position ); 18790 18791 if ( !content ) { 18792 return; 18793 } 18794 18795 // Content can be updated multiple times. If the tooltip already 18796 // exists, then just update the content and bail. 18797 tooltipData = this._find( target ); 18798 if ( tooltipData ) { 18799 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 18800 return; 18801 } 18802 18803 // If we have a title, clear it to prevent the native tooltip 18804 // we have to check first to avoid defining a title if none exists 18805 // (we don't want to cause an element to start matching [title]) 18806 // 18807 // We use removeAttr only for key events, to allow IE to export the correct 18808 // accessible attributes. For mouse events, set to empty string to avoid 18809 // native tooltip showing up (happens only when removing inside mouseover). 18810 if ( target.is( "[title]" ) ) { 18811 if ( event && event.type === "mouseover" ) { 18812 target.attr( "title", "" ); 18813 } else { 18814 target.removeAttr( "title" ); 18815 } 18816 } 18817 18818 tooltipData = this._tooltip( target ); 18819 tooltip = tooltipData.tooltip; 18820 this._addDescribedBy( target, tooltip.attr( "id" ) ); 18821 tooltip.find( ".ui-tooltip-content" ).html( content ); 18822 18823 // Support: Voiceover on OS X, JAWS on IE <= 9 18824 // JAWS announces deletions even when aria-relevant="additions" 18825 // Voiceover will sometimes re-read the entire log region's contents from the beginning 18826 this.liveRegion.children().hide(); 18827 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 18828 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 18829 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 18830 a11yContent.appendTo( this.liveRegion ); 18831 18832 function position( event ) { 18833 positionOption.of = event; 18834 if ( tooltip.is( ":hidden" ) ) { 18835 return; 18836 } 18837 tooltip.position( positionOption ); 18838 } 18839 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 18840 this._on( this.document, { 18841 mousemove: position 18842 } ); 18843 18844 // trigger once to override element-relative positioning 18845 position( event ); 18846 } else { 18847 tooltip.position( $.extend( { 18848 of: target 18849 }, this.options.position ) ); 18850 } 18851 18852 tooltip.hide(); 18853 18854 this._show( tooltip, this.options.show ); 18855 18856 // Handle tracking tooltips that are shown with a delay (#8644). As soon 18857 // as the tooltip is visible, position the tooltip using the most recent 18858 // event. 18859 // Adds the check to add the timers only when both delay and track options are set (#14682) 18860 if ( this.options.track && this.options.show && this.options.show.delay ) { 18861 delayedShow = this.delayedShow = setInterval( function() { 18862 if ( tooltip.is( ":visible" ) ) { 18863 position( positionOption.of ); 18864 clearInterval( delayedShow ); 18865 } 18866 }, 13 ); 18867 } 18868 18869 this._trigger( "open", event, { tooltip: tooltip } ); 18870 }, 18871 18872 _registerCloseHandlers: function( event, target ) { 18873 var events = { 18874 keyup: function( event ) { 18875 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 18876 var fakeEvent = $.Event( event ); 18877 fakeEvent.currentTarget = target[ 0 ]; 18878 this.close( fakeEvent, true ); 18879 } 18880 } 18881 }; 18882 18883 // Only bind remove handler for delegated targets. Non-delegated 18884 // tooltips will handle this in destroy. 18885 if ( target[ 0 ] !== this.element[ 0 ] ) { 18886 events.remove = function() { 18887 var targetElement = this._find( target ); 18888 if ( targetElement ) { 18889 this._removeTooltip( targetElement.tooltip ); 18890 } 18891 }; 18892 } 18893 18894 if ( !event || event.type === "mouseover" ) { 18895 events.mouseleave = "close"; 18896 } 18897 if ( !event || event.type === "focusin" ) { 18898 events.focusout = "close"; 18899 } 18900 this._on( true, target, events ); 18901 }, 18902 18903 close: function( event ) { 18904 var tooltip, 18905 that = this, 18906 target = $( event ? event.currentTarget : this.element ), 18907 tooltipData = this._find( target ); 18908 18909 // The tooltip may already be closed 18910 if ( !tooltipData ) { 18911 18912 // We set ui-tooltip-open immediately upon open (in open()), but only set the 18913 // additional data once there's actually content to show (in _open()). So even if the 18914 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 18915 // the period between open() and _open(). 18916 target.removeData( "ui-tooltip-open" ); 18917 return; 18918 } 18919 18920 tooltip = tooltipData.tooltip; 18921 18922 // Disabling closes the tooltip, so we need to track when we're closing 18923 // to avoid an infinite loop in case the tooltip becomes disabled on close 18924 if ( tooltipData.closing ) { 18925 return; 18926 } 18927 18928 // Clear the interval for delayed tracking tooltips 18929 clearInterval( this.delayedShow ); 18930 18931 // Only set title if we had one before (see comment in _open()) 18932 // If the title attribute has changed since open(), don't restore 18933 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 18934 target.attr( "title", target.data( "ui-tooltip-title" ) ); 18935 } 18936 18937 this._removeDescribedBy( target ); 18938 18939 tooltipData.hiding = true; 18940 tooltip.stop( true ); 18941 this._hide( tooltip, this.options.hide, function() { 18942 that._removeTooltip( $( this ) ); 18943 } ); 18944 18945 target.removeData( "ui-tooltip-open" ); 18946 this._off( target, "mouseleave focusout keyup" ); 18947 18948 // Remove 'remove' binding only on delegated targets 18949 if ( target[ 0 ] !== this.element[ 0 ] ) { 18950 this._off( target, "remove" ); 18951 } 18952 this._off( this.document, "mousemove" ); 18953 18954 if ( event && event.type === "mouseleave" ) { 18955 $.each( this.parents, function( id, parent ) { 18956 $( parent.element ).attr( "title", parent.title ); 18957 delete that.parents[ id ]; 18958 } ); 18959 } 18960 18961 tooltipData.closing = true; 18962 this._trigger( "close", event, { tooltip: tooltip } ); 18963 if ( !tooltipData.hiding ) { 18964 tooltipData.closing = false; 18965 } 18966 }, 18967 18968 _tooltip: function( element ) { 18969 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 18970 content = $( "<div>" ).appendTo( tooltip ), 18971 id = tooltip.uniqueId().attr( "id" ); 18972 18973 this._addClass( content, "ui-tooltip-content" ); 18974 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 18975 18976 tooltip.appendTo( this._appendTo( element ) ); 18977 18978 return this.tooltips[ id ] = { 18979 element: element, 18980 tooltip: tooltip 18981 }; 18982 }, 18983 18984 _find: function( target ) { 18985 var id = target.data( "ui-tooltip-id" ); 18986 return id ? this.tooltips[ id ] : null; 18987 }, 18988 18989 _removeTooltip: function( tooltip ) { 18990 18991 // Clear the interval for delayed tracking tooltips 18992 clearInterval( this.delayedShow ); 18993 18994 tooltip.remove(); 18995 delete this.tooltips[ tooltip.attr( "id" ) ]; 18996 }, 18997 18998 _appendTo: function( target ) { 18999 var element = target.closest( ".ui-front, dialog" ); 19000 19001 if ( !element.length ) { 19002 element = this.document[ 0 ].body; 19003 } 19004 19005 return element; 19006 }, 19007 19008 _destroy: function() { 19009 var that = this; 19010 19011 // Close open tooltips 19012 $.each( this.tooltips, function( id, tooltipData ) { 19013 19014 // Delegate to close method to handle common cleanup 19015 var event = $.Event( "blur" ), 19016 element = tooltipData.element; 19017 event.target = event.currentTarget = element[ 0 ]; 19018 that.close( event, true ); 19019 19020 // Remove immediately; destroying an open tooltip doesn't use the 19021 // hide animation 19022 $( "#" + id ).remove(); 19023 19024 // Restore the title 19025 if ( element.data( "ui-tooltip-title" ) ) { 19026 19027 // If the title attribute has changed since open(), don't restore 19028 if ( !element.attr( "title" ) ) { 19029 element.attr( "title", element.data( "ui-tooltip-title" ) ); 19030 } 19031 element.removeData( "ui-tooltip-title" ); 19032 } 19033 } ); 19034 this.liveRegion.remove(); 19035 } 19036} ); 19037 19038// DEPRECATED 19039// TODO: Switch return back to widget declaration at top of file when this is removed 19040if ( $.uiBackCompat !== false ) { 19041 19042 // Backcompat for tooltipClass option 19043 $.widget( "ui.tooltip", $.ui.tooltip, { 19044 options: { 19045 tooltipClass: null 19046 }, 19047 _tooltip: function() { 19048 var tooltipData = this._superApply( arguments ); 19049 if ( this.options.tooltipClass ) { 19050 tooltipData.tooltip.addClass( this.options.tooltipClass ); 19051 } 19052 return tooltipData; 19053 } 19054 } ); 19055} 19056 19057var widgetsTooltip = $.ui.tooltip; 19058 19059 19060 19061 19062} );
19062 19063// Copyright (c) 2009 Daniel Wachsstock 19064// MIT license: 19065// Permission is hereby granted, free of charge, to any person 19066// obtaining a copy of this software and associated documentation 19067// files (the "Software"), to deal in the Software without 19068// restriction, including without limitation the rights to use, 19069// copy, modify, merge, publish, distribute, sublicense, and/or sell 19070// copies of the Software, and to permit persons to whom the 19071// Software is furnished to do so, subject to the following 19072// conditions: 19073 19074// The above copyright notice and this permission notice shall be 19075// included in all copies or substantial portions of the Software. 19076 19077// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19078// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19079// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19080// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19081// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19082// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19083// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19084// OTHER DEALINGS IN THE SOFTWARE. 19085(function($){ 19086// create the master widget 19087 $.widget("ui.widget",{ 19088 // Aspect Oriented Programming tools from Justin Palmer's article 19089 'yield': null, 19090 returnValues: { }, 19091 before: function(method, f) { 19092 var original = this[method]; 19093 this[method] = function() { 19094 f.apply(this, arguments); 19095 return original.apply(this, arguments); 19096 }; 19097 }, 19098 after: function(method, f) { 19099 var original = this[method]; 19100 this[method] = function() { 19101 this.returnValues[method] = original.apply(this, arguments); 19102 return f.apply(this, arguments); 19103 } 19104 }, 19105 around: function(method, f) { 19106 var original = this[method]; 19107 this[method] = function() { 19108 var tmp = this["yield"]; 19109 this["yield"] = original; 19110 var ret = f.apply(this, arguments); 19111 this["yield"] = tmp; 19112 return ret; 19113 } 19114 } 19115 }); 19116 19117// from http://groups.google.com/group/comp.lang.javascript/msg/e04726a66face2a2 and 19118// http://webreflection.blogspot.com/2008/10/big-douglas-begetobject-revisited.html 19119 var object = (function(F){ 19120 return (function(o){ 19121 F.prototype = o; 19122 return new F(); 19123 }); 19124 })(function (){}); 19125 19126// create a widget subclass 19127 var OVERRIDE = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; 19128 $.ui.widget.subclass = function subclass(name){ 19129 $.widget(name); // Slightly inefficient to create a widget only to discard its prototype, but it's not too bad 19130 name = name.split('.'); 19131 var widget = $[name[0]][name[1]], superclass = this, superproto = superclass.prototype; 19132 19133 19134 var proto = arguments[0] = widget.prototype = object(superproto); // inherit from the superclass 19135 $.extend.apply(null, arguments); // and add other add-in methods to the prototype 19136 widget.subclass = subclass; 19137 19138 // Subtle point: we want to call superclass init and destroy if they exist 19139 // (otherwise the user of this function would have to keep track of all that) 19140 for (key in proto) if (proto.hasOwnProperty(key)) switch (key){ 19141 case '_create': 19142 var create = proto._create; 19143 proto._create = function(){ 19144 superproto._create.apply(this); 19145 create.apply(this); 19146 }; 19147 break; 19148 case '_init': 19149 var init = proto._init; 19150 proto._init = function(){ 19151 superproto._init.apply(this); 19152 init.apply(this); 19153 }; 19154 break; 19155 case 'destroy': 19156 var destroy = proto.destroy; 19157 proto.destroy = function(){ 19158 destroy.apply(this); 19159 superproto.destroy.apply(this); 19160 }; 19161 break; 19162 case 'options': 19163 var options = proto.options; 19164 proto.options = $.extend ({}, superproto.options, options); 19165 break; 19166 default: 19167 if ($.isFunction(proto[key]) && $.isFunction(superproto[key]) && OVERRIDE.test(proto[key])){ 19168 proto[key] = (function(name, fn){ 19169 return function() { 19170 var tmp = this._super; 19171 this._super = superproto[name]; 19172 try { var ret = fn.apply(this, arguments); } 19173 finally { this._super = tmp; } 19174 return ret; 19175 }; 19176 })(key, proto[key]); 19177 } 19178 break; 19179 } 19180 }; 19181})(jQuery); 19182
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.