1/*! jQuery UI - v1.12.1 - 2020-11-26 2* http://jqueryui.com 3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer
vendor: 46,668 bytes, lines 3-1721
3.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( factory ) { 7 if ( typeof define === "function" && define.amd ) { 8 9 // AMD. Register as an anonymous module. 10 define([ "jquery" ], factory ); 11 } else { 12 13 // Browser globals 14 factory( jQuery ); 15 } 16}(function( $ ) { 17 18$.ui = $.ui || {}; 19 20var version = $.ui.version = "1.12.1"; 21 22 23/*! 24 * jQuery UI Widget 1.12.1 25 * http://jqueryui.com 26 * 27 * Copyright jQuery Foundation and other contributors 28 * Released under the MIT license. 29 * http://jquery.org/license 30 */ 31 32//>>label: Widget 33//>>group: Core 34//>>description: Provides a factory for creating stateful widgets with a common API. 35//>>docs: http://api.jqueryui.com/jQuery.widget/ 36//>>demos: http://jqueryui.com/widget/ 37 38 39 40var widgetUuid = 0; 41var widgetSlice = Array.prototype.slice; 42 43$.cleanData = ( function( orig ) { 44 return function( elems ) { 45 var events, elem, i; 46 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 47 try { 48 49 // Only trigger remove when necessary to save time 50 events = $._data( elem, "events" ); 51 if ( events && events.remove ) { 52 $( elem ).triggerHandler( "remove" ); 53 } 54 55 // Http://bugs.jquery.com/ticket/8235 56 } catch ( e ) {} 57 } 58 orig( elems ); 59 }; 60} )( $.cleanData ); 61 62$.widget = function( name, base, prototype ) { 63 var existingConstructor, constructor, basePrototype; 64 65 // ProxiedPrototype allows the provided prototype to remain unmodified 66 // so that it can be used as a mixin for multiple widgets (#8876) 67 var proxiedPrototype = {}; 68 69 var namespace = name.split( "." )[ 0 ]; 70 name = name.split( "." )[ 1 ]; 71 var fullName = namespace + "-" + name; 72 73 if ( !prototype ) { 74 prototype = base; 75 base = $.Widget; 76 } 77 78 if ( $.isArray( prototype ) ) { 79 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 80 } 81 82 // Create selector for plugin 83 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 84 return !!$.data( elem, fullName ); 85 }; 86 87 $[ namespace ] = $[ namespace ] || {}; 88 existingConstructor = $[ namespace ][ name ]; 89 constructor = $[ namespace ][ name ] = function( options, element ) { 90 91 // Allow instantiation without "new" keyword 92 if ( !this._createWidget ) { 93 return new constructor( options, element ); 94 } 95 96 // Allow instantiation without initializing for simple inheritance 97 // must use "new" keyword (the code above always passes args) 98 if ( arguments.length ) { 99 this._createWidget( options, element ); 100 } 101 }; 102 103 // Extend with the existing constructor to carry over any static properties 104 $.extend( constructor, existingConstructor, { 105 version: prototype.version, 106 107 // Copy the object used to create the prototype in case we need to 108 // redefine the widget later 109 _proto: $.extend( {}, prototype ), 110 111 // Track widgets that inherit from this widget in case this widget is 112 // redefined after a widget inherits from it 113 _childConstructors: [] 114 } ); 115 116 basePrototype = new base(); 117 118 // We need to make the options hash a property directly on the new instance 119 // otherwise we'll modify the options hash on the prototype that we're 120 // inheriting from 121 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 122 $.each( prototype, function( prop, value ) { 123 if ( !$.isFunction( value ) ) { 124 proxiedPrototype[ prop ] = value; 125 return; 126 } 127 proxiedPrototype[ prop ] = ( function() { 128 function _super() { 129 return base.prototype[ prop ].apply( this, arguments ); 130 } 131 132 function _superApply( args ) { 133 return base.prototype[ prop ].apply( this, args ); 134 } 135 136 return function() { 137 var __super = this._super; 138 var __superApply = this._superApply; 139 var returnValue; 140 141 this._super = _super; 142 this._superApply = _superApply; 143 144 returnValue = value.apply( this, arguments ); 145 146 this._super = __super; 147 this._superApply = __superApply; 148 149 return returnValue; 150 }; 151 } )(); 152 } ); 153 constructor.prototype = $.widget.extend( basePrototype, { 154 155 // TODO: remove support for widgetEventPrefix 156 // always use the name + a colon as the prefix, e.g., draggable:start 157 // don't prefix for widgets that aren't DOM-based 158 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 159 }, proxiedPrototype, { 160 constructor: constructor, 161 namespace: namespace, 162 widgetName: name, 163 widgetFullName: fullName 164 } ); 165 166 // If this widget is being redefined then we need to find all widgets that 167 // are inheriting from it and redefine all of them so that they inherit from 168 // the new version of this widget. We're essentially trying to replace one 169 // level in the prototype chain. 170 if ( existingConstructor ) { 171 $.each( existingConstructor._childConstructors, function( i, child ) { 172 var childPrototype = child.prototype; 173 174 // Redefine the child widget using the same prototype that was 175 // originally used, but inherit from the new version of the base 176 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 177 child._proto ); 178 } ); 179 180 // Remove the list of existing child constructors from the old constructor 181 // so the old child constructors can be garbage collected 182 delete existingConstructor._childConstructors; 183 } else { 184 base._childConstructors.push( constructor ); 185 } 186 187 $.widget.bridge( name, constructor ); 188 189 return constructor; 190}; 191 192$.widget.extend = function( target ) { 193 var input = widgetSlice.call( arguments, 1 ); 194 var inputIndex = 0; 195 var inputLength = input.length; 196 var key; 197 var value; 198 199 for ( ; inputIndex < inputLength; inputIndex++ ) { 200 for ( key in input[ inputIndex ] ) { 201 value = input[ inputIndex ][ key ]; 202 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 203 204 // Clone objects 205 if ( $.isPlainObject( value ) ) { 206 target[ key ] = $.isPlainObject( target[ key ] ) ? 207 $.widget.extend( {}, target[ key ], value ) : 208 209 // Don't extend strings, arrays, etc. with objects 210 $.widget.extend( {}, value ); 211 212 // Copy everything else by reference 213 } else { 214 target[ key ] = value; 215 } 216 } 217 } 218 } 219 return target; 220}; 221 222$.widget.bridge = function( name, object ) { 223 var fullName = object.prototype.widgetFullName || name; 224 $.fn[ name ] = function( options ) { 225 var isMethodCall = typeof options === "string"; 226 var args = widgetSlice.call( arguments, 1 ); 227 var returnValue = this; 228 229 if ( isMethodCall ) { 230 231 // If this is an empty collection, we need to have the instance method 232 // return undefined instead of the jQuery instance 233 if ( !this.length && options === "instance" ) { 234 returnValue = undefined; 235 } else { 236 this.each( function() { 237 var methodValue; 238 var instance = $.data( this, fullName ); 239 240 if ( options === "instance" ) { 241 returnValue = instance; 242 return false; 243 } 244 245 if ( !instance ) { 246 return $.error( "cannot call methods on " + name + 247 " prior to initialization; " + 248 "attempted to call method '" + options + "'" ); 249 } 250 251 if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { 252 return $.error( "no such method '" + options + "' for " + name + 253 " widget instance" ); 254 } 255 256 methodValue = instance[ options ].apply( instance, args ); 257 258 if ( methodValue !== instance && methodValue !== undefined ) { 259 returnValue = methodValue && methodValue.jquery ? 260 returnValue.pushStack( methodValue.get() ) : 261 methodValue; 262 return false; 263 } 264 } ); 265 } 266 } else { 267 268 // Allow multiple hashes to be passed on init 269 if ( args.length ) { 270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 271 } 272 273 this.each( function() { 274 var instance = $.data( this, fullName ); 275 if ( instance ) { 276 instance.option( options || {} ); 277 if ( instance._init ) { 278 instance._init(); 279 } 280 } else { 281 $.data( this, fullName, new object( options, this ) ); 282 } 283 } ); 284 } 285 286 return returnValue; 287 }; 288}; 289 290$.Widget = function( /* options, element */ ) {}; 291$.Widget._childConstructors = []; 292 293$.Widget.prototype = { 294 widgetName: "widget", 295 widgetEventPrefix: "", 296 defaultElement: "<div>", 297 298 options: { 299 classes: {}, 300 disabled: false, 301 302 // Callbacks 303 create: null 304 }, 305 306 _createWidget: function( options, element ) { 307 element = $( element || this.defaultElement || this )[ 0 ]; 308 this.element = $( element ); 309 this.uuid = widgetUuid++; 310 this.eventNamespace = "." + this.widgetName + this.uuid; 311 312 this.bindings = $(); 313 this.hoverable = $(); 314 this.focusable = $(); 315 this.classesElementLookup = {}; 316 317 if ( element !== this ) { 318 $.data( element, this.widgetFullName, this ); 319 this._on( true, this.element, { 320 remove: function( event ) { 321 if ( event.target === element ) { 322 this.destroy(); 323 } 324 } 325 } ); 326 this.document = $( element.style ? 327 328 // Element within the document 329 element.ownerDocument : 330 331 // Element is window or document 332 element.document || element ); 333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 334 } 335 336 this.options = $.widget.extend( {}, 337 this.options, 338 this._getCreateOptions(), 339 options ); 340 341 this._create(); 342 343 if ( this.options.disabled ) { 344 this._setOptionDisabled( this.options.disabled ); 345 } 346 347 this._trigger( "create", null, this._getCreateEventData() ); 348 this._init(); 349 }, 350 351 _getCreateOptions: function() { 352 return {}; 353 }, 354 355 _getCreateEventData: $.noop, 356 357 _create: $.noop, 358 359 _init: $.noop, 360 361 destroy: function() { 362 var that = this; 363 364 this._destroy(); 365 $.each( this.classesElementLookup, function( key, value ) { 366 that._removeClass( value, key ); 367 } ); 368 369 // We can probably remove the unbind calls in 2.0 370 // all event bindings should go through this._on() 371 this.element 372 .off( this.eventNamespace ) 373 .removeData( this.widgetFullName ); 374 this.widget() 375 .off( this.eventNamespace ) 376 .removeAttr( "aria-disabled" ); 377 378 // Clean up events and states 379 this.bindings.off( this.eventNamespace ); 380 }, 381 382 _destroy: $.noop, 383 384 widget: function() { 385 return this.element; 386 }, 387 388 option: function( key, value ) { 389 var options = key; 390 var parts; 391 var curOption; 392 var i; 393 394 if ( arguments.length === 0 ) { 395 396 // Don't return a reference to the internal hash 397 return $.widget.extend( {}, this.options ); 398 } 399 400 if ( typeof key === "string" ) { 401 402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 403 options = {}; 404 parts = key.split( "." ); 405 key = parts.shift(); 406 if ( parts.length ) { 407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 408 for ( i = 0; i < parts.length - 1; i++ ) { 409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 410 curOption = curOption[ parts[ i ] ]; 411 } 412 key = parts.pop(); 413 if ( arguments.length === 1 ) { 414 return curOption[ key ] === undefined ? null : curOption[ key ]; 415 } 416 curOption[ key ] = value; 417 } else { 418 if ( arguments.length === 1 ) { 419 return this.options[ key ] === undefined ? null : this.options[ key ]; 420 } 421 options[ key ] = value; 422 } 423 } 424 425 this._setOptions( options ); 426 427 return this; 428 }, 429 430 _setOptions: function( options ) { 431 var key; 432 433 for ( key in options ) { 434 this._setOption( key, options[ key ] ); 435 } 436 437 return this; 438 }, 439 440 _setOption: function( key, value ) { 441 if ( key === "classes" ) { 442 this._setOptionClasses( value ); 443 } 444 445 this.options[ key ] = value; 446 447 if ( key === "disabled" ) { 448 this._setOptionDisabled( value ); 449 } 450 451 return this; 452 }, 453 454 _setOptionClasses: function( value ) { 455 var classKey, elements, currentElements; 456 457 for ( classKey in value ) { 458 currentElements = this.classesElementLookup[ classKey ]; 459 if ( value[ classKey ] === this.options.classes[ classKey ] || 460 !currentElements || 461 !currentElements.length ) { 462 continue; 463 } 464 465 // We are doing this to create a new jQuery object because the _removeClass() call 466 // on the next line is going to destroy the reference to the current elements being 467 // tracked. We need to save a copy of this collection so that we can add the new classes 468 // below. 469 elements = $( currentElements.get() ); 470 this._removeClass( currentElements, classKey ); 471 472 // We don't use _addClass() here, because that uses this.options.classes 473 // for generating the string of classes. We want to use the value passed in from 474 // _setOption(), this is the new value of the classes option which was passed to 475 // _setOption(). We pass this value directly to _classes(). 476 elements.addClass( this._classes( { 477 element: elements, 478 keys: classKey, 479 classes: value, 480 add: true 481 } ) ); 482 } 483 }, 484 485 _setOptionDisabled: function( value ) { 486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 487 488 // If the widget is becoming disabled, then nothing is interactive 489 if ( value ) { 490 this._removeClass( this.hoverable, null, "ui-state-hover" ); 491 this._removeClass( this.focusable, null, "ui-state-focus" ); 492 } 493 }, 494 495 enable: function() { 496 return this._setOptions( { disabled: false } ); 497 }, 498 499 disable: function() { 500 return this._setOptions( { disabled: true } ); 501 }, 502 503 _classes: function( options ) { 504 var full = []; 505 var that = this; 506 507 options = $.extend( { 508 element: this.element, 509 classes: this.options.classes || {} 510 }, options ); 511 512 function processClassString( classes, checkOption ) { 513 var current, i; 514 for ( i = 0; i < classes.length; i++ ) { 515 current = that.classesElementLookup[ classes[ i ] ] || $(); 516 if ( options.add ) { 517 current = $( $.unique( current.get().concat( options.element.get() ) ) ); 518 } else { 519 current = $( current.not( options.element ).get() ); 520 } 521 that.classesElementLookup[ classes[ i ] ] = current; 522 full.push( classes[ i ] ); 523 if ( checkOption && options.classes[ classes[ i ] ] ) { 524 full.push( options.classes[ classes[ i ] ] ); 525 } 526 } 527 } 528 529 this._on( options.element, { 530 "remove": "_untrackClassesElement" 531 } ); 532 533 if ( options.keys ) { 534 processClassString( options.keys.match( /\S+/g ) || [], true ); 535 } 536 if ( options.extra ) { 537 processClassString( options.extra.match( /\S+/g ) || [] ); 538 } 539 540 return full.join( " " ); 541 }, 542 543 _untrackClassesElement: function( event ) { 544 var that = this; 545 $.each( that.classesElementLookup, function( key, value ) { 546 if ( $.inArray( event.target, value ) !== -1 ) { 547 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 548 } 549 } ); 550 }, 551 552 _removeClass: function( element, keys, extra ) { 553 return this._toggleClass( element, keys, extra, false ); 554 }, 555 556 _addClass: function( element, keys, extra ) { 557 return this._toggleClass( element, keys, extra, true ); 558 }, 559 560 _toggleClass: function( element, keys, extra, add ) { 561 add = ( typeof add === "boolean" ) ? add : extra; 562 var shift = ( typeof element === "string" || element === null ), 563 options = { 564 extra: shift ? keys : extra, 565 keys: shift ? element : keys, 566 element: shift ? this.element : element, 567 add: add 568 }; 569 options.element.toggleClass( this._classes( options ), add ); 570 return this; 571 }, 572 573 _on: function( suppressDisabledCheck, element, handlers ) { 574 var delegateElement; 575 var instance = this; 576 577 // No suppressDisabledCheck flag, shuffle arguments 578 if ( typeof suppressDisabledCheck !== "boolean" ) { 579 handlers = element; 580 element = suppressDisabledCheck; 581 suppressDisabledCheck = false; 582 } 583 584 // No element argument, shuffle and use this.element 585 if ( !handlers ) { 586 handlers = element; 587 element = this.element; 588 delegateElement = this.widget(); 589 } else { 590 element = delegateElement = $( element ); 591 this.bindings = this.bindings.add( element ); 592 } 593 594 $.each( handlers, function( event, handler ) { 595 function handlerProxy() { 596 597 // Allow widgets to customize the disabled handling 598 // - disabled as an array instead of boolean 599 // - disabled class as method for disabling individual parts 600 if ( !suppressDisabledCheck && 601 ( instance.options.disabled === true || 602 $( this ).hasClass( "ui-state-disabled" ) ) ) { 603 return; 604 } 605 return ( typeof handler === "string" ? instance[ handler ] : handler ) 606 .apply( instance, arguments ); 607 } 608 609 // Copy the guid so direct unbinding works 610 if ( typeof handler !== "string" ) { 611 handlerProxy.guid = handler.guid = 612 handler.guid || handlerProxy.guid || $.guid++; 613 } 614 615 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 616 var eventName = match[ 1 ] + instance.eventNamespace; 617 var selector = match[ 2 ]; 618 619 if ( selector ) { 620 delegateElement.on( eventName, selector, handlerProxy ); 621 } else { 622 element.on( eventName, handlerProxy ); 623 } 624 } ); 625 }, 626 627 _off: function( element, eventName ) { 628 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 629 this.eventNamespace; 630 element.off( eventName ).off( eventName ); 631 632 // Clear the stack to avoid memory leaks (#10056) 633 this.bindings = $( this.bindings.not( element ).get() ); 634 this.focusable = $( this.focusable.not( element ).get() ); 635 this.hoverable = $( this.hoverable.not( element ).get() ); 636 }, 637 638 _delay: function( handler, delay ) { 639 function handlerProxy() { 640 return ( typeof handler === "string" ? instance[ handler ] : handler ) 641 .apply( instance, arguments ); 642 } 643 var instance = this; 644 return setTimeout( handlerProxy, delay || 0 ); 645 }, 646 647 _hoverable: function( element ) { 648 this.hoverable = this.hoverable.add( element ); 649 this._on( element, { 650 mouseenter: function( event ) { 651 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 652 }, 653 mouseleave: function( event ) { 654 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 655 } 656 } ); 657 }, 658 659 _focusable: function( element ) { 660 this.focusable = this.focusable.add( element ); 661 this._on( element, { 662 focusin: function( event ) { 663 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 664 }, 665 focusout: function( event ) { 666 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 667 } 668 } ); 669 }, 670 671 _trigger: function( type, event, data ) { 672 var prop, orig; 673 var callback = this.options[ type ]; 674 675 data = data || {}; 676 event = $.Event( event ); 677 event.type = ( type === this.widgetEventPrefix ? 678 type : 679 this.widgetEventPrefix + type ).toLowerCase(); 680 681 // The original event may come from any element 682 // so we need to reset the target on the new event 683 event.target = this.element[ 0 ]; 684 685 // Copy original event properties over to the new event 686 orig = event.originalEvent; 687 if ( orig ) { 688 for ( prop in orig ) { 689 if ( !( prop in event ) ) { 690 event[ prop ] = orig[ prop ]; 691 } 692 } 693 } 694 695 this.element.trigger( event, data ); 696 return !( $.isFunction( callback ) && 697 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 698 event.isDefaultPrevented() ); 699 } 700}; 701 702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 703 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 704 if ( typeof options === "string" ) { 705 options = { effect: options }; 706 } 707 708 var hasOptions; 709 var effectName = !options ? 710 method : 711 options === true || typeof options === "number" ? 712 defaultEffect : 713 options.effect || defaultEffect; 714 715 options = options || {}; 716 if ( typeof options === "number" ) { 717 options = { duration: options }; 718 } 719 720 hasOptions = !$.isEmptyObject( options ); 721 options.complete = callback; 722 723 if ( options.delay ) { 724 element.delay( options.delay ); 725 } 726 727 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 728 element[ method ]( options ); 729 } else if ( effectName !== method && element[ effectName ] ) { 730 element[ effectName ]( options.duration, options.easing, callback ); 731 } else { 732 element.queue( function( next ) { 733 $( this )[ method ](); 734 if ( callback ) { 735 callback.call( element[ 0 ] ); 736 } 737 next(); 738 } ); 739 } 740 }; 741} ); 742 743var widget = $.widget; 744 745 746/*! 747 * jQuery UI Position 1.12.1 748 * http://jqueryui.com 749 * 750 * Copyright jQuery Foundation and other contributors 751 * Released under the MIT license. 752 * http://jquery.org/license 753 * 754 * http://api.jqueryui.com/position/ 755 */ 756 757//>>label: Position 758//>>group: Core 759//>>description: Positions elements relative to other elements. 760//>>docs: http://api.jqueryui.com/position/ 761//>>demos: http://jqueryui.com/position/ 762 763 764( function() { 765var cachedScrollbarWidth, 766 max = Math.max, 767 abs = Math.abs, 768 rhorizontal = /left|center|right/, 769 rvertical = /top|center|bottom/, 770 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 771 rposition = /^\w+/, 772 rpercent = /%$/, 773 _position = $.fn.position; 774 775function getOffsets( offsets, width, height ) { 776 return [ 777 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 778 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 779 ]; 780} 781 782function parseCss( element, property ) { 783 return parseInt( $.css( element, property ), 10 ) || 0; 784} 785 786function getDimensions( elem ) { 787 var raw = elem[ 0 ]; 788 if ( raw.nodeType === 9 ) { 789 return { 790 width: elem.width(), 791 height: elem.height(), 792 offset: { top: 0, left: 0 } 793 }; 794 } 795 if ( $.isWindow( raw ) ) { 796 return { 797 width: elem.width(), 798 height: elem.height(), 799 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 800 }; 801 } 802 if ( raw.preventDefault ) { 803 return { 804 width: 0, 805 height: 0, 806 offset: { top: raw.pageY, left: raw.pageX } 807 }; 808 } 809 return { 810 width: elem.outerWidth(), 811 height: elem.outerHeight(), 812 offset: elem.offset() 813 }; 814} 815 816$.position = { 817 scrollbarWidth: function() { 818 if ( cachedScrollbarWidth !== undefined ) { 819 return cachedScrollbarWidth; 820 } 821 var w1, w2, 822 div = $( "<div " + 823 "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + 824 "<div style='height:100px;width:auto;'></div></div>" ), 825 innerDiv = div.children()[ 0 ]; 826 827 $( "body" ).append( div ); 828 w1 = innerDiv.offsetWidth; 829 div.css( "overflow", "scroll" ); 830 831 w2 = innerDiv.offsetWidth; 832 833 if ( w1 === w2 ) { 834 w2 = div[ 0 ].clientWidth; 835 } 836 837 div.remove(); 838 839 return ( cachedScrollbarWidth = w1 - w2 ); 840 }, 841 getScrollInfo: function( within ) { 842 var overflowX = within.isWindow || within.isDocument ? "" : 843 within.element.css( "overflow-x" ), 844 overflowY = within.isWindow || within.isDocument ? "" : 845 within.element.css( "overflow-y" ), 846 hasOverflowX = overflowX === "scroll" || 847 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 848 hasOverflowY = overflowY === "scroll" || 849 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 850 return { 851 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 852 height: hasOverflowX ? $.position.scrollbarWidth() : 0 853 }; 854 }, 855 getWithinInfo: function( element ) { 856 var withinElement = $( element || window ), 857 isWindow = $.isWindow( withinElement[ 0 ] ), 858 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 859 hasOffset = !isWindow && !isDocument; 860 return { 861 element: withinElement, 862 isWindow: isWindow, 863 isDocument: isDocument, 864 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 865 scrollLeft: withinElement.scrollLeft(), 866 scrollTop: withinElement.scrollTop(), 867 width: withinElement.outerWidth(), 868 height: withinElement.outerHeight() 869 }; 870 } 871}; 872 873$.fn.position = function( options ) { 874 if ( !options || !options.of ) { 875 return _position.apply( this, arguments ); 876 } 877 878 // Make a copy, we don't want to modify arguments 879 options = $.extend( {}, options ); 880 881 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 882 target = $( options.of ), 883 within = $.position.getWithinInfo( options.within ), 884 scrollInfo = $.position.getScrollInfo( within ), 885 collision = ( options.collision || "flip" ).split( " " ), 886 offsets = {}; 887 888 dimensions = getDimensions( target ); 889 if ( target[ 0 ].preventDefault ) { 890 891 // Force left top to allow flipping 892 options.at = "left top"; 893 } 894 targetWidth = dimensions.width; 895 targetHeight = dimensions.height; 896 targetOffset = dimensions.offset; 897 898 // Clone to reuse original targetOffset later 899 basePosition = $.extend( {}, targetOffset ); 900 901 // Force my and at to have valid horizontal and vertical positions 902 // if a value is missing or invalid, it will be converted to center 903 $.each( [ "my", "at" ], function() { 904 var pos = ( options[ this ] || "" ).split( " " ), 905 horizontalOffset, 906 verticalOffset; 907 908 if ( pos.length === 1 ) { 909 pos = rhorizontal.test( pos[ 0 ] ) ? 910 pos.concat( [ "center" ] ) : 911 rvertical.test( pos[ 0 ] ) ? 912 [ "center" ].concat( pos ) : 913 [ "center", "center" ]; 914 } 915 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 916 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 917 918 // Calculate offsets 919 horizontalOffset = roffset.exec( pos[ 0 ] ); 920 verticalOffset = roffset.exec( pos[ 1 ] ); 921 offsets[ this ] = [ 922 horizontalOffset ? horizontalOffset[ 0 ] : 0, 923 verticalOffset ? verticalOffset[ 0 ] : 0 924 ]; 925 926 // Reduce to just the positions without the offsets 927 options[ this ] = [ 928 rposition.exec( pos[ 0 ] )[ 0 ], 929 rposition.exec( pos[ 1 ] )[ 0 ] 930 ]; 931 } ); 932 933 // Normalize collision option 934 if ( collision.length === 1 ) { 935 collision[ 1 ] = collision[ 0 ]; 936 } 937 938 if ( options.at[ 0 ] === "right" ) { 939 basePosition.left += targetWidth; 940 } else if ( options.at[ 0 ] === "center" ) { 941 basePosition.left += targetWidth / 2; 942 } 943 944 if ( options.at[ 1 ] === "bottom" ) { 945 basePosition.top += targetHeight; 946 } else if ( options.at[ 1 ] === "center" ) { 947 basePosition.top += targetHeight / 2; 948 } 949 950 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 951 basePosition.left += atOffset[ 0 ]; 952 basePosition.top += atOffset[ 1 ]; 953 954 return this.each( function() { 955 var collisionPosition, using, 956 elem = $( this ), 957 elemWidth = elem.outerWidth(), 958 elemHeight = elem.outerHeight(), 959 marginLeft = parseCss( this, "marginLeft" ), 960 marginTop = parseCss( this, "marginTop" ), 961 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 962 scrollInfo.width, 963 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 964 scrollInfo.height, 965 position = $.extend( {}, basePosition ), 966 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 967 968 if ( options.my[ 0 ] === "right" ) { 969 position.left -= elemWidth; 970 } else if ( options.my[ 0 ] === "center" ) { 971 position.left -= elemWidth / 2; 972 } 973 974 if ( options.my[ 1 ] === "bottom" ) { 975 position.top -= elemHeight; 976 } else if ( options.my[ 1 ] === "center" ) { 977 position.top -= elemHeight / 2; 978 } 979 980 position.left += myOffset[ 0 ]; 981 position.top += myOffset[ 1 ]; 982 983 collisionPosition = { 984 marginLeft: marginLeft, 985 marginTop: marginTop 986 }; 987 988 $.each( [ "left", "top" ], function( i, dir ) { 989 if ( $.ui.position[ collision[ i ] ] ) { 990 $.ui.position[ collision[ i ] ][ dir ]( position, { 991 targetWidth: targetWidth, 992 targetHeight: targetHeight, 993 elemWidth: elemWidth, 994 elemHeight: elemHeight, 995 collisionPosition: collisionPosition, 996 collisionWidth: collisionWidth, 997 collisionHeight: collisionHeight, 998 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 999 my: options.my, 1000 at: options.at, 1001 within: within, 1002 elem: elem 1003 } ); 1004 } 1005 } ); 1006 1007 if ( options.using ) { 1008 1009 // Adds feedback as second argument to using callback, if present 1010 using = function( props ) { 1011 var left = targetOffset.left - position.left, 1012 right = left + targetWidth - elemWidth, 1013 top = targetOffset.top - position.top, 1014 bottom = top + targetHeight - elemHeight, 1015 feedback = { 1016 target: { 1017 element: target, 1018 left: targetOffset.left, 1019 top: targetOffset.top, 1020 width: targetWidth, 1021 height: targetHeight 1022 }, 1023 element: { 1024 element: elem, 1025 left: position.left, 1026 top: position.top, 1027 width: elemWidth, 1028 height: elemHeight 1029 }, 1030 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1031 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1032 }; 1033 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1034 feedback.horizontal = "center"; 1035 } 1036 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1037 feedback.vertical = "middle"; 1038 } 1039 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1040 feedback.important = "horizontal"; 1041 } else { 1042 feedback.important = "vertical"; 1043 } 1044 options.using.call( this, props, feedback ); 1045 }; 1046 } 1047 1048 elem.offset( $.extend( position, { using: using } ) ); 1049 } ); 1050}; 1051 1052$.ui.position = { 1053 fit: { 1054 left: function( position, data ) { 1055 var within = data.within, 1056 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1057 outerWidth = within.width, 1058 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1059 overLeft = withinOffset - collisionPosLeft, 1060 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1061 newOverRight; 1062 1063 // Element is wider than within 1064 if ( data.collisionWidth > outerWidth ) { 1065 1066 // Element is initially over the left side of within 1067 if ( overLeft > 0 && overRight <= 0 ) { 1068 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1069 withinOffset; 1070 position.left += overLeft - newOverRight; 1071 1072 // Element is initially over right side of within 1073 } else if ( overRight > 0 && overLeft <= 0 ) { 1074 position.left = withinOffset; 1075 1076 // Element is initially over both left and right sides of within 1077 } else { 1078 if ( overLeft > overRight ) { 1079 position.left = withinOffset + outerWidth - data.collisionWidth; 1080 } else { 1081 position.left = withinOffset; 1082 } 1083 } 1084 1085 // Too far left -> align with left edge 1086 } else if ( overLeft > 0 ) { 1087 position.left += overLeft; 1088 1089 // Too far right -> align with right edge 1090 } else if ( overRight > 0 ) { 1091 position.left -= overRight; 1092 1093 // Adjust based on position and margin 1094 } else { 1095 position.left = max( position.left - collisionPosLeft, position.left ); 1096 } 1097 }, 1098 top: function( position, data ) { 1099 var within = data.within, 1100 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1101 outerHeight = data.within.height, 1102 collisionPosTop = position.top - data.collisionPosition.marginTop, 1103 overTop = withinOffset - collisionPosTop, 1104 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1105 newOverBottom; 1106 1107 // Element is taller than within 1108 if ( data.collisionHeight > outerHeight ) { 1109 1110 // Element is initially over the top of within 1111 if ( overTop > 0 && overBottom <= 0 ) { 1112 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1113 withinOffset; 1114 position.top += overTop - newOverBottom; 1115 1116 // Element is initially over bottom of within 1117 } else if ( overBottom > 0 && overTop <= 0 ) { 1118 position.top = withinOffset; 1119 1120 // Element is initially over both top and bottom of within 1121 } else { 1122 if ( overTop > overBottom ) { 1123 position.top = withinOffset + outerHeight - data.collisionHeight; 1124 } else { 1125 position.top = withinOffset; 1126 } 1127 } 1128 1129 // Too far up -> align with top 1130 } else if ( overTop > 0 ) { 1131 position.top += overTop; 1132 1133 // Too far down -> align with bottom edge 1134 } else if ( overBottom > 0 ) { 1135 position.top -= overBottom; 1136 1137 // Adjust based on position and margin 1138 } else { 1139 position.top = max( position.top - collisionPosTop, position.top ); 1140 } 1141 } 1142 }, 1143 flip: { 1144 left: function( position, data ) { 1145 var within = data.within, 1146 withinOffset = within.offset.left + within.scrollLeft, 1147 outerWidth = within.width, 1148 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1149 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1150 overLeft = collisionPosLeft - offsetLeft, 1151 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1152 myOffset = data.my[ 0 ] === "left" ? 1153 -data.elemWidth : 1154 data.my[ 0 ] === "right" ? 1155 data.elemWidth : 1156 0, 1157 atOffset = data.at[ 0 ] === "left" ? 1158 data.targetWidth : 1159 data.at[ 0 ] === "right" ? 1160 -data.targetWidth : 1161 0, 1162 offset = -2 * data.offset[ 0 ], 1163 newOverRight, 1164 newOverLeft; 1165 1166 if ( overLeft < 0 ) { 1167 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1168 outerWidth - withinOffset; 1169 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1170 position.left += myOffset + atOffset + offset; 1171 } 1172 } else if ( overRight > 0 ) { 1173 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1174 atOffset + offset - offsetLeft; 1175 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1176 position.left += myOffset + atOffset + offset; 1177 } 1178 } 1179 }, 1180 top: function( position, data ) { 1181 var within = data.within, 1182 withinOffset = within.offset.top + within.scrollTop, 1183 outerHeight = within.height, 1184 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1185 collisionPosTop = position.top - data.collisionPosition.marginTop, 1186 overTop = collisionPosTop - offsetTop, 1187 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1188 top = data.my[ 1 ] === "top", 1189 myOffset = top ? 1190 -data.elemHeight : 1191 data.my[ 1 ] === "bottom" ? 1192 data.elemHeight : 1193 0, 1194 atOffset = data.at[ 1 ] === "top" ? 1195 data.targetHeight : 1196 data.at[ 1 ] === "bottom" ? 1197 -data.targetHeight : 1198 0, 1199 offset = -2 * data.offset[ 1 ], 1200 newOverTop, 1201 newOverBottom; 1202 if ( overTop < 0 ) { 1203 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1204 outerHeight - withinOffset; 1205 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1206 position.top += myOffset + atOffset + offset; 1207 } 1208 } else if ( overBottom > 0 ) { 1209 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1210 offset - offsetTop; 1211 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1212 position.top += myOffset + atOffset + offset; 1213 } 1214 } 1215 } 1216 }, 1217 flipfit: { 1218 left: function() { 1219 $.ui.position.flip.left.apply( this, arguments ); 1220 $.ui.position.fit.left.apply( this, arguments ); 1221 }, 1222 top: function() { 1223 $.ui.position.flip.top.apply( this, arguments ); 1224 $.ui.position.fit.top.apply( this, arguments ); 1225 } 1226 } 1227}; 1228 1229} )(); 1230 1231var position = $.ui.position; 1232 1233 1234/*! 1235 * jQuery UI :data 1.12.1 1236 * http://jqueryui.com 1237 * 1238 * Copyright jQuery Foundation and other contributors 1239 * Released under the MIT license. 1240 * http://jquery.org/license 1241 */ 1242 1243//>>label: :data Selector 1244//>>group: Core 1245//>>description: Selects elements which have data stored under the specified key. 1246//>>docs: http://api.jqueryui.com/data-selector/ 1247 1248 1249var data = $.extend( $.expr[ ":" ], { 1250 data: $.expr.createPseudo ? 1251 $.expr.createPseudo( function( dataName ) { 1252 return function( elem ) { 1253 return !!$.data( elem, dataName ); 1254 }; 1255 } ) : 1256 1257 // Support: jQuery <1.8 1258 function( elem, i, match ) { 1259 return !!$.data( elem, match[ 3 ] ); 1260 } 1261} ); 1262 1263/*! 1264 * jQuery UI Disable Selection 1.12.1 1265 * http://jqueryui.com 1266 * 1267 * Copyright jQuery Foundation and other contributors 1268 * Released under the MIT license. 1269 * http://jquery.org/license 1270 */ 1271 1272//>>label: disableSelection 1273//>>group: Core 1274//>>description: Disable selection of text content within the set of matched elements. 1275//>>docs: http://api.jqueryui.com/disableSelection/ 1276 1277// This file is deprecated 1278 1279 1280var disableSelection = $.fn.extend( { 1281 disableSelection: ( function() { 1282 var eventType = "onselectstart" in document.createElement( "div" ) ? 1283 "selectstart" : 1284 "mousedown"; 1285 1286 return function() { 1287 return this.on( eventType + ".ui-disableSelection", function( event ) { 1288 event.preventDefault(); 1289 } ); 1290 }; 1291 } )(), 1292 1293 enableSelection: function() { 1294 return this.off( ".ui-disableSelection" ); 1295 } 1296} ); 1297 1298 1299/*! 1300 * jQuery UI Focusable 1.12.1 1301 * http://jqueryui.com 1302 * 1303 * Copyright jQuery Foundation and other contributors 1304 * Released under the MIT license. 1305 * http://jquery.org/license 1306 */ 1307 1308//>>label: :focusable Selector 1309//>>group: Core 1310//>>description: Selects elements which can be focused. 1311//>>docs: http://api.jqueryui.com/focusable-selector/ 1312 1313 1314 1315// Selectors 1316$.ui.focusable = function( element, hasTabindex ) { 1317 var map, mapName, img, focusableIfVisible, fieldset, 1318 nodeName = element.nodeName.toLowerCase(); 1319 1320 if ( "area" === nodeName ) { 1321 map = element.parentNode; 1322 mapName = map.name; 1323 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 1324 return false; 1325 } 1326 img = $( "img[usemap='#" + mapName + "']" ); 1327 return img.length > 0 && img.is( ":visible" ); 1328 } 1329 1330 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 1331 focusableIfVisible = !element.disabled; 1332 1333 if ( focusableIfVisible ) { 1334 1335 // Form controls within a disabled fieldset are disabled. 1336 // However, controls within the fieldset's legend do not get disabled. 1337 // Since controls generally aren't placed inside legends, we skip 1338 // this portion of the check. 1339 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 1340 if ( fieldset ) { 1341 focusableIfVisible = !fieldset.disabled; 1342 } 1343 } 1344 } else if ( "a" === nodeName ) { 1345 focusableIfVisible = element.href || hasTabindex; 1346 } else { 1347 focusableIfVisible = hasTabindex; 1348 } 1349 1350 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 1351}; 1352 1353// Support: IE 8 only 1354// IE 8 doesn't resolve inherit to visible/hidden for computed values 1355function visible( element ) { 1356 var visibility = element.css( "visibility" ); 1357 while ( visibility === "inherit" ) { 1358 element = element.parent(); 1359 visibility = element.css( "visibility" ); 1360 } 1361 return visibility !== "hidden"; 1362} 1363 1364$.extend( $.expr[ ":" ], { 1365 focusable: function( element ) { 1366 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 1367 } 1368} ); 1369 1370var focusable = $.ui.focusable; 1371 1372 1373 1374 1375// Support: IE8 Only 1376// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 1377// with a string, so we need to find the proper form. 1378var form = $.fn.form = function() { 1379 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 1380}; 1381 1382 1383/*! 1384 * jQuery UI Form Reset Mixin 1.12.1 1385 * http://jqueryui.com 1386 * 1387 * Copyright jQuery Foundation and other contributors 1388 * Released under the MIT license. 1389 * http://jquery.org/license 1390 */ 1391 1392//>>label: Form Reset Mixin 1393//>>group: Core 1394//>>description: Refresh input widgets when their form is reset 1395//>>docs: http://api.jqueryui.com/form-reset-mixin/ 1396 1397 1398 1399var formResetMixin = $.ui.formResetMixin = { 1400 _formResetHandler: function() { 1401 var form = $( this ); 1402 1403 // Wait for the form reset to actually happen before refreshing 1404 setTimeout( function() { 1405 var instances = form.data( "ui-form-reset-instances" ); 1406 $.each( instances, function() { 1407 this.refresh(); 1408 } ); 1409 } ); 1410 }, 1411 1412 _bindFormResetHandler: function() { 1413 this.form = this.element.form(); 1414 if ( !this.form.length ) { 1415 return; 1416 } 1417 1418 var instances = this.form.data( "ui-form-reset-instances" ) || []; 1419 if ( !instances.length ) { 1420 1421 // We don't use _on() here because we use a single event handler per form 1422 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 1423 } 1424 instances.push( this ); 1425 this.form.data( "ui-form-reset-instances", instances ); 1426 }, 1427 1428 _unbindFormResetHandler: function() { 1429 if ( !this.form.length ) { 1430 return; 1431 } 1432 1433 var instances = this.form.data( "ui-form-reset-instances" ); 1434 instances.splice( $.inArray( this, instances ), 1 ); 1435 if ( instances.length ) { 1436 this.form.data( "ui-form-reset-instances", instances ); 1437 } else { 1438 this.form 1439 .removeData( "ui-form-reset-instances" ) 1440 .off( "reset.ui-form-reset" ); 1441 } 1442 } 1443}; 1444 1445 1446/*! 1447 * jQuery UI Support for jQuery core 1.7.x 1.12.1 1448 * http://jqueryui.com 1449 * 1450 * Copyright jQuery Foundation and other contributors 1451 * Released under the MIT license. 1452 * http://jquery.org/license 1453 * 1454 */ 1455 1456//>>label: jQuery 1.7 Support 1457//>>group: Core 1458//>>description: Support version 1.7.x of jQuery core 1459 1460 1461 1462// Support: jQuery 1.7 only 1463// Not a great way to check versions, but since we only support 1.7+ and only 1464// need to detect <1.8, this is a simple check that should suffice. Checking 1465// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0 1466// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting 1467// 1.7 anymore). See #11197 for why we're not using feature detection. 1468if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) { 1469 1470 // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight() 1471 // Unlike jQuery Core 1.8+, these only support numeric values to set the 1472 // dimensions in pixels 1473 $.each( [ "Width", "Height" ], function( i, name ) { 1474 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 1475 type = name.toLowerCase(), 1476 orig = { 1477 innerWidth: $.fn.innerWidth, 1478 innerHeight: $.fn.innerHeight, 1479 outerWidth: $.fn.outerWidth, 1480 outerHeight: $.fn.outerHeight 1481 }; 1482 1483 function reduce( elem, size, border, margin ) { 1484 $.each( side, function() { 1485 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 1486 if ( border ) { 1487 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 1488 } 1489 if ( margin ) { 1490 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 1491 } 1492 } ); 1493 return size; 1494 } 1495 1496 $.fn[ "inner" + name ] = function( size ) { 1497 if ( size === undefined ) { 1498 return orig[ "inner" + name ].call( this ); 1499 } 1500 1501 return this.each( function() { 1502 $( this ).css( type, reduce( this, size ) + "px" ); 1503 } ); 1504 }; 1505 1506 $.fn[ "outer" + name ] = function( size, margin ) { 1507 if ( typeof size !== "number" ) { 1508 return orig[ "outer" + name ].call( this, size ); 1509 } 1510 1511 return this.each( function() { 1512 $( this ).css( type, reduce( this, size, true, margin ) + "px" ); 1513 } ); 1514 }; 1515 } ); 1516 1517 $.fn.addBack = function( selector ) { 1518 return this.add( selector == null ? 1519 this.prevObject : this.prevObject.filter( selector ) 1520 ); 1521 }; 1522} 1523 1524; 1525/*! 1526 * jQuery UI Keycode 1.12.1 1527 * http://jqueryui.com 1528 * 1529 * Copyright jQuery Foundation and other contributors 1530 * Released under the MIT license. 1531 * http://jquery.org/license 1532 */ 1533 1534//>>label: Keycode 1535//>>group: Core 1536//>>description: Provide keycodes as keynames 1537//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 1538 1539 1540var keycode = $.ui.keyCode = { 1541 BACKSPACE: 8, 1542 COMMA: 188, 1543 DELETE: 46, 1544 DOWN: 40, 1545 END: 35, 1546 ENTER: 13, 1547 ESCAPE: 27, 1548 HOME: 36, 1549 LEFT: 37, 1550 PAGE_DOWN: 34, 1551 PAGE_UP: 33, 1552 PERIOD: 190, 1553 RIGHT: 39, 1554 SPACE: 32, 1555 TAB: 9, 1556 UP: 38 1557}; 1558 1559 1560 1561 1562// Internal use only 1563var escapeSelector = $.ui.escapeSelector = ( function() { 1564 var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; 1565 return function( selector ) { 1566 return selector.replace( selectorEscape, "\\$1" ); 1567 }; 1568} )(); 1569 1570 1571/*! 1572 * jQuery UI Labels 1.12.1 1573 * http://jqueryui.com 1574 * 1575 * Copyright jQuery Foundation and other contributors 1576 * Released under the MIT license. 1577 * http://jquery.org/license 1578 */ 1579 1580//>>label: labels 1581//>>group: Core 1582//>>description: Find all the labels associated with a given input 1583//>>docs: http://api.jqueryui.com/labels/ 1584 1585 1586 1587var labels = $.fn.labels = function() { 1588 var ancestor, selector, id, labels, ancestors; 1589 1590 // Check control.labels first 1591 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 1592 return this.pushStack( this[ 0 ].labels ); 1593 } 1594 1595 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 1596 // Above browsers do not support control.labels. Everything below is to support them 1597 // as well as document fragments. control.labels does not work on document fragments 1598 labels = this.eq( 0 ).parents( "label" ); 1599 1600 // Look for the label based on the id 1601 id = this.attr( "id" ); 1602 if ( id ) { 1603 1604 // We don't search against the document in case the element 1605 // is disconnected from the DOM 1606 ancestor = this.eq( 0 ).parents().last(); 1607 1608 // Get a full set of top level ancestors 1609 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 1610 1611 // Create a selector for the label based on the id 1612 selector = "label[for='" + $.ui.escapeSelector( id ) + "']"; 1613 1614 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 1615 1616 } 1617 1618 // Return whatever we have found for labels 1619 return this.pushStack( labels ); 1620}; 1621 1622 1623/*! 1624 * jQuery UI Scroll Parent 1.12.1 1625 * http://jqueryui.com 1626 * 1627 * Copyright jQuery Foundation and other contributors 1628 * Released under the MIT license. 1629 * http://jquery.org/license 1630 */ 1631 1632//>>label: scrollParent 1633//>>group: Core 1634//>>description: Get the closest ancestor element that is scrollable. 1635//>>docs: http://api.jqueryui.com/scrollParent/ 1636 1637 1638 1639var scrollParent = $.fn.scrollParent = function( includeHidden ) { 1640 var position = this.css( "position" ), 1641 excludeStaticParent = position === "absolute", 1642 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 1643 scrollParent = this.parents().filter( function() { 1644 var parent = $( this ); 1645 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 1646 return false; 1647 } 1648 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 1649 parent.css( "overflow-x" ) ); 1650 } ).eq( 0 ); 1651 1652 return position === "fixed" || !scrollParent.length ? 1653 $( this[ 0 ].ownerDocument || document ) : 1654 scrollParent; 1655}; 1656 1657 1658/*! 1659 * jQuery UI Tabbable 1.12.1 1660 * http://jqueryui.com 1661 * 1662 * Copyright jQuery Foundation and other contributors 1663 * Released under the MIT license. 1664 * http://jquery.org/license 1665 */ 1666 1667//>>label: :tabbable Selector 1668//>>group: Core 1669//>>description: Selects elements which can be tabbed to. 1670//>>docs: http://api.jqueryui.com/tabbable-selector/ 1671 1672 1673 1674var tabbable = $.extend( $.expr[ ":" ], { 1675 tabbable: function( element ) { 1676 var tabIndex = $.attr( element, "tabindex" ), 1677 hasTabindex = tabIndex != null; 1678 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 1679 } 1680} ); 1681 1682 1683/*! 1684 * jQuery UI Unique ID 1.12.1 1685 * http://jqueryui.com 1686 * 1687 * Copyright jQuery Foundation and other contributors 1688 * Released under the MIT license. 1689 * http://jquery.org/license 1690 */ 1691 1692//>>label: uniqueId 1693//>>group: Core 1694//>>description: Functions to generate and remove uniqueId's 1695//>>docs: http://api.jqueryui.com/uniqueId/ 1696 1697 1698 1699var uniqueId = $.fn.extend( { 1700 uniqueId: ( function() { 1701 var uuid = 0; 1702 1703 return function() { 1704 return this.each( function() { 1705 if ( !this.id ) { 1706 this.id = "ui-id-" + ( ++uuid ); 1707 } 1708 } ); 1709 }; 1710 } )(), 1711 1712 removeUniqueId: function() { 1713 return this.each( function() { 1714 if ( /^ui-id-\d+$/.test( this.id ) ) { 1715 $( this ).removeAttr( "id" ); 1716 } 1717 } ); 1718 } 1719} ); 1720 1721
vendor: 46,453 bytes, lines 1722-3408
1722 1723 1724// This file is deprecated 1725var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 1726 1727/*! 1728 * jQuery UI Mouse 1.12.1 1729 * http://jqueryui.com 1730 * 1731 * Copyright jQuery Foundation and other contributors 1732 * Released under the MIT license. 1733 * http://jquery.org/license 1734 */ 1735 1736//>>label: Mouse 1737//>>group: Widgets 1738//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 1739//>>docs: http://api.jqueryui.com/mouse/ 1740 1741 1742 1743var mouseHandled = false; 1744$( document ).on( "mouseup", function() { 1745 mouseHandled = false; 1746} ); 1747 1748var widgetsMouse = $.widget( "ui.mouse", { 1749 version: "1.12.1", 1750 options: { 1751 cancel: "input, textarea, button, select, option", 1752 distance: 1, 1753 delay: 0 1754 }, 1755 _mouseInit: function() { 1756 var that = this; 1757 1758 this.element 1759 .on( "mousedown." + this.widgetName, function( event ) { 1760 return that._mouseDown( event ); 1761 } ) 1762 .on( "click." + this.widgetName, function( event ) { 1763 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 1764 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 1765 event.stopImmediatePropagation(); 1766 return false; 1767 } 1768 } ); 1769 1770 this.started = false; 1771 }, 1772 1773 // TODO: make sure destroying one instance of mouse doesn't mess with 1774 // other instances of mouse 1775 _mouseDestroy: function() { 1776 this.element.off( "." + this.widgetName ); 1777 if ( this._mouseMoveDelegate ) { 1778 this.document 1779 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1780 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1781 } 1782 }, 1783 1784 _mouseDown: function( event ) { 1785 1786 // don't let more than one widget handle mouseStart 1787 if ( mouseHandled ) { 1788 return; 1789 } 1790 1791 this._mouseMoved = false; 1792 1793 // We may have missed mouseup (out of window) 1794 ( this._mouseStarted && this._mouseUp( event ) ); 1795 1796 this._mouseDownEvent = event; 1797 1798 var that = this, 1799 btnIsLeft = ( event.which === 1 ), 1800 1801 // event.target.nodeName works around a bug in IE 8 with 1802 // disabled inputs (#7620) 1803 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 1804 $( event.target ).closest( this.options.cancel ).length : false ); 1805 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 1806 return true; 1807 } 1808 1809 this.mouseDelayMet = !this.options.delay; 1810 if ( !this.mouseDelayMet ) { 1811 this._mouseDelayTimer = setTimeout( function() { 1812 that.mouseDelayMet = true; 1813 }, this.options.delay ); 1814 } 1815 1816 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1817 this._mouseStarted = ( this._mouseStart( event ) !== false ); 1818 if ( !this._mouseStarted ) { 1819 event.preventDefault(); 1820 return true; 1821 } 1822 } 1823 1824 // Click event may never have fired (Gecko & Opera) 1825 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 1826 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 1827 } 1828 1829 // These delegates are required to keep context 1830 this._mouseMoveDelegate = function( event ) { 1831 return that._mouseMove( event ); 1832 }; 1833 this._mouseUpDelegate = function( event ) { 1834 return that._mouseUp( event ); 1835 }; 1836 1837 this.document 1838 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1839 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1840 1841 event.preventDefault(); 1842 1843 mouseHandled = true; 1844 return true; 1845 }, 1846 1847 _mouseMove: function( event ) { 1848 1849 // Only check for mouseups outside the document if you've moved inside the document 1850 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 1851 // fire a mousemove event if content is placed under the cursor. See #7778 1852 // Support: IE <9 1853 if ( this._mouseMoved ) { 1854 1855 // IE mouseup check - mouseup happened when mouse was out of window 1856 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 1857 !event.button ) { 1858 return this._mouseUp( event ); 1859 1860 // Iframe mouseup check - mouseup occurred in another document 1861 } else if ( !event.which ) { 1862 1863 // Support: Safari <=8 - 9 1864 // Safari sets which to 0 if you press any of the following keys 1865 // during a drag (#14461) 1866 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 1867 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 1868 this.ignoreMissingWhich = true; 1869 } else if ( !this.ignoreMissingWhich ) { 1870 return this._mouseUp( event ); 1871 } 1872 } 1873 } 1874 1875 if ( event.which || event.button ) { 1876 this._mouseMoved = true; 1877 } 1878 1879 if ( this._mouseStarted ) { 1880 this._mouseDrag( event ); 1881 return event.preventDefault(); 1882 } 1883 1884 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1885 this._mouseStarted = 1886 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 1887 ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); 1888 } 1889 1890 return !this._mouseStarted; 1891 }, 1892 1893 _mouseUp: function( event ) { 1894 this.document 1895 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1896 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1897 1898 if ( this._mouseStarted ) { 1899 this._mouseStarted = false; 1900 1901 if ( event.target === this._mouseDownEvent.target ) { 1902 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 1903 } 1904 1905 this._mouseStop( event ); 1906 } 1907 1908 if ( this._mouseDelayTimer ) { 1909 clearTimeout( this._mouseDelayTimer ); 1910 delete this._mouseDelayTimer; 1911 } 1912 1913 this.ignoreMissingWhich = false; 1914 mouseHandled = false; 1915 event.preventDefault(); 1916 }, 1917 1918 _mouseDistanceMet: function( event ) { 1919 return ( Math.max( 1920 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 1921 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 1922 ) >= this.options.distance 1923 ); 1924 }, 1925 1926 _mouseDelayMet: function( /* event */ ) { 1927 return this.mouseDelayMet; 1928 }, 1929 1930 // These are placeholder methods, to be overriden by extending plugin 1931 _mouseStart: function( /* event */ ) {}, 1932 _mouseDrag: function( /* event */ ) {}, 1933 _mouseStop: function( /* event */ ) {}, 1934 _mouseCapture: function( /* event */ ) { return true; } 1935} ); 1936 1937 1938 1939 1940// $.ui.plugin is deprecated. Use $.widget() extensions instead. 1941var plugin = $.ui.plugin = { 1942 add: function( module, option, set ) { 1943 var i, 1944 proto = $.ui[ module ].prototype; 1945 for ( i in set ) { 1946 proto.plugins[ i ] = proto.plugins[ i ] || []; 1947 proto.plugins[ i ].push( [ option, set[ i ] ] ); 1948 } 1949 }, 1950 call: function( instance, name, args, allowDisconnected ) { 1951 var i, 1952 set = instance.plugins[ name ]; 1953 1954 if ( !set ) { 1955 return; 1956 } 1957 1958 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 1959 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 1960 return; 1961 } 1962 1963 for ( i = 0; i < set.length; i++ ) { 1964 if ( instance.options[ set[ i ][ 0 ] ] ) { 1965 set[ i ][ 1 ].apply( instance.element, args ); 1966 } 1967 } 1968 } 1969}; 1970 1971 1972 1973var safeActiveElement = $.ui.safeActiveElement = function( document ) { 1974 var activeElement; 1975 1976 // Support: IE 9 only 1977 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1978 try { 1979 activeElement = document.activeElement; 1980 } catch ( error ) { 1981 activeElement = document.body; 1982 } 1983 1984 // Support: IE 9 - 11 only 1985 // IE may return null instead of an element 1986 // Interestingly, this only seems to occur when NOT in an iframe 1987 if ( !activeElement ) { 1988 activeElement = document.body; 1989 } 1990 1991 // Support: IE 11 only 1992 // IE11 returns a seemingly empty object in some cases when accessing 1993 // document.activeElement from an <iframe> 1994 if ( !activeElement.nodeName ) { 1995 activeElement = document.body; 1996 } 1997 1998 return activeElement; 1999}; 2000 2001 2002 2003var safeBlur = $.ui.safeBlur = function( element ) { 2004 2005 // Support: IE9 - 10 only 2006 // If the <body> is blurred, IE will switch windows, see #9420 2007 if ( element && element.nodeName.toLowerCase() !== "body" ) { 2008 $( element ).trigger( "blur" ); 2009 } 2010}; 2011 2012 2013/*! 2014 * jQuery UI Draggable 1.12.1 2015 * http://jqueryui.com 2016 * 2017 * Copyright jQuery Foundation and other contributors 2018 * Released under the MIT license. 2019 * http://jquery.org/license 2020 */ 2021 2022//>>label: Draggable 2023//>>group: Interactions 2024//>>description: Enables dragging functionality for any element. 2025//>>docs: http://api.jqueryui.com/draggable/ 2026//>>demos: http://jqueryui.com/draggable/ 2027//>>css.structure: ../../themes/base/draggable.css 2028 2029 2030 2031$.widget( "ui.draggable", $.ui.mouse, { 2032 version: "1.12.1", 2033 widgetEventPrefix: "drag", 2034 options: { 2035 addClasses: true, 2036 appendTo: "parent", 2037 axis: false, 2038 connectToSortable: false, 2039 containment: false, 2040 cursor: "auto", 2041 cursorAt: false, 2042 grid: false, 2043 handle: false, 2044 helper: "original", 2045 iframeFix: false, 2046 opacity: false, 2047 refreshPositions: false, 2048 revert: false, 2049 revertDuration: 500, 2050 scope: "default", 2051 scroll: true, 2052 scrollSensitivity: 20, 2053 scrollSpeed: 20, 2054 snap: false, 2055 snapMode: "both", 2056 snapTolerance: 20, 2057 stack: false, 2058 zIndex: false, 2059 2060 // Callbacks 2061 drag: null, 2062 start: null, 2063 stop: null 2064 }, 2065 _create: function() { 2066 2067 if ( this.options.helper === "original" ) { 2068 this._setPositionRelative(); 2069 } 2070 if ( this.options.addClasses ) { 2071 this._addClass( "ui-draggable" ); 2072 } 2073 this._setHandleClassName(); 2074 2075 this._mouseInit(); 2076 }, 2077 2078 _setOption: function( key, value ) { 2079 this._super( key, value ); 2080 if ( key === "handle" ) { 2081 this._removeHandleClassName(); 2082 this._setHandleClassName(); 2083 } 2084 }, 2085 2086 _destroy: function() { 2087 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 2088 this.destroyOnClear = true; 2089 return; 2090 } 2091 this._removeHandleClassName(); 2092 this._mouseDestroy(); 2093 }, 2094 2095 _mouseCapture: function( event ) { 2096 var o = this.options; 2097 2098 // Among others, prevent a drag on a resizable-handle 2099 if ( this.helper || o.disabled || 2100 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 2101 return false; 2102 } 2103 2104 //Quit if we're not on a valid handle 2105 this.handle = this._getHandle( event ); 2106 if ( !this.handle ) { 2107 return false; 2108 } 2109 2110 this._blurActiveElement( event ); 2111 2112 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 2113 2114 return true; 2115 2116 }, 2117 2118 _blockFrames: function( selector ) { 2119 this.iframeBlocks = this.document.find( selector ).map( function() { 2120 var iframe = $( this ); 2121 2122 return $( "<div>" ) 2123 .css( "position", "absolute" ) 2124 .appendTo( iframe.parent() ) 2125 .outerWidth( iframe.outerWidth() ) 2126 .outerHeight( iframe.outerHeight() ) 2127 .offset( iframe.offset() )[ 0 ]; 2128 } ); 2129 }, 2130 2131 _unblockFrames: function() { 2132 if ( this.iframeBlocks ) { 2133 this.iframeBlocks.remove(); 2134 delete this.iframeBlocks; 2135 } 2136 }, 2137 2138 _blurActiveElement: function( event ) { 2139 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 2140 target = $( event.target ); 2141 2142 // Don't blur if the event occurred on an element that is within 2143 // the currently focused element 2144 // See #10527, #12472 2145 if ( target.closest( activeElement ).length ) { 2146 return; 2147 } 2148 2149 // Blur any element that currently has focus, see #4261 2150 $.ui.safeBlur( activeElement ); 2151 }, 2152 2153 _mouseStart: function( event ) { 2154 2155 var o = this.options; 2156 2157 //Create and append the visible helper 2158 this.helper = this._createHelper( event ); 2159 2160 this._addClass( this.helper, "ui-draggable-dragging" ); 2161 2162 //Cache the helper size 2163 this._cacheHelperProportions(); 2164 2165 //If ddmanager is used for droppables, set the global draggable 2166 if ( $.ui.ddmanager ) { 2167 $.ui.ddmanager.current = this; 2168 } 2169 2170 /* 2171 * - Position generation - 2172 * This block generates everything position related - it's the core of draggables. 2173 */ 2174 2175 //Cache the margins of the original element 2176 this._cacheMargins(); 2177 2178 //Store the helper's css position 2179 this.cssPosition = this.helper.css( "position" ); 2180 this.scrollParent = this.helper.scrollParent( true ); 2181 this.offsetParent = this.helper.offsetParent(); 2182 this.hasFixedAncestor = this.helper.parents().filter( function() { 2183 return $( this ).css( "position" ) === "fixed"; 2184 } ).length > 0; 2185 2186 //The element's absolute position on the page minus margins 2187 this.positionAbs = this.element.offset(); 2188 this._refreshOffsets( event ); 2189 2190 //Generate the original position 2191 this.originalPosition = this.position = this._generatePosition( event, false ); 2192 this.originalPageX = event.pageX; 2193 this.originalPageY = event.pageY; 2194 2195 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 2196 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); 2197 2198 //Set a containment if given in the options 2199 this._setContainment(); 2200 2201 //Trigger event + callbacks 2202 if ( this._trigger( "start", event ) === false ) { 2203 this._clear(); 2204 return false; 2205 } 2206 2207 //Recache the helper size 2208 this._cacheHelperProportions(); 2209 2210 //Prepare the droppable offsets 2211 if ( $.ui.ddmanager && !o.dropBehaviour ) { 2212 $.ui.ddmanager.prepareOffsets( this, event ); 2213 } 2214 2215 // Execute the drag once - this causes the helper not to be visible before getting its 2216 // correct position 2217 this._mouseDrag( event, true ); 2218 2219 // If the ddmanager is used for droppables, inform the manager that dragging has started 2220 // (see #5003) 2221 if ( $.ui.ddmanager ) { 2222 $.ui.ddmanager.dragStart( this, event ); 2223 } 2224 2225 return true; 2226 }, 2227 2228 _refreshOffsets: function( event ) { 2229 this.offset = { 2230 top: this.positionAbs.top - this.margins.top, 2231 left: this.positionAbs.left - this.margins.left, 2232 scroll: false, 2233 parent: this._getParentOffset(), 2234 relative: this._getRelativeOffset() 2235 }; 2236 2237 this.offset.click = { 2238 left: event.pageX - this.offset.left, 2239 top: event.pageY - this.offset.top 2240 }; 2241 }, 2242 2243 _mouseDrag: function( event, noPropagation ) { 2244 2245 // reset any necessary cached properties (see #5009) 2246 if ( this.hasFixedAncestor ) { 2247 this.offset.parent = this._getParentOffset(); 2248 } 2249 2250 //Compute the helpers position 2251 this.position = this._generatePosition( event, true ); 2252 this.positionAbs = this._convertPositionTo( "absolute" ); 2253 2254 //Call plugins and callbacks and use the resulting position if something is returned 2255 if ( !noPropagation ) { 2256 var ui = this._uiHash(); 2257 if ( this._trigger( "drag", event, ui ) === false ) { 2258 this._mouseUp( new $.Event( "mouseup", event ) ); 2259 return false; 2260 } 2261 this.position = ui.position; 2262 } 2263 2264 this.helper[ 0 ].style.left = this.position.left + "px"; 2265 this.helper[ 0 ].style.top = this.position.top + "px"; 2266 2267 if ( $.ui.ddmanager ) { 2268 $.ui.ddmanager.drag( this, event ); 2269 } 2270 2271 return false; 2272 }, 2273 2274 _mouseStop: function( event ) { 2275 2276 //If we are using droppables, inform the manager about the drop 2277 var that = this, 2278 dropped = false; 2279 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 2280 dropped = $.ui.ddmanager.drop( this, event ); 2281 } 2282 2283 //if a drop comes from outside (a sortable) 2284 if ( this.dropped ) { 2285 dropped = this.dropped; 2286 this.dropped = false; 2287 } 2288 2289 if ( ( this.options.revert === "invalid" && !dropped ) || 2290 ( this.options.revert === "valid" && dropped ) || 2291 this.options.revert === true || ( $.isFunction( this.options.revert ) && 2292 this.options.revert.call( this.element, dropped ) ) 2293 ) { 2294 $( this.helper ).animate( 2295 this.originalPosition, 2296 parseInt( this.options.revertDuration, 10 ), 2297 function() { 2298 if ( that._trigger( "stop", event ) !== false ) { 2299 that._clear(); 2300 } 2301 } 2302 ); 2303 } else { 2304 if ( this._trigger( "stop", event ) !== false ) { 2305 this._clear(); 2306 } 2307 } 2308 2309 return false; 2310 }, 2311 2312 _mouseUp: function( event ) { 2313 this._unblockFrames(); 2314 2315 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 2316 // (see #5003) 2317 if ( $.ui.ddmanager ) { 2318 $.ui.ddmanager.dragStop( this, event ); 2319 } 2320 2321 // Only need to focus if the event occurred on the draggable itself, see #10527 2322 if ( this.handleElement.is( event.target ) ) { 2323 2324 // The interaction is over; whether or not the click resulted in a drag, 2325 // focus the element 2326 this.element.trigger( "focus" ); 2327 } 2328 2329 return $.ui.mouse.prototype._mouseUp.call( this, event ); 2330 }, 2331 2332 cancel: function() { 2333 2334 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 2335 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 2336 } else { 2337 this._clear(); 2338 } 2339 2340 return this; 2341 2342 }, 2343 2344 _getHandle: function( event ) { 2345 return this.options.handle ? 2346 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 2347 true; 2348 }, 2349 2350 _setHandleClassName: function() { 2351 this.handleElement = this.options.handle ? 2352 this.element.find( this.options.handle ) : this.element; 2353 this._addClass( this.handleElement, "ui-draggable-handle" ); 2354 }, 2355 2356 _removeHandleClassName: function() { 2357 this._removeClass( this.handleElement, "ui-draggable-handle" ); 2358 }, 2359 2360 _createHelper: function( event ) { 2361 2362 var o = this.options, 2363 helperIsFunction = $.isFunction( o.helper ), 2364 helper = helperIsFunction ? 2365 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 2366 ( o.helper === "clone" ? 2367 this.element.clone().removeAttr( "id" ) : 2368 this.element ); 2369 2370 if ( !helper.parents( "body" ).length ) { 2371 helper.appendTo( ( o.appendTo === "parent" ? 2372 this.element[ 0 ].parentNode : 2373 o.appendTo ) ); 2374 } 2375 2376 // Http://bugs.jqueryui.com/ticket/9446 2377 // a helper function can return the original element 2378 // which wouldn't have been set to relative in _create 2379 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 2380 this._setPositionRelative(); 2381 } 2382 2383 if ( helper[ 0 ] !== this.element[ 0 ] && 2384 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 2385 helper.css( "position", "absolute" ); 2386 } 2387 2388 return helper; 2389 2390 }, 2391 2392 _setPositionRelative: function() { 2393 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 2394 this.element[ 0 ].style.position = "relative"; 2395 } 2396 }, 2397 2398 _adjustOffsetFromHelper: function( obj ) { 2399 if ( typeof obj === "string" ) { 2400 obj = obj.split( " " ); 2401 } 2402 if ( $.isArray( obj ) ) { 2403 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 2404 } 2405 if ( "left" in obj ) { 2406 this.offset.click.left = obj.left + this.margins.left; 2407 } 2408 if ( "right" in obj ) { 2409 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 2410 } 2411 if ( "top" in obj ) { 2412 this.offset.click.top = obj.top + this.margins.top; 2413 } 2414 if ( "bottom" in obj ) { 2415 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 2416 } 2417 }, 2418 2419 _isRootNode: function( element ) { 2420 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 2421 }, 2422 2423 _getParentOffset: function() { 2424 2425 //Get the offsetParent and cache its position 2426 var po = this.offsetParent.offset(), 2427 document = this.document[ 0 ]; 2428 2429 // This is a special case where we need to modify a offset calculated on start, since the 2430 // following happened: 2431 // 1. The position of the helper is absolute, so it's position is calculated based on the 2432 // next positioned parent 2433 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 2434 // the document, which means that the scroll is included in the initial calculation of the 2435 // offset of the parent, and never recalculated upon drag 2436 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 2437 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 2438 po.left += this.scrollParent.scrollLeft(); 2439 po.top += this.scrollParent.scrollTop(); 2440 } 2441 2442 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 2443 po = { top: 0, left: 0 }; 2444 } 2445 2446 return { 2447 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 2448 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 2449 }; 2450 2451 }, 2452 2453 _getRelativeOffset: function() { 2454 if ( this.cssPosition !== "relative" ) { 2455 return { top: 0, left: 0 }; 2456 } 2457 2458 var p = this.element.position(), 2459 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2460 2461 return { 2462 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 2463 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 2464 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 2465 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 2466 }; 2467 2468 }, 2469 2470 _cacheMargins: function() { 2471 this.margins = { 2472 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 2473 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 2474 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 2475 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 2476 }; 2477 }, 2478 2479 _cacheHelperProportions: function() { 2480 this.helperProportions = { 2481 width: this.helper.outerWidth(), 2482 height: this.helper.outerHeight() 2483 }; 2484 }, 2485 2486 _setContainment: function() { 2487 2488 var isUserScrollable, c, ce, 2489 o = this.options, 2490 document = this.document[ 0 ]; 2491 2492 this.relativeContainer = null; 2493 2494 if ( !o.containment ) { 2495 this.containment = null; 2496 return; 2497 } 2498 2499 if ( o.containment === "window" ) { 2500 this.containment = [ 2501 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 2502 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 2503 $( window ).scrollLeft() + $( window ).width() - 2504 this.helperProportions.width - this.margins.left, 2505 $( window ).scrollTop() + 2506 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 2507 this.helperProportions.height - this.margins.top 2508 ]; 2509 return; 2510 } 2511 2512 if ( o.containment === "document" ) { 2513 this.containment = [ 2514 0, 2515 0, 2516 $( document ).width() - this.helperProportions.width - this.margins.left, 2517 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 2518 this.helperProportions.height - this.margins.top 2519 ]; 2520 return; 2521 } 2522 2523 if ( o.containment.constructor === Array ) { 2524 this.containment = o.containment; 2525 return; 2526 } 2527 2528 if ( o.containment === "parent" ) { 2529 o.containment = this.helper[ 0 ].parentNode; 2530 } 2531 2532 c = $( o.containment ); 2533 ce = c[ 0 ]; 2534 2535 if ( !ce ) { 2536 return; 2537 } 2538 2539 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 2540 2541 this.containment = [ 2542 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 2543 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 2544 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 2545 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 2546 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 2547 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 2548 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 2549 this.helperProportions.width - 2550 this.margins.left - 2551 this.margins.right, 2552 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 2553 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 2554 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 2555 this.helperProportions.height - 2556 this.margins.top - 2557 this.margins.bottom 2558 ]; 2559 this.relativeContainer = c; 2560 }, 2561 2562 _convertPositionTo: function( d, pos ) { 2563 2564 if ( !pos ) { 2565 pos = this.position; 2566 } 2567 2568 var mod = d === "absolute" ? 1 : -1, 2569 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2570 2571 return { 2572 top: ( 2573 2574 // The absolute mouse position 2575 pos.top + 2576 2577 // Only for relative positioned nodes: Relative offset from element to offset parent 2578 this.offset.relative.top * mod + 2579 2580 // The offsetParent's offset without borders (offset + border) 2581 this.offset.parent.top * mod - 2582 ( ( this.cssPosition === "fixed" ? 2583 -this.offset.scroll.top : 2584 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 2585 ), 2586 left: ( 2587 2588 // The absolute mouse position 2589 pos.left + 2590 2591 // Only for relative positioned nodes: Relative offset from element to offset parent 2592 this.offset.relative.left * mod + 2593 2594 // The offsetParent's offset without borders (offset + border) 2595 this.offset.parent.left * mod - 2596 ( ( this.cssPosition === "fixed" ? 2597 -this.offset.scroll.left : 2598 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 2599 ) 2600 }; 2601 2602 }, 2603 2604 _generatePosition: function( event, constrainPosition ) { 2605 2606 var containment, co, top, left, 2607 o = this.options, 2608 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2609 pageX = event.pageX, 2610 pageY = event.pageY; 2611 2612 // Cache the scroll 2613 if ( !scrollIsRootNode || !this.offset.scroll ) { 2614 this.offset.scroll = { 2615 top: this.scrollParent.scrollTop(), 2616 left: this.scrollParent.scrollLeft() 2617 }; 2618 } 2619 2620 /* 2621 * - Position constraining - 2622 * Constrain the position to a mix of grid, containment. 2623 */ 2624 2625 // If we are not dragging yet, we won't check for options 2626 if ( constrainPosition ) { 2627 if ( this.containment ) { 2628 if ( this.relativeContainer ) { 2629 co = this.relativeContainer.offset(); 2630 containment = [ 2631 this.containment[ 0 ] + co.left, 2632 this.containment[ 1 ] + co.top, 2633 this.containment[ 2 ] + co.left, 2634 this.containment[ 3 ] + co.top 2635 ]; 2636 } else { 2637 containment = this.containment; 2638 } 2639 2640 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 2641 pageX = containment[ 0 ] + this.offset.click.left; 2642 } 2643 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 2644 pageY = containment[ 1 ] + this.offset.click.top; 2645 } 2646 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 2647 pageX = containment[ 2 ] + this.offset.click.left; 2648 } 2649 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 2650 pageY = containment[ 3 ] + this.offset.click.top; 2651 } 2652 } 2653 2654 if ( o.grid ) { 2655 2656 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 2657 // argument errors in IE (see ticket #6950) 2658 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 2659 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 2660 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 2661 top - this.offset.click.top > containment[ 3 ] ) ? 2662 top : 2663 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 2664 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 2665 2666 left = o.grid[ 0 ] ? this.originalPageX + 2667 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 2668 this.originalPageX; 2669 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 2670 left - this.offset.click.left > containment[ 2 ] ) ? 2671 left : 2672 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 2673 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 2674 } 2675 2676 if ( o.axis === "y" ) { 2677 pageX = this.originalPageX; 2678 } 2679 2680 if ( o.axis === "x" ) { 2681 pageY = this.originalPageY; 2682 } 2683 } 2684 2685 return { 2686 top: ( 2687 2688 // The absolute mouse position 2689 pageY - 2690 2691 // Click offset (relative to the element) 2692 this.offset.click.top - 2693 2694 // Only for relative positioned nodes: Relative offset from element to offset parent 2695 this.offset.relative.top - 2696 2697 // The offsetParent's offset without borders (offset + border) 2698 this.offset.parent.top + 2699 ( this.cssPosition === "fixed" ? 2700 -this.offset.scroll.top : 2701 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2702 ), 2703 left: ( 2704 2705 // The absolute mouse position 2706 pageX - 2707 2708 // Click offset (relative to the element) 2709 this.offset.click.left - 2710 2711 // Only for relative positioned nodes: Relative offset from element to offset parent 2712 this.offset.relative.left - 2713 2714 // The offsetParent's offset without borders (offset + border) 2715 this.offset.parent.left + 2716 ( this.cssPosition === "fixed" ? 2717 -this.offset.scroll.left : 2718 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2719 ) 2720 }; 2721 2722 }, 2723 2724 _clear: function() { 2725 this._removeClass( this.helper, "ui-draggable-dragging" ); 2726 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 2727 this.helper.remove(); 2728 } 2729 this.helper = null; 2730 this.cancelHelperRemoval = false; 2731 if ( this.destroyOnClear ) { 2732 this.destroy(); 2733 } 2734 }, 2735 2736 // From now on bulk stuff - mainly helpers 2737 2738 _trigger: function( type, event, ui ) { 2739 ui = ui || this._uiHash(); 2740 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2741 2742 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 2743 if ( /^(drag|start|stop)/.test( type ) ) { 2744 this.positionAbs = this._convertPositionTo( "absolute" ); 2745 ui.offset = this.positionAbs; 2746 } 2747 return $.Widget.prototype._trigger.call( this, type, event, ui ); 2748 }, 2749 2750 plugins: {}, 2751 2752 _uiHash: function() { 2753 return { 2754 helper: this.helper, 2755 position: this.position, 2756 originalPosition: this.originalPosition, 2757 offset: this.positionAbs 2758 }; 2759 } 2760 2761} ); 2762 2763$.ui.plugin.add( "draggable", "connectToSortable", { 2764 start: function( event, ui, draggable ) { 2765 var uiSortable = $.extend( {}, ui, { 2766 item: draggable.element 2767 } ); 2768 2769 draggable.sortables = []; 2770 $( draggable.options.connectToSortable ).each( function() { 2771 var sortable = $( this ).sortable( "instance" ); 2772 2773 if ( sortable && !sortable.options.disabled ) { 2774 draggable.sortables.push( sortable ); 2775 2776 // RefreshPositions is called at drag start to refresh the containerCache 2777 // which is used in drag. This ensures it's initialized and synchronized 2778 // with any changes that might have happened on the page since initialization. 2779 sortable.refreshPositions(); 2780 sortable._trigger( "activate", event, uiSortable ); 2781 } 2782 } ); 2783 }, 2784 stop: function( event, ui, draggable ) { 2785 var uiSortable = $.extend( {}, ui, { 2786 item: draggable.element 2787 } ); 2788 2789 draggable.cancelHelperRemoval = false; 2790 2791 $.each( draggable.sortables, function() { 2792 var sortable = this; 2793 2794 if ( sortable.isOver ) { 2795 sortable.isOver = 0; 2796 2797 // Allow this sortable to handle removing the helper 2798 draggable.cancelHelperRemoval = true; 2799 sortable.cancelHelperRemoval = false; 2800 2801 // Use _storedCSS To restore properties in the sortable, 2802 // as this also handles revert (#9675) since the draggable 2803 // may have modified them in unexpected ways (#8809) 2804 sortable._storedCSS = { 2805 position: sortable.placeholder.css( "position" ), 2806 top: sortable.placeholder.css( "top" ), 2807 left: sortable.placeholder.css( "left" ) 2808 }; 2809 2810 sortable._mouseStop( event ); 2811 2812 // Once drag has ended, the sortable should return to using 2813 // its original helper, not the shared helper from draggable 2814 sortable.options.helper = sortable.options._helper; 2815 } else { 2816 2817 // Prevent this Sortable from removing the helper. 2818 // However, don't set the draggable to remove the helper 2819 // either as another connected Sortable may yet handle the removal. 2820 sortable.cancelHelperRemoval = true; 2821 2822 sortable._trigger( "deactivate", event, uiSortable ); 2823 } 2824 } ); 2825 }, 2826 drag: function( event, ui, draggable ) { 2827 $.each( draggable.sortables, function() { 2828 var innermostIntersecting = false, 2829 sortable = this; 2830 2831 // Copy over variables that sortable's _intersectsWith uses 2832 sortable.positionAbs = draggable.positionAbs; 2833 sortable.helperProportions = draggable.helperProportions; 2834 sortable.offset.click = draggable.offset.click; 2835 2836 if ( sortable._intersectsWith( sortable.containerCache ) ) { 2837 innermostIntersecting = true; 2838 2839 $.each( draggable.sortables, function() { 2840 2841 // Copy over variables that sortable's _intersectsWith uses 2842 this.positionAbs = draggable.positionAbs; 2843 this.helperProportions = draggable.helperProportions; 2844 this.offset.click = draggable.offset.click; 2845 2846 if ( this !== sortable && 2847 this._intersectsWith( this.containerCache ) && 2848 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 2849 innermostIntersecting = false; 2850 } 2851 2852 return innermostIntersecting; 2853 } ); 2854 } 2855 2856 if ( innermostIntersecting ) { 2857 2858 // If it intersects, we use a little isOver variable and set it once, 2859 // so that the move-in stuff gets fired only once. 2860 if ( !sortable.isOver ) { 2861 sortable.isOver = 1; 2862 2863 // Store draggable's parent in case we need to reappend to it later. 2864 draggable._parent = ui.helper.parent(); 2865 2866 sortable.currentItem = ui.helper 2867 .appendTo( sortable.element ) 2868 .data( "ui-sortable-item", true ); 2869 2870 // Store helper option to later restore it 2871 sortable.options._helper = sortable.options.helper; 2872 2873 sortable.options.helper = function() { 2874 return ui.helper[ 0 ]; 2875 }; 2876 2877 // Fire the start events of the sortable with our passed browser event, 2878 // and our own helper (so it doesn't create a new one) 2879 event.target = sortable.currentItem[ 0 ]; 2880 sortable._mouseCapture( event, true ); 2881 sortable._mouseStart( event, true, true ); 2882 2883 // Because the browser event is way off the new appended portlet, 2884 // modify necessary variables to reflect the changes 2885 sortable.offset.click.top = draggable.offset.click.top; 2886 sortable.offset.click.left = draggable.offset.click.left; 2887 sortable.offset.parent.left -= draggable.offset.parent.left - 2888 sortable.offset.parent.left; 2889 sortable.offset.parent.top -= draggable.offset.parent.top - 2890 sortable.offset.parent.top; 2891 2892 draggable._trigger( "toSortable", event ); 2893 2894 // Inform draggable that the helper is in a valid drop zone, 2895 // used solely in the revert option to handle "valid/invalid". 2896 draggable.dropped = sortable.element; 2897 2898 // Need to refreshPositions of all sortables in the case that 2899 // adding to one sortable changes the location of the other sortables (#9675) 2900 $.each( draggable.sortables, function() { 2901 this.refreshPositions(); 2902 } ); 2903 2904 // Hack so receive/update callbacks work (mostly) 2905 draggable.currentItem = draggable.element; 2906 sortable.fromOutside = draggable; 2907 } 2908 2909 if ( sortable.currentItem ) { 2910 sortable._mouseDrag( event ); 2911 2912 // Copy the sortable's position because the draggable's can potentially reflect 2913 // a relative position, while sortable is always absolute, which the dragged 2914 // element has now become. (#8809) 2915 ui.position = sortable.position; 2916 } 2917 } else { 2918 2919 // If it doesn't intersect with the sortable, and it intersected before, 2920 // we fake the drag stop of the sortable, but make sure it doesn't remove 2921 // the helper by using cancelHelperRemoval. 2922 if ( sortable.isOver ) { 2923 2924 sortable.isOver = 0; 2925 sortable.cancelHelperRemoval = true; 2926 2927 // Calling sortable's mouseStop would trigger a revert, 2928 // so revert must be temporarily false until after mouseStop is called. 2929 sortable.options._revert = sortable.options.revert; 2930 sortable.options.revert = false; 2931 2932 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 2933 sortable._mouseStop( event, true ); 2934 2935 // Restore sortable behaviors that were modfied 2936 // when the draggable entered the sortable area (#9481) 2937 sortable.options.revert = sortable.options._revert; 2938 sortable.options.helper = sortable.options._helper; 2939 2940 if ( sortable.placeholder ) { 2941 sortable.placeholder.remove(); 2942 } 2943 2944 // Restore and recalculate the draggable's offset considering the sortable 2945 // may have modified them in unexpected ways. (#8809, #10669) 2946 ui.helper.appendTo( draggable._parent ); 2947 draggable._refreshOffsets( event ); 2948 ui.position = draggable._generatePosition( event, true ); 2949 2950 draggable._trigger( "fromSortable", event ); 2951 2952 // Inform draggable that the helper is no longer in a valid drop zone 2953 draggable.dropped = false; 2954 2955 // Need to refreshPositions of all sortables just in case removing 2956 // from one sortable changes the location of other sortables (#9675) 2957 $.each( draggable.sortables, function() { 2958 this.refreshPositions(); 2959 } ); 2960 } 2961 } 2962 } ); 2963 } 2964} ); 2965 2966$.ui.plugin.add( "draggable", "cursor", { 2967 start: function( event, ui, instance ) { 2968 var t = $( "body" ), 2969 o = instance.options; 2970 2971 if ( t.css( "cursor" ) ) { 2972 o._cursor = t.css( "cursor" ); 2973 } 2974 t.css( "cursor", o.cursor ); 2975 }, 2976 stop: function( event, ui, instance ) { 2977 var o = instance.options; 2978 if ( o._cursor ) { 2979 $( "body" ).css( "cursor", o._cursor ); 2980 } 2981 } 2982} ); 2983 2984$.ui.plugin.add( "draggable", "opacity", { 2985 start: function( event, ui, instance ) { 2986 var t = $( ui.helper ), 2987 o = instance.options; 2988 if ( t.css( "opacity" ) ) { 2989 o._opacity = t.css( "opacity" ); 2990 } 2991 t.css( "opacity", o.opacity ); 2992 }, 2993 stop: function( event, ui, instance ) { 2994 var o = instance.options; 2995 if ( o._opacity ) { 2996 $( ui.helper ).css( "opacity", o._opacity ); 2997 } 2998 } 2999} ); 3000 3001$.ui.plugin.add( "draggable", "scroll", { 3002 start: function( event, ui, i ) { 3003 if ( !i.scrollParentNotHidden ) { 3004 i.scrollParentNotHidden = i.helper.scrollParent( false ); 3005 } 3006 3007 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 3008 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 3009 i.overflowOffset = i.scrollParentNotHidden.offset(); 3010 } 3011 }, 3012 drag: function( event, ui, i ) { 3013 3014 var o = i.options, 3015 scrolled = false, 3016 scrollParent = i.scrollParentNotHidden[ 0 ], 3017 document = i.document[ 0 ]; 3018 3019 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 3020 if ( !o.axis || o.axis !== "x" ) { 3021 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 3022 o.scrollSensitivity ) { 3023 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 3024 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 3025 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 3026 } 3027 } 3028 3029 if ( !o.axis || o.axis !== "y" ) { 3030 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 3031 o.scrollSensitivity ) { 3032 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 3033 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 3034 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 3035 } 3036 } 3037 3038 } else { 3039 3040 if ( !o.axis || o.axis !== "x" ) { 3041 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 3042 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 3043 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 3044 o.scrollSensitivity ) { 3045 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 3046 } 3047 } 3048 3049 if ( !o.axis || o.axis !== "y" ) { 3050 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 3051 scrolled = $( document ).scrollLeft( 3052 $( document ).scrollLeft() - o.scrollSpeed 3053 ); 3054 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 3055 o.scrollSensitivity ) { 3056 scrolled = $( document ).scrollLeft( 3057 $( document ).scrollLeft() + o.scrollSpeed 3058 ); 3059 } 3060 } 3061 3062 } 3063 3064 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 3065 $.ui.ddmanager.prepareOffsets( i, event ); 3066 } 3067 3068 } 3069} ); 3070 3071$.ui.plugin.add( "draggable", "snap", { 3072 start: function( event, ui, i ) { 3073 3074 var o = i.options; 3075 3076 i.snapElements = []; 3077 3078 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 3079 .each( function() { 3080 var $t = $( this ), 3081 $o = $t.offset(); 3082 if ( this !== i.element[ 0 ] ) { 3083 i.snapElements.push( { 3084 item: this, 3085 width: $t.outerWidth(), height: $t.outerHeight(), 3086 top: $o.top, left: $o.left 3087 } ); 3088 } 3089 } ); 3090 3091 }, 3092 drag: function( event, ui, inst ) { 3093 3094 var ts, bs, ls, rs, l, r, t, b, i, first, 3095 o = inst.options, 3096 d = o.snapTolerance, 3097 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 3098 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 3099 3100 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 3101 3102 l = inst.snapElements[ i ].left - inst.margins.left; 3103 r = l + inst.snapElements[ i ].width; 3104 t = inst.snapElements[ i ].top - inst.margins.top; 3105 b = t + inst.snapElements[ i ].height; 3106 3107 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 3108 !$.contains( inst.snapElements[ i ].item.ownerDocument, 3109 inst.snapElements[ i ].item ) ) { 3110 if ( inst.snapElements[ i ].snapping ) { 3111 ( inst.options.snap.release && 3112 inst.options.snap.release.call( 3113 inst.element, 3114 event, 3115 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 3116 ) ); 3117 } 3118 inst.snapElements[ i ].snapping = false; 3119 continue; 3120 } 3121 3122 if ( o.snapMode !== "inner" ) { 3123 ts = Math.abs( t - y2 ) <= d; 3124 bs = Math.abs( b - y1 ) <= d; 3125 ls = Math.abs( l - x2 ) <= d; 3126 rs = Math.abs( r - x1 ) <= d; 3127 if ( ts ) { 3128 ui.position.top = inst._convertPositionTo( "relative", { 3129 top: t - inst.helperProportions.height, 3130 left: 0 3131 } ).top; 3132 } 3133 if ( bs ) { 3134 ui.position.top = inst._convertPositionTo( "relative", { 3135 top: b, 3136 left: 0 3137 } ).top; 3138 } 3139 if ( ls ) { 3140 ui.position.left = inst._convertPositionTo( "relative", { 3141 top: 0, 3142 left: l - inst.helperProportions.width 3143 } ).left; 3144 } 3145 if ( rs ) { 3146 ui.position.left = inst._convertPositionTo( "relative", { 3147 top: 0, 3148 left: r 3149 } ).left; 3150 } 3151 } 3152 3153 first = ( ts || bs || ls || rs ); 3154 3155 if ( o.snapMode !== "outer" ) { 3156 ts = Math.abs( t - y1 ) <= d; 3157 bs = Math.abs( b - y2 ) <= d; 3158 ls = Math.abs( l - x1 ) <= d; 3159 rs = Math.abs( r - x2 ) <= d; 3160 if ( ts ) { 3161 ui.position.top = inst._convertPositionTo( "relative", { 3162 top: t, 3163 left: 0 3164 } ).top; 3165 } 3166 if ( bs ) { 3167 ui.position.top = inst._convertPositionTo( "relative", { 3168 top: b - inst.helperProportions.height, 3169 left: 0 3170 } ).top; 3171 } 3172 if ( ls ) { 3173 ui.position.left = inst._convertPositionTo( "relative", { 3174 top: 0, 3175 left: l 3176 } ).left; 3177 } 3178 if ( rs ) { 3179 ui.position.left = inst._convertPositionTo( "relative", { 3180 top: 0, 3181 left: r - inst.helperProportions.width 3182 } ).left; 3183 } 3184 } 3185 3186 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 3187 ( inst.options.snap.snap && 3188 inst.options.snap.snap.call( 3189 inst.element, 3190 event, 3191 $.extend( inst._uiHash(), { 3192 snapItem: inst.snapElements[ i ].item 3193 } ) ) ); 3194 } 3195 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 3196 3197 } 3198 3199 } 3200} ); 3201 3202$.ui.plugin.add( "draggable", "stack", { 3203 start: function( event, ui, instance ) { 3204 var min, 3205 o = instance.options, 3206 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 3207 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 3208 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 3209 } ); 3210 3211 if ( !group.length ) { return; } 3212 3213 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 3214 $( group ).each( function( i ) { 3215 $( this ).css( "zIndex", min + i ); 3216 } ); 3217 this.css( "zIndex", ( min + group.length ) ); 3218 } 3219} ); 3220 3221$.ui.plugin.add( "draggable", "zIndex", { 3222 start: function( event, ui, instance ) { 3223 var t = $( ui.helper ), 3224 o = instance.options; 3225 3226 if ( t.css( "zIndex" ) ) { 3227 o._zIndex = t.css( "zIndex" ); 3228 } 3229 t.css( "zIndex", o.zIndex ); 3230 }, 3231 stop: function( event, ui, instance ) { 3232 var o = instance.options; 3233 3234 if ( o._zIndex ) { 3235 $( ui.helper ).css( "zIndex", o._zIndex ); 3236 } 3237 } 3238} ); 3239 3240var widgetsDraggable = $.ui.draggable; 3241 3242 3243/*! 3244 * jQuery UI Droppable 1.12.1 3245 * http://jqueryui.com 3246 * 3247 * Copyright jQuery Foundation and other contributors 3248 * Released under the MIT license. 3249 * http://jquery.org/license 3250 */ 3251 3252//>>label: Droppable 3253//>>group: Interactions 3254//>>description: Enables drop targets for draggable elements. 3255//>>docs: http://api.jqueryui.com/droppable/ 3256//>>demos: http://jqueryui.com/droppable/ 3257 3258 3259 3260$.widget( "ui.droppable", { 3261 version: "1.12.1", 3262 widgetEventPrefix: "drop", 3263 options: { 3264 accept: "*", 3265 addClasses: true, 3266 greedy: false, 3267 scope: "default", 3268 tolerance: "intersect", 3269 3270 // Callbacks 3271 activate: null, 3272 deactivate: null, 3273 drop: null, 3274 out: null, 3275 over: null 3276 }, 3277 _create: function() { 3278 3279 var proportions, 3280 o = this.options, 3281 accept = o.accept; 3282 3283 this.isover = false; 3284 this.isout = true; 3285 3286 this.accept = $.isFunction( accept ) ? accept : function( d ) { 3287 return d.is( accept ); 3288 }; 3289 3290 this.proportions = function( /* valueToWrite */ ) { 3291 if ( arguments.length ) { 3292 3293 // Store the droppable's proportions 3294 proportions = arguments[ 0 ]; 3295 } else { 3296 3297 // Retrieve or derive the droppable's proportions 3298 return proportions ? 3299 proportions : 3300 proportions = { 3301 width: this.element[ 0 ].offsetWidth, 3302 height: this.element[ 0 ].offsetHeight 3303 }; 3304 } 3305 }; 3306 3307 this._addToManager( o.scope ); 3308 3309 o.addClasses && this._addClass( "ui-droppable" ); 3310 3311 }, 3312 3313 _addToManager: function( scope ) { 3314 3315 // Add the reference and positions to the manager 3316 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 3317 $.ui.ddmanager.droppables[ scope ].push( this ); 3318 }, 3319 3320 _splice: function( drop ) { 3321 var i = 0; 3322 for ( ; i < drop.length; i++ ) { 3323 if ( drop[ i ] === this ) { 3324 drop.splice( i, 1 ); 3325 } 3326 } 3327 }, 3328 3329 _destroy: function() { 3330 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3331 3332 this._splice( drop ); 3333 }, 3334 3335 _setOption: function( key, value ) { 3336 3337 if ( key === "accept" ) { 3338 this.accept = $.isFunction( value ) ? value : function( d ) { 3339 return d.is( value ); 3340 }; 3341 } else if ( key === "scope" ) { 3342 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3343 3344 this._splice( drop ); 3345 this._addToManager( value ); 3346 } 3347 3348 this._super( key, value ); 3349 }, 3350 3351 _activate: function( event ) { 3352 var draggable = $.ui.ddmanager.current; 3353 3354 this._addActiveClass(); 3355 if ( draggable ) { 3356 this._trigger( "activate", event, this.ui( draggable ) ); 3357 } 3358 }, 3359 3360 _deactivate: function( event ) { 3361 var draggable = $.ui.ddmanager.current; 3362 3363 this._removeActiveClass(); 3364 if ( draggable ) { 3365 this._trigger( "deactivate", event, this.ui( draggable ) ); 3366 } 3367 }, 3368 3369 _over: function( event ) { 3370 3371 var draggable = $.ui.ddmanager.current; 3372 3373 // Bail if draggable and droppable are same element 3374 if ( !draggable || ( draggable.currentItem || 3375 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3376 return; 3377 } 3378 3379 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3380 draggable.element ) ) ) { 3381 this._addHoverClass(); 3382 this._trigger( "over", event, this.ui( draggable ) ); 3383 } 3384 3385 }, 3386 3387 _out: function( event ) { 3388 3389 var draggable = $.ui.ddmanager.current; 3390 3391 // Bail if draggable and droppable are same element 3392 if ( !draggable || ( draggable.currentItem || 3393 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3394 return; 3395 } 3396 3397 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3398 draggable.element ) ) ) { 3399 this._removeHoverClass(); 3400 this._trigger( "out", event, this.ui( draggable ) ); 3401 } 3402 3403 }, 3404 3405 _drop: function( event, custom ) { 3406 3407 var draggable = custom || $.ui.ddmanager.current, 3408 childrenIntersection = false;
vendor: 4,744 bytes, lines 3409-3581
3409 3410 // Bail if draggable and droppable are same element 3411 if ( !draggable || ( draggable.currentItem || 3412 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3413 return false; 3414 } 3415 3416 this.element 3417 .find( ":data(ui-droppable)" ) 3418 .not( ".ui-draggable-dragging" ) 3419 .each( function() { 3420 var inst = $( this ).droppable( "instance" ); 3421 if ( 3422 inst.options.greedy && 3423 !inst.options.disabled && 3424 inst.options.scope === draggable.options.scope && 3425 inst.accept.call( 3426 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 3427 ) && 3428 intersect( 3429 draggable, 3430 $.extend( inst, { offset: inst.element.offset() } ), 3431 inst.options.tolerance, event 3432 ) 3433 ) { 3434 childrenIntersection = true; 3435 return false; } 3436 } ); 3437 if ( childrenIntersection ) { 3438 return false; 3439 } 3440 3441 if ( this.accept.call( this.element[ 0 ], 3442 ( draggable.currentItem || draggable.element ) ) ) { 3443 this._removeActiveClass(); 3444 this._removeHoverClass(); 3445 3446 this._trigger( "drop", event, this.ui( draggable ) ); 3447 return this.element; 3448 } 3449 3450 return false; 3451 3452 }, 3453 3454 ui: function( c ) { 3455 return { 3456 draggable: ( c.currentItem || c.element ), 3457 helper: c.helper, 3458 position: c.position, 3459 offset: c.positionAbs 3460 }; 3461 }, 3462 3463 // Extension points just to make backcompat sane and avoid duplicating logic 3464 // TODO: Remove in 1.13 along with call to it below 3465 _addHoverClass: function() { 3466 this._addClass( "ui-droppable-hover" ); 3467 }, 3468 3469 _removeHoverClass: function() { 3470 this._removeClass( "ui-droppable-hover" ); 3471 }, 3472 3473 _addActiveClass: function() { 3474 this._addClass( "ui-droppable-active" ); 3475 }, 3476 3477 _removeActiveClass: function() { 3478 this._removeClass( "ui-droppable-active" ); 3479 } 3480} ); 3481 3482var intersect = $.ui.intersect = ( function() { 3483 function isOverAxis( x, reference, size ) { 3484 return ( x >= reference ) && ( x < ( reference + size ) ); 3485 } 3486 3487 return function( draggable, droppable, toleranceMode, event ) { 3488 3489 if ( !droppable.offset ) { 3490 return false; 3491 } 3492 3493 var x1 = ( draggable.positionAbs || 3494 draggable.position.absolute ).left + draggable.margins.left, 3495 y1 = ( draggable.positionAbs || 3496 draggable.position.absolute ).top + draggable.margins.top, 3497 x2 = x1 + draggable.helperProportions.width, 3498 y2 = y1 + draggable.helperProportions.height, 3499 l = droppable.offset.left, 3500 t = droppable.offset.top, 3501 r = l + droppable.proportions().width, 3502 b = t + droppable.proportions().height; 3503 3504 switch ( toleranceMode ) { 3505 case "fit": 3506 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 3507 case "intersect": 3508 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 3509 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 3510 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 3511 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 3512 case "pointer": 3513 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 3514 isOverAxis( event.pageX, l, droppable.proportions().width ); 3515 case "touch": 3516 return ( 3517 ( y1 >= t && y1 <= b ) || // Top edge touching 3518 ( y2 >= t && y2 <= b ) || // Bottom edge touching 3519 ( y1 < t && y2 > b ) // Surrounded vertically 3520 ) && ( 3521 ( x1 >= l && x1 <= r ) || // Left edge touching 3522 ( x2 >= l && x2 <= r ) || // Right edge touching 3523 ( x1 < l && x2 > r ) // Surrounded horizontally 3524 ); 3525 default: 3526 return false; 3527 } 3528 }; 3529} )(); 3530 3531/* 3532 This manager tracks offsets of draggables and droppables 3533*/ 3534$.ui.ddmanager = { 3535 current: null, 3536 droppables: { "default": [] }, 3537 prepareOffsets: function( t, event ) { 3538 3539 var i, j, 3540 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 3541 type = event ? event.type : null, // workaround for #2317 3542 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 3543 3544 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 3545 3546 // No disabled and non-accepted 3547 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 3548 ( t.currentItem || t.element ) ) ) ) { 3549 continue; 3550 } 3551 3552 // Filter out elements in the current dragged item 3553 for ( j = 0; j < list.length; j++ ) { 3554 if ( list[ j ] === m[ i ].element[ 0 ] ) { 3555 m[ i ].proportions().height = 0; 3556 continue droppablesLoop; 3557 } 3558 } 3559 3560 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 3561 if ( !m[ i ].visible ) { 3562 continue; 3563 } 3564 3565 // Activate the droppable if used directly from draggables 3566 if ( type === "mousedown" ) { 3567 m[ i ]._activate.call( m[ i ], event ); 3568 } 3569 3570 m[ i ].offset = m[ i ].element.offset(); 3571 m[ i ].proportions( { 3572 width: m[ i ].element[ 0 ].offsetWidth, 3573 height: m[ i ].element[ 0 ].offsetHeight 3574 } ); 3575 3576 } 3577 3578 }, 3579 drop: function( draggable, event ) { 3580 3581 var dropped = false;
vendor: 5,516 bytes, lines 3582-3787
3582 3583 // Create a copy of the droppables in case the list changes during the drop (#9116) 3584 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 3585 3586 if ( !this.options ) { 3587 return; 3588 } 3589 if ( !this.options.disabled && this.visible && 3590 intersect( draggable, this, this.options.tolerance, event ) ) { 3591 dropped = this._drop.call( this, event ) || dropped; 3592 } 3593 3594 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 3595 ( draggable.currentItem || draggable.element ) ) ) { 3596 this.isout = true; 3597 this.isover = false; 3598 this._deactivate.call( this, event ); 3599 } 3600 3601 } ); 3602 return dropped; 3603 3604 }, 3605 dragStart: function( draggable, event ) { 3606 3607 // Listen for scrolling so that if the dragging causes scrolling the position of the 3608 // droppables can be recalculated (see #5003) 3609 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 3610 if ( !draggable.options.refreshPositions ) { 3611 $.ui.ddmanager.prepareOffsets( draggable, event ); 3612 } 3613 } ); 3614 }, 3615 drag: function( draggable, event ) { 3616 3617 // If you have a highly dynamic page, you might try this option. It renders positions 3618 // every time you move the mouse. 3619 if ( draggable.options.refreshPositions ) { 3620 $.ui.ddmanager.prepareOffsets( draggable, event ); 3621 } 3622 3623 // Run through all droppables and check their positions based on specific tolerance options 3624 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 3625 3626 if ( this.options.disabled || this.greedyChild || !this.visible ) { 3627 return; 3628 } 3629 3630 var parentInstance, scope, parent, 3631 intersects = intersect( draggable, this, this.options.tolerance, event ), 3632 c = !intersects && this.isover ? 3633 "isout" : 3634 ( intersects && !this.isover ? "isover" : null ); 3635 if ( !c ) { 3636 return; 3637 } 3638 3639 if ( this.options.greedy ) { 3640 3641 // find droppable parents with same scope 3642 scope = this.options.scope; 3643 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 3644 return $( this ).droppable( "instance" ).options.scope === scope; 3645 } ); 3646 3647 if ( parent.length ) { 3648 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 3649 parentInstance.greedyChild = ( c === "isover" ); 3650 } 3651 } 3652 3653 // We just moved into a greedy child 3654 if ( parentInstance && c === "isover" ) { 3655 parentInstance.isover = false; 3656 parentInstance.isout = true; 3657 parentInstance._out.call( parentInstance, event ); 3658 } 3659 3660 this[ c ] = true; 3661 this[ c === "isout" ? "isover" : "isout" ] = false; 3662 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 3663 3664 // We just moved out of a greedy child 3665 if ( parentInstance && c === "isout" ) { 3666 parentInstance.isout = false; 3667 parentInstance.isover = true; 3668 parentInstance._over.call( parentInstance, event ); 3669 } 3670 } ); 3671 3672 }, 3673 dragStop: function( draggable, event ) { 3674 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 3675 3676 // Call prepareOffsets one final time since IE does not fire return scroll events when 3677 // overflow was caused by drag (see #5003) 3678 if ( !draggable.options.refreshPositions ) { 3679 $.ui.ddmanager.prepareOffsets( draggable, event ); 3680 } 3681 } 3682}; 3683 3684// DEPRECATED 3685// TODO: switch return back to widget declaration at top of file when this is removed 3686if ( $.uiBackCompat !== false ) { 3687 3688 // Backcompat for activeClass and hoverClass options 3689 $.widget( "ui.droppable", $.ui.droppable, { 3690 options: { 3691 hoverClass: false, 3692 activeClass: false 3693 }, 3694 _addActiveClass: function() { 3695 this._super(); 3696 if ( this.options.activeClass ) { 3697 this.element.addClass( this.options.activeClass ); 3698 } 3699 }, 3700 _removeActiveClass: function() { 3701 this._super(); 3702 if ( this.options.activeClass ) { 3703 this.element.removeClass( this.options.activeClass ); 3704 } 3705 }, 3706 _addHoverClass: function() { 3707 this._super(); 3708 if ( this.options.hoverClass ) { 3709 this.element.addClass( this.options.hoverClass ); 3710 } 3711 }, 3712 _removeHoverClass: function() { 3713 this._super(); 3714 if ( this.options.hoverClass ) { 3715 this.element.removeClass( this.options.hoverClass ); 3716 } 3717 } 3718 } ); 3719} 3720 3721var widgetsDroppable = $.ui.droppable; 3722 3723 3724/*! 3725 * jQuery UI Resizable 1.12.1 3726 * http://jqueryui.com 3727 * 3728 * Copyright jQuery Foundation and other contributors 3729 * Released under the MIT license. 3730 * http://jquery.org/license 3731 */ 3732 3733//>>label: Resizable 3734//>>group: Interactions 3735//>>description: Enables resize functionality for any element. 3736//>>docs: http://api.jqueryui.com/resizable/ 3737//>>demos: http://jqueryui.com/resizable/ 3738//>>css.structure: ../../themes/base/core.css 3739//>>css.structure: ../../themes/base/resizable.css 3740//>>css.theme: ../../themes/base/theme.css 3741 3742 3743 3744$.widget( "ui.resizable", $.ui.mouse, { 3745 version: "1.12.1", 3746 widgetEventPrefix: "resize", 3747 options: { 3748 alsoResize: false, 3749 animate: false, 3750 animateDuration: "slow", 3751 animateEasing: "swing", 3752 aspectRatio: false, 3753 autoHide: false, 3754 classes: { 3755 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 3756 }, 3757 containment: false, 3758 ghost: false, 3759 grid: false, 3760 handles: "e,s,se", 3761 helper: false, 3762 maxHeight: null, 3763 maxWidth: null, 3764 minHeight: 10, 3765 minWidth: 10, 3766 3767 // See #7960 3768 zIndex: 90, 3769 3770 // Callbacks 3771 resize: null, 3772 start: null, 3773 stop: null 3774 }, 3775 3776 _num: function( value ) { 3777 return parseFloat( value ) || 0; 3778 }, 3779 3780 _isNumber: function( value ) { 3781 return !isNaN( parseFloat( value ) ); 3782 }, 3783 3784 _hasScroll: function( el, a ) { 3785 3786 if ( $( el ).css( "overflow" ) === "hidden" ) { 3787 return false;
vendor: 26,006 bytes, lines 3788-4816
3788 } 3789 3790 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3791 has = false; 3792 3793 if ( el[ scroll ] > 0 ) { 3794 return true; 3795 } 3796 3797 // TODO: determine which cases actually cause this to happen 3798 // if the element doesn't have the scroll set, see if it's possible to 3799 // set the scroll 3800 el[ scroll ] = 1; 3801 has = ( el[ scroll ] > 0 ); 3802 el[ scroll ] = 0; 3803 return has; 3804 }, 3805 3806 _create: function() { 3807 3808 var margins, 3809 o = this.options, 3810 that = this; 3811 this._addClass( "ui-resizable" ); 3812 3813 $.extend( this, { 3814 _aspectRatio: !!( o.aspectRatio ), 3815 aspectRatio: o.aspectRatio, 3816 originalElement: this.element, 3817 _proportionallyResizeElements: [], 3818 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 3819 } ); 3820 3821 // Wrap the element if it cannot hold child nodes 3822 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 3823 3824 this.element.wrap( 3825 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( { 3826 position: this.element.css( "position" ), 3827 width: this.element.outerWidth(), 3828 height: this.element.outerHeight(), 3829 top: this.element.css( "top" ), 3830 left: this.element.css( "left" ) 3831 } ) 3832 ); 3833 3834 this.element = this.element.parent().data( 3835 "ui-resizable", this.element.resizable( "instance" ) 3836 ); 3837 3838 this.elementIsWrapper = true; 3839 3840 margins = { 3841 marginTop: this.originalElement.css( "marginTop" ), 3842 marginRight: this.originalElement.css( "marginRight" ), 3843 marginBottom: this.originalElement.css( "marginBottom" ), 3844 marginLeft: this.originalElement.css( "marginLeft" ) 3845 }; 3846 3847 this.element.css( margins ); 3848 this.originalElement.css( "margin", 0 ); 3849 3850 // support: Safari 3851 // Prevent Safari textarea resize 3852 this.originalResizeStyle = this.originalElement.css( "resize" ); 3853 this.originalElement.css( "resize", "none" ); 3854 3855 this._proportionallyResizeElements.push( this.originalElement.css( { 3856 position: "static", 3857 zoom: 1, 3858 display: "block" 3859 } ) ); 3860 3861 // Support: IE9 3862 // avoid IE jump (hard set the margin) 3863 this.originalElement.css( margins ); 3864 3865 this._proportionallyResize(); 3866 } 3867 3868 this._setupHandles(); 3869 3870 if ( o.autoHide ) { 3871 $( this.element ) 3872 .on( "mouseenter", function() { 3873 if ( o.disabled ) { 3874 return; 3875 } 3876 that._removeClass( "ui-resizable-autohide" ); 3877 that._handles.show(); 3878 } ) 3879 .on( "mouseleave", function() { 3880 if ( o.disabled ) { 3881 return; 3882 } 3883 if ( !that.resizing ) { 3884 that._addClass( "ui-resizable-autohide" ); 3885 that._handles.hide(); 3886 } 3887 } ); 3888 } 3889 3890 this._mouseInit(); 3891 }, 3892 3893 _destroy: function() { 3894 3895 this._mouseDestroy(); 3896 3897 var wrapper, 3898 _destroy = function( exp ) { 3899 $( exp ) 3900 .removeData( "resizable" ) 3901 .removeData( "ui-resizable" ) 3902 .off( ".resizable" ) 3903 .find( ".ui-resizable-handle" ) 3904 .remove(); 3905 }; 3906 3907 // TODO: Unwrap at same DOM position 3908 if ( this.elementIsWrapper ) { 3909 _destroy( this.element ); 3910 wrapper = this.element; 3911 this.originalElement.css( { 3912 position: wrapper.css( "position" ), 3913 width: wrapper.outerWidth(), 3914 height: wrapper.outerHeight(), 3915 top: wrapper.css( "top" ), 3916 left: wrapper.css( "left" ) 3917 } ).insertAfter( wrapper ); 3918 wrapper.remove(); 3919 } 3920 3921 this.originalElement.css( "resize", this.originalResizeStyle ); 3922 _destroy( this.originalElement ); 3923 3924 return this; 3925 }, 3926 3927 _setOption: function( key, value ) { 3928 this._super( key, value ); 3929 3930 switch ( key ) { 3931 case "handles": 3932 this._removeHandles(); 3933 this._setupHandles(); 3934 break; 3935 default: 3936 break; 3937 } 3938 }, 3939 3940 _setupHandles: function() { 3941 var o = this.options, handle, i, n, hname, axis, that = this; 3942 this.handles = o.handles || 3943 ( !$( ".ui-resizable-handle", this.element ).length ? 3944 "e,s,se" : { 3945 n: ".ui-resizable-n", 3946 e: ".ui-resizable-e", 3947 s: ".ui-resizable-s", 3948 w: ".ui-resizable-w", 3949 se: ".ui-resizable-se", 3950 sw: ".ui-resizable-sw", 3951 ne: ".ui-resizable-ne", 3952 nw: ".ui-resizable-nw" 3953 } ); 3954 3955 this._handles = $(); 3956 if ( this.handles.constructor === String ) { 3957 3958 if ( this.handles === "all" ) { 3959 this.handles = "n,e,s,w,se,sw,ne,nw"; 3960 } 3961 3962 n = this.handles.split( "," ); 3963 this.handles = {}; 3964 3965 for ( i = 0; i < n.length; i++ ) { 3966 3967 handle = $.trim( n[ i ] ); 3968 hname = "ui-resizable-" + handle; 3969 axis = $( "<div>" ); 3970 this._addClass( axis, "ui-resizable-handle " + hname ); 3971 3972 axis.css( { zIndex: o.zIndex } ); 3973 3974 this.handles[ handle ] = ".ui-resizable-" + handle; 3975 this.element.append( axis ); 3976 } 3977 3978 } 3979 3980 this._renderAxis = function( target ) { 3981 3982 var i, axis, padPos, padWrapper; 3983 3984 target = target || this.element; 3985 3986 for ( i in this.handles ) { 3987 3988 if ( this.handles[ i ].constructor === String ) { 3989 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 3990 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 3991 this.handles[ i ] = $( this.handles[ i ] ); 3992 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 3993 } 3994 3995 if ( this.elementIsWrapper && 3996 this.originalElement[ 0 ] 3997 .nodeName 3998 .match( /^(textarea|input|select|button)$/i ) ) { 3999 axis = $( this.handles[ i ], this.element ); 4000 4001 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 4002 axis.outerHeight() : 4003 axis.outerWidth(); 4004 4005 padPos = [ "padding", 4006 /ne|nw|n/.test( i ) ? "Top" : 4007 /se|sw|s/.test( i ) ? "Bottom" : 4008 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 4009 4010 target.css( padPos, padWrapper ); 4011 4012 this._proportionallyResize(); 4013 } 4014 4015 this._handles = this._handles.add( this.handles[ i ] ); 4016 } 4017 }; 4018 4019 // TODO: make renderAxis a prototype function 4020 this._renderAxis( this.element ); 4021 4022 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 4023 this._handles.disableSelection(); 4024 4025 this._handles.on( "mouseover", function() { 4026 if ( !that.resizing ) { 4027 if ( this.className ) { 4028 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 4029 } 4030 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 4031 } 4032 } ); 4033 4034 if ( o.autoHide ) { 4035 this._handles.hide(); 4036 this._addClass( "ui-resizable-autohide" ); 4037 } 4038 }, 4039 4040 _removeHandles: function() { 4041 this._handles.remove(); 4042 }, 4043 4044 _mouseCapture: function( event ) { 4045 var i, handle, 4046 capture = false; 4047 4048 for ( i in this.handles ) { 4049 handle = $( this.handles[ i ] )[ 0 ]; 4050 if ( handle === event.target || $.contains( handle, event.target ) ) { 4051 capture = true; 4052 } 4053 } 4054 4055 return !this.options.disabled && capture; 4056 }, 4057 4058 _mouseStart: function( event ) { 4059 4060 var curleft, curtop, cursor, 4061 o = this.options, 4062 el = this.element; 4063 4064 this.resizing = true; 4065 4066 this._renderProxy(); 4067 4068 curleft = this._num( this.helper.css( "left" ) ); 4069 curtop = this._num( this.helper.css( "top" ) ); 4070 4071 if ( o.containment ) { 4072 curleft += $( o.containment ).scrollLeft() || 0; 4073 curtop += $( o.containment ).scrollTop() || 0; 4074 } 4075 4076 this.offset = this.helper.offset(); 4077 this.position = { left: curleft, top: curtop }; 4078 4079 this.size = this._helper ? { 4080 width: this.helper.width(), 4081 height: this.helper.height() 4082 } : { 4083 width: el.width(), 4084 height: el.height() 4085 }; 4086 4087 this.originalSize = this._helper ? { 4088 width: el.outerWidth(), 4089 height: el.outerHeight() 4090 } : { 4091 width: el.width(), 4092 height: el.height() 4093 }; 4094 4095 this.sizeDiff = { 4096 width: el.outerWidth() - el.width(), 4097 height: el.outerHeight() - el.height() 4098 }; 4099 4100 this.originalPosition = { left: curleft, top: curtop }; 4101 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 4102 4103 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 4104 o.aspectRatio : 4105 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 4106 4107 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 4108 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 4109 4110 this._addClass( "ui-resizable-resizing" ); 4111 this._propagate( "start", event ); 4112 return true; 4113 }, 4114 4115 _mouseDrag: function( event ) { 4116 4117 var data, props, 4118 smp = this.originalMousePosition, 4119 a = this.axis, 4120 dx = ( event.pageX - smp.left ) || 0, 4121 dy = ( event.pageY - smp.top ) || 0, 4122 trigger = this._change[ a ]; 4123 4124 this._updatePrevProperties(); 4125 4126 if ( !trigger ) { 4127 return false; 4128 } 4129 4130 data = trigger.apply( this, [ event, dx, dy ] ); 4131 4132 this._updateVirtualBoundaries( event.shiftKey ); 4133 if ( this._aspectRatio || event.shiftKey ) { 4134 data = this._updateRatio( data, event ); 4135 } 4136 4137 data = this._respectSize( data, event ); 4138 4139 this._updateCache( data ); 4140 4141 this._propagate( "resize", event ); 4142 4143 props = this._applyChanges(); 4144 4145 if ( !this._helper && this._proportionallyResizeElements.length ) { 4146 this._proportionallyResize(); 4147 } 4148 4149 if ( !$.isEmptyObject( props ) ) { 4150 this._updatePrevProperties(); 4151 this._trigger( "resize", event, this.ui() ); 4152 this._applyChanges(); 4153 } 4154 4155 return false; 4156 }, 4157 4158 _mouseStop: function( event ) { 4159 4160 this.resizing = false; 4161 var pr, ista, soffseth, soffsetw, s, left, top, 4162 o = this.options, that = this; 4163 4164 if ( this._helper ) { 4165 4166 pr = this._proportionallyResizeElements; 4167 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 4168 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 4169 soffsetw = ista ? 0 : that.sizeDiff.width; 4170 4171 s = { 4172 width: ( that.helper.width() - soffsetw ), 4173 height: ( that.helper.height() - soffseth ) 4174 }; 4175 left = ( parseFloat( that.element.css( "left" ) ) + 4176 ( that.position.left - that.originalPosition.left ) ) || null; 4177 top = ( parseFloat( that.element.css( "top" ) ) + 4178 ( that.position.top - that.originalPosition.top ) ) || null; 4179 4180 if ( !o.animate ) { 4181 this.element.css( $.extend( s, { top: top, left: left } ) ); 4182 } 4183 4184 that.helper.height( that.size.height ); 4185 that.helper.width( that.size.width ); 4186 4187 if ( this._helper && !o.animate ) { 4188 this._proportionallyResize(); 4189 } 4190 } 4191 4192 $( "body" ).css( "cursor", "auto" ); 4193 4194 this._removeClass( "ui-resizable-resizing" ); 4195 4196 this._propagate( "stop", event ); 4197 4198 if ( this._helper ) { 4199 this.helper.remove(); 4200 } 4201 4202 return false; 4203 4204 }, 4205 4206 _updatePrevProperties: function() { 4207 this.prevPosition = { 4208 top: this.position.top, 4209 left: this.position.left 4210 }; 4211 this.prevSize = { 4212 width: this.size.width, 4213 height: this.size.height 4214 }; 4215 }, 4216 4217 _applyChanges: function() { 4218 var props = {}; 4219 4220 if ( this.position.top !== this.prevPosition.top ) { 4221 props.top = this.position.top + "px"; 4222 } 4223 if ( this.position.left !== this.prevPosition.left ) { 4224 props.left = this.position.left + "px"; 4225 } 4226 if ( this.size.width !== this.prevSize.width ) { 4227 props.width = this.size.width + "px"; 4228 } 4229 if ( this.size.height !== this.prevSize.height ) { 4230 props.height = this.size.height + "px"; 4231 } 4232 4233 this.helper.css( props ); 4234 4235 return props; 4236 }, 4237 4238 _updateVirtualBoundaries: function( forceAspectRatio ) { 4239 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 4240 o = this.options; 4241 4242 b = { 4243 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 4244 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 4245 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 4246 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 4247 }; 4248 4249 if ( this._aspectRatio || forceAspectRatio ) { 4250 pMinWidth = b.minHeight * this.aspectRatio; 4251 pMinHeight = b.minWidth / this.aspectRatio; 4252 pMaxWidth = b.maxHeight * this.aspectRatio; 4253 pMaxHeight = b.maxWidth / this.aspectRatio; 4254 4255 if ( pMinWidth > b.minWidth ) { 4256 b.minWidth = pMinWidth; 4257 } 4258 if ( pMinHeight > b.minHeight ) { 4259 b.minHeight = pMinHeight; 4260 } 4261 if ( pMaxWidth < b.maxWidth ) { 4262 b.maxWidth = pMaxWidth; 4263 } 4264 if ( pMaxHeight < b.maxHeight ) { 4265 b.maxHeight = pMaxHeight; 4266 } 4267 } 4268 this._vBoundaries = b; 4269 }, 4270 4271 _updateCache: function( data ) { 4272 this.offset = this.helper.offset(); 4273 if ( this._isNumber( data.left ) ) { 4274 this.position.left = data.left; 4275 } 4276 if ( this._isNumber( data.top ) ) { 4277 this.position.top = data.top; 4278 } 4279 if ( this._isNumber( data.height ) ) { 4280 this.size.height = data.height; 4281 } 4282 if ( this._isNumber( data.width ) ) { 4283 this.size.width = data.width; 4284 } 4285 }, 4286 4287 _updateRatio: function( data ) { 4288 4289 var cpos = this.position, 4290 csize = this.size, 4291 a = this.axis; 4292 4293 if ( this._isNumber( data.height ) ) { 4294 data.width = ( data.height * this.aspectRatio ); 4295 } else if ( this._isNumber( data.width ) ) { 4296 data.height = ( data.width / this.aspectRatio ); 4297 } 4298 4299 if ( a === "sw" ) { 4300 data.left = cpos.left + ( csize.width - data.width ); 4301 data.top = null; 4302 } 4303 if ( a === "nw" ) { 4304 data.top = cpos.top + ( csize.height - data.height ); 4305 data.left = cpos.left + ( csize.width - data.width ); 4306 } 4307 4308 return data; 4309 }, 4310 4311 _respectSize: function( data ) { 4312 4313 var o = this._vBoundaries, 4314 a = this.axis, 4315 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 4316 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 4317 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 4318 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 4319 dw = this.originalPosition.left + this.originalSize.width, 4320 dh = this.originalPosition.top + this.originalSize.height, 4321 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 4322 if ( isminw ) { 4323 data.width = o.minWidth; 4324 } 4325 if ( isminh ) { 4326 data.height = o.minHeight; 4327 } 4328 if ( ismaxw ) { 4329 data.width = o.maxWidth; 4330 } 4331 if ( ismaxh ) { 4332 data.height = o.maxHeight; 4333 } 4334 4335 if ( isminw && cw ) { 4336 data.left = dw - o.minWidth; 4337 } 4338 if ( ismaxw && cw ) { 4339 data.left = dw - o.maxWidth; 4340 } 4341 if ( isminh && ch ) { 4342 data.top = dh - o.minHeight; 4343 } 4344 if ( ismaxh && ch ) { 4345 data.top = dh - o.maxHeight; 4346 } 4347 4348 // Fixing jump error on top/left - bug #2330 4349 if ( !data.width && !data.height && !data.left && data.top ) { 4350 data.top = null; 4351 } else if ( !data.width && !data.height && !data.top && data.left ) { 4352 data.left = null; 4353 } 4354 4355 return data; 4356 }, 4357 4358 _getPaddingPlusBorderDimensions: function( element ) { 4359 var i = 0, 4360 widths = [], 4361 borders = [ 4362 element.css( "borderTopWidth" ), 4363 element.css( "borderRightWidth" ), 4364 element.css( "borderBottomWidth" ), 4365 element.css( "borderLeftWidth" ) 4366 ], 4367 paddings = [ 4368 element.css( "paddingTop" ), 4369 element.css( "paddingRight" ), 4370 element.css( "paddingBottom" ), 4371 element.css( "paddingLeft" ) 4372 ]; 4373 4374 for ( ; i < 4; i++ ) { 4375 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 4376 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 4377 } 4378 4379 return { 4380 height: widths[ 0 ] + widths[ 2 ], 4381 width: widths[ 1 ] + widths[ 3 ] 4382 }; 4383 }, 4384 4385 _proportionallyResize: function() { 4386 4387 if ( !this._proportionallyResizeElements.length ) { 4388 return; 4389 } 4390 4391 var prel, 4392 i = 0, 4393 element = this.helper || this.element; 4394 4395 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 4396 4397 prel = this._proportionallyResizeElements[ i ]; 4398 4399 // TODO: Seems like a bug to cache this.outerDimensions 4400 // considering that we are in a loop. 4401 if ( !this.outerDimensions ) { 4402 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 4403 } 4404 4405 prel.css( { 4406 height: ( element.height() - this.outerDimensions.height ) || 0, 4407 width: ( element.width() - this.outerDimensions.width ) || 0 4408 } ); 4409 4410 } 4411 4412 }, 4413 4414 _renderProxy: function() { 4415 4416 var el = this.element, o = this.options; 4417 this.elementOffset = el.offset(); 4418 4419 if ( this._helper ) { 4420 4421 this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" ); 4422 4423 this._addClass( this.helper, this._helper ); 4424 this.helper.css( { 4425 width: this.element.outerWidth(), 4426 height: this.element.outerHeight(), 4427 position: "absolute", 4428 left: this.elementOffset.left + "px", 4429 top: this.elementOffset.top + "px", 4430 zIndex: ++o.zIndex //TODO: Don't modify option 4431 } ); 4432 4433 this.helper 4434 .appendTo( "body" ) 4435 .disableSelection(); 4436 4437 } else { 4438 this.helper = this.element; 4439 } 4440 4441 }, 4442 4443 _change: { 4444 e: function( event, dx ) { 4445 return { width: this.originalSize.width + dx }; 4446 }, 4447 w: function( event, dx ) { 4448 var cs = this.originalSize, sp = this.originalPosition; 4449 return { left: sp.left + dx, width: cs.width - dx }; 4450 }, 4451 n: function( event, dx, dy ) { 4452 var cs = this.originalSize, sp = this.originalPosition; 4453 return { top: sp.top + dy, height: cs.height - dy }; 4454 }, 4455 s: function( event, dx, dy ) { 4456 return { height: this.originalSize.height + dy }; 4457 }, 4458 se: function( event, dx, dy ) { 4459 return $.extend( this._change.s.apply( this, arguments ), 4460 this._change.e.apply( this, [ event, dx, dy ] ) ); 4461 }, 4462 sw: function( event, dx, dy ) { 4463 return $.extend( this._change.s.apply( this, arguments ), 4464 this._change.w.apply( this, [ event, dx, dy ] ) ); 4465 }, 4466 ne: function( event, dx, dy ) { 4467 return $.extend( this._change.n.apply( this, arguments ), 4468 this._change.e.apply( this, [ event, dx, dy ] ) ); 4469 }, 4470 nw: function( event, dx, dy ) { 4471 return $.extend( this._change.n.apply( this, arguments ), 4472 this._change.w.apply( this, [ event, dx, dy ] ) ); 4473 } 4474 }, 4475 4476 _propagate: function( n, event ) { 4477 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 4478 ( n !== "resize" && this._trigger( n, event, this.ui() ) ); 4479 }, 4480 4481 plugins: {}, 4482 4483 ui: function() { 4484 return { 4485 originalElement: this.originalElement, 4486 element: this.element, 4487 helper: this.helper, 4488 position: this.position, 4489 size: this.size, 4490 originalSize: this.originalSize, 4491 originalPosition: this.originalPosition 4492 }; 4493 } 4494 4495} ); 4496 4497/* 4498 * Resizable Extensions 4499 */ 4500 4501$.ui.plugin.add( "resizable", "animate", { 4502 4503 stop: function( event ) { 4504 var that = $( this ).resizable( "instance" ), 4505 o = that.options, 4506 pr = that._proportionallyResizeElements, 4507 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 4508 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 4509 soffsetw = ista ? 0 : that.sizeDiff.width, 4510 style = { 4511 width: ( that.size.width - soffsetw ), 4512 height: ( that.size.height - soffseth ) 4513 }, 4514 left = ( parseFloat( that.element.css( "left" ) ) + 4515 ( that.position.left - that.originalPosition.left ) ) || null, 4516 top = ( parseFloat( that.element.css( "top" ) ) + 4517 ( that.position.top - that.originalPosition.top ) ) || null; 4518 4519 that.element.animate( 4520 $.extend( style, top && left ? { top: top, left: left } : {} ), { 4521 duration: o.animateDuration, 4522 easing: o.animateEasing, 4523 step: function() { 4524 4525 var data = { 4526 width: parseFloat( that.element.css( "width" ) ), 4527 height: parseFloat( that.element.css( "height" ) ), 4528 top: parseFloat( that.element.css( "top" ) ), 4529 left: parseFloat( that.element.css( "left" ) ) 4530 }; 4531 4532 if ( pr && pr.length ) { 4533 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 4534 } 4535 4536 // Propagating resize, and updating values for each animation step 4537 that._updateCache( data ); 4538 that._propagate( "resize", event ); 4539 4540 } 4541 } 4542 ); 4543 } 4544 4545} ); 4546 4547$.ui.plugin.add( "resizable", "containment", { 4548 4549 start: function() { 4550 var element, p, co, ch, cw, width, height, 4551 that = $( this ).resizable( "instance" ), 4552 o = that.options, 4553 el = that.element, 4554 oc = o.containment, 4555 ce = ( oc instanceof $ ) ? 4556 oc.get( 0 ) : 4557 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 4558 4559 if ( !ce ) { 4560 return; 4561 } 4562 4563 that.containerElement = $( ce ); 4564 4565 if ( /document/.test( oc ) || oc === document ) { 4566 that.containerOffset = { 4567 left: 0, 4568 top: 0 4569 }; 4570 that.containerPosition = { 4571 left: 0, 4572 top: 0 4573 }; 4574 4575 that.parentData = { 4576 element: $( document ), 4577 left: 0, 4578 top: 0, 4579 width: $( document ).width(), 4580 height: $( document ).height() || document.body.parentNode.scrollHeight 4581 }; 4582 } else { 4583 element = $( ce ); 4584 p = []; 4585 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 4586 p[ i ] = that._num( element.css( "padding" + name ) ); 4587 } ); 4588 4589 that.containerOffset = element.offset(); 4590 that.containerPosition = element.position(); 4591 that.containerSize = { 4592 height: ( element.innerHeight() - p[ 3 ] ), 4593 width: ( element.innerWidth() - p[ 1 ] ) 4594 }; 4595 4596 co = that.containerOffset; 4597 ch = that.containerSize.height; 4598 cw = that.containerSize.width; 4599 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 4600 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 4601 4602 that.parentData = { 4603 element: ce, 4604 left: co.left, 4605 top: co.top, 4606 width: width, 4607 height: height 4608 }; 4609 } 4610 }, 4611 4612 resize: function( event ) { 4613 var woset, hoset, isParent, isOffsetRelative, 4614 that = $( this ).resizable( "instance" ), 4615 o = that.options, 4616 co = that.containerOffset, 4617 cp = that.position, 4618 pRatio = that._aspectRatio || event.shiftKey, 4619 cop = { 4620 top: 0, 4621 left: 0 4622 }, 4623 ce = that.containerElement, 4624 continueResize = true; 4625 4626 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 4627 cop = co; 4628 } 4629 4630 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 4631 that.size.width = that.size.width + 4632 ( that._helper ? 4633 ( that.position.left - co.left ) : 4634 ( that.position.left - cop.left ) ); 4635 4636 if ( pRatio ) { 4637 that.size.height = that.size.width / that.aspectRatio; 4638 continueResize = false; 4639 } 4640 that.position.left = o.helper ? co.left : 0; 4641 } 4642 4643 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 4644 that.size.height = that.size.height + 4645 ( that._helper ? 4646 ( that.position.top - co.top ) : 4647 that.position.top ); 4648 4649 if ( pRatio ) { 4650 that.size.width = that.size.height * that.aspectRatio; 4651 continueResize = false; 4652 } 4653 that.position.top = that._helper ? co.top : 0; 4654 } 4655 4656 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 4657 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 4658 4659 if ( isParent && isOffsetRelative ) { 4660 that.offset.left = that.parentData.left + that.position.left; 4661 that.offset.top = that.parentData.top + that.position.top; 4662 } else { 4663 that.offset.left = that.element.offset().left; 4664 that.offset.top = that.element.offset().top; 4665 } 4666 4667 woset = Math.abs( that.sizeDiff.width + 4668 ( that._helper ? 4669 that.offset.left - cop.left : 4670 ( that.offset.left - co.left ) ) ); 4671 4672 hoset = Math.abs( that.sizeDiff.height + 4673 ( that._helper ? 4674 that.offset.top - cop.top : 4675 ( that.offset.top - co.top ) ) ); 4676 4677 if ( woset + that.size.width >= that.parentData.width ) { 4678 that.size.width = that.parentData.width - woset; 4679 if ( pRatio ) { 4680 that.size.height = that.size.width / that.aspectRatio; 4681 continueResize = false; 4682 } 4683 } 4684 4685 if ( hoset + that.size.height >= that.parentData.height ) { 4686 that.size.height = that.parentData.height - hoset; 4687 if ( pRatio ) { 4688 that.size.width = that.size.height * that.aspectRatio; 4689 continueResize = false; 4690 } 4691 } 4692 4693 if ( !continueResize ) { 4694 that.position.left = that.prevPosition.left; 4695 that.position.top = that.prevPosition.top; 4696 that.size.width = that.prevSize.width; 4697 that.size.height = that.prevSize.height; 4698 } 4699 }, 4700 4701 stop: function() { 4702 var that = $( this ).resizable( "instance" ), 4703 o = that.options, 4704 co = that.containerOffset, 4705 cop = that.containerPosition, 4706 ce = that.containerElement, 4707 helper = $( that.helper ), 4708 ho = helper.offset(), 4709 w = helper.outerWidth() - that.sizeDiff.width, 4710 h = helper.outerHeight() - that.sizeDiff.height; 4711 4712 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 4713 $( this ).css( { 4714 left: ho.left - cop.left - co.left, 4715 width: w, 4716 height: h 4717 } ); 4718 } 4719 4720 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 4721 $( this ).css( { 4722 left: ho.left - cop.left - co.left, 4723 width: w, 4724 height: h 4725 } ); 4726 } 4727 } 4728} ); 4729 4730$.ui.plugin.add( "resizable", "alsoResize", { 4731 4732 start: function() { 4733 var that = $( this ).resizable( "instance" ), 4734 o = that.options; 4735 4736 $( o.alsoResize ).each( function() { 4737 var el = $( this ); 4738 el.data( "ui-resizable-alsoresize", { 4739 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 4740 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 4741 } ); 4742 } ); 4743 }, 4744 4745 resize: function( event, ui ) { 4746 var that = $( this ).resizable( "instance" ), 4747 o = that.options, 4748 os = that.originalSize, 4749 op = that.originalPosition, 4750 delta = { 4751 height: ( that.size.height - os.height ) || 0, 4752 width: ( that.size.width - os.width ) || 0, 4753 top: ( that.position.top - op.top ) || 0, 4754 left: ( that.position.left - op.left ) || 0 4755 }; 4756 4757 $( o.alsoResize ).each( function() { 4758 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 4759 css = el.parents( ui.originalElement[ 0 ] ).length ? 4760 [ "width", "height" ] : 4761 [ "width", "height", "top", "left" ]; 4762 4763 $.each( css, function( i, prop ) { 4764 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 4765 if ( sum && sum >= 0 ) { 4766 style[ prop ] = sum || null; 4767 } 4768 } ); 4769 4770 el.css( style ); 4771 } ); 4772 }, 4773 4774 stop: function() { 4775 $( this ).removeData( "ui-resizable-alsoresize" ); 4776 } 4777} ); 4778 4779$.ui.plugin.add( "resizable", "ghost", { 4780 4781 start: function() { 4782 4783 var that = $( this ).resizable( "instance" ), cs = that.size; 4784 4785 that.ghost = that.originalElement.clone(); 4786 that.ghost.css( { 4787 opacity: 0.25, 4788 display: "block", 4789 position: "relative", 4790 height: cs.height, 4791 width: cs.width, 4792 margin: 0, 4793 left: 0, 4794 top: 0 4795 } ); 4796 4797 that._addClass( that.ghost, "ui-resizable-ghost" ); 4798 4799 // DEPRECATED 4800 // TODO: remove after 1.12 4801 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 4802 4803 // Ghost option 4804 that.ghost.addClass( this.options.ghost ); 4805 } 4806 4807 that.ghost.appendTo( that.helper ); 4808 4809 }, 4810 4811 resize: function() { 4812 var that = $( this ).resizable( "instance" ); 4813 if ( that.ghost ) { 4814 that.ghost.css( { 4815 position: "relative", 4816 height: that.size.height,
vendor: 13,664 bytes, lines 4817-5361
4817 width: that.size.width 4818 } ); 4819 } 4820 }, 4821 4822 stop: function() { 4823 var that = $( this ).resizable( "instance" ); 4824 if ( that.ghost && that.helper ) { 4825 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 4826 } 4827 } 4828 4829} ); 4830 4831$.ui.plugin.add( "resizable", "grid", { 4832 4833 resize: function() { 4834 var outerDimensions, 4835 that = $( this ).resizable( "instance" ), 4836 o = that.options, 4837 cs = that.size, 4838 os = that.originalSize, 4839 op = that.originalPosition, 4840 a = that.axis, 4841 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4842 gridX = ( grid[ 0 ] || 1 ), 4843 gridY = ( grid[ 1 ] || 1 ), 4844 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 4845 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 4846 newWidth = os.width + ox, 4847 newHeight = os.height + oy, 4848 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 4849 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 4850 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 4851 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 4852 4853 o.grid = grid; 4854 4855 if ( isMinWidth ) { 4856 newWidth += gridX; 4857 } 4858 if ( isMinHeight ) { 4859 newHeight += gridY; 4860 } 4861 if ( isMaxWidth ) { 4862 newWidth -= gridX; 4863 } 4864 if ( isMaxHeight ) { 4865 newHeight -= gridY; 4866 } 4867 4868 if ( /^(se|s|e)$/.test( a ) ) { 4869 that.size.width = newWidth; 4870 that.size.height = newHeight; 4871 } else if ( /^(ne)$/.test( a ) ) { 4872 that.size.width = newWidth; 4873 that.size.height = newHeight; 4874 that.position.top = op.top - oy; 4875 } else if ( /^(sw)$/.test( a ) ) { 4876 that.size.width = newWidth; 4877 that.size.height = newHeight; 4878 that.position.left = op.left - ox; 4879 } else { 4880 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 4881 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4882 } 4883 4884 if ( newHeight - gridY > 0 ) { 4885 that.size.height = newHeight; 4886 that.position.top = op.top - oy; 4887 } else { 4888 newHeight = gridY - outerDimensions.height; 4889 that.size.height = newHeight; 4890 that.position.top = op.top + os.height - newHeight; 4891 } 4892 if ( newWidth - gridX > 0 ) { 4893 that.size.width = newWidth; 4894 that.position.left = op.left - ox; 4895 } else { 4896 newWidth = gridX - outerDimensions.width; 4897 that.size.width = newWidth; 4898 that.position.left = op.left + os.width - newWidth; 4899 } 4900 } 4901 } 4902 4903} ); 4904 4905var widgetsResizable = $.ui.resizable; 4906 4907 4908/*! 4909 * jQuery UI Selectable 1.12.1 4910 * http://jqueryui.com 4911 * 4912 * Copyright jQuery Foundation and other contributors 4913 * Released under the MIT license. 4914 * http://jquery.org/license 4915 */ 4916 4917//>>label: Selectable 4918//>>group: Interactions 4919//>>description: Allows groups of elements to be selected with the mouse. 4920//>>docs: http://api.jqueryui.com/selectable/ 4921//>>demos: http://jqueryui.com/selectable/ 4922//>>css.structure: ../../themes/base/selectable.css 4923 4924 4925 4926var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 4927 version: "1.12.1", 4928 options: { 4929 appendTo: "body", 4930 autoRefresh: true, 4931 distance: 0, 4932 filter: "*", 4933 tolerance: "touch", 4934 4935 // Callbacks 4936 selected: null, 4937 selecting: null, 4938 start: null, 4939 stop: null, 4940 unselected: null, 4941 unselecting: null 4942 }, 4943 _create: function() { 4944 var that = this; 4945 4946 this._addClass( "ui-selectable" ); 4947 4948 this.dragged = false; 4949 4950 // Cache selectee children based on filter 4951 this.refresh = function() { 4952 that.elementPos = $( that.element[ 0 ] ).offset(); 4953 that.selectees = $( that.options.filter, that.element[ 0 ] ); 4954 that._addClass( that.selectees, "ui-selectee" ); 4955 that.selectees.each( function() { 4956 var $this = $( this ), 4957 selecteeOffset = $this.offset(), 4958 pos = { 4959 left: selecteeOffset.left - that.elementPos.left, 4960 top: selecteeOffset.top - that.elementPos.top 4961 }; 4962 $.data( this, "selectable-item", { 4963 element: this, 4964 $element: $this, 4965 left: pos.left, 4966 top: pos.top, 4967 right: pos.left + $this.outerWidth(), 4968 bottom: pos.top + $this.outerHeight(), 4969 startselected: false, 4970 selected: $this.hasClass( "ui-selected" ), 4971 selecting: $this.hasClass( "ui-selecting" ), 4972 unselecting: $this.hasClass( "ui-unselecting" ) 4973 } ); 4974 } ); 4975 }; 4976 this.refresh(); 4977 4978 this._mouseInit(); 4979 4980 this.helper = $( "<div>" ); 4981 this._addClass( this.helper, "ui-selectable-helper" ); 4982 }, 4983 4984 _destroy: function() { 4985 this.selectees.removeData( "selectable-item" ); 4986 this._mouseDestroy(); 4987 }, 4988 4989 _mouseStart: function( event ) { 4990 var that = this, 4991 options = this.options; 4992 4993 this.opos = [ event.pageX, event.pageY ]; 4994 this.elementPos = $( this.element[ 0 ] ).offset(); 4995 4996 if ( this.options.disabled ) { 4997 return; 4998 } 4999 5000 this.selectees = $( options.filter, this.element[ 0 ] ); 5001 5002 this._trigger( "start", event ); 5003 5004 $( options.appendTo ).append( this.helper ); 5005 5006 // position helper (lasso) 5007 this.helper.css( { 5008 "left": event.pageX, 5009 "top": event.pageY, 5010 "width": 0, 5011 "height": 0 5012 } ); 5013 5014 if ( options.autoRefresh ) { 5015 this.refresh(); 5016 } 5017 5018 this.selectees.filter( ".ui-selected" ).each( function() { 5019 var selectee = $.data( this, "selectable-item" ); 5020 selectee.startselected = true; 5021 if ( !event.metaKey && !event.ctrlKey ) { 5022 that._removeClass( selectee.$element, "ui-selected" ); 5023 selectee.selected = false; 5024 that._addClass( selectee.$element, "ui-unselecting" ); 5025 selectee.unselecting = true; 5026 5027 // selectable UNSELECTING callback 5028 that._trigger( "unselecting", event, { 5029 unselecting: selectee.element 5030 } ); 5031 } 5032 } ); 5033 5034 $( event.target ).parents().addBack().each( function() { 5035 var doSelect, 5036 selectee = $.data( this, "selectable-item" ); 5037 if ( selectee ) { 5038 doSelect = ( !event.metaKey && !event.ctrlKey ) || 5039 !selectee.$element.hasClass( "ui-selected" ); 5040 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 5041 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 5042 selectee.unselecting = !doSelect; 5043 selectee.selecting = doSelect; 5044 selectee.selected = doSelect; 5045 5046 // selectable (UN)SELECTING callback 5047 if ( doSelect ) { 5048 that._trigger( "selecting", event, { 5049 selecting: selectee.element 5050 } ); 5051 } else { 5052 that._trigger( "unselecting", event, { 5053 unselecting: selectee.element 5054 } ); 5055 } 5056 return false; 5057 } 5058 } ); 5059 5060 }, 5061 5062 _mouseDrag: function( event ) { 5063 5064 this.dragged = true; 5065 5066 if ( this.options.disabled ) { 5067 return; 5068 } 5069 5070 var tmp, 5071 that = this, 5072 options = this.options, 5073 x1 = this.opos[ 0 ], 5074 y1 = this.opos[ 1 ], 5075 x2 = event.pageX, 5076 y2 = event.pageY; 5077 5078 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; } 5079 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; } 5080 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 5081 5082 this.selectees.each( function() { 5083 var selectee = $.data( this, "selectable-item" ), 5084 hit = false, 5085 offset = {}; 5086 5087 //prevent helper from being selected if appendTo: selectable 5088 if ( !selectee || selectee.element === that.element[ 0 ] ) { 5089 return; 5090 } 5091 5092 offset.left = selectee.left + that.elementPos.left; 5093 offset.right = selectee.right + that.elementPos.left; 5094 offset.top = selectee.top + that.elementPos.top; 5095 offset.bottom = selectee.bottom + that.elementPos.top; 5096 5097 if ( options.tolerance === "touch" ) { 5098 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 5099 offset.bottom < y1 ) ); 5100 } else if ( options.tolerance === "fit" ) { 5101 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 5102 offset.bottom < y2 ); 5103 } 5104 5105 if ( hit ) { 5106 5107 // SELECT 5108 if ( selectee.selected ) { 5109 that._removeClass( selectee.$element, "ui-selected" ); 5110 selectee.selected = false; 5111 } 5112 if ( selectee.unselecting ) { 5113 that._removeClass( selectee.$element, "ui-unselecting" ); 5114 selectee.unselecting = false; 5115 } 5116 if ( !selectee.selecting ) { 5117 that._addClass( selectee.$element, "ui-selecting" ); 5118 selectee.selecting = true; 5119 5120 // selectable SELECTING callback 5121 that._trigger( "selecting", event, { 5122 selecting: selectee.element 5123 } ); 5124 } 5125 } else { 5126 5127 // UNSELECT 5128 if ( selectee.selecting ) { 5129 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 5130 that._removeClass( selectee.$element, "ui-selecting" ); 5131 selectee.selecting = false; 5132 that._addClass( selectee.$element, "ui-selected" ); 5133 selectee.selected = true; 5134 } else { 5135 that._removeClass( selectee.$element, "ui-selecting" ); 5136 selectee.selecting = false; 5137 if ( selectee.startselected ) { 5138 that._addClass( selectee.$element, "ui-unselecting" ); 5139 selectee.unselecting = true; 5140 } 5141 5142 // selectable UNSELECTING callback 5143 that._trigger( "unselecting", event, { 5144 unselecting: selectee.element 5145 } ); 5146 } 5147 } 5148 if ( selectee.selected ) { 5149 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 5150 that._removeClass( selectee.$element, "ui-selected" ); 5151 selectee.selected = false; 5152 5153 that._addClass( selectee.$element, "ui-unselecting" ); 5154 selectee.unselecting = true; 5155 5156 // selectable UNSELECTING callback 5157 that._trigger( "unselecting", event, { 5158 unselecting: selectee.element 5159 } ); 5160 } 5161 } 5162 } 5163 } ); 5164 5165 return false; 5166 }, 5167 5168 _mouseStop: function( event ) { 5169 var that = this; 5170 5171 this.dragged = false; 5172 5173 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 5174 var selectee = $.data( this, "selectable-item" ); 5175 that._removeClass( selectee.$element, "ui-unselecting" ); 5176 selectee.unselecting = false; 5177 selectee.startselected = false; 5178 that._trigger( "unselected", event, { 5179 unselected: selectee.element 5180 } ); 5181 } ); 5182 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 5183 var selectee = $.data( this, "selectable-item" ); 5184 that._removeClass( selectee.$element, "ui-selecting" ) 5185 ._addClass( selectee.$element, "ui-selected" ); 5186 selectee.selecting = false; 5187 selectee.selected = true; 5188 selectee.startselected = true; 5189 that._trigger( "selected", event, { 5190 selected: selectee.element 5191 } ); 5192 } ); 5193 this._trigger( "stop", event ); 5194 5195 this.helper.remove(); 5196 5197 return false; 5198 } 5199 5200} ); 5201 5202 5203/*! 5204 * jQuery UI Sortable 1.12.1 5205 * http://jqueryui.com 5206 * 5207 * Copyright jQuery Foundation and other contributors 5208 * Released under the MIT license. 5209 * http://jquery.org/license 5210 */ 5211 5212//>>label: Sortable 5213//>>group: Interactions 5214//>>description: Enables items in a list to be sorted using the mouse. 5215//>>docs: http://api.jqueryui.com/sortable/ 5216//>>demos: http://jqueryui.com/sortable/ 5217//>>css.structure: ../../themes/base/sortable.css 5218 5219 5220 5221var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { 5222 version: "1.12.1", 5223 widgetEventPrefix: "sort", 5224 ready: false, 5225 options: { 5226 appendTo: "parent", 5227 axis: false, 5228 connectWith: false, 5229 containment: false, 5230 cursor: "auto", 5231 cursorAt: false, 5232 dropOnEmpty: true, 5233 forcePlaceholderSize: false, 5234 forceHelperSize: false, 5235 grid: false, 5236 handle: false, 5237 helper: "original", 5238 items: "> *", 5239 opacity: false, 5240 placeholder: false, 5241 revert: false, 5242 scroll: true, 5243 scrollSensitivity: 20, 5244 scrollSpeed: 20, 5245 scope: "default", 5246 tolerance: "intersect", 5247 zIndex: 1000, 5248 5249 // Callbacks 5250 activate: null, 5251 beforeStop: null, 5252 change: null, 5253 deactivate: null, 5254 out: null, 5255 over: null, 5256 receive: null, 5257 remove: null, 5258 sort: null, 5259 start: null, 5260 stop: null, 5261 update: null 5262 }, 5263 5264 _isOverAxis: function( x, reference, size ) { 5265 return ( x >= reference ) && ( x < ( reference + size ) ); 5266 }, 5267 5268 _isFloating: function( item ) { 5269 return ( /left|right/ ).test( item.css( "float" ) ) || 5270 ( /inline|table-cell/ ).test( item.css( "display" ) ); 5271 }, 5272 5273 _create: function() { 5274 this.containerCache = {}; 5275 this._addClass( "ui-sortable" ); 5276 5277 //Get the items 5278 this.refresh(); 5279 5280 //Let's determine the parent's offset 5281 this.offset = this.element.offset(); 5282 5283 //Initialize mouse events for interaction 5284 this._mouseInit(); 5285 5286 this._setHandleClassName(); 5287 5288 //We're ready to go 5289 this.ready = true; 5290 5291 }, 5292 5293 _setOption: function( key, value ) { 5294 this._super( key, value ); 5295 5296 if ( key === "handle" ) { 5297 this._setHandleClassName(); 5298 } 5299 }, 5300 5301 _setHandleClassName: function() { 5302 var that = this; 5303 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 5304 $.each( this.items, function() { 5305 that._addClass( 5306 this.instance.options.handle ? 5307 this.item.find( this.instance.options.handle ) : 5308 this.item, 5309 "ui-sortable-handle" 5310 ); 5311 } ); 5312 }, 5313 5314 _destroy: function() { 5315 this._mouseDestroy(); 5316 5317 for ( var i = this.items.length - 1; i >= 0; i-- ) { 5318 this.items[ i ].item.removeData( this.widgetName + "-item" ); 5319 } 5320 5321 return this; 5322 }, 5323 5324 _mouseCapture: function( event, overrideHandle ) { 5325 var currentItem = null, 5326 validHandle = false, 5327 that = this; 5328 5329 if ( this.reverting ) { 5330 return false; 5331 } 5332 5333 if ( this.options.disabled || this.options.type === "static" ) { 5334 return false; 5335 } 5336 5337 //We have to refresh the items data once first 5338 this._refreshItems( event ); 5339 5340 //Find out if the clicked node (or one of its parents) is a actual item in this.items 5341 $( event.target ).parents().each( function() { 5342 if ( $.data( this, that.widgetName + "-item" ) === that ) { 5343 currentItem = $( this ); 5344 return false; 5345 } 5346 } ); 5347 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 5348 currentItem = $( event.target ); 5349 } 5350 5351 if ( !currentItem ) { 5352 return false; 5353 } 5354 if ( this.options.handle && !overrideHandle ) { 5355 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 5356 if ( this === event.target ) { 5357 validHandle = true; 5358 } 5359 } ); 5360 if ( !validHandle ) { 5361 return false;
vendor: 42,276 bytes, lines 5362-6740
5362 } 5363 } 5364 5365 this.currentItem = currentItem; 5366 this._removeCurrentsFromItems(); 5367 return true; 5368 5369 }, 5370 5371 _mouseStart: function( event, overrideHandle, noActivation ) { 5372 5373 var i, body, 5374 o = this.options; 5375 5376 this.currentContainer = this; 5377 5378 //We only need to call refreshPositions, because the refreshItems call has been moved to 5379 // mouseCapture 5380 this.refreshPositions(); 5381 5382 //Create and append the visible helper 5383 this.helper = this._createHelper( event ); 5384 5385 //Cache the helper size 5386 this._cacheHelperProportions(); 5387 5388 /* 5389 * - Position generation - 5390 * This block generates everything position related - it's the core of draggables. 5391 */ 5392 5393 //Cache the margins of the original element 5394 this._cacheMargins(); 5395 5396 //Get the next scrolling parent 5397 this.scrollParent = this.helper.scrollParent(); 5398 5399 //The element's absolute position on the page minus margins 5400 this.offset = this.currentItem.offset(); 5401 this.offset = { 5402 top: this.offset.top - this.margins.top, 5403 left: this.offset.left - this.margins.left 5404 }; 5405 5406 $.extend( this.offset, { 5407 click: { //Where the click happened, relative to the element 5408 left: event.pageX - this.offset.left, 5409 top: event.pageY - this.offset.top 5410 }, 5411 parent: this._getParentOffset(), 5412 5413 // This is a relative to absolute position minus the actual position calculation - 5414 // only used for relative positioned helper 5415 relative: this._getRelativeOffset() 5416 } ); 5417 5418 // Only after we got the offset, we can change the helper's position to absolute 5419 // TODO: Still need to figure out a way to make relative sorting possible 5420 this.helper.css( "position", "absolute" ); 5421 this.cssPosition = this.helper.css( "position" ); 5422 5423 //Generate the original position 5424 this.originalPosition = this._generatePosition( event ); 5425 this.originalPageX = event.pageX; 5426 this.originalPageY = event.pageY; 5427 5428 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 5429 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); 5430 5431 //Cache the former DOM position 5432 this.domPosition = { 5433 prev: this.currentItem.prev()[ 0 ], 5434 parent: this.currentItem.parent()[ 0 ] 5435 }; 5436 5437 // If the helper is not the original, hide the original so it's not playing any role during 5438 // the drag, won't cause anything bad this way 5439 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 5440 this.currentItem.hide(); 5441 } 5442 5443 //Create the placeholder 5444 this._createPlaceholder(); 5445 5446 //Set a containment if given in the options 5447 if ( o.containment ) { 5448 this._setContainment(); 5449 } 5450 5451 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 5452 body = this.document.find( "body" ); 5453 5454 // Support: IE 5455 this.storedCursor = body.css( "cursor" ); 5456 body.css( "cursor", o.cursor ); 5457 5458 this.storedStylesheet = 5459 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 5460 } 5461 5462 if ( o.opacity ) { // opacity option 5463 if ( this.helper.css( "opacity" ) ) { 5464 this._storedOpacity = this.helper.css( "opacity" ); 5465 } 5466 this.helper.css( "opacity", o.opacity ); 5467 } 5468 5469 if ( o.zIndex ) { // zIndex option 5470 if ( this.helper.css( "zIndex" ) ) { 5471 this._storedZIndex = this.helper.css( "zIndex" ); 5472 } 5473 this.helper.css( "zIndex", o.zIndex ); 5474 } 5475 5476 //Prepare scrolling 5477 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5478 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5479 this.overflowOffset = this.scrollParent.offset(); 5480 } 5481 5482 //Call callbacks 5483 this._trigger( "start", event, this._uiHash() ); 5484 5485 //Recache the helper size 5486 if ( !this._preserveHelperProportions ) { 5487 this._cacheHelperProportions(); 5488 } 5489 5490 //Post "activate" events to possible containers 5491 if ( !noActivation ) { 5492 for ( i = this.containers.length - 1; i >= 0; i-- ) { 5493 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 5494 } 5495 } 5496 5497 //Prepare possible droppables 5498 if ( $.ui.ddmanager ) { 5499 $.ui.ddmanager.current = this; 5500 } 5501 5502 if ( $.ui.ddmanager && !o.dropBehaviour ) { 5503 $.ui.ddmanager.prepareOffsets( this, event ); 5504 } 5505 5506 this.dragging = true; 5507 5508 this._addClass( this.helper, "ui-sortable-helper" ); 5509 5510 // Execute the drag once - this causes the helper not to be visiblebefore getting its 5511 // correct position 5512 this._mouseDrag( event ); 5513 return true; 5514 5515 }, 5516 5517 _mouseDrag: function( event ) { 5518 var i, item, itemElement, intersection, 5519 o = this.options, 5520 scrolled = false; 5521 5522 //Compute the helpers position 5523 this.position = this._generatePosition( event ); 5524 this.positionAbs = this._convertPositionTo( "absolute" ); 5525 5526 if ( !this.lastPositionAbs ) { 5527 this.lastPositionAbs = this.positionAbs; 5528 } 5529 5530 //Do scrolling 5531 if ( this.options.scroll ) { 5532 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 5533 this.scrollParent[ 0 ].tagName !== "HTML" ) { 5534 5535 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 5536 event.pageY < o.scrollSensitivity ) { 5537 this.scrollParent[ 0 ].scrollTop = 5538 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 5539 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 5540 this.scrollParent[ 0 ].scrollTop = 5541 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 5542 } 5543 5544 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 5545 event.pageX < o.scrollSensitivity ) { 5546 this.scrollParent[ 0 ].scrollLeft = scrolled = 5547 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 5548 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 5549 this.scrollParent[ 0 ].scrollLeft = scrolled = 5550 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 5551 } 5552 5553 } else { 5554 5555 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 5556 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 5557 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 5558 o.scrollSensitivity ) { 5559 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 5560 } 5561 5562 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 5563 scrolled = this.document.scrollLeft( 5564 this.document.scrollLeft() - o.scrollSpeed 5565 ); 5566 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 5567 o.scrollSensitivity ) { 5568 scrolled = this.document.scrollLeft( 5569 this.document.scrollLeft() + o.scrollSpeed 5570 ); 5571 } 5572 5573 } 5574 5575 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 5576 $.ui.ddmanager.prepareOffsets( this, event ); 5577 } 5578 } 5579 5580 //Regenerate the absolute position used for position checks 5581 this.positionAbs = this._convertPositionTo( "absolute" ); 5582 5583 //Set the helper position 5584 if ( !this.options.axis || this.options.axis !== "y" ) { 5585 this.helper[ 0 ].style.left = this.position.left + "px"; 5586 } 5587 if ( !this.options.axis || this.options.axis !== "x" ) { 5588 this.helper[ 0 ].style.top = this.position.top + "px"; 5589 } 5590 5591 //Rearrange 5592 for ( i = this.items.length - 1; i >= 0; i-- ) { 5593 5594 //Cache variables and intersection, continue if no intersection 5595 item = this.items[ i ]; 5596 itemElement = item.item[ 0 ]; 5597 intersection = this._intersectsWithPointer( item ); 5598 if ( !intersection ) { 5599 continue; 5600 } 5601 5602 // Only put the placeholder inside the current Container, skip all 5603 // items from other containers. This works because when moving 5604 // an item from one container to another the 5605 // currentContainer is switched before the placeholder is moved. 5606 // 5607 // Without this, moving items in "sub-sortables" can cause 5608 // the placeholder to jitter between the outer and inner container. 5609 if ( item.instance !== this.currentContainer ) { 5610 continue; 5611 } 5612 5613 // Cannot intersect with itself 5614 // no useless actions that have been done before 5615 // no action if the item moved is the parent of the item checked 5616 if ( itemElement !== this.currentItem[ 0 ] && 5617 this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement && 5618 !$.contains( this.placeholder[ 0 ], itemElement ) && 5619 ( this.options.type === "semi-dynamic" ? 5620 !$.contains( this.element[ 0 ], itemElement ) : 5621 true 5622 ) 5623 ) { 5624 5625 this.direction = intersection === 1 ? "down" : "up"; 5626 5627 if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) { 5628 this._rearrange( event, item ); 5629 } else { 5630 break; 5631 } 5632 5633 this._trigger( "change", event, this._uiHash() ); 5634 break; 5635 } 5636 } 5637 5638 //Post events to containers 5639 this._contactContainers( event ); 5640 5641 //Interconnect with droppables 5642 if ( $.ui.ddmanager ) { 5643 $.ui.ddmanager.drag( this, event ); 5644 } 5645 5646 //Call callbacks 5647 this._trigger( "sort", event, this._uiHash() ); 5648 5649 this.lastPositionAbs = this.positionAbs; 5650 return false; 5651 5652 }, 5653 5654 _mouseStop: function( event, noPropagation ) { 5655 5656 if ( !event ) { 5657 return; 5658 } 5659 5660 //If we are using droppables, inform the manager about the drop 5661 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 5662 $.ui.ddmanager.drop( this, event ); 5663 } 5664 5665 if ( this.options.revert ) { 5666 var that = this, 5667 cur = this.placeholder.offset(), 5668 axis = this.options.axis, 5669 animation = {}; 5670 5671 if ( !axis || axis === "x" ) { 5672 animation.left = cur.left - this.offset.parent.left - this.margins.left + 5673 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5674 0 : 5675 this.offsetParent[ 0 ].scrollLeft 5676 ); 5677 } 5678 if ( !axis || axis === "y" ) { 5679 animation.top = cur.top - this.offset.parent.top - this.margins.top + 5680 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 5681 0 : 5682 this.offsetParent[ 0 ].scrollTop 5683 ); 5684 } 5685 this.reverting = true; 5686 $( this.helper ).animate( 5687 animation, 5688 parseInt( this.options.revert, 10 ) || 500, 5689 function() { 5690 that._clear( event ); 5691 } 5692 ); 5693 } else { 5694 this._clear( event, noPropagation ); 5695 } 5696 5697 return false; 5698 5699 }, 5700 5701 cancel: function() { 5702 5703 if ( this.dragging ) { 5704 5705 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 5706 5707 if ( this.options.helper === "original" ) { 5708 this.currentItem.css( this._storedCSS ); 5709 this._removeClass( this.currentItem, "ui-sortable-helper" ); 5710 } else { 5711 this.currentItem.show(); 5712 } 5713 5714 //Post deactivating events to containers 5715 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 5716 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 5717 if ( this.containers[ i ].containerCache.over ) { 5718 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 5719 this.containers[ i ].containerCache.over = 0; 5720 } 5721 } 5722 5723 } 5724 5725 if ( this.placeholder ) { 5726 5727 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 5728 // it unbinds ALL events from the original node! 5729 if ( this.placeholder[ 0 ].parentNode ) { 5730 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 5731 } 5732 if ( this.options.helper !== "original" && this.helper && 5733 this.helper[ 0 ].parentNode ) { 5734 this.helper.remove(); 5735 } 5736 5737 $.extend( this, { 5738 helper: null, 5739 dragging: false, 5740 reverting: false, 5741 _noFinalSort: null 5742 } ); 5743 5744 if ( this.domPosition.prev ) { 5745 $( this.domPosition.prev ).after( this.currentItem ); 5746 } else { 5747 $( this.domPosition.parent ).prepend( this.currentItem ); 5748 } 5749 } 5750 5751 return this; 5752 5753 }, 5754 5755 serialize: function( o ) { 5756 5757 var items = this._getItemsAsjQuery( o && o.connected ), 5758 str = []; 5759 o = o || {}; 5760 5761 $( items ).each( function() { 5762 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 5763 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 5764 if ( res ) { 5765 str.push( 5766 ( o.key || res[ 1 ] + "[]" ) + 5767 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 5768 } 5769 } ); 5770 5771 if ( !str.length && o.key ) { 5772 str.push( o.key + "=" ); 5773 } 5774 5775 return str.join( "&" ); 5776 5777 }, 5778 5779 toArray: function( o ) { 5780 5781 var items = this._getItemsAsjQuery( o && o.connected ), 5782 ret = []; 5783 5784 o = o || {}; 5785 5786 items.each( function() { 5787 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 5788 } ); 5789 return ret; 5790 5791 }, 5792 5793 /* Be careful with the following core functions */ 5794 _intersectsWith: function( item ) { 5795 5796 var x1 = this.positionAbs.left, 5797 x2 = x1 + this.helperProportions.width, 5798 y1 = this.positionAbs.top, 5799 y2 = y1 + this.helperProportions.height, 5800 l = item.left, 5801 r = l + item.width, 5802 t = item.top, 5803 b = t + item.height, 5804 dyClick = this.offset.click.top, 5805 dxClick = this.offset.click.left, 5806 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 5807 ( y1 + dyClick ) < b ), 5808 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 5809 ( x1 + dxClick ) < r ), 5810 isOverElement = isOverElementHeight && isOverElementWidth; 5811 5812 if ( this.options.tolerance === "pointer" || 5813 this.options.forcePointerForContainers || 5814 ( this.options.tolerance !== "pointer" && 5815 this.helperProportions[ this.floating ? "width" : "height" ] > 5816 item[ this.floating ? "width" : "height" ] ) 5817 ) { 5818 return isOverElement; 5819 } else { 5820 5821 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 5822 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 5823 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 5824 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 5825 5826 } 5827 }, 5828 5829 _intersectsWithPointer: function( item ) { 5830 var verticalDirection, horizontalDirection, 5831 isOverElementHeight = ( this.options.axis === "x" ) || 5832 this._isOverAxis( 5833 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 5834 isOverElementWidth = ( this.options.axis === "y" ) || 5835 this._isOverAxis( 5836 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 5837 isOverElement = isOverElementHeight && isOverElementWidth; 5838 5839 if ( !isOverElement ) { 5840 return false; 5841 } 5842 5843 verticalDirection = this._getDragVerticalDirection(); 5844 horizontalDirection = this._getDragHorizontalDirection(); 5845 5846 return this.floating ? 5847 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) 5848 : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 5849 5850 }, 5851 5852 _intersectsWithSides: function( item ) { 5853 5854 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 5855 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 5856 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 5857 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 5858 verticalDirection = this._getDragVerticalDirection(), 5859 horizontalDirection = this._getDragHorizontalDirection(); 5860 5861 if ( this.floating && horizontalDirection ) { 5862 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 5863 ( horizontalDirection === "left" && !isOverRightHalf ) ); 5864 } else { 5865 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 5866 ( verticalDirection === "up" && !isOverBottomHalf ) ); 5867 } 5868 5869 }, 5870 5871 _getDragVerticalDirection: function() { 5872 var delta = this.positionAbs.top - this.lastPositionAbs.top; 5873 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 5874 }, 5875 5876 _getDragHorizontalDirection: function() { 5877 var delta = this.positionAbs.left - this.lastPositionAbs.left; 5878 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 5879 }, 5880 5881 refresh: function( event ) { 5882 this._refreshItems( event ); 5883 this._setHandleClassName(); 5884 this.refreshPositions(); 5885 return this; 5886 }, 5887 5888 _connectWith: function() { 5889 var options = this.options; 5890 return options.connectWith.constructor === String ? 5891 [ options.connectWith ] : 5892 options.connectWith; 5893 }, 5894 5895 _getItemsAsjQuery: function( connected ) { 5896 5897 var i, j, cur, inst, 5898 items = [], 5899 queries = [], 5900 connectWith = this._connectWith(); 5901 5902 if ( connectWith && connected ) { 5903 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5904 cur = $( connectWith[ i ], this.document[ 0 ] ); 5905 for ( j = cur.length - 1; j >= 0; j-- ) { 5906 inst = $.data( cur[ j ], this.widgetFullName ); 5907 if ( inst && inst !== this && !inst.options.disabled ) { 5908 queries.push( [ $.isFunction( inst.options.items ) ? 5909 inst.options.items.call( inst.element ) : 5910 $( inst.options.items, inst.element ) 5911 .not( ".ui-sortable-helper" ) 5912 .not( ".ui-sortable-placeholder" ), inst ] ); 5913 } 5914 } 5915 } 5916 } 5917 5918 queries.push( [ $.isFunction( this.options.items ) ? 5919 this.options.items 5920 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 5921 $( this.options.items, this.element ) 5922 .not( ".ui-sortable-helper" ) 5923 .not( ".ui-sortable-placeholder" ), this ] ); 5924 5925 function addItems() { 5926 items.push( this ); 5927 } 5928 for ( i = queries.length - 1; i >= 0; i-- ) { 5929 queries[ i ][ 0 ].each( addItems ); 5930 } 5931 5932 return $( items ); 5933 5934 }, 5935 5936 _removeCurrentsFromItems: function() { 5937 5938 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 5939 5940 this.items = $.grep( this.items, function( item ) { 5941 for ( var j = 0; j < list.length; j++ ) { 5942 if ( list[ j ] === item.item[ 0 ] ) { 5943 return false; 5944 } 5945 } 5946 return true; 5947 } ); 5948 5949 }, 5950 5951 _refreshItems: function( event ) { 5952 5953 this.items = []; 5954 this.containers = [ this ]; 5955 5956 var i, j, cur, inst, targetData, _queries, item, queriesLength, 5957 items = this.items, 5958 queries = [ [ $.isFunction( this.options.items ) ? 5959 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 5960 $( this.options.items, this.element ), this ] ], 5961 connectWith = this._connectWith(); 5962 5963 //Shouldn't be run the first time through due to massive slow-down 5964 if ( connectWith && this.ready ) { 5965 for ( i = connectWith.length - 1; i >= 0; i-- ) { 5966 cur = $( connectWith[ i ], this.document[ 0 ] ); 5967 for ( j = cur.length - 1; j >= 0; j-- ) { 5968 inst = $.data( cur[ j ], this.widgetFullName ); 5969 if ( inst && inst !== this && !inst.options.disabled ) { 5970 queries.push( [ $.isFunction( inst.options.items ) ? 5971 inst.options.items 5972 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 5973 $( inst.options.items, inst.element ), inst ] ); 5974 this.containers.push( inst ); 5975 } 5976 } 5977 } 5978 } 5979 5980 for ( i = queries.length - 1; i >= 0; i-- ) { 5981 targetData = queries[ i ][ 1 ]; 5982 _queries = queries[ i ][ 0 ]; 5983 5984 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 5985 item = $( _queries[ j ] ); 5986 5987 // Data for target checking (mouse manager) 5988 item.data( this.widgetName + "-item", targetData ); 5989 5990 items.push( { 5991 item: item, 5992 instance: targetData, 5993 width: 0, height: 0, 5994 left: 0, top: 0 5995 } ); 5996 } 5997 } 5998 5999 }, 6000 6001 refreshPositions: function( fast ) { 6002 6003 // Determine whether items are being displayed horizontally 6004 this.floating = this.items.length ? 6005 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 6006 false; 6007 6008 //This has to be redone because due to the item being moved out/into the offsetParent, 6009 // the offsetParent's position will change 6010 if ( this.offsetParent && this.helper ) { 6011 this.offset.parent = this._getParentOffset(); 6012 } 6013 6014 var i, item, t, p; 6015 6016 for ( i = this.items.length - 1; i >= 0; i-- ) { 6017 item = this.items[ i ]; 6018 6019 //We ignore calculating positions of all connected containers when we're not over them 6020 if ( item.instance !== this.currentContainer && this.currentContainer && 6021 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 6022 continue; 6023 } 6024 6025 t = this.options.toleranceElement ? 6026 $( this.options.toleranceElement, item.item ) : 6027 item.item; 6028 6029 if ( !fast ) { 6030 item.width = t.outerWidth(); 6031 item.height = t.outerHeight(); 6032 } 6033 6034 p = t.offset(); 6035 item.left = p.left; 6036 item.top = p.top; 6037 } 6038 6039 if ( this.options.custom && this.options.custom.refreshContainers ) { 6040 this.options.custom.refreshContainers.call( this ); 6041 } else { 6042 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6043 p = this.containers[ i ].element.offset(); 6044 this.containers[ i ].containerCache.left = p.left; 6045 this.containers[ i ].containerCache.top = p.top; 6046 this.containers[ i ].containerCache.width = 6047 this.containers[ i ].element.outerWidth(); 6048 this.containers[ i ].containerCache.height = 6049 this.containers[ i ].element.outerHeight(); 6050 } 6051 } 6052 6053 return this; 6054 }, 6055 6056 _createPlaceholder: function( that ) { 6057 that = that || this; 6058 var className, 6059 o = that.options; 6060 6061 if ( !o.placeholder || o.placeholder.constructor === String ) { 6062 className = o.placeholder; 6063 o.placeholder = { 6064 element: function() { 6065 6066 var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(), 6067 element = $( "<" + nodeName + ">", that.document[ 0 ] ); 6068 6069 that._addClass( element, "ui-sortable-placeholder", 6070 className || that.currentItem[ 0 ].className ) 6071 ._removeClass( element, "ui-sortable-helper" ); 6072 6073 if ( nodeName === "tbody" ) { 6074 that._createTrPlaceholder( 6075 that.currentItem.find( "tr" ).eq( 0 ), 6076 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 6077 ); 6078 } else if ( nodeName === "tr" ) { 6079 that._createTrPlaceholder( that.currentItem, element ); 6080 } else if ( nodeName === "img" ) { 6081 element.attr( "src", that.currentItem.attr( "src" ) ); 6082 } 6083 6084 if ( !className ) { 6085 element.css( "visibility", "hidden" ); 6086 } 6087 6088 return element; 6089 }, 6090 update: function( container, p ) { 6091 6092 // 1. If a className is set as 'placeholder option, we don't force sizes - 6093 // the class is responsible for that 6094 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 6095 // class name is specified 6096 if ( className && !o.forcePlaceholderSize ) { 6097 return; 6098 } 6099 6100 //If the element doesn't have a actual height by itself (without styles coming 6101 // from a stylesheet), it receives the inline height from the dragged item 6102 if ( !p.height() ) { 6103 p.height( 6104 that.currentItem.innerHeight() - 6105 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 6106 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 6107 } 6108 if ( !p.width() ) { 6109 p.width( 6110 that.currentItem.innerWidth() - 6111 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 6112 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 6113 } 6114 } 6115 }; 6116 } 6117 6118 //Create the placeholder 6119 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 6120 6121 //Append it after the actual current item 6122 that.currentItem.after( that.placeholder ); 6123 6124 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 6125 o.placeholder.update( that, that.placeholder ); 6126 6127 }, 6128 6129 _createTrPlaceholder: function( sourceTr, targetTr ) { 6130 var that = this; 6131 6132 sourceTr.children().each( function() { 6133 $( "<td> </td>", that.document[ 0 ] ) 6134 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 6135 .appendTo( targetTr ); 6136 } ); 6137 }, 6138 6139 _contactContainers: function( event ) { 6140 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 6141 floating, axis, 6142 innermostContainer = null, 6143 innermostIndex = null; 6144 6145 // Get innermost container that intersects with item 6146 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6147 6148 // Never consider a container that's located within the item itself 6149 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 6150 continue; 6151 } 6152 6153 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 6154 6155 // If we've already found a container and it's more "inner" than this, then continue 6156 if ( innermostContainer && 6157 $.contains( 6158 this.containers[ i ].element[ 0 ], 6159 innermostContainer.element[ 0 ] ) ) { 6160 continue; 6161 } 6162 6163 innermostContainer = this.containers[ i ]; 6164 innermostIndex = i; 6165 6166 } else { 6167 6168 // container doesn't intersect. trigger "out" event if necessary 6169 if ( this.containers[ i ].containerCache.over ) { 6170 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 6171 this.containers[ i ].containerCache.over = 0; 6172 } 6173 } 6174 6175 } 6176 6177 // If no intersecting containers found, return 6178 if ( !innermostContainer ) { 6179 return; 6180 } 6181 6182 // Move the item into the container if it's not there already 6183 if ( this.containers.length === 1 ) { 6184 if ( !this.containers[ innermostIndex ].containerCache.over ) { 6185 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6186 this.containers[ innermostIndex ].containerCache.over = 1; 6187 } 6188 } else { 6189 6190 // When entering a new container, we will find the item with the least distance and 6191 // append our item near it 6192 dist = 10000; 6193 itemWithLeastDistance = null; 6194 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 6195 posProperty = floating ? "left" : "top"; 6196 sizeProperty = floating ? "width" : "height"; 6197 axis = floating ? "pageX" : "pageY"; 6198 6199 for ( j = this.items.length - 1; j >= 0; j-- ) { 6200 if ( !$.contains( 6201 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 6202 ) { 6203 continue; 6204 } 6205 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 6206 continue; 6207 } 6208 6209 cur = this.items[ j ].item.offset()[ posProperty ]; 6210 nearBottom = false; 6211 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 6212 nearBottom = true; 6213 } 6214 6215 if ( Math.abs( event[ axis ] - cur ) < dist ) { 6216 dist = Math.abs( event[ axis ] - cur ); 6217 itemWithLeastDistance = this.items[ j ]; 6218 this.direction = nearBottom ? "up" : "down"; 6219 } 6220 } 6221 6222 //Check if dropOnEmpty is enabled 6223 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 6224 return; 6225 } 6226 6227 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 6228 if ( !this.currentContainer.containerCache.over ) { 6229 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 6230 this.currentContainer.containerCache.over = 1; 6231 } 6232 return; 6233 } 6234 6235 itemWithLeastDistance ? 6236 this._rearrange( event, itemWithLeastDistance, null, true ) : 6237 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 6238 this._trigger( "change", event, this._uiHash() ); 6239 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 6240 this.currentContainer = this.containers[ innermostIndex ]; 6241 6242 //Update the placeholder 6243 this.options.placeholder.update( this.currentContainer, this.placeholder ); 6244 6245 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 6246 this.containers[ innermostIndex ].containerCache.over = 1; 6247 } 6248 6249 }, 6250 6251 _createHelper: function( event ) { 6252 6253 var o = this.options, 6254 helper = $.isFunction( o.helper ) ? 6255 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 6256 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 6257 6258 //Add the helper to the DOM if that didn't happen already 6259 if ( !helper.parents( "body" ).length ) { 6260 $( o.appendTo !== "parent" ? 6261 o.appendTo : 6262 this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); 6263 } 6264 6265 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 6266 this._storedCSS = { 6267 width: this.currentItem[ 0 ].style.width, 6268 height: this.currentItem[ 0 ].style.height, 6269 position: this.currentItem.css( "position" ), 6270 top: this.currentItem.css( "top" ), 6271 left: this.currentItem.css( "left" ) 6272 }; 6273 } 6274 6275 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 6276 helper.width( this.currentItem.width() ); 6277 } 6278 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 6279 helper.height( this.currentItem.height() ); 6280 } 6281 6282 return helper; 6283 6284 }, 6285 6286 _adjustOffsetFromHelper: function( obj ) { 6287 if ( typeof obj === "string" ) { 6288 obj = obj.split( " " ); 6289 } 6290 if ( $.isArray( obj ) ) { 6291 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 6292 } 6293 if ( "left" in obj ) { 6294 this.offset.click.left = obj.left + this.margins.left; 6295 } 6296 if ( "right" in obj ) { 6297 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6298 } 6299 if ( "top" in obj ) { 6300 this.offset.click.top = obj.top + this.margins.top; 6301 } 6302 if ( "bottom" in obj ) { 6303 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6304 } 6305 }, 6306 6307 _getParentOffset: function() { 6308 6309 //Get the offsetParent and cache its position 6310 this.offsetParent = this.helper.offsetParent(); 6311 var po = this.offsetParent.offset(); 6312 6313 // This is a special case where we need to modify a offset calculated on start, since the 6314 // following happened: 6315 // 1. The position of the helper is absolute, so it's position is calculated based on the 6316 // next positioned parent 6317 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 6318 // the document, which means that the scroll is included in the initial calculation of the 6319 // offset of the parent, and never recalculated upon drag 6320 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 6321 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 6322 po.left += this.scrollParent.scrollLeft(); 6323 po.top += this.scrollParent.scrollTop(); 6324 } 6325 6326 // This needs to be actually done for all browsers, since pageX/pageY includes this 6327 // information with an ugly IE fix 6328 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || 6329 ( this.offsetParent[ 0 ].tagName && 6330 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { 6331 po = { top: 0, left: 0 }; 6332 } 6333 6334 return { 6335 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 6336 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 6337 }; 6338 6339 }, 6340 6341 _getRelativeOffset: function() { 6342 6343 if ( this.cssPosition === "relative" ) { 6344 var p = this.currentItem.position(); 6345 return { 6346 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 6347 this.scrollParent.scrollTop(), 6348 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 6349 this.scrollParent.scrollLeft() 6350 }; 6351 } else { 6352 return { top: 0, left: 0 }; 6353 } 6354 6355 }, 6356 6357 _cacheMargins: function() { 6358 this.margins = { 6359 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 6360 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 6361 }; 6362 }, 6363 6364 _cacheHelperProportions: function() { 6365 this.helperProportions = { 6366 width: this.helper.outerWidth(), 6367 height: this.helper.outerHeight() 6368 }; 6369 }, 6370 6371 _setContainment: function() { 6372 6373 var ce, co, over, 6374 o = this.options; 6375 if ( o.containment === "parent" ) { 6376 o.containment = this.helper[ 0 ].parentNode; 6377 } 6378 if ( o.containment === "document" || o.containment === "window" ) { 6379 this.containment = [ 6380 0 - this.offset.relative.left - this.offset.parent.left, 6381 0 - this.offset.relative.top - this.offset.parent.top, 6382 o.containment === "document" ? 6383 this.document.width() : 6384 this.window.width() - this.helperProportions.width - this.margins.left, 6385 ( o.containment === "document" ? 6386 ( this.document.height() || document.body.parentNode.scrollHeight ) : 6387 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 6388 ) - this.helperProportions.height - this.margins.top 6389 ]; 6390 } 6391 6392 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 6393 ce = $( o.containment )[ 0 ]; 6394 co = $( o.containment ).offset(); 6395 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 6396 6397 this.containment = [ 6398 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 6399 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 6400 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 6401 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 6402 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 6403 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 6404 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 6405 this.helperProportions.width - this.margins.left, 6406 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 6407 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 6408 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 6409 this.helperProportions.height - this.margins.top 6410 ]; 6411 } 6412 6413 }, 6414 6415 _convertPositionTo: function( d, pos ) { 6416 6417 if ( !pos ) { 6418 pos = this.position; 6419 } 6420 var mod = d === "absolute" ? 1 : -1, 6421 scroll = this.cssPosition === "absolute" && 6422 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6423 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6424 this.offsetParent : 6425 this.scrollParent, 6426 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6427 6428 return { 6429 top: ( 6430 6431 // The absolute mouse position 6432 pos.top + 6433 6434 // Only for relative positioned nodes: Relative offset from element to offset parent 6435 this.offset.relative.top * mod + 6436 6437 // The offsetParent's offset without borders (offset + border) 6438 this.offset.parent.top * mod - 6439 ( ( this.cssPosition === "fixed" ? 6440 -this.scrollParent.scrollTop() : 6441 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 6442 ), 6443 left: ( 6444 6445 // The absolute mouse position 6446 pos.left + 6447 6448 // Only for relative positioned nodes: Relative offset from element to offset parent 6449 this.offset.relative.left * mod + 6450 6451 // The offsetParent's offset without borders (offset + border) 6452 this.offset.parent.left * mod - 6453 ( ( this.cssPosition === "fixed" ? 6454 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : 6455 scroll.scrollLeft() ) * mod ) 6456 ) 6457 }; 6458 6459 }, 6460 6461 _generatePosition: function( event ) { 6462 6463 var top, left, 6464 o = this.options, 6465 pageX = event.pageX, 6466 pageY = event.pageY, 6467 scroll = this.cssPosition === "absolute" && 6468 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6469 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 6470 this.offsetParent : 6471 this.scrollParent, 6472 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 6473 6474 // This is another very weird special case that only happens for relative elements: 6475 // 1. If the css position is relative 6476 // 2. and the scroll parent is the document or similar to the offset parent 6477 // we have to refresh the relative offset during the scroll so there are no jumps 6478 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 6479 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 6480 this.offset.relative = this._getRelativeOffset(); 6481 } 6482 6483 /* 6484 * - Position constraining - 6485 * Constrain the position to a mix of grid, containment. 6486 */ 6487 6488 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 6489 6490 if ( this.containment ) { 6491 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 6492 pageX = this.containment[ 0 ] + this.offset.click.left; 6493 } 6494 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 6495 pageY = this.containment[ 1 ] + this.offset.click.top; 6496 } 6497 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 6498 pageX = this.containment[ 2 ] + this.offset.click.left; 6499 } 6500 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 6501 pageY = this.containment[ 3 ] + this.offset.click.top; 6502 } 6503 } 6504 6505 if ( o.grid ) { 6506 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 6507 o.grid[ 1 ] ) * o.grid[ 1 ]; 6508 pageY = this.containment ? 6509 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 6510 top - this.offset.click.top <= this.containment[ 3 ] ) ? 6511 top : 6512 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 6513 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 6514 top; 6515 6516 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 6517 o.grid[ 0 ] ) * o.grid[ 0 ]; 6518 pageX = this.containment ? 6519 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 6520 left - this.offset.click.left <= this.containment[ 2 ] ) ? 6521 left : 6522 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 6523 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 6524 left; 6525 } 6526 6527 } 6528 6529 return { 6530 top: ( 6531 6532 // The absolute mouse position 6533 pageY - 6534 6535 // Click offset (relative to the element) 6536 this.offset.click.top - 6537 6538 // Only for relative positioned nodes: Relative offset from element to offset parent 6539 this.offset.relative.top - 6540 6541 // The offsetParent's offset without borders (offset + border) 6542 this.offset.parent.top + 6543 ( ( this.cssPosition === "fixed" ? 6544 -this.scrollParent.scrollTop() : 6545 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 6546 ), 6547 left: ( 6548 6549 // The absolute mouse position 6550 pageX - 6551 6552 // Click offset (relative to the element) 6553 this.offset.click.left - 6554 6555 // Only for relative positioned nodes: Relative offset from element to offset parent 6556 this.offset.relative.left - 6557 6558 // The offsetParent's offset without borders (offset + border) 6559 this.offset.parent.left + 6560 ( ( this.cssPosition === "fixed" ? 6561 -this.scrollParent.scrollLeft() : 6562 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 6563 ) 6564 }; 6565 6566 }, 6567 6568 _rearrange: function( event, i, a, hardRefresh ) { 6569 6570 a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : 6571 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 6572 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 6573 6574 //Various things done here to improve the performance: 6575 // 1. we create a setTimeout, that calls refreshPositions 6576 // 2. on the instance, we have a counter variable, that get's higher after every append 6577 // 3. on the local scope, we copy the counter variable, and check in the timeout, 6578 // if it's still the same 6579 // 4. this lets only the last addition to the timeout stack through 6580 this.counter = this.counter ? ++this.counter : 1; 6581 var counter = this.counter; 6582 6583 this._delay( function() { 6584 if ( counter === this.counter ) { 6585 6586 //Precompute after each DOM insertion, NOT on mousemove 6587 this.refreshPositions( !hardRefresh ); 6588 } 6589 } ); 6590 6591 }, 6592 6593 _clear: function( event, noPropagation ) { 6594 6595 this.reverting = false; 6596 6597 // We delay all events that have to be triggered to after the point where the placeholder 6598 // has been removed and everything else normalized again 6599 var i, 6600 delayedTriggers = []; 6601 6602 // We first have to update the dom position of the actual currentItem 6603 // Note: don't do it if the current item is already removed (by a user), or it gets 6604 // reappended (see #4088) 6605 if ( !this._noFinalSort && this.currentItem.parent().length ) { 6606 this.placeholder.before( this.currentItem ); 6607 } 6608 this._noFinalSort = null; 6609 6610 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 6611 for ( i in this._storedCSS ) { 6612 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 6613 this._storedCSS[ i ] = ""; 6614 } 6615 } 6616 this.currentItem.css( this._storedCSS ); 6617 this._removeClass( this.currentItem, "ui-sortable-helper" ); 6618 } else { 6619 this.currentItem.show(); 6620 } 6621 6622 if ( this.fromOutside && !noPropagation ) { 6623 delayedTriggers.push( function( event ) { 6624 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 6625 } ); 6626 } 6627 if ( ( this.fromOutside || 6628 this.domPosition.prev !== 6629 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 6630 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 6631 6632 // Trigger update callback if the DOM position has changed 6633 delayedTriggers.push( function( event ) { 6634 this._trigger( "update", event, this._uiHash() ); 6635 } ); 6636 } 6637 6638 // Check if the items Container has Changed and trigger appropriate 6639 // events. 6640 if ( this !== this.currentContainer ) { 6641 if ( !noPropagation ) { 6642 delayedTriggers.push( function( event ) { 6643 this._trigger( "remove", event, this._uiHash() ); 6644 } ); 6645 delayedTriggers.push( ( function( c ) { 6646 return function( event ) { 6647 c._trigger( "receive", event, this._uiHash( this ) ); 6648 }; 6649 } ).call( this, this.currentContainer ) ); 6650 delayedTriggers.push( ( function( c ) { 6651 return function( event ) { 6652 c._trigger( "update", event, this._uiHash( this ) ); 6653 }; 6654 } ).call( this, this.currentContainer ) ); 6655 } 6656 } 6657 6658 //Post events to containers 6659 function delayEvent( type, instance, container ) { 6660 return function( event ) { 6661 container._trigger( type, event, instance._uiHash( instance ) ); 6662 }; 6663 } 6664 for ( i = this.containers.length - 1; i >= 0; i-- ) { 6665 if ( !noPropagation ) { 6666 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 6667 } 6668 if ( this.containers[ i ].containerCache.over ) { 6669 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 6670 this.containers[ i ].containerCache.over = 0; 6671 } 6672 } 6673 6674 //Do what was originally in plugins 6675 if ( this.storedCursor ) { 6676 this.document.find( "body" ).css( "cursor", this.storedCursor ); 6677 this.storedStylesheet.remove(); 6678 } 6679 if ( this._storedOpacity ) { 6680 this.helper.css( "opacity", this._storedOpacity ); 6681 } 6682 if ( this._storedZIndex ) { 6683 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 6684 } 6685 6686 this.dragging = false; 6687 6688 if ( !noPropagation ) { 6689 this._trigger( "beforeStop", event, this._uiHash() ); 6690 } 6691 6692 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 6693 // it unbinds ALL events from the original node! 6694 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 6695 6696 if ( !this.cancelHelperRemoval ) { 6697 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 6698 this.helper.remove(); 6699 } 6700 this.helper = null; 6701 } 6702 6703 if ( !noPropagation ) { 6704 for ( i = 0; i < delayedTriggers.length; i++ ) { 6705 6706 // Trigger all delayed events 6707 delayedTriggers[ i ].call( this, event ); 6708 } 6709 this._trigger( "stop", event, this._uiHash() ); 6710 } 6711 6712 this.fromOutside = false; 6713 return !this.cancelHelperRemoval; 6714 6715 }, 6716 6717 _trigger: function() { 6718 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 6719 this.cancel(); 6720 } 6721 }, 6722 6723 _uiHash: function( _inst ) { 6724 var inst = _inst || this; 6725 return { 6726 helper: inst.helper, 6727 placeholder: inst.placeholder || $( [] ), 6728 position: inst.position, 6729 originalPosition: inst.originalPosition, 6730 offset: inst.positionAbs, 6731 item: inst.currentItem, 6732 sender: _inst ? _inst.element : null 6733 }; 6734 } 6735 6736} ); 6737 6738 6739/*! 6740 * jQuery UI
vendor: 2,177 bytes, lines 6740-6831
6740Accordion 1.12.1 6741 * http://jqueryui.com 6742 * 6743 * Copyright jQuery Foundation and other contributors 6744 * Released under the MIT license. 6745 * http://jquery.org/license 6746 */ 6747 6748//>>label: Accordion 6749//>>group: Widgets 6750// jscs:disable maximumLineLength 6751//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 6752// jscs:enable maximumLineLength 6753//>>docs: http://api.jqueryui.com/accordion/ 6754//>>demos: http://jqueryui.com/accordion/ 6755//>>css.structure: ../../themes/base/core.css 6756//>>css.structure: ../../themes/base/accordion.css 6757//>>css.theme: ../../themes/base/theme.css 6758 6759 6760 6761var widgetsAccordion = $.widget( "ui.accordion", { 6762 version: "1.12.1", 6763 options: { 6764 active: 0, 6765 animate: {}, 6766 classes: { 6767 "ui-accordion-header": "ui-corner-top", 6768 "ui-accordion-header-collapsed": "ui-corner-all", 6769 "ui-accordion-content": "ui-corner-bottom" 6770 }, 6771 collapsible: false, 6772 event: "click", 6773 header: "> li > :first-child, > :not(li):even", 6774 heightStyle: "auto", 6775 icons: { 6776 activeHeader: "ui-icon-triangle-1-s", 6777 header: "ui-icon-triangle-1-e" 6778 }, 6779 6780 // Callbacks 6781 activate: null, 6782 beforeActivate: null 6783 }, 6784 6785 hideProps: { 6786 borderTopWidth: "hide", 6787 borderBottomWidth: "hide", 6788 paddingTop: "hide", 6789 paddingBottom: "hide", 6790 height: "hide" 6791 }, 6792 6793 showProps: { 6794 borderTopWidth: "show", 6795 borderBottomWidth: "show", 6796 paddingTop: "show", 6797 paddingBottom: "show", 6798 height: "show" 6799 }, 6800 6801 _create: function() { 6802 var options = this.options; 6803 6804 this.prevShow = this.prevHide = $(); 6805 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 6806 this.element.attr( "role", "tablist" ); 6807 6808 // Don't allow collapsible: false and active: false / null 6809 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 6810 options.active = 0; 6811 } 6812 6813 this._processPanels(); 6814 6815 // handle negative values 6816 if ( options.active < 0 ) { 6817 options.active += this.headers.length; 6818 } 6819 this._refresh(); 6820 }, 6821 6822 _getCreateEventData: function() { 6823 return { 6824 header: this.active, 6825 panel: !this.active.length ? $() : this.active.next() 6826 }; 6827 }, 6828 6829 _createIcons: function() { 6830 var icon, children, 6831 icons = this.options.icons;
vendor: 8,005 bytes, lines 6831-7148
6831 6832 }, 6833 6834 _destroyIcons: function() { 6835 this._removeClass( this.headers, "ui-accordion-icons" ); 6836 this.headers.children( ".ui-accordion-header-icon" ).remove(); 6837 }, 6838 6839 _destroy: function() { 6840 var contents; 6841 6842 // Clean up main element 6843 this.element.removeAttr( "role" ); 6844 6845 // Clean up headers 6846 this.headers 6847 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 6848 .removeUniqueId(); 6849 6850 this._destroyIcons(); 6851 6852 // Clean up content panels 6853 contents = this.headers.next() 6854 .css( "display", "" ) 6855 .removeAttr( "role aria-hidden aria-labelledby" ) 6856 .removeUniqueId(); 6857 6858 if ( this.options.heightStyle !== "content" ) { 6859 contents.css( "height", "" ); 6860 } 6861 }, 6862 6863 _setOption: function( key, value ) { 6864 if ( key === "active" ) { 6865 6866 // _activate() will handle invalid values and update this.options 6867 this._activate( value ); 6868 return; 6869 } 6870 6871 if ( key === "event" ) { 6872 if ( this.options.event ) { 6873 this._off( this.headers, this.options.event ); 6874 } 6875 this._setupEvents( value ); 6876 } 6877 6878 this._super( key, value ); 6879 6880 // Setting collapsible: false while collapsed; open first panel 6881 if ( key === "collapsible" && !value && this.options.active === false ) { 6882 this._activate( 0 ); 6883 } 6884 6885 if ( key === "icons" ) { 6886 this._destroyIcons(); 6887 if ( value ) { 6888 this._createIcons(); 6889 } 6890 } 6891 }, 6892 6893 _setOptionDisabled: function( value ) { 6894 this._super( value ); 6895 6896 this.element.attr( "aria-disabled", value ); 6897 6898 // Support: IE8 Only 6899 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE 6900 // so we need to add the disabled class to the headers and panels 6901 this._toggleClass( null, "ui-state-disabled", !!value ); 6902 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", 6903 !!value ); 6904 }, 6905 6906 _keydown: function( event ) { 6907 if ( event.altKey || event.ctrlKey ) { 6908 return; 6909 } 6910 6911 var keyCode = $.ui.keyCode, 6912 length = this.headers.length, 6913 currentIndex = this.headers.index( event.target ), 6914 toFocus = false; 6915 6916 switch ( event.keyCode ) { 6917 case keyCode.RIGHT: 6918 case keyCode.DOWN: 6919 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6920 break; 6921 case keyCode.LEFT: 6922 case keyCode.UP: 6923 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6924 break; 6925 case keyCode.SPACE: 6926 case keyCode.ENTER: 6927 this._eventHandler( event ); 6928 break; 6929 case keyCode.HOME: 6930 toFocus = this.headers[ 0 ]; 6931 break; 6932 case keyCode.END: 6933 toFocus = this.headers[ length - 1 ]; 6934 break; 6935 } 6936 6937 if ( toFocus ) { 6938 $( event.target ).attr( "tabIndex", -1 ); 6939 $( toFocus ).attr( "tabIndex", 0 ); 6940 $( toFocus ).trigger( "focus" ); 6941 event.preventDefault(); 6942 } 6943 }, 6944 6945 _panelKeyDown: function( event ) { 6946 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6947 $( event.currentTarget ).prev().trigger( "focus" ); 6948 } 6949 }, 6950 6951 refresh: function() { 6952 var options = this.options; 6953 this._processPanels(); 6954 6955 // Was collapsed or no panel 6956 if ( ( options.active === false && options.collapsible === true ) || 6957 !this.headers.length ) { 6958 options.active = false; 6959 this.active = $(); 6960 6961 // active false only when collapsible is true 6962 } else if ( options.active === false ) { 6963 this._activate( 0 ); 6964 6965 // was active, but active panel is gone 6966 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6967 6968 // all remaining panel are disabled 6969 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 6970 options.active = false; 6971 this.active = $(); 6972 6973 // activate previous panel 6974 } else { 6975 this._activate( Math.max( 0, options.active - 1 ) ); 6976 } 6977 6978 // was active, active panel still exists 6979 } else { 6980 6981 // make sure active index is correct 6982 options.active = this.headers.index( this.active ); 6983 } 6984 6985 this._destroyIcons(); 6986 6987 this._refresh(); 6988 }, 6989 6990 _processPanels: function() { 6991 var prevHeaders = this.headers, 6992 prevPanels = this.panels; 6993 6994 this.headers = this.element.find( this.options.header ); 6995 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 6996 "ui-state-default" ); 6997 6998 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 6999 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 7000 7001 // Avoid memory leaks (#10056) 7002 if ( prevPanels ) { 7003 this._off( prevHeaders.not( this.headers ) ); 7004 this._off( prevPanels.not( this.panels ) ); 7005 } 7006 }, 7007 7008 _refresh: function() { 7009 var maxHeight, 7010 options = this.options, 7011 heightStyle = options.heightStyle, 7012 parent = this.element.parent(); 7013 7014 this.active = this._findActive( options.active ); 7015 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 7016 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 7017 this._addClass( this.active.next(), "ui-accordion-content-active" ); 7018 this.active.next().show(); 7019 7020 this.headers 7021 .attr( "role", "tab" ) 7022 .each( function() { 7023 var header = $( this ), 7024 headerId = header.uniqueId().attr( "id" ), 7025 panel = header.next(), 7026 panelId = panel.uniqueId().attr( "id" ); 7027 header.attr( "aria-controls", panelId ); 7028 panel.attr( "aria-labelledby", headerId ); 7029 } ) 7030 .next() 7031 .attr( "role", "tabpanel" ); 7032 7033 this.headers 7034 .not( this.active ) 7035 .attr( { 7036 "aria-selected": "false", 7037 "aria-expanded": "false", 7038 tabIndex: -1 7039 } ) 7040 .next() 7041 .attr( { 7042 "aria-hidden": "true" 7043 } ) 7044 .hide(); 7045 7046 // Make sure at least one header is in the tab order 7047 if ( !this.active.length ) { 7048 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 7049 } else { 7050 this.active.attr( { 7051 "aria-selected": "true", 7052 "aria-expanded": "true", 7053 tabIndex: 0 7054 } ) 7055 .next() 7056 .attr( { 7057 "aria-hidden": "false" 7058 } ); 7059 } 7060 7061 this._createIcons(); 7062 7063 this._setupEvents( options.event ); 7064 7065 if ( heightStyle === "fill" ) { 7066 maxHeight = parent.height(); 7067 this.element.siblings( ":visible" ).each( function() { 7068 var elem = $( this ), 7069 position = elem.css( "position" ); 7070 7071 if ( position === "absolute" || position === "fixed" ) { 7072 return; 7073 } 7074 maxHeight -= elem.outerHeight( true ); 7075 } ); 7076 7077 this.headers.each( function() { 7078 maxHeight -= $( this ).outerHeight( true ); 7079 } ); 7080 7081 this.headers.next() 7082 .each( function() { 7083 $( this ).height( Math.max( 0, maxHeight - 7084 $( this ).innerHeight() + $( this ).height() ) ); 7085 } ) 7086 .css( "overflow", "auto" ); 7087 } else if ( heightStyle === "auto" ) { 7088 maxHeight = 0; 7089 this.headers.next() 7090 .each( function() { 7091 var isVisible = $( this ).is( ":visible" ); 7092 if ( !isVisible ) { 7093 $( this ).show(); 7094 } 7095 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 7096 if ( !isVisible ) { 7097 $( this ).hide(); 7098 } 7099 } ) 7100 .height( maxHeight ); 7101 } 7102 }, 7103 7104 _activate: function( index ) { 7105 var active = this._findActive( index )[ 0 ]; 7106 7107 // Trying to activate the already active panel 7108 if ( active === this.active[ 0 ] ) { 7109 return; 7110 } 7111 7112 // Trying to collapse, simulate a click on the currently active header 7113 active = active || this.active[ 0 ]; 7114 7115 this._eventHandler( { 7116 target: active, 7117 currentTarget: active, 7118 preventDefault: $.noop 7119 } ); 7120 }, 7121 7122 _findActive: function( selector ) { 7123 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 7124 }, 7125 7126 _setupEvents: function( event ) { 7127 var events = { 7128 keydown: "_keydown" 7129 }; 7130 if ( event ) { 7131 $.each( event.split( " " ), function( index, eventName ) { 7132 events[ eventName ] = "_eventHandler"; 7133 } ); 7134 } 7135 7136 this._off( this.headers.add( this.headers.next() ) ); 7137 this._on( this.headers, events ); 7138 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 7139 this._hoverable( this.headers ); 7140 this._focusable( this.headers ); 7141 }, 7142 7143 _eventHandler: function( event ) { 7144 var activeChildren, clickedChildren, 7145 options = this.options, 7146 active = this.active, 7147 clicked = $( event.currentTarget ), 7148 clickedIsActive = clicked[ 0 ] === active[ 0 ],
vendor: 6,030 bytes, lines 7149-7373
7149 collapsing = clickedIsActive && options.collapsible, 7150 toShow = collapsing ? $() : clicked.next(), 7151 toHide = active.next(), 7152 eventData = { 7153 oldHeader: active, 7154 oldPanel: toHide, 7155 newHeader: collapsing ? $() : clicked, 7156 newPanel: toShow 7157 }; 7158 7159 event.preventDefault(); 7160 7161 if ( 7162 7163 // click on active header, but not collapsible 7164 ( clickedIsActive && !options.collapsible ) || 7165 7166 // allow canceling activation 7167 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 7168 return; 7169 } 7170 7171 options.active = collapsing ? false : this.headers.index( clicked ); 7172 7173 // When the call to ._toggle() comes after the class changes 7174 // it causes a very odd bug in IE 8 (see #6720) 7175 this.active = clickedIsActive ? $() : clicked; 7176 this._toggle( eventData ); 7177 7178 // Switch classes 7179 // corner classes on the previously active header stay after the animation 7180 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 7181 if ( options.icons ) { 7182 activeChildren = active.children( ".ui-accordion-header-icon" ); 7183 this._removeClass( activeChildren, null, options.icons.activeHeader ) 7184 ._addClass( activeChildren, null, options.icons.header ); 7185 } 7186 7187 if ( !clickedIsActive ) { 7188 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 7189 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 7190 if ( options.icons ) { 7191 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 7192 this._removeClass( clickedChildren, null, options.icons.header ) 7193 ._addClass( clickedChildren, null, options.icons.activeHeader ); 7194 } 7195 7196 this._addClass( clicked.next(), "ui-accordion-content-active" ); 7197 } 7198 }, 7199 7200 _toggle: function( data ) { 7201 var toShow = data.newPanel, 7202 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 7203 7204 // Handle activating a panel during the animation for another activation 7205 this.prevShow.add( this.prevHide ).stop( true, true ); 7206 this.prevShow = toShow; 7207 this.prevHide = toHide; 7208 7209 if ( this.options.animate ) { 7210 this._animate( toShow, toHide, data ); 7211 } else { 7212 toHide.hide(); 7213 toShow.show(); 7214 this._toggleComplete( data ); 7215 } 7216 7217 toHide.attr( { 7218 "aria-hidden": "true" 7219 } ); 7220 toHide.prev().attr( { 7221 "aria-selected": "false", 7222 "aria-expanded": "false" 7223 } ); 7224 7225 // if we're switching panels, remove the old header from the tab order 7226 // if we're opening from collapsed state, remove the previous header from the tab order 7227 // if we're collapsing, then keep the collapsing header in the tab order 7228 if ( toShow.length && toHide.length ) { 7229 toHide.prev().attr( { 7230 "tabIndex": -1, 7231 "aria-expanded": "false" 7232 } ); 7233 } else if ( toShow.length ) { 7234 this.headers.filter( function() { 7235 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 7236 } ) 7237 .attr( "tabIndex", -1 ); 7238 } 7239 7240 toShow 7241 .attr( "aria-hidden", "false" ) 7242 .prev() 7243 .attr( { 7244 "aria-selected": "true", 7245 "aria-expanded": "true", 7246 tabIndex: 0 7247 } ); 7248 }, 7249 7250 _animate: function( toShow, toHide, data ) { 7251 var total, easing, duration, 7252 that = this, 7253 adjust = 0, 7254 boxSizing = toShow.css( "box-sizing" ), 7255 down = toShow.length && 7256 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 7257 animate = this.options.animate || {}, 7258 options = down && animate.down || animate, 7259 complete = function() { 7260 that._toggleComplete( data ); 7261 }; 7262 7263 if ( typeof options === "number" ) { 7264 duration = options; 7265 } 7266 if ( typeof options === "string" ) { 7267 easing = options; 7268 } 7269 7270 // fall back from options to animation in case of partial down settings 7271 easing = easing || options.easing || animate.easing; 7272 duration = duration || options.duration || animate.duration; 7273 7274 if ( !toHide.length ) { 7275 return toShow.animate( this.showProps, duration, easing, complete ); 7276 } 7277 if ( !toShow.length ) { 7278 return toHide.animate( this.hideProps, duration, easing, complete ); 7279 } 7280 7281 total = toShow.show().outerHeight(); 7282 toHide.animate( this.hideProps, { 7283 duration: duration, 7284 easing: easing, 7285 step: function( now, fx ) { 7286 fx.now = Math.round( now ); 7287 } 7288 } ); 7289 toShow 7290 .hide() 7291 .animate( this.showProps, { 7292 duration: duration, 7293 easing: easing, 7294 complete: complete, 7295 step: function( now, fx ) { 7296 fx.now = Math.round( now ); 7297 if ( fx.prop !== "height" ) { 7298 if ( boxSizing === "content-box" ) { 7299 adjust += fx.now; 7300 } 7301 } else if ( that.options.heightStyle !== "content" ) { 7302 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 7303 adjust = 0; 7304 } 7305 } 7306 } ); 7307 }, 7308 7309 _toggleComplete: function( data ) { 7310 var toHide = data.oldPanel, 7311 prev = toHide.prev(); 7312 7313 this._removeClass( toHide, "ui-accordion-content-active" ); 7314 this._removeClass( prev, "ui-accordion-header-active" ) 7315 ._addClass( prev, "ui-accordion-header-collapsed" ); 7316 7317 // Work around for rendering bug in IE (#5421) 7318 if ( toHide.length ) { 7319 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 7320 } 7321 this._trigger( "activate", null, data ); 7322 } 7323} ); 7324 7325 7326/*! 7327 * jQuery UI Menu 1.12.1 7328 * http://jqueryui.com 7329 * 7330 * Copyright jQuery Foundation and other contributors 7331 * Released under the MIT license. 7332 * http://jquery.org/license 7333 */ 7334 7335//>>label: Menu 7336//>>group: Widgets 7337//>>description: Creates nestable menus. 7338//>>docs: http://api.jqueryui.com/menu/ 7339//>>demos: http://jqueryui.com/menu/ 7340//>>css.structure: ../../themes/base/core.css 7341//>>css.structure: ../../themes/base/menu.css 7342//>>css.theme: ../../themes/base/theme.css 7343 7344 7345 7346var widgetsMenu = $.widget( "ui.menu", { 7347 version: "1.12.1", 7348 defaultElement: "<ul>", 7349 delay: 300, 7350 options: { 7351 icons: { 7352 submenu: "ui-icon-caret-1-e" 7353 }, 7354 items: "> *", 7355 menus: "ul", 7356 position: { 7357 my: "left top", 7358 at: "right top" 7359 }, 7360 role: "menu", 7361 7362 // Callbacks 7363 blur: null, 7364 focus: null, 7365 select: null 7366 }, 7367 7368 _create: function() { 7369 this.activeMenu = this.element; 7370 7371 // Flag used to prevent firing of the click handler 7372 // as the event bubbles up through nested menus 7373 this.mouseHandled = false;
vendor: 139,549 bytes, lines 7374-11665
7374 this.element 7375 .uniqueId() 7376 .attr( { 7377 role: this.options.role, 7378 tabIndex: 0 7379 } ); 7380 7381 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 7382 this._on( { 7383 7384 // Prevent focus from sticking to links inside menu after clicking 7385 // them (focus should always stay on UL during navigation). 7386 "mousedown .ui-menu-item": function( event ) { 7387 event.preventDefault(); 7388 }, 7389 "click .ui-menu-item": function( event ) { 7390 var target = $( event.target ); 7391 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 7392 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 7393 this.select( event ); 7394 7395 // Only set the mouseHandled flag if the event will bubble, see #9469. 7396 if ( !event.isPropagationStopped() ) { 7397 this.mouseHandled = true; 7398 } 7399 7400 // Open submenu on click 7401 if ( target.has( ".ui-menu" ).length ) { 7402 this.expand( event ); 7403 } else if ( !this.element.is( ":focus" ) && 7404 active.closest( ".ui-menu" ).length ) { 7405 7406 // Redirect focus to the menu 7407 this.element.trigger( "focus", [ true ] ); 7408 7409 // If the active item is on the top level, let it stay active. 7410 // Otherwise, blur the active item since it is no longer visible. 7411 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 7412 clearTimeout( this.timer ); 7413 } 7414 } 7415 } 7416 }, 7417 "mouseenter .ui-menu-item": function( event ) { 7418 7419 // Ignore mouse events while typeahead is active, see #10458. 7420 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 7421 // is over an item in the menu 7422 if ( this.previousFilter ) { 7423 return; 7424 } 7425 7426 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 7427 target = $( event.currentTarget ); 7428 7429 // Ignore bubbled events on parent items, see #11641 7430 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 7431 return; 7432 } 7433 7434 // Remove ui-state-active class from siblings of the newly focused menu item 7435 // to avoid a jump caused by adjacent elements both having a class with a border 7436 this._removeClass( target.siblings().children( ".ui-state-active" ), 7437 null, "ui-state-active" ); 7438 this.focus( event, target ); 7439 }, 7440 mouseleave: "collapseAll", 7441 "mouseleave .ui-menu": "collapseAll", 7442 focus: function( event, keepActiveItem ) { 7443 7444 // If there's already an active item, keep it active 7445 // If not, activate the first item 7446 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 7447 7448 if ( !keepActiveItem ) { 7449 this.focus( event, item ); 7450 } 7451 }, 7452 blur: function( event ) { 7453 this._delay( function() { 7454 var notContained = !$.contains( 7455 this.element[ 0 ], 7456 $.ui.safeActiveElement( this.document[ 0 ] ) 7457 ); 7458 if ( notContained ) { 7459 this.collapseAll( event ); 7460 } 7461 } ); 7462 }, 7463 keydown: "_keydown" 7464 } ); 7465 7466 this.refresh(); 7467 7468 // Clicks outside of a menu collapse any open menus 7469 this._on( this.document, { 7470 click: function( event ) { 7471 if ( this._closeOnDocumentClick( event ) ) { 7472 this.collapseAll( event ); 7473 } 7474 7475 // Reset the mouseHandled flag 7476 this.mouseHandled = false; 7477 } 7478 } ); 7479 }, 7480 7481 _destroy: function() { 7482 var items = this.element.find( ".ui-menu-item" ) 7483 .removeAttr( "role aria-disabled" ), 7484 submenus = items.children( ".ui-menu-item-wrapper" ) 7485 .removeUniqueId() 7486 .removeAttr( "tabIndex role aria-haspopup" ); 7487 7488 // Destroy (sub)menus 7489 this.element 7490 .removeAttr( "aria-activedescendant" ) 7491 .find( ".ui-menu" ).addBack() 7492 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 7493 "tabIndex" ) 7494 .removeUniqueId() 7495 .show(); 7496 7497 submenus.children().each( function() { 7498 var elem = $( this ); 7499 if ( elem.data( "ui-menu-submenu-caret" ) ) { 7500 elem.remove(); 7501 } 7502 } ); 7503 }, 7504 7505 _keydown: function( event ) { 7506 var match, prev, character, skip, 7507 preventDefault = true; 7508 7509 switch ( event.keyCode ) { 7510 case $.ui.keyCode.PAGE_UP: 7511 this.previousPage( event ); 7512 break; 7513 case $.ui.keyCode.PAGE_DOWN: 7514 this.nextPage( event ); 7515 break; 7516 case $.ui.keyCode.HOME: 7517 this._move( "first", "first", event ); 7518 break; 7519 case $.ui.keyCode.END: 7520 this._move( "last", "last", event ); 7521 break; 7522 case $.ui.keyCode.UP: 7523 this.previous( event ); 7524 break; 7525 case $.ui.keyCode.DOWN: 7526 this.next( event ); 7527 break; 7528 case $.ui.keyCode.LEFT: 7529 this.collapse( event ); 7530 break; 7531 case $.ui.keyCode.RIGHT: 7532 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7533 this.expand( event ); 7534 } 7535 break; 7536 case $.ui.keyCode.ENTER: 7537 case $.ui.keyCode.SPACE: 7538 this._activate( event ); 7539 break; 7540 case $.ui.keyCode.ESCAPE: 7541 this.collapse( event ); 7542 break; 7543 default: 7544 preventDefault = false; 7545 prev = this.previousFilter || ""; 7546 skip = false; 7547 7548 // Support number pad values 7549 character = event.keyCode >= 96 && event.keyCode <= 105 ? 7550 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 7551 7552 clearTimeout( this.filterTimer ); 7553 7554 if ( character === prev ) { 7555 skip = true; 7556 } else { 7557 character = prev + character; 7558 } 7559 7560 match = this._filterMenuItems( character ); 7561 match = skip && match.index( this.active.next() ) !== -1 ? 7562 this.active.nextAll( ".ui-menu-item" ) : 7563 match; 7564 7565 // If no matches on the current filter, reset to the last character pressed 7566 // to move down the menu to the first item that starts with that character 7567 if ( !match.length ) { 7568 character = String.fromCharCode( event.keyCode ); 7569 match = this._filterMenuItems( character ); 7570 } 7571 7572 if ( match.length ) { 7573 this.focus( event, match ); 7574 this.previousFilter = character; 7575 this.filterTimer = this._delay( function() { 7576 delete this.previousFilter; 7577 }, 1000 ); 7578 } else { 7579 delete this.previousFilter; 7580 } 7581 } 7582 7583 if ( preventDefault ) { 7584 event.preventDefault(); 7585 } 7586 }, 7587 7588 _activate: function( event ) { 7589 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 7590 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 7591 this.expand( event ); 7592 } else { 7593 this.select( event ); 7594 } 7595 } 7596 }, 7597 7598 refresh: function() { 7599 var menus, items, newSubmenus, newItems, newWrappers, 7600 that = this, 7601 icon = this.options.icons.submenu, 7602 submenus = this.element.find( this.options.menus ); 7603 7604 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 7605 7606 // Initialize nested menus 7607 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 7608 .hide() 7609 .attr( { 7610 role: this.options.role, 7611 "aria-hidden": "true", 7612 "aria-expanded": "false" 7613 } ) 7614 .each( function() { 7615 var menu = $( this ), 7616 item = menu.prev(), 7617 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 7618 7619 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 7620 item 7621 .attr( "aria-haspopup", "true" ) 7622 .prepend( submenuCaret ); 7623 menu.attr( "aria-labelledby", item.attr( "id" ) ); 7624 } ); 7625 7626 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 7627 7628 menus = submenus.add( this.element ); 7629 items = menus.find( this.options.items ); 7630 7631 // Initialize menu-items containing spaces and/or dashes only as dividers 7632 items.not( ".ui-menu-item" ).each( function() { 7633 var item = $( this ); 7634 if ( that._isDivider( item ) ) { 7635 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 7636 } 7637 } ); 7638 7639 // Don't refresh list items that are already adapted 7640 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 7641 newWrappers = newItems.children() 7642 .not( ".ui-menu" ) 7643 .uniqueId() 7644 .attr( { 7645 tabIndex: -1, 7646 role: this._itemRole() 7647 } ); 7648 this._addClass( newItems, "ui-menu-item" ) 7649 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 7650 7651 // Add aria-disabled attribute to any disabled menu item 7652 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 7653 7654 // If the active item has been removed, blur the menu 7655 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 7656 this.blur(); 7657 } 7658 }, 7659 7660 _itemRole: function() { 7661 return { 7662 menu: "menuitem", 7663 listbox: "option" 7664 }[ this.options.role ]; 7665 }, 7666 7667 _setOption: function( key, value ) { 7668 if ( key === "icons" ) { 7669 var icons = this.element.find( ".ui-menu-icon" ); 7670 this._removeClass( icons, null, this.options.icons.submenu ) 7671 ._addClass( icons, null, value.submenu ); 7672 } 7673 this._super( key, value ); 7674 }, 7675 7676 _setOptionDisabled: function( value ) { 7677 this._super( value ); 7678 7679 this.element.attr( "aria-disabled", String( value ) ); 7680 this._toggleClass( null, "ui-state-disabled", !!value ); 7681 }, 7682 7683 focus: function( event, item ) { 7684 var nested, focused, activeParent; 7685 this.blur( event, event && event.type === "focus" ); 7686 7687 this._scrollIntoView( item ); 7688 7689 this.active = item.first(); 7690 7691 focused = this.active.children( ".ui-menu-item-wrapper" ); 7692 this._addClass( focused, null, "ui-state-active" ); 7693 7694 // Only update aria-activedescendant if there's a role 7695 // otherwise we assume focus is managed elsewhere 7696 if ( this.options.role ) { 7697 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 7698 } 7699 7700 // Highlight active parent menu item, if any 7701 activeParent = this.active 7702 .parent() 7703 .closest( ".ui-menu-item" ) 7704 .children( ".ui-menu-item-wrapper" ); 7705 this._addClass( activeParent, null, "ui-state-active" ); 7706 7707 if ( event && event.type === "keydown" ) { 7708 this._close(); 7709 } else { 7710 this.timer = this._delay( function() { 7711 this._close(); 7712 }, this.delay ); 7713 } 7714 7715 nested = item.children( ".ui-menu" ); 7716 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 7717 this._startOpening( nested ); 7718 } 7719 this.activeMenu = item.parent(); 7720 7721 this._trigger( "focus", event, { item: item } ); 7722 }, 7723 7724 _scrollIntoView: function( item ) { 7725 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 7726 if ( this._hasScroll() ) { 7727 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 7728 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 7729 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 7730 scroll = this.activeMenu.scrollTop(); 7731 elementHeight = this.activeMenu.height(); 7732 itemHeight = item.outerHeight(); 7733 7734 if ( offset < 0 ) { 7735 this.activeMenu.scrollTop( scroll + offset ); 7736 } else if ( offset + itemHeight > elementHeight ) { 7737 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 7738 } 7739 } 7740 }, 7741 7742 blur: function( event, fromFocus ) { 7743 if ( !fromFocus ) { 7744 clearTimeout( this.timer ); 7745 } 7746 7747 if ( !this.active ) { 7748 return; 7749 } 7750 7751 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 7752 null, "ui-state-active" ); 7753 7754 this._trigger( "blur", event, { item: this.active } ); 7755 this.active = null; 7756 }, 7757 7758 _startOpening: function( submenu ) { 7759 clearTimeout( this.timer ); 7760 7761 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 7762 // shift in the submenu position when mousing over the caret icon 7763 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 7764 return; 7765 } 7766 7767 this.timer = this._delay( function() { 7768 this._close(); 7769 this._open( submenu ); 7770 }, this.delay ); 7771 }, 7772 7773 _open: function( submenu ) { 7774 var position = $.extend( { 7775 of: this.active 7776 }, this.options.position ); 7777 7778 clearTimeout( this.timer ); 7779 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 7780 .hide() 7781 .attr( "aria-hidden", "true" ); 7782 7783 submenu 7784 .show() 7785 .removeAttr( "aria-hidden" ) 7786 .attr( "aria-expanded", "true" ) 7787 .position( position ); 7788 }, 7789 7790 collapseAll: function( event, all ) { 7791 clearTimeout( this.timer ); 7792 this.timer = this._delay( function() { 7793 7794 // If we were passed an event, look for the submenu that contains the event 7795 var currentMenu = all ? this.element : 7796 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 7797 7798 // If we found no valid submenu ancestor, use the main menu to close all 7799 // sub menus anyway 7800 if ( !currentMenu.length ) { 7801 currentMenu = this.element; 7802 } 7803 7804 this._close( currentMenu ); 7805 7806 this.blur( event ); 7807 7808 // Work around active item staying active after menu is blurred 7809 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 7810 7811 this.activeMenu = currentMenu; 7812 }, this.delay ); 7813 }, 7814 7815 // With no arguments, closes the currently active menu - if nothing is active 7816 // it closes all menus. If passed an argument, it will search for menus BELOW 7817 _close: function( startMenu ) { 7818 if ( !startMenu ) { 7819 startMenu = this.active ? this.active.parent() : this.element; 7820 } 7821 7822 startMenu.find( ".ui-menu" ) 7823 .hide() 7824 .attr( "aria-hidden", "true" ) 7825 .attr( "aria-expanded", "false" ); 7826 }, 7827 7828 _closeOnDocumentClick: function( event ) { 7829 return !$( event.target ).closest( ".ui-menu" ).length; 7830 }, 7831 7832 _isDivider: function( item ) { 7833 7834 // Match hyphen, em dash, en dash 7835 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 7836 }, 7837 7838 collapse: function( event ) { 7839 var newItem = this.active && 7840 this.active.parent().closest( ".ui-menu-item", this.element ); 7841 if ( newItem && newItem.length ) { 7842 this._close(); 7843 this.focus( event, newItem ); 7844 } 7845 }, 7846 7847 expand: function( event ) { 7848 var newItem = this.active && 7849 this.active 7850 .children( ".ui-menu " ) 7851 .find( this.options.items ) 7852 .first(); 7853 7854 if ( newItem && newItem.length ) { 7855 this._open( newItem.parent() ); 7856 7857 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 7858 this._delay( function() { 7859 this.focus( event, newItem ); 7860 } ); 7861 } 7862 }, 7863 7864 next: function( event ) { 7865 this._move( "next", "first", event ); 7866 }, 7867 7868 previous: function( event ) { 7869 this._move( "prev", "last", event ); 7870 }, 7871 7872 isFirstItem: function() { 7873 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 7874 }, 7875 7876 isLastItem: function() { 7877 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 7878 }, 7879 7880 _move: function( direction, filter, event ) { 7881 var next; 7882 if ( this.active ) { 7883 if ( direction === "first" || direction === "last" ) { 7884 next = this.active 7885 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 7886 .eq( -1 ); 7887 } else { 7888 next = this.active 7889 [ direction + "All" ]( ".ui-menu-item" ) 7890 .eq( 0 ); 7891 } 7892 } 7893 if ( !next || !next.length || !this.active ) { 7894 next = this.activeMenu.find( this.options.items )[ filter ](); 7895 } 7896 7897 this.focus( event, next ); 7898 }, 7899 7900 nextPage: function( event ) { 7901 var item, base, height; 7902 7903 if ( !this.active ) { 7904 this.next( event ); 7905 return; 7906 } 7907 if ( this.isLastItem() ) { 7908 return; 7909 } 7910 if ( this._hasScroll() ) { 7911 base = this.active.offset().top; 7912 height = this.element.height(); 7913 this.active.nextAll( ".ui-menu-item" ).each( function() { 7914 item = $( this ); 7915 return item.offset().top - base - height < 0; 7916 } ); 7917 7918 this.focus( event, item ); 7919 } else { 7920 this.focus( event, this.activeMenu.find( this.options.items ) 7921 [ !this.active ? "first" : "last" ]() ); 7922 } 7923 }, 7924 7925 previousPage: function( event ) { 7926 var item, base, height; 7927 if ( !this.active ) { 7928 this.next( event ); 7929 return; 7930 } 7931 if ( this.isFirstItem() ) { 7932 return; 7933 } 7934 if ( this._hasScroll() ) { 7935 base = this.active.offset().top; 7936 height = this.element.height(); 7937 this.active.prevAll( ".ui-menu-item" ).each( function() { 7938 item = $( this ); 7939 return item.offset().top - base + height > 0; 7940 } ); 7941 7942 this.focus( event, item ); 7943 } else { 7944 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 7945 } 7946 }, 7947 7948 _hasScroll: function() { 7949 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 7950 }, 7951 7952 select: function( event ) { 7953 7954 // TODO: It should never be possible to not have an active item at this 7955 // point, but the tests don't trigger mouseenter before click. 7956 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 7957 var ui = { item: this.active }; 7958 if ( !this.active.has( ".ui-menu" ).length ) { 7959 this.collapseAll( event, true ); 7960 } 7961 this._trigger( "select", event, ui ); 7962 }, 7963 7964 _filterMenuItems: function( character ) { 7965 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 7966 regex = new RegExp( "^" + escapedCharacter, "i" ); 7967 7968 return this.activeMenu 7969 .find( this.options.items ) 7970 7971 // Only match on items, not dividers or other content (#10571) 7972 .filter( ".ui-menu-item" ) 7973 .filter( function() { 7974 return regex.test( 7975 $.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 7976 } ); 7977 } 7978} ); 7979 7980 7981/*! 7982 * jQuery UI Autocomplete 1.12.1 7983 * http://jqueryui.com 7984 * 7985 * Copyright jQuery Foundation and other contributors 7986 * Released under the MIT license. 7987 * http://jquery.org/license 7988 */ 7989 7990//>>label: Autocomplete 7991//>>group: Widgets 7992//>>description: Lists suggested words as the user is typing. 7993//>>docs: http://api.jqueryui.com/autocomplete/ 7994//>>demos: http://jqueryui.com/autocomplete/ 7995//>>css.structure: ../../themes/base/core.css 7996//>>css.structure: ../../themes/base/autocomplete.css 7997//>>css.theme: ../../themes/base/theme.css 7998 7999 8000 8001$.widget( "ui.autocomplete", { 8002 version: "1.12.1", 8003 defaultElement: "<input>", 8004 options: { 8005 appendTo: null, 8006 autoFocus: false, 8007 delay: 300, 8008 minLength: 1, 8009 position: { 8010 my: "left top", 8011 at: "left bottom", 8012 collision: "none" 8013 }, 8014 source: null, 8015 8016 // Callbacks 8017 change: null, 8018 close: null, 8019 focus: null, 8020 open: null, 8021 response: null, 8022 search: null, 8023 select: null 8024 }, 8025 8026 requestIndex: 0, 8027 pending: 0, 8028 8029 _create: function() { 8030 8031 // Some browsers only repeat keydown events, not keypress events, 8032 // so we use the suppressKeyPress flag to determine if we've already 8033 // handled the keydown event. #7269 8034 // Unfortunately the code for & in keypress is the same as the up arrow, 8035 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 8036 // events when we know the keydown event was used to modify the 8037 // search term. #7799 8038 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 8039 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 8040 isTextarea = nodeName === "textarea", 8041 isInput = nodeName === "input"; 8042 8043 // Textareas are always multi-line 8044 // Inputs are always single-line, even if inside a contentEditable element 8045 // IE also treats inputs as contentEditable 8046 // All other element types are determined by whether or not they're contentEditable 8047 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 8048 8049 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 8050 this.isNewMenu = true; 8051 8052 this._addClass( "ui-autocomplete-input" ); 8053 this.element.attr( "autocomplete", "off" ); 8054 8055 this._on( this.element, { 8056 keydown: function( event ) { 8057 if ( this.element.prop( "readOnly" ) ) { 8058 suppressKeyPress = true; 8059 suppressInput = true; 8060 suppressKeyPressRepeat = true; 8061 return; 8062 } 8063 8064 suppressKeyPress = false; 8065 suppressInput = false; 8066 suppressKeyPressRepeat = false; 8067 var keyCode = $.ui.keyCode; 8068 switch ( event.keyCode ) { 8069 case keyCode.PAGE_UP: 8070 suppressKeyPress = true; 8071 this._move( "previousPage", event ); 8072 break; 8073 case keyCode.PAGE_DOWN: 8074 suppressKeyPress = true; 8075 this._move( "nextPage", event ); 8076 break; 8077 case keyCode.UP: 8078 suppressKeyPress = true; 8079 this._keyEvent( "previous", event ); 8080 break; 8081 case keyCode.DOWN: 8082 suppressKeyPress = true; 8083 this._keyEvent( "next", event ); 8084 break; 8085 case keyCode.ENTER: 8086 8087 // when menu is open and has focus 8088 if ( this.menu.active ) { 8089 8090 // #6055 - Opera still allows the keypress to occur 8091 // which causes forms to submit 8092 suppressKeyPress = true; 8093 event.preventDefault(); 8094 this.menu.select( event ); 8095 } 8096 break; 8097 case keyCode.TAB: 8098 if ( this.menu.active ) { 8099 this.menu.select( event ); 8100 } 8101 break; 8102 case keyCode.ESCAPE: 8103 if ( this.menu.element.is( ":visible" ) ) { 8104 if ( !this.isMultiLine ) { 8105 this._value( this.term ); 8106 } 8107 this.close( event ); 8108 8109 // Different browsers have different default behavior for escape 8110 // Single press can mean undo or clear 8111 // Double press in IE means clear the whole form 8112 event.preventDefault(); 8113 } 8114 break; 8115 default: 8116 suppressKeyPressRepeat = true; 8117 8118 // search timeout should be triggered before the input value is changed 8119 this._searchTimeout( event ); 8120 break; 8121 } 8122 }, 8123 keypress: function( event ) { 8124 if ( suppressKeyPress ) { 8125 suppressKeyPress = false; 8126 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8127 event.preventDefault(); 8128 } 8129 return; 8130 } 8131 if ( suppressKeyPressRepeat ) { 8132 return; 8133 } 8134 8135 // Replicate some key handlers to allow them to repeat in Firefox and Opera 8136 var keyCode = $.ui.keyCode; 8137 switch ( event.keyCode ) { 8138 case keyCode.PAGE_UP: 8139 this._move( "previousPage", event ); 8140 break; 8141 case keyCode.PAGE_DOWN: 8142 this._move( "nextPage", event ); 8143 break; 8144 case keyCode.UP: 8145 this._keyEvent( "previous", event ); 8146 break; 8147 case keyCode.DOWN: 8148 this._keyEvent( "next", event ); 8149 break; 8150 } 8151 }, 8152 input: function( event ) { 8153 if ( suppressInput ) { 8154 suppressInput = false; 8155 event.preventDefault(); 8156 return; 8157 } 8158 this._searchTimeout( event ); 8159 }, 8160 focus: function() { 8161 this.selectedItem = null; 8162 this.previous = this._value(); 8163 }, 8164 blur: function( event ) { 8165 if ( this.cancelBlur ) { 8166 delete this.cancelBlur; 8167 return; 8168 } 8169 8170 clearTimeout( this.searching ); 8171 this.close( event ); 8172 this._change( event ); 8173 } 8174 } ); 8175 8176 this._initSource(); 8177 this.menu = $( "<ul>" ) 8178 .appendTo( this._appendTo() ) 8179 .menu( { 8180 8181 // disable ARIA support, the live region takes care of that 8182 role: null 8183 } ) 8184 .hide() 8185 .menu( "instance" ); 8186 8187 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 8188 this._on( this.menu.element, { 8189 mousedown: function( event ) { 8190 8191 // prevent moving focus out of the text field 8192 event.preventDefault(); 8193 8194 // IE doesn't prevent moving focus even with event.preventDefault() 8195 // so we set a flag to know when we should ignore the blur event 8196 this.cancelBlur = true; 8197 this._delay( function() { 8198 delete this.cancelBlur; 8199 8200 // Support: IE 8 only 8201 // Right clicking a menu item or selecting text from the menu items will 8202 // result in focus moving out of the input. However, we've already received 8203 // and ignored the blur event because of the cancelBlur flag set above. So 8204 // we restore focus to ensure that the menu closes properly based on the user's 8205 // next actions. 8206 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 8207 this.element.trigger( "focus" ); 8208 } 8209 } ); 8210 }, 8211 menufocus: function( event, ui ) { 8212 var label, item; 8213 8214 // support: Firefox 8215 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 8216 if ( this.isNewMenu ) { 8217 this.isNewMenu = false; 8218 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 8219 this.menu.blur(); 8220 8221 this.document.one( "mousemove", function() { 8222 $( event.target ).trigger( event.originalEvent ); 8223 } ); 8224 8225 return; 8226 } 8227 } 8228 8229 item = ui.item.data( "ui-autocomplete-item" ); 8230 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 8231 8232 // use value to match what will end up in the input, if it was a key event 8233 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 8234 this._value( item.value ); 8235 } 8236 } 8237 8238 // Announce the value in the liveRegion 8239 label = ui.item.attr( "aria-label" ) || item.value; 8240 if ( label && $.trim( label ).length ) { 8241 this.liveRegion.children().hide(); 8242 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 8243 } 8244 }, 8245 menuselect: function( event, ui ) { 8246 var item = ui.item.data( "ui-autocomplete-item" ), 8247 previous = this.previous; 8248 8249 // Only trigger when focus was lost (click on menu) 8250 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 8251 this.element.trigger( "focus" ); 8252 this.previous = previous; 8253 8254 // #6109 - IE triggers two focus events and the second 8255 // is asynchronous, so we need to reset the previous 8256 // term synchronously and asynchronously :-( 8257 this._delay( function() { 8258 this.previous = previous; 8259 this.selectedItem = item; 8260 } ); 8261 } 8262 8263 if ( false !== this._trigger( "select", event, { item: item } ) ) { 8264 this._value( item.value ); 8265 } 8266 8267 // reset the term after the select event 8268 // this allows custom select handling to work properly 8269 this.term = this._value(); 8270 8271 this.close( event ); 8272 this.selectedItem = item; 8273 } 8274 } ); 8275 8276 this.liveRegion = $( "<div>", { 8277 role: "status", 8278 "aria-live": "assertive", 8279 "aria-relevant": "additions" 8280 } ) 8281 .appendTo( this.document[ 0 ].body ); 8282 8283 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 8284 8285 // Turning off autocomplete prevents the browser from remembering the 8286 // value when navigating through history, so we re-enable autocomplete 8287 // if the page is unloaded before the widget is destroyed. #7790 8288 this._on( this.window, { 8289 beforeunload: function() { 8290 this.element.removeAttr( "autocomplete" ); 8291 } 8292 } ); 8293 }, 8294 8295 _destroy: function() { 8296 clearTimeout( this.searching ); 8297 this.element.removeAttr( "autocomplete" ); 8298 this.menu.element.remove(); 8299 this.liveRegion.remove(); 8300 }, 8301 8302 _setOption: function( key, value ) { 8303 this._super( key, value ); 8304 if ( key === "source" ) { 8305 this._initSource(); 8306 } 8307 if ( key === "appendTo" ) { 8308 this.menu.element.appendTo( this._appendTo() ); 8309 } 8310 if ( key === "disabled" && value && this.xhr ) { 8311 this.xhr.abort(); 8312 } 8313 }, 8314 8315 _isEventTargetInWidget: function( event ) { 8316 var menuElement = this.menu.element[ 0 ]; 8317 8318 return event.target === this.element[ 0 ] || 8319 event.target === menuElement || 8320 $.contains( menuElement, event.target ); 8321 }, 8322 8323 _closeOnClickOutside: function( event ) { 8324 if ( !this._isEventTargetInWidget( event ) ) { 8325 this.close(); 8326 } 8327 }, 8328 8329 _appendTo: function() { 8330 var element = this.options.appendTo; 8331 8332 if ( element ) { 8333 element = element.jquery || element.nodeType ? 8334 $( element ) : 8335 this.document.find( element ).eq( 0 ); 8336 } 8337 8338 if ( !element || !element[ 0 ] ) { 8339 element = this.element.closest( ".ui-front, dialog" ); 8340 } 8341 8342 if ( !element.length ) { 8343 element = this.document[ 0 ].body; 8344 } 8345 8346 return element; 8347 }, 8348 8349 _initSource: function() { 8350 var array, url, 8351 that = this; 8352 if ( $.isArray( this.options.source ) ) { 8353 array = this.options.source; 8354 this.source = function( request, response ) { 8355 response( $.ui.autocomplete.filter( array, request.term ) ); 8356 }; 8357 } else if ( typeof this.options.source === "string" ) { 8358 url = this.options.source; 8359 this.source = function( request, response ) { 8360 if ( that.xhr ) { 8361 that.xhr.abort(); 8362 } 8363 that.xhr = $.ajax( { 8364 url: url, 8365 data: request, 8366 dataType: "json", 8367 success: function( data ) { 8368 response( data ); 8369 }, 8370 error: function() { 8371 response( [] ); 8372 } 8373 } ); 8374 }; 8375 } else { 8376 this.source = this.options.source; 8377 } 8378 }, 8379 8380 _searchTimeout: function( event ) { 8381 clearTimeout( this.searching ); 8382 this.searching = this._delay( function() { 8383 8384 // Search if the value has changed, or if the user retypes the same value (see #7434) 8385 var equalValues = this.term === this._value(), 8386 menuVisible = this.menu.element.is( ":visible" ), 8387 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 8388 8389 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 8390 this.selectedItem = null; 8391 this.search( null, event ); 8392 } 8393 }, this.options.delay ); 8394 }, 8395 8396 search: function( value, event ) { 8397 value = value != null ? value : this._value(); 8398 8399 // Always save the actual value, not the one passed as an argument 8400 this.term = this._value(); 8401 8402 if ( value.length < this.options.minLength ) { 8403 return this.close( event ); 8404 } 8405 8406 if ( this._trigger( "search", event ) === false ) { 8407 return; 8408 } 8409 8410 return this._search( value ); 8411 }, 8412 8413 _search: function( value ) { 8414 this.pending++; 8415 this._addClass( "ui-autocomplete-loading" ); 8416 this.cancelSearch = false; 8417 8418 this.source( { term: value }, this._response() ); 8419 }, 8420 8421 _response: function() { 8422 var index = ++this.requestIndex; 8423 8424 return $.proxy( function( content ) { 8425 if ( index === this.requestIndex ) { 8426 this.__response( content ); 8427 } 8428 8429 this.pending--; 8430 if ( !this.pending ) { 8431 this._removeClass( "ui-autocomplete-loading" ); 8432 } 8433 }, this ); 8434 }, 8435 8436 __response: function( content ) { 8437 if ( content ) { 8438 content = this._normalize( content ); 8439 } 8440 this._trigger( "response", null, { content: content } ); 8441 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 8442 this._suggest( content ); 8443 this._trigger( "open" ); 8444 } else { 8445 8446 // use ._close() instead of .close() so we don't cancel future searches 8447 this._close(); 8448 } 8449 }, 8450 8451 close: function( event ) { 8452 this.cancelSearch = true; 8453 this._close( event ); 8454 }, 8455 8456 _close: function( event ) { 8457 8458 // Remove the handler that closes the menu on outside clicks 8459 this._off( this.document, "mousedown" ); 8460 8461 if ( this.menu.element.is( ":visible" ) ) { 8462 this.menu.element.hide(); 8463 this.menu.blur(); 8464 this.isNewMenu = true; 8465 this._trigger( "close", event ); 8466 } 8467 }, 8468 8469 _change: function( event ) { 8470 if ( this.previous !== this._value() ) { 8471 this._trigger( "change", event, { item: this.selectedItem } ); 8472 } 8473 }, 8474 8475 _normalize: function( items ) { 8476 8477 // assume all items have the right format when the first item is complete 8478 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 8479 return items; 8480 } 8481 return $.map( items, function( item ) { 8482 if ( typeof item === "string" ) { 8483 return { 8484 label: item, 8485 value: item 8486 }; 8487 } 8488 return $.extend( {}, item, { 8489 label: item.label || item.value, 8490 value: item.value || item.label 8491 } ); 8492 } ); 8493 }, 8494 8495 _suggest: function( items ) { 8496 var ul = this.menu.element.empty(); 8497 this._renderMenu( ul, items ); 8498 this.isNewMenu = true; 8499 this.menu.refresh(); 8500 8501 // Size and position menu 8502 ul.show(); 8503 this._resizeMenu(); 8504 ul.position( $.extend( { 8505 of: this.element 8506 }, this.options.position ) ); 8507 8508 if ( this.options.autoFocus ) { 8509 this.menu.next(); 8510 } 8511 8512 // Listen for interactions outside of the widget (#6642) 8513 this._on( this.document, { 8514 mousedown: "_closeOnClickOutside" 8515 } ); 8516 }, 8517 8518 _resizeMenu: function() { 8519 var ul = this.menu.element; 8520 ul.outerWidth( Math.max( 8521 8522 // Firefox wraps long text (possibly a rounding bug) 8523 // so we add 1px to avoid the wrapping (#7513) 8524 ul.width( "" ).outerWidth() + 1, 8525 this.element.outerWidth() 8526 ) ); 8527 }, 8528 8529 _renderMenu: function( ul, items ) { 8530 var that = this; 8531 $.each( items, function( index, item ) { 8532 that._renderItemData( ul, item ); 8533 } ); 8534 }, 8535 8536 _renderItemData: function( ul, item ) { 8537 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 8538 }, 8539 8540 _renderItem: function( ul, item ) { 8541 return $( "<li>" ) 8542 .append( $( "<div>" ).text( item.label ) ) 8543 .appendTo( ul ); 8544 }, 8545 8546 _move: function( direction, event ) { 8547 if ( !this.menu.element.is( ":visible" ) ) { 8548 this.search( null, event ); 8549 return; 8550 } 8551 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 8552 this.menu.isLastItem() && /^next/.test( direction ) ) { 8553 8554 if ( !this.isMultiLine ) { 8555 this._value( this.term ); 8556 } 8557 8558 this.menu.blur(); 8559 return; 8560 } 8561 this.menu[ direction ]( event ); 8562 }, 8563 8564 widget: function() { 8565 return this.menu.element; 8566 }, 8567 8568 _value: function() { 8569 return this.valueMethod.apply( this.element, arguments ); 8570 }, 8571 8572 _keyEvent: function( keyEvent, event ) { 8573 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 8574 this._move( keyEvent, event ); 8575 8576 // Prevents moving cursor to beginning/end of the text field in some browsers 8577 event.preventDefault(); 8578 } 8579 }, 8580 8581 // Support: Chrome <=50 8582 // We should be able to just use this.element.prop( "isContentEditable" ) 8583 // but hidden elements always report false in Chrome. 8584 // https://code.google.com/p/chromium/issues/detail?id=313082 8585 _isContentEditable: function( element ) { 8586 if ( !element.length ) { 8587 return false; 8588 } 8589 8590 var editable = element.prop( "contentEditable" ); 8591 8592 if ( editable === "inherit" ) { 8593 return this._isContentEditable( element.parent() ); 8594 } 8595 8596 return editable === "true"; 8597 } 8598} ); 8599 8600$.extend( $.ui.autocomplete, { 8601 escapeRegex: function( value ) { 8602 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 8603 }, 8604 filter: function( array, term ) { 8605 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 8606 return $.grep( array, function( value ) { 8607 return matcher.test( value.label || value.value || value ); 8608 } ); 8609 } 8610} ); 8611 8612// Live region extension, adding a `messages` option 8613// NOTE: This is an experimental API. We are still investigating 8614// a full solution for string manipulation and internationalization. 8615$.widget( "ui.autocomplete", $.ui.autocomplete, { 8616 options: { 8617 messages: { 8618 noResults: "No search results.", 8619 results: function( amount ) { 8620 return amount + ( amount > 1 ? " results are" : " result is" ) + 8621 " available, use up and down arrow keys to navigate."; 8622 } 8623 } 8624 }, 8625 8626 __response: function( content ) { 8627 var message; 8628 this._superApply( arguments ); 8629 if ( this.options.disabled || this.cancelSearch ) { 8630 return; 8631 } 8632 if ( content && content.length ) { 8633 message = this.options.messages.results( content.length ); 8634 } else { 8635 message = this.options.messages.noResults; 8636 } 8637 this.liveRegion.children().hide(); 8638 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 8639 } 8640} ); 8641 8642var widgetsAutocomplete = $.ui.autocomplete; 8643 8644 8645/*! 8646 * jQuery UI Controlgroup 1.12.1 8647 * http://jqueryui.com 8648 * 8649 * Copyright jQuery Foundation and other contributors 8650 * Released under the MIT license. 8651 * http://jquery.org/license 8652 */ 8653 8654//>>label: Controlgroup 8655//>>group: Widgets 8656//>>description: Visually groups form control widgets 8657//>>docs: http://api.jqueryui.com/controlgroup/ 8658//>>demos: http://jqueryui.com/controlgroup/ 8659//>>css.structure: ../../themes/base/core.css 8660//>>css.structure: ../../themes/base/controlgroup.css 8661//>>css.theme: ../../themes/base/theme.css 8662 8663 8664var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 8665 8666var widgetsControlgroup = $.widget( "ui.controlgroup", { 8667 version: "1.12.1", 8668 defaultElement: "<div>", 8669 options: { 8670 direction: "horizontal", 8671 disabled: null, 8672 onlyVisible: true, 8673 items: { 8674 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 8675 "controlgroupLabel": ".ui-controlgroup-label", 8676 "checkboxradio": "input[type='checkbox'], input[type='radio']", 8677 "selectmenu": "select", 8678 "spinner": ".ui-spinner-input" 8679 } 8680 }, 8681 8682 _create: function() { 8683 this._enhance(); 8684 }, 8685 8686 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 8687 _enhance: function() { 8688 this.element.attr( "role", "toolbar" ); 8689 this.refresh(); 8690 }, 8691 8692 _destroy: function() { 8693 this._callChildMethod( "destroy" ); 8694 this.childWidgets.removeData( "ui-controlgroup-data" ); 8695 this.element.removeAttr( "role" ); 8696 if ( this.options.items.controlgroupLabel ) { 8697 this.element 8698 .find( this.options.items.controlgroupLabel ) 8699 .find( ".ui-controlgroup-label-contents" ) 8700 .contents().unwrap(); 8701 } 8702 }, 8703 8704 _initWidgets: function() { 8705 var that = this, 8706 childWidgets = []; 8707 8708 // First we iterate over each of the items options 8709 $.each( this.options.items, function( widget, selector ) { 8710 var labels; 8711 var options = {}; 8712 8713 // Make sure the widget has a selector set 8714 if ( !selector ) { 8715 return; 8716 } 8717 8718 if ( widget === "controlgroupLabel" ) { 8719 labels = that.element.find( selector ); 8720 labels.each( function() { 8721 var element = $( this ); 8722 8723 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 8724 return; 8725 } 8726 element.contents() 8727 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 8728 } ); 8729 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 8730 childWidgets = childWidgets.concat( labels.get() ); 8731 return; 8732 } 8733 8734 // Make sure the widget actually exists 8735 if ( !$.fn[ widget ] ) { 8736 return; 8737 } 8738 8739 // We assume everything is in the middle to start because we can't determine 8740 // first / last elements until all enhancments are done. 8741 if ( that[ "_" + widget + "Options" ] ) { 8742 options = that[ "_" + widget + "Options" ]( "middle" ); 8743 } else { 8744 options = { classes: {} }; 8745 } 8746 8747 // Find instances of this widget inside controlgroup and init them 8748 that.element 8749 .find( selector ) 8750 .each( function() { 8751 var element = $( this ); 8752 var instance = element[ widget ]( "instance" ); 8753 8754 // We need to clone the default options for this type of widget to avoid 8755 // polluting the variable options which has a wider scope than a single widget. 8756 var instanceOptions = $.widget.extend( {}, options ); 8757 8758 // If the button is the child of a spinner ignore it 8759 // TODO: Find a more generic solution 8760 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 8761 return; 8762 } 8763 8764 // Create the widget if it doesn't exist 8765 if ( !instance ) { 8766 instance = element[ widget ]()[ widget ]( "instance" ); 8767 } 8768 if ( instance ) { 8769 instanceOptions.classes = 8770 that._resolveClassesValues( instanceOptions.classes, instance ); 8771 } 8772 element[ widget ]( instanceOptions ); 8773 8774 // Store an instance of the controlgroup to be able to reference 8775 // from the outermost element for changing options and refresh 8776 var widgetElement = element[ widget ]( "widget" ); 8777 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 8778 instance ? instance : element[ widget ]( "instance" ) ); 8779 8780 childWidgets.push( widgetElement[ 0 ] ); 8781 } ); 8782 } ); 8783 8784 this.childWidgets = $( $.unique( childWidgets ) ); 8785 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 8786 }, 8787 8788 _callChildMethod: function( method ) { 8789 this.childWidgets.each( function() { 8790 var element = $( this ), 8791 data = element.data( "ui-controlgroup-data" ); 8792 if ( data && data[ method ] ) { 8793 data[ method ](); 8794 } 8795 } ); 8796 }, 8797 8798 _updateCornerClass: function( element, position ) { 8799 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 8800 var add = this._buildSimpleOptions( position, "label" ).classes.label; 8801 8802 this._removeClass( element, null, remove ); 8803 this._addClass( element, null, add ); 8804 }, 8805 8806 _buildSimpleOptions: function( position, key ) { 8807 var direction = this.options.direction === "vertical"; 8808 var result = { 8809 classes: {} 8810 }; 8811 result.classes[ key ] = { 8812 "middle": "", 8813 "first": "ui-corner-" + ( direction ? "top" : "left" ), 8814 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 8815 "only": "ui-corner-all" 8816 }[ position ]; 8817 8818 return result; 8819 }, 8820 8821 _spinnerOptions: function( position ) { 8822 var options = this._buildSimpleOptions( position, "ui-spinner" ); 8823 8824 options.classes[ "ui-spinner-up" ] = ""; 8825 options.classes[ "ui-spinner-down" ] = ""; 8826 8827 return options; 8828 }, 8829 8830 _buttonOptions: function( position ) { 8831 return this._buildSimpleOptions( position, "ui-button" ); 8832 }, 8833 8834 _checkboxradioOptions: function( position ) { 8835 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 8836 }, 8837 8838 _selectmenuOptions: function( position ) { 8839 var direction = this.options.direction === "vertical"; 8840 return { 8841 width: direction ? "auto" : false, 8842 classes: { 8843 middle: { 8844 "ui-selectmenu-button-open": "", 8845 "ui-selectmenu-button-closed": "" 8846 }, 8847 first: { 8848 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 8849 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 8850 }, 8851 last: { 8852 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 8853 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 8854 }, 8855 only: { 8856 "ui-selectmenu-button-open": "ui-corner-top", 8857 "ui-selectmenu-button-closed": "ui-corner-all" 8858 } 8859 8860 }[ position ] 8861 }; 8862 }, 8863 8864 _resolveClassesValues: function( classes, instance ) { 8865 var result = {}; 8866 $.each( classes, function( key ) { 8867 var current = instance.options.classes[ key ] || ""; 8868 current = $.trim( current.replace( controlgroupCornerRegex, "" ) ); 8869 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 8870 } ); 8871 return result; 8872 }, 8873 8874 _setOption: function( key, value ) { 8875 if ( key === "direction" ) { 8876 this._removeClass( "ui-controlgroup-" + this.options.direction ); 8877 } 8878 8879 this._super( key, value ); 8880 if ( key === "disabled" ) { 8881 this._callChildMethod( value ? "disable" : "enable" ); 8882 return; 8883 } 8884 8885 this.refresh(); 8886 }, 8887 8888 refresh: function() { 8889 var children, 8890 that = this; 8891 8892 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 8893 8894 if ( this.options.direction === "horizontal" ) { 8895 this._addClass( null, "ui-helper-clearfix" ); 8896 } 8897 this._initWidgets(); 8898 8899 children = this.childWidgets; 8900 8901 // We filter here because we need to track all childWidgets not just the visible ones 8902 if ( this.options.onlyVisible ) { 8903 children = children.filter( ":visible" ); 8904 } 8905 8906 if ( children.length ) { 8907 8908 // We do this last because we need to make sure all enhancment is done 8909 // before determining first and last 8910 $.each( [ "first", "last" ], function( index, value ) { 8911 var instance = children[ value ]().data( "ui-controlgroup-data" ); 8912 8913 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 8914 var options = that[ "_" + instance.widgetName + "Options" ]( 8915 children.length === 1 ? "only" : value 8916 ); 8917 options.classes = that._resolveClassesValues( options.classes, instance ); 8918 instance.element[ instance.widgetName ]( options ); 8919 } else { 8920 that._updateCornerClass( children[ value ](), value ); 8921 } 8922 } ); 8923 8924 // Finally call the refresh method on each of the child widgets. 8925 this._callChildMethod( "refresh" ); 8926 } 8927 } 8928} ); 8929 8930/*! 8931 * jQuery UI Checkboxradio 1.12.1 8932 * http://jqueryui.com 8933 * 8934 * Copyright jQuery Foundation and other contributors 8935 * Released under the MIT license. 8936 * http://jquery.org/license 8937 */ 8938 8939//>>label: Checkboxradio 8940//>>group: Widgets 8941//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 8942//>>docs: http://api.jqueryui.com/checkboxradio/ 8943//>>demos: http://jqueryui.com/checkboxradio/ 8944//>>css.structure: ../../themes/base/core.css 8945//>>css.structure: ../../themes/base/button.css 8946//>>css.structure: ../../themes/base/checkboxradio.css 8947//>>css.theme: ../../themes/base/theme.css 8948 8949 8950 8951$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 8952 version: "1.12.1", 8953 options: { 8954 disabled: null, 8955 label: null, 8956 icon: true, 8957 classes: { 8958 "ui-checkboxradio-label": "ui-corner-all", 8959 "ui-checkboxradio-icon": "ui-corner-all" 8960 } 8961 }, 8962 8963 _getCreateOptions: function() { 8964 var disabled, labels; 8965 var that = this; 8966 var options = this._super() || {}; 8967 8968 // We read the type here, because it makes more sense to throw a element type error first, 8969 // rather then the error for lack of a label. Often if its the wrong type, it 8970 // won't have a label (e.g. calling on a div, btn, etc) 8971 this._readType(); 8972 8973 labels = this.element.labels(); 8974 8975 // If there are multiple labels, use the last one 8976 this.label = $( labels[ labels.length - 1 ] ); 8977 if ( !this.label.length ) { 8978 $.error( "No label found for checkboxradio widget" ); 8979 } 8980 8981 this.originalLabel = ""; 8982 8983 // We need to get the label text but this may also need to make sure it does not contain the 8984 // input itself. 8985 this.label.contents().not( this.element[ 0 ] ).each( function() { 8986 8987 // The label contents could be text, html, or a mix. We concat each element to get a 8988 // string representation of the label, without the input as part of it. 8989 that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; 8990 } ); 8991 8992 // Set the label option if we found label text 8993 if ( this.originalLabel ) { 8994 options.label = this.originalLabel; 8995 } 8996 8997 disabled = this.element[ 0 ].disabled; 8998 if ( disabled != null ) { 8999 options.disabled = disabled; 9000 } 9001 return options; 9002 }, 9003 9004 _create: function() { 9005 var checked = this.element[ 0 ].checked; 9006 9007 this._bindFormResetHandler(); 9008 9009 if ( this.options.disabled == null ) { 9010 this.options.disabled = this.element[ 0 ].disabled; 9011 } 9012 9013 this._setOption( "disabled", this.options.disabled ); 9014 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 9015 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 9016 9017 if ( this.type === "radio" ) { 9018 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 9019 } 9020 9021 if ( this.options.label && this.options.label !== this.originalLabel ) { 9022 this._updateLabel(); 9023 } else if ( this.originalLabel ) { 9024 this.options.label = this.originalLabel; 9025 } 9026 9027 this._enhance(); 9028 9029 if ( checked ) { 9030 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 9031 if ( this.icon ) { 9032 this._addClass( this.icon, null, "ui-state-hover" ); 9033 } 9034 } 9035 9036 this._on( { 9037 change: "_toggleClasses", 9038 focus: function() { 9039 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9040 }, 9041 blur: function() { 9042 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 9043 } 9044 } ); 9045 }, 9046 9047 _readType: function() { 9048 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 9049 this.type = this.element[ 0 ].type; 9050 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 9051 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 9052 " and element.type=" + this.type ); 9053 } 9054 }, 9055 9056 // Support jQuery Mobile enhanced option 9057 _enhance: function() { 9058 this._updateIcon( this.element[ 0 ].checked ); 9059 }, 9060 9061 widget: function() { 9062 return this.label; 9063 }, 9064 9065 _getRadioGroup: function() { 9066 var group; 9067 var name = this.element[ 0 ].name; 9068 var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']"; 9069 9070 if ( !name ) { 9071 return $( [] ); 9072 } 9073 9074 if ( this.form.length ) { 9075 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 9076 } else { 9077 9078 // Not inside a form, check all inputs that also are not inside a form 9079 group = $( nameSelector ).filter( function() { 9080 return $( this ).form().length === 0; 9081 } ); 9082 } 9083 9084 return group.not( this.element ); 9085 }, 9086 9087 _toggleClasses: function() { 9088 var checked = this.element[ 0 ].checked; 9089 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9090 9091 if ( this.options.icon && this.type === "checkbox" ) { 9092 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 9093 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 9094 } 9095 9096 if ( this.type === "radio" ) { 9097 this._getRadioGroup() 9098 .each( function() { 9099 var instance = $( this ).checkboxradio( "instance" ); 9100 9101 if ( instance ) { 9102 instance._removeClass( instance.label, 9103 "ui-checkboxradio-checked", "ui-state-active" ); 9104 } 9105 } ); 9106 } 9107 }, 9108 9109 _destroy: function() { 9110 this._unbindFormResetHandler(); 9111 9112 if ( this.icon ) { 9113 this.icon.remove(); 9114 this.iconSpace.remove(); 9115 } 9116 }, 9117 9118 _setOption: function( key, value ) { 9119 9120 // We don't allow the value to be set to nothing 9121 if ( key === "label" && !value ) { 9122 return; 9123 } 9124 9125 this._super( key, value ); 9126 9127 if ( key === "disabled" ) { 9128 this._toggleClass( this.label, null, "ui-state-disabled", value ); 9129 this.element[ 0 ].disabled = value; 9130 9131 // Don't refresh when setting disabled 9132 return; 9133 } 9134 this.refresh(); 9135 }, 9136 9137 _updateIcon: function( checked ) { 9138 var toAdd = "ui-icon ui-icon-background "; 9139 9140 if ( this.options.icon ) { 9141 if ( !this.icon ) { 9142 this.icon = $( "<span>" ); 9143 this.iconSpace = $( "<span> </span>" ); 9144 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 9145 } 9146 9147 if ( this.type === "checkbox" ) { 9148 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 9149 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 9150 } else { 9151 toAdd += "ui-icon-blank"; 9152 } 9153 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 9154 if ( !checked ) { 9155 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 9156 } 9157 this.icon.prependTo( this.label ).after( this.iconSpace ); 9158 } else if ( this.icon !== undefined ) { 9159 this.icon.remove(); 9160 this.iconSpace.remove(); 9161 delete this.icon; 9162 } 9163 }, 9164 9165 _updateLabel: function() { 9166 9167 // Remove the contents of the label ( minus the icon, icon space, and input ) 9168 var contents = this.label.contents().not( this.element[ 0 ] ); 9169 if ( this.icon ) { 9170 contents = contents.not( this.icon[ 0 ] ); 9171 } 9172 if ( this.iconSpace ) { 9173 contents = contents.not( this.iconSpace[ 0 ] ); 9174 } 9175 contents.remove(); 9176 9177 this.label.append( this.options.label ); 9178 }, 9179 9180 refresh: function() { 9181 var checked = this.element[ 0 ].checked, 9182 isDisabled = this.element[ 0 ].disabled; 9183 9184 this._updateIcon( checked ); 9185 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 9186 if ( this.options.label !== null ) { 9187 this._updateLabel(); 9188 } 9189 9190 if ( isDisabled !== this.options.disabled ) { 9191 this._setOptions( { "disabled": isDisabled } ); 9192 } 9193 } 9194 9195} ] ); 9196 9197var widgetsCheckboxradio = $.ui.checkboxradio; 9198 9199 9200/*! 9201 * jQuery UI Button 1.12.1 9202 * http://jqueryui.com 9203 * 9204 * Copyright jQuery Foundation and other contributors 9205 * Released under the MIT license. 9206 * http://jquery.org/license 9207 */ 9208 9209//>>label: Button 9210//>>group: Widgets 9211//>>description: Enhances a form with themeable buttons. 9212//>>docs: http://api.jqueryui.com/button/ 9213//>>demos: http://jqueryui.com/button/ 9214//>>css.structure: ../../themes/base/core.css 9215//>>css.structure: ../../themes/base/button.css 9216//>>css.theme: ../../themes/base/theme.css 9217 9218 9219 9220$.widget( "ui.button", { 9221 version: "1.12.1", 9222 defaultElement: "<button>", 9223 options: { 9224 classes: { 9225 "ui-button": "ui-corner-all" 9226 }, 9227 disabled: null, 9228 icon: null, 9229 iconPosition: "beginning", 9230 label: null, 9231 showLabel: true 9232 }, 9233 9234 _getCreateOptions: function() { 9235 var disabled, 9236 9237 // This is to support cases like in jQuery Mobile where the base widget does have 9238 // an implementation of _getCreateOptions 9239 options = this._super() || {}; 9240 9241 this.isInput = this.element.is( "input" ); 9242 9243 disabled = this.element[ 0 ].disabled; 9244 if ( disabled != null ) { 9245 options.disabled = disabled; 9246 } 9247 9248 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 9249 if ( this.originalLabel ) { 9250 options.label = this.originalLabel; 9251 } 9252 9253 return options; 9254 }, 9255 9256 _create: function() { 9257 if ( !this.option.showLabel & !this.options.icon ) { 9258 this.options.showLabel = true; 9259 } 9260 9261 // We have to check the option again here even though we did in _getCreateOptions, 9262 // because null may have been passed on init which would override what was set in 9263 // _getCreateOptions 9264 if ( this.options.disabled == null ) { 9265 this.options.disabled = this.element[ 0 ].disabled || false; 9266 } 9267 9268 this.hasTitle = !!this.element.attr( "title" ); 9269 9270 // Check to see if the label needs to be set or if its already correct 9271 if ( this.options.label && this.options.label !== this.originalLabel ) { 9272 if ( this.isInput ) { 9273 this.element.val( this.options.label ); 9274 } else { 9275 this.element.html( this.options.label ); 9276 } 9277 } 9278 this._addClass( "ui-button", "ui-widget" ); 9279 this._setOption( "disabled", this.options.disabled ); 9280 this._enhance(); 9281 9282 if ( this.element.is( "a" ) ) { 9283 this._on( { 9284 "keyup": function( event ) { 9285 if ( event.keyCode === $.ui.keyCode.SPACE ) { 9286 event.preventDefault(); 9287 9288 // Support: PhantomJS <= 1.9, IE 8 Only 9289 // If a native click is available use it so we actually cause navigation 9290 // otherwise just trigger a click event 9291 if ( this.element[ 0 ].click ) { 9292 this.element[ 0 ].click(); 9293 } else { 9294 this.element.trigger( "click" ); 9295 } 9296 } 9297 } 9298 } ); 9299 } 9300 }, 9301 9302 _enhance: function() { 9303 if ( !this.element.is( "button" ) ) { 9304 this.element.attr( "role", "button" ); 9305 } 9306 9307 if ( this.options.icon ) { 9308 this._updateIcon( "icon", this.options.icon ); 9309 this._updateTooltip(); 9310 } 9311 }, 9312 9313 _updateTooltip: function() { 9314 this.title = this.element.attr( "title" ); 9315 9316 if ( !this.options.showLabel && !this.title ) { 9317 this.element.attr( "title", this.options.label ); 9318 } 9319 }, 9320 9321 _updateIcon: function( option, value ) { 9322 var icon = option !== "iconPosition", 9323 position = icon ? this.options.iconPosition : value, 9324 displayBlock = position === "top" || position === "bottom"; 9325 9326 // Create icon 9327 if ( !this.icon ) { 9328 this.icon = $( "<span>" ); 9329 9330 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 9331 9332 if ( !this.options.showLabel ) { 9333 this._addClass( "ui-button-icon-only" ); 9334 } 9335 } else if ( icon ) { 9336 9337 // If we are updating the icon remove the old icon class 9338 this._removeClass( this.icon, null, this.options.icon ); 9339 } 9340 9341 // If we are updating the icon add the new icon class 9342 if ( icon ) { 9343 this._addClass( this.icon, null, value ); 9344 } 9345 9346 this._attachIcon( position ); 9347 9348 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 9349 // the iconSpace if there is one. 9350 if ( displayBlock ) { 9351 this._addClass( this.icon, null, "ui-widget-icon-block" ); 9352 if ( this.iconSpace ) { 9353 this.iconSpace.remove(); 9354 } 9355 } else { 9356 9357 // Position is beginning or end so remove the ui-widget-icon-block class and add the 9358 // space if it does not exist 9359 if ( !this.iconSpace ) { 9360 this.iconSpace = $( "<span> </span>" ); 9361 this._addClass( this.iconSpace, "ui-button-icon-space" ); 9362 } 9363 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 9364 this._attachIconSpace( position ); 9365 } 9366 }, 9367 9368 _destroy: function() { 9369 this.element.removeAttr( "role" ); 9370 9371 if ( this.icon ) { 9372 this.icon.remove(); 9373 } 9374 if ( this.iconSpace ) { 9375 this.iconSpace.remove(); 9376 } 9377 if ( !this.hasTitle ) { 9378 this.element.removeAttr( "title" ); 9379 } 9380 }, 9381 9382 _attachIconSpace: function( iconPosition ) { 9383 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 9384 }, 9385 9386 _attachIcon: function( iconPosition ) { 9387 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 9388 }, 9389 9390 _setOptions: function( options ) { 9391 var newShowLabel = options.showLabel === undefined ? 9392 this.options.showLabel : 9393 options.showLabel, 9394 newIcon = options.icon === undefined ? this.options.icon : options.icon; 9395 9396 if ( !newShowLabel && !newIcon ) { 9397 options.showLabel = true; 9398 } 9399 this._super( options ); 9400 }, 9401 9402 _setOption: function( key, value ) { 9403 if ( key === "icon" ) { 9404 if ( value ) { 9405 this._updateIcon( key, value ); 9406 } else if ( this.icon ) { 9407 this.icon.remove(); 9408 if ( this.iconSpace ) { 9409 this.iconSpace.remove(); 9410 } 9411 } 9412 } 9413 9414 if ( key === "iconPosition" ) { 9415 this._updateIcon( key, value ); 9416 } 9417 9418 // Make sure we can't end up with a button that has neither text nor icon 9419 if ( key === "showLabel" ) { 9420 this._toggleClass( "ui-button-icon-only", null, !value ); 9421 this._updateTooltip(); 9422 } 9423 9424 if ( key === "label" ) { 9425 if ( this.isInput ) { 9426 this.element.val( value ); 9427 } else { 9428 9429 // If there is an icon, append it, else nothing then append the value 9430 // this avoids removal of the icon when setting label text 9431 this.element.html( value ); 9432 if ( this.icon ) { 9433 this._attachIcon( this.options.iconPosition ); 9434 this._attachIconSpace( this.options.iconPosition ); 9435 } 9436 } 9437 } 9438 9439 this._super( key, value ); 9440 9441 if ( key === "disabled" ) { 9442 this._toggleClass( null, "ui-state-disabled", value ); 9443 this.element[ 0 ].disabled = value; 9444 if ( value ) { 9445 this.element.blur(); 9446 } 9447 } 9448 }, 9449 9450 refresh: function() { 9451 9452 // Make sure to only check disabled if its an element that supports this otherwise 9453 // check for the disabled class to determine state 9454 var isDisabled = this.element.is( "input, button" ) ? 9455 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 9456 9457 if ( isDisabled !== this.options.disabled ) { 9458 this._setOptions( { disabled: isDisabled } ); 9459 } 9460 9461 this._updateTooltip(); 9462 } 9463} ); 9464 9465// DEPRECATED 9466if ( $.uiBackCompat !== false ) { 9467 9468 // Text and Icons options 9469 $.widget( "ui.button", $.ui.button, { 9470 options: { 9471 text: true, 9472 icons: { 9473 primary: null, 9474 secondary: null 9475 } 9476 }, 9477 9478 _create: function() { 9479 if ( this.options.showLabel && !this.options.text ) { 9480 this.options.showLabel = this.options.text; 9481 } 9482 if ( !this.options.showLabel && this.options.text ) { 9483 this.options.text = this.options.showLabel; 9484 } 9485 if ( !this.options.icon && ( this.options.icons.primary || 9486 this.options.icons.secondary ) ) { 9487 if ( this.options.icons.primary ) { 9488 this.options.icon = this.options.icons.primary; 9489 } else { 9490 this.options.icon = this.options.icons.secondary; 9491 this.options.iconPosition = "end"; 9492 } 9493 } else if ( this.options.icon ) { 9494 this.options.icons.primary = this.options.icon; 9495 } 9496 this._super(); 9497 }, 9498 9499 _setOption: function( key, value ) { 9500 if ( key === "text" ) { 9501 this._super( "showLabel", value ); 9502 return; 9503 } 9504 if ( key === "showLabel" ) { 9505 this.options.text = value; 9506 } 9507 if ( key === "icon" ) { 9508 this.options.icons.primary = value; 9509 } 9510 if ( key === "icons" ) { 9511 if ( value.primary ) { 9512 this._super( "icon", value.primary ); 9513 this._super( "iconPosition", "beginning" ); 9514 } else if ( value.secondary ) { 9515 this._super( "icon", value.secondary ); 9516 this._super( "iconPosition", "end" ); 9517 } 9518 } 9519 this._superApply( arguments ); 9520 } 9521 } ); 9522 9523 $.fn.button = ( function( orig ) { 9524 return function() { 9525 if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) || 9526 ( this.length && this[ 0 ].tagName === "INPUT" && ( 9527 this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio" 9528 ) ) ) { 9529 return orig.apply( this, arguments ); 9530 } 9531 if ( !$.ui.checkboxradio ) { 9532 $.error( "Checkboxradio widget missing" ); 9533 } 9534 if ( arguments.length === 0 ) { 9535 return this.checkboxradio( { 9536 "icon": false 9537 } ); 9538 } 9539 return this.checkboxradio.apply( this, arguments ); 9540 }; 9541 } )( $.fn.button ); 9542 9543 $.fn.buttonset = function() { 9544 if ( !$.ui.controlgroup ) { 9545 $.error( "Controlgroup widget missing" ); 9546 } 9547 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 9548 return this.controlgroup.apply( this, 9549 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 9550 } 9551 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 9552 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 9553 } 9554 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 9555 arguments[ 0 ].items = { 9556 button: arguments[ 0 ].items 9557 }; 9558 } 9559 return this.controlgroup.apply( this, arguments ); 9560 }; 9561} 9562 9563var widgetsButton = $.ui.button; 9564 9565 9566// jscs:disable maximumLineLength 9567/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */ 9568/*! 9569 * jQuery UI Datepicker 1.12.1 9570 * http://jqueryui.com 9571 * 9572 * Copyright jQuery Foundation and other contributors 9573 * Released under the MIT license. 9574 * http://jquery.org/license 9575 */ 9576 9577//>>label: Datepicker 9578//>>group: Widgets 9579//>>description: Displays a calendar from an input or inline for selecting dates. 9580//>>docs: http://api.jqueryui.com/datepicker/ 9581//>>demos: http://jqueryui.com/datepicker/ 9582//>>css.structure: ../../themes/base/core.css 9583//>>css.structure: ../../themes/base/datepicker.css 9584//>>css.theme: ../../themes/base/theme.css 9585 9586 9587 9588$.extend( $.ui, { datepicker: { version: "1.12.1" } } ); 9589 9590var datepicker_instActive; 9591 9592function datepicker_getZindex( elem ) { 9593 var position, value; 9594 while ( elem.length && elem[ 0 ] !== document ) { 9595 9596 // Ignore z-index if position is set to a value where z-index is ignored by the browser 9597 // This makes behavior of this function consistent across browsers 9598 // WebKit always returns auto if the element is positioned 9599 position = elem.css( "position" ); 9600 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 9601 9602 // IE returns 0 when zIndex is not specified 9603 // other browsers return a string 9604 // we ignore the case of nested elements with an explicit value of 0 9605 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 9606 value = parseInt( elem.css( "zIndex" ), 10 ); 9607 if ( !isNaN( value ) && value !== 0 ) { 9608 return value; 9609 } 9610 } 9611 elem = elem.parent(); 9612 } 9613 9614 return 0; 9615} 9616/* Date picker manager. 9617 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 9618 Settings for (groups of) date pickers are maintained in an instance object, 9619 allowing multiple different settings on the same page. */ 9620 9621function Datepicker() { 9622 this._curInst = null; // The current instance in use 9623 this._keyEvent = false; // If the last event was a key event 9624 this._disabledInputs = []; // List of date picker inputs that have been disabled 9625 this._datepickerShowing = false; // True if the popup picker is showing , false if not 9626 this._inDialog = false; // True if showing within a "dialog", false if not 9627 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 9628 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 9629 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 9630 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 9631 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 9632 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 9633 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 9634 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 9635 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 9636 this.regional = []; // Available regional settings, indexed by language code 9637 this.regional[ "" ] = { // Default regional settings 9638 closeText: "Done", // Display text for close link 9639 prevText: "Prev", // Display text for previous month link 9640 nextText: "Next", // Display text for next month link 9641 currentText: "Today", // Display text for current month link 9642 monthNames: [ "January","February","March","April","May","June", 9643 "July","August","September","October","November","December" ], // Names of months for drop-down and formatting 9644 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 9645 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 9646 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 9647 dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday 9648 weekHeader: "Wk", // Column header for week of the year 9649 dateFormat: "mm/dd/yy", // See format options on parseDate 9650 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 9651 isRTL: false, // True if right-to-left language, false if left-to-right 9652 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 9653 yearSuffix: "" // Additional text to append to the year in the month headers 9654 }; 9655 this._defaults = { // Global defaults for all the date picker instances 9656 showOn: "focus", // "focus" for popup on focus, 9657 // "button" for trigger button, or "both" for either 9658 showAnim: "fadeIn", // Name of jQuery animation for popup 9659 showOptions: {}, // Options for enhanced animations 9660 defaultDate: null, // Used when field is blank: actual date, 9661 // +/-number for offset from today, null for today 9662 appendText: "", // Display text following the input box, e.g. showing the format 9663 buttonText: "...", // Text for trigger button 9664 buttonImage: "", // URL for trigger button image 9665 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 9666 hideIfNoPrevNext: false, // True to hide next/previous month links 9667 // if not applicable, false to just disable them 9668 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 9669 gotoCurrent: false, // True if today link goes back to current selection instead 9670 changeMonth: false, // True if month can be selected directly, false if only prev/next 9671 changeYear: false, // True if year can be selected directly, false if only prev/next 9672 yearRange: "c-10:c+10", // Range of years to display in drop-down, 9673 // either relative to today's year (-nn:+nn), relative to currently displayed year 9674 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 9675 showOtherMonths: false, // True to show dates in other months, false to leave blank 9676 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 9677 showWeek: false, // True to show week of the year, false to not show it 9678 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 9679 // takes a Date and returns the number of the week for it 9680 shortYearCutoff: "+10", // Short year values < this are in the current century, 9681 // > this are in the previous century, 9682 // string value starting with "+" for current year + value 9683 minDate: null, // The earliest selectable date, or null for no limit 9684 maxDate: null, // The latest selectable date, or null for no limit 9685 duration: "fast", // Duration of display/closure 9686 beforeShowDay: null, // Function that takes a date and returns an array with 9687 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 9688 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 9689 beforeShow: null, // Function that takes an input field and 9690 // returns a set of custom settings for the date picker 9691 onSelect: null, // Define a callback function when a date is selected 9692 onChangeMonthYear: null, // Define a callback function when the month or year is changed 9693 onClose: null, // Define a callback function when the datepicker is closed 9694 numberOfMonths: 1, // Number of months to show at a time 9695 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 9696 stepMonths: 1, // Number of months to step back/forward 9697 stepBigMonths: 12, // Number of months to step back/forward for the big links 9698 altField: "", // Selector for an alternate field to store selected dates into 9699 altFormat: "", // The date format to use for the alternate field 9700 constrainInput: true, // The input is constrained by the current date format 9701 showButtonPanel: false, // True to show button panel, false to not show it 9702 autoSize: false, // True to size the input for the date format, false to leave as is 9703 disabled: false // The initial disabled state 9704 }; 9705 $.extend( this._defaults, this.regional[ "" ] ); 9706 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 9707 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 9708 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 9709} 9710 9711$.extend( Datepicker.prototype, { 9712 /* Class name added to elements to indicate already configured with a date picker. */ 9713 markerClassName: "hasDatepicker", 9714 9715 //Keep track of the maximum number of rows displayed (see #7043) 9716 maxRows: 4, 9717 9718 // TODO rename to "widget" when switching to widget factory 9719 _widgetDatepicker: function() { 9720 return this.dpDiv; 9721 }, 9722 9723 /* Override the default settings for all instances of the date picker. 9724 * @param settings object - the new settings to use as defaults (anonymous object) 9725 * @return the manager object 9726 */ 9727 setDefaults: function( settings ) { 9728 datepicker_extendRemove( this._defaults, settings || {} ); 9729 return this; 9730 }, 9731 9732 /* Attach the date picker to a jQuery selection. 9733 * @param target element - the target input field or division or span 9734 * @param settings object - the new settings to use for this date picker instance (anonymous) 9735 */ 9736 _attachDatepicker: function( target, settings ) { 9737 var nodeName, inline, inst; 9738 nodeName = target.nodeName.toLowerCase(); 9739 inline = ( nodeName === "div" || nodeName === "span" ); 9740 if ( !target.id ) { 9741 this.uuid += 1; 9742 target.id = "dp" + this.uuid; 9743 } 9744 inst = this._newInst( $( target ), inline ); 9745 inst.settings = $.extend( {}, settings || {} ); 9746 if ( nodeName === "input" ) { 9747 this._connectDatepicker( target, inst ); 9748 } else if ( inline ) { 9749 this._inlineDatepicker( target, inst ); 9750 } 9751 }, 9752 9753 /* Create a new instance object. */ 9754 _newInst: function( target, inline ) { 9755 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 9756 return { id: id, input: target, // associated target 9757 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 9758 drawMonth: 0, drawYear: 0, // month being drawn 9759 inline: inline, // is datepicker inline or not 9760 dpDiv: ( !inline ? this.dpDiv : // presentation div 9761 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 9762 }, 9763 9764 /* Attach the date picker to an input field. */ 9765 _connectDatepicker: function( target, inst ) { 9766 var input = $( target ); 9767 inst.append = $( [] ); 9768 inst.trigger = $( [] ); 9769 if ( input.hasClass( this.markerClassName ) ) { 9770 return; 9771 } 9772 this._attachments( input, inst ); 9773 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 9774 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 9775 this._autoSize( inst ); 9776 $.data( target, "datepicker", inst ); 9777 9778 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 9779 if ( inst.settings.disabled ) { 9780 this._disableDatepicker( target ); 9781 } 9782 }, 9783 9784 /* Make attachments based on settings. */ 9785 _attachments: function( input, inst ) { 9786 var showOn, buttonText, buttonImage, 9787 appendText = this._get( inst, "appendText" ), 9788 isRTL = this._get( inst, "isRTL" ); 9789 9790 if ( inst.append ) { 9791 inst.append.remove(); 9792 } 9793 if ( appendText ) { 9794 inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" ); 9795 input[ isRTL ? "before" : "after" ]( inst.append ); 9796 } 9797 9798 input.off( "focus", this._showDatepicker ); 9799 9800 if ( inst.trigger ) { 9801 inst.trigger.remove(); 9802 } 9803 9804 showOn = this._get( inst, "showOn" ); 9805 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 9806 input.on( "focus", this._showDatepicker ); 9807 } 9808 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 9809 buttonText = this._get( inst, "buttonText" ); 9810 buttonImage = this._get( inst, "buttonImage" ); 9811 inst.trigger = $( this._get( inst, "buttonImageOnly" ) ? 9812 $( "<img/>" ).addClass( this._triggerClass ). 9813 attr( { src: buttonImage, alt: buttonText, title: buttonText } ) : 9814 $( "<button type='button'></button>" ).addClass( this._triggerClass ). 9815 html( !buttonImage ? buttonText : $( "<img/>" ).attr( 9816 { src:buttonImage, alt:buttonText, title:buttonText } ) ) ); 9817 input[ isRTL ? "before" : "after" ]( inst.trigger ); 9818 inst.trigger.on( "click", function() { 9819 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 9820 $.datepicker._hideDatepicker(); 9821 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 9822 $.datepicker._hideDatepicker(); 9823 $.datepicker._showDatepicker( input[ 0 ] ); 9824 } else { 9825 $.datepicker._showDatepicker( input[ 0 ] ); 9826 } 9827 return false; 9828 } ); 9829 } 9830 }, 9831 9832 /* Apply the maximum length for the date format. */ 9833 _autoSize: function( inst ) { 9834 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 9835 var findMax, max, maxI, i, 9836 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 9837 dateFormat = this._get( inst, "dateFormat" ); 9838 9839 if ( dateFormat.match( /[DM]/ ) ) { 9840 findMax = function( names ) { 9841 max = 0; 9842 maxI = 0; 9843 for ( i = 0; i < names.length; i++ ) { 9844 if ( names[ i ].length > max ) { 9845 max = names[ i ].length; 9846 maxI = i; 9847 } 9848 } 9849 return maxI; 9850 }; 9851 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 9852 "monthNames" : "monthNamesShort" ) ) ) ); 9853 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 9854 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 9855 } 9856 inst.input.attr( "size", this._formatDate( inst, date ).length ); 9857 } 9858 }, 9859 9860 /* Attach an inline date picker to a div. */ 9861 _inlineDatepicker: function( target, inst ) { 9862 var divSpan = $( target ); 9863 if ( divSpan.hasClass( this.markerClassName ) ) { 9864 return; 9865 } 9866 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 9867 $.data( target, "datepicker", inst ); 9868 this._setDate( inst, this._getDefaultDate( inst ), true ); 9869 this._updateDatepicker( inst ); 9870 this._updateAlternate( inst ); 9871 9872 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 9873 if ( inst.settings.disabled ) { 9874 this._disableDatepicker( target ); 9875 } 9876 9877 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 9878 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 9879 inst.dpDiv.css( "display", "block" ); 9880 }, 9881 9882 /* Pop-up the date picker in a "dialog" box. 9883 * @param input element - ignored 9884 * @param date string or Date - the initial date to display 9885 * @param onSelect function - the function to call when a date is selected 9886 * @param settings object - update the dialog date picker instance's settings (anonymous object) 9887 * @param pos int[2] - coordinates for the dialog's position within the screen or 9888 * event - with x/y coordinates or 9889 * leave empty for default (screen centre) 9890 * @return the manager object 9891 */ 9892 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 9893 var id, browserWidth, browserHeight, scrollX, scrollY, 9894 inst = this._dialogInst; // internal instance 9895 9896 if ( !inst ) { 9897 this.uuid += 1; 9898 id = "dp" + this.uuid; 9899 this._dialogInput = $( "<input type='text' id='" + id + 9900 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 9901 this._dialogInput.on( "keydown", this._doKeyDown ); 9902 $( "body" ).append( this._dialogInput ); 9903 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 9904 inst.settings = {}; 9905 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 9906 } 9907 datepicker_extendRemove( inst.settings, settings || {} ); 9908 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 9909 this._dialogInput.val( date ); 9910 9911 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 9912 if ( !this._pos ) { 9913 browserWidth = document.documentElement.clientWidth; 9914 browserHeight = document.documentElement.clientHeight; 9915 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 9916 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 9917 this._pos = // should use actual width/height below 9918 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 9919 } 9920 9921 // Move input on screen for focus, but hidden behind dialog 9922 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 9923 inst.settings.onSelect = onSelect; 9924 this._inDialog = true; 9925 this.dpDiv.addClass( this._dialogClass ); 9926 this._showDatepicker( this._dialogInput[ 0 ] ); 9927 if ( $.blockUI ) { 9928 $.blockUI( this.dpDiv ); 9929 } 9930 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 9931 return this; 9932 }, 9933 9934 /* Detach a datepicker from its control. 9935 * @param target element - the target input field or division or span 9936 */ 9937 _destroyDatepicker: function( target ) { 9938 var nodeName, 9939 $target = $( target ), 9940 inst = $.data( target, "datepicker" ); 9941 9942 if ( !$target.hasClass( this.markerClassName ) ) { 9943 return; 9944 } 9945 9946 nodeName = target.nodeName.toLowerCase(); 9947 $.removeData( target, "datepicker" ); 9948 if ( nodeName === "input" ) { 9949 inst.append.remove(); 9950 inst.trigger.remove(); 9951 $target.removeClass( this.markerClassName ). 9952 off( "focus", this._showDatepicker ). 9953 off( "keydown", this._doKeyDown ). 9954 off( "keypress", this._doKeyPress ). 9955 off( "keyup", this._doKeyUp ); 9956 } else if ( nodeName === "div" || nodeName === "span" ) { 9957 $target.removeClass( this.markerClassName ).empty(); 9958 } 9959 9960 if ( datepicker_instActive === inst ) { 9961 datepicker_instActive = null; 9962 } 9963 }, 9964 9965 /* Enable the date picker to a jQuery selection. 9966 * @param target element - the target input field or division or span 9967 */ 9968 _enableDatepicker: function( target ) { 9969 var nodeName, inline, 9970 $target = $( target ), 9971 inst = $.data( target, "datepicker" ); 9972 9973 if ( !$target.hasClass( this.markerClassName ) ) { 9974 return; 9975 } 9976 9977 nodeName = target.nodeName.toLowerCase(); 9978 if ( nodeName === "input" ) { 9979 target.disabled = false; 9980 inst.trigger.filter( "button" ). 9981 each( function() { this.disabled = false; } ).end(). 9982 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 9983 } else if ( nodeName === "div" || nodeName === "span" ) { 9984 inline = $target.children( "." + this._inlineClass ); 9985 inline.children().removeClass( "ui-state-disabled" ); 9986 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 9987 prop( "disabled", false ); 9988 } 9989 this._disabledInputs = $.map( this._disabledInputs, 9990 function( value ) { return ( value === target ? null : value ); } ); // delete entry 9991 }, 9992 9993 /* Disable the date picker to a jQuery selection. 9994 * @param target element - the target input field or division or span 9995 */ 9996 _disableDatepicker: function( target ) { 9997 var nodeName, inline, 9998 $target = $( target ), 9999 inst = $.data( target, "datepicker" ); 10000 10001 if ( !$target.hasClass( this.markerClassName ) ) { 10002 return; 10003 } 10004 10005 nodeName = target.nodeName.toLowerCase(); 10006 if ( nodeName === "input" ) { 10007 target.disabled = true; 10008 inst.trigger.filter( "button" ). 10009 each( function() { this.disabled = true; } ).end(). 10010 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 10011 } else if ( nodeName === "div" || nodeName === "span" ) { 10012 inline = $target.children( "." + this._inlineClass ); 10013 inline.children().addClass( "ui-state-disabled" ); 10014 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 10015 prop( "disabled", true ); 10016 } 10017 this._disabledInputs = $.map( this._disabledInputs, 10018 function( value ) { return ( value === target ? null : value ); } ); // delete entry 10019 this._disabledInputs[ this._disabledInputs.length ] = target; 10020 }, 10021 10022 /* Is the first field in a jQuery collection disabled as a datepicker? 10023 * @param target element - the target input field or division or span 10024 * @return boolean - true if disabled, false if enabled 10025 */ 10026 _isDisabledDatepicker: function( target ) { 10027 if ( !target ) { 10028 return false; 10029 } 10030 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 10031 if ( this._disabledInputs[ i ] === target ) { 10032 return true; 10033 } 10034 } 10035 return false; 10036 }, 10037 10038 /* Retrieve the instance data for the target control. 10039 * @param target element - the target input field or division or span 10040 * @return object - the associated instance data 10041 * @throws error if a jQuery problem getting data 10042 */ 10043 _getInst: function( target ) { 10044 try { 10045 return $.data( target, "datepicker" ); 10046 } 10047 catch ( err ) { 10048 throw "Missing instance data for this datepicker"; 10049 } 10050 }, 10051 10052 /* Update or retrieve the settings for a date picker attached to an input field or division. 10053 * @param target element - the target input field or division or span 10054 * @param name object - the new settings to update or 10055 * string - the name of the setting to change or retrieve, 10056 * when retrieving also "all" for all instance settings or 10057 * "defaults" for all global defaults 10058 * @param value any - the new value for the setting 10059 * (omit if above is an object or to retrieve a value) 10060 */ 10061 _optionDatepicker: function( target, name, value ) { 10062 var settings, date, minDate, maxDate, 10063 inst = this._getInst( target ); 10064 10065 if ( arguments.length === 2 && typeof name === "string" ) { 10066 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 10067 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 10068 this._get( inst, name ) ) : null ) ); 10069 } 10070 10071 settings = name || {}; 10072 if ( typeof name === "string" ) { 10073 settings = {}; 10074 settings[ name ] = value; 10075 } 10076 10077 if ( inst ) { 10078 if ( this._curInst === inst ) { 10079 this._hideDatepicker(); 10080 } 10081 10082 date = this._getDateDatepicker( target, true ); 10083 minDate = this._getMinMaxDate( inst, "min" ); 10084 maxDate = this._getMinMaxDate( inst, "max" ); 10085 datepicker_extendRemove( inst.settings, settings ); 10086 10087 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 10088 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 10089 inst.settings.minDate = this._formatDate( inst, minDate ); 10090 } 10091 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 10092 inst.settings.maxDate = this._formatDate( inst, maxDate ); 10093 } 10094 if ( "disabled" in settings ) { 10095 if ( settings.disabled ) { 10096 this._disableDatepicker( target ); 10097 } else { 10098 this._enableDatepicker( target ); 10099 } 10100 } 10101 this._attachments( $( target ), inst ); 10102 this._autoSize( inst ); 10103 this._setDate( inst, date ); 10104 this._updateAlternate( inst ); 10105 this._updateDatepicker( inst ); 10106 } 10107 }, 10108 10109 // Change method deprecated 10110 _changeDatepicker: function( target, name, value ) { 10111 this._optionDatepicker( target, name, value ); 10112 }, 10113 10114 /* Redraw the date picker attached to an input field or division. 10115 * @param target element - the target input field or division or span 10116 */ 10117 _refreshDatepicker: function( target ) { 10118 var inst = this._getInst( target ); 10119 if ( inst ) { 10120 this._updateDatepicker( inst ); 10121 } 10122 }, 10123 10124 /* Set the dates for a jQuery selection. 10125 * @param target element - the target input field or division or span 10126 * @param date Date - the new date 10127 */ 10128 _setDateDatepicker: function( target, date ) { 10129 var inst = this._getInst( target ); 10130 if ( inst ) { 10131 this._setDate( inst, date ); 10132 this._updateDatepicker( inst ); 10133 this._updateAlternate( inst ); 10134 } 10135 }, 10136 10137 /* Get the date(s) for the first entry in a jQuery selection. 10138 * @param target element - the target input field or division or span 10139 * @param noDefault boolean - true if no default date is to be used 10140 * @return Date - the current date 10141 */ 10142 _getDateDatepicker: function( target, noDefault ) { 10143 var inst = this._getInst( target ); 10144 if ( inst && !inst.inline ) { 10145 this._setDateFromField( inst, noDefault ); 10146 } 10147 return ( inst ? this._getDate( inst ) : null ); 10148 }, 10149 10150 /* Handle keystrokes. */ 10151 _doKeyDown: function( event ) { 10152 var onSelect, dateStr, sel, 10153 inst = $.datepicker._getInst( event.target ), 10154 handled = true, 10155 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 10156 10157 inst._keyEvent = true; 10158 if ( $.datepicker._datepickerShowing ) { 10159 switch ( event.keyCode ) { 10160 case 9: $.datepicker._hideDatepicker(); 10161 handled = false; 10162 break; // hide on tab out 10163 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 10164 $.datepicker._currentClass + ")", inst.dpDiv ); 10165 if ( sel[ 0 ] ) { 10166 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 10167 } 10168 10169 onSelect = $.datepicker._get( inst, "onSelect" ); 10170 if ( onSelect ) { 10171 dateStr = $.datepicker._formatDate( inst ); 10172 10173 // Trigger custom callback 10174 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 10175 } else { 10176 $.datepicker._hideDatepicker(); 10177 } 10178 10179 return false; // don't submit the form 10180 case 27: $.datepicker._hideDatepicker(); 10181 break; // hide on escape 10182 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10183 -$.datepicker._get( inst, "stepBigMonths" ) : 10184 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10185 break; // previous month/year on page up/+ ctrl 10186 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10187 +$.datepicker._get( inst, "stepBigMonths" ) : 10188 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10189 break; // next month/year on page down/+ ctrl 10190 case 35: if ( event.ctrlKey || event.metaKey ) { 10191 $.datepicker._clearDate( event.target ); 10192 } 10193 handled = event.ctrlKey || event.metaKey; 10194 break; // clear on ctrl or command +end 10195 case 36: if ( event.ctrlKey || event.metaKey ) { 10196 $.datepicker._gotoToday( event.target ); 10197 } 10198 handled = event.ctrlKey || event.metaKey; 10199 break; // current on ctrl or command +home 10200 case 37: if ( event.ctrlKey || event.metaKey ) { 10201 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 10202 } 10203 handled = event.ctrlKey || event.metaKey; 10204 10205 // -1 day on ctrl or command +left 10206 if ( event.originalEvent.altKey ) { 10207 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10208 -$.datepicker._get( inst, "stepBigMonths" ) : 10209 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10210 } 10211 10212 // next month/year on alt +left on Mac 10213 break; 10214 case 38: if ( event.ctrlKey || event.metaKey ) { 10215 $.datepicker._adjustDate( event.target, -7, "D" ); 10216 } 10217 handled = event.ctrlKey || event.metaKey; 10218 break; // -1 week on ctrl or command +up 10219 case 39: if ( event.ctrlKey || event.metaKey ) { 10220 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 10221 } 10222 handled = event.ctrlKey || event.metaKey; 10223 10224 // +1 day on ctrl or command +right 10225 if ( event.originalEvent.altKey ) { 10226 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 10227 +$.datepicker._get( inst, "stepBigMonths" ) : 10228 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 10229 } 10230 10231 // next month/year on alt +right 10232 break; 10233 case 40: if ( event.ctrlKey || event.metaKey ) { 10234 $.datepicker._adjustDate( event.target, +7, "D" ); 10235 } 10236 handled = event.ctrlKey || event.metaKey; 10237 break; // +1 week on ctrl or command +down 10238 default: handled = false; 10239 } 10240 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 10241 $.datepicker._showDatepicker( this ); 10242 } else { 10243 handled = false; 10244 } 10245 10246 if ( handled ) { 10247 event.preventDefault(); 10248 event.stopPropagation(); 10249 } 10250 }, 10251 10252 /* Filter entered characters - based on date format. */ 10253 _doKeyPress: function( event ) { 10254 var chars, chr, 10255 inst = $.datepicker._getInst( event.target ); 10256 10257 if ( $.datepicker._get( inst, "constrainInput" ) ) { 10258 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 10259 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 10260 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 10261 } 10262 }, 10263 10264 /* Synchronise manual entry and field/alternate field. */ 10265 _doKeyUp: function( event ) { 10266 var date, 10267 inst = $.datepicker._getInst( event.target ); 10268 10269 if ( inst.input.val() !== inst.lastVal ) { 10270 try { 10271 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 10272 ( inst.input ? inst.input.val() : null ), 10273 $.datepicker._getFormatConfig( inst ) ); 10274 10275 if ( date ) { // only if valid 10276 $.datepicker._setDateFromField( inst ); 10277 $.datepicker._updateAlternate( inst ); 10278 $.datepicker._updateDatepicker( inst ); 10279 } 10280 } 10281 catch ( err ) { 10282 } 10283 } 10284 return true; 10285 }, 10286 10287 /* Pop-up the date picker for a given input field. 10288 * If false returned from beforeShow event handler do not show. 10289 * @param input element - the input field attached to the date picker or 10290 * event - if triggered by focus 10291 */ 10292 _showDatepicker: function( input ) { 10293 input = input.target || input; 10294 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 10295 input = $( "input", input.parentNode )[ 0 ]; 10296 } 10297 10298 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 10299 return; 10300 } 10301 10302 var inst, beforeShow, beforeShowSettings, isFixed, 10303 offset, showAnim, duration; 10304 10305 inst = $.datepicker._getInst( input ); 10306 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 10307 $.datepicker._curInst.dpDiv.stop( true, true ); 10308 if ( inst && $.datepicker._datepickerShowing ) { 10309 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 10310 } 10311 } 10312 10313 beforeShow = $.datepicker._get( inst, "beforeShow" ); 10314 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 10315 if ( beforeShowSettings === false ) { 10316 return; 10317 } 10318 datepicker_extendRemove( inst.settings, beforeShowSettings ); 10319 10320 inst.lastVal = null; 10321 $.datepicker._lastInput = input; 10322 $.datepicker._setDateFromField( inst ); 10323 10324 if ( $.datepicker._inDialog ) { // hide cursor 10325 input.value = ""; 10326 } 10327 if ( !$.datepicker._pos ) { // position below input 10328 $.datepicker._pos = $.datepicker._findPos( input ); 10329 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 10330 } 10331 10332 isFixed = false; 10333 $( input ).parents().each( function() { 10334 isFixed |= $( this ).css( "position" ) === "fixed"; 10335 return !isFixed; 10336 } ); 10337 10338 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 10339 $.datepicker._pos = null; 10340 10341 //to avoid flashes on Firefox 10342 inst.dpDiv.empty(); 10343 10344 // determine sizing offscreen 10345 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 10346 $.datepicker._updateDatepicker( inst ); 10347 10348 // fix width for dynamic number of date pickers 10349 // and adjust position before showing 10350 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 10351 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 10352 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 10353 left: offset.left + "px", top: offset.top + "px" } ); 10354 10355 if ( !inst.inline ) { 10356 showAnim = $.datepicker._get( inst, "showAnim" ); 10357 duration = $.datepicker._get( inst, "duration" ); 10358 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 10359 $.datepicker._datepickerShowing = true; 10360 10361 if ( $.effects && $.effects.effect[ showAnim ] ) { 10362 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 10363 } else { 10364 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 10365 } 10366 10367 if ( $.datepicker._shouldFocusInput( inst ) ) { 10368 inst.input.trigger( "focus" ); 10369 } 10370 10371 $.datepicker._curInst = inst; 10372 } 10373 }, 10374 10375 /* Generate the date picker content. */ 10376 _updateDatepicker: function( inst ) { 10377 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 10378 datepicker_instActive = inst; // for delegate hover events 10379 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 10380 this._attachHandlers( inst ); 10381 10382 var origyearshtml, 10383 numMonths = this._getNumberOfMonths( inst ), 10384 cols = numMonths[ 1 ], 10385 width = 17, 10386 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 10387 10388 if ( activeCell.length > 0 ) { 10389 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 10390 } 10391 10392 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 10393 if ( cols > 1 ) { 10394 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 10395 } 10396 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 10397 "Class" ]( "ui-datepicker-multi" ); 10398 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 10399 "Class" ]( "ui-datepicker-rtl" ); 10400 10401 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 10402 inst.input.trigger( "focus" ); 10403 } 10404 10405 // Deffered render of the years select (to avoid flashes on Firefox) 10406 if ( inst.yearshtml ) { 10407 origyearshtml = inst.yearshtml; 10408 setTimeout( function() { 10409 10410 //assure that inst.yearshtml didn't change. 10411 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 10412 inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml ); 10413 } 10414 origyearshtml = inst.yearshtml = null; 10415 }, 0 ); 10416 } 10417 }, 10418 10419 // #6694 - don't focus the input if it's already focused 10420 // this breaks the change event in IE 10421 // Support: IE and jQuery <1.9 10422 _shouldFocusInput: function( inst ) { 10423 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 10424 }, 10425 10426 /* Check positioning to remain on screen. */ 10427 _checkOffset: function( inst, offset, isFixed ) { 10428 var dpWidth = inst.dpDiv.outerWidth(), 10429 dpHeight = inst.dpDiv.outerHeight(), 10430 inputWidth = inst.input ? inst.input.outerWidth() : 0, 10431 inputHeight = inst.input ? inst.input.outerHeight() : 0, 10432 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 10433 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 10434 10435 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 10436 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 10437 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 10438 10439 // Now check if datepicker is showing outside window viewport - move to a better place if so. 10440 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 10441 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 10442 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 10443 Math.abs( dpHeight + inputHeight ) : 0 ); 10444 10445 return offset; 10446 }, 10447 10448 /* Find an object's position on the screen. */ 10449 _findPos: function( obj ) { 10450 var position, 10451 inst = this._getInst( obj ), 10452 isRTL = this._get( inst, "isRTL" ); 10453 10454 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) { 10455 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 10456 } 10457 10458 position = $( obj ).offset(); 10459 return [ position.left, position.top ]; 10460 }, 10461 10462 /* Hide the date picker from view. 10463 * @param input element - the input field attached to the date picker 10464 */ 10465 _hideDatepicker: function( input ) { 10466 var showAnim, duration, postProcess, onClose, 10467 inst = this._curInst; 10468 10469 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 10470 return; 10471 } 10472 10473 if ( this._datepickerShowing ) { 10474 showAnim = this._get( inst, "showAnim" ); 10475 duration = this._get( inst, "duration" ); 10476 postProcess = function() { 10477 $.datepicker._tidyDialog( inst ); 10478 }; 10479 10480 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 10481 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 10482 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 10483 } else { 10484 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 10485 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 10486 } 10487 10488 if ( !showAnim ) { 10489 postProcess(); 10490 } 10491 this._datepickerShowing = false; 10492 10493 onClose = this._get( inst, "onClose" ); 10494 if ( onClose ) { 10495 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 10496 } 10497 10498 this._lastInput = null; 10499 if ( this._inDialog ) { 10500 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 10501 if ( $.blockUI ) { 10502 $.unblockUI(); 10503 $( "body" ).append( this.dpDiv ); 10504 } 10505 } 10506 this._inDialog = false; 10507 } 10508 }, 10509 10510 /* Tidy up after a dialog display. */ 10511 _tidyDialog: function( inst ) { 10512 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 10513 }, 10514 10515 /* Close date picker if clicked elsewhere. */ 10516 _checkExternalClick: function( event ) { 10517 if ( !$.datepicker._curInst ) { 10518 return; 10519 } 10520 10521 var $target = $( event.target ), 10522 inst = $.datepicker._getInst( $target[ 0 ] ); 10523 10524 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 10525 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 10526 !$target.hasClass( $.datepicker.markerClassName ) && 10527 !$target.closest( "." + $.datepicker._triggerClass ).length && 10528 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 10529 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 10530 $.datepicker._hideDatepicker(); 10531 } 10532 }, 10533 10534 /* Adjust one of the date sub-fields. */ 10535 _adjustDate: function( id, offset, period ) { 10536 var target = $( id ), 10537 inst = this._getInst( target[ 0 ] ); 10538 10539 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 10540 return; 10541 } 10542 this._adjustInstDate( inst, offset + 10543 ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning 10544 period ); 10545 this._updateDatepicker( inst ); 10546 }, 10547 10548 /* Action for current link. */ 10549 _gotoToday: function( id ) { 10550 var date, 10551 target = $( id ), 10552 inst = this._getInst( target[ 0 ] ); 10553 10554 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 10555 inst.selectedDay = inst.currentDay; 10556 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 10557 inst.drawYear = inst.selectedYear = inst.currentYear; 10558 } else { 10559 date = new Date(); 10560 inst.selectedDay = date.getDate(); 10561 inst.drawMonth = inst.selectedMonth = date.getMonth(); 10562 inst.drawYear = inst.selectedYear = date.getFullYear(); 10563 } 10564 this._notifyChange( inst ); 10565 this._adjustDate( target ); 10566 }, 10567 10568 /* Action for selecting a new month/year. */ 10569 _selectMonthYear: function( id, select, period ) { 10570 var target = $( id ), 10571 inst = this._getInst( target[ 0 ] ); 10572 10573 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 10574 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 10575 parseInt( select.options[ select.selectedIndex ].value, 10 ); 10576 10577 this._notifyChange( inst ); 10578 this._adjustDate( target ); 10579 }, 10580 10581 /* Action for selecting a day. */ 10582 _selectDay: function( id, month, year, td ) { 10583 var inst, 10584 target = $( id ); 10585 10586 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 10587 return; 10588 } 10589 10590 inst = this._getInst( target[ 0 ] ); 10591 inst.selectedDay = inst.currentDay = $( "a", td ).html(); 10592 inst.selectedMonth = inst.currentMonth = month; 10593 inst.selectedYear = inst.currentYear = year; 10594 this._selectDate( id, this._formatDate( inst, 10595 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 10596 }, 10597 10598 /* Erase the input field and hide the date picker. */ 10599 _clearDate: function( id ) { 10600 var target = $( id ); 10601 this._selectDate( target, "" ); 10602 }, 10603 10604 /* Update the input field with the selected date. */ 10605 _selectDate: function( id, dateStr ) { 10606 var onSelect, 10607 target = $( id ), 10608 inst = this._getInst( target[ 0 ] ); 10609 10610 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 10611 if ( inst.input ) { 10612 inst.input.val( dateStr ); 10613 } 10614 this._updateAlternate( inst ); 10615 10616 onSelect = this._get( inst, "onSelect" ); 10617 if ( onSelect ) { 10618 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 10619 } else if ( inst.input ) { 10620 inst.input.trigger( "change" ); // fire the change event 10621 } 10622 10623 if ( inst.inline ) { 10624 this._updateDatepicker( inst ); 10625 } else { 10626 this._hideDatepicker(); 10627 this._lastInput = inst.input[ 0 ]; 10628 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 10629 inst.input.trigger( "focus" ); // restore focus 10630 } 10631 this._lastInput = null; 10632 } 10633 }, 10634 10635 /* Update any alternate field to synchronise with the main field. */ 10636 _updateAlternate: function( inst ) { 10637 var altFormat, date, dateStr, 10638 altField = this._get( inst, "altField" ); 10639 10640 if ( altField ) { // update alternate field too 10641 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 10642 date = this._getDate( inst ); 10643 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 10644 $( altField ).val( dateStr ); 10645 } 10646 }, 10647 10648 /* Set as beforeShowDay function to prevent selection of weekends. 10649 * @param date Date - the date to customise 10650 * @return [boolean, string] - is this date selectable?, what is its CSS class? 10651 */ 10652 noWeekends: function( date ) { 10653 var day = date.getDay(); 10654 return [ ( day > 0 && day < 6 ), "" ]; 10655 }, 10656 10657 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 10658 * @param date Date - the date to get the week for 10659 * @return number - the number of the week within the year that contains this date 10660 */ 10661 iso8601Week: function( date ) { 10662 var time, 10663 checkDate = new Date( date.getTime() ); 10664 10665 // Find Thursday of this week starting on Monday 10666 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 10667 10668 time = checkDate.getTime(); 10669 checkDate.setMonth( 0 ); // Compare with Jan 1 10670 checkDate.setDate( 1 ); 10671 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 10672 }, 10673 10674 /* Parse a string value into a date object. 10675 * See formatDate below for the possible formats. 10676 * 10677 * @param format string - the expected format of the date 10678 * @param value string - the date in the above format 10679 * @param settings Object - attributes include: 10680 * shortYearCutoff number - the cutoff year for determining the century (optional) 10681 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 10682 * dayNames string[7] - names of the days from Sunday (optional) 10683 * monthNamesShort string[12] - abbreviated names of the months (optional) 10684 * monthNames string[12] - names of the months (optional) 10685 * @return Date - the extracted date value or null if value is blank 10686 */ 10687 parseDate: function( format, value, settings ) { 10688 if ( format == null || value == null ) { 10689 throw "Invalid arguments"; 10690 } 10691 10692 value = ( typeof value === "object" ? value.toString() : value + "" ); 10693 if ( value === "" ) { 10694 return null; 10695 } 10696 10697 var iFormat, dim, extra, 10698 iValue = 0, 10699 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 10700 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 10701 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 10702 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 10703 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 10704 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 10705 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 10706 year = -1, 10707 month = -1, 10708 day = -1, 10709 doy = -1, 10710 literal = false, 10711 date, 10712 10713 // Check whether a format character is doubled 10714 lookAhead = function( match ) { 10715 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 10716 if ( matches ) { 10717 iFormat++; 10718 } 10719 return matches; 10720 }, 10721 10722 // Extract a number from the string value 10723 getNumber = function( match ) { 10724 var isDoubled = lookAhead( match ), 10725 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 10726 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 10727 minSize = ( match === "y" ? size : 1 ), 10728 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 10729 num = value.substring( iValue ).match( digits ); 10730 if ( !num ) { 10731 throw "Missing number at position " + iValue; 10732 } 10733 iValue += num[ 0 ].length; 10734 return parseInt( num[ 0 ], 10 ); 10735 }, 10736 10737 // Extract a name from the string value and convert to an index 10738 getName = function( match, shortNames, longNames ) { 10739 var index = -1, 10740 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 10741 return [ [ k, v ] ]; 10742 } ).sort( function( a, b ) { 10743 return -( a[ 1 ].length - b[ 1 ].length ); 10744 } ); 10745 10746 $.each( names, function( i, pair ) { 10747 var name = pair[ 1 ]; 10748 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 10749 index = pair[ 0 ]; 10750 iValue += name.length; 10751 return false; 10752 } 10753 } ); 10754 if ( index !== -1 ) { 10755 return index + 1; 10756 } else { 10757 throw "Unknown name at position " + iValue; 10758 } 10759 }, 10760 10761 // Confirm that a literal character matches the string value 10762 checkLiteral = function() { 10763 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 10764 throw "Unexpected literal at position " + iValue; 10765 } 10766 iValue++; 10767 }; 10768 10769 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 10770 if ( literal ) { 10771 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 10772 literal = false; 10773 } else { 10774 checkLiteral(); 10775 } 10776 } else { 10777 switch ( format.charAt( iFormat ) ) { 10778 case "d": 10779 day = getNumber( "d" ); 10780 break; 10781 case "D": 10782 getName( "D", dayNamesShort, dayNames ); 10783 break; 10784 case "o": 10785 doy = getNumber( "o" ); 10786 break; 10787 case "m": 10788 month = getNumber( "m" ); 10789 break; 10790 case "M": 10791 month = getName( "M", monthNamesShort, monthNames ); 10792 break; 10793 case "y": 10794 year = getNumber( "y" ); 10795 break; 10796 case "@": 10797 date = new Date( getNumber( "@" ) ); 10798 year = date.getFullYear(); 10799 month = date.getMonth() + 1; 10800 day = date.getDate(); 10801 break; 10802 case "!": 10803 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 10804 year = date.getFullYear(); 10805 month = date.getMonth() + 1; 10806 day = date.getDate(); 10807 break; 10808 case "'": 10809 if ( lookAhead( "'" ) ) { 10810 checkLiteral(); 10811 } else { 10812 literal = true; 10813 } 10814 break; 10815 default: 10816 checkLiteral(); 10817 } 10818 } 10819 } 10820 10821 if ( iValue < value.length ) { 10822 extra = value.substr( iValue ); 10823 if ( !/^\s+/.test( extra ) ) { 10824 throw "Extra/unparsed characters found in date: " + extra; 10825 } 10826 } 10827 10828 if ( year === -1 ) { 10829 year = new Date().getFullYear(); 10830 } else if ( year < 100 ) { 10831 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 10832 ( year <= shortYearCutoff ? 0 : -100 ); 10833 } 10834 10835 if ( doy > -1 ) { 10836 month = 1; 10837 day = doy; 10838 do { 10839 dim = this._getDaysInMonth( year, month - 1 ); 10840 if ( day <= dim ) { 10841 break; 10842 } 10843 month++; 10844 day -= dim; 10845 } while ( true ); 10846 } 10847 10848 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 10849 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 10850 throw "Invalid date"; // E.g. 31/02/00 10851 } 10852 return date; 10853 }, 10854 10855 /* Standard date formats. */ 10856 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 10857 COOKIE: "D, dd M yy", 10858 ISO_8601: "yy-mm-dd", 10859 RFC_822: "D, d M y", 10860 RFC_850: "DD, dd-M-y", 10861 RFC_1036: "D, d M y", 10862 RFC_1123: "D, d M yy", 10863 RFC_2822: "D, d M yy", 10864 RSS: "D, d M y", // RFC 822 10865 TICKS: "!", 10866 TIMESTAMP: "@", 10867 W3C: "yy-mm-dd", // ISO 8601 10868 10869 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 10870 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 10871 10872 /* Format a date object into a string value. 10873 * The format can be combinations of the following: 10874 * d - day of month (no leading zero) 10875 * dd - day of month (two digit) 10876 * o - day of year (no leading zeros) 10877 * oo - day of year (three digit) 10878 * D - day name short 10879 * DD - day name long 10880 * m - month of year (no leading zero) 10881 * mm - month of year (two digit) 10882 * M - month name short 10883 * MM - month name long 10884 * y - year (two digit) 10885 * yy - year (four digit) 10886 * @ - Unix timestamp (ms since 01/01/1970) 10887 * ! - Windows ticks (100ns since 01/01/0001) 10888 * "..." - literal text 10889 * '' - single quote 10890 * 10891 * @param format string - the desired format of the date 10892 * @param date Date - the date value to format 10893 * @param settings Object - attributes include: 10894 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 10895 * dayNames string[7] - names of the days from Sunday (optional) 10896 * monthNamesShort string[12] - abbreviated names of the months (optional) 10897 * monthNames string[12] - names of the months (optional) 10898 * @return string - the date in the above format 10899 */ 10900 formatDate: function( format, date, settings ) { 10901 if ( !date ) { 10902 return ""; 10903 } 10904 10905 var iFormat, 10906 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 10907 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 10908 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 10909 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 10910 10911 // Check whether a format character is doubled 10912 lookAhead = function( match ) { 10913 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 10914 if ( matches ) { 10915 iFormat++; 10916 } 10917 return matches; 10918 }, 10919 10920 // Format a number, with leading zero if necessary 10921 formatNumber = function( match, value, len ) { 10922 var num = "" + value; 10923 if ( lookAhead( match ) ) { 10924 while ( num.length < len ) { 10925 num = "0" + num; 10926 } 10927 } 10928 return num; 10929 }, 10930 10931 // Format a name, short or long as requested 10932 formatName = function( match, value, shortNames, longNames ) { 10933 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 10934 }, 10935 output = "", 10936 literal = false; 10937 10938 if ( date ) { 10939 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 10940 if ( literal ) { 10941 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 10942 literal = false; 10943 } else { 10944 output += format.charAt( iFormat ); 10945 } 10946 } else { 10947 switch ( format.charAt( iFormat ) ) { 10948 case "d": 10949 output += formatNumber( "d", date.getDate(), 2 ); 10950 break; 10951 case "D": 10952 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 10953 break; 10954 case "o": 10955 output += formatNumber( "o", 10956 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 10957 break; 10958 case "m": 10959 output += formatNumber( "m", date.getMonth() + 1, 2 ); 10960 break; 10961 case "M": 10962 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 10963 break; 10964 case "y": 10965 output += ( lookAhead( "y" ) ? date.getFullYear() : 10966 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 10967 break; 10968 case "@": 10969 output += date.getTime(); 10970 break; 10971 case "!": 10972 output += date.getTime() * 10000 + this._ticksTo1970; 10973 break; 10974 case "'": 10975 if ( lookAhead( "'" ) ) { 10976 output += "'"; 10977 } else { 10978 literal = true; 10979 } 10980 break; 10981 default: 10982 output += format.charAt( iFormat ); 10983 } 10984 } 10985 } 10986 } 10987 return output; 10988 }, 10989 10990 /* Extract all possible characters from the date format. */ 10991 _possibleChars: function( format ) { 10992 var iFormat, 10993 chars = "", 10994 literal = false, 10995 10996 // Check whether a format character is doubled 10997 lookAhead = function( match ) { 10998 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 10999 if ( matches ) { 11000 iFormat++; 11001 } 11002 return matches; 11003 }; 11004 11005 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 11006 if ( literal ) { 11007 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 11008 literal = false; 11009 } else { 11010 chars += format.charAt( iFormat ); 11011 } 11012 } else { 11013 switch ( format.charAt( iFormat ) ) { 11014 case "d": case "m": case "y": case "@": 11015 chars += "0123456789"; 11016 break; 11017 case "D": case "M": 11018 return null; // Accept anything 11019 case "'": 11020 if ( lookAhead( "'" ) ) { 11021 chars += "'"; 11022 } else { 11023 literal = true; 11024 } 11025 break; 11026 default: 11027 chars += format.charAt( iFormat ); 11028 } 11029 } 11030 } 11031 return chars; 11032 }, 11033 11034 /* Get a setting value, defaulting if necessary. */ 11035 _get: function( inst, name ) { 11036 return inst.settings[ name ] !== undefined ? 11037 inst.settings[ name ] : this._defaults[ name ]; 11038 }, 11039 11040 /* Parse existing date and initialise date picker. */ 11041 _setDateFromField: function( inst, noDefault ) { 11042 if ( inst.input.val() === inst.lastVal ) { 11043 return; 11044 } 11045 11046 var dateFormat = this._get( inst, "dateFormat" ), 11047 dates = inst.lastVal = inst.input ? inst.input.val() : null, 11048 defaultDate = this._getDefaultDate( inst ), 11049 date = defaultDate, 11050 settings = this._getFormatConfig( inst ); 11051 11052 try { 11053 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 11054 } catch ( event ) { 11055 dates = ( noDefault ? "" : dates ); 11056 } 11057 inst.selectedDay = date.getDate(); 11058 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11059 inst.drawYear = inst.selectedYear = date.getFullYear(); 11060 inst.currentDay = ( dates ? date.getDate() : 0 ); 11061 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 11062 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 11063 this._adjustInstDate( inst ); 11064 }, 11065 11066 /* Retrieve the default date shown on opening. */ 11067 _getDefaultDate: function( inst ) { 11068 return this._restrictMinMax( inst, 11069 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 11070 }, 11071 11072 /* A date may be specified as an exact value or a relative one. */ 11073 _determineDate: function( inst, date, defaultDate ) { 11074 var offsetNumeric = function( offset ) { 11075 var date = new Date(); 11076 date.setDate( date.getDate() + offset ); 11077 return date; 11078 }, 11079 offsetString = function( offset ) { 11080 try { 11081 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 11082 offset, $.datepicker._getFormatConfig( inst ) ); 11083 } 11084 catch ( e ) { 11085 11086 // Ignore 11087 } 11088 11089 var date = ( offset.toLowerCase().match( /^c/ ) ? 11090 $.datepicker._getDate( inst ) : null ) || new Date(), 11091 year = date.getFullYear(), 11092 month = date.getMonth(), 11093 day = date.getDate(), 11094 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 11095 matches = pattern.exec( offset ); 11096 11097 while ( matches ) { 11098 switch ( matches[ 2 ] || "d" ) { 11099 case "d" : case "D" : 11100 day += parseInt( matches[ 1 ], 10 ); break; 11101 case "w" : case "W" : 11102 day += parseInt( matches[ 1 ], 10 ) * 7; break; 11103 case "m" : case "M" : 11104 month += parseInt( matches[ 1 ], 10 ); 11105 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11106 break; 11107 case "y": case "Y" : 11108 year += parseInt( matches[ 1 ], 10 ); 11109 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 11110 break; 11111 } 11112 matches = pattern.exec( offset ); 11113 } 11114 return new Date( year, month, day ); 11115 }, 11116 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 11117 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 11118 11119 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 11120 if ( newDate ) { 11121 newDate.setHours( 0 ); 11122 newDate.setMinutes( 0 ); 11123 newDate.setSeconds( 0 ); 11124 newDate.setMilliseconds( 0 ); 11125 } 11126 return this._daylightSavingAdjust( newDate ); 11127 }, 11128 11129 /* Handle switch to/from daylight saving. 11130 * Hours may be non-zero on daylight saving cut-over: 11131 * > 12 when midnight changeover, but then cannot generate 11132 * midnight datetime, so jump to 1AM, otherwise reset. 11133 * @param date (Date) the date to check 11134 * @return (Date) the corrected date 11135 */ 11136 _daylightSavingAdjust: function( date ) { 11137 if ( !date ) { 11138 return null; 11139 } 11140 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 11141 return date; 11142 }, 11143 11144 /* Set the date(s) directly. */ 11145 _setDate: function( inst, date, noChange ) { 11146 var clear = !date, 11147 origMonth = inst.selectedMonth, 11148 origYear = inst.selectedYear, 11149 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 11150 11151 inst.selectedDay = inst.currentDay = newDate.getDate(); 11152 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 11153 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 11154 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 11155 this._notifyChange( inst ); 11156 } 11157 this._adjustInstDate( inst ); 11158 if ( inst.input ) { 11159 inst.input.val( clear ? "" : this._formatDate( inst ) ); 11160 } 11161 }, 11162 11163 /* Retrieve the date(s) directly. */ 11164 _getDate: function( inst ) { 11165 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 11166 this._daylightSavingAdjust( new Date( 11167 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11168 return startDate; 11169 }, 11170 11171 /* Attach the onxxx handlers. These are declared statically so 11172 * they work with static code transformers like Caja. 11173 */ 11174 _attachHandlers: function( inst ) { 11175 var stepMonths = this._get( inst, "stepMonths" ), 11176 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 11177 inst.dpDiv.find( "[data-handler]" ).map( function() { 11178 var handler = { 11179 prev: function() { 11180 $.datepicker._adjustDate( id, -stepMonths, "M" ); 11181 }, 11182 next: function() { 11183 $.datepicker._adjustDate( id, +stepMonths, "M" ); 11184 }, 11185 hide: function() { 11186 $.datepicker._hideDatepicker(); 11187 }, 11188 today: function() { 11189 $.datepicker._gotoToday( id ); 11190 }, 11191 selectDay: function() { 11192 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 11193 return false; 11194 }, 11195 selectMonth: function() { 11196 $.datepicker._selectMonthYear( id, this, "M" ); 11197 return false; 11198 }, 11199 selectYear: function() { 11200 $.datepicker._selectMonthYear( id, this, "Y" ); 11201 return false; 11202 } 11203 }; 11204 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 11205 } ); 11206 }, 11207 11208 /* Generate the HTML for the current state of the date picker. */ 11209 _generateHTML: function( inst ) { 11210 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 11211 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 11212 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 11213 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 11214 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 11215 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 11216 tempDate = new Date(), 11217 today = this._daylightSavingAdjust( 11218 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 11219 isRTL = this._get( inst, "isRTL" ), 11220 showButtonPanel = this._get( inst, "showButtonPanel" ), 11221 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 11222 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 11223 numMonths = this._getNumberOfMonths( inst ), 11224 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 11225 stepMonths = this._get( inst, "stepMonths" ), 11226 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 11227 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 11228 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 11229 minDate = this._getMinMaxDate( inst, "min" ), 11230 maxDate = this._getMinMaxDate( inst, "max" ), 11231 drawMonth = inst.drawMonth - showCurrentAtPos, 11232 drawYear = inst.drawYear; 11233 11234 if ( drawMonth < 0 ) { 11235 drawMonth += 12; 11236 drawYear--; 11237 } 11238 if ( maxDate ) { 11239 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 11240 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 11241 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 11242 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 11243 drawMonth--; 11244 if ( drawMonth < 0 ) { 11245 drawMonth = 11; 11246 drawYear--; 11247 } 11248 } 11249 } 11250 inst.drawMonth = drawMonth; 11251 inst.drawYear = drawYear; 11252 11253 prevText = this._get( inst, "prevText" ); 11254 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 11255 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 11256 this._getFormatConfig( inst ) ) ); 11257 11258 prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ? 11259 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 11260 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" : 11261 ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) ); 11262 11263 nextText = this._get( inst, "nextText" ); 11264 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 11265 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 11266 this._getFormatConfig( inst ) ) ); 11267 11268 next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ? 11269 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 11270 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" : 11271 ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) ); 11272 11273 currentText = this._get( inst, "currentText" ); 11274 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 11275 currentText = ( !navigationAsDateFormat ? currentText : 11276 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 11277 11278 controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + 11279 this._get( inst, "closeText" ) + "</button>" : "" ); 11280 11281 buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) + 11282 ( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + 11283 ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : ""; 11284 11285 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 11286 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 11287 11288 showWeek = this._get( inst, "showWeek" ); 11289 dayNames = this._get( inst, "dayNames" ); 11290 dayNamesMin = this._get( inst, "dayNamesMin" ); 11291 monthNames = this._get( inst, "monthNames" ); 11292 monthNamesShort = this._get( inst, "monthNamesShort" ); 11293 beforeShowDay = this._get( inst, "beforeShowDay" ); 11294 showOtherMonths = this._get( inst, "showOtherMonths" ); 11295 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 11296 defaultDate = this._getDefaultDate( inst ); 11297 html = ""; 11298 11299 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 11300 group = ""; 11301 this.maxRows = 4; 11302 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 11303 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 11304 cornerClass = " ui-corner-all"; 11305 calender = ""; 11306 if ( isMultiMonth ) { 11307 calender += "<div class='ui-datepicker-group"; 11308 if ( numMonths[ 1 ] > 1 ) { 11309 switch ( col ) { 11310 case 0: calender += " ui-datepicker-group-first"; 11311 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 11312 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 11313 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 11314 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 11315 } 11316 } 11317 calender += "'>"; 11318 } 11319 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 11320 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 11321 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 11322 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 11323 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 11324 "</div><table class='ui-datepicker-calendar'><thead>" + 11325 "<tr>"; 11326 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 11327 for ( dow = 0; dow < 7; dow++ ) { // days of the week 11328 day = ( dow + firstDay ) % 7; 11329 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 11330 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 11331 } 11332 calender += thead + "</tr></thead><tbody>"; 11333 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 11334 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 11335 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 11336 } 11337 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 11338 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 11339 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 11340 this.maxRows = numRows; 11341 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 11342 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 11343 calender += "<tr>"; 11344 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 11345 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 11346 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 11347 daySettings = ( beforeShowDay ? 11348 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 11349 otherMonth = ( printDate.getMonth() !== drawMonth ); 11350 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 11351 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 11352 tbody += "<td class='" + 11353 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 11354 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 11355 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 11356 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 11357 11358 // or defaultDate is current printedDate and defaultDate is selectedDate 11359 " " + this._dayOverClass : "" ) + // highlight selected day 11360 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 11361 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 11362 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 11363 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 11364 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 11365 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 11366 ( otherMonth && !showOtherMonths ? " " : // display for other months 11367 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 11368 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 11369 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 11370 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 11371 "' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 11372 printDate.setDate( printDate.getDate() + 1 ); 11373 printDate = this._daylightSavingAdjust( printDate ); 11374 } 11375 calender += tbody + "</tr>"; 11376 } 11377 drawMonth++; 11378 if ( drawMonth > 11 ) { 11379 drawMonth = 0; 11380 drawYear++; 11381 } 11382 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 11383 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 11384 group += calender; 11385 } 11386 html += group; 11387 } 11388 html += buttonPanel; 11389 inst._keyEvent = false; 11390 return html; 11391 }, 11392 11393 /* Generate the month and year header. */ 11394 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 11395 secondary, monthNames, monthNamesShort ) { 11396 11397 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 11398 changeMonth = this._get( inst, "changeMonth" ), 11399 changeYear = this._get( inst, "changeYear" ), 11400 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 11401 html = "<div class='ui-datepicker-title'>", 11402 monthHtml = ""; 11403 11404 // Month selection 11405 if ( secondary || !changeMonth ) { 11406 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 11407 } else { 11408 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 11409 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 11410 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 11411 for ( month = 0; month < 12; month++ ) { 11412 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 11413 monthHtml += "<option value='" + month + "'" + 11414 ( month === drawMonth ? " selected='selected'" : "" ) + 11415 ">" + monthNamesShort[ month ] + "</option>"; 11416 } 11417 } 11418 monthHtml += "</select>"; 11419 } 11420 11421 if ( !showMonthAfterYear ) { 11422 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 11423 } 11424 11425 // Year selection 11426 if ( !inst.yearshtml ) { 11427 inst.yearshtml = ""; 11428 if ( secondary || !changeYear ) { 11429 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 11430 } else { 11431 11432 // determine range of years to display 11433 years = this._get( inst, "yearRange" ).split( ":" ); 11434 thisYear = new Date().getFullYear(); 11435 determineYear = function( value ) { 11436 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 11437 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 11438 parseInt( value, 10 ) ) ); 11439 return ( isNaN( year ) ? thisYear : year ); 11440 }; 11441 year = determineYear( years[ 0 ] ); 11442 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 11443 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 11444 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 11445 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 11446 for ( ; year <= endYear; year++ ) { 11447 inst.yearshtml += "<option value='" + year + "'" + 11448 ( year === drawYear ? " selected='selected'" : "" ) + 11449 ">" + year + "</option>"; 11450 } 11451 inst.yearshtml += "</select>"; 11452 11453 html += inst.yearshtml; 11454 inst.yearshtml = null; 11455 } 11456 } 11457 11458 html += this._get( inst, "yearSuffix" ); 11459 if ( showMonthAfterYear ) { 11460 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 11461 } 11462 html += "</div>"; // Close datepicker_header 11463 return html; 11464 }, 11465 11466 /* Adjust one of the date sub-fields. */ 11467 _adjustInstDate: function( inst, offset, period ) { 11468 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 11469 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 11470 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 11471 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 11472 11473 inst.selectedDay = date.getDate(); 11474 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11475 inst.drawYear = inst.selectedYear = date.getFullYear(); 11476 if ( period === "M" || period === "Y" ) { 11477 this._notifyChange( inst ); 11478 } 11479 }, 11480 11481 /* Ensure a date is within any min/max bounds. */ 11482 _restrictMinMax: function( inst, date ) { 11483 var minDate = this._getMinMaxDate( inst, "min" ), 11484 maxDate = this._getMinMaxDate( inst, "max" ), 11485 newDate = ( minDate && date < minDate ? minDate : date ); 11486 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 11487 }, 11488 11489 /* Notify change of month/year. */ 11490 _notifyChange: function( inst ) { 11491 var onChange = this._get( inst, "onChangeMonthYear" ); 11492 if ( onChange ) { 11493 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 11494 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 11495 } 11496 }, 11497 11498 /* Determine the number of months to show. */ 11499 _getNumberOfMonths: function( inst ) { 11500 var numMonths = this._get( inst, "numberOfMonths" ); 11501 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 11502 }, 11503 11504 /* Determine the current maximum date - ensure no time components are set. */ 11505 _getMinMaxDate: function( inst, minMax ) { 11506 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 11507 }, 11508 11509 /* Find the number of days in a given month. */ 11510 _getDaysInMonth: function( year, month ) { 11511 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 11512 }, 11513 11514 /* Find the day of the week of the first of a month. */ 11515 _getFirstDayOfMonth: function( year, month ) { 11516 return new Date( year, month, 1 ).getDay(); 11517 }, 11518 11519 /* Determines if we should allow a "next/prev" month display change. */ 11520 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 11521 var numMonths = this._getNumberOfMonths( inst ), 11522 date = this._daylightSavingAdjust( new Date( curYear, 11523 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 11524 11525 if ( offset < 0 ) { 11526 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 11527 } 11528 return this._isInRange( inst, date ); 11529 }, 11530 11531 /* Is the given date in the accepted range? */ 11532 _isInRange: function( inst, date ) { 11533 var yearSplit, currentYear, 11534 minDate = this._getMinMaxDate( inst, "min" ), 11535 maxDate = this._getMinMaxDate( inst, "max" ), 11536 minYear = null, 11537 maxYear = null, 11538 years = this._get( inst, "yearRange" ); 11539 if ( years ) { 11540 yearSplit = years.split( ":" ); 11541 currentYear = new Date().getFullYear(); 11542 minYear = parseInt( yearSplit[ 0 ], 10 ); 11543 maxYear = parseInt( yearSplit[ 1 ], 10 ); 11544 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 11545 minYear += currentYear; 11546 } 11547 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 11548 maxYear += currentYear; 11549 } 11550 } 11551 11552 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 11553 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 11554 ( !minYear || date.getFullYear() >= minYear ) && 11555 ( !maxYear || date.getFullYear() <= maxYear ) ); 11556 }, 11557 11558 /* Provide the configuration settings for formatting/parsing. */ 11559 _getFormatConfig: function( inst ) { 11560 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 11561 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 11562 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 11563 return { shortYearCutoff: shortYearCutoff, 11564 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 11565 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 11566 }, 11567 11568 /* Format the given date for display. */ 11569 _formatDate: function( inst, day, month, year ) { 11570 if ( !day ) { 11571 inst.currentDay = inst.selectedDay; 11572 inst.currentMonth = inst.selectedMonth; 11573 inst.currentYear = inst.selectedYear; 11574 } 11575 var date = ( day ? ( typeof day === "object" ? day : 11576 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 11577 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 11578 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 11579 } 11580} ); 11581 11582/* 11583 * Bind hover events for datepicker elements. 11584 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 11585 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 11586 */ 11587function datepicker_bindHover( dpDiv ) { 11588 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 11589 return dpDiv.on( "mouseout", selector, function() { 11590 $( this ).removeClass( "ui-state-hover" ); 11591 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11592 $( this ).removeClass( "ui-datepicker-prev-hover" ); 11593 } 11594 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11595 $( this ).removeClass( "ui-datepicker-next-hover" ); 11596 } 11597 } ) 11598 .on( "mouseover", selector, datepicker_handleMouseover ); 11599} 11600 11601function datepicker_handleMouseover() { 11602 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 11603 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 11604 $( this ).addClass( "ui-state-hover" ); 11605 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 11606 $( this ).addClass( "ui-datepicker-prev-hover" ); 11607 } 11608 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 11609 $( this ).addClass( "ui-datepicker-next-hover" ); 11610 } 11611 } 11612} 11613 11614/* jQuery extend now ignores nulls! */ 11615function datepicker_extendRemove( target, props ) { 11616 $.extend( target, props ); 11617 for ( var name in props ) { 11618 if ( props[ name ] == null ) { 11619 target[ name ] = props[ name ]; 11620 } 11621 } 11622 return target; 11623} 11624 11625/* Invoke the datepicker functionality. 11626 @param options string - a command, optionally followed by additional parameters or 11627 Object - settings for attaching new datepicker functionality 11628 @return jQuery object */ 11629$.fn.datepicker = function( options ) { 11630 11631 /* Verify an empty collection wasn't passed - Fixes #6976 */ 11632 if ( !this.length ) { 11633 return this; 11634 } 11635 11636 /* Initialise the date picker. */ 11637 if ( !$.datepicker.initialized ) { 11638 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 11639 $.datepicker.initialized = true; 11640 } 11641 11642 /* Append datepicker main container to body if not exist. */ 11643 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 11644 $( "body" ).append( $.datepicker.dpDiv ); 11645 } 11646 11647 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 11648 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 11649 return $.datepicker[ "_" + options + "Datepicker" ]. 11650 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11651 } 11652 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 11653 return $.datepicker[ "_" + options + "Datepicker" ]. 11654 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 11655 } 11656 return this.each( function() { 11657 typeof options === "string" ? 11658 $.datepicker[ "_" + options + "Datepicker" ]. 11659 apply( $.datepicker, [ this ].concat( otherArgs ) ) : 11660 $.datepicker._attachDatepicker( this, options ); 11661 } ); 11662}; 11663 11664$.datepicker = new Datepicker(); // singleton instance 11665$.datepicker.initialized = false;
vendor: 36,125 bytes, lines 11666-13138
11666$.datepicker.uuid = new Date().getTime(); 11667$.datepicker.version = "1.12.1"; 11668 11669var widgetsDatepicker = $.datepicker; 11670 11671 11672/*! 11673 * jQuery UI Dialog 1.12.1 11674 * http://jqueryui.com 11675 * 11676 * Copyright jQuery Foundation and other contributors 11677 * Released under the MIT license. 11678 * http://jquery.org/license 11679 */ 11680 11681//>>label: Dialog 11682//>>group: Widgets 11683//>>description: Displays customizable dialog windows. 11684//>>docs: http://api.jqueryui.com/dialog/ 11685//>>demos: http://jqueryui.com/dialog/ 11686//>>css.structure: ../../themes/base/core.css 11687//>>css.structure: ../../themes/base/dialog.css 11688//>>css.theme: ../../themes/base/theme.css 11689 11690 11691 11692$.widget( "ui.dialog", { 11693 version: "1.12.1", 11694 options: { 11695 appendTo: "body", 11696 autoOpen: true, 11697 buttons: [], 11698 classes: { 11699 "ui-dialog": "ui-corner-all", 11700 "ui-dialog-titlebar": "ui-corner-all" 11701 }, 11702 closeOnEscape: true, 11703 closeText: "Close", 11704 draggable: true, 11705 hide: null, 11706 height: "auto", 11707 maxHeight: null, 11708 maxWidth: null, 11709 minHeight: 150, 11710 minWidth: 150, 11711 modal: false, 11712 position: { 11713 my: "center", 11714 at: "center", 11715 of: window, 11716 collision: "fit", 11717 11718 // Ensure the titlebar is always visible 11719 using: function( pos ) { 11720 var topOffset = $( this ).css( pos ).offset().top; 11721 if ( topOffset < 0 ) { 11722 $( this ).css( "top", pos.top - topOffset ); 11723 } 11724 } 11725 }, 11726 resizable: true, 11727 show: null, 11728 title: null, 11729 width: 300, 11730 11731 // Callbacks 11732 beforeClose: null, 11733 close: null, 11734 drag: null, 11735 dragStart: null, 11736 dragStop: null, 11737 focus: null, 11738 open: null, 11739 resize: null, 11740 resizeStart: null, 11741 resizeStop: null 11742 }, 11743 11744 sizeRelatedOptions: { 11745 buttons: true, 11746 height: true, 11747 maxHeight: true, 11748 maxWidth: true, 11749 minHeight: true, 11750 minWidth: true, 11751 width: true 11752 }, 11753 11754 resizableRelatedOptions: { 11755 maxHeight: true, 11756 maxWidth: true, 11757 minHeight: true, 11758 minWidth: true 11759 }, 11760 11761 _create: function() { 11762 this.originalCss = { 11763 display: this.element[ 0 ].style.display, 11764 width: this.element[ 0 ].style.width, 11765 minHeight: this.element[ 0 ].style.minHeight, 11766 maxHeight: this.element[ 0 ].style.maxHeight, 11767 height: this.element[ 0 ].style.height 11768 }; 11769 this.originalPosition = { 11770 parent: this.element.parent(), 11771 index: this.element.parent().children().index( this.element ) 11772 }; 11773 this.originalTitle = this.element.attr( "title" ); 11774 if ( this.options.title == null && this.originalTitle != null ) { 11775 this.options.title = this.originalTitle; 11776 } 11777 11778 // Dialogs can't be disabled 11779 if ( this.options.disabled ) { 11780 this.options.disabled = false; 11781 } 11782 11783 this._createWrapper(); 11784 11785 this.element 11786 .show() 11787 .removeAttr( "title" ) 11788 .appendTo( this.uiDialog ); 11789 11790 this._addClass( "ui-dialog-content", "ui-widget-content" ); 11791 11792 this._createTitlebar(); 11793 this._createButtonPane(); 11794 11795 if ( this.options.draggable && $.fn.draggable ) { 11796 this._makeDraggable(); 11797 } 11798 if ( this.options.resizable && $.fn.resizable ) { 11799 this._makeResizable(); 11800 } 11801 11802 this._isOpen = false; 11803 11804 this._trackFocus(); 11805 }, 11806 11807 _init: function() { 11808 if ( this.options.autoOpen ) { 11809 this.open(); 11810 } 11811 }, 11812 11813 _appendTo: function() { 11814 var element = this.options.appendTo; 11815 if ( element && ( element.jquery || element.nodeType ) ) { 11816 return $( element ); 11817 } 11818 return this.document.find( element || "body" ).eq( 0 ); 11819 }, 11820 11821 _destroy: function() { 11822 var next, 11823 originalPosition = this.originalPosition; 11824 11825 this._untrackInstance(); 11826 this._destroyOverlay(); 11827 11828 this.element 11829 .removeUniqueId() 11830 .css( this.originalCss ) 11831 11832 // Without detaching first, the following becomes really slow 11833 .detach(); 11834 11835 this.uiDialog.remove(); 11836 11837 if ( this.originalTitle ) { 11838 this.element.attr( "title", this.originalTitle ); 11839 } 11840 11841 next = originalPosition.parent.children().eq( originalPosition.index ); 11842 11843 // Don't try to place the dialog next to itself (#8613) 11844 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 11845 next.before( this.element ); 11846 } else { 11847 originalPosition.parent.append( this.element ); 11848 } 11849 }, 11850 11851 widget: function() { 11852 return this.uiDialog; 11853 }, 11854 11855 disable: $.noop, 11856 enable: $.noop, 11857 11858 close: function( event ) { 11859 var that = this; 11860 11861 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 11862 return; 11863 } 11864 11865 this._isOpen = false; 11866 this._focusedElement = null; 11867 this._destroyOverlay(); 11868 this._untrackInstance(); 11869 11870 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 11871 11872 // Hiding a focused element doesn't trigger blur in WebKit 11873 // so in case we have nothing to focus on, explicitly blur the active element 11874 // https://bugs.webkit.org/show_bug.cgi?id=47182 11875 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); 11876 } 11877 11878 this._hide( this.uiDialog, this.options.hide, function() { 11879 that._trigger( "close", event ); 11880 } ); 11881 }, 11882 11883 isOpen: function() { 11884 return this._isOpen; 11885 }, 11886 11887 moveToTop: function() { 11888 this._moveToTop(); 11889 }, 11890 11891 _moveToTop: function( event, silent ) { 11892 var moved = false, 11893 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 11894 return +$( this ).css( "z-index" ); 11895 } ).get(), 11896 zIndexMax = Math.max.apply( null, zIndices ); 11897 11898 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 11899 this.uiDialog.css( "z-index", zIndexMax + 1 ); 11900 moved = true; 11901 } 11902 11903 if ( moved && !silent ) { 11904 this._trigger( "focus", event ); 11905 } 11906 return moved; 11907 }, 11908 11909 open: function() { 11910 var that = this; 11911 if ( this._isOpen ) { 11912 if ( this._moveToTop() ) { 11913 this._focusTabbable(); 11914 } 11915 return; 11916 } 11917 11918 this._isOpen = true; 11919 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 11920 11921 this._size(); 11922 this._position(); 11923 this._createOverlay(); 11924 this._moveToTop( null, true ); 11925 11926 // Ensure the overlay is moved to the top with the dialog, but only when 11927 // opening. The overlay shouldn't move after the dialog is open so that 11928 // modeless dialogs opened after the modal dialog stack properly. 11929 if ( this.overlay ) { 11930 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 11931 } 11932 11933 this._show( this.uiDialog, this.options.show, function() { 11934 that._focusTabbable(); 11935 that._trigger( "focus" ); 11936 } ); 11937 11938 // Track the dialog immediately upon openening in case a focus event 11939 // somehow occurs outside of the dialog before an element inside the 11940 // dialog is focused (#10152) 11941 this._makeFocusTarget(); 11942 11943 this._trigger( "open" ); 11944 }, 11945 11946 _focusTabbable: function() { 11947 11948 // Set focus to the first match: 11949 // 1. An element that was focused previously 11950 // 2. First element inside the dialog matching [autofocus] 11951 // 3. Tabbable element inside the content element 11952 // 4. Tabbable element inside the buttonpane 11953 // 5. The close button 11954 // 6. The dialog itself 11955 var hasFocus = this._focusedElement; 11956 if ( !hasFocus ) { 11957 hasFocus = this.element.find( "[autofocus]" ); 11958 } 11959 if ( !hasFocus.length ) { 11960 hasFocus = this.element.find( ":tabbable" ); 11961 } 11962 if ( !hasFocus.length ) { 11963 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 11964 } 11965 if ( !hasFocus.length ) { 11966 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 11967 } 11968 if ( !hasFocus.length ) { 11969 hasFocus = this.uiDialog; 11970 } 11971 hasFocus.eq( 0 ).trigger( "focus" ); 11972 }, 11973 11974 _keepFocus: function( event ) { 11975 function checkFocus() { 11976 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 11977 isActive = this.uiDialog[ 0 ] === activeElement || 11978 $.contains( this.uiDialog[ 0 ], activeElement ); 11979 if ( !isActive ) { 11980 this._focusTabbable(); 11981 } 11982 } 11983 event.preventDefault(); 11984 checkFocus.call( this ); 11985 11986 // support: IE 11987 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 11988 // so we check again later 11989 this._delay( checkFocus ); 11990 }, 11991 11992 _createWrapper: function() { 11993 this.uiDialog = $( "<div>" ) 11994 .hide() 11995 .attr( { 11996 11997 // Setting tabIndex makes the div focusable 11998 tabIndex: -1, 11999 role: "dialog" 12000 } ) 12001 .appendTo( this._appendTo() ); 12002 12003 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 12004 this._on( this.uiDialog, { 12005 keydown: function( event ) { 12006 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 12007 event.keyCode === $.ui.keyCode.ESCAPE ) { 12008 event.preventDefault(); 12009 this.close( event ); 12010 return; 12011 } 12012 12013 // Prevent tabbing out of dialogs 12014 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 12015 return; 12016 } 12017 var tabbables = this.uiDialog.find( ":tabbable" ), 12018 first = tabbables.filter( ":first" ), 12019 last = tabbables.filter( ":last" ); 12020 12021 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 12022 !event.shiftKey ) { 12023 this._delay( function() { 12024 first.trigger( "focus" ); 12025 } ); 12026 event.preventDefault(); 12027 } else if ( ( event.target === first[ 0 ] || 12028 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 12029 this._delay( function() { 12030 last.trigger( "focus" ); 12031 } ); 12032 event.preventDefault(); 12033 } 12034 }, 12035 mousedown: function( event ) { 12036 if ( this._moveToTop( event ) ) { 12037 this._focusTabbable(); 12038 } 12039 } 12040 } ); 12041 12042 // We assume that any existing aria-describedby attribute means 12043 // that the dialog content is marked up properly 12044 // otherwise we brute force the content as the description 12045 if ( !this.element.find( "[aria-describedby]" ).length ) { 12046 this.uiDialog.attr( { 12047 "aria-describedby": this.element.uniqueId().attr( "id" ) 12048 } ); 12049 } 12050 }, 12051 12052 _createTitlebar: function() { 12053 var uiDialogTitle; 12054 12055 this.uiDialogTitlebar = $( "<div>" ); 12056 this._addClass( this.uiDialogTitlebar, 12057 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 12058 this._on( this.uiDialogTitlebar, { 12059 mousedown: function( event ) { 12060 12061 // Don't prevent click on close button (#8838) 12062 // Focusing a dialog that is partially scrolled out of view 12063 // causes the browser to scroll it into view, preventing the click event 12064 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 12065 12066 // Dialog isn't getting focus when dragging (#8063) 12067 this.uiDialog.trigger( "focus" ); 12068 } 12069 } 12070 } ); 12071 12072 // Support: IE 12073 // Use type="button" to prevent enter keypresses in textboxes from closing the 12074 // dialog in IE (#9312) 12075 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 12076 .button( { 12077 label: $( "<a>" ).text( this.options.closeText ).html(), 12078 icon: "ui-icon-closethick", 12079 showLabel: false 12080 } ) 12081 .appendTo( this.uiDialogTitlebar ); 12082 12083 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 12084 this._on( this.uiDialogTitlebarClose, { 12085 click: function( event ) { 12086 event.preventDefault(); 12087 this.close( event ); 12088 } 12089 } ); 12090 12091 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); 12092 this._addClass( uiDialogTitle, "ui-dialog-title" ); 12093 this._title( uiDialogTitle ); 12094 12095 this.uiDialogTitlebar.prependTo( this.uiDialog ); 12096 12097 this.uiDialog.attr( { 12098 "aria-labelledby": uiDialogTitle.attr( "id" ) 12099 } ); 12100 }, 12101 12102 _title: function( title ) { 12103 if ( this.options.title ) { 12104 title.text( this.options.title ); 12105 } else { 12106 title.html( " " ); 12107 } 12108 }, 12109 12110 _createButtonPane: function() { 12111 this.uiDialogButtonPane = $( "<div>" ); 12112 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 12113 "ui-widget-content ui-helper-clearfix" ); 12114 12115 this.uiButtonSet = $( "<div>" ) 12116 .appendTo( this.uiDialogButtonPane ); 12117 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 12118 12119 this._createButtons(); 12120 }, 12121 12122 _createButtons: function() { 12123 var that = this, 12124 buttons = this.options.buttons; 12125 12126 // If we already have a button pane, remove it 12127 this.uiDialogButtonPane.remove(); 12128 this.uiButtonSet.empty(); 12129 12130 if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) { 12131 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 12132 return; 12133 } 12134 12135 $.each( buttons, function( name, props ) { 12136 var click, buttonOptions; 12137 props = $.isFunction( props ) ? 12138 { click: props, text: name } : 12139 props; 12140 12141 // Default to a non-submitting button 12142 props = $.extend( { type: "button" }, props ); 12143 12144 // Change the context for the click callback to be the main element 12145 click = props.click; 12146 buttonOptions = { 12147 icon: props.icon, 12148 iconPosition: props.iconPosition, 12149 showLabel: props.showLabel, 12150 12151 // Deprecated options 12152 icons: props.icons, 12153 text: props.text 12154 }; 12155 12156 delete props.click; 12157 delete props.icon; 12158 delete props.iconPosition; 12159 delete props.showLabel; 12160 12161 // Deprecated options 12162 delete props.icons; 12163 if ( typeof props.text === "boolean" ) { 12164 delete props.text; 12165 } 12166 12167 $( "<button></button>", props ) 12168 .button( buttonOptions ) 12169 .appendTo( that.uiButtonSet ) 12170 .on( "click", function() { 12171 click.apply( that.element[ 0 ], arguments ); 12172 } ); 12173 } ); 12174 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 12175 this.uiDialogButtonPane.appendTo( this.uiDialog ); 12176 }, 12177 12178 _makeDraggable: function() { 12179 var that = this, 12180 options = this.options; 12181 12182 function filteredUi( ui ) { 12183 return { 12184 position: ui.position, 12185 offset: ui.offset 12186 }; 12187 } 12188 12189 this.uiDialog.draggable( { 12190 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 12191 handle: ".ui-dialog-titlebar", 12192 containment: "document", 12193 start: function( event, ui ) { 12194 that._addClass( $( this ), "ui-dialog-dragging" ); 12195 that._blockFrames(); 12196 that._trigger( "dragStart", event, filteredUi( ui ) ); 12197 }, 12198 drag: function( event, ui ) { 12199 that._trigger( "drag", event, filteredUi( ui ) ); 12200 }, 12201 stop: function( event, ui ) { 12202 var left = ui.offset.left - that.document.scrollLeft(), 12203 top = ui.offset.top - that.document.scrollTop(); 12204 12205 options.position = { 12206 my: "left top", 12207 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12208 "top" + ( top >= 0 ? "+" : "" ) + top, 12209 of: that.window 12210 }; 12211 that._removeClass( $( this ), "ui-dialog-dragging" ); 12212 that._unblockFrames(); 12213 that._trigger( "dragStop", event, filteredUi( ui ) ); 12214 } 12215 } ); 12216 }, 12217 12218 _makeResizable: function() { 12219 var that = this, 12220 options = this.options, 12221 handles = options.resizable, 12222 12223 // .ui-resizable has position: relative defined in the stylesheet 12224 // but dialogs have to use absolute or fixed positioning 12225 position = this.uiDialog.css( "position" ), 12226 resizeHandles = typeof handles === "string" ? 12227 handles : 12228 "n,e,s,w,se,sw,ne,nw"; 12229 12230 function filteredUi( ui ) { 12231 return { 12232 originalPosition: ui.originalPosition, 12233 originalSize: ui.originalSize, 12234 position: ui.position, 12235 size: ui.size 12236 }; 12237 } 12238 12239 this.uiDialog.resizable( { 12240 cancel: ".ui-dialog-content", 12241 containment: "document", 12242 alsoResize: this.element, 12243 maxWidth: options.maxWidth, 12244 maxHeight: options.maxHeight, 12245 minWidth: options.minWidth, 12246 minHeight: this._minHeight(), 12247 handles: resizeHandles, 12248 start: function( event, ui ) { 12249 that._addClass( $( this ), "ui-dialog-resizing" ); 12250 that._blockFrames(); 12251 that._trigger( "resizeStart", event, filteredUi( ui ) ); 12252 }, 12253 resize: function( event, ui ) { 12254 that._trigger( "resize", event, filteredUi( ui ) ); 12255 }, 12256 stop: function( event, ui ) { 12257 var offset = that.uiDialog.offset(), 12258 left = offset.left - that.document.scrollLeft(), 12259 top = offset.top - that.document.scrollTop(); 12260 12261 options.height = that.uiDialog.height(); 12262 options.width = that.uiDialog.width(); 12263 options.position = { 12264 my: "left top", 12265 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 12266 "top" + ( top >= 0 ? "+" : "" ) + top, 12267 of: that.window 12268 }; 12269 that._removeClass( $( this ), "ui-dialog-resizing" ); 12270 that._unblockFrames(); 12271 that._trigger( "resizeStop", event, filteredUi( ui ) ); 12272 } 12273 } ) 12274 .css( "position", position ); 12275 }, 12276 12277 _trackFocus: function() { 12278 this._on( this.widget(), { 12279 focusin: function( event ) { 12280 this._makeFocusTarget(); 12281 this._focusedElement = $( event.target ); 12282 } 12283 } ); 12284 }, 12285 12286 _makeFocusTarget: function() { 12287 this._untrackInstance(); 12288 this._trackingInstances().unshift( this ); 12289 }, 12290 12291 _untrackInstance: function() { 12292 var instances = this._trackingInstances(), 12293 exists = $.inArray( this, instances ); 12294 if ( exists !== -1 ) { 12295 instances.splice( exists, 1 ); 12296 } 12297 }, 12298 12299 _trackingInstances: function() { 12300 var instances = this.document.data( "ui-dialog-instances" ); 12301 if ( !instances ) { 12302 instances = []; 12303 this.document.data( "ui-dialog-instances", instances ); 12304 } 12305 return instances; 12306 }, 12307 12308 _minHeight: function() { 12309 var options = this.options; 12310 12311 return options.height === "auto" ? 12312 options.minHeight : 12313 Math.min( options.minHeight, options.height ); 12314 }, 12315 12316 _position: function() { 12317 12318 // Need to show the dialog to get the actual offset in the position plugin 12319 var isVisible = this.uiDialog.is( ":visible" ); 12320 if ( !isVisible ) { 12321 this.uiDialog.show(); 12322 } 12323 this.uiDialog.position( this.options.position ); 12324 if ( !isVisible ) { 12325 this.uiDialog.hide(); 12326 } 12327 }, 12328 12329 _setOptions: function( options ) { 12330 var that = this, 12331 resize = false, 12332 resizableOptions = {}; 12333 12334 $.each( options, function( key, value ) { 12335 that._setOption( key, value ); 12336 12337 if ( key in that.sizeRelatedOptions ) { 12338 resize = true; 12339 } 12340 if ( key in that.resizableRelatedOptions ) { 12341 resizableOptions[ key ] = value; 12342 } 12343 } ); 12344 12345 if ( resize ) { 12346 this._size(); 12347 this._position(); 12348 } 12349 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 12350 this.uiDialog.resizable( "option", resizableOptions ); 12351 } 12352 }, 12353 12354 _setOption: function( key, value ) { 12355 var isDraggable, isResizable, 12356 uiDialog = this.uiDialog; 12357 12358 if ( key === "disabled" ) { 12359 return; 12360 } 12361 12362 this._super( key, value ); 12363 12364 if ( key === "appendTo" ) { 12365 this.uiDialog.appendTo( this._appendTo() ); 12366 } 12367 12368 if ( key === "buttons" ) { 12369 this._createButtons(); 12370 } 12371 12372 if ( key === "closeText" ) { 12373 this.uiDialogTitlebarClose.button( { 12374 12375 // Ensure that we always pass a string 12376 label: $( "<a>" ).text( "" + this.options.closeText ).html() 12377 } ); 12378 } 12379 12380 if ( key === "draggable" ) { 12381 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 12382 if ( isDraggable && !value ) { 12383 uiDialog.draggable( "destroy" ); 12384 } 12385 12386 if ( !isDraggable && value ) { 12387 this._makeDraggable(); 12388 } 12389 } 12390 12391 if ( key === "position" ) { 12392 this._position(); 12393 } 12394 12395 if ( key === "resizable" ) { 12396 12397 // currently resizable, becoming non-resizable 12398 isResizable = uiDialog.is( ":data(ui-resizable)" ); 12399 if ( isResizable && !value ) { 12400 uiDialog.resizable( "destroy" ); 12401 } 12402 12403 // Currently resizable, changing handles 12404 if ( isResizable && typeof value === "string" ) { 12405 uiDialog.resizable( "option", "handles", value ); 12406 } 12407 12408 // Currently non-resizable, becoming resizable 12409 if ( !isResizable && value !== false ) { 12410 this._makeResizable(); 12411 } 12412 } 12413 12414 if ( key === "title" ) { 12415 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 12416 } 12417 }, 12418 12419 _size: function() { 12420 12421 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 12422 // divs will both have width and height set, so we need to reset them 12423 var nonContentHeight, minContentHeight, maxContentHeight, 12424 options = this.options; 12425 12426 // Reset content sizing 12427 this.element.show().css( { 12428 width: "auto", 12429 minHeight: 0, 12430 maxHeight: "none", 12431 height: 0 12432 } ); 12433 12434 if ( options.minWidth > options.width ) { 12435 options.width = options.minWidth; 12436 } 12437 12438 // Reset wrapper sizing 12439 // determine the height of all the non-content elements 12440 nonContentHeight = this.uiDialog.css( { 12441 height: "auto", 12442 width: options.width 12443 } ) 12444 .outerHeight(); 12445 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 12446 maxContentHeight = typeof options.maxHeight === "number" ? 12447 Math.max( 0, options.maxHeight - nonContentHeight ) : 12448 "none"; 12449 12450 if ( options.height === "auto" ) { 12451 this.element.css( { 12452 minHeight: minContentHeight, 12453 maxHeight: maxContentHeight, 12454 height: "auto" 12455 } ); 12456 } else { 12457 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 12458 } 12459 12460 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 12461 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 12462 } 12463 }, 12464 12465 _blockFrames: function() { 12466 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 12467 var iframe = $( this ); 12468 12469 return $( "<div>" ) 12470 .css( { 12471 position: "absolute", 12472 width: iframe.outerWidth(), 12473 height: iframe.outerHeight() 12474 } ) 12475 .appendTo( iframe.parent() ) 12476 .offset( iframe.offset() )[ 0 ]; 12477 } ); 12478 }, 12479 12480 _unblockFrames: function() { 12481 if ( this.iframeBlocks ) { 12482 this.iframeBlocks.remove(); 12483 delete this.iframeBlocks; 12484 } 12485 }, 12486 12487 _allowInteraction: function( event ) { 12488 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 12489 return true; 12490 } 12491 12492 // TODO: Remove hack when datepicker implements 12493 // the .ui-front logic (#8989) 12494 return !!$( event.target ).closest( ".ui-datepicker" ).length; 12495 }, 12496 12497 _createOverlay: function() { 12498 if ( !this.options.modal ) { 12499 return; 12500 } 12501 12502 // We use a delay in case the overlay is created from an 12503 // event that we're going to be cancelling (#2804) 12504 var isOpening = true; 12505 this._delay( function() { 12506 isOpening = false; 12507 } ); 12508 12509 if ( !this.document.data( "ui-dialog-overlays" ) ) { 12510 12511 // Prevent use of anchors and inputs 12512 // Using _on() for an event handler shared across many instances is 12513 // safe because the dialogs stack and must be closed in reverse order 12514 this._on( this.document, { 12515 focusin: function( event ) { 12516 if ( isOpening ) { 12517 return; 12518 } 12519 12520 if ( !this._allowInteraction( event ) ) { 12521 event.preventDefault(); 12522 this._trackingInstances()[ 0 ]._focusTabbable(); 12523 } 12524 } 12525 } ); 12526 } 12527 12528 this.overlay = $( "<div>" ) 12529 .appendTo( this._appendTo() ); 12530 12531 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 12532 this._on( this.overlay, { 12533 mousedown: "_keepFocus" 12534 } ); 12535 this.document.data( "ui-dialog-overlays", 12536 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 12537 }, 12538 12539 _destroyOverlay: function() { 12540 if ( !this.options.modal ) { 12541 return; 12542 } 12543 12544 if ( this.overlay ) { 12545 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 12546 12547 if ( !overlays ) { 12548 this._off( this.document, "focusin" ); 12549 this.document.removeData( "ui-dialog-overlays" ); 12550 } else { 12551 this.document.data( "ui-dialog-overlays", overlays ); 12552 } 12553 12554 this.overlay.remove(); 12555 this.overlay = null; 12556 } 12557 } 12558} ); 12559 12560// DEPRECATED 12561// TODO: switch return back to widget declaration at top of file when this is removed 12562if ( $.uiBackCompat !== false ) { 12563 12564 // Backcompat for dialogClass option 12565 $.widget( "ui.dialog", $.ui.dialog, { 12566 options: { 12567 dialogClass: "" 12568 }, 12569 _createWrapper: function() { 12570 this._super(); 12571 this.uiDialog.addClass( this.options.dialogClass ); 12572 }, 12573 _setOption: function( key, value ) { 12574 if ( key === "dialogClass" ) { 12575 this.uiDialog 12576 .removeClass( this.options.dialogClass ) 12577 .addClass( value ); 12578 } 12579 this._superApply( arguments ); 12580 } 12581 } ); 12582} 12583 12584var widgetsDialog = $.ui.dialog; 12585 12586 12587/*! 12588 * jQuery UI Progressbar 1.12.1 12589 * http://jqueryui.com 12590 * 12591 * Copyright jQuery Foundation and other contributors 12592 * Released under the MIT license. 12593 * http://jquery.org/license 12594 */ 12595 12596//>>label: Progressbar 12597//>>group: Widgets 12598// jscs:disable maximumLineLength 12599//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 12600// jscs:enable maximumLineLength 12601//>>docs: http://api.jqueryui.com/progressbar/ 12602//>>demos: http://jqueryui.com/progressbar/ 12603//>>css.structure: ../../themes/base/core.css 12604//>>css.structure: ../../themes/base/progressbar.css 12605//>>css.theme: ../../themes/base/theme.css 12606 12607 12608 12609var widgetsProgressbar = $.widget( "ui.progressbar", { 12610 version: "1.12.1", 12611 options: { 12612 classes: { 12613 "ui-progressbar": "ui-corner-all", 12614 "ui-progressbar-value": "ui-corner-left", 12615 "ui-progressbar-complete": "ui-corner-right" 12616 }, 12617 max: 100, 12618 value: 0, 12619 12620 change: null, 12621 complete: null 12622 }, 12623 12624 min: 0, 12625 12626 _create: function() { 12627 12628 // Constrain initial value 12629 this.oldValue = this.options.value = this._constrainedValue(); 12630 12631 this.element.attr( { 12632 12633 // Only set static values; aria-valuenow and aria-valuemax are 12634 // set inside _refreshValue() 12635 role: "progressbar", 12636 "aria-valuemin": this.min 12637 } ); 12638 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 12639 12640 this.valueDiv = $( "<div>" ).appendTo( this.element ); 12641 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 12642 this._refreshValue(); 12643 }, 12644 12645 _destroy: function() { 12646 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 12647 12648 this.valueDiv.remove(); 12649 }, 12650 12651 value: function( newValue ) { 12652 if ( newValue === undefined ) { 12653 return this.options.value; 12654 } 12655 12656 this.options.value = this._constrainedValue( newValue ); 12657 this._refreshValue(); 12658 }, 12659 12660 _constrainedValue: function( newValue ) { 12661 if ( newValue === undefined ) { 12662 newValue = this.options.value; 12663 } 12664 12665 this.indeterminate = newValue === false; 12666 12667 // Sanitize value 12668 if ( typeof newValue !== "number" ) { 12669 newValue = 0; 12670 } 12671 12672 return this.indeterminate ? false : 12673 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12674 }, 12675 12676 _setOptions: function( options ) { 12677 12678 // Ensure "value" option is set after other values (like max) 12679 var value = options.value; 12680 delete options.value; 12681 12682 this._super( options ); 12683 12684 this.options.value = this._constrainedValue( value ); 12685 this._refreshValue(); 12686 }, 12687 12688 _setOption: function( key, value ) { 12689 if ( key === "max" ) { 12690 12691 // Don't allow a max less than min 12692 value = Math.max( this.min, value ); 12693 } 12694 this._super( key, value ); 12695 }, 12696 12697 _setOptionDisabled: function( value ) { 12698 this._super( value ); 12699 12700 this.element.attr( "aria-disabled", value ); 12701 this._toggleClass( null, "ui-state-disabled", !!value ); 12702 }, 12703 12704 _percentage: function() { 12705 return this.indeterminate ? 12706 100 : 12707 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12708 }, 12709 12710 _refreshValue: function() { 12711 var value = this.options.value, 12712 percentage = this._percentage(); 12713 12714 this.valueDiv 12715 .toggle( this.indeterminate || value > this.min ) 12716 .width( percentage.toFixed( 0 ) + "%" ); 12717 12718 this 12719 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 12720 value === this.options.max ) 12721 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 12722 12723 if ( this.indeterminate ) { 12724 this.element.removeAttr( "aria-valuenow" ); 12725 if ( !this.overlayDiv ) { 12726 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 12727 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 12728 } 12729 } else { 12730 this.element.attr( { 12731 "aria-valuemax": this.options.max, 12732 "aria-valuenow": value 12733 } ); 12734 if ( this.overlayDiv ) { 12735 this.overlayDiv.remove(); 12736 this.overlayDiv = null; 12737 } 12738 } 12739 12740 if ( this.oldValue !== value ) { 12741 this.oldValue = value; 12742 this._trigger( "change" ); 12743 } 12744 if ( value === this.options.max ) { 12745 this._trigger( "complete" ); 12746 } 12747 } 12748} ); 12749 12750 12751/*! 12752 * jQuery UI Selectmenu 1.12.1 12753 * http://jqueryui.com 12754 * 12755 * Copyright jQuery Foundation and other contributors 12756 * Released under the MIT license. 12757 * http://jquery.org/license 12758 */ 12759 12760//>>label: Selectmenu 12761//>>group: Widgets 12762// jscs:disable maximumLineLength 12763//>>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. 12764// jscs:enable maximumLineLength 12765//>>docs: http://api.jqueryui.com/selectmenu/ 12766//>>demos: http://jqueryui.com/selectmenu/ 12767//>>css.structure: ../../themes/base/core.css 12768//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 12769//>>css.theme: ../../themes/base/theme.css 12770 12771 12772 12773var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 12774 version: "1.12.1", 12775 defaultElement: "<select>", 12776 options: { 12777 appendTo: null, 12778 classes: { 12779 "ui-selectmenu-button-open": "ui-corner-top", 12780 "ui-selectmenu-button-closed": "ui-corner-all" 12781 }, 12782 disabled: null, 12783 icons: { 12784 button: "ui-icon-triangle-1-s" 12785 }, 12786 position: { 12787 my: "left top", 12788 at: "left bottom", 12789 collision: "none" 12790 }, 12791 width: false, 12792 12793 // Callbacks 12794 change: null, 12795 close: null, 12796 focus: null, 12797 open: null, 12798 select: null 12799 }, 12800 12801 _create: function() { 12802 var selectmenuId = this.element.uniqueId().attr( "id" ); 12803 this.ids = { 12804 element: selectmenuId, 12805 button: selectmenuId + "-button", 12806 menu: selectmenuId + "-menu" 12807 }; 12808 12809 this._drawButton(); 12810 this._drawMenu(); 12811 this._bindFormResetHandler(); 12812 12813 this._rendered = false; 12814 this.menuItems = $(); 12815 }, 12816 12817 _drawButton: function() { 12818 var icon, 12819 that = this, 12820 item = this._parseOption( 12821 this.element.find( "option:selected" ), 12822 this.element[ 0 ].selectedIndex 12823 ); 12824 12825 // Associate existing label with the new button 12826 this.labels = this.element.labels().attr( "for", this.ids.button ); 12827 this._on( this.labels, { 12828 click: function( event ) { 12829 this.button.focus(); 12830 event.preventDefault(); 12831 } 12832 } ); 12833 12834 // Hide original select element 12835 this.element.hide(); 12836 12837 // Create button 12838 this.button = $( "<span>", { 12839 tabindex: this.options.disabled ? -1 : 0, 12840 id: this.ids.button, 12841 role: "combobox", 12842 "aria-expanded": "false", 12843 "aria-autocomplete": "list", 12844 "aria-owns": this.ids.menu, 12845 "aria-haspopup": "true", 12846 title: this.element.attr( "title" ) 12847 } ) 12848 .insertAfter( this.element ); 12849 12850 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 12851 "ui-button ui-widget" ); 12852 12853 icon = $( "<span>" ).appendTo( this.button ); 12854 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 12855 this.buttonItem = this._renderButtonItem( item ) 12856 .appendTo( this.button ); 12857 12858 if ( this.options.width !== false ) { 12859 this._resizeButton(); 12860 } 12861 12862 this._on( this.button, this._buttonEvents ); 12863 this.button.one( "focusin", function() { 12864 12865 // Delay rendering the menu items until the button receives focus. 12866 // The menu may have already been rendered via a programmatic open. 12867 if ( !that._rendered ) { 12868 that._refreshMenu(); 12869 } 12870 } ); 12871 }, 12872 12873 _drawMenu: function() { 12874 var that = this; 12875 12876 // Create menu 12877 this.menu = $( "<ul>", { 12878 "aria-hidden": "true", 12879 "aria-labelledby": this.ids.button, 12880 id: this.ids.menu 12881 } ); 12882 12883 // Wrap menu 12884 this.menuWrap = $( "<div>" ).append( this.menu ); 12885 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 12886 this.menuWrap.appendTo( this._appendTo() ); 12887 12888 // Initialize menu widget 12889 this.menuInstance = this.menu 12890 .menu( { 12891 classes: { 12892 "ui-menu": "ui-corner-bottom" 12893 }, 12894 role: "listbox", 12895 select: function( event, ui ) { 12896 event.preventDefault(); 12897 12898 // Support: IE8 12899 // If the item was selected via a click, the text selection 12900 // will be destroyed in IE 12901 that._setSelection(); 12902 12903 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 12904 }, 12905 focus: function( event, ui ) { 12906 var item = ui.item.data( "ui-selectmenu-item" ); 12907 12908 // Prevent inital focus from firing and check if its a newly focused item 12909 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 12910 that._trigger( "focus", event, { item: item } ); 12911 if ( !that.isOpen ) { 12912 that._select( item, event ); 12913 } 12914 } 12915 that.focusIndex = item.index; 12916 12917 that.button.attr( "aria-activedescendant", 12918 that.menuItems.eq( item.index ).attr( "id" ) ); 12919 } 12920 } ) 12921 .menu( "instance" ); 12922 12923 // Don't close the menu on mouseleave 12924 this.menuInstance._off( this.menu, "mouseleave" ); 12925 12926 // Cancel the menu's collapseAll on document click 12927 this.menuInstance._closeOnDocumentClick = function() { 12928 return false; 12929 }; 12930 12931 // Selects often contain empty items, but never contain dividers 12932 this.menuInstance._isDivider = function() { 12933 return false; 12934 }; 12935 }, 12936 12937 refresh: function() { 12938 this._refreshMenu(); 12939 this.buttonItem.replaceWith( 12940 this.buttonItem = this._renderButtonItem( 12941 12942 // Fall back to an empty object in case there are no options 12943 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 12944 ) 12945 ); 12946 if ( this.options.width === null ) { 12947 this._resizeButton(); 12948 } 12949 }, 12950 12951 _refreshMenu: function() { 12952 var item, 12953 options = this.element.find( "option" ); 12954 12955 this.menu.empty(); 12956 12957 this._parseOptions( options ); 12958 this._renderMenu( this.menu, this.items ); 12959 12960 this.menuInstance.refresh(); 12961 this.menuItems = this.menu.find( "li" ) 12962 .not( ".ui-selectmenu-optgroup" ) 12963 .find( ".ui-menu-item-wrapper" ); 12964 12965 this._rendered = true; 12966 12967 if ( !options.length ) { 12968 return; 12969 } 12970 12971 item = this._getSelectedItem(); 12972 12973 // Update the menu to have the correct item focused 12974 this.menuInstance.focus( null, item ); 12975 this._setAria( item.data( "ui-selectmenu-item" ) ); 12976 12977 // Set disabled state 12978 this._setOption( "disabled", this.element.prop( "disabled" ) ); 12979 }, 12980 12981 open: function( event ) { 12982 if ( this.options.disabled ) { 12983 return; 12984 } 12985 12986 // If this is the first time the menu is being opened, render the items 12987 if ( !this._rendered ) { 12988 this._refreshMenu(); 12989 } else { 12990 12991 // Menu clears focus on close, reset focus to selected item 12992 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 12993 this.menuInstance.focus( null, this._getSelectedItem() ); 12994 } 12995 12996 // If there are no options, don't open the menu 12997 if ( !this.menuItems.length ) { 12998 return; 12999 } 13000 13001 this.isOpen = true; 13002 this._toggleAttr(); 13003 this._resizeMenu(); 13004 this._position(); 13005 13006 this._on( this.document, this._documentClick ); 13007 13008 this._trigger( "open", event ); 13009 }, 13010 13011 _position: function() { 13012 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 13013 }, 13014 13015 close: function( event ) { 13016 if ( !this.isOpen ) { 13017 return; 13018 } 13019 13020 this.isOpen = false; 13021 this._toggleAttr(); 13022 13023 this.range = null; 13024 this._off( this.document ); 13025 13026 this._trigger( "close", event ); 13027 }, 13028 13029 widget: function() { 13030 return this.button; 13031 }, 13032 13033 menuWidget: function() { 13034 return this.menu; 13035 }, 13036 13037 _renderButtonItem: function( item ) { 13038 var buttonItem = $( "<span>" ); 13039 13040 this._setText( buttonItem, item.label ); 13041 this._addClass( buttonItem, "ui-selectmenu-text" ); 13042 13043 return buttonItem; 13044 }, 13045 13046 _renderMenu: function( ul, items ) { 13047 var that = this, 13048 currentOptgroup = ""; 13049 13050 $.each( items, function( index, item ) { 13051 var li; 13052 13053 if ( item.optgroup !== currentOptgroup ) { 13054 li = $( "<li>", { 13055 text: item.optgroup 13056 } ); 13057 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 13058 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 13059 " ui-state-disabled" : 13060 "" ) ); 13061 13062 li.appendTo( ul ); 13063 13064 currentOptgroup = item.optgroup; 13065 } 13066 13067 that._renderItemData( ul, item ); 13068 } ); 13069 }, 13070 13071 _renderItemData: function( ul, item ) { 13072 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 13073 }, 13074 13075 _renderItem: function( ul, item ) { 13076 var li = $( "<li>" ), 13077 wrapper = $( "<div>", { 13078 title: item.element.attr( "title" ) 13079 } ); 13080 13081 if ( item.disabled ) { 13082 this._addClass( li, null, "ui-state-disabled" ); 13083 } 13084 this._setText( wrapper, item.label ); 13085 13086 return li.append( wrapper ).appendTo( ul ); 13087 }, 13088 13089 _setText: function( element, value ) { 13090 if ( value ) { 13091 element.text( value ); 13092 } else { 13093 element.html( " " ); 13094 } 13095 }, 13096 13097 _move: function( direction, event ) { 13098 var item, next, 13099 filter = ".ui-menu-item"; 13100 13101 if ( this.isOpen ) { 13102 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13103 } else { 13104 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13105 filter += ":not(.ui-state-disabled)"; 13106 } 13107 13108 if ( direction === "first" || direction === "last" ) { 13109 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 13110 } else { 13111 next = item[ direction + "All" ]( filter ).eq( 0 ); 13112 } 13113 13114 if ( next.length ) { 13115 this.menuInstance.focus( event, next ); 13116 } 13117 }, 13118 13119 _getSelectedItem: function() { 13120 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 13121 }, 13122 13123 _toggle: function( event ) { 13124 this[ this.isOpen ? "close" : "open" ]( event ); 13125 }, 13126 13127 _setSelection: function() { 13128 var selection; 13129 13130 if ( !this.range ) { 13131 return; 13132 } 13133 13134 if ( window.getSelection ) { 13135 selection = window.getSelection(); 13136 selection.removeAllRanges(); 13137 selection.addRange( this.range ); 13138
vendor: 25,061 bytes, lines 13139-14121
13139 // Support: IE8 13140 } else { 13141 this.range.select(); 13142 } 13143 13144 // Support: IE 13145 // Setting the text selection kills the button focus in IE, but 13146 // restoring the focus doesn't kill the selection. 13147 this.button.focus(); 13148 }, 13149 13150 _documentClick: { 13151 mousedown: function( event ) { 13152 if ( !this.isOpen ) { 13153 return; 13154 } 13155 13156 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 13157 $.ui.escapeSelector( this.ids.button ) ).length ) { 13158 this.close( event ); 13159 } 13160 } 13161 }, 13162 13163 _buttonEvents: { 13164 13165 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 13166 mousedown: function() { 13167 var selection; 13168 13169 if ( window.getSelection ) { 13170 selection = window.getSelection(); 13171 if ( selection.rangeCount ) { 13172 this.range = selection.getRangeAt( 0 ); 13173 } 13174 13175 // Support: IE8 13176 } else { 13177 this.range = document.selection.createRange(); 13178 } 13179 }, 13180 13181 click: function( event ) { 13182 this._setSelection(); 13183 this._toggle( event ); 13184 }, 13185 13186 keydown: function( event ) { 13187 var preventDefault = true; 13188 switch ( event.keyCode ) { 13189 case $.ui.keyCode.TAB: 13190 case $.ui.keyCode.ESCAPE: 13191 this.close( event ); 13192 preventDefault = false; 13193 break; 13194 case $.ui.keyCode.ENTER: 13195 if ( this.isOpen ) { 13196 this._selectFocusedItem( event ); 13197 } 13198 break; 13199 case $.ui.keyCode.UP: 13200 if ( event.altKey ) { 13201 this._toggle( event ); 13202 } else { 13203 this._move( "prev", event ); 13204 } 13205 break; 13206 case $.ui.keyCode.DOWN: 13207 if ( event.altKey ) { 13208 this._toggle( event ); 13209 } else { 13210 this._move( "next", event ); 13211 } 13212 break; 13213 case $.ui.keyCode.SPACE: 13214 if ( this.isOpen ) { 13215 this._selectFocusedItem( event ); 13216 } else { 13217 this._toggle( event ); 13218 } 13219 break; 13220 case $.ui.keyCode.LEFT: 13221 this._move( "prev", event ); 13222 break; 13223 case $.ui.keyCode.RIGHT: 13224 this._move( "next", event ); 13225 break; 13226 case $.ui.keyCode.HOME: 13227 case $.ui.keyCode.PAGE_UP: 13228 this._move( "first", event ); 13229 break; 13230 case $.ui.keyCode.END: 13231 case $.ui.keyCode.PAGE_DOWN: 13232 this._move( "last", event ); 13233 break; 13234 default: 13235 this.menu.trigger( event ); 13236 preventDefault = false; 13237 } 13238 13239 if ( preventDefault ) { 13240 event.preventDefault(); 13241 } 13242 } 13243 }, 13244 13245 _selectFocusedItem: function( event ) { 13246 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 13247 if ( !item.hasClass( "ui-state-disabled" ) ) { 13248 this._select( item.data( "ui-selectmenu-item" ), event ); 13249 } 13250 }, 13251 13252 _select: function( item, event ) { 13253 var oldIndex = this.element[ 0 ].selectedIndex; 13254 13255 // Change native select element 13256 this.element[ 0 ].selectedIndex = item.index; 13257 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 13258 this._setAria( item ); 13259 this._trigger( "select", event, { item: item } ); 13260 13261 if ( item.index !== oldIndex ) { 13262 this._trigger( "change", event, { item: item } ); 13263 } 13264 13265 this.close( event ); 13266 }, 13267 13268 _setAria: function( item ) { 13269 var id = this.menuItems.eq( item.index ).attr( "id" ); 13270 13271 this.button.attr( { 13272 "aria-labelledby": id, 13273 "aria-activedescendant": id 13274 } ); 13275 this.menu.attr( "aria-activedescendant", id ); 13276 }, 13277 13278 _setOption: function( key, value ) { 13279 if ( key === "icons" ) { 13280 var icon = this.button.find( "span.ui-icon" ); 13281 this._removeClass( icon, null, this.options.icons.button ) 13282 ._addClass( icon, null, value.button ); 13283 } 13284 13285 this._super( key, value ); 13286 13287 if ( key === "appendTo" ) { 13288 this.menuWrap.appendTo( this._appendTo() ); 13289 } 13290 13291 if ( key === "width" ) { 13292 this._resizeButton(); 13293 } 13294 }, 13295 13296 _setOptionDisabled: function( value ) { 13297 this._super( value ); 13298 13299 this.menuInstance.option( "disabled", value ); 13300 this.button.attr( "aria-disabled", value ); 13301 this._toggleClass( this.button, null, "ui-state-disabled", value ); 13302 13303 this.element.prop( "disabled", value ); 13304 if ( value ) { 13305 this.button.attr( "tabindex", -1 ); 13306 this.close(); 13307 } else { 13308 this.button.attr( "tabindex", 0 ); 13309 } 13310 }, 13311 13312 _appendTo: function() { 13313 var element = this.options.appendTo; 13314 13315 if ( element ) { 13316 element = element.jquery || element.nodeType ? 13317 $( element ) : 13318 this.document.find( element ).eq( 0 ); 13319 } 13320 13321 if ( !element || !element[ 0 ] ) { 13322 element = this.element.closest( ".ui-front, dialog" ); 13323 } 13324 13325 if ( !element.length ) { 13326 element = this.document[ 0 ].body; 13327 } 13328 13329 return element; 13330 }, 13331 13332 _toggleAttr: function() { 13333 this.button.attr( "aria-expanded", this.isOpen ); 13334 13335 // We can't use two _toggleClass() calls here, because we need to make sure 13336 // we always remove classes first and add them second, otherwise if both classes have the 13337 // same theme class, it will be removed after we add it. 13338 this._removeClass( this.button, "ui-selectmenu-button-" + 13339 ( this.isOpen ? "closed" : "open" ) ) 13340 ._addClass( this.button, "ui-selectmenu-button-" + 13341 ( this.isOpen ? "open" : "closed" ) ) 13342 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 13343 13344 this.menu.attr( "aria-hidden", !this.isOpen ); 13345 }, 13346 13347 _resizeButton: function() { 13348 var width = this.options.width; 13349 13350 // For `width: false`, just remove inline style and stop 13351 if ( width === false ) { 13352 this.button.css( "width", "" ); 13353 return; 13354 } 13355 13356 // For `width: null`, match the width of the original element 13357 if ( width === null ) { 13358 width = this.element.show().outerWidth(); 13359 this.element.hide(); 13360 } 13361 13362 this.button.outerWidth( width ); 13363 }, 13364 13365 _resizeMenu: function() { 13366 this.menu.outerWidth( Math.max( 13367 this.button.outerWidth(), 13368 13369 // Support: IE10 13370 // IE10 wraps long text (possibly a rounding bug) 13371 // so we add 1px to avoid the wrapping 13372 this.menu.width( "" ).outerWidth() + 1 13373 ) ); 13374 }, 13375 13376 _getCreateOptions: function() { 13377 var options = this._super(); 13378 13379 options.disabled = this.element.prop( "disabled" ); 13380 13381 return options; 13382 }, 13383 13384 _parseOptions: function( options ) { 13385 var that = this, 13386 data = []; 13387 options.each( function( index, item ) { 13388 data.push( that._parseOption( $( item ), index ) ); 13389 } ); 13390 this.items = data; 13391 }, 13392 13393 _parseOption: function( option, index ) { 13394 var optgroup = option.parent( "optgroup" ); 13395 13396 return { 13397 element: option, 13398 index: index, 13399 value: option.val(), 13400 label: option.text(), 13401 optgroup: optgroup.attr( "label" ) || "", 13402 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 13403 }; 13404 }, 13405 13406 _destroy: function() { 13407 this._unbindFormResetHandler(); 13408 this.menuWrap.remove(); 13409 this.button.remove(); 13410 this.element.show(); 13411 this.element.removeUniqueId(); 13412 this.labels.attr( "for", this.ids.element ); 13413 } 13414} ] ); 13415 13416 13417/*! 13418 * jQuery UI Slider 1.12.1 13419 * http://jqueryui.com 13420 * 13421 * Copyright jQuery Foundation and other contributors 13422 * Released under the MIT license. 13423 * http://jquery.org/license 13424 */ 13425 13426//>>label: Slider 13427//>>group: Widgets 13428//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 13429//>>docs: http://api.jqueryui.com/slider/ 13430//>>demos: http://jqueryui.com/slider/ 13431//>>css.structure: ../../themes/base/core.css 13432//>>css.structure: ../../themes/base/slider.css 13433//>>css.theme: ../../themes/base/theme.css 13434 13435 13436 13437var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 13438 version: "1.12.1", 13439 widgetEventPrefix: "slide", 13440 13441 options: { 13442 animate: false, 13443 classes: { 13444 "ui-slider": "ui-corner-all", 13445 "ui-slider-handle": "ui-corner-all", 13446 13447 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 13448 // element, but worked best visually with a variety of themes 13449 "ui-slider-range": "ui-corner-all ui-widget-header" 13450 }, 13451 distance: 0, 13452 max: 100, 13453 min: 0, 13454 orientation: "horizontal", 13455 range: false, 13456 step: 1, 13457 value: 0, 13458 values: null, 13459 13460 // Callbacks 13461 change: null, 13462 slide: null, 13463 start: null, 13464 stop: null 13465 }, 13466 13467 // Number of pages in a slider 13468 // (how many times can you page up/down to go through the whole range) 13469 numPages: 5, 13470 13471 _create: function() { 13472 this._keySliding = false; 13473 this._mouseSliding = false; 13474 this._animateOff = true; 13475 this._handleIndex = null; 13476 this._detectOrientation(); 13477 this._mouseInit(); 13478 this._calculateNewMax(); 13479 13480 this._addClass( "ui-slider ui-slider-" + this.orientation, 13481 "ui-widget ui-widget-content" ); 13482 13483 this._refresh(); 13484 13485 this._animateOff = false; 13486 }, 13487 13488 _refresh: function() { 13489 this._createRange(); 13490 this._createHandles(); 13491 this._setupEvents(); 13492 this._refreshValue(); 13493 }, 13494 13495 _createHandles: function() { 13496 var i, handleCount, 13497 options = this.options, 13498 existingHandles = this.element.find( ".ui-slider-handle" ), 13499 handle = "<span tabindex='0'></span>", 13500 handles = []; 13501 13502 handleCount = ( options.values && options.values.length ) || 1; 13503 13504 if ( existingHandles.length > handleCount ) { 13505 existingHandles.slice( handleCount ).remove(); 13506 existingHandles = existingHandles.slice( 0, handleCount ); 13507 } 13508 13509 for ( i = existingHandles.length; i < handleCount; i++ ) { 13510 handles.push( handle ); 13511 } 13512 13513 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13514 13515 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 13516 13517 this.handle = this.handles.eq( 0 ); 13518 13519 this.handles.each( function( i ) { 13520 $( this ) 13521 .data( "ui-slider-handle-index", i ) 13522 .attr( "tabIndex", 0 ); 13523 } ); 13524 }, 13525 13526 _createRange: function() { 13527 var options = this.options; 13528 13529 if ( options.range ) { 13530 if ( options.range === true ) { 13531 if ( !options.values ) { 13532 options.values = [ this._valueMin(), this._valueMin() ]; 13533 } else if ( options.values.length && options.values.length !== 2 ) { 13534 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 13535 } else if ( $.isArray( options.values ) ) { 13536 options.values = options.values.slice( 0 ); 13537 } 13538 } 13539 13540 if ( !this.range || !this.range.length ) { 13541 this.range = $( "<div>" ) 13542 .appendTo( this.element ); 13543 13544 this._addClass( this.range, "ui-slider-range" ); 13545 } else { 13546 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 13547 13548 // Handle range switching from true to min/max 13549 this.range.css( { 13550 "left": "", 13551 "bottom": "" 13552 } ); 13553 } 13554 if ( options.range === "min" || options.range === "max" ) { 13555 this._addClass( this.range, "ui-slider-range-" + options.range ); 13556 } 13557 } else { 13558 if ( this.range ) { 13559 this.range.remove(); 13560 } 13561 this.range = null; 13562 } 13563 }, 13564 13565 _setupEvents: function() { 13566 this._off( this.handles ); 13567 this._on( this.handles, this._handleEvents ); 13568 this._hoverable( this.handles ); 13569 this._focusable( this.handles ); 13570 }, 13571 13572 _destroy: function() { 13573 this.handles.remove(); 13574 if ( this.range ) { 13575 this.range.remove(); 13576 } 13577 13578 this._mouseDestroy(); 13579 }, 13580 13581 _mouseCapture: function( event ) { 13582 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 13583 that = this, 13584 o = this.options; 13585 13586 if ( o.disabled ) { 13587 return false; 13588 } 13589 13590 this.elementSize = { 13591 width: this.element.outerWidth(), 13592 height: this.element.outerHeight() 13593 }; 13594 this.elementOffset = this.element.offset(); 13595 13596 position = { x: event.pageX, y: event.pageY }; 13597 normValue = this._normValueFromMouse( position ); 13598 distance = this._valueMax() - this._valueMin() + 1; 13599 this.handles.each( function( i ) { 13600 var thisDistance = Math.abs( normValue - that.values( i ) ); 13601 if ( ( distance > thisDistance ) || 13602 ( distance === thisDistance && 13603 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 13604 distance = thisDistance; 13605 closestHandle = $( this ); 13606 index = i; 13607 } 13608 } ); 13609 13610 allowed = this._start( event, index ); 13611 if ( allowed === false ) { 13612 return false; 13613 } 13614 this._mouseSliding = true; 13615 13616 this._handleIndex = index; 13617 13618 this._addClass( closestHandle, null, "ui-state-active" ); 13619 closestHandle.trigger( "focus" ); 13620 13621 offset = closestHandle.offset(); 13622 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13623 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13624 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13625 top: event.pageY - offset.top - 13626 ( closestHandle.height() / 2 ) - 13627 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 13628 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 13629 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 13630 }; 13631 13632 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13633 this._slide( event, index, normValue ); 13634 } 13635 this._animateOff = true; 13636 return true; 13637 }, 13638 13639 _mouseStart: function() { 13640 return true; 13641 }, 13642 13643 _mouseDrag: function( event ) { 13644 var position = { x: event.pageX, y: event.pageY }, 13645 normValue = this._normValueFromMouse( position ); 13646 13647 this._slide( event, this._handleIndex, normValue ); 13648 13649 return false; 13650 }, 13651 13652 _mouseStop: function( event ) { 13653 this._removeClass( this.handles, null, "ui-state-active" ); 13654 this._mouseSliding = false; 13655 13656 this._stop( event, this._handleIndex ); 13657 this._change( event, this._handleIndex ); 13658 13659 this._handleIndex = null; 13660 this._clickOffset = null; 13661 this._animateOff = false; 13662 13663 return false; 13664 }, 13665 13666 _detectOrientation: function() { 13667 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13668 }, 13669 13670 _normValueFromMouse: function( position ) { 13671 var pixelTotal, 13672 pixelMouse, 13673 percentMouse, 13674 valueTotal, 13675 valueMouse; 13676 13677 if ( this.orientation === "horizontal" ) { 13678 pixelTotal = this.elementSize.width; 13679 pixelMouse = position.x - this.elementOffset.left - 13680 ( this._clickOffset ? this._clickOffset.left : 0 ); 13681 } else { 13682 pixelTotal = this.elementSize.height; 13683 pixelMouse = position.y - this.elementOffset.top - 13684 ( this._clickOffset ? this._clickOffset.top : 0 ); 13685 } 13686 13687 percentMouse = ( pixelMouse / pixelTotal ); 13688 if ( percentMouse > 1 ) { 13689 percentMouse = 1; 13690 } 13691 if ( percentMouse < 0 ) { 13692 percentMouse = 0; 13693 } 13694 if ( this.orientation === "vertical" ) { 13695 percentMouse = 1 - percentMouse; 13696 } 13697 13698 valueTotal = this._valueMax() - this._valueMin(); 13699 valueMouse = this._valueMin() + percentMouse * valueTotal; 13700 13701 return this._trimAlignValue( valueMouse ); 13702 }, 13703 13704 _uiHash: function( index, value, values ) { 13705 var uiHash = { 13706 handle: this.handles[ index ], 13707 handleIndex: index, 13708 value: value !== undefined ? value : this.value() 13709 }; 13710 13711 if ( this._hasMultipleValues() ) { 13712 uiHash.value = value !== undefined ? value : this.values( index ); 13713 uiHash.values = values || this.values(); 13714 } 13715 13716 return uiHash; 13717 }, 13718 13719 _hasMultipleValues: function() { 13720 return this.options.values && this.options.values.length; 13721 }, 13722 13723 _start: function( event, index ) { 13724 return this._trigger( "start", event, this._uiHash( index ) ); 13725 }, 13726 13727 _slide: function( event, index, newVal ) { 13728 var allowed, otherVal, 13729 currentValue = this.value(), 13730 newValues = this.values(); 13731 13732 if ( this._hasMultipleValues() ) { 13733 otherVal = this.values( index ? 0 : 1 ); 13734 currentValue = this.values( index ); 13735 13736 if ( this.options.values.length === 2 && this.options.range === true ) { 13737 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 13738 } 13739 13740 newValues[ index ] = newVal; 13741 } 13742 13743 if ( newVal === currentValue ) { 13744 return; 13745 } 13746 13747 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 13748 13749 // A slide can be canceled by returning false from the slide callback 13750 if ( allowed === false ) { 13751 return; 13752 } 13753 13754 if ( this._hasMultipleValues() ) { 13755 this.values( index, newVal ); 13756 } else { 13757 this.value( newVal ); 13758 } 13759 }, 13760 13761 _stop: function( event, index ) { 13762 this._trigger( "stop", event, this._uiHash( index ) ); 13763 }, 13764 13765 _change: function( event, index ) { 13766 if ( !this._keySliding && !this._mouseSliding ) { 13767 13768 //store the last changed value index for reference when handles overlap 13769 this._lastChangedValue = index; 13770 this._trigger( "change", event, this._uiHash( index ) ); 13771 } 13772 }, 13773 13774 value: function( newValue ) { 13775 if ( arguments.length ) { 13776 this.options.value = this._trimAlignValue( newValue ); 13777 this._refreshValue(); 13778 this._change( null, 0 ); 13779 return; 13780 } 13781 13782 return this._value(); 13783 }, 13784 13785 values: function( index, newValue ) { 13786 var vals, 13787 newValues, 13788 i; 13789 13790 if ( arguments.length > 1 ) { 13791 this.options.values[ index ] = this._trimAlignValue( newValue ); 13792 this._refreshValue(); 13793 this._change( null, index ); 13794 return; 13795 } 13796 13797 if ( arguments.length ) { 13798 if ( $.isArray( arguments[ 0 ] ) ) { 13799 vals = this.options.values; 13800 newValues = arguments[ 0 ]; 13801 for ( i = 0; i < vals.length; i += 1 ) { 13802 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13803 this._change( null, i ); 13804 } 13805 this._refreshValue(); 13806 } else { 13807 if ( this._hasMultipleValues() ) { 13808 return this._values( index ); 13809 } else { 13810 return this.value(); 13811 } 13812 } 13813 } else { 13814 return this._values(); 13815 } 13816 }, 13817 13818 _setOption: function( key, value ) { 13819 var i, 13820 valsLength = 0; 13821 13822 if ( key === "range" && this.options.range === true ) { 13823 if ( value === "min" ) { 13824 this.options.value = this._values( 0 ); 13825 this.options.values = null; 13826 } else if ( value === "max" ) { 13827 this.options.value = this._values( this.options.values.length - 1 ); 13828 this.options.values = null; 13829 } 13830 } 13831 13832 if ( $.isArray( this.options.values ) ) { 13833 valsLength = this.options.values.length; 13834 } 13835 13836 this._super( key, value ); 13837 13838 switch ( key ) { 13839 case "orientation": 13840 this._detectOrientation(); 13841 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13842 ._addClass( "ui-slider-" + this.orientation ); 13843 this._refreshValue(); 13844 if ( this.options.range ) { 13845 this._refreshRange( value ); 13846 } 13847 13848 // Reset positioning from previous orientation 13849 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 13850 break; 13851 case "value": 13852 this._animateOff = true; 13853 this._refreshValue(); 13854 this._change( null, 0 ); 13855 this._animateOff = false; 13856 break; 13857 case "values": 13858 this._animateOff = true; 13859 this._refreshValue(); 13860 13861 // Start from the last handle to prevent unreachable handles (#9046) 13862 for ( i = valsLength - 1; i >= 0; i-- ) { 13863 this._change( null, i ); 13864 } 13865 this._animateOff = false; 13866 break; 13867 case "step": 13868 case "min": 13869 case "max": 13870 this._animateOff = true; 13871 this._calculateNewMax(); 13872 this._refreshValue(); 13873 this._animateOff = false; 13874 break; 13875 case "range": 13876 this._animateOff = true; 13877 this._refresh(); 13878 this._animateOff = false; 13879 break; 13880 } 13881 }, 13882 13883 _setOptionDisabled: function( value ) { 13884 this._super( value ); 13885 13886 this._toggleClass( null, "ui-state-disabled", !!value ); 13887 }, 13888 13889 //internal value getter 13890 // _value() returns value trimmed by min and max, aligned by step 13891 _value: function() { 13892 var val = this.options.value; 13893 val = this._trimAlignValue( val ); 13894 13895 return val; 13896 }, 13897 13898 //internal values getter 13899 // _values() returns array of values trimmed by min and max, aligned by step 13900 // _values( index ) returns single value trimmed by min and max, aligned by step 13901 _values: function( index ) { 13902 var val, 13903 vals, 13904 i; 13905 13906 if ( arguments.length ) { 13907 val = this.options.values[ index ]; 13908 val = this._trimAlignValue( val ); 13909 13910 return val; 13911 } else if ( this._hasMultipleValues() ) { 13912 13913 // .slice() creates a copy of the array 13914 // this copy gets trimmed by min and max and then returned 13915 vals = this.options.values.slice(); 13916 for ( i = 0; i < vals.length; i += 1 ) { 13917 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13918 } 13919 13920 return vals; 13921 } else { 13922 return []; 13923 } 13924 }, 13925 13926 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 13927 _trimAlignValue: function( val ) { 13928 if ( val <= this._valueMin() ) { 13929 return this._valueMin(); 13930 } 13931 if ( val >= this._valueMax() ) { 13932 return this._valueMax(); 13933 } 13934 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13935 valModStep = ( val - this._valueMin() ) % step, 13936 alignValue = val - valModStep; 13937 13938 if ( Math.abs( valModStep ) * 2 >= step ) { 13939 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13940 } 13941 13942 // Since JavaScript has problems with large floats, round 13943 // the final value to 5 digits after the decimal point (see #4124) 13944 return parseFloat( alignValue.toFixed( 5 ) ); 13945 }, 13946 13947 _calculateNewMax: function() { 13948 var max = this.options.max, 13949 min = this._valueMin(), 13950 step = this.options.step, 13951 aboveMin = Math.round( ( max - min ) / step ) * step; 13952 max = aboveMin + min; 13953 if ( max > this.options.max ) { 13954 13955 //If max is not divisible by step, rounding off may increase its value 13956 max -= step; 13957 } 13958 this.max = parseFloat( max.toFixed( this._precision() ) ); 13959 }, 13960 13961 _precision: function() { 13962 var precision = this._precisionOf( this.options.step ); 13963 if ( this.options.min !== null ) { 13964 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13965 } 13966 return precision; 13967 }, 13968 13969 _precisionOf: function( num ) { 13970 var str = num.toString(), 13971 decimal = str.indexOf( "." ); 13972 return decimal === -1 ? 0 : str.length - decimal - 1; 13973 }, 13974 13975 _valueMin: function() { 13976 return this.options.min; 13977 }, 13978 13979 _valueMax: function() { 13980 return this.max; 13981 }, 13982 13983 _refreshRange: function( orientation ) { 13984 if ( orientation === "vertical" ) { 13985 this.range.css( { "width": "", "left": "" } ); 13986 } 13987 if ( orientation === "horizontal" ) { 13988 this.range.css( { "height": "", "bottom": "" } ); 13989 } 13990 }, 13991 13992 _refreshValue: function() { 13993 var lastValPercent, valPercent, value, valueMin, valueMax, 13994 oRange = this.options.range, 13995 o = this.options, 13996 that = this, 13997 animate = ( !this._animateOff ) ? o.animate : false, 13998 _set = {}; 13999 14000 if ( this._hasMultipleValues() ) { 14001 this.handles.each( function( i ) { 14002 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 14003 that._valueMin() ) * 100; 14004 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14005 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14006 if ( that.options.range === true ) { 14007 if ( that.orientation === "horizontal" ) { 14008 if ( i === 0 ) { 14009 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14010 left: valPercent + "%" 14011 }, o.animate ); 14012 } 14013 if ( i === 1 ) { 14014 that.range[ animate ? "animate" : "css" ]( { 14015 width: ( valPercent - lastValPercent ) + "%" 14016 }, { 14017 queue: false, 14018 duration: o.animate 14019 } ); 14020 } 14021 } else { 14022 if ( i === 0 ) { 14023 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14024 bottom: ( valPercent ) + "%" 14025 }, o.animate ); 14026 } 14027 if ( i === 1 ) { 14028 that.range[ animate ? "animate" : "css" ]( { 14029 height: ( valPercent - lastValPercent ) + "%" 14030 }, { 14031 queue: false, 14032 duration: o.animate 14033 } ); 14034 } 14035 } 14036 } 14037 lastValPercent = valPercent; 14038 } ); 14039 } else { 14040 value = this.value(); 14041 valueMin = this._valueMin(); 14042 valueMax = this._valueMax(); 14043 valPercent = ( valueMax !== valueMin ) ? 14044 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 14045 0; 14046 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14047 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14048 14049 if ( oRange === "min" && this.orientation === "horizontal" ) { 14050 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14051 width: valPercent + "%" 14052 }, o.animate ); 14053 } 14054 if ( oRange === "max" && this.orientation === "horizontal" ) { 14055 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14056 width: ( 100 - valPercent ) + "%" 14057 }, o.animate ); 14058 } 14059 if ( oRange === "min" && this.orientation === "vertical" ) { 14060 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14061 height: valPercent + "%" 14062 }, o.animate ); 14063 } 14064 if ( oRange === "max" && this.orientation === "vertical" ) { 14065 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14066 height: ( 100 - valPercent ) + "%" 14067 }, o.animate ); 14068 } 14069 } 14070 }, 14071 14072 _handleEvents: { 14073 keydown: function( event ) { 14074 var allowed, curVal, newVal, step, 14075 index = $( event.target ).data( "ui-slider-handle-index" ); 14076 14077 switch ( event.keyCode ) { 14078 case $.ui.keyCode.HOME: 14079 case $.ui.keyCode.END: 14080 case $.ui.keyCode.PAGE_UP: 14081 case $.ui.keyCode.PAGE_DOWN: 14082 case $.ui.keyCode.UP: 14083 case $.ui.keyCode.RIGHT: 14084 case $.ui.keyCode.DOWN: 14085 case $.ui.keyCode.LEFT: 14086 event.preventDefault(); 14087 if ( !this._keySliding ) { 14088 this._keySliding = true; 14089 this._addClass( $( event.target ), null, "ui-state-active" ); 14090 allowed = this._start( event, index ); 14091 if ( allowed === false ) { 14092 return; 14093 } 14094 } 14095 break; 14096 } 14097 14098 step = this.options.step; 14099 if ( this._hasMultipleValues() ) { 14100 curVal = newVal = this.values( index ); 14101 } else { 14102 curVal = newVal = this.value(); 14103 } 14104 14105 switch ( event.keyCode ) { 14106 case $.ui.keyCode.HOME: 14107 newVal = this._valueMin(); 14108 break; 14109 case $.ui.keyCode.END: 14110 newVal = this._valueMax(); 14111 break; 14112 case $.ui.keyCode.PAGE_UP: 14113 newVal = this._trimAlignValue( 14114 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 14115 ); 14116 break; 14117 case $.ui.keyCode.PAGE_DOWN: 14118 newVal = this._trimAlignValue( 14119 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 14120 break; 14121 case $.ui.keyCode.UP:
vendor: 5,058 bytes, lines 14122-14320
14122 case $.ui.keyCode.RIGHT: 14123 if ( curVal === this._valueMax() ) { 14124 return; 14125 } 14126 newVal = this._trimAlignValue( curVal + step ); 14127 break; 14128 case $.ui.keyCode.DOWN: 14129 case $.ui.keyCode.LEFT: 14130 if ( curVal === this._valueMin() ) { 14131 return; 14132 } 14133 newVal = this._trimAlignValue( curVal - step ); 14134 break; 14135 } 14136 14137 this._slide( event, index, newVal ); 14138 }, 14139 keyup: function( event ) { 14140 var index = $( event.target ).data( "ui-slider-handle-index" ); 14141 14142 if ( this._keySliding ) { 14143 this._keySliding = false; 14144 this._stop( event, index ); 14145 this._change( event, index ); 14146 this._removeClass( $( event.target ), null, "ui-state-active" ); 14147 } 14148 } 14149 } 14150} ); 14151 14152 14153/*! 14154 * jQuery UI Spinner 1.12.1 14155 * http://jqueryui.com 14156 * 14157 * Copyright jQuery Foundation and other contributors 14158 * Released under the MIT license. 14159 * http://jquery.org/license 14160 */ 14161 14162//>>label: Spinner 14163//>>group: Widgets 14164//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 14165//>>docs: http://api.jqueryui.com/spinner/ 14166//>>demos: http://jqueryui.com/spinner/ 14167//>>css.structure: ../../themes/base/core.css 14168//>>css.structure: ../../themes/base/spinner.css 14169//>>css.theme: ../../themes/base/theme.css 14170 14171 14172 14173function spinnerModifer( fn ) { 14174 return function() { 14175 var previous = this.element.val(); 14176 fn.apply( this, arguments ); 14177 this._refresh(); 14178 if ( previous !== this.element.val() ) { 14179 this._trigger( "change" ); 14180 } 14181 }; 14182} 14183 14184$.widget( "ui.spinner", { 14185 version: "1.12.1", 14186 defaultElement: "<input>", 14187 widgetEventPrefix: "spin", 14188 options: { 14189 classes: { 14190 "ui-spinner": "ui-corner-all", 14191 "ui-spinner-down": "ui-corner-br", 14192 "ui-spinner-up": "ui-corner-tr" 14193 }, 14194 culture: null, 14195 icons: { 14196 down: "ui-icon-triangle-1-s", 14197 up: "ui-icon-triangle-1-n" 14198 }, 14199 incremental: true, 14200 max: null, 14201 min: null, 14202 numberFormat: null, 14203 page: 10, 14204 step: 1, 14205 14206 change: null, 14207 spin: null, 14208 start: null, 14209 stop: null 14210 }, 14211 14212 _create: function() { 14213 14214 // handle string values that need to be parsed 14215 this._setOption( "max", this.options.max ); 14216 this._setOption( "min", this.options.min ); 14217 this._setOption( "step", this.options.step ); 14218 14219 // Only format if there is a value, prevents the field from being marked 14220 // as invalid in Firefox, see #9573. 14221 if ( this.value() !== "" ) { 14222 14223 // Format the value, but don't constrain. 14224 this._value( this.element.val(), true ); 14225 } 14226 14227 this._draw(); 14228 this._on( this._events ); 14229 this._refresh(); 14230 14231 // Turning off autocomplete prevents the browser from remembering the 14232 // value when navigating through history, so we re-enable autocomplete 14233 // if the page is unloaded before the widget is destroyed. #7790 14234 this._on( this.window, { 14235 beforeunload: function() { 14236 this.element.removeAttr( "autocomplete" ); 14237 } 14238 } ); 14239 }, 14240 14241 _getCreateOptions: function() { 14242 var options = this._super(); 14243 var element = this.element; 14244 14245 $.each( [ "min", "max", "step" ], function( i, option ) { 14246 var value = element.attr( option ); 14247 if ( value != null && value.length ) { 14248 options[ option ] = value; 14249 } 14250 } ); 14251 14252 return options; 14253 }, 14254 14255 _events: { 14256 keydown: function( event ) { 14257 if ( this._start( event ) && this._keydown( event ) ) { 14258 event.preventDefault(); 14259 } 14260 }, 14261 keyup: "_stop", 14262 focus: function() { 14263 this.previous = this.element.val(); 14264 }, 14265 blur: function( event ) { 14266 if ( this.cancelBlur ) { 14267 delete this.cancelBlur; 14268 return; 14269 } 14270 14271 this._stop(); 14272 this._refresh(); 14273 if ( this.previous !== this.element.val() ) { 14274 this._trigger( "change", event ); 14275 } 14276 }, 14277 mousewheel: function( event, delta ) { 14278 if ( !delta ) { 14279 return; 14280 } 14281 if ( !this.spinning && !this._start( event ) ) { 14282 return false; 14283 } 14284 14285 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 14286 clearTimeout( this.mousewheelTimer ); 14287 this.mousewheelTimer = this._delay( function() { 14288 if ( this.spinning ) { 14289 this._stop( event ); 14290 } 14291 }, 100 ); 14292 event.preventDefault(); 14293 }, 14294 "mousedown .ui-spinner-button": function( event ) { 14295 var previous; 14296 14297 // We never want the buttons to have focus; whenever the user is 14298 // interacting with the spinner, the focus should be on the input. 14299 // If the input is focused then this.previous is properly set from 14300 // when the input first received focus. If the input is not focused 14301 // then we need to set this.previous based on the value before spinning. 14302 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? 14303 this.previous : this.element.val(); 14304 function checkFocus() { 14305 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); 14306 if ( !isActive ) { 14307 this.element.trigger( "focus" ); 14308 this.previous = previous; 14309 14310 // support: IE 14311 // IE sets focus asynchronously, so we need to check if focus 14312 // moved off of the input because the user clicked on the button. 14313 this._delay( function() { 14314 this.previous = previous; 14315 } ); 14316 } 14317 } 14318 14319 // Ensure focus is on (or stays on) the text field 14320 event.preventDefault();
vendor: 42,977 bytes, lines 14321-15975
14321 checkFocus.call( this ); 14322 14323 // Support: IE 14324 // IE doesn't prevent moving focus even with event.preventDefault() 14325 // so we set a flag to know when we should ignore the blur event 14326 // and check (again) if focus moved off of the input. 14327 this.cancelBlur = true; 14328 this._delay( function() { 14329 delete this.cancelBlur; 14330 checkFocus.call( this ); 14331 } ); 14332 14333 if ( this._start( event ) === false ) { 14334 return; 14335 } 14336 14337 this._repeat( null, $( event.currentTarget ) 14338 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14339 }, 14340 "mouseup .ui-spinner-button": "_stop", 14341 "mouseenter .ui-spinner-button": function( event ) { 14342 14343 // button will add ui-state-active if mouse was down while mouseleave and kept down 14344 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14345 return; 14346 } 14347 14348 if ( this._start( event ) === false ) { 14349 return false; 14350 } 14351 this._repeat( null, $( event.currentTarget ) 14352 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14353 }, 14354 14355 // TODO: do we really want to consider this a stop? 14356 // shouldn't we just stop the repeater and wait until mouseup before 14357 // we trigger the stop event? 14358 "mouseleave .ui-spinner-button": "_stop" 14359 }, 14360 14361 // Support mobile enhanced option and make backcompat more sane 14362 _enhance: function() { 14363 this.uiSpinner = this.element 14364 .attr( "autocomplete", "off" ) 14365 .wrap( "<span>" ) 14366 .parent() 14367 14368 // Add buttons 14369 .append( 14370 "<a></a><a></a>" 14371 ); 14372 }, 14373 14374 _draw: function() { 14375 this._enhance(); 14376 14377 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 14378 this._addClass( "ui-spinner-input" ); 14379 14380 this.element.attr( "role", "spinbutton" ); 14381 14382 // Button bindings 14383 this.buttons = this.uiSpinner.children( "a" ) 14384 .attr( "tabIndex", -1 ) 14385 .attr( "aria-hidden", true ) 14386 .button( { 14387 classes: { 14388 "ui-button": "" 14389 } 14390 } ); 14391 14392 // TODO: Right now button does not support classes this is already updated in button PR 14393 this._removeClass( this.buttons, "ui-corner-all" ); 14394 14395 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 14396 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 14397 this.buttons.first().button( { 14398 "icon": this.options.icons.up, 14399 "showLabel": false 14400 } ); 14401 this.buttons.last().button( { 14402 "icon": this.options.icons.down, 14403 "showLabel": false 14404 } ); 14405 14406 // IE 6 doesn't understand height: 50% for the buttons 14407 // unless the wrapper has an explicit height 14408 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 14409 this.uiSpinner.height() > 0 ) { 14410 this.uiSpinner.height( this.uiSpinner.height() ); 14411 } 14412 }, 14413 14414 _keydown: function( event ) { 14415 var options = this.options, 14416 keyCode = $.ui.keyCode; 14417 14418 switch ( event.keyCode ) { 14419 case keyCode.UP: 14420 this._repeat( null, 1, event ); 14421 return true; 14422 case keyCode.DOWN: 14423 this._repeat( null, -1, event ); 14424 return true; 14425 case keyCode.PAGE_UP: 14426 this._repeat( null, options.page, event ); 14427 return true; 14428 case keyCode.PAGE_DOWN: 14429 this._repeat( null, -options.page, event ); 14430 return true; 14431 } 14432 14433 return false; 14434 }, 14435 14436 _start: function( event ) { 14437 if ( !this.spinning && this._trigger( "start", event ) === false ) { 14438 return false; 14439 } 14440 14441 if ( !this.counter ) { 14442 this.counter = 1; 14443 } 14444 this.spinning = true; 14445 return true; 14446 }, 14447 14448 _repeat: function( i, steps, event ) { 14449 i = i || 500; 14450 14451 clearTimeout( this.timer ); 14452 this.timer = this._delay( function() { 14453 this._repeat( 40, steps, event ); 14454 }, i ); 14455 14456 this._spin( steps * this.options.step, event ); 14457 }, 14458 14459 _spin: function( step, event ) { 14460 var value = this.value() || 0; 14461 14462 if ( !this.counter ) { 14463 this.counter = 1; 14464 } 14465 14466 value = this._adjustValue( value + step * this._increment( this.counter ) ); 14467 14468 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 14469 this._value( value ); 14470 this.counter++; 14471 } 14472 }, 14473 14474 _increment: function( i ) { 14475 var incremental = this.options.incremental; 14476 14477 if ( incremental ) { 14478 return $.isFunction( incremental ) ? 14479 incremental( i ) : 14480 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 14481 } 14482 14483 return 1; 14484 }, 14485 14486 _precision: function() { 14487 var precision = this._precisionOf( this.options.step ); 14488 if ( this.options.min !== null ) { 14489 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14490 } 14491 return precision; 14492 }, 14493 14494 _precisionOf: function( num ) { 14495 var str = num.toString(), 14496 decimal = str.indexOf( "." ); 14497 return decimal === -1 ? 0 : str.length - decimal - 1; 14498 }, 14499 14500 _adjustValue: function( value ) { 14501 var base, aboveMin, 14502 options = this.options; 14503 14504 // Make sure we're at a valid step 14505 // - find out where we are relative to the base (min or 0) 14506 base = options.min !== null ? options.min : 0; 14507 aboveMin = value - base; 14508 14509 // - round to the nearest step 14510 aboveMin = Math.round( aboveMin / options.step ) * options.step; 14511 14512 // - rounding is based on 0, so adjust back to our base 14513 value = base + aboveMin; 14514 14515 // Fix precision from bad JS floating point math 14516 value = parseFloat( value.toFixed( this._precision() ) ); 14517 14518 // Clamp the value 14519 if ( options.max !== null && value > options.max ) { 14520 return options.max; 14521 } 14522 if ( options.min !== null && value < options.min ) { 14523 return options.min; 14524 } 14525 14526 return value; 14527 }, 14528 14529 _stop: function( event ) { 14530 if ( !this.spinning ) { 14531 return; 14532 } 14533 14534 clearTimeout( this.timer ); 14535 clearTimeout( this.mousewheelTimer ); 14536 this.counter = 0; 14537 this.spinning = false; 14538 this._trigger( "stop", event ); 14539 }, 14540 14541 _setOption: function( key, value ) { 14542 var prevValue, first, last; 14543 14544 if ( key === "culture" || key === "numberFormat" ) { 14545 prevValue = this._parse( this.element.val() ); 14546 this.options[ key ] = value; 14547 this.element.val( this._format( prevValue ) ); 14548 return; 14549 } 14550 14551 if ( key === "max" || key === "min" || key === "step" ) { 14552 if ( typeof value === "string" ) { 14553 value = this._parse( value ); 14554 } 14555 } 14556 if ( key === "icons" ) { 14557 first = this.buttons.first().find( ".ui-icon" ); 14558 this._removeClass( first, null, this.options.icons.up ); 14559 this._addClass( first, null, value.up ); 14560 last = this.buttons.last().find( ".ui-icon" ); 14561 this._removeClass( last, null, this.options.icons.down ); 14562 this._addClass( last, null, value.down ); 14563 } 14564 14565 this._super( key, value ); 14566 }, 14567 14568 _setOptionDisabled: function( value ) { 14569 this._super( value ); 14570 14571 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 14572 this.element.prop( "disabled", !!value ); 14573 this.buttons.button( value ? "disable" : "enable" ); 14574 }, 14575 14576 _setOptions: spinnerModifer( function( options ) { 14577 this._super( options ); 14578 } ), 14579 14580 _parse: function( val ) { 14581 if ( typeof val === "string" && val !== "" ) { 14582 val = window.Globalize && this.options.numberFormat ? 14583 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 14584 } 14585 return val === "" || isNaN( val ) ? null : val; 14586 }, 14587 14588 _format: function( value ) { 14589 if ( value === "" ) { 14590 return ""; 14591 } 14592 return window.Globalize && this.options.numberFormat ? 14593 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 14594 value; 14595 }, 14596 14597 _refresh: function() { 14598 this.element.attr( { 14599 "aria-valuemin": this.options.min, 14600 "aria-valuemax": this.options.max, 14601 14602 // TODO: what should we do with values that can't be parsed? 14603 "aria-valuenow": this._parse( this.element.val() ) 14604 } ); 14605 }, 14606 14607 isValid: function() { 14608 var value = this.value(); 14609 14610 // Null is invalid 14611 if ( value === null ) { 14612 return false; 14613 } 14614 14615 // If value gets adjusted, it's invalid 14616 return value === this._adjustValue( value ); 14617 }, 14618 14619 // Update the value without triggering change 14620 _value: function( value, allowAny ) { 14621 var parsed; 14622 if ( value !== "" ) { 14623 parsed = this._parse( value ); 14624 if ( parsed !== null ) { 14625 if ( !allowAny ) { 14626 parsed = this._adjustValue( parsed ); 14627 } 14628 value = this._format( parsed ); 14629 } 14630 } 14631 this.element.val( value ); 14632 this._refresh(); 14633 }, 14634 14635 _destroy: function() { 14636 this.element 14637 .prop( "disabled", false ) 14638 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 14639 14640 this.uiSpinner.replaceWith( this.element ); 14641 }, 14642 14643 stepUp: spinnerModifer( function( steps ) { 14644 this._stepUp( steps ); 14645 } ), 14646 _stepUp: function( steps ) { 14647 if ( this._start() ) { 14648 this._spin( ( steps || 1 ) * this.options.step ); 14649 this._stop(); 14650 } 14651 }, 14652 14653 stepDown: spinnerModifer( function( steps ) { 14654 this._stepDown( steps ); 14655 } ), 14656 _stepDown: function( steps ) { 14657 if ( this._start() ) { 14658 this._spin( ( steps || 1 ) * -this.options.step ); 14659 this._stop(); 14660 } 14661 }, 14662 14663 pageUp: spinnerModifer( function( pages ) { 14664 this._stepUp( ( pages || 1 ) * this.options.page ); 14665 } ), 14666 14667 pageDown: spinnerModifer( function( pages ) { 14668 this._stepDown( ( pages || 1 ) * this.options.page ); 14669 } ), 14670 14671 value: function( newVal ) { 14672 if ( !arguments.length ) { 14673 return this._parse( this.element.val() ); 14674 } 14675 spinnerModifer( this._value ).call( this, newVal ); 14676 }, 14677 14678 widget: function() { 14679 return this.uiSpinner; 14680 } 14681} ); 14682 14683// DEPRECATED 14684// TODO: switch return back to widget declaration at top of file when this is removed 14685if ( $.uiBackCompat !== false ) { 14686 14687 // Backcompat for spinner html extension points 14688 $.widget( "ui.spinner", $.ui.spinner, { 14689 _enhance: function() { 14690 this.uiSpinner = this.element 14691 .attr( "autocomplete", "off" ) 14692 .wrap( this._uiSpinnerHtml() ) 14693 .parent() 14694 14695 // Add buttons 14696 .append( this._buttonHtml() ); 14697 }, 14698 _uiSpinnerHtml: function() { 14699 return "<span>"; 14700 }, 14701 14702 _buttonHtml: function() { 14703 return "<a></a><a></a>"; 14704 } 14705 } ); 14706} 14707 14708var widgetsSpinner = $.ui.spinner; 14709 14710 14711/*! 14712 * jQuery UI Tabs 1.12.1 14713 * http://jqueryui.com 14714 * 14715 * Copyright jQuery Foundation and other contributors 14716 * Released under the MIT license. 14717 * http://jquery.org/license 14718 */ 14719 14720//>>label: Tabs 14721//>>group: Widgets 14722//>>description: Transforms a set of container elements into a tab structure. 14723//>>docs: http://api.jqueryui.com/tabs/ 14724//>>demos: http://jqueryui.com/tabs/ 14725//>>css.structure: ../../themes/base/core.css 14726//>>css.structure: ../../themes/base/tabs.css 14727//>>css.theme: ../../themes/base/theme.css 14728 14729 14730 14731$.widget( "ui.tabs", { 14732 version: "1.12.1", 14733 delay: 300, 14734 options: { 14735 active: null, 14736 classes: { 14737 "ui-tabs": "ui-corner-all", 14738 "ui-tabs-nav": "ui-corner-all", 14739 "ui-tabs-panel": "ui-corner-bottom", 14740 "ui-tabs-tab": "ui-corner-top" 14741 }, 14742 collapsible: false, 14743 event: "click", 14744 heightStyle: "content", 14745 hide: null, 14746 show: null, 14747 14748 // Callbacks 14749 activate: null, 14750 beforeActivate: null, 14751 beforeLoad: null, 14752 load: null 14753 }, 14754 14755 _isLocal: ( function() { 14756 var rhash = /#.*$/; 14757 14758 return function( anchor ) { 14759 var anchorUrl, locationUrl; 14760 14761 anchorUrl = anchor.href.replace( rhash, "" ); 14762 locationUrl = location.href.replace( rhash, "" ); 14763 14764 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 14765 try { 14766 anchorUrl = decodeURIComponent( anchorUrl ); 14767 } catch ( error ) {} 14768 try { 14769 locationUrl = decodeURIComponent( locationUrl ); 14770 } catch ( error ) {} 14771 14772 return anchor.hash.length > 1 && anchorUrl === locationUrl; 14773 }; 14774 } )(), 14775 14776 _create: function() { 14777 var that = this, 14778 options = this.options; 14779 14780 this.running = false; 14781 14782 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 14783 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 14784 14785 this._processTabs(); 14786 options.active = this._initialActive(); 14787 14788 // Take disabling tabs via class attribute from HTML 14789 // into account and update option properly. 14790 if ( $.isArray( options.disabled ) ) { 14791 options.disabled = $.unique( options.disabled.concat( 14792 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 14793 return that.tabs.index( li ); 14794 } ) 14795 ) ).sort(); 14796 } 14797 14798 // Check for length avoids error when initializing empty list 14799 if ( this.options.active !== false && this.anchors.length ) { 14800 this.active = this._findActive( options.active ); 14801 } else { 14802 this.active = $(); 14803 } 14804 14805 this._refresh(); 14806 14807 if ( this.active.length ) { 14808 this.load( options.active ); 14809 } 14810 }, 14811 14812 _initialActive: function() { 14813 var active = this.options.active, 14814 collapsible = this.options.collapsible, 14815 locationHash = location.hash.substring( 1 ); 14816 14817 if ( active === null ) { 14818 14819 // check the fragment identifier in the URL 14820 if ( locationHash ) { 14821 this.tabs.each( function( i, tab ) { 14822 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 14823 active = i; 14824 return false; 14825 } 14826 } ); 14827 } 14828 14829 // Check for a tab marked active via a class 14830 if ( active === null ) { 14831 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 14832 } 14833 14834 // No active tab, set to false 14835 if ( active === null || active === -1 ) { 14836 active = this.tabs.length ? 0 : false; 14837 } 14838 } 14839 14840 // Handle numbers: negative, out of range 14841 if ( active !== false ) { 14842 active = this.tabs.index( this.tabs.eq( active ) ); 14843 if ( active === -1 ) { 14844 active = collapsible ? false : 0; 14845 } 14846 } 14847 14848 // Don't allow collapsible: false and active: false 14849 if ( !collapsible && active === false && this.anchors.length ) { 14850 active = 0; 14851 } 14852 14853 return active; 14854 }, 14855 14856 _getCreateEventData: function() { 14857 return { 14858 tab: this.active, 14859 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 14860 }; 14861 }, 14862 14863 _tabKeydown: function( event ) { 14864 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), 14865 selectedIndex = this.tabs.index( focusedTab ), 14866 goingForward = true; 14867 14868 if ( this._handlePageNav( event ) ) { 14869 return; 14870 } 14871 14872 switch ( event.keyCode ) { 14873 case $.ui.keyCode.RIGHT: 14874 case $.ui.keyCode.DOWN: 14875 selectedIndex++; 14876 break; 14877 case $.ui.keyCode.UP: 14878 case $.ui.keyCode.LEFT: 14879 goingForward = false; 14880 selectedIndex--; 14881 break; 14882 case $.ui.keyCode.END: 14883 selectedIndex = this.anchors.length - 1; 14884 break; 14885 case $.ui.keyCode.HOME: 14886 selectedIndex = 0; 14887 break; 14888 case $.ui.keyCode.SPACE: 14889 14890 // Activate only, no collapsing 14891 event.preventDefault(); 14892 clearTimeout( this.activating ); 14893 this._activate( selectedIndex ); 14894 return; 14895 case $.ui.keyCode.ENTER: 14896 14897 // Toggle (cancel delayed activation, allow collapsing) 14898 event.preventDefault(); 14899 clearTimeout( this.activating ); 14900 14901 // Determine if we should collapse or activate 14902 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 14903 return; 14904 default: 14905 return; 14906 } 14907 14908 // Focus the appropriate tab, based on which key was pressed 14909 event.preventDefault(); 14910 clearTimeout( this.activating ); 14911 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 14912 14913 // Navigating with control/command key will prevent automatic activation 14914 if ( !event.ctrlKey && !event.metaKey ) { 14915 14916 // Update aria-selected immediately so that AT think the tab is already selected. 14917 // Otherwise AT may confuse the user by stating that they need to activate the tab, 14918 // but the tab will already be activated by the time the announcement finishes. 14919 focusedTab.attr( "aria-selected", "false" ); 14920 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 14921 14922 this.activating = this._delay( function() { 14923 this.option( "active", selectedIndex ); 14924 }, this.delay ); 14925 } 14926 }, 14927 14928 _panelKeydown: function( event ) { 14929 if ( this._handlePageNav( event ) ) { 14930 return; 14931 } 14932 14933 // Ctrl+up moves focus to the current tab 14934 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 14935 event.preventDefault(); 14936 this.active.trigger( "focus" ); 14937 } 14938 }, 14939 14940 // Alt+page up/down moves focus to the previous/next tab (and activates) 14941 _handlePageNav: function( event ) { 14942 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 14943 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 14944 return true; 14945 } 14946 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14947 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14948 return true; 14949 } 14950 }, 14951 14952 _findNextTab: function( index, goingForward ) { 14953 var lastTabIndex = this.tabs.length - 1; 14954 14955 function constrain() { 14956 if ( index > lastTabIndex ) { 14957 index = 0; 14958 } 14959 if ( index < 0 ) { 14960 index = lastTabIndex; 14961 } 14962 return index; 14963 } 14964 14965 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14966 index = goingForward ? index + 1 : index - 1; 14967 } 14968 14969 return index; 14970 }, 14971 14972 _focusNextTab: function( index, goingForward ) { 14973 index = this._findNextTab( index, goingForward ); 14974 this.tabs.eq( index ).trigger( "focus" ); 14975 return index; 14976 }, 14977 14978 _setOption: function( key, value ) { 14979 if ( key === "active" ) { 14980 14981 // _activate() will handle invalid values and update this.options 14982 this._activate( value ); 14983 return; 14984 } 14985 14986 this._super( key, value ); 14987 14988 if ( key === "collapsible" ) { 14989 this._toggleClass( "ui-tabs-collapsible", null, value ); 14990 14991 // Setting collapsible: false while collapsed; open first panel 14992 if ( !value && this.options.active === false ) { 14993 this._activate( 0 ); 14994 } 14995 } 14996 14997 if ( key === "event" ) { 14998 this._setupEvents( value ); 14999 } 15000 15001 if ( key === "heightStyle" ) { 15002 this._setupHeightStyle( value ); 15003 } 15004 }, 15005 15006 _sanitizeSelector: function( hash ) { 15007 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 15008 }, 15009 15010 refresh: function() { 15011 var options = this.options, 15012 lis = this.tablist.children( ":has(a[href])" ); 15013 15014 // Get disabled tabs from class attribute from HTML 15015 // this will get converted to a boolean if needed in _refresh() 15016 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15017 return lis.index( tab ); 15018 } ); 15019 15020 this._processTabs(); 15021 15022 // Was collapsed or no tabs 15023 if ( options.active === false || !this.anchors.length ) { 15024 options.active = false; 15025 this.active = $(); 15026 15027 // was active, but active tab is gone 15028 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15029 15030 // all remaining tabs are disabled 15031 if ( this.tabs.length === options.disabled.length ) { 15032 options.active = false; 15033 this.active = $(); 15034 15035 // activate previous tab 15036 } else { 15037 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15038 } 15039 15040 // was active, active tab still exists 15041 } else { 15042 15043 // make sure active index is correct 15044 options.active = this.tabs.index( this.active ); 15045 } 15046 15047 this._refresh(); 15048 }, 15049 15050 _refresh: function() { 15051 this._setOptionDisabled( this.options.disabled ); 15052 this._setupEvents( this.options.event ); 15053 this._setupHeightStyle( this.options.heightStyle ); 15054 15055 this.tabs.not( this.active ).attr( { 15056 "aria-selected": "false", 15057 "aria-expanded": "false", 15058 tabIndex: -1 15059 } ); 15060 this.panels.not( this._getPanelForTab( this.active ) ) 15061 .hide() 15062 .attr( { 15063 "aria-hidden": "true" 15064 } ); 15065 15066 // Make sure one tab is in the tab order 15067 if ( !this.active.length ) { 15068 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15069 } else { 15070 this.active 15071 .attr( { 15072 "aria-selected": "true", 15073 "aria-expanded": "true", 15074 tabIndex: 0 15075 } ); 15076 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 15077 this._getPanelForTab( this.active ) 15078 .show() 15079 .attr( { 15080 "aria-hidden": "false" 15081 } ); 15082 } 15083 }, 15084 15085 _processTabs: function() { 15086 var that = this, 15087 prevTabs = this.tabs, 15088 prevAnchors = this.anchors, 15089 prevPanels = this.panels; 15090 15091 this.tablist = this._getList().attr( "role", "tablist" ); 15092 this._addClass( this.tablist, "ui-tabs-nav", 15093 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 15094 15095 // Prevent users from focusing disabled tabs via click 15096 this.tablist 15097 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 15098 if ( $( this ).is( ".ui-state-disabled" ) ) { 15099 event.preventDefault(); 15100 } 15101 } ) 15102 15103 // Support: IE <9 15104 // Preventing the default action in mousedown doesn't prevent IE 15105 // from focusing the element, so if the anchor gets focused, blur. 15106 // We don't have to worry about focusing the previously focused 15107 // element since clicking on a non-focusable element should focus 15108 // the body anyway. 15109 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { 15110 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 15111 this.blur(); 15112 } 15113 } ); 15114 15115 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15116 .attr( { 15117 role: "tab", 15118 tabIndex: -1 15119 } ); 15120 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 15121 15122 this.anchors = this.tabs.map( function() { 15123 return $( "a", this )[ 0 ]; 15124 } ) 15125 .attr( { 15126 role: "presentation", 15127 tabIndex: -1 15128 } ); 15129 this._addClass( this.anchors, "ui-tabs-anchor" ); 15130 15131 this.panels = $(); 15132 15133 this.anchors.each( function( i, anchor ) { 15134 var selector, panel, panelId, 15135 anchorId = $( anchor ).uniqueId().attr( "id" ), 15136 tab = $( anchor ).closest( "li" ), 15137 originalAriaControls = tab.attr( "aria-controls" ); 15138 15139 // Inline tab 15140 if ( that._isLocal( anchor ) ) { 15141 selector = anchor.hash; 15142 panelId = selector.substring( 1 ); 15143 panel = that.element.find( that._sanitizeSelector( selector ) ); 15144 15145 // remote tab 15146 } else { 15147 15148 // If the tab doesn't already have aria-controls, 15149 // generate an id by using a throw-away element 15150 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15151 selector = "#" + panelId; 15152 panel = that.element.find( selector ); 15153 if ( !panel.length ) { 15154 panel = that._createPanel( panelId ); 15155 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15156 } 15157 panel.attr( "aria-live", "polite" ); 15158 } 15159 15160 if ( panel.length ) { 15161 that.panels = that.panels.add( panel ); 15162 } 15163 if ( originalAriaControls ) { 15164 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15165 } 15166 tab.attr( { 15167 "aria-controls": panelId, 15168 "aria-labelledby": anchorId 15169 } ); 15170 panel.attr( "aria-labelledby", anchorId ); 15171 } ); 15172 15173 this.panels.attr( "role", "tabpanel" ); 15174 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 15175 15176 // Avoid memory leaks (#10056) 15177 if ( prevTabs ) { 15178 this._off( prevTabs.not( this.tabs ) ); 15179 this._off( prevAnchors.not( this.anchors ) ); 15180 this._off( prevPanels.not( this.panels ) ); 15181 } 15182 }, 15183 15184 // Allow overriding how to find the list for rare usage scenarios (#7715) 15185 _getList: function() { 15186 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 15187 }, 15188 15189 _createPanel: function( id ) { 15190 return $( "<div>" ) 15191 .attr( "id", id ) 15192 .data( "ui-tabs-destroy", true ); 15193 }, 15194 15195 _setOptionDisabled: function( disabled ) { 15196 var currentItem, li, i; 15197 15198 if ( $.isArray( disabled ) ) { 15199 if ( !disabled.length ) { 15200 disabled = false; 15201 } else if ( disabled.length === this.anchors.length ) { 15202 disabled = true; 15203 } 15204 } 15205 15206 // Disable tabs 15207 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 15208 currentItem = $( li ); 15209 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15210 currentItem.attr( "aria-disabled", "true" ); 15211 this._addClass( currentItem, null, "ui-state-disabled" ); 15212 } else { 15213 currentItem.removeAttr( "aria-disabled" ); 15214 this._removeClass( currentItem, null, "ui-state-disabled" ); 15215 } 15216 } 15217 15218 this.options.disabled = disabled; 15219 15220 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 15221 disabled === true ); 15222 }, 15223 15224 _setupEvents: function( event ) { 15225 var events = {}; 15226 if ( event ) { 15227 $.each( event.split( " " ), function( index, eventName ) { 15228 events[ eventName ] = "_eventHandler"; 15229 } ); 15230 } 15231 15232 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15233 15234 // Always prevent the default action, even when disabled 15235 this._on( true, this.anchors, { 15236 click: function( event ) { 15237 event.preventDefault(); 15238 } 15239 } ); 15240 this._on( this.anchors, events ); 15241 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15242 this._on( this.panels, { keydown: "_panelKeydown" } ); 15243 15244 this._focusable( this.tabs ); 15245 this._hoverable( this.tabs ); 15246 }, 15247 15248 _setupHeightStyle: function( heightStyle ) { 15249 var maxHeight, 15250 parent = this.element.parent(); 15251 15252 if ( heightStyle === "fill" ) { 15253 maxHeight = parent.height(); 15254 maxHeight -= this.element.outerHeight() - this.element.height(); 15255 15256 this.element.siblings( ":visible" ).each( function() { 15257 var elem = $( this ), 15258 position = elem.css( "position" ); 15259 15260 if ( position === "absolute" || position === "fixed" ) { 15261 return; 15262 } 15263 maxHeight -= elem.outerHeight( true ); 15264 } ); 15265 15266 this.element.children().not( this.panels ).each( function() { 15267 maxHeight -= $( this ).outerHeight( true ); 15268 } ); 15269 15270 this.panels.each( function() { 15271 $( this ).height( Math.max( 0, maxHeight - 15272 $( this ).innerHeight() + $( this ).height() ) ); 15273 } ) 15274 .css( "overflow", "auto" ); 15275 } else if ( heightStyle === "auto" ) { 15276 maxHeight = 0; 15277 this.panels.each( function() { 15278 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15279 } ).height( maxHeight ); 15280 } 15281 }, 15282 15283 _eventHandler: function( event ) { 15284 var options = this.options, 15285 active = this.active, 15286 anchor = $( event.currentTarget ), 15287 tab = anchor.closest( "li" ), 15288 clickedIsActive = tab[ 0 ] === active[ 0 ], 15289 collapsing = clickedIsActive && options.collapsible, 15290 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15291 toHide = !active.length ? $() : this._getPanelForTab( active ), 15292 eventData = { 15293 oldTab: active, 15294 oldPanel: toHide, 15295 newTab: collapsing ? $() : tab, 15296 newPanel: toShow 15297 }; 15298 15299 event.preventDefault(); 15300 15301 if ( tab.hasClass( "ui-state-disabled" ) || 15302 15303 // tab is already loading 15304 tab.hasClass( "ui-tabs-loading" ) || 15305 15306 // can't switch durning an animation 15307 this.running || 15308 15309 // click on active header, but not collapsible 15310 ( clickedIsActive && !options.collapsible ) || 15311 15312 // allow canceling activation 15313 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15314 return; 15315 } 15316 15317 options.active = collapsing ? false : this.tabs.index( tab ); 15318 15319 this.active = clickedIsActive ? $() : tab; 15320 if ( this.xhr ) { 15321 this.xhr.abort(); 15322 } 15323 15324 if ( !toHide.length && !toShow.length ) { 15325 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15326 } 15327 15328 if ( toShow.length ) { 15329 this.load( this.tabs.index( tab ), event ); 15330 } 15331 this._toggle( event, eventData ); 15332 }, 15333 15334 // Handles show/hide for selecting tabs 15335 _toggle: function( event, eventData ) { 15336 var that = this, 15337 toShow = eventData.newPanel, 15338 toHide = eventData.oldPanel; 15339 15340 this.running = true; 15341 15342 function complete() { 15343 that.running = false; 15344 that._trigger( "activate", event, eventData ); 15345 } 15346 15347 function show() { 15348 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 15349 15350 if ( toShow.length && that.options.show ) { 15351 that._show( toShow, that.options.show, complete ); 15352 } else { 15353 toShow.show(); 15354 complete(); 15355 } 15356 } 15357 15358 // Start out by hiding, then showing, then completing 15359 if ( toHide.length && this.options.hide ) { 15360 this._hide( toHide, this.options.hide, function() { 15361 that._removeClass( eventData.oldTab.closest( "li" ), 15362 "ui-tabs-active", "ui-state-active" ); 15363 show(); 15364 } ); 15365 } else { 15366 this._removeClass( eventData.oldTab.closest( "li" ), 15367 "ui-tabs-active", "ui-state-active" ); 15368 toHide.hide(); 15369 show(); 15370 } 15371 15372 toHide.attr( "aria-hidden", "true" ); 15373 eventData.oldTab.attr( { 15374 "aria-selected": "false", 15375 "aria-expanded": "false" 15376 } ); 15377 15378 // If we're switching tabs, remove the old tab from the tab order. 15379 // If we're opening from collapsed state, remove the previous tab from the tab order. 15380 // If we're collapsing, then keep the collapsing tab in the tab order. 15381 if ( toShow.length && toHide.length ) { 15382 eventData.oldTab.attr( "tabIndex", -1 ); 15383 } else if ( toShow.length ) { 15384 this.tabs.filter( function() { 15385 return $( this ).attr( "tabIndex" ) === 0; 15386 } ) 15387 .attr( "tabIndex", -1 ); 15388 } 15389 15390 toShow.attr( "aria-hidden", "false" ); 15391 eventData.newTab.attr( { 15392 "aria-selected": "true", 15393 "aria-expanded": "true", 15394 tabIndex: 0 15395 } ); 15396 }, 15397 15398 _activate: function( index ) { 15399 var anchor, 15400 active = this._findActive( index ); 15401 15402 // Trying to activate the already active panel 15403 if ( active[ 0 ] === this.active[ 0 ] ) { 15404 return; 15405 } 15406 15407 // Trying to collapse, simulate a click on the current active header 15408 if ( !active.length ) { 15409 active = this.active; 15410 } 15411 15412 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15413 this._eventHandler( { 15414 target: anchor, 15415 currentTarget: anchor, 15416 preventDefault: $.noop 15417 } ); 15418 }, 15419 15420 _findActive: function( index ) { 15421 return index === false ? $() : this.tabs.eq( index ); 15422 }, 15423 15424 _getIndex: function( index ) { 15425 15426 // meta-function to give users option to provide a href string instead of a numerical index. 15427 if ( typeof index === "string" ) { 15428 index = this.anchors.index( this.anchors.filter( "[href$='" + 15429 $.ui.escapeSelector( index ) + "']" ) ); 15430 } 15431 15432 return index; 15433 }, 15434 15435 _destroy: function() { 15436 if ( this.xhr ) { 15437 this.xhr.abort(); 15438 } 15439 15440 this.tablist 15441 .removeAttr( "role" ) 15442 .off( this.eventNamespace ); 15443 15444 this.anchors 15445 .removeAttr( "role tabIndex" ) 15446 .removeUniqueId(); 15447 15448 this.tabs.add( this.panels ).each( function() { 15449 if ( $.data( this, "ui-tabs-destroy" ) ) { 15450 $( this ).remove(); 15451 } else { 15452 $( this ).removeAttr( "role tabIndex " + 15453 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 15454 } 15455 } ); 15456 15457 this.tabs.each( function() { 15458 var li = $( this ), 15459 prev = li.data( "ui-tabs-aria-controls" ); 15460 if ( prev ) { 15461 li 15462 .attr( "aria-controls", prev ) 15463 .removeData( "ui-tabs-aria-controls" ); 15464 } else { 15465 li.removeAttr( "aria-controls" ); 15466 } 15467 } ); 15468 15469 this.panels.show(); 15470 15471 if ( this.options.heightStyle !== "content" ) { 15472 this.panels.css( "height", "" ); 15473 } 15474 }, 15475 15476 enable: function( index ) { 15477 var disabled = this.options.disabled; 15478 if ( disabled === false ) { 15479 return; 15480 } 15481 15482 if ( index === undefined ) { 15483 disabled = false; 15484 } else { 15485 index = this._getIndex( index ); 15486 if ( $.isArray( disabled ) ) { 15487 disabled = $.map( disabled, function( num ) { 15488 return num !== index ? num : null; 15489 } ); 15490 } else { 15491 disabled = $.map( this.tabs, function( li, num ) { 15492 return num !== index ? num : null; 15493 } ); 15494 } 15495 } 15496 this._setOptionDisabled( disabled ); 15497 }, 15498 15499 disable: function( index ) { 15500 var disabled = this.options.disabled; 15501 if ( disabled === true ) { 15502 return; 15503 } 15504 15505 if ( index === undefined ) { 15506 disabled = true; 15507 } else { 15508 index = this._getIndex( index ); 15509 if ( $.inArray( index, disabled ) !== -1 ) { 15510 return; 15511 } 15512 if ( $.isArray( disabled ) ) { 15513 disabled = $.merge( [ index ], disabled ).sort(); 15514 } else { 15515 disabled = [ index ]; 15516 } 15517 } 15518 this._setOptionDisabled( disabled ); 15519 }, 15520 15521 load: function( index, event ) { 15522 index = this._getIndex( index ); 15523 var that = this, 15524 tab = this.tabs.eq( index ), 15525 anchor = tab.find( ".ui-tabs-anchor" ), 15526 panel = this._getPanelForTab( tab ), 15527 eventData = { 15528 tab: tab, 15529 panel: panel 15530 }, 15531 complete = function( jqXHR, status ) { 15532 if ( status === "abort" ) { 15533 that.panels.stop( false, true ); 15534 } 15535 15536 that._removeClass( tab, "ui-tabs-loading" ); 15537 panel.removeAttr( "aria-busy" ); 15538 15539 if ( jqXHR === that.xhr ) { 15540 delete that.xhr; 15541 } 15542 }; 15543 15544 // Not remote 15545 if ( this._isLocal( anchor[ 0 ] ) ) { 15546 return; 15547 } 15548 15549 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 15550 15551 // Support: jQuery <1.8 15552 // jQuery <1.8 returns false if the request is canceled in beforeSend, 15553 // but as of 1.8, $.ajax() always returns a jqXHR object. 15554 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 15555 this._addClass( tab, "ui-tabs-loading" ); 15556 panel.attr( "aria-busy", "true" ); 15557 15558 this.xhr 15559 .done( function( response, status, jqXHR ) { 15560 15561 // support: jQuery <1.8 15562 // http://bugs.jquery.com/ticket/11778 15563 setTimeout( function() { 15564 panel.html( response ); 15565 that._trigger( "load", event, eventData ); 15566 15567 complete( jqXHR, status ); 15568 }, 1 ); 15569 } ) 15570 .fail( function( jqXHR, status ) { 15571 15572 // support: jQuery <1.8 15573 // http://bugs.jquery.com/ticket/11778 15574 setTimeout( function() { 15575 complete( jqXHR, status ); 15576 }, 1 ); 15577 } ); 15578 } 15579 }, 15580 15581 _ajaxSettings: function( anchor, event, eventData ) { 15582 var that = this; 15583 return { 15584 15585 // Support: IE <11 only 15586 // Strip any hash that exists to prevent errors with the Ajax request 15587 url: anchor.attr( "href" ).replace( /#.*$/, "" ), 15588 beforeSend: function( jqXHR, settings ) { 15589 return that._trigger( "beforeLoad", event, 15590 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 15591 } 15592 }; 15593 }, 15594 15595 _getPanelForTab: function( tab ) { 15596 var id = $( tab ).attr( "aria-controls" ); 15597 return this.element.find( this._sanitizeSelector( "#" + id ) ); 15598 } 15599} ); 15600 15601// DEPRECATED 15602// TODO: Switch return back to widget declaration at top of file when this is removed 15603if ( $.uiBackCompat !== false ) { 15604 15605 // Backcompat for ui-tab class (now ui-tabs-tab) 15606 $.widget( "ui.tabs", $.ui.tabs, { 15607 _processTabs: function() { 15608 this._superApply( arguments ); 15609 this._addClass( this.tabs, "ui-tab" ); 15610 } 15611 } ); 15612} 15613 15614var widgetsTabs = $.ui.tabs; 15615 15616 15617/*! 15618 * jQuery UI Tooltip 1.12.1 15619 * http://jqueryui.com 15620 * 15621 * Copyright jQuery Foundation and other contributors 15622 * Released under the MIT license. 15623 * http://jquery.org/license 15624 */ 15625 15626//>>label: Tooltip 15627//>>group: Widgets 15628//>>description: Shows additional information for any element on hover or focus. 15629//>>docs: http://api.jqueryui.com/tooltip/ 15630//>>demos: http://jqueryui.com/tooltip/ 15631//>>css.structure: ../../themes/base/core.css 15632//>>css.structure: ../../themes/base/tooltip.css 15633//>>css.theme: ../../themes/base/theme.css 15634 15635 15636 15637$.widget( "ui.tooltip", { 15638 version: "1.12.1", 15639 options: { 15640 classes: { 15641 "ui-tooltip": "ui-corner-all ui-widget-shadow" 15642 }, 15643 content: function() { 15644 15645 // support: IE<9, Opera in jQuery <1.7 15646 // .text() can't accept undefined, so coerce to a string 15647 var title = $( this ).attr( "title" ) || ""; 15648 15649 // Escape title, since we're going from an attribute to raw HTML 15650 return $( "<a>" ).text( title ).html(); 15651 }, 15652 hide: true, 15653 15654 // Disabled elements have inconsistent behavior across browsers (#8661) 15655 items: "[title]:not([disabled])", 15656 position: { 15657 my: "left top+15", 15658 at: "left bottom", 15659 collision: "flipfit flip" 15660 }, 15661 show: true, 15662 track: false, 15663 15664 // Callbacks 15665 close: null, 15666 open: null 15667 }, 15668 15669 _addDescribedBy: function( elem, id ) { 15670 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 15671 describedby.push( id ); 15672 elem 15673 .data( "ui-tooltip-id", id ) 15674 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 15675 }, 15676 15677 _removeDescribedBy: function( elem ) { 15678 var id = elem.data( "ui-tooltip-id" ), 15679 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 15680 index = $.inArray( id, describedby ); 15681 15682 if ( index !== -1 ) { 15683 describedby.splice( index, 1 ); 15684 } 15685 15686 elem.removeData( "ui-tooltip-id" ); 15687 describedby = $.trim( describedby.join( " " ) ); 15688 if ( describedby ) { 15689 elem.attr( "aria-describedby", describedby ); 15690 } else { 15691 elem.removeAttr( "aria-describedby" ); 15692 } 15693 }, 15694 15695 _create: function() { 15696 this._on( { 15697 mouseover: "open", 15698 focusin: "open" 15699 } ); 15700 15701 // IDs of generated tooltips, needed for destroy 15702 this.tooltips = {}; 15703 15704 // IDs of parent tooltips where we removed the title attribute 15705 this.parents = {}; 15706 15707 // Append the aria-live region so tooltips announce correctly 15708 this.liveRegion = $( "<div>" ) 15709 .attr( { 15710 role: "log", 15711 "aria-live": "assertive", 15712 "aria-relevant": "additions" 15713 } ) 15714 .appendTo( this.document[ 0 ].body ); 15715 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 15716 15717 this.disabledTitles = $( [] ); 15718 }, 15719 15720 _setOption: function( key, value ) { 15721 var that = this; 15722 15723 this._super( key, value ); 15724 15725 if ( key === "content" ) { 15726 $.each( this.tooltips, function( id, tooltipData ) { 15727 that._updateContent( tooltipData.element ); 15728 } ); 15729 } 15730 }, 15731 15732 _setOptionDisabled: function( value ) { 15733 this[ value ? "_disable" : "_enable" ](); 15734 }, 15735 15736 _disable: function() { 15737 var that = this; 15738 15739 // Close open tooltips 15740 $.each( this.tooltips, function( id, tooltipData ) { 15741 var event = $.Event( "blur" ); 15742 event.target = event.currentTarget = tooltipData.element[ 0 ]; 15743 that.close( event, true ); 15744 } ); 15745 15746 // Remove title attributes to prevent native tooltips 15747 this.disabledTitles = this.disabledTitles.add( 15748 this.element.find( this.options.items ).addBack() 15749 .filter( function() { 15750 var element = $( this ); 15751 if ( element.is( "[title]" ) ) { 15752 return element 15753 .data( "ui-tooltip-title", element.attr( "title" ) ) 15754 .removeAttr( "title" ); 15755 } 15756 } ) 15757 ); 15758 }, 15759 15760 _enable: function() { 15761 15762 // restore title attributes 15763 this.disabledTitles.each( function() { 15764 var element = $( this ); 15765 if ( element.data( "ui-tooltip-title" ) ) { 15766 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15767 } 15768 } ); 15769 this.disabledTitles = $( [] ); 15770 }, 15771 15772 open: function( event ) { 15773 var that = this, 15774 target = $( event ? event.target : this.element ) 15775 15776 // we need closest here due to mouseover bubbling, 15777 // but always pointing at the same event target 15778 .closest( this.options.items ); 15779 15780 // No element to show a tooltip for or the tooltip is already open 15781 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 15782 return; 15783 } 15784 15785 if ( target.attr( "title" ) ) { 15786 target.data( "ui-tooltip-title", target.attr( "title" ) ); 15787 } 15788 15789 target.data( "ui-tooltip-open", true ); 15790 15791 // Kill parent tooltips, custom or native, for hover 15792 if ( event && event.type === "mouseover" ) { 15793 target.parents().each( function() { 15794 var parent = $( this ), 15795 blurEvent; 15796 if ( parent.data( "ui-tooltip-open" ) ) { 15797 blurEvent = $.Event( "blur" ); 15798 blurEvent.target = blurEvent.currentTarget = this; 15799 that.close( blurEvent, true ); 15800 } 15801 if ( parent.attr( "title" ) ) { 15802 parent.uniqueId(); 15803 that.parents[ this.id ] = { 15804 element: this, 15805 title: parent.attr( "title" ) 15806 }; 15807 parent.attr( "title", "" ); 15808 } 15809 } ); 15810 } 15811 15812 this._registerCloseHandlers( event, target ); 15813 this._updateContent( target, event ); 15814 }, 15815 15816 _updateContent: function( target, event ) { 15817 var content, 15818 contentOption = this.options.content, 15819 that = this, 15820 eventType = event ? event.type : null; 15821 15822 if ( typeof contentOption === "string" || contentOption.nodeType || 15823 contentOption.jquery ) { 15824 return this._open( event, target, contentOption ); 15825 } 15826 15827 content = contentOption.call( target[ 0 ], function( response ) { 15828 15829 // IE may instantly serve a cached response for ajax requests 15830 // delay this call to _open so the other call to _open runs first 15831 that._delay( function() { 15832 15833 // Ignore async response if tooltip was closed already 15834 if ( !target.data( "ui-tooltip-open" ) ) { 15835 return; 15836 } 15837 15838 // JQuery creates a special event for focusin when it doesn't 15839 // exist natively. To improve performance, the native event 15840 // object is reused and the type is changed. Therefore, we can't 15841 // rely on the type being correct after the event finished 15842 // bubbling, so we set it back to the previous value. (#8740) 15843 if ( event ) { 15844 event.type = eventType; 15845 } 15846 this._open( event, target, response ); 15847 } ); 15848 } ); 15849 if ( content ) { 15850 this._open( event, target, content ); 15851 } 15852 }, 15853 15854 _open: function( event, target, content ) { 15855 var tooltipData, tooltip, delayedShow, a11yContent, 15856 positionOption = $.extend( {}, this.options.position ); 15857 15858 if ( !content ) { 15859 return; 15860 } 15861 15862 // Content can be updated multiple times. If the tooltip already 15863 // exists, then just update the content and bail. 15864 tooltipData = this._find( target ); 15865 if ( tooltipData ) { 15866 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 15867 return; 15868 } 15869 15870 // If we have a title, clear it to prevent the native tooltip 15871 // we have to check first to avoid defining a title if none exists 15872 // (we don't want to cause an element to start matching [title]) 15873 // 15874 // We use removeAttr only for key events, to allow IE to export the correct 15875 // accessible attributes. For mouse events, set to empty string to avoid 15876 // native tooltip showing up (happens only when removing inside mouseover). 15877 if ( target.is( "[title]" ) ) { 15878 if ( event && event.type === "mouseover" ) { 15879 target.attr( "title", "" ); 15880 } else { 15881 target.removeAttr( "title" ); 15882 } 15883 } 15884 15885 tooltipData = this._tooltip( target ); 15886 tooltip = tooltipData.tooltip; 15887 this._addDescribedBy( target, tooltip.attr( "id" ) ); 15888 tooltip.find( ".ui-tooltip-content" ).html( content ); 15889 15890 // Support: Voiceover on OS X, JAWS on IE <= 9 15891 // JAWS announces deletions even when aria-relevant="additions" 15892 // Voiceover will sometimes re-read the entire log region's contents from the beginning 15893 this.liveRegion.children().hide(); 15894 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 15895 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 15896 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 15897 a11yContent.appendTo( this.liveRegion ); 15898 15899 function position( event ) { 15900 positionOption.of = event; 15901 if ( tooltip.is( ":hidden" ) ) { 15902 return; 15903 } 15904 tooltip.position( positionOption ); 15905 } 15906 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 15907 this._on( this.document, { 15908 mousemove: position 15909 } ); 15910 15911 // trigger once to override element-relative positioning 15912 position( event ); 15913 } else { 15914 tooltip.position( $.extend( { 15915 of: target 15916 }, this.options.position ) ); 15917 } 15918 15919 tooltip.hide(); 15920 15921 this._show( tooltip, this.options.show ); 15922 15923 // Handle tracking tooltips that are shown with a delay (#8644). As soon 15924 // as the tooltip is visible, position the tooltip using the most recent 15925 // event. 15926 // Adds the check to add the timers only when both delay and track options are set (#14682) 15927 if ( this.options.track && this.options.show && this.options.show.delay ) { 15928 delayedShow = this.delayedShow = setInterval( function() { 15929 if ( tooltip.is( ":visible" ) ) { 15930 position( positionOption.of ); 15931 clearInterval( delayedShow ); 15932 } 15933 }, $.fx.interval ); 15934 } 15935 15936 this._trigger( "open", event, { tooltip: tooltip } ); 15937 }, 15938 15939 _registerCloseHandlers: function( event, target ) { 15940 var events = { 15941 keyup: function( event ) { 15942 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 15943 var fakeEvent = $.Event( event ); 15944 fakeEvent.currentTarget = target[ 0 ]; 15945 this.close( fakeEvent, true ); 15946 } 15947 } 15948 }; 15949 15950 // Only bind remove handler for delegated targets. Non-delegated 15951 // tooltips will handle this in destroy. 15952 if ( target[ 0 ] !== this.element[ 0 ] ) { 15953 events.remove = function() { 15954 this._removeTooltip( this._find( target ).tooltip ); 15955 }; 15956 } 15957 15958 if ( !event || event.type === "mouseover" ) { 15959 events.mouseleave = "close"; 15960 } 15961 if ( !event || event.type === "focusin" ) { 15962 events.focusout = "close"; 15963 } 15964 this._on( true, target, events ); 15965 }, 15966 15967 close: function( event ) { 15968 var tooltip, 15969 that = this, 15970 target = $( event ? event.currentTarget : this.element ), 15971 tooltipData = this._find( target ); 15972 15973 // The tooltip may already be closed 15974 if ( !tooltipData ) { 15975
vendor: 17,492 bytes, lines 15976-16676
15976 // We set ui-tooltip-open immediately upon open (in open()), but only set the 15977 // additional data once there's actually content to show (in _open()). So even if the 15978 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 15979 // the period between open() and _open(). 15980 target.removeData( "ui-tooltip-open" ); 15981 return; 15982 } 15983 15984 tooltip = tooltipData.tooltip; 15985 15986 // Disabling closes the tooltip, so we need to track when we're closing 15987 // to avoid an infinite loop in case the tooltip becomes disabled on close 15988 if ( tooltipData.closing ) { 15989 return; 15990 } 15991 15992 // Clear the interval for delayed tracking tooltips 15993 clearInterval( this.delayedShow ); 15994 15995 // Only set title if we had one before (see comment in _open()) 15996 // If the title attribute has changed since open(), don't restore 15997 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 15998 target.attr( "title", target.data( "ui-tooltip-title" ) ); 15999 } 16000 16001 this._removeDescribedBy( target ); 16002 16003 tooltipData.hiding = true; 16004 tooltip.stop( true ); 16005 this._hide( tooltip, this.options.hide, function() { 16006 that._removeTooltip( $( this ) ); 16007 } ); 16008 16009 target.removeData( "ui-tooltip-open" ); 16010 this._off( target, "mouseleave focusout keyup" ); 16011 16012 // Remove 'remove' binding only on delegated targets 16013 if ( target[ 0 ] !== this.element[ 0 ] ) { 16014 this._off( target, "remove" ); 16015 } 16016 this._off( this.document, "mousemove" ); 16017 16018 if ( event && event.type === "mouseleave" ) { 16019 $.each( this.parents, function( id, parent ) { 16020 $( parent.element ).attr( "title", parent.title ); 16021 delete that.parents[ id ]; 16022 } ); 16023 } 16024 16025 tooltipData.closing = true; 16026 this._trigger( "close", event, { tooltip: tooltip } ); 16027 if ( !tooltipData.hiding ) { 16028 tooltipData.closing = false; 16029 } 16030 }, 16031 16032 _tooltip: function( element ) { 16033 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 16034 content = $( "<div>" ).appendTo( tooltip ), 16035 id = tooltip.uniqueId().attr( "id" ); 16036 16037 this._addClass( content, "ui-tooltip-content" ); 16038 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 16039 16040 tooltip.appendTo( this._appendTo( element ) ); 16041 16042 return this.tooltips[ id ] = { 16043 element: element, 16044 tooltip: tooltip 16045 }; 16046 }, 16047 16048 _find: function( target ) { 16049 var id = target.data( "ui-tooltip-id" ); 16050 return id ? this.tooltips[ id ] : null; 16051 }, 16052 16053 _removeTooltip: function( tooltip ) { 16054 tooltip.remove(); 16055 delete this.tooltips[ tooltip.attr( "id" ) ]; 16056 }, 16057 16058 _appendTo: function( target ) { 16059 var element = target.closest( ".ui-front, dialog" ); 16060 16061 if ( !element.length ) { 16062 element = this.document[ 0 ].body; 16063 } 16064 16065 return element; 16066 }, 16067 16068 _destroy: function() { 16069 var that = this; 16070 16071 // Close open tooltips 16072 $.each( this.tooltips, function( id, tooltipData ) { 16073 16074 // Delegate to close method to handle common cleanup 16075 var event = $.Event( "blur" ), 16076 element = tooltipData.element; 16077 event.target = event.currentTarget = element[ 0 ]; 16078 that.close( event, true ); 16079 16080 // Remove immediately; destroying an open tooltip doesn't use the 16081 // hide animation 16082 $( "#" + id ).remove(); 16083 16084 // Restore the title 16085 if ( element.data( "ui-tooltip-title" ) ) { 16086 16087 // If the title attribute has changed since open(), don't restore 16088 if ( !element.attr( "title" ) ) { 16089 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16090 } 16091 element.removeData( "ui-tooltip-title" ); 16092 } 16093 } ); 16094 this.liveRegion.remove(); 16095 } 16096} ); 16097 16098// DEPRECATED 16099// TODO: Switch return back to widget declaration at top of file when this is removed 16100if ( $.uiBackCompat !== false ) { 16101 16102 // Backcompat for tooltipClass option 16103 $.widget( "ui.tooltip", $.ui.tooltip, { 16104 options: { 16105 tooltipClass: null 16106 }, 16107 _tooltip: function() { 16108 var tooltipData = this._superApply( arguments ); 16109 if ( this.options.tooltipClass ) { 16110 tooltipData.tooltip.addClass( this.options.tooltipClass ); 16111 } 16112 return tooltipData; 16113 } 16114 } ); 16115} 16116 16117var widgetsTooltip = $.ui.tooltip; 16118 16119 16120/*! 16121 * jQuery UI Effects 1.12.1 16122 * http://jqueryui.com 16123 * 16124 * Copyright jQuery Foundation and other contributors 16125 * Released under the MIT license. 16126 * http://jquery.org/license 16127 */ 16128 16129//>>label: Effects Core 16130//>>group: Effects 16131// jscs:disable maximumLineLength 16132//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 16133// jscs:enable maximumLineLength 16134//>>docs: http://api.jqueryui.com/category/effects-core/ 16135//>>demos: http://jqueryui.com/effect/ 16136 16137 16138 16139var dataSpace = "ui-effects-", 16140 dataSpaceStyle = "ui-effects-style", 16141 dataSpaceAnimated = "ui-effects-animated", 16142 16143 // Create a local jQuery because jQuery Color relies on it and the 16144 // global may not exist with AMD and a custom build (#10199) 16145 jQuery = $; 16146 16147$.effects = { 16148 effect: {} 16149}; 16150 16151/*! 16152 * jQuery Color Animations v2.1.2 16153 * https://github.com/jquery/jquery-color 16154 * 16155 * Copyright 2014 jQuery Foundation and other contributors 16156 * Released under the MIT license. 16157 * http://jquery.org/license 16158 * 16159 * Date: Wed Jan 16 08:47:09 2013 -0600 16160 */ 16161( function( jQuery, undefined ) { 16162 16163 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 16164 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 16165 16166 // Plusequals test for += 100 -= 100 16167 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 16168 16169 // A set of RE's that can match strings and generate color tuples. 16170 stringParsers = [ { 16171 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16172 parse: function( execResult ) { 16173 return [ 16174 execResult[ 1 ], 16175 execResult[ 2 ], 16176 execResult[ 3 ], 16177 execResult[ 4 ] 16178 ]; 16179 } 16180 }, { 16181 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16182 parse: function( execResult ) { 16183 return [ 16184 execResult[ 1 ] * 2.55, 16185 execResult[ 2 ] * 2.55, 16186 execResult[ 3 ] * 2.55, 16187 execResult[ 4 ] 16188 ]; 16189 } 16190 }, { 16191 16192 // This regex ignores A-F because it's compared against an already lowercased string 16193 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 16194 parse: function( execResult ) { 16195 return [ 16196 parseInt( execResult[ 1 ], 16 ), 16197 parseInt( execResult[ 2 ], 16 ), 16198 parseInt( execResult[ 3 ], 16 ) 16199 ]; 16200 } 16201 }, { 16202 16203 // This regex ignores A-F because it's compared against an already lowercased string 16204 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 16205 parse: function( execResult ) { 16206 return [ 16207 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 16208 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 16209 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 16210 ]; 16211 } 16212 }, { 16213 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16214 space: "hsla", 16215 parse: function( execResult ) { 16216 return [ 16217 execResult[ 1 ], 16218 execResult[ 2 ] / 100, 16219 execResult[ 3 ] / 100, 16220 execResult[ 4 ] 16221 ]; 16222 } 16223 } ], 16224 16225 // JQuery.Color( ) 16226 color = jQuery.Color = function( color, green, blue, alpha ) { 16227 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 16228 }, 16229 spaces = { 16230 rgba: { 16231 props: { 16232 red: { 16233 idx: 0, 16234 type: "byte" 16235 }, 16236 green: { 16237 idx: 1, 16238 type: "byte" 16239 }, 16240 blue: { 16241 idx: 2, 16242 type: "byte" 16243 } 16244 } 16245 }, 16246 16247 hsla: { 16248 props: { 16249 hue: { 16250 idx: 0, 16251 type: "degrees" 16252 }, 16253 saturation: { 16254 idx: 1, 16255 type: "percent" 16256 }, 16257 lightness: { 16258 idx: 2, 16259 type: "percent" 16260 } 16261 } 16262 } 16263 }, 16264 propTypes = { 16265 "byte": { 16266 floor: true, 16267 max: 255 16268 }, 16269 "percent": { 16270 max: 1 16271 }, 16272 "degrees": { 16273 mod: 360, 16274 floor: true 16275 } 16276 }, 16277 support = color.support = {}, 16278 16279 // Element for support tests 16280 supportElem = jQuery( "<p>" )[ 0 ], 16281 16282 // Colors = jQuery.Color.names 16283 colors, 16284 16285 // Local aliases of functions called often 16286 each = jQuery.each; 16287 16288// Determine rgba support immediately 16289supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 16290support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 16291 16292// Define cache name and alpha properties 16293// for rgba and hsla spaces 16294each( spaces, function( spaceName, space ) { 16295 space.cache = "_" + spaceName; 16296 space.props.alpha = { 16297 idx: 3, 16298 type: "percent", 16299 def: 1 16300 }; 16301} ); 16302 16303function clamp( value, prop, allowEmpty ) { 16304 var type = propTypes[ prop.type ] || {}; 16305 16306 if ( value == null ) { 16307 return ( allowEmpty || !prop.def ) ? null : prop.def; 16308 } 16309 16310 // ~~ is an short way of doing floor for positive numbers 16311 value = type.floor ? ~~value : parseFloat( value ); 16312 16313 // IE will pass in empty strings as value for alpha, 16314 // which will hit this case 16315 if ( isNaN( value ) ) { 16316 return prop.def; 16317 } 16318 16319 if ( type.mod ) { 16320 16321 // We add mod before modding to make sure that negatives values 16322 // get converted properly: -10 -> 350 16323 return ( value + type.mod ) % type.mod; 16324 } 16325 16326 // For now all property types without mod have min and max 16327 return 0 > value ? 0 : type.max < value ? type.max : value; 16328} 16329 16330function stringParse( string ) { 16331 var inst = color(), 16332 rgba = inst._rgba = []; 16333 16334 string = string.toLowerCase(); 16335 16336 each( stringParsers, function( i, parser ) { 16337 var parsed, 16338 match = parser.re.exec( string ), 16339 values = match && parser.parse( match ), 16340 spaceName = parser.space || "rgba"; 16341 16342 if ( values ) { 16343 parsed = inst[ spaceName ]( values ); 16344 16345 // If this was an rgba parse the assignment might happen twice 16346 // oh well.... 16347 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 16348 rgba = inst._rgba = parsed._rgba; 16349 16350 // Exit each( stringParsers ) here because we matched 16351 return false; 16352 } 16353 } ); 16354 16355 // Found a stringParser that handled it 16356 if ( rgba.length ) { 16357 16358 // If this came from a parsed string, force "transparent" when alpha is 0 16359 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 16360 if ( rgba.join() === "0,0,0,0" ) { 16361 jQuery.extend( rgba, colors.transparent ); 16362 } 16363 return inst; 16364 } 16365 16366 // Named colors 16367 return colors[ string ]; 16368} 16369 16370color.fn = jQuery.extend( color.prototype, { 16371 parse: function( red, green, blue, alpha ) { 16372 if ( red === undefined ) { 16373 this._rgba = [ null, null, null, null ]; 16374 return this; 16375 } 16376 if ( red.jquery || red.nodeType ) { 16377 red = jQuery( red ).css( green ); 16378 green = undefined; 16379 } 16380 16381 var inst = this, 16382 type = jQuery.type( red ), 16383 rgba = this._rgba = []; 16384 16385 // More than 1 argument specified - assume ( red, green, blue, alpha ) 16386 if ( green !== undefined ) { 16387 red = [ red, green, blue, alpha ]; 16388 type = "array"; 16389 } 16390 16391 if ( type === "string" ) { 16392 return this.parse( stringParse( red ) || colors._default ); 16393 } 16394 16395 if ( type === "array" ) { 16396 each( spaces.rgba.props, function( key, prop ) { 16397 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 16398 } ); 16399 return this; 16400 } 16401 16402 if ( type === "object" ) { 16403 if ( red instanceof color ) { 16404 each( spaces, function( spaceName, space ) { 16405 if ( red[ space.cache ] ) { 16406 inst[ space.cache ] = red[ space.cache ].slice(); 16407 } 16408 } ); 16409 } else { 16410 each( spaces, function( spaceName, space ) { 16411 var cache = space.cache; 16412 each( space.props, function( key, prop ) { 16413 16414 // If the cache doesn't exist, and we know how to convert 16415 if ( !inst[ cache ] && space.to ) { 16416 16417 // If the value was null, we don't need to copy it 16418 // if the key was alpha, we don't need to copy it either 16419 if ( key === "alpha" || red[ key ] == null ) { 16420 return; 16421 } 16422 inst[ cache ] = space.to( inst._rgba ); 16423 } 16424 16425 // This is the only case where we allow nulls for ALL properties. 16426 // call clamp with alwaysAllowEmpty 16427 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 16428 } ); 16429 16430 // Everything defined but alpha? 16431 if ( inst[ cache ] && 16432 jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 16433 16434 // Use the default of 1 16435 inst[ cache ][ 3 ] = 1; 16436 if ( space.from ) { 16437 inst._rgba = space.from( inst[ cache ] ); 16438 } 16439 } 16440 } ); 16441 } 16442 return this; 16443 } 16444 }, 16445 is: function( compare ) { 16446 var is = color( compare ), 16447 same = true, 16448 inst = this; 16449 16450 each( spaces, function( _, space ) { 16451 var localCache, 16452 isCache = is[ space.cache ]; 16453 if ( isCache ) { 16454 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 16455 each( space.props, function( _, prop ) { 16456 if ( isCache[ prop.idx ] != null ) { 16457 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 16458 return same; 16459 } 16460 } ); 16461 } 16462 return same; 16463 } ); 16464 return same; 16465 }, 16466 _space: function() { 16467 var used = [], 16468 inst = this; 16469 each( spaces, function( spaceName, space ) { 16470 if ( inst[ space.cache ] ) { 16471 used.push( spaceName ); 16472 } 16473 } ); 16474 return used.pop(); 16475 }, 16476 transition: function( other, distance ) { 16477 var end = color( other ), 16478 spaceName = end._space(), 16479 space = spaces[ spaceName ], 16480 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 16481 start = startColor[ space.cache ] || space.to( startColor._rgba ), 16482 result = start.slice(); 16483 16484 end = end[ space.cache ]; 16485 each( space.props, function( key, prop ) { 16486 var index = prop.idx, 16487 startValue = start[ index ], 16488 endValue = end[ index ], 16489 type = propTypes[ prop.type ] || {}; 16490 16491 // If null, don't override start value 16492 if ( endValue === null ) { 16493 return; 16494 } 16495 16496 // If null - use end 16497 if ( startValue === null ) { 16498 result[ index ] = endValue; 16499 } else { 16500 if ( type.mod ) { 16501 if ( endValue - startValue > type.mod / 2 ) { 16502 startValue += type.mod; 16503 } else if ( startValue - endValue > type.mod / 2 ) { 16504 startValue -= type.mod; 16505 } 16506 } 16507 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 16508 } 16509 } ); 16510 return this[ spaceName ]( result ); 16511 }, 16512 blend: function( opaque ) { 16513 16514 // If we are already opaque - return ourself 16515 if ( this._rgba[ 3 ] === 1 ) { 16516 return this; 16517 } 16518 16519 var rgb = this._rgba.slice(), 16520 a = rgb.pop(), 16521 blend = color( opaque )._rgba; 16522 16523 return color( jQuery.map( rgb, function( v, i ) { 16524 return ( 1 - a ) * blend[ i ] + a * v; 16525 } ) ); 16526 }, 16527 toRgbaString: function() { 16528 var prefix = "rgba(", 16529 rgba = jQuery.map( this._rgba, function( v, i ) { 16530 return v == null ? ( i > 2 ? 1 : 0 ) : v; 16531 } ); 16532 16533 if ( rgba[ 3 ] === 1 ) { 16534 rgba.pop(); 16535 prefix = "rgb("; 16536 } 16537 16538 return prefix + rgba.join() + ")"; 16539 }, 16540 toHslaString: function() { 16541 var prefix = "hsla(", 16542 hsla = jQuery.map( this.hsla(), function( v, i ) { 16543 if ( v == null ) { 16544 v = i > 2 ? 1 : 0; 16545 } 16546 16547 // Catch 1 and 2 16548 if ( i && i < 3 ) { 16549 v = Math.round( v * 100 ) + "%"; 16550 } 16551 return v; 16552 } ); 16553 16554 if ( hsla[ 3 ] === 1 ) { 16555 hsla.pop(); 16556 prefix = "hsl("; 16557 } 16558 return prefix + hsla.join() + ")"; 16559 }, 16560 toHexString: function( includeAlpha ) { 16561 var rgba = this._rgba.slice(), 16562 alpha = rgba.pop(); 16563 16564 if ( includeAlpha ) { 16565 rgba.push( ~~( alpha * 255 ) ); 16566 } 16567 16568 return "#" + jQuery.map( rgba, function( v ) { 16569 16570 // Default to 0 when nulls exist 16571 v = ( v || 0 ).toString( 16 ); 16572 return v.length === 1 ? "0" + v : v; 16573 } ).join( "" ); 16574 }, 16575 toString: function() { 16576 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 16577 } 16578} ); 16579color.fn.parse.prototype = color.fn; 16580 16581// Hsla conversions adapted from: 16582// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 16583 16584function hue2rgb( p, q, h ) { 16585 h = ( h + 1 ) % 1; 16586 if ( h * 6 < 1 ) { 16587 return p + ( q - p ) * h * 6; 16588 } 16589 if ( h * 2 < 1 ) { 16590 return q; 16591 } 16592 if ( h * 3 < 2 ) { 16593 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 16594 } 16595 return p; 16596} 16597 16598spaces.hsla.to = function( rgba ) { 16599 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 16600 return [ null, null, null, rgba[ 3 ] ]; 16601 } 16602 var r = rgba[ 0 ] / 255, 16603 g = rgba[ 1 ] / 255, 16604 b = rgba[ 2 ] / 255, 16605 a = rgba[ 3 ], 16606 max = Math.max( r, g, b ), 16607 min = Math.min( r, g, b ), 16608 diff = max - min, 16609 add = max + min, 16610 l = add * 0.5, 16611 h, s; 16612 16613 if ( min === max ) { 16614 h = 0; 16615 } else if ( r === max ) { 16616 h = ( 60 * ( g - b ) / diff ) + 360; 16617 } else if ( g === max ) { 16618 h = ( 60 * ( b - r ) / diff ) + 120; 16619 } else { 16620 h = ( 60 * ( r - g ) / diff ) + 240; 16621 } 16622 16623 // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 16624 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 16625 if ( diff === 0 ) { 16626 s = 0; 16627 } else if ( l <= 0.5 ) { 16628 s = diff / add; 16629 } else { 16630 s = diff / ( 2 - add ); 16631 } 16632 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 16633}; 16634 16635spaces.hsla.from = function( hsla ) { 16636 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 16637 return [ null, null, null, hsla[ 3 ] ]; 16638 } 16639 var h = hsla[ 0 ] / 360, 16640 s = hsla[ 1 ], 16641 l = hsla[ 2 ], 16642 a = hsla[ 3 ], 16643 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 16644 p = 2 * l - q; 16645 16646 return [ 16647 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 16648 Math.round( hue2rgb( p, q, h ) * 255 ), 16649 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 16650 a 16651 ]; 16652}; 16653 16654each( spaces, function( spaceName, space ) { 16655 var props = space.props, 16656 cache = space.cache, 16657 to = space.to, 16658 from = space.from; 16659 16660 // Makes rgba() and hsla() 16661 color.fn[ spaceName ] = function( value ) { 16662 16663 // Generate a cache for this space if it doesn't exist 16664 if ( to && !this[ cache ] ) { 16665 this[ cache ] = to( this._rgba ); 16666 } 16667 if ( value === undefined ) { 16668 return this[ cache ].slice(); 16669 } 16670 16671 var ret, 16672 type = jQuery.type( value ), 16673 arr = ( type === "array" || type === "object" ) ? value : arguments, 16674 local = this[ cache ].slice(); 16675 16676 each( props, function( key, prop ) {
vendor: 50,833 bytes, lines 16677-18662
16677 var val = arr[ type === "object" ? key : prop.idx ]; 16678 if ( val == null ) { 16679 val = local[ prop.idx ]; 16680 } 16681 local[ prop.idx ] = clamp( val, prop ); 16682 } ); 16683 16684 if ( from ) { 16685 ret = color( from( local ) ); 16686 ret[ cache ] = local; 16687 return ret; 16688 } else { 16689 return color( local ); 16690 } 16691 }; 16692 16693 // Makes red() green() blue() alpha() hue() saturation() lightness() 16694 each( props, function( key, prop ) { 16695 16696 // Alpha is included in more than one space 16697 if ( color.fn[ key ] ) { 16698 return; 16699 } 16700 color.fn[ key ] = function( value ) { 16701 var vtype = jQuery.type( value ), 16702 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 16703 local = this[ fn ](), 16704 cur = local[ prop.idx ], 16705 match; 16706 16707 if ( vtype === "undefined" ) { 16708 return cur; 16709 } 16710 16711 if ( vtype === "function" ) { 16712 value = value.call( this, cur ); 16713 vtype = jQuery.type( value ); 16714 } 16715 if ( value == null && prop.empty ) { 16716 return this; 16717 } 16718 if ( vtype === "string" ) { 16719 match = rplusequals.exec( value ); 16720 if ( match ) { 16721 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 16722 } 16723 } 16724 local[ prop.idx ] = value; 16725 return this[ fn ]( local ); 16726 }; 16727 } ); 16728} ); 16729 16730// Add cssHook and .fx.step function for each named hook. 16731// accept a space separated string of properties 16732color.hook = function( hook ) { 16733 var hooks = hook.split( " " ); 16734 each( hooks, function( i, hook ) { 16735 jQuery.cssHooks[ hook ] = { 16736 set: function( elem, value ) { 16737 var parsed, curElem, 16738 backgroundColor = ""; 16739 16740 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || 16741 ( parsed = stringParse( value ) ) ) ) { 16742 value = color( parsed || value ); 16743 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 16744 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 16745 while ( 16746 ( backgroundColor === "" || backgroundColor === "transparent" ) && 16747 curElem && curElem.style 16748 ) { 16749 try { 16750 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 16751 curElem = curElem.parentNode; 16752 } catch ( e ) { 16753 } 16754 } 16755 16756 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 16757 backgroundColor : 16758 "_default" ); 16759 } 16760 16761 value = value.toRgbaString(); 16762 } 16763 try { 16764 elem.style[ hook ] = value; 16765 } catch ( e ) { 16766 16767 // Wrapped to prevent IE from throwing errors on "invalid" values like 16768 // 'auto' or 'inherit' 16769 } 16770 } 16771 }; 16772 jQuery.fx.step[ hook ] = function( fx ) { 16773 if ( !fx.colorInit ) { 16774 fx.start = color( fx.elem, hook ); 16775 fx.end = color( fx.end ); 16776 fx.colorInit = true; 16777 } 16778 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 16779 }; 16780 } ); 16781 16782}; 16783 16784color.hook( stepHooks ); 16785 16786jQuery.cssHooks.borderColor = { 16787 expand: function( value ) { 16788 var expanded = {}; 16789 16790 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 16791 expanded[ "border" + part + "Color" ] = value; 16792 } ); 16793 return expanded; 16794 } 16795}; 16796 16797// Basic color names only. 16798// Usage of any of the other color names requires adding yourself or including 16799// jquery.color.svg-names.js. 16800colors = jQuery.Color.names = { 16801 16802 // 4.1. Basic color keywords 16803 aqua: "#00ffff", 16804 black: "#000000", 16805 blue: "#0000ff", 16806 fuchsia: "#ff00ff", 16807 gray: "#808080", 16808 green: "#008000", 16809 lime: "#00ff00", 16810 maroon: "#800000", 16811 navy: "#000080", 16812 olive: "#808000", 16813 purple: "#800080", 16814 red: "#ff0000", 16815 silver: "#c0c0c0", 16816 teal: "#008080", 16817 white: "#ffffff", 16818 yellow: "#ffff00", 16819 16820 // 4.2.3. "transparent" color keyword 16821 transparent: [ null, null, null, 0 ], 16822 16823 _default: "#ffffff" 16824}; 16825 16826} )( jQuery ); 16827 16828/******************************************************************************/ 16829/****************************** CLASS ANIMATIONS ******************************/ 16830/******************************************************************************/ 16831( function() { 16832 16833var classAnimationActions = [ "add", "remove", "toggle" ], 16834 shorthandStyles = { 16835 border: 1, 16836 borderBottom: 1, 16837 borderColor: 1, 16838 borderLeft: 1, 16839 borderRight: 1, 16840 borderTop: 1, 16841 borderWidth: 1, 16842 margin: 1, 16843 padding: 1 16844 }; 16845 16846$.each( 16847 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 16848 function( _, prop ) { 16849 $.fx.step[ prop ] = function( fx ) { 16850 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 16851 jQuery.style( fx.elem, prop, fx.end ); 16852 fx.setAttr = true; 16853 } 16854 }; 16855 } 16856); 16857 16858function getElementStyles( elem ) { 16859 var key, len, 16860 style = elem.ownerDocument.defaultView ? 16861 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 16862 elem.currentStyle, 16863 styles = {}; 16864 16865 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 16866 len = style.length; 16867 while ( len-- ) { 16868 key = style[ len ]; 16869 if ( typeof style[ key ] === "string" ) { 16870 styles[ $.camelCase( key ) ] = style[ key ]; 16871 } 16872 } 16873 16874 // Support: Opera, IE <9 16875 } else { 16876 for ( key in style ) { 16877 if ( typeof style[ key ] === "string" ) { 16878 styles[ key ] = style[ key ]; 16879 } 16880 } 16881 } 16882 16883 return styles; 16884} 16885 16886function styleDifference( oldStyle, newStyle ) { 16887 var diff = {}, 16888 name, value; 16889 16890 for ( name in newStyle ) { 16891 value = newStyle[ name ]; 16892 if ( oldStyle[ name ] !== value ) { 16893 if ( !shorthandStyles[ name ] ) { 16894 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 16895 diff[ name ] = value; 16896 } 16897 } 16898 } 16899 } 16900 16901 return diff; 16902} 16903 16904// Support: jQuery <1.8 16905if ( !$.fn.addBack ) { 16906 $.fn.addBack = function( selector ) { 16907 return this.add( selector == null ? 16908 this.prevObject : this.prevObject.filter( selector ) 16909 ); 16910 }; 16911} 16912 16913$.effects.animateClass = function( value, duration, easing, callback ) { 16914 var o = $.speed( duration, easing, callback ); 16915 16916 return this.queue( function() { 16917 var animated = $( this ), 16918 baseClass = animated.attr( "class" ) || "", 16919 applyClassChange, 16920 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 16921 16922 // Map the animated objects to store the original styles. 16923 allAnimations = allAnimations.map( function() { 16924 var el = $( this ); 16925 return { 16926 el: el, 16927 start: getElementStyles( this ) 16928 }; 16929 } ); 16930 16931 // Apply class change 16932 applyClassChange = function() { 16933 $.each( classAnimationActions, function( i, action ) { 16934 if ( value[ action ] ) { 16935 animated[ action + "Class" ]( value[ action ] ); 16936 } 16937 } ); 16938 }; 16939 applyClassChange(); 16940 16941 // Map all animated objects again - calculate new styles and diff 16942 allAnimations = allAnimations.map( function() { 16943 this.end = getElementStyles( this.el[ 0 ] ); 16944 this.diff = styleDifference( this.start, this.end ); 16945 return this; 16946 } ); 16947 16948 // Apply original class 16949 animated.attr( "class", baseClass ); 16950 16951 // Map all animated objects again - this time collecting a promise 16952 allAnimations = allAnimations.map( function() { 16953 var styleInfo = this, 16954 dfd = $.Deferred(), 16955 opts = $.extend( {}, o, { 16956 queue: false, 16957 complete: function() { 16958 dfd.resolve( styleInfo ); 16959 } 16960 } ); 16961 16962 this.el.animate( this.diff, opts ); 16963 return dfd.promise(); 16964 } ); 16965 16966 // Once all animations have completed: 16967 $.when.apply( $, allAnimations.get() ).done( function() { 16968 16969 // Set the final class 16970 applyClassChange(); 16971 16972 // For each animated element, 16973 // clear all css properties that were animated 16974 $.each( arguments, function() { 16975 var el = this.el; 16976 $.each( this.diff, function( key ) { 16977 el.css( key, "" ); 16978 } ); 16979 } ); 16980 16981 // This is guarnteed to be there if you use jQuery.speed() 16982 // it also handles dequeuing the next anim... 16983 o.complete.call( animated[ 0 ] ); 16984 } ); 16985 } ); 16986}; 16987 16988$.fn.extend( { 16989 addClass: ( function( orig ) { 16990 return function( classNames, speed, easing, callback ) { 16991 return speed ? 16992 $.effects.animateClass.call( this, 16993 { add: classNames }, speed, easing, callback ) : 16994 orig.apply( this, arguments ); 16995 }; 16996 } )( $.fn.addClass ), 16997 16998 removeClass: ( function( orig ) { 16999 return function( classNames, speed, easing, callback ) { 17000 return arguments.length > 1 ? 17001 $.effects.animateClass.call( this, 17002 { remove: classNames }, speed, easing, callback ) : 17003 orig.apply( this, arguments ); 17004 }; 17005 } )( $.fn.removeClass ), 17006 17007 toggleClass: ( function( orig ) { 17008 return function( classNames, force, speed, easing, callback ) { 17009 if ( typeof force === "boolean" || force === undefined ) { 17010 if ( !speed ) { 17011 17012 // Without speed parameter 17013 return orig.apply( this, arguments ); 17014 } else { 17015 return $.effects.animateClass.call( this, 17016 ( force ? { add: classNames } : { remove: classNames } ), 17017 speed, easing, callback ); 17018 } 17019 } else { 17020 17021 // Without force parameter 17022 return $.effects.animateClass.call( this, 17023 { toggle: classNames }, force, speed, easing ); 17024 } 17025 }; 17026 } )( $.fn.toggleClass ), 17027 17028 switchClass: function( remove, add, speed, easing, callback ) { 17029 return $.effects.animateClass.call( this, { 17030 add: add, 17031 remove: remove 17032 }, speed, easing, callback ); 17033 } 17034} ); 17035 17036} )(); 17037 17038/******************************************************************************/ 17039/*********************************** EFFECTS **********************************/ 17040/******************************************************************************/ 17041 17042( function() { 17043 17044if ( $.expr && $.expr.filters && $.expr.filters.animated ) { 17045 $.expr.filters.animated = ( function( orig ) { 17046 return function( elem ) { 17047 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 17048 }; 17049 } )( $.expr.filters.animated ); 17050} 17051 17052if ( $.uiBackCompat !== false ) { 17053 $.extend( $.effects, { 17054 17055 // Saves a set of properties in a data storage 17056 save: function( element, set ) { 17057 var i = 0, length = set.length; 17058 for ( ; i < length; i++ ) { 17059 if ( set[ i ] !== null ) { 17060 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 17061 } 17062 } 17063 }, 17064 17065 // Restores a set of previously saved properties from a data storage 17066 restore: function( element, set ) { 17067 var val, i = 0, length = set.length; 17068 for ( ; i < length; i++ ) { 17069 if ( set[ i ] !== null ) { 17070 val = element.data( dataSpace + set[ i ] ); 17071 element.css( set[ i ], val ); 17072 } 17073 } 17074 }, 17075 17076 setMode: function( el, mode ) { 17077 if ( mode === "toggle" ) { 17078 mode = el.is( ":hidden" ) ? "show" : "hide"; 17079 } 17080 return mode; 17081 }, 17082 17083 // Wraps the element around a wrapper that copies position properties 17084 createWrapper: function( element ) { 17085 17086 // If the element is already wrapped, return it 17087 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17088 return element.parent(); 17089 } 17090 17091 // Wrap the element 17092 var props = { 17093 width: element.outerWidth( true ), 17094 height: element.outerHeight( true ), 17095 "float": element.css( "float" ) 17096 }, 17097 wrapper = $( "<div></div>" ) 17098 .addClass( "ui-effects-wrapper" ) 17099 .css( { 17100 fontSize: "100%", 17101 background: "transparent", 17102 border: "none", 17103 margin: 0, 17104 padding: 0 17105 } ), 17106 17107 // Store the size in case width/height are defined in % - Fixes #5245 17108 size = { 17109 width: element.width(), 17110 height: element.height() 17111 }, 17112 active = document.activeElement; 17113 17114 // Support: Firefox 17115 // Firefox incorrectly exposes anonymous content 17116 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 17117 try { 17118 active.id; 17119 } catch ( e ) { 17120 active = document.body; 17121 } 17122 17123 element.wrap( wrapper ); 17124 17125 // Fixes #7595 - Elements lose focus when wrapped. 17126 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17127 $( active ).trigger( "focus" ); 17128 } 17129 17130 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 17131 // lose the reference to the wrapped element 17132 wrapper = element.parent(); 17133 17134 // Transfer positioning properties to the wrapper 17135 if ( element.css( "position" ) === "static" ) { 17136 wrapper.css( { position: "relative" } ); 17137 element.css( { position: "relative" } ); 17138 } else { 17139 $.extend( props, { 17140 position: element.css( "position" ), 17141 zIndex: element.css( "z-index" ) 17142 } ); 17143 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 17144 props[ pos ] = element.css( pos ); 17145 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 17146 props[ pos ] = "auto"; 17147 } 17148 } ); 17149 element.css( { 17150 position: "relative", 17151 top: 0, 17152 left: 0, 17153 right: "auto", 17154 bottom: "auto" 17155 } ); 17156 } 17157 element.css( size ); 17158 17159 return wrapper.css( props ).show(); 17160 }, 17161 17162 removeWrapper: function( element ) { 17163 var active = document.activeElement; 17164 17165 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17166 element.parent().replaceWith( element ); 17167 17168 // Fixes #7595 - Elements lose focus when wrapped. 17169 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17170 $( active ).trigger( "focus" ); 17171 } 17172 } 17173 17174 return element; 17175 } 17176 } ); 17177} 17178 17179$.extend( $.effects, { 17180 version: "1.12.1", 17181 17182 define: function( name, mode, effect ) { 17183 if ( !effect ) { 17184 effect = mode; 17185 mode = "effect"; 17186 } 17187 17188 $.effects.effect[ name ] = effect; 17189 $.effects.effect[ name ].mode = mode; 17190 17191 return effect; 17192 }, 17193 17194 scaledDimensions: function( element, percent, direction ) { 17195 if ( percent === 0 ) { 17196 return { 17197 height: 0, 17198 width: 0, 17199 outerHeight: 0, 17200 outerWidth: 0 17201 }; 17202 } 17203 17204 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 17205 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 17206 17207 return { 17208 height: element.height() * y, 17209 width: element.width() * x, 17210 outerHeight: element.outerHeight() * y, 17211 outerWidth: element.outerWidth() * x 17212 }; 17213 17214 }, 17215 17216 clipToBox: function( animation ) { 17217 return { 17218 width: animation.clip.right - animation.clip.left, 17219 height: animation.clip.bottom - animation.clip.top, 17220 left: animation.clip.left, 17221 top: animation.clip.top 17222 }; 17223 }, 17224 17225 // Injects recently queued functions to be first in line (after "inprogress") 17226 unshift: function( element, queueLength, count ) { 17227 var queue = element.queue(); 17228 17229 if ( queueLength > 1 ) { 17230 queue.splice.apply( queue, 17231 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 17232 } 17233 element.dequeue(); 17234 }, 17235 17236 saveStyle: function( element ) { 17237 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 17238 }, 17239 17240 restoreStyle: function( element ) { 17241 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 17242 element.removeData( dataSpaceStyle ); 17243 }, 17244 17245 mode: function( element, mode ) { 17246 var hidden = element.is( ":hidden" ); 17247 17248 if ( mode === "toggle" ) { 17249 mode = hidden ? "show" : "hide"; 17250 } 17251 if ( hidden ? mode === "hide" : mode === "show" ) { 17252 mode = "none"; 17253 } 17254 return mode; 17255 }, 17256 17257 // Translates a [top,left] array into a baseline value 17258 getBaseline: function( origin, original ) { 17259 var y, x; 17260 17261 switch ( origin[ 0 ] ) { 17262 case "top": 17263 y = 0; 17264 break; 17265 case "middle": 17266 y = 0.5; 17267 break; 17268 case "bottom": 17269 y = 1; 17270 break; 17271 default: 17272 y = origin[ 0 ] / original.height; 17273 } 17274 17275 switch ( origin[ 1 ] ) { 17276 case "left": 17277 x = 0; 17278 break; 17279 case "center": 17280 x = 0.5; 17281 break; 17282 case "right": 17283 x = 1; 17284 break; 17285 default: 17286 x = origin[ 1 ] / original.width; 17287 } 17288 17289 return { 17290 x: x, 17291 y: y 17292 }; 17293 }, 17294 17295 // Creates a placeholder element so that the original element can be made absolute 17296 createPlaceholder: function( element ) { 17297 var placeholder, 17298 cssPosition = element.css( "position" ), 17299 position = element.position(); 17300 17301 // Lock in margins first to account for form elements, which 17302 // will change margin if you explicitly set height 17303 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 17304 // Support: Safari 17305 element.css( { 17306 marginTop: element.css( "marginTop" ), 17307 marginBottom: element.css( "marginBottom" ), 17308 marginLeft: element.css( "marginLeft" ), 17309 marginRight: element.css( "marginRight" ) 17310 } ) 17311 .outerWidth( element.outerWidth() ) 17312 .outerHeight( element.outerHeight() ); 17313 17314 if ( /^(static|relative)/.test( cssPosition ) ) { 17315 cssPosition = "absolute"; 17316 17317 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 17318 17319 // Convert inline to inline block to account for inline elements 17320 // that turn to inline block based on content (like img) 17321 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 17322 "inline-block" : 17323 "block", 17324 visibility: "hidden", 17325 17326 // Margins need to be set to account for margin collapse 17327 marginTop: element.css( "marginTop" ), 17328 marginBottom: element.css( "marginBottom" ), 17329 marginLeft: element.css( "marginLeft" ), 17330 marginRight: element.css( "marginRight" ), 17331 "float": element.css( "float" ) 17332 } ) 17333 .outerWidth( element.outerWidth() ) 17334 .outerHeight( element.outerHeight() ) 17335 .addClass( "ui-effects-placeholder" ); 17336 17337 element.data( dataSpace + "placeholder", placeholder ); 17338 } 17339 17340 element.css( { 17341 position: cssPosition, 17342 left: position.left, 17343 top: position.top 17344 } ); 17345 17346 return placeholder; 17347 }, 17348 17349 removePlaceholder: function( element ) { 17350 var dataKey = dataSpace + "placeholder", 17351 placeholder = element.data( dataKey ); 17352 17353 if ( placeholder ) { 17354 placeholder.remove(); 17355 element.removeData( dataKey ); 17356 } 17357 }, 17358 17359 // Removes a placeholder if it exists and restores 17360 // properties that were modified during placeholder creation 17361 cleanUp: function( element ) { 17362 $.effects.restoreStyle( element ); 17363 $.effects.removePlaceholder( element ); 17364 }, 17365 17366 setTransition: function( element, list, factor, value ) { 17367 value = value || {}; 17368 $.each( list, function( i, x ) { 17369 var unit = element.cssUnit( x ); 17370 if ( unit[ 0 ] > 0 ) { 17371 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 17372 } 17373 } ); 17374 return value; 17375 } 17376} ); 17377 17378// Return an effect options object for the given parameters: 17379function _normalizeArguments( effect, options, speed, callback ) { 17380 17381 // Allow passing all options as the first parameter 17382 if ( $.isPlainObject( effect ) ) { 17383 options = effect; 17384 effect = effect.effect; 17385 } 17386 17387 // Convert to an object 17388 effect = { effect: effect }; 17389 17390 // Catch (effect, null, ...) 17391 if ( options == null ) { 17392 options = {}; 17393 } 17394 17395 // Catch (effect, callback) 17396 if ( $.isFunction( options ) ) { 17397 callback = options; 17398 speed = null; 17399 options = {}; 17400 } 17401 17402 // Catch (effect, speed, ?) 17403 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 17404 callback = speed; 17405 speed = options; 17406 options = {}; 17407 } 17408 17409 // Catch (effect, options, callback) 17410 if ( $.isFunction( speed ) ) { 17411 callback = speed; 17412 speed = null; 17413 } 17414 17415 // Add options to effect 17416 if ( options ) { 17417 $.extend( effect, options ); 17418 } 17419 17420 speed = speed || options.duration; 17421 effect.duration = $.fx.off ? 0 : 17422 typeof speed === "number" ? speed : 17423 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 17424 $.fx.speeds._default; 17425 17426 effect.complete = callback || options.complete; 17427 17428 return effect; 17429} 17430 17431function standardAnimationOption( option ) { 17432 17433 // Valid standard speeds (nothing, number, named speed) 17434 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 17435 return true; 17436 } 17437 17438 // Invalid strings - treat as "normal" speed 17439 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 17440 return true; 17441 } 17442 17443 // Complete callback 17444 if ( $.isFunction( option ) ) { 17445 return true; 17446 } 17447 17448 // Options hash (but not naming an effect) 17449 if ( typeof option === "object" && !option.effect ) { 17450 return true; 17451 } 17452 17453 // Didn't match any standard API 17454 return false; 17455} 17456 17457$.fn.extend( { 17458 effect: function( /* effect, options, speed, callback */ ) { 17459 var args = _normalizeArguments.apply( this, arguments ), 17460 effectMethod = $.effects.effect[ args.effect ], 17461 defaultMode = effectMethod.mode, 17462 queue = args.queue, 17463 queueName = queue || "fx", 17464 complete = args.complete, 17465 mode = args.mode, 17466 modes = [], 17467 prefilter = function( next ) { 17468 var el = $( this ), 17469 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 17470 17471 // Sentinel for duck-punching the :animated psuedo-selector 17472 el.data( dataSpaceAnimated, true ); 17473 17474 // Save effect mode for later use, 17475 // we can't just call $.effects.mode again later, 17476 // as the .show() below destroys the initial state 17477 modes.push( normalizedMode ); 17478 17479 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13 17480 if ( defaultMode && ( normalizedMode === "show" || 17481 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 17482 el.show(); 17483 } 17484 17485 if ( !defaultMode || normalizedMode !== "none" ) { 17486 $.effects.saveStyle( el ); 17487 } 17488 17489 if ( $.isFunction( next ) ) { 17490 next(); 17491 } 17492 }; 17493 17494 if ( $.fx.off || !effectMethod ) { 17495 17496 // Delegate to the original method (e.g., .show()) if possible 17497 if ( mode ) { 17498 return this[ mode ]( args.duration, complete ); 17499 } else { 17500 return this.each( function() { 17501 if ( complete ) { 17502 complete.call( this ); 17503 } 17504 } ); 17505 } 17506 } 17507 17508 function run( next ) { 17509 var elem = $( this ); 17510 17511 function cleanup() { 17512 elem.removeData( dataSpaceAnimated ); 17513 17514 $.effects.cleanUp( elem ); 17515 17516 if ( args.mode === "hide" ) { 17517 elem.hide(); 17518 } 17519 17520 done(); 17521 } 17522 17523 function done() { 17524 if ( $.isFunction( complete ) ) { 17525 complete.call( elem[ 0 ] ); 17526 } 17527 17528 if ( $.isFunction( next ) ) { 17529 next(); 17530 } 17531 } 17532 17533 // Override mode option on a per element basis, 17534 // as toggle can be either show or hide depending on element state 17535 args.mode = modes.shift(); 17536 17537 if ( $.uiBackCompat !== false && !defaultMode ) { 17538 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 17539 17540 // Call the core method to track "olddisplay" properly 17541 elem[ mode ](); 17542 done(); 17543 } else { 17544 effectMethod.call( elem[ 0 ], args, done ); 17545 } 17546 } else { 17547 if ( args.mode === "none" ) { 17548 17549 // Call the core method to track "olddisplay" properly 17550 elem[ mode ](); 17551 done(); 17552 } else { 17553 effectMethod.call( elem[ 0 ], args, cleanup ); 17554 } 17555 } 17556 } 17557 17558 // Run prefilter on all elements first to ensure that 17559 // any showing or hiding happens before placeholder creation, 17560 // which ensures that any layout changes are correctly captured. 17561 return queue === false ? 17562 this.each( prefilter ).each( run ) : 17563 this.queue( queueName, prefilter ).queue( queueName, run ); 17564 }, 17565 17566 show: ( function( orig ) { 17567 return function( option ) { 17568 if ( standardAnimationOption( option ) ) { 17569 return orig.apply( this, arguments ); 17570 } else { 17571 var args = _normalizeArguments.apply( this, arguments ); 17572 args.mode = "show"; 17573 return this.effect.call( this, args ); 17574 } 17575 }; 17576 } )( $.fn.show ), 17577 17578 hide: ( function( orig ) { 17579 return function( option ) { 17580 if ( standardAnimationOption( option ) ) { 17581 return orig.apply( this, arguments ); 17582 } else { 17583 var args = _normalizeArguments.apply( this, arguments ); 17584 args.mode = "hide"; 17585 return this.effect.call( this, args ); 17586 } 17587 }; 17588 } )( $.fn.hide ), 17589 17590 toggle: ( function( orig ) { 17591 return function( option ) { 17592 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 17593 return orig.apply( this, arguments ); 17594 } else { 17595 var args = _normalizeArguments.apply( this, arguments ); 17596 args.mode = "toggle"; 17597 return this.effect.call( this, args ); 17598 } 17599 }; 17600 } )( $.fn.toggle ), 17601 17602 cssUnit: function( key ) { 17603 var style = this.css( key ), 17604 val = []; 17605 17606 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 17607 if ( style.indexOf( unit ) > 0 ) { 17608 val = [ parseFloat( style ), unit ]; 17609 } 17610 } ); 17611 return val; 17612 }, 17613 17614 cssClip: function( clipObj ) { 17615 if ( clipObj ) { 17616 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 17617 clipObj.bottom + "px " + clipObj.left + "px)" ); 17618 } 17619 return parseClip( this.css( "clip" ), this ); 17620 }, 17621 17622 transfer: function( options, done ) { 17623 var element = $( this ), 17624 target = $( options.to ), 17625 targetFixed = target.css( "position" ) === "fixed", 17626 body = $( "body" ), 17627 fixTop = targetFixed ? body.scrollTop() : 0, 17628 fixLeft = targetFixed ? body.scrollLeft() : 0, 17629 endPosition = target.offset(), 17630 animation = { 17631 top: endPosition.top - fixTop, 17632 left: endPosition.left - fixLeft, 17633 height: target.innerHeight(), 17634 width: target.innerWidth() 17635 }, 17636 startPosition = element.offset(), 17637 transfer = $( "<div class='ui-effects-transfer'></div>" ) 17638 .appendTo( "body" ) 17639 .addClass( options.className ) 17640 .css( { 17641 top: startPosition.top - fixTop, 17642 left: startPosition.left - fixLeft, 17643 height: element.innerHeight(), 17644 width: element.innerWidth(), 17645 position: targetFixed ? "fixed" : "absolute" 17646 } ) 17647 .animate( animation, options.duration, options.easing, function() { 17648 transfer.remove(); 17649 if ( $.isFunction( done ) ) { 17650 done(); 17651 } 17652 } ); 17653 } 17654} ); 17655 17656function parseClip( str, element ) { 17657 var outerWidth = element.outerWidth(), 17658 outerHeight = element.outerHeight(), 17659 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)\)$/, 17660 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 17661 17662 return { 17663 top: parseFloat( values[ 1 ] ) || 0, 17664 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 17665 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 17666 left: parseFloat( values[ 4 ] ) || 0 17667 }; 17668} 17669 17670$.fx.step.clip = function( fx ) { 17671 if ( !fx.clipInit ) { 17672 fx.start = $( fx.elem ).cssClip(); 17673 if ( typeof fx.end === "string" ) { 17674 fx.end = parseClip( fx.end, fx.elem ); 17675 } 17676 fx.clipInit = true; 17677 } 17678 17679 $( fx.elem ).cssClip( { 17680 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 17681 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 17682 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 17683 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 17684 } ); 17685}; 17686 17687} )(); 17688 17689/******************************************************************************/ 17690/*********************************** EASING ***********************************/ 17691/******************************************************************************/ 17692 17693( function() { 17694 17695// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 17696 17697var baseEasings = {}; 17698 17699$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 17700 baseEasings[ name ] = function( p ) { 17701 return Math.pow( p, i + 2 ); 17702 }; 17703} ); 17704 17705$.extend( baseEasings, { 17706 Sine: function( p ) { 17707 return 1 - Math.cos( p * Math.PI / 2 ); 17708 }, 17709 Circ: function( p ) { 17710 return 1 - Math.sqrt( 1 - p * p ); 17711 }, 17712 Elastic: function( p ) { 17713 return p === 0 || p === 1 ? p : 17714 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 17715 }, 17716 Back: function( p ) { 17717 return p * p * ( 3 * p - 2 ); 17718 }, 17719 Bounce: function( p ) { 17720 var pow2, 17721 bounce = 4; 17722 17723 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 17724 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 17725 } 17726} ); 17727 17728$.each( baseEasings, function( name, easeIn ) { 17729 $.easing[ "easeIn" + name ] = easeIn; 17730 $.easing[ "easeOut" + name ] = function( p ) { 17731 return 1 - easeIn( 1 - p ); 17732 }; 17733 $.easing[ "easeInOut" + name ] = function( p ) { 17734 return p < 0.5 ? 17735 easeIn( p * 2 ) / 2 : 17736 1 - easeIn( p * -2 + 2 ) / 2; 17737 }; 17738} ); 17739 17740} )(); 17741 17742var effect = $.effects; 17743 17744 17745/*! 17746 * jQuery UI Effects Blind 1.12.1 17747 * http://jqueryui.com 17748 * 17749 * Copyright jQuery Foundation and other contributors 17750 * Released under the MIT license. 17751 * http://jquery.org/license 17752 */ 17753 17754//>>label: Blind Effect 17755//>>group: Effects 17756//>>description: Blinds the element. 17757//>>docs: http://api.jqueryui.com/blind-effect/ 17758//>>demos: http://jqueryui.com/effect/ 17759 17760 17761 17762var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 17763 var map = { 17764 up: [ "bottom", "top" ], 17765 vertical: [ "bottom", "top" ], 17766 down: [ "top", "bottom" ], 17767 left: [ "right", "left" ], 17768 horizontal: [ "right", "left" ], 17769 right: [ "left", "right" ] 17770 }, 17771 element = $( this ), 17772 direction = options.direction || "up", 17773 start = element.cssClip(), 17774 animate = { clip: $.extend( {}, start ) }, 17775 placeholder = $.effects.createPlaceholder( element ); 17776 17777 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 17778 17779 if ( options.mode === "show" ) { 17780 element.cssClip( animate.clip ); 17781 if ( placeholder ) { 17782 placeholder.css( $.effects.clipToBox( animate ) ); 17783 } 17784 17785 animate.clip = start; 17786 } 17787 17788 if ( placeholder ) { 17789 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 17790 } 17791 17792 element.animate( animate, { 17793 queue: false, 17794 duration: options.duration, 17795 easing: options.easing, 17796 complete: done 17797 } ); 17798} ); 17799 17800 17801/*! 17802 * jQuery UI Effects Bounce 1.12.1 17803 * http://jqueryui.com 17804 * 17805 * Copyright jQuery Foundation and other contributors 17806 * Released under the MIT license. 17807 * http://jquery.org/license 17808 */ 17809 17810//>>label: Bounce Effect 17811//>>group: Effects 17812//>>description: Bounces an element horizontally or vertically n times. 17813//>>docs: http://api.jqueryui.com/bounce-effect/ 17814//>>demos: http://jqueryui.com/effect/ 17815 17816 17817 17818var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 17819 var upAnim, downAnim, refValue, 17820 element = $( this ), 17821 17822 // Defaults: 17823 mode = options.mode, 17824 hide = mode === "hide", 17825 show = mode === "show", 17826 direction = options.direction || "up", 17827 distance = options.distance, 17828 times = options.times || 5, 17829 17830 // Number of internal animations 17831 anims = times * 2 + ( show || hide ? 1 : 0 ), 17832 speed = options.duration / anims, 17833 easing = options.easing, 17834 17835 // Utility: 17836 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17837 motion = ( direction === "up" || direction === "left" ), 17838 i = 0, 17839 17840 queuelen = element.queue().length; 17841 17842 $.effects.createPlaceholder( element ); 17843 17844 refValue = element.css( ref ); 17845 17846 // Default distance for the BIGGEST bounce is the outer Distance / 3 17847 if ( !distance ) { 17848 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 17849 } 17850 17851 if ( show ) { 17852 downAnim = { opacity: 1 }; 17853 downAnim[ ref ] = refValue; 17854 17855 // If we are showing, force opacity 0 and set the initial position 17856 // then do the "first" animation 17857 element 17858 .css( "opacity", 0 ) 17859 .css( ref, motion ? -distance * 2 : distance * 2 ) 17860 .animate( downAnim, speed, easing ); 17861 } 17862 17863 // Start at the smallest distance if we are hiding 17864 if ( hide ) { 17865 distance = distance / Math.pow( 2, times - 1 ); 17866 } 17867 17868 downAnim = {}; 17869 downAnim[ ref ] = refValue; 17870 17871 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 17872 for ( ; i < times; i++ ) { 17873 upAnim = {}; 17874 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 17875 17876 element 17877 .animate( upAnim, speed, easing ) 17878 .animate( downAnim, speed, easing ); 17879 17880 distance = hide ? distance * 2 : distance / 2; 17881 } 17882 17883 // Last Bounce when Hiding 17884 if ( hide ) { 17885 upAnim = { opacity: 0 }; 17886 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 17887 17888 element.animate( upAnim, speed, easing ); 17889 } 17890 17891 element.queue( done ); 17892 17893 $.effects.unshift( element, queuelen, anims + 1 ); 17894} ); 17895 17896 17897/*! 17898 * jQuery UI Effects Clip 1.12.1 17899 * http://jqueryui.com 17900 * 17901 * Copyright jQuery Foundation and other contributors 17902 * Released under the MIT license. 17903 * http://jquery.org/license 17904 */ 17905 17906//>>label: Clip Effect 17907//>>group: Effects 17908//>>description: Clips the element on and off like an old TV. 17909//>>docs: http://api.jqueryui.com/clip-effect/ 17910//>>demos: http://jqueryui.com/effect/ 17911 17912 17913 17914var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 17915 var start, 17916 animate = {}, 17917 element = $( this ), 17918 direction = options.direction || "vertical", 17919 both = direction === "both", 17920 horizontal = both || direction === "horizontal", 17921 vertical = both || direction === "vertical"; 17922 17923 start = element.cssClip(); 17924 animate.clip = { 17925 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 17926 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 17927 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 17928 left: horizontal ? ( start.right - start.left ) / 2 : start.left 17929 }; 17930 17931 $.effects.createPlaceholder( element ); 17932 17933 if ( options.mode === "show" ) { 17934 element.cssClip( animate.clip ); 17935 animate.clip = start; 17936 } 17937 17938 element.animate( animate, { 17939 queue: false, 17940 duration: options.duration, 17941 easing: options.easing, 17942 complete: done 17943 } ); 17944 17945} ); 17946 17947 17948/*! 17949 * jQuery UI Effects Drop 1.12.1 17950 * http://jqueryui.com 17951 * 17952 * Copyright jQuery Foundation and other contributors 17953 * Released under the MIT license. 17954 * http://jquery.org/license 17955 */ 17956 17957//>>label: Drop Effect 17958//>>group: Effects 17959//>>description: Moves an element in one direction and hides it at the same time. 17960//>>docs: http://api.jqueryui.com/drop-effect/ 17961//>>demos: http://jqueryui.com/effect/ 17962 17963 17964 17965var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 17966 17967 var distance, 17968 element = $( this ), 17969 mode = options.mode, 17970 show = mode === "show", 17971 direction = options.direction || "left", 17972 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17973 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 17974 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 17975 animation = { 17976 opacity: 0 17977 }; 17978 17979 $.effects.createPlaceholder( element ); 17980 17981 distance = options.distance || 17982 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 17983 17984 animation[ ref ] = motion + distance; 17985 17986 if ( show ) { 17987 element.css( animation ); 17988 17989 animation[ ref ] = oppositeMotion + distance; 17990 animation.opacity = 1; 17991 } 17992 17993 // Animate 17994 element.animate( animation, { 17995 queue: false, 17996 duration: options.duration, 17997 easing: options.easing, 17998 complete: done 17999 } ); 18000} ); 18001 18002 18003/*! 18004 * jQuery UI Effects Explode 1.12.1 18005 * http://jqueryui.com 18006 * 18007 * Copyright jQuery Foundation and other contributors 18008 * Released under the MIT license. 18009 * http://jquery.org/license 18010 */ 18011 18012//>>label: Explode Effect 18013//>>group: Effects 18014// jscs:disable maximumLineLength 18015//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 18016// jscs:enable maximumLineLength 18017//>>docs: http://api.jqueryui.com/explode-effect/ 18018//>>demos: http://jqueryui.com/effect/ 18019 18020 18021 18022var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 18023 18024 var i, j, left, top, mx, my, 18025 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 18026 cells = rows, 18027 element = $( this ), 18028 mode = options.mode, 18029 show = mode === "show", 18030 18031 // Show and then visibility:hidden the element before calculating offset 18032 offset = element.show().css( "visibility", "hidden" ).offset(), 18033 18034 // Width and height of a piece 18035 width = Math.ceil( element.outerWidth() / cells ), 18036 height = Math.ceil( element.outerHeight() / rows ), 18037 pieces = []; 18038 18039 // Children animate complete: 18040 function childComplete() { 18041 pieces.push( this ); 18042 if ( pieces.length === rows * cells ) { 18043 animComplete(); 18044 } 18045 } 18046 18047 // Clone the element for each row and cell. 18048 for ( i = 0; i < rows; i++ ) { // ===> 18049 top = offset.top + i * height; 18050 my = i - ( rows - 1 ) / 2; 18051 18052 for ( j = 0; j < cells; j++ ) { // ||| 18053 left = offset.left + j * width; 18054 mx = j - ( cells - 1 ) / 2; 18055 18056 // Create a clone of the now hidden main element that will be absolute positioned 18057 // within a wrapper div off the -left and -top equal to size of our pieces 18058 element 18059 .clone() 18060 .appendTo( "body" ) 18061 .wrap( "<div></div>" ) 18062 .css( { 18063 position: "absolute", 18064 visibility: "visible", 18065 left: -j * width, 18066 top: -i * height 18067 } ) 18068 18069 // Select the wrapper - make it overflow: hidden and absolute positioned based on 18070 // where the original was located +left and +top equal to the size of pieces 18071 .parent() 18072 .addClass( "ui-effects-explode" ) 18073 .css( { 18074 position: "absolute", 18075 overflow: "hidden", 18076 width: width, 18077 height: height, 18078 left: left + ( show ? mx * width : 0 ), 18079 top: top + ( show ? my * height : 0 ), 18080 opacity: show ? 0 : 1 18081 } ) 18082 .animate( { 18083 left: left + ( show ? 0 : mx * width ), 18084 top: top + ( show ? 0 : my * height ), 18085 opacity: show ? 1 : 0 18086 }, options.duration || 500, options.easing, childComplete ); 18087 } 18088 } 18089 18090 function animComplete() { 18091 element.css( { 18092 visibility: "visible" 18093 } ); 18094 $( pieces ).remove(); 18095 done(); 18096 } 18097} ); 18098 18099 18100/*! 18101 * jQuery UI Effects Fade 1.12.1 18102 * http://jqueryui.com 18103 * 18104 * Copyright jQuery Foundation and other contributors 18105 * Released under the MIT license. 18106 * http://jquery.org/license 18107 */ 18108 18109//>>label: Fade Effect 18110//>>group: Effects 18111//>>description: Fades the element. 18112//>>docs: http://api.jqueryui.com/fade-effect/ 18113//>>demos: http://jqueryui.com/effect/ 18114 18115 18116 18117var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 18118 var show = options.mode === "show"; 18119 18120 $( this ) 18121 .css( "opacity", show ? 0 : 1 ) 18122 .animate( { 18123 opacity: show ? 1 : 0 18124 }, { 18125 queue: false, 18126 duration: options.duration, 18127 easing: options.easing, 18128 complete: done 18129 } ); 18130} ); 18131 18132 18133/*! 18134 * jQuery UI Effects Fold 1.12.1 18135 * http://jqueryui.com 18136 * 18137 * Copyright jQuery Foundation and other contributors 18138 * Released under the MIT license. 18139 * http://jquery.org/license 18140 */ 18141 18142//>>label: Fold Effect 18143//>>group: Effects 18144//>>description: Folds an element first horizontally and then vertically. 18145//>>docs: http://api.jqueryui.com/fold-effect/ 18146//>>demos: http://jqueryui.com/effect/ 18147 18148 18149 18150var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 18151 18152 // Create element 18153 var element = $( this ), 18154 mode = options.mode, 18155 show = mode === "show", 18156 hide = mode === "hide", 18157 size = options.size || 15, 18158 percent = /([0-9]+)%/.exec( size ), 18159 horizFirst = !!options.horizFirst, 18160 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 18161 duration = options.duration / 2, 18162 18163 placeholder = $.effects.createPlaceholder( element ), 18164 18165 start = element.cssClip(), 18166 animation1 = { clip: $.extend( {}, start ) }, 18167 animation2 = { clip: $.extend( {}, start ) }, 18168 18169 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 18170 18171 queuelen = element.queue().length; 18172 18173 if ( percent ) { 18174 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 18175 } 18176 animation1.clip[ ref[ 0 ] ] = size; 18177 animation2.clip[ ref[ 0 ] ] = size; 18178 animation2.clip[ ref[ 1 ] ] = 0; 18179 18180 if ( show ) { 18181 element.cssClip( animation2.clip ); 18182 if ( placeholder ) { 18183 placeholder.css( $.effects.clipToBox( animation2 ) ); 18184 } 18185 18186 animation2.clip = start; 18187 } 18188 18189 // Animate 18190 element 18191 .queue( function( next ) { 18192 if ( placeholder ) { 18193 placeholder 18194 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 18195 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 18196 } 18197 18198 next(); 18199 } ) 18200 .animate( animation1, duration, options.easing ) 18201 .animate( animation2, duration, options.easing ) 18202 .queue( done ); 18203 18204 $.effects.unshift( element, queuelen, 4 ); 18205} ); 18206 18207 18208/*! 18209 * jQuery UI Effects Highlight 1.12.1 18210 * http://jqueryui.com 18211 * 18212 * Copyright jQuery Foundation and other contributors 18213 * Released under the MIT license. 18214 * http://jquery.org/license 18215 */ 18216 18217//>>label: Highlight Effect 18218//>>group: Effects 18219//>>description: Highlights the background of an element in a defined color for a custom duration. 18220//>>docs: http://api.jqueryui.com/highlight-effect/ 18221//>>demos: http://jqueryui.com/effect/ 18222 18223 18224 18225var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 18226 var element = $( this ), 18227 animation = { 18228 backgroundColor: element.css( "backgroundColor" ) 18229 }; 18230 18231 if ( options.mode === "hide" ) { 18232 animation.opacity = 0; 18233 } 18234 18235 $.effects.saveStyle( element ); 18236 18237 element 18238 .css( { 18239 backgroundImage: "none", 18240 backgroundColor: options.color || "#ffff99" 18241 } ) 18242 .animate( animation, { 18243 queue: false, 18244 duration: options.duration, 18245 easing: options.easing, 18246 complete: done 18247 } ); 18248} ); 18249 18250 18251/*! 18252 * jQuery UI Effects Size 1.12.1 18253 * http://jqueryui.com 18254 * 18255 * Copyright jQuery Foundation and other contributors 18256 * Released under the MIT license. 18257 * http://jquery.org/license 18258 */ 18259 18260//>>label: Size Effect 18261//>>group: Effects 18262//>>description: Resize an element to a specified width and height. 18263//>>docs: http://api.jqueryui.com/size-effect/ 18264//>>demos: http://jqueryui.com/effect/ 18265 18266 18267 18268var effectsEffectSize = $.effects.define( "size", function( options, done ) { 18269 18270 // Create element 18271 var baseline, factor, temp, 18272 element = $( this ), 18273 18274 // Copy for children 18275 cProps = [ "fontSize" ], 18276 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 18277 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 18278 18279 // Set options 18280 mode = options.mode, 18281 restore = mode !== "effect", 18282 scale = options.scale || "both", 18283 origin = options.origin || [ "middle", "center" ], 18284 position = element.css( "position" ), 18285 pos = element.position(), 18286 original = $.effects.scaledDimensions( element ), 18287 from = options.from || original, 18288 to = options.to || $.effects.scaledDimensions( element, 0 ); 18289 18290 $.effects.createPlaceholder( element ); 18291 18292 if ( mode === "show" ) { 18293 temp = from; 18294 from = to; 18295 to = temp; 18296 } 18297 18298 // Set scaling factor 18299 factor = { 18300 from: { 18301 y: from.height / original.height, 18302 x: from.width / original.width 18303 }, 18304 to: { 18305 y: to.height / original.height, 18306 x: to.width / original.width 18307 } 18308 }; 18309 18310 // Scale the css box 18311 if ( scale === "box" || scale === "both" ) { 18312 18313 // Vertical props scaling 18314 if ( factor.from.y !== factor.to.y ) { 18315 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 18316 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 18317 } 18318 18319 // Horizontal props scaling 18320 if ( factor.from.x !== factor.to.x ) { 18321 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 18322 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 18323 } 18324 } 18325 18326 // Scale the content 18327 if ( scale === "content" || scale === "both" ) { 18328 18329 // Vertical props scaling 18330 if ( factor.from.y !== factor.to.y ) { 18331 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 18332 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 18333 } 18334 } 18335 18336 // Adjust the position properties based on the provided origin points 18337 if ( origin ) { 18338 baseline = $.effects.getBaseline( origin, original ); 18339 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 18340 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 18341 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 18342 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 18343 } 18344 element.css( from ); 18345 18346 // Animate the children if desired 18347 if ( scale === "content" || scale === "both" ) { 18348 18349 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 18350 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 18351 18352 // Only animate children with width attributes specified 18353 // TODO: is this right? should we include anything with css width specified as well 18354 element.find( "*[width]" ).each( function() { 18355 var child = $( this ), 18356 childOriginal = $.effects.scaledDimensions( child ), 18357 childFrom = { 18358 height: childOriginal.height * factor.from.y, 18359 width: childOriginal.width * factor.from.x, 18360 outerHeight: childOriginal.outerHeight * factor.from.y, 18361 outerWidth: childOriginal.outerWidth * factor.from.x 18362 }, 18363 childTo = { 18364 height: childOriginal.height * factor.to.y, 18365 width: childOriginal.width * factor.to.x, 18366 outerHeight: childOriginal.height * factor.to.y, 18367 outerWidth: childOriginal.width * factor.to.x 18368 }; 18369 18370 // Vertical props scaling 18371 if ( factor.from.y !== factor.to.y ) { 18372 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 18373 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 18374 } 18375 18376 // Horizontal props scaling 18377 if ( factor.from.x !== factor.to.x ) { 18378 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 18379 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 18380 } 18381 18382 if ( restore ) { 18383 $.effects.saveStyle( child ); 18384 } 18385 18386 // Animate children 18387 child.css( childFrom ); 18388 child.animate( childTo, options.duration, options.easing, function() { 18389 18390 // Restore children 18391 if ( restore ) { 18392 $.effects.restoreStyle( child ); 18393 } 18394 } ); 18395 } ); 18396 } 18397 18398 // Animate 18399 element.animate( to, { 18400 queue: false, 18401 duration: options.duration, 18402 easing: options.easing, 18403 complete: function() { 18404 18405 var offset = element.offset(); 18406 18407 if ( to.opacity === 0 ) { 18408 element.css( "opacity", from.opacity ); 18409 } 18410 18411 if ( !restore ) { 18412 element 18413 .css( "position", position === "static" ? "relative" : position ) 18414 .offset( offset ); 18415 18416 // Need to save style here so that automatic style restoration 18417 // doesn't restore to the original styles from before the animation. 18418 $.effects.saveStyle( element ); 18419 } 18420 18421 done(); 18422 } 18423 } ); 18424 18425} ); 18426 18427 18428/*! 18429 * jQuery UI Effects Scale 1.12.1 18430 * http://jqueryui.com 18431 * 18432 * Copyright jQuery Foundation and other contributors 18433 * Released under the MIT license. 18434 * http://jquery.org/license 18435 */ 18436 18437//>>label: Scale Effect 18438//>>group: Effects 18439//>>description: Grows or shrinks an element and its content. 18440//>>docs: http://api.jqueryui.com/scale-effect/ 18441//>>demos: http://jqueryui.com/effect/ 18442 18443 18444 18445var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 18446 18447 // Create element 18448 var el = $( this ), 18449 mode = options.mode, 18450 percent = parseInt( options.percent, 10 ) || 18451 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 18452 18453 newOptions = $.extend( true, { 18454 from: $.effects.scaledDimensions( el ), 18455 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 18456 origin: options.origin || [ "middle", "center" ] 18457 }, options ); 18458 18459 // Fade option to support puff 18460 if ( options.fade ) { 18461 newOptions.from.opacity = 1; 18462 newOptions.to.opacity = 0; 18463 } 18464 18465 $.effects.effect.size.call( this, newOptions, done ); 18466} ); 18467 18468 18469/*! 18470 * jQuery UI Effects Puff 1.12.1 18471 * http://jqueryui.com 18472 * 18473 * Copyright jQuery Foundation and other contributors 18474 * Released under the MIT license. 18475 * http://jquery.org/license 18476 */ 18477 18478//>>label: Puff Effect 18479//>>group: Effects 18480//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 18481//>>docs: http://api.jqueryui.com/puff-effect/ 18482//>>demos: http://jqueryui.com/effect/ 18483 18484 18485 18486var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 18487 var newOptions = $.extend( true, {}, options, { 18488 fade: true, 18489 percent: parseInt( options.percent, 10 ) || 150 18490 } ); 18491 18492 $.effects.effect.scale.call( this, newOptions, done ); 18493} ); 18494 18495 18496/*! 18497 * jQuery UI Effects Pulsate 1.12.1 18498 * http://jqueryui.com 18499 * 18500 * Copyright jQuery Foundation and other contributors 18501 * Released under the MIT license. 18502 * http://jquery.org/license 18503 */ 18504 18505//>>label: Pulsate Effect 18506//>>group: Effects 18507//>>description: Pulsates an element n times by changing the opacity to zero and back. 18508//>>docs: http://api.jqueryui.com/pulsate-effect/ 18509//>>demos: http://jqueryui.com/effect/ 18510 18511 18512 18513var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 18514 var element = $( this ), 18515 mode = options.mode, 18516 show = mode === "show", 18517 hide = mode === "hide", 18518 showhide = show || hide, 18519 18520 // Showing or hiding leaves off the "last" animation 18521 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 18522 duration = options.duration / anims, 18523 animateTo = 0, 18524 i = 1, 18525 queuelen = element.queue().length; 18526 18527 if ( show || !element.is( ":visible" ) ) { 18528 element.css( "opacity", 0 ).show(); 18529 animateTo = 1; 18530 } 18531 18532 // Anims - 1 opacity "toggles" 18533 for ( ; i < anims; i++ ) { 18534 element.animate( { opacity: animateTo }, duration, options.easing ); 18535 animateTo = 1 - animateTo; 18536 } 18537 18538 element.animate( { opacity: animateTo }, duration, options.easing ); 18539 18540 element.queue( done ); 18541 18542 $.effects.unshift( element, queuelen, anims + 1 ); 18543} ); 18544 18545 18546/*! 18547 * jQuery UI Effects Shake 1.12.1 18548 * http://jqueryui.com 18549 * 18550 * Copyright jQuery Foundation and other contributors 18551 * Released under the MIT license. 18552 * http://jquery.org/license 18553 */ 18554 18555//>>label: Shake Effect 18556//>>group: Effects 18557//>>description: Shakes an element horizontally or vertically n times. 18558//>>docs: http://api.jqueryui.com/shake-effect/ 18559//>>demos: http://jqueryui.com/effect/ 18560 18561 18562 18563var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 18564 18565 var i = 1, 18566 element = $( this ), 18567 direction = options.direction || "left", 18568 distance = options.distance || 20, 18569 times = options.times || 3, 18570 anims = times * 2 + 1, 18571 speed = Math.round( options.duration / anims ), 18572 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18573 positiveMotion = ( direction === "up" || direction === "left" ), 18574 animation = {}, 18575 animation1 = {}, 18576 animation2 = {}, 18577 18578 queuelen = element.queue().length; 18579 18580 $.effects.createPlaceholder( element ); 18581 18582 // Animation 18583 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 18584 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 18585 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 18586 18587 // Animate 18588 element.animate( animation, speed, options.easing ); 18589 18590 // Shakes 18591 for ( ; i < times; i++ ) { 18592 element 18593 .animate( animation1, speed, options.easing ) 18594 .animate( animation2, speed, options.easing ); 18595 } 18596 18597 element 18598 .animate( animation1, speed, options.easing ) 18599 .animate( animation, speed / 2, options.easing ) 18600 .queue( done ); 18601 18602 $.effects.unshift( element, queuelen, anims + 1 ); 18603} ); 18604 18605 18606/*! 18607 * jQuery UI Effects Slide 1.12.1 18608 * http://jqueryui.com 18609 * 18610 * Copyright jQuery Foundation and other contributors 18611 * Released under the MIT license. 18612 * http://jquery.org/license 18613 */ 18614 18615//>>label: Slide Effect 18616//>>group: Effects 18617//>>description: Slides an element in and out of the viewport. 18618//>>docs: http://api.jqueryui.com/slide-effect/ 18619//>>demos: http://jqueryui.com/effect/ 18620 18621 18622 18623var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 18624 var startClip, startRef, 18625 element = $( this ), 18626 map = { 18627 up: [ "bottom", "top" ], 18628 down: [ "top", "bottom" ], 18629 left: [ "right", "left" ], 18630 right: [ "left", "right" ] 18631 }, 18632 mode = options.mode, 18633 direction = options.direction || "left", 18634 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18635 positiveMotion = ( direction === "up" || direction === "left" ), 18636 distance = options.distance || 18637 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 18638 animation = {}; 18639 18640 $.effects.createPlaceholder( element ); 18641 18642 startClip = element.cssClip(); 18643 startRef = element.position()[ ref ]; 18644 18645 // Define hide animation 18646 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 18647 animation.clip = element.cssClip(); 18648 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 18649 18650 // Reverse the animation if we're showing 18651 if ( mode === "show" ) { 18652 element.cssClip( animation.clip ); 18653 element.css( ref, animation[ ref ] ); 18654 animation.clip = startClip; 18655 animation[ ref ] = startRef; 18656 } 18657 18658 // Actually animate 18659 element.animate( animation, { 18660 queue: false, 18661 duration: options.duration, 18662 easing: options.easing,
vendor: 637 bytes, lines 18663-18696
18663 complete: done 18664 } ); 18665} ); 18666 18667 18668/*! 18669 * jQuery UI Effects Transfer 1.12.1 18670 * http://jqueryui.com 18671 * 18672 * Copyright jQuery Foundation and other contributors 18673 * Released under the MIT license. 18674 * http://jquery.org/license 18675 */ 18676 18677//>>label: Transfer Effect 18678//>>group: Effects 18679//>>description: Displays a transfer effect from one element to another. 18680//>>docs: http://api.jqueryui.com/transfer-effect/ 18681//>>demos: http://jqueryui.com/effect/ 18682 18683 18684 18685var effect; 18686if ( $.uiBackCompat !== false ) { 18687 effect = $.effects.define( "transfer", function( options, done ) { 18688 $( this ).transfer( options, done ); 18689 } ); 18690} 18691var effectsEffectTransfer = effect; 18692 18693 18694 18695 18696}));
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.