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