1/*! jQuery UI - v1.12.1 - 2016-12-29 2* http://jqueryui.com 3* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer
vendor: 46,668 bytes, lines 3-1721
3.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( factory ) { 7 if ( typeof define === "function" && define.amd ) { 8 9 // AMD. Register as an anonymous module. 10 define([ "jquery" ], factory ); 11 } else { 12 13 // Browser globals 14 factory( jQuery ); 15 } 16}(function( $ ) { 17 18$.ui = $.ui || {}; 19 20var version = $.ui.version = "1.12.1"; 21 22 23/*! 24 * jQuery UI Widget 1.12.1 25 * http://jqueryui.com 26 * 27 * Copyright jQuery Foundation and other contributors 28 * Released under the MIT license. 29 * http://jquery.org/license 30 */ 31 32//>>label: Widget 33//>>group: Core 34//>>description: Provides a factory for creating stateful widgets with a common API. 35//>>docs: http://api.jqueryui.com/jQuery.widget/ 36//>>demos: http://jqueryui.com/widget/ 37 38 39 40var widgetUuid = 0; 41var widgetSlice = Array.prototype.slice; 42 43$.cleanData = ( function( orig ) { 44 return function( elems ) { 45 var events, elem, i; 46 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 47 try { 48 49 // Only trigger remove when necessary to save time 50 events = $._data( elem, "events" ); 51 if ( events && events.remove ) { 52 $( elem ).triggerHandler( "remove" ); 53 } 54 55 // Http://bugs.jquery.com/ticket/8235 56 } catch ( e ) {} 57 } 58 orig( elems ); 59 }; 60} )( $.cleanData ); 61 62$.widget = function( name, base, prototype ) { 63 var existingConstructor, constructor, basePrototype; 64 65 // ProxiedPrototype allows the provided prototype to remain unmodified 66 // so that it can be used as a mixin for multiple widgets (#8876) 67 var proxiedPrototype = {}; 68 69 var namespace = name.split( "." )[ 0 ]; 70 name = name.split( "." )[ 1 ]; 71 var fullName = namespace + "-" + name; 72 73 if ( !prototype ) { 74 prototype = base; 75 base = $.Widget; 76 } 77 78 if ( $.isArray( prototype ) ) { 79 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 80 } 81 82 // Create selector for plugin 83 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 84 return !!$.data( elem, fullName ); 85 }; 86 87 $[ namespace ] = $[ namespace ] || {}; 88 existingConstructor = $[ namespace ][ name ]; 89 constructor = $[ namespace ][ name ] = function( options, element ) { 90 91 // Allow instantiation without "new" keyword 92 if ( !this._createWidget ) { 93 return new constructor( options, element ); 94 } 95 96 // Allow instantiation without initializing for simple inheritance 97 // must use "new" keyword (the code above always passes args) 98 if ( arguments.length ) { 99 this._createWidget( options, element ); 100 } 101 }; 102 103 // Extend with the existing constructor to carry over any static properties 104 $.extend( constructor, existingConstructor, { 105 version: prototype.version, 106 107 // Copy the object used to create the prototype in case we need to 108 // redefine the widget later 109 _proto: $.extend( {}, prototype ), 110 111 // Track widgets that inherit from this widget in case this widget is 112 // redefined after a widget inherits from it 113 _childConstructors: [] 114 } ); 115 116 basePrototype = new base(); 117 118 // We need to make the options hash a property directly on the new instance 119 // otherwise we'll modify the options hash on the prototype that we're 120 // inheriting from 121 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 122 $.each( prototype, function( prop, value ) { 123 if ( !$.isFunction( value ) ) { 124 proxiedPrototype[ prop ] = value; 125 return; 126 } 127 proxiedPrototype[ prop ] = ( function() { 128 function _super() { 129 return base.prototype[ prop ].apply( this, arguments ); 130 } 131 132 function _superApply( args ) { 133 return base.prototype[ prop ].apply( this, args ); 134 } 135 136 return function() { 137 var __super = this._super; 138 var __superApply = this._superApply; 139 var returnValue; 140 141 this._super = _super; 142 this._superApply = _superApply; 143 144 returnValue = value.apply( this, arguments ); 145 146 this._super = __super; 147 this._superApply = __superApply; 148 149 return returnValue; 150 }; 151 } )(); 152 } ); 153 constructor.prototype = $.widget.extend( basePrototype, { 154 155 // TODO: remove support for widgetEventPrefix 156 // always use the name + a colon as the prefix, e.g., draggable:start 157 // don't prefix for widgets that aren't DOM-based 158 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 159 }, proxiedPrototype, { 160 constructor: constructor, 161 namespace: namespace, 162 widgetName: name, 163 widgetFullName: fullName 164 } ); 165 166 // If this widget is being redefined then we need to find all widgets that 167 // are inheriting from it and redefine all of them so that they inherit from 168 // the new version of this widget. We're essentially trying to replace one 169 // level in the prototype chain. 170 if ( existingConstructor ) { 171 $.each( existingConstructor._childConstructors, function( i, child ) { 172 var childPrototype = child.prototype; 173 174 // Redefine the child widget using the same prototype that was 175 // originally used, but inherit from the new version of the base 176 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 177 child._proto ); 178 } ); 179 180 // Remove the list of existing child constructors from the old constructor 181 // so the old child constructors can be garbage collected 182 delete existingConstructor._childConstructors; 183 } else { 184 base._childConstructors.push( constructor ); 185 } 186 187 $.widget.bridge( name, constructor ); 188 189 return constructor; 190}; 191 192$.widget.extend = function( target ) { 193 var input = widgetSlice.call( arguments, 1 ); 194 var inputIndex = 0; 195 var inputLength = input.length; 196 var key; 197 var value; 198 199 for ( ; inputIndex < inputLength; inputIndex++ ) { 200 for ( key in input[ inputIndex ] ) { 201 value = input[ inputIndex ][ key ]; 202 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 203 204 // Clone objects 205 if ( $.isPlainObject( value ) ) { 206 target[ key ] = $.isPlainObject( target[ key ] ) ? 207 $.widget.extend( {}, target[ key ], value ) : 208 209 // Don't extend strings, arrays, etc. with objects 210 $.widget.extend( {}, value ); 211 212 // Copy everything else by reference 213 } else { 214 target[ key ] = value; 215 } 216 } 217 } 218 } 219 return target; 220}; 221 222$.widget.bridge = function( name, object ) { 223 var fullName = object.prototype.widgetFullName || name; 224 $.fn[ name ] = function( options ) { 225 var isMethodCall = typeof options === "string"; 226 var args = widgetSlice.call( arguments, 1 ); 227 var returnValue = this; 228 229 if ( isMethodCall ) { 230 231 // If this is an empty collection, we need to have the instance method 232 // return undefined instead of the jQuery instance 233 if ( !this.length && options === "instance" ) { 234 returnValue = undefined; 235 } else { 236 this.each( function() { 237 var methodValue; 238 var instance = $.data( this, fullName ); 239 240 if ( options === "instance" ) { 241 returnValue = instance; 242 return false; 243 } 244 245 if ( !instance ) { 246 return $.error( "cannot call methods on " + name + 247 " prior to initialization; " + 248 "attempted to call method '" + options + "'" ); 249 } 250 251 if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { 252 return $.error( "no such method '" + options + "' for " + name + 253 " widget instance" ); 254 } 255 256 methodValue = instance[ options ].apply( instance, args ); 257 258 if ( methodValue !== instance && methodValue !== undefined ) { 259 returnValue = methodValue && methodValue.jquery ? 260 returnValue.pushStack( methodValue.get() ) : 261 methodValue; 262 return false; 263 } 264 } ); 265 } 266 } else { 267 268 // Allow multiple hashes to be passed on init 269 if ( args.length ) { 270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 271 } 272 273 this.each( function() { 274 var instance = $.data( this, fullName ); 275 if ( instance ) { 276 instance.option( options || {} ); 277 if ( instance._init ) { 278 instance._init(); 279 } 280 } else { 281 $.data( this, fullName, new object( options, this ) ); 282 } 283 } ); 284 } 285 286 return returnValue; 287 }; 288}; 289 290$.Widget = function( /* options, element */ ) {}; 291$.Widget._childConstructors = []; 292 293$.Widget.prototype = { 294 widgetName: "widget", 295 widgetEventPrefix: "", 296 defaultElement: "<div>", 297 298 options: { 299 classes: {}, 300 disabled: false, 301 302 // Callbacks 303 create: null 304 }, 305 306 _createWidget: function( options, element ) { 307 element = $( element || this.defaultElement || this )[ 0 ]; 308 this.element = $( element ); 309 this.uuid = widgetUuid++; 310 this.eventNamespace = "." + this.widgetName + this.uuid; 311 312 this.bindings = $(); 313 this.hoverable = $(); 314 this.focusable = $(); 315 this.classesElementLookup = {}; 316 317 if ( element !== this ) { 318 $.data( element, this.widgetFullName, this ); 319 this._on( true, this.element, { 320 remove: function( event ) { 321 if ( event.target === element ) { 322 this.destroy(); 323 } 324 } 325 } ); 326 this.document = $( element.style ? 327 328 // Element within the document 329 element.ownerDocument : 330 331 // Element is window or document 332 element.document || element ); 333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 334 } 335 336 this.options = $.widget.extend( {}, 337 this.options, 338 this._getCreateOptions(), 339 options ); 340 341 this._create(); 342 343 if ( this.options.disabled ) { 344 this._setOptionDisabled( this.options.disabled ); 345 } 346 347 this._trigger( "create", null, this._getCreateEventData() ); 348 this._init(); 349 }, 350 351 _getCreateOptions: function() { 352 return {}; 353 }, 354 355 _getCreateEventData: $.noop, 356 357 _create: $.noop, 358 359 _init: $.noop, 360 361 destroy: function() { 362 var that = this; 363 364 this._destroy(); 365 $.each( this.classesElementLookup, function( key, value ) { 366 that._removeClass( value, key ); 367 } ); 368 369 // We can probably remove the unbind calls in 2.0 370 // all event bindings should go through this._on() 371 this.element 372 .off( this.eventNamespace ) 373 .removeData( this.widgetFullName ); 374 this.widget() 375 .off( this.eventNamespace ) 376 .removeAttr( "aria-disabled" ); 377 378 // Clean up events and states 379 this.bindings.off( this.eventNamespace ); 380 }, 381 382 _destroy: $.noop, 383 384 widget: function() { 385 return this.element; 386 }, 387 388 option: function( key, value ) { 389 var options = key; 390 var parts; 391 var curOption; 392 var i; 393 394 if ( arguments.length === 0 ) { 395 396 // Don't return a reference to the internal hash 397 return $.widget.extend( {}, this.options ); 398 } 399 400 if ( typeof key === "string" ) { 401 402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 403 options = {}; 404 parts = key.split( "." ); 405 key = parts.shift(); 406 if ( parts.length ) { 407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 408 for ( i = 0; i < parts.length - 1; i++ ) { 409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 410 curOption = curOption[ parts[ i ] ]; 411 } 412 key = parts.pop(); 413 if ( arguments.length === 1 ) { 414 return curOption[ key ] === undefined ? null : curOption[ key ]; 415 } 416 curOption[ key ] = value; 417 } else { 418 if ( arguments.length === 1 ) { 419 return this.options[ key ] === undefined ? null : this.options[ key ]; 420 } 421 options[ key ] = value; 422 } 423 } 424 425 this._setOptions( options ); 426 427 return this; 428 }, 429 430 _setOptions: function( options ) { 431 var key; 432 433 for ( key in options ) { 434 this._setOption( key, options[ key ] ); 435 } 436 437 return this; 438 }, 439 440 _setOption: function( key, value ) { 441 if ( key === "classes" ) { 442 this._setOptionClasses( value ); 443 } 444 445 this.options[ key ] = value; 446 447 if ( key === "disabled" ) { 448 this._setOptionDisabled( value ); 449 } 450 451 return this; 452 }, 453 454 _setOptionClasses: function( value ) { 455 var classKey, elements, currentElements; 456 457 for ( classKey in value ) { 458 currentElements = this.classesElementLookup[ classKey ]; 459 if ( value[ classKey ] === this.options.classes[ classKey ] || 460 !currentElements || 461 !currentElements.length ) { 462 continue; 463 } 464 465 // We are doing this to create a new jQuery object because the _removeClass() call 466 // on the next line is going to destroy the reference to the current elements being 467 // tracked. We need to save a copy of this collection so that we can add the new classes 468 // below. 469 elements = $( currentElements.get() ); 470 this._removeClass( currentElements, classKey ); 471 472 // We don't use _addClass() here, because that uses this.options.classes 473 // for generating the string of classes. We want to use the value passed in from 474 // _setOption(), this is the new value of the classes option which was passed to 475 // _setOption(). We pass this value directly to _classes(). 476 elements.addClass( this._classes( { 477 element: elements, 478 keys: classKey, 479 classes: value, 480 add: true 481 } ) ); 482 } 483 }, 484 485 _setOptionDisabled: function( value ) { 486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 487 488 // If the widget is becoming disabled, then nothing is interactive 489 if ( value ) { 490 this._removeClass( this.hoverable, null, "ui-state-hover" ); 491 this._removeClass( this.focusable, null, "ui-state-focus" ); 492 } 493 }, 494 495 enable: function() { 496 return this._setOptions( { disabled: false } ); 497 }, 498 499 disable: function() { 500 return this._setOptions( { disabled: true } ); 501 }, 502 503 _classes: function( options ) { 504 var full = []; 505 var that = this; 506 507 options = $.extend( { 508 element: this.element, 509 classes: this.options.classes || {} 510 }, options ); 511 512 function processClassString( classes, checkOption ) { 513 var current, i; 514 for ( i = 0; i < classes.length; i++ ) { 515 current = that.classesElementLookup[ classes[ i ] ] || $(); 516 if ( options.add ) { 517 current = $( $.unique( current.get().concat( options.element.get() ) ) ); 518 } else { 519 current = $( current.not( options.element ).get() ); 520 } 521 that.classesElementLookup[ classes[ i ] ] = current; 522 full.push( classes[ i ] ); 523 if ( checkOption && options.classes[ classes[ i ] ] ) { 524 full.push( options.classes[ classes[ i ] ] ); 525 } 526 } 527 } 528 529 this._on( options.element, { 530 "remove": "_untrackClassesElement" 531 } ); 532 533 if ( options.keys ) { 534 processClassString( options.keys.match( /\S+/g ) || [], true ); 535 } 536 if ( options.extra ) { 537 processClassString( options.extra.match( /\S+/g ) || [] ); 538 } 539 540 return full.join( " " ); 541 }, 542 543 _untrackClassesElement: function( event ) { 544 var that = this; 545 $.each( that.classesElementLookup, function( key, value ) { 546 if ( $.inArray( event.target, value ) !== -1 ) { 547 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 548 } 549 } ); 550 }, 551 552 _removeClass: function( element, keys, extra ) { 553 return this._toggleClass( element, keys, extra, false ); 554 }, 555 556 _addClass: function( element, keys, extra ) { 557 return this._toggleClass( element, keys, extra, true ); 558 }, 559 560 _toggleClass: function( element, keys, extra, add ) { 561 add = ( typeof add === "boolean" ) ? add : extra; 562 var shift = ( typeof element === "string" || element === null ), 563 options = { 564 extra: shift ? keys : extra, 565 keys: shift ? element : keys, 566 element: shift ? this.element : element, 567 add: add 568 }; 569 options.element.toggleClass( this._classes( options ), add ); 570 return this; 571 }, 572 573 _on: function( suppressDisabledCheck, element, handlers ) { 574 var delegateElement; 575 var instance = this; 576 577 // No suppressDisabledCheck flag, shuffle arguments 578 if ( typeof suppressDisabledCheck !== "boolean" ) { 579 handlers = element; 580 element = suppressDisabledCheck; 581 suppressDisabledCheck = false; 582 } 583 584 // No element argument, shuffle and use this.element 585 if ( !handlers ) { 586 handlers = element; 587 element = this.element; 588 delegateElement = this.widget(); 589 } else { 590 element = delegateElement = $( element ); 591 this.bindings = this.bindings.add( element ); 592 } 593 594 $.each( handlers, function( event, handler ) { 595 function handlerProxy() { 596 597 // Allow widgets to customize the disabled handling 598 // - disabled as an array instead of boolean 599 // - disabled class as method for disabling individual parts 600 if ( !suppressDisabledCheck && 601 ( instance.options.disabled === true || 602 $( this ).hasClass( "ui-state-disabled" ) ) ) { 603 return; 604 } 605 return ( typeof handler === "string" ? instance[ handler ] : handler ) 606 .apply( instance, arguments ); 607 } 608 609 // Copy the guid so direct unbinding works 610 if ( typeof handler !== "string" ) { 611 handlerProxy.guid = handler.guid = 612 handler.guid || handlerProxy.guid || $.guid++; 613 } 614 615 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 616 var eventName = match[ 1 ] + instance.eventNamespace; 617 var selector = match[ 2 ]; 618 619 if ( selector ) { 620 delegateElement.on( eventName, selector, handlerProxy ); 621 } else { 622 element.on( eventName, handlerProxy ); 623 } 624 } ); 625 }, 626 627 _off: function( element, eventName ) { 628 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 629 this.eventNamespace; 630 element.off( eventName ).off( eventName ); 631 632 // Clear the stack to avoid memory leaks (#10056) 633 this.bindings = $( this.bindings.not( element ).get() ); 634 this.focusable = $( this.focusable.not( element ).get() ); 635 this.hoverable = $( this.hoverable.not( element ).get() ); 636 }, 637 638 _delay: function( handler, delay ) { 639 function handlerProxy() { 640 return ( typeof handler === "string" ? instance[ handler ] : handler ) 641 .apply( instance, arguments ); 642 } 643 var instance = this; 644 return setTimeout( handlerProxy, delay || 0 ); 645 }, 646 647 _hoverable: function( element ) { 648 this.hoverable = this.hoverable.add( element ); 649 this._on( element, { 650 mouseenter: function( event ) { 651 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 652 }, 653 mouseleave: function( event ) { 654 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 655 } 656 } ); 657 }, 658 659 _focusable: function( element ) { 660 this.focusable = this.focusable.add( element ); 661 this._on( element, { 662 focusin: function( event ) { 663 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 664 }, 665 focusout: function( event ) { 666 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 667 } 668 } ); 669 }, 670 671 _trigger: function( type, event, data ) { 672 var prop, orig; 673 var callback = this.options[ type ]; 674 675 data = data || {}; 676 event = $.Event( event ); 677 event.type = ( type === this.widgetEventPrefix ? 678 type : 679 this.widgetEventPrefix + type ).toLowerCase(); 680 681 // The original event may come from any element 682 // so we need to reset the target on the new event 683 event.target = this.element[ 0 ]; 684 685 // Copy original event properties over to the new event 686 orig = event.originalEvent; 687 if ( orig ) { 688 for ( prop in orig ) { 689 if ( !( prop in event ) ) { 690 event[ prop ] = orig[ prop ]; 691 } 692 } 693 } 694 695 this.element.trigger( event, data ); 696 return !( $.isFunction( callback ) && 697 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 698 event.isDefaultPrevented() ); 699 } 700}; 701 702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 703 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 704 if ( typeof options === "string" ) { 705 options = { effect: options }; 706 } 707 708 var hasOptions; 709 var effectName = !options ? 710 method : 711 options === true || typeof options === "number" ? 712 defaultEffect : 713 options.effect || defaultEffect; 714 715 options = options || {}; 716 if ( typeof options === "number" ) { 717 options = { duration: options }; 718 } 719 720 hasOptions = !$.isEmptyObject( options ); 721 options.complete = callback; 722 723 if ( options.delay ) { 724 element.delay( options.delay ); 725 } 726 727 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 728 element[ method ]( options ); 729 } else if ( effectName !== method && element[ effectName ] ) { 730 element[ effectName ]( options.duration, options.easing, callback ); 731 } else { 732 element.queue( function( next ) { 733 $( this )[ method ](); 734 if ( callback ) { 735 callback.call( element[ 0 ] ); 736 } 737 next(); 738 } ); 739 } 740 }; 741} ); 742 743var widget = $.widget; 744 745 746/*! 747 * jQuery UI Position 1.12.1 748 * http://jqueryui.com 749 * 750 * Copyright jQuery Foundation and other contributors 751 * Released under the MIT license. 752 * http://jquery.org/license 753 * 754 * http://api.jqueryui.com/position/ 755 */ 756 757//>>label: Position 758//>>group: Core 759//>>description: Positions elements relative to other elements. 760//>>docs: http://api.jqueryui.com/position/ 761//>>demos: http://jqueryui.com/position/ 762 763 764( function() { 765var cachedScrollbarWidth, 766 max = Math.max, 767 abs = Math.abs, 768 rhorizontal = /left|center|right/, 769 rvertical = /top|center|bottom/, 770 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 771 rposition = /^\w+/, 772 rpercent = /%$/, 773 _position = $.fn.position; 774 775function getOffsets( offsets, width, height ) { 776 return [ 777 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 778 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 779 ]; 780} 781 782function parseCss( element, property ) { 783 return parseInt( $.css( element, property ), 10 ) || 0; 784} 785 786function getDimensions( elem ) { 787 var raw = elem[ 0 ]; 788 if ( raw.nodeType === 9 ) { 789 return { 790 width: elem.width(), 791 height: elem.height(), 792 offset: { top: 0, left: 0 } 793 }; 794 } 795 if ( $.isWindow( raw ) ) { 796 return { 797 width: elem.width(), 798 height: elem.height(), 799 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 800 }; 801 } 802 if ( raw.preventDefault ) { 803 return { 804 width: 0, 805 height: 0, 806 offset: { top: raw.pageY, left: raw.pageX } 807 }; 808 } 809 return { 810 width: elem.outerWidth(), 811 height: elem.outerHeight(), 812 offset: elem.offset() 813 }; 814} 815 816$.position = { 817 scrollbarWidth: function() { 818 if ( cachedScrollbarWidth !== undefined ) { 819 return cachedScrollbarWidth; 820 } 821 var w1, w2, 822 div = $( "<div " + 823 "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + 824 "<div style='height:100px;width:auto;'></div></div>" ), 825 innerDiv = div.children()[ 0 ]; 826 827 $( "body" ).append( div ); 828 w1 = innerDiv.offsetWidth; 829 div.css( "overflow", "scroll" ); 830 831 w2 = innerDiv.offsetWidth; 832 833 if ( w1 === w2 ) { 834 w2 = div[ 0 ].clientWidth; 835 } 836 837 div.remove(); 838 839 return ( cachedScrollbarWidth = w1 - w2 ); 840 }, 841 getScrollInfo: function( within ) { 842 var overflowX = within.isWindow || within.isDocument ? "" : 843 within.element.css( "overflow-x" ), 844 overflowY = within.isWindow || within.isDocument ? "" : 845 within.element.css( "overflow-y" ), 846 hasOverflowX = overflowX === "scroll" || 847 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 848 hasOverflowY = overflowY === "scroll" || 849 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 850 return { 851 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 852 height: hasOverflowX ? $.position.scrollbarWidth() : 0 853 }; 854 }, 855 getWithinInfo: function( element ) { 856 var withinElement = $( element || window ), 857 isWindow = $.isWindow( withinElement[ 0 ] ), 858 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 859 hasOffset = !isWindow && !isDocument; 860 return { 861 element: withinElement, 862 isWindow: isWindow, 863 isDocument: isDocument, 864 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 865 scrollLeft: withinElement.scrollLeft(), 866 scrollTop: withinElement.scrollTop(), 867 width: withinElement.outerWidth(), 868 height: withinElement.outerHeight() 869 }; 870 } 871}; 872 873$.fn.position = function( options ) { 874 if ( !options || !options.of ) { 875 return _position.apply( this, arguments ); 876 } 877 878 // Make a copy, we don't want to modify arguments 879 options = $.extend( {}, options ); 880 881 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 882 target = $( options.of ), 883 within = $.position.getWithinInfo( options.within ), 884 scrollInfo = $.position.getScrollInfo( within ), 885 collision = ( options.collision || "flip" ).split( " " ), 886 offsets = {}; 887 888 dimensions = getDimensions( target ); 889 if ( target[ 0 ].preventDefault ) { 890 891 // Force left top to allow flipping 892 options.at = "left top"; 893 } 894 targetWidth = dimensions.width; 895 targetHeight = dimensions.height; 896 targetOffset = dimensions.offset; 897 898 // Clone to reuse original targetOffset later 899 basePosition = $.extend( {}, targetOffset ); 900 901 // Force my and at to have valid horizontal and vertical positions 902 // if a value is missing or invalid, it will be converted to center 903 $.each( [ "my", "at" ], function() { 904 var pos = ( options[ this ] || "" ).split( " " ), 905 horizontalOffset, 906 verticalOffset; 907 908 if ( pos.length === 1 ) { 909 pos = rhorizontal.test( pos[ 0 ] ) ? 910 pos.concat( [ "center" ] ) : 911 rvertical.test( pos[ 0 ] ) ? 912 [ "center" ].concat( pos ) : 913 [ "center", "center" ]; 914 } 915 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 916 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 917 918 // Calculate offsets 919 horizontalOffset = roffset.exec( pos[ 0 ] ); 920 verticalOffset = roffset.exec( pos[ 1 ] ); 921 offsets[ this ] = [ 922 horizontalOffset ? horizontalOffset[ 0 ] : 0, 923 verticalOffset ? verticalOffset[ 0 ] : 0 924 ]; 925 926 // Reduce to just the positions without the offsets 927 options[ this ] = [ 928 rposition.exec( pos[ 0 ] )[ 0 ], 929 rposition.exec( pos[ 1 ] )[ 0 ] 930 ]; 931 } ); 932 933 // Normalize collision option 934 if ( collision.length === 1 ) { 935 collision[ 1 ] = collision[ 0 ]; 936 } 937 938 if ( options.at[ 0 ] === "right" ) { 939 basePosition.left += targetWidth; 940 } else if ( options.at[ 0 ] === "center" ) { 941 basePosition.left += targetWidth / 2; 942 } 943 944 if ( options.at[ 1 ] === "bottom" ) { 945 basePosition.top += targetHeight; 946 } else if ( options.at[ 1 ] === "center" ) { 947 basePosition.top += targetHeight / 2; 948 } 949 950 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 951 basePosition.left += atOffset[ 0 ]; 952 basePosition.top += atOffset[ 1 ]; 953 954 return this.each( function() { 955 var collisionPosition, using, 956 elem = $( this ), 957 elemWidth = elem.outerWidth(), 958 elemHeight = elem.outerHeight(), 959 marginLeft = parseCss( this, "marginLeft" ), 960 marginTop = parseCss( this, "marginTop" ), 961 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 962 scrollInfo.width, 963 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 964 scrollInfo.height, 965 position = $.extend( {}, basePosition ), 966 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 967 968 if ( options.my[ 0 ] === "right" ) { 969 position.left -= elemWidth; 970 } else if ( options.my[ 0 ] === "center" ) { 971 position.left -= elemWidth / 2; 972 } 973 974 if ( options.my[ 1 ] === "bottom" ) { 975 position.top -= elemHeight; 976 } else if ( options.my[ 1 ] === "center" ) { 977 position.top -= elemHeight / 2; 978 } 979 980 position.left += myOffset[ 0 ]; 981 position.top += myOffset[ 1 ]; 982 983 collisionPosition = { 984 marginLeft: marginLeft, 985 marginTop: marginTop 986 }; 987 988 $.each( [ "left", "top" ], function( i, dir ) { 989 if ( $.ui.position[ collision[ i ] ] ) { 990 $.ui.position[ collision[ i ] ][ dir ]( position, { 991 targetWidth: targetWidth, 992 targetHeight: targetHeight, 993 elemWidth: elemWidth, 994 elemHeight: elemHeight, 995 collisionPosition: collisionPosition, 996 collisionWidth: collisionWidth, 997 collisionHeight: collisionHeight, 998 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 999 my: options.my, 1000 at: options.at, 1001 within: within, 1002 elem: elem 1003 } ); 1004 } 1005 } ); 1006 1007 if ( options.using ) { 1008 1009 // Adds feedback as second argument to using callback, if present 1010 using = function( props ) { 1011 var left = targetOffset.left - position.left, 1012 right = left + targetWidth - elemWidth, 1013 top = targetOffset.top - position.top, 1014 bottom = top + targetHeight - elemHeight, 1015 feedback = { 1016 target: { 1017 element: target, 1018 left: targetOffset.left, 1019 top: targetOffset.top, 1020 width: targetWidth, 1021 height: targetHeight 1022 }, 1023 element: { 1024 element: elem, 1025 left: position.left, 1026 top: position.top, 1027 width: elemWidth, 1028 height: elemHeight 1029 }, 1030 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1031 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1032 }; 1033 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1034 feedback.horizontal = "center"; 1035 } 1036 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1037 feedback.vertical = "middle"; 1038 } 1039 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1040 feedback.important = "horizontal"; 1041 } else { 1042 feedback.important = "vertical"; 1043 } 1044 options.using.call( this, props, feedback ); 1045 }; 1046 } 1047 1048 elem.offset( $.extend( position, { using: using } ) ); 1049 } ); 1050}; 1051 1052$.ui.position = { 1053 fit: { 1054 left: function( position, data ) { 1055 var within = data.within, 1056 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1057 outerWidth = within.width, 1058 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1059 overLeft = withinOffset - collisionPosLeft, 1060 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1061 newOverRight; 1062 1063 // Element is wider than within 1064 if ( data.collisionWidth > outerWidth ) { 1065 1066 // Element is initially over the left side of within 1067 if ( overLeft > 0 && overRight <= 0 ) { 1068 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1069 withinOffset; 1070 position.left += overLeft - newOverRight; 1071 1072 // Element is initially over right side of within 1073 } else if ( overRight > 0 && overLeft <= 0 ) { 1074 position.left = withinOffset; 1075 1076 // Element is initially over both left and right sides of within 1077 } else { 1078 if ( overLeft > overRight ) { 1079 position.left = withinOffset + outerWidth - data.collisionWidth; 1080 } else { 1081 position.left = withinOffset; 1082 } 1083 } 1084 1085 // Too far left -> align with left edge 1086 } else if ( overLeft > 0 ) { 1087 position.left += overLeft; 1088 1089 // Too far right -> align with right edge 1090 } else if ( overRight > 0 ) { 1091 position.left -= overRight; 1092 1093 // Adjust based on position and margin 1094 } else { 1095 position.left = max( position.left - collisionPosLeft, position.left ); 1096 } 1097 }, 1098 top: function( position, data ) { 1099 var within = data.within, 1100 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1101 outerHeight = data.within.height, 1102 collisionPosTop = position.top - data.collisionPosition.marginTop, 1103 overTop = withinOffset - collisionPosTop, 1104 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1105 newOverBottom; 1106 1107 // Element is taller than within 1108 if ( data.collisionHeight > outerHeight ) { 1109 1110 // Element is initially over the top of within 1111 if ( overTop > 0 && overBottom <= 0 ) { 1112 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1113 withinOffset; 1114 position.top += overTop - newOverBottom; 1115 1116 // Element is initially over bottom of within 1117 } else if ( overBottom > 0 && overTop <= 0 ) { 1118 position.top = withinOffset; 1119 1120 // Element is initially over both top and bottom of within 1121 } else { 1122 if ( overTop > overBottom ) { 1123 position.top = withinOffset + outerHeight - data.collisionHeight; 1124 } else { 1125 position.top = withinOffset; 1126 } 1127 } 1128 1129 // Too far up -> align with top 1130 } else if ( overTop > 0 ) { 1131 position.top += overTop; 1132 1133 // Too far down -> align with bottom edge 1134 } else if ( overBottom > 0 ) { 1135 position.top -= overBottom; 1136 1137 // Adjust based on position and margin 1138 } else { 1139 position.top = max( position.top - collisionPosTop, position.top ); 1140 } 1141 } 1142 }, 1143 flip: { 1144 left: function( position, data ) { 1145 var within = data.within, 1146 withinOffset = within.offset.left + within.scrollLeft, 1147 outerWidth = within.width, 1148 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1149 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1150 overLeft = collisionPosLeft - offsetLeft, 1151 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1152 myOffset = data.my[ 0 ] === "left" ? 1153 -data.elemWidth : 1154 data.my[ 0 ] === "right" ? 1155 data.elemWidth : 1156 0, 1157 atOffset = data.at[ 0 ] === "left" ? 1158 data.targetWidth : 1159 data.at[ 0 ] === "right" ? 1160 -data.targetWidth : 1161 0, 1162 offset = -2 * data.offset[ 0 ], 1163 newOverRight, 1164 newOverLeft; 1165 1166 if ( overLeft < 0 ) { 1167 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1168 outerWidth - withinOffset; 1169 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1170 position.left += myOffset + atOffset + offset; 1171 } 1172 } else if ( overRight > 0 ) { 1173 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1174 atOffset + offset - offsetLeft; 1175 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1176 position.left += myOffset + atOffset + offset; 1177 } 1178 } 1179 }, 1180 top: function( position, data ) { 1181 var within = data.within, 1182 withinOffset = within.offset.top + within.scrollTop, 1183 outerHeight = within.height, 1184 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1185 collisionPosTop = position.top - data.collisionPosition.marginTop, 1186 overTop = collisionPosTop - offsetTop, 1187 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1188 top = data.my[ 1 ] === "top", 1189 myOffset = top ? 1190 -data.elemHeight : 1191 data.my[ 1 ] === "bottom" ? 1192 data.elemHeight : 1193 0, 1194 atOffset = data.at[ 1 ] === "top" ? 1195 data.targetHeight : 1196 data.at[ 1 ] === "bottom" ? 1197 -data.targetHeight : 1198 0, 1199 offset = -2 * data.offset[ 1 ], 1200 newOverTop, 1201 newOverBottom; 1202 if ( overTop < 0 ) { 1203 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1204 outerHeight - withinOffset; 1205 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1206 position.top += myOffset + atOffset + offset; 1207 } 1208 } else if ( overBottom > 0 ) { 1209 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1210 offset - offsetTop; 1211 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1212 position.top += myOffset + atOffset + offset; 1213 } 1214 } 1215 } 1216 }, 1217 flipfit: { 1218 left: function() { 1219 $.ui.position.flip.left.apply( this, arguments ); 1220 $.ui.position.fit.left.apply( this, arguments ); 1221 }, 1222 top: function() { 1223 $.ui.position.flip.top.apply( this, arguments ); 1224 $.ui.position.fit.top.apply( this, arguments ); 1225 } 1226 } 1227}; 1228 1229} )(); 1230 1231var position = $.ui.position; 1232 1233 1234/*! 1235 * jQuery UI :data 1.12.1 1236 * http://jqueryui.com 1237 * 1238 * Copyright jQuery Foundation and other contributors 1239 * Released under the MIT license. 1240 * http://jquery.org/license 1241 */ 1242 1243//>>label: :data Selector 1244//>>group: Core 1245//>>description: Selects elements which have data stored under the specified key. 1246//>>docs: http://api.jqueryui.com/data-selector/ 1247 1248 1249var data = $.extend( $.expr[ ":" ], { 1250 data: $.expr.createPseudo ? 1251 $.expr.createPseudo( function( dataName ) { 1252 return function( elem ) { 1253 return !!$.data( elem, dataName ); 1254 }; 1255 } ) : 1256 1257 // Support: jQuery <1.8 1258 function( elem, i, match ) { 1259 return !!$.data( elem, match[ 3 ] ); 1260 } 1261} ); 1262 1263/*! 1264 * jQuery UI Disable Selection 1.12.1 1265 * http://jqueryui.com 1266 * 1267 * Copyright jQuery Foundation and other contributors 1268 * Released under the MIT license. 1269 * http://jquery.org/license 1270 */ 1271 1272//>>label: disableSelection 1273//>>group: Core 1274//>>description: Disable selection of text content within the set of matched elements. 1275//>>docs: http://api.jqueryui.com/disableSelection/ 1276 1277// This file is deprecated 1278 1279 1280var disableSelection = $.fn.extend( { 1281 disableSelection: ( function() { 1282 var eventType = "onselectstart" in document.createElement( "div" ) ? 1283 "selectstart" : 1284 "mousedown"; 1285 1286 return function() { 1287 return this.on( eventType + ".ui-disableSelection", function( event ) { 1288 event.preventDefault(); 1289 } ); 1290 }; 1291 } )(), 1292 1293 enableSelection: function() { 1294 return this.off( ".ui-disableSelection" ); 1295 } 1296} ); 1297 1298 1299/*! 1300 * jQuery UI Focusable 1.12.1 1301 * http://jqueryui.com 1302 * 1303 * Copyright jQuery Foundation and other contributors 1304 * Released under the MIT license. 1305 * http://jquery.org/license 1306 */ 1307 1308//>>label: :focusable Selector 1309//>>group: Core 1310//>>description: Selects elements which can be focused. 1311//>>docs: http://api.jqueryui.com/focusable-selector/ 1312 1313 1314 1315// Selectors 1316$.ui.focusable = function( element, hasTabindex ) { 1317 var map, mapName, img, focusableIfVisible, fieldset, 1318 nodeName = element.nodeName.toLowerCase(); 1319 1320 if ( "area" === nodeName ) { 1321 map = element.parentNode; 1322 mapName = map.name; 1323 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 1324 return false; 1325 } 1326 img = $( "img[usemap='#" + mapName + "']" ); 1327 return img.length > 0 && img.is( ":visible" ); 1328 } 1329 1330 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 1331 focusableIfVisible = !element.disabled; 1332 1333 if ( focusableIfVisible ) { 1334 1335 // Form controls within a disabled fieldset are disabled. 1336 // However, controls within the fieldset's legend do not get disabled. 1337 // Since controls generally aren't placed inside legends, we skip 1338 // this portion of the check. 1339 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 1340 if ( fieldset ) { 1341 focusableIfVisible = !fieldset.disabled; 1342 } 1343 } 1344 } else if ( "a" === nodeName ) { 1345 focusableIfVisible = element.href || hasTabindex; 1346 } else { 1347 focusableIfVisible = hasTabindex; 1348 } 1349 1350 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 1351}; 1352 1353// Support: IE 8 only 1354// IE 8 doesn't resolve inherit to visible/hidden for computed values 1355function visible( element ) { 1356 var visibility = element.css( "visibility" ); 1357 while ( visibility === "inherit" ) { 1358 element = element.parent(); 1359 visibility = element.css( "visibility" ); 1360 } 1361 return visibility !== "hidden"; 1362} 1363 1364$.extend( $.expr[ ":" ], { 1365 focusable: function( element ) { 1366 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 1367 } 1368} ); 1369 1370var focusable = $.ui.focusable; 1371 1372 1373 1374 1375// Support: IE8 Only 1376// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 1377// with a string, so we need to find the proper form. 1378var form = $.fn.form = function() { 1379 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 1380}; 1381 1382 1383/*! 1384 * jQuery UI Form Reset Mixin 1.12.1 1385 * http://jqueryui.com 1386 * 1387 * Copyright jQuery Foundation and other contributors 1388 * Released under the MIT license. 1389 * http://jquery.org/license 1390 */ 1391 1392//>>label: Form Reset Mixin 1393//>>group: Core 1394//>>description: Refresh input widgets when their form is reset 1395//>>docs: http://api.jqueryui.com/form-reset-mixin/ 1396 1397 1398 1399var formResetMixin = $.ui.formResetMixin = { 1400 _formResetHandler: function() { 1401 var form = $( this ); 1402 1403 // Wait for the form reset to actually happen before refreshing 1404 setTimeout( function() { 1405 var instances = form.data( "ui-form-reset-instances" ); 1406 $.each( instances, function() { 1407 this.refresh(); 1408 } ); 1409 } ); 1410 }, 1411 1412 _bindFormResetHandler: function() { 1413 this.form = this.element.form(); 1414 if ( !this.form.length ) { 1415 return; 1416 } 1417 1418 var instances = this.form.data( "ui-form-reset-instances" ) || []; 1419 if ( !instances.length ) { 1420 1421 // We don't use _on() here because we use a single event handler per form 1422 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 1423 } 1424 instances.push( this ); 1425 this.form.data( "ui-form-reset-instances", instances ); 1426 }, 1427 1428 _unbindFormResetHandler: function() { 1429 if ( !this.form.length ) { 1430 return; 1431 } 1432 1433 var instances = this.form.data( "ui-form-reset-instances" ); 1434 instances.splice( $.inArray( this, instances ), 1 ); 1435 if ( instances.length ) { 1436 this.form.data( "ui-form-reset-instances", instances ); 1437 } else { 1438 this.form 1439 .removeData( "ui-form-reset-instances" ) 1440 .off( "reset.ui-form-reset" ); 1441 } 1442 } 1443}; 1444 1445 1446/*! 1447 * jQuery UI Support for jQuery core 1.7.x 1.12.1 1448 * http://jqueryui.com 1449 * 1450 * Copyright jQuery Foundation and other contributors 1451 * Released under the MIT license. 1452 * http://jquery.org/license 1453 * 1454 */ 1455 1456//>>label: jQuery 1.7 Support 1457//>>group: Core 1458//>>description: Support version 1.7.x of jQuery core 1459 1460 1461 1462// Support: jQuery 1.7 only 1463// Not a great way to check versions, but since we only support 1.7+ and only 1464// need to detect <1.8, this is a simple check that should suffice. Checking 1465// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0 1466// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting 1467// 1.7 anymore). See #11197 for why we're not using feature detection. 1468if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) { 1469 1470 // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight() 1471 // Unlike jQuery Core 1.8+, these only support numeric values to set the 1472 // dimensions in pixels 1473 $.each( [ "Width", "Height" ], function( i, name ) { 1474 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 1475 type = name.toLowerCase(), 1476 orig = { 1477 innerWidth: $.fn.innerWidth, 1478 innerHeight: $.fn.innerHeight, 1479 outerWidth: $.fn.outerWidth, 1480 outerHeight: $.fn.outerHeight 1481 }; 1482 1483 function reduce( elem, size, border, margin ) { 1484 $.each( side, function() { 1485 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 1486 if ( border ) { 1487 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 1488 } 1489 if ( margin ) { 1490 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 1491 } 1492 } ); 1493 return size; 1494 } 1495 1496 $.fn[ "inner" + name ] = function( size ) { 1497 if ( size === undefined ) { 1498 return orig[ "inner" + name ].call( this ); 1499 } 1500 1501 return this.each( function() { 1502 $( this ).css( type, reduce( this, size ) + "px" ); 1503 } ); 1504 }; 1505 1506 $.fn[ "outer" + name ] = function( size, margin ) { 1507 if ( typeof size !== "number" ) { 1508 return orig[ "outer" + name ].call( this, size ); 1509 } 1510 1511 return this.each( function() { 1512 $( this ).css( type, reduce( this, size, true, margin ) + "px" ); 1513 } ); 1514 }; 1515 } ); 1516 1517 $.fn.addBack = function( selector ) { 1518 return this.add( selector == null ? 1519 this.prevObject : this.prevObject.filter( selector ) 1520 ); 1521 }; 1522} 1523 1524; 1525/*! 1526 * jQuery UI Keycode 1.12.1 1527 * http://jqueryui.com 1528 * 1529 * Copyright jQuery Foundation and other contributors 1530 * Released under the MIT license. 1531 * http://jquery.org/license 1532 */ 1533 1534//>>label: Keycode 1535//>>group: Core 1536//>>description: Provide keycodes as keynames 1537//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 1538 1539 1540var keycode = $.ui.keyCode = { 1541 BACKSPACE: 8, 1542 COMMA: 188, 1543 DELETE: 46, 1544 DOWN: 40, 1545 END: 35, 1546 ENTER: 13, 1547 ESCAPE: 27, 1548 HOME: 36, 1549 LEFT: 37, 1550 PAGE_DOWN: 34, 1551 PAGE_UP: 33, 1552 PERIOD: 190, 1553 RIGHT: 39, 1554 SPACE: 32, 1555 TAB: 9, 1556 UP: 38 1557}; 1558 1559 1560 1561 1562// Internal use only 1563var escapeSelector = $.ui.escapeSelector = ( function() { 1564 var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; 1565 return function( selector ) { 1566 return selector.replace( selectorEscape, "\\$1" ); 1567 }; 1568} )(); 1569 1570 1571/*! 1572 * jQuery UI Labels 1.12.1 1573 * http://jqueryui.com 1574 * 1575 * Copyright jQuery Foundation and other contributors 1576 * Released under the MIT license. 1577 * http://jquery.org/license 1578 */ 1579 1580//>>label: labels 1581//>>group: Core 1582//>>description: Find all the labels associated with a given input 1583//>>docs: http://api.jqueryui.com/labels/ 1584 1585 1586 1587var labels = $.fn.labels = function() { 1588 var ancestor, selector, id, labels, ancestors; 1589 1590 // Check control.labels first 1591 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 1592 return this.pushStack( this[ 0 ].labels ); 1593 } 1594 1595 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 1596 // Above browsers do not support control.labels. Everything below is to support them 1597 // as well as document fragments. control.labels does not work on document fragments 1598 labels = this.eq( 0 ).parents( "label" ); 1599 1600 // Look for the label based on the id 1601 id = this.attr( "id" ); 1602 if ( id ) { 1603 1604 // We don't search against the document in case the element 1605 // is disconnected from the DOM 1606 ancestor = this.eq( 0 ).parents().last(); 1607 1608 // Get a full set of top level ancestors 1609 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 1610 1611 // Create a selector for the label based on the id 1612 selector = "label[for='" + $.ui.escapeSelector( id ) + "']"; 1613 1614 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 1615 1616 } 1617 1618 // Return whatever we have found for labels 1619 return this.pushStack( labels ); 1620}; 1621 1622 1623/*! 1624 * jQuery UI Scroll Parent 1.12.1 1625 * http://jqueryui.com 1626 * 1627 * Copyright jQuery Foundation and other contributors 1628 * Released under the MIT license. 1629 * http://jquery.org/license 1630 */ 1631 1632//>>label: scrollParent 1633//>>group: Core 1634//>>description: Get the closest ancestor element that is scrollable. 1635//>>docs: http://api.jqueryui.com/scrollParent/ 1636 1637 1638 1639var scrollParent = $.fn.scrollParent = function( includeHidden ) { 1640 var position = this.css( "position" ), 1641 excludeStaticParent = position === "absolute", 1642 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 1643 scrollParent = this.parents().filter( function() { 1644 var parent = $( this ); 1645 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 1646 return false; 1647 } 1648 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 1649 parent.css( "overflow-x" ) ); 1650 } ).eq( 0 ); 1651 1652 return position === "fixed" || !scrollParent.length ? 1653 $( this[ 0 ].ownerDocument || document ) : 1654 scrollParent; 1655}; 1656 1657 1658/*! 1659 * jQuery UI Tabbable 1.12.1 1660 * http://jqueryui.com 1661 * 1662 * Copyright jQuery Foundation and other contributors 1663 * Released under the MIT license. 1664 * http://jquery.org/license 1665 */ 1666 1667//>>label: :tabbable Selector 1668//>>group: Core 1669//>>description: Selects elements which can be tabbed to. 1670//>>docs: http://api.jqueryui.com/tabbable-selector/ 1671 1672 1673 1674var tabbable = $.extend( $.expr[ ":" ], { 1675 tabbable: function( element ) { 1676 var tabIndex = $.attr( element, "tabindex" ), 1677 hasTabindex = tabIndex != null; 1678 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 1679 } 1680} ); 1681 1682 1683/*! 1684 * jQuery UI Unique ID 1.12.1 1685 * http://jqueryui.com 1686 * 1687 * Copyright jQuery Foundation and other contributors 1688 * Released under the MIT license. 1689 * http://jquery.org/license 1690 */ 1691 1692//>>label: uniqueId 1693//>>group: Core 1694//>>description: Functions to generate and remove uniqueId's 1695//>>docs: http://api.jqueryui.com/uniqueId/ 1696 1697 1698 1699var uniqueId = $.fn.extend( { 1700 uniqueId: ( function() { 1701 var uuid = 0; 1702 1703 return function() { 1704 return this.each( function() { 1705 if ( !this.id ) { 1706 this.id = "ui-id-" + ( ++uuid ); 1707 } 1708 } ); 1709 }; 1710 } )(), 1711 1712 removeUniqueId: function() { 1713 return this.each( function() { 1714 if ( /^ui-id-\d+$/.test( this.id ) ) { 1715 $( this ).removeAttr( "id" ); 1716 } 1717 } ); 1718 } 1719} ); 1720 1721
vendor: 46,453 bytes, lines 1722-3408
1722 1723 1724// This file is deprecated 1725var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 1726 1727/*! 1728 * jQuery UI Mouse 1.12.1 1729 * http://jqueryui.com 1730 * 1731 * Copyright jQuery Foundation and other contributors 1732 * Released under the MIT license. 1733 * http://jquery.org/license 1734 */ 1735 1736//>>label: Mouse 1737//>>group: Widgets 1738//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 1739//>>docs: http://api.jqueryui.com/mouse/ 1740 1741 1742 1743var mouseHandled = false; 1744$( document ).on( "mouseup", function() { 1745 mouseHandled = false; 1746} ); 1747 1748var widgetsMouse = $.widget( "ui.mouse", { 1749 version: "1.12.1", 1750 options: { 1751 cancel: "input, textarea, button, select, option", 1752 distance: 1, 1753 delay: 0 1754 }, 1755 _mouseInit: function() { 1756 var that = this; 1757 1758 this.element 1759 .on( "mousedown." + this.widgetName, function( event ) { 1760 return that._mouseDown( event ); 1761 } ) 1762 .on( "click." + this.widgetName, function( event ) { 1763 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 1764 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 1765 event.stopImmediatePropagation(); 1766 return false; 1767 } 1768 } ); 1769 1770 this.started = false; 1771 }, 1772 1773 // TODO: make sure destroying one instance of mouse doesn't mess with 1774 // other instances of mouse 1775 _mouseDestroy: function() { 1776 this.element.off( "." + this.widgetName ); 1777 if ( this._mouseMoveDelegate ) { 1778 this.document 1779 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1780 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1781 } 1782 }, 1783 1784 _mouseDown: function( event ) { 1785 1786 // don't let more than one widget handle mouseStart 1787 if ( mouseHandled ) { 1788 return; 1789 } 1790 1791 this._mouseMoved = false; 1792 1793 // We may have missed mouseup (out of window) 1794 ( this._mouseStarted && this._mouseUp( event ) ); 1795 1796 this._mouseDownEvent = event; 1797 1798 var that = this, 1799 btnIsLeft = ( event.which === 1 ), 1800 1801 // event.target.nodeName works around a bug in IE 8 with 1802 // disabled inputs (#7620) 1803 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 1804 $( event.target ).closest( this.options.cancel ).length : false ); 1805 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 1806 return true; 1807 } 1808 1809 this.mouseDelayMet = !this.options.delay; 1810 if ( !this.mouseDelayMet ) { 1811 this._mouseDelayTimer = setTimeout( function() { 1812 that.mouseDelayMet = true; 1813 }, this.options.delay ); 1814 } 1815 1816 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1817 this._mouseStarted = ( this._mouseStart( event ) !== false ); 1818 if ( !this._mouseStarted ) { 1819 event.preventDefault(); 1820 return true; 1821 } 1822 } 1823 1824 // Click event may never have fired (Gecko & Opera) 1825 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 1826 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 1827 } 1828 1829 // These delegates are required to keep context 1830 this._mouseMoveDelegate = function( event ) { 1831 return that._mouseMove( event ); 1832 }; 1833 this._mouseUpDelegate = function( event ) { 1834 return that._mouseUp( event ); 1835 }; 1836 1837 this.document 1838 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1839 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1840 1841 event.preventDefault(); 1842 1843 mouseHandled = true; 1844 return true; 1845 }, 1846 1847 _mouseMove: function( event ) { 1848 1849 // Only check for mouseups outside the document if you've moved inside the document 1850 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 1851 // fire a mousemove event if content is placed under the cursor. See #7778 1852 // Support: IE <9 1853 if ( this._mouseMoved ) { 1854 1855 // IE mouseup check - mouseup happened when mouse was out of window 1856 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 1857 !event.button ) { 1858 return this._mouseUp( event ); 1859 1860 // Iframe mouseup check - mouseup occurred in another document 1861 } else if ( !event.which ) { 1862 1863 // Support: Safari <=8 - 9 1864 // Safari sets which to 0 if you press any of the following keys 1865 // during a drag (#14461) 1866 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 1867 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 1868 this.ignoreMissingWhich = true; 1869 } else if ( !this.ignoreMissingWhich ) { 1870 return this._mouseUp( event ); 1871 } 1872 } 1873 } 1874 1875 if ( event.which || event.button ) { 1876 this._mouseMoved = true; 1877 } 1878 1879 if ( this._mouseStarted ) { 1880 this._mouseDrag( event ); 1881 return event.preventDefault(); 1882 } 1883 1884 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 1885 this._mouseStarted = 1886 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 1887 ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); 1888 } 1889 1890 return !this._mouseStarted; 1891 }, 1892 1893 _mouseUp: function( event ) { 1894 this.document 1895 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1896 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1897 1898 if ( this._mouseStarted ) { 1899 this._mouseStarted = false; 1900 1901 if ( event.target === this._mouseDownEvent.target ) { 1902 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 1903 } 1904 1905 this._mouseStop( event ); 1906 } 1907 1908 if ( this._mouseDelayTimer ) { 1909 clearTimeout( this._mouseDelayTimer ); 1910 delete this._mouseDelayTimer; 1911 } 1912 1913 this.ignoreMissingWhich = false; 1914 mouseHandled = false; 1915 event.preventDefault(); 1916 }, 1917 1918 _mouseDistanceMet: function( event ) { 1919 return ( Math.max( 1920 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 1921 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 1922 ) >= this.options.distance 1923 ); 1924 }, 1925 1926 _mouseDelayMet: function( /* event */ ) { 1927 return this.mouseDelayMet; 1928 }, 1929 1930 // These are placeholder methods, to be overriden by extending plugin 1931 _mouseStart: function( /* event */ ) {}, 1932 _mouseDrag: function( /* event */ ) {}, 1933 _mouseStop: function( /* event */ ) {}, 1934 _mouseCapture: function( /* event */ ) { return true; } 1935} ); 1936 1937 1938 1939 1940// $.ui.plugin is deprecated. Use $.widget() extensions instead. 1941var plugin = $.ui.plugin = { 1942 add: function( module, option, set ) { 1943 var i, 1944 proto = $.ui[ module ].prototype; 1945 for ( i in set ) { 1946 proto.plugins[ i ] = proto.plugins[ i ] || []; 1947 proto.plugins[ i ].push( [ option, set[ i ] ] ); 1948 } 1949 }, 1950 call: function( instance, name, args, allowDisconnected ) { 1951 var i, 1952 set = instance.plugins[ name ]; 1953 1954 if ( !set ) { 1955 return; 1956 } 1957 1958 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 1959 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 1960 return; 1961 } 1962 1963 for ( i = 0; i < set.length; i++ ) { 1964 if ( instance.options[ set[ i ][ 0 ] ] ) { 1965 set[ i ][ 1 ].apply( instance.element, args ); 1966 } 1967 } 1968 } 1969}; 1970 1971 1972 1973var safeActiveElement = $.ui.safeActiveElement = function( document ) { 1974 var activeElement; 1975 1976 // Support: IE 9 only 1977 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1978 try { 1979 activeElement = document.activeElement; 1980 } catch ( error ) { 1981 activeElement = document.body; 1982 } 1983 1984 // Support: IE 9 - 11 only 1985 // IE may return null instead of an element 1986 // Interestingly, this only seems to occur when NOT in an iframe 1987 if ( !activeElement ) { 1988 activeElement = document.body; 1989 } 1990 1991 // Support: IE 11 only 1992 // IE11 returns a seemingly empty object in some cases when accessing 1993 // document.activeElement from an <iframe> 1994 if ( !activeElement.nodeName ) { 1995 activeElement = document.body; 1996 } 1997 1998 return activeElement; 1999}; 2000 2001 2002 2003var safeBlur = $.ui.safeBlur = function( element ) { 2004 2005 // Support: IE9 - 10 only 2006 // If the <body> is blurred, IE will switch windows, see #9420 2007 if ( element && element.nodeName.toLowerCase() !== "body" ) { 2008 $( element ).trigger( "blur" ); 2009 } 2010}; 2011 2012 2013/*! 2014 * jQuery UI Draggable 1.12.1 2015 * http://jqueryui.com 2016 * 2017 * Copyright jQuery Foundation and other contributors 2018 * Released under the MIT license. 2019 * http://jquery.org/license 2020 */ 2021 2022//>>label: Draggable 2023//>>group: Interactions 2024//>>description: Enables dragging functionality for any element. 2025//>>docs: http://api.jqueryui.com/draggable/ 2026//>>demos: http://jqueryui.com/draggable/ 2027//>>css.structure: ../../themes/base/draggable.css 2028 2029 2030 2031$.widget( "ui.draggable", $.ui.mouse, { 2032 version: "1.12.1", 2033 widgetEventPrefix: "drag", 2034 options: { 2035 addClasses: true, 2036 appendTo: "parent", 2037 axis: false, 2038 connectToSortable: false, 2039 containment: false, 2040 cursor: "auto", 2041 cursorAt: false, 2042 grid: false, 2043 handle: false, 2044 helper: "original", 2045 iframeFix: false, 2046 opacity: false, 2047 refreshPositions: false, 2048 revert: false, 2049 revertDuration: 500, 2050 scope: "default", 2051 scroll: true, 2052 scrollSensitivity: 20, 2053 scrollSpeed: 20, 2054 snap: false, 2055 snapMode: "both", 2056 snapTolerance: 20, 2057 stack: false, 2058 zIndex: false, 2059 2060 // Callbacks 2061 drag: null, 2062 start: null, 2063 stop: null 2064 }, 2065 _create: function() { 2066 2067 if ( this.options.helper === "original" ) { 2068 this._setPositionRelative(); 2069 } 2070 if ( this.options.addClasses ) { 2071 this._addClass( "ui-draggable" ); 2072 } 2073 this._setHandleClassName(); 2074 2075 this._mouseInit(); 2076 }, 2077 2078 _setOption: function( key, value ) { 2079 this._super( key, value ); 2080 if ( key === "handle" ) { 2081 this._removeHandleClassName(); 2082 this._setHandleClassName(); 2083 } 2084 }, 2085 2086 _destroy: function() { 2087 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 2088 this.destroyOnClear = true; 2089 return; 2090 } 2091 this._removeHandleClassName(); 2092 this._mouseDestroy(); 2093 }, 2094 2095 _mouseCapture: function( event ) { 2096 var o = this.options; 2097 2098 // Among others, prevent a drag on a resizable-handle 2099 if ( this.helper || o.disabled || 2100 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 2101 return false; 2102 } 2103 2104 //Quit if we're not on a valid handle 2105 this.handle = this._getHandle( event ); 2106 if ( !this.handle ) { 2107 return false; 2108 } 2109 2110 this._blurActiveElement( event ); 2111 2112 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 2113 2114 return true; 2115 2116 }, 2117 2118 _blockFrames: function( selector ) { 2119 this.iframeBlocks = this.document.find( selector ).map( function() { 2120 var iframe = $( this ); 2121 2122 return $( "<div>" ) 2123 .css( "position", "absolute" ) 2124 .appendTo( iframe.parent() ) 2125 .outerWidth( iframe.outerWidth() ) 2126 .outerHeight( iframe.outerHeight() ) 2127 .offset( iframe.offset() )[ 0 ]; 2128 } ); 2129 }, 2130 2131 _unblockFrames: function() { 2132 if ( this.iframeBlocks ) { 2133 this.iframeBlocks.remove(); 2134 delete this.iframeBlocks; 2135 } 2136 }, 2137 2138 _blurActiveElement: function( event ) { 2139 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 2140 target = $( event.target ); 2141 2142 // Don't blur if the event occurred on an element that is within 2143 // the currently focused element 2144 // See #10527, #12472 2145 if ( target.closest( activeElement ).length ) { 2146 return; 2147 } 2148 2149 // Blur any element that currently has focus, see #4261 2150 $.ui.safeBlur( activeElement ); 2151 }, 2152 2153 _mouseStart: function( event ) { 2154 2155 var o = this.options; 2156 2157 //Create and append the visible helper 2158 this.helper = this._createHelper( event ); 2159 2160 this._addClass( this.helper, "ui-draggable-dragging" ); 2161 2162 //Cache the helper size 2163 this._cacheHelperProportions(); 2164 2165 //If ddmanager is used for droppables, set the global draggable 2166 if ( $.ui.ddmanager ) { 2167 $.ui.ddmanager.current = this; 2168 } 2169 2170 /* 2171 * - Position generation - 2172 * This block generates everything position related - it's the core of draggables. 2173 */ 2174 2175 //Cache the margins of the original element 2176 this._cacheMargins(); 2177 2178 //Store the helper's css position 2179 this.cssPosition = this.helper.css( "position" ); 2180 this.scrollParent = this.helper.scrollParent( true ); 2181 this.offsetParent = this.helper.offsetParent(); 2182 this.hasFixedAncestor = this.helper.parents().filter( function() { 2183 return $( this ).css( "position" ) === "fixed"; 2184 } ).length > 0; 2185 2186 //The element's absolute position on the page minus margins 2187 this.positionAbs = this.element.offset(); 2188 this._refreshOffsets( event ); 2189 2190 //Generate the original position 2191 this.originalPosition = this.position = this._generatePosition( event, false ); 2192 this.originalPageX = event.pageX; 2193 this.originalPageY = event.pageY; 2194 2195 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 2196 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); 2197 2198 //Set a containment if given in the options 2199 this._setContainment(); 2200 2201 //Trigger event + callbacks 2202 if ( this._trigger( "start", event ) === false ) { 2203 this._clear(); 2204 return false; 2205 } 2206 2207 //Recache the helper size 2208 this._cacheHelperProportions(); 2209 2210 //Prepare the droppable offsets 2211 if ( $.ui.ddmanager && !o.dropBehaviour ) { 2212 $.ui.ddmanager.prepareOffsets( this, event ); 2213 } 2214 2215 // Execute the drag once - this causes the helper not to be visible before getting its 2216 // correct position 2217 this._mouseDrag( event, true ); 2218 2219 // If the ddmanager is used for droppables, inform the manager that dragging has started 2220 // (see #5003) 2221 if ( $.ui.ddmanager ) { 2222 $.ui.ddmanager.dragStart( this, event ); 2223 } 2224 2225 return true; 2226 }, 2227 2228 _refreshOffsets: function( event ) { 2229 this.offset = { 2230 top: this.positionAbs.top - this.margins.top, 2231 left: this.positionAbs.left - this.margins.left, 2232 scroll: false, 2233 parent: this._getParentOffset(), 2234 relative: this._getRelativeOffset() 2235 }; 2236 2237 this.offset.click = { 2238 left: event.pageX - this.offset.left, 2239 top: event.pageY - this.offset.top 2240 }; 2241 }, 2242 2243 _mouseDrag: function( event, noPropagation ) { 2244 2245 // reset any necessary cached properties (see #5009) 2246 if ( this.hasFixedAncestor ) { 2247 this.offset.parent = this._getParentOffset(); 2248 } 2249 2250 //Compute the helpers position 2251 this.position = this._generatePosition( event, true ); 2252 this.positionAbs = this._convertPositionTo( "absolute" ); 2253 2254 //Call plugins and callbacks and use the resulting position if something is returned 2255 if ( !noPropagation ) { 2256 var ui = this._uiHash(); 2257 if ( this._trigger( "drag", event, ui ) === false ) { 2258 this._mouseUp( new $.Event( "mouseup", event ) ); 2259 return false; 2260 } 2261 this.position = ui.position; 2262 } 2263 2264 this.helper[ 0 ].style.left = this.position.left + "px"; 2265 this.helper[ 0 ].style.top = this.position.top + "px"; 2266 2267 if ( $.ui.ddmanager ) { 2268 $.ui.ddmanager.drag( this, event ); 2269 } 2270 2271 return false; 2272 }, 2273 2274 _mouseStop: function( event ) { 2275 2276 //If we are using droppables, inform the manager about the drop 2277 var that = this, 2278 dropped = false; 2279 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 2280 dropped = $.ui.ddmanager.drop( this, event ); 2281 } 2282 2283 //if a drop comes from outside (a sortable) 2284 if ( this.dropped ) { 2285 dropped = this.dropped; 2286 this.dropped = false; 2287 } 2288 2289 if ( ( this.options.revert === "invalid" && !dropped ) || 2290 ( this.options.revert === "valid" && dropped ) || 2291 this.options.revert === true || ( $.isFunction( this.options.revert ) && 2292 this.options.revert.call( this.element, dropped ) ) 2293 ) { 2294 $( this.helper ).animate( 2295 this.originalPosition, 2296 parseInt( this.options.revertDuration, 10 ), 2297 function() { 2298 if ( that._trigger( "stop", event ) !== false ) { 2299 that._clear(); 2300 } 2301 } 2302 ); 2303 } else { 2304 if ( this._trigger( "stop", event ) !== false ) { 2305 this._clear(); 2306 } 2307 } 2308 2309 return false; 2310 }, 2311 2312 _mouseUp: function( event ) { 2313 this._unblockFrames(); 2314 2315 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 2316 // (see #5003) 2317 if ( $.ui.ddmanager ) { 2318 $.ui.ddmanager.dragStop( this, event ); 2319 } 2320 2321 // Only need to focus if the event occurred on the draggable itself, see #10527 2322 if ( this.handleElement.is( event.target ) ) { 2323 2324 // The interaction is over; whether or not the click resulted in a drag, 2325 // focus the element 2326 this.element.trigger( "focus" ); 2327 } 2328 2329 return $.ui.mouse.prototype._mouseUp.call( this, event ); 2330 }, 2331 2332 cancel: function() { 2333 2334 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 2335 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 2336 } else { 2337 this._clear(); 2338 } 2339 2340 return this; 2341 2342 }, 2343 2344 _getHandle: function( event ) { 2345 return this.options.handle ? 2346 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 2347 true; 2348 }, 2349 2350 _setHandleClassName: function() { 2351 this.handleElement = this.options.handle ? 2352 this.element.find( this.options.handle ) : this.element; 2353 this._addClass( this.handleElement, "ui-draggable-handle" ); 2354 }, 2355 2356 _removeHandleClassName: function() { 2357 this._removeClass( this.handleElement, "ui-draggable-handle" ); 2358 }, 2359 2360 _createHelper: function( event ) { 2361 2362 var o = this.options, 2363 helperIsFunction = $.isFunction( o.helper ), 2364 helper = helperIsFunction ? 2365 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 2366 ( o.helper === "clone" ? 2367 this.element.clone().removeAttr( "id" ) : 2368 this.element ); 2369 2370 if ( !helper.parents( "body" ).length ) { 2371 helper.appendTo( ( o.appendTo === "parent" ? 2372 this.element[ 0 ].parentNode : 2373 o.appendTo ) ); 2374 } 2375 2376 // Http://bugs.jqueryui.com/ticket/9446 2377 // a helper function can return the original element 2378 // which wouldn't have been set to relative in _create 2379 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 2380 this._setPositionRelative(); 2381 } 2382 2383 if ( helper[ 0 ] !== this.element[ 0 ] && 2384 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 2385 helper.css( "position", "absolute" ); 2386 } 2387 2388 return helper; 2389 2390 }, 2391 2392 _setPositionRelative: function() { 2393 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 2394 this.element[ 0 ].style.position = "relative"; 2395 } 2396 }, 2397 2398 _adjustOffsetFromHelper: function( obj ) { 2399 if ( typeof obj === "string" ) { 2400 obj = obj.split( " " ); 2401 } 2402 if ( $.isArray( obj ) ) { 2403 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 2404 } 2405 if ( "left" in obj ) { 2406 this.offset.click.left = obj.left + this.margins.left; 2407 } 2408 if ( "right" in obj ) { 2409 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 2410 } 2411 if ( "top" in obj ) { 2412 this.offset.click.top = obj.top + this.margins.top; 2413 } 2414 if ( "bottom" in obj ) { 2415 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 2416 } 2417 }, 2418 2419 _isRootNode: function( element ) { 2420 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 2421 }, 2422 2423 _getParentOffset: function() { 2424 2425 //Get the offsetParent and cache its position 2426 var po = this.offsetParent.offset(), 2427 document = this.document[ 0 ]; 2428 2429 // This is a special case where we need to modify a offset calculated on start, since the 2430 // following happened: 2431 // 1. The position of the helper is absolute, so it's position is calculated based on the 2432 // next positioned parent 2433 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 2434 // the document, which means that the scroll is included in the initial calculation of the 2435 // offset of the parent, and never recalculated upon drag 2436 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 2437 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 2438 po.left += this.scrollParent.scrollLeft(); 2439 po.top += this.scrollParent.scrollTop(); 2440 } 2441 2442 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 2443 po = { top: 0, left: 0 }; 2444 } 2445 2446 return { 2447 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 2448 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 2449 }; 2450 2451 }, 2452 2453 _getRelativeOffset: function() { 2454 if ( this.cssPosition !== "relative" ) { 2455 return { top: 0, left: 0 }; 2456 } 2457 2458 var p = this.element.position(), 2459 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2460 2461 return { 2462 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 2463 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 2464 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 2465 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 2466 }; 2467 2468 }, 2469 2470 _cacheMargins: function() { 2471 this.margins = { 2472 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 2473 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 2474 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 2475 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 2476 }; 2477 }, 2478 2479 _cacheHelperProportions: function() { 2480 this.helperProportions = { 2481 width: this.helper.outerWidth(), 2482 height: this.helper.outerHeight() 2483 }; 2484 }, 2485 2486 _setContainment: function() { 2487 2488 var isUserScrollable, c, ce, 2489 o = this.options, 2490 document = this.document[ 0 ]; 2491 2492 this.relativeContainer = null; 2493 2494 if ( !o.containment ) { 2495 this.containment = null; 2496 return; 2497 } 2498 2499 if ( o.containment === "window" ) { 2500 this.containment = [ 2501 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 2502 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 2503 $( window ).scrollLeft() + $( window ).width() - 2504 this.helperProportions.width - this.margins.left, 2505 $( window ).scrollTop() + 2506 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 2507 this.helperProportions.height - this.margins.top 2508 ]; 2509 return; 2510 } 2511 2512 if ( o.containment === "document" ) { 2513 this.containment = [ 2514 0, 2515 0, 2516 $( document ).width() - this.helperProportions.width - this.margins.left, 2517 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 2518 this.helperProportions.height - this.margins.top 2519 ]; 2520 return; 2521 } 2522 2523 if ( o.containment.constructor === Array ) { 2524 this.containment = o.containment; 2525 return; 2526 } 2527 2528 if ( o.containment === "parent" ) { 2529 o.containment = this.helper[ 0 ].parentNode; 2530 } 2531 2532 c = $( o.containment ); 2533 ce = c[ 0 ]; 2534 2535 if ( !ce ) { 2536 return; 2537 } 2538 2539 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 2540 2541 this.containment = [ 2542 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 2543 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 2544 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 2545 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 2546 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 2547 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 2548 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 2549 this.helperProportions.width - 2550 this.margins.left - 2551 this.margins.right, 2552 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 2553 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 2554 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 2555 this.helperProportions.height - 2556 this.margins.top - 2557 this.margins.bottom 2558 ]; 2559 this.relativeContainer = c; 2560 }, 2561 2562 _convertPositionTo: function( d, pos ) { 2563 2564 if ( !pos ) { 2565 pos = this.position; 2566 } 2567 2568 var mod = d === "absolute" ? 1 : -1, 2569 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2570 2571 return { 2572 top: ( 2573 2574 // The absolute mouse position 2575 pos.top + 2576 2577 // Only for relative positioned nodes: Relative offset from element to offset parent 2578 this.offset.relative.top * mod + 2579 2580 // The offsetParent's offset without borders (offset + border) 2581 this.offset.parent.top * mod - 2582 ( ( this.cssPosition === "fixed" ? 2583 -this.offset.scroll.top : 2584 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 2585 ), 2586 left: ( 2587 2588 // The absolute mouse position 2589 pos.left + 2590 2591 // Only for relative positioned nodes: Relative offset from element to offset parent 2592 this.offset.relative.left * mod + 2593 2594 // The offsetParent's offset without borders (offset + border) 2595 this.offset.parent.left * mod - 2596 ( ( this.cssPosition === "fixed" ? 2597 -this.offset.scroll.left : 2598 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 2599 ) 2600 }; 2601 2602 }, 2603 2604 _generatePosition: function( event, constrainPosition ) { 2605 2606 var containment, co, top, left, 2607 o = this.options, 2608 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2609 pageX = event.pageX, 2610 pageY = event.pageY; 2611 2612 // Cache the scroll 2613 if ( !scrollIsRootNode || !this.offset.scroll ) { 2614 this.offset.scroll = { 2615 top: this.scrollParent.scrollTop(), 2616 left: this.scrollParent.scrollLeft() 2617 }; 2618 } 2619 2620 /* 2621 * - Position constraining - 2622 * Constrain the position to a mix of grid, containment. 2623 */ 2624 2625 // If we are not dragging yet, we won't check for options 2626 if ( constrainPosition ) { 2627 if ( this.containment ) { 2628 if ( this.relativeContainer ) { 2629 co = this.relativeContainer.offset(); 2630 containment = [ 2631 this.containment[ 0 ] + co.left, 2632 this.containment[ 1 ] + co.top, 2633 this.containment[ 2 ] + co.left, 2634 this.containment[ 3 ] + co.top 2635 ]; 2636 } else { 2637 containment = this.containment; 2638 } 2639 2640 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 2641 pageX = containment[ 0 ] + this.offset.click.left; 2642 } 2643 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 2644 pageY = containment[ 1 ] + this.offset.click.top; 2645 } 2646 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 2647 pageX = containment[ 2 ] + this.offset.click.left; 2648 } 2649 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 2650 pageY = containment[ 3 ] + this.offset.click.top; 2651 } 2652 } 2653 2654 if ( o.grid ) { 2655 2656 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 2657 // argument errors in IE (see ticket #6950) 2658 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 2659 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 2660 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 2661 top - this.offset.click.top > containment[ 3 ] ) ? 2662 top : 2663 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 2664 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 2665 2666 left = o.grid[ 0 ] ? this.originalPageX + 2667 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 2668 this.originalPageX; 2669 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 2670 left - this.offset.click.left > containment[ 2 ] ) ? 2671 left : 2672 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 2673 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 2674 } 2675 2676 if ( o.axis === "y" ) { 2677 pageX = this.originalPageX; 2678 } 2679 2680 if ( o.axis === "x" ) { 2681 pageY = this.originalPageY; 2682 } 2683 } 2684 2685 return { 2686 top: ( 2687 2688 // The absolute mouse position 2689 pageY - 2690 2691 // Click offset (relative to the element) 2692 this.offset.click.top - 2693 2694 // Only for relative positioned nodes: Relative offset from element to offset parent 2695 this.offset.relative.top - 2696 2697 // The offsetParent's offset without borders (offset + border) 2698 this.offset.parent.top + 2699 ( this.cssPosition === "fixed" ? 2700 -this.offset.scroll.top : 2701 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2702 ), 2703 left: ( 2704 2705 // The absolute mouse position 2706 pageX - 2707 2708 // Click offset (relative to the element) 2709 this.offset.click.left - 2710 2711 // Only for relative positioned nodes: Relative offset from element to offset parent 2712 this.offset.relative.left - 2713 2714 // The offsetParent's offset without borders (offset + border) 2715 this.offset.parent.left + 2716 ( this.cssPosition === "fixed" ? 2717 -this.offset.scroll.left : 2718 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2719 ) 2720 }; 2721 2722 }, 2723 2724 _clear: function() { 2725 this._removeClass( this.helper, "ui-draggable-dragging" ); 2726 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 2727 this.helper.remove(); 2728 } 2729 this.helper = null; 2730 this.cancelHelperRemoval = false; 2731 if ( this.destroyOnClear ) { 2732 this.destroy(); 2733 } 2734 }, 2735 2736 // From now on bulk stuff - mainly helpers 2737 2738 _trigger: function( type, event, ui ) { 2739 ui = ui || this._uiHash(); 2740 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2741 2742 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 2743 if ( /^(drag|start|stop)/.test( type ) ) { 2744 this.positionAbs = this._convertPositionTo( "absolute" ); 2745 ui.offset = this.positionAbs; 2746 } 2747 return $.Widget.prototype._trigger.call( this, type, event, ui ); 2748 }, 2749 2750 plugins: {}, 2751 2752 _uiHash: function() { 2753 return { 2754 helper: this.helper, 2755 position: this.position, 2756 originalPosition: this.originalPosition, 2757 offset: this.positionAbs 2758 }; 2759 } 2760 2761} ); 2762 2763$.ui.plugin.add( "draggable", "connectToSortable", { 2764 start: function( event, ui, draggable ) { 2765 var uiSortable = $.extend( {}, ui, { 2766 item: draggable.element 2767 } ); 2768 2769 draggable.sortables = []; 2770 $( draggable.options.connectToSortable ).each( function() { 2771 var sortable = $( this ).sortable( "instance" ); 2772 2773 if ( sortable && !sortable.options.disabled ) { 2774 draggable.sortables.push( sortable ); 2775 2776 // RefreshPositions is called at drag start to refresh the containerCache 2777 // which is used in drag. This ensures it's initialized and synchronized 2778 // with any changes that might have happened on the page since initialization. 2779 sortable.refreshPositions(); 2780 sortable._trigger( "activate", event, uiSortable ); 2781 } 2782 } ); 2783 }, 2784 stop: function( event, ui, draggable ) { 2785 var uiSortable = $.extend( {}, ui, { 2786 item: draggable.element 2787 } ); 2788 2789 draggable.cancelHelperRemoval = false; 2790 2791 $.each( draggable.sortables, function() { 2792 var sortable = this; 2793 2794 if ( sortable.isOver ) { 2795 sortable.isOver = 0; 2796 2797 // Allow this sortable to handle removing the helper 2798 draggable.cancelHelperRemoval = true; 2799 sortable.cancelHelperRemoval = false; 2800 2801 // Use _storedCSS To restore properties in the sortable, 2802 // as this also handles revert (#9675) since the draggable 2803 // may have modified them in unexpected ways (#8809) 2804 sortable._storedCSS = { 2805 position: sortable.placeholder.css( "position" ), 2806 top: sortable.placeholder.css( "top" ), 2807 left: sortable.placeholder.css( "left" ) 2808 }; 2809 2810 sortable._mouseStop( event ); 2811 2812 // Once drag has ended, the sortable should return to using 2813 // its original helper, not the shared helper from draggable 2814 sortable.options.helper = sortable.options._helper; 2815 } else { 2816 2817 // Prevent this Sortable from removing the helper. 2818 // However, don't set the draggable to remove the helper 2819 // either as another connected Sortable may yet handle the removal. 2820 sortable.cancelHelperRemoval = true; 2821 2822 sortable._trigger( "deactivate", event, uiSortable ); 2823 } 2824 } ); 2825 }, 2826 drag: function( event, ui, draggable ) { 2827 $.each( draggable.sortables, function() { 2828 var innermostIntersecting = false, 2829 sortable = this; 2830 2831 // Copy over variables that sortable's _intersectsWith uses 2832 sortable.positionAbs = draggable.positionAbs; 2833 sortable.helperProportions = draggable.helperProportions; 2834 sortable.offset.click = draggable.offset.click; 2835 2836 if ( sortable._intersectsWith( sortable.containerCache ) ) { 2837 innermostIntersecting = true; 2838 2839 $.each( draggable.sortables, function() { 2840 2841 // Copy over variables that sortable's _intersectsWith uses 2842 this.positionAbs = draggable.positionAbs; 2843 this.helperProportions = draggable.helperProportions; 2844 this.offset.click = draggable.offset.click; 2845 2846 if ( this !== sortable && 2847 this._intersectsWith( this.containerCache ) && 2848 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 2849 innermostIntersecting = false; 2850 } 2851 2852 return innermostIntersecting; 2853 } ); 2854 } 2855 2856 if ( innermostIntersecting ) { 2857 2858 // If it intersects, we use a little isOver variable and set it once, 2859 // so that the move-in stuff gets fired only once. 2860 if ( !sortable.isOver ) { 2861 sortable.isOver = 1; 2862 2863 // Store draggable's parent in case we need to reappend to it later. 2864 draggable._parent = ui.helper.parent(); 2865 2866 sortable.currentItem = ui.helper 2867 .appendTo( sortable.element ) 2868 .data( "ui-sortable-item", true ); 2869 2870 // Store helper option to later restore it 2871 sortable.options._helper = sortable.options.helper; 2872 2873 sortable.options.helper = function() { 2874 return ui.helper[ 0 ]; 2875 }; 2876 2877 // Fire the start events of the sortable with our passed browser event, 2878 // and our own helper (so it doesn't create a new one) 2879 event.target = sortable.currentItem[ 0 ]; 2880 sortable._mouseCapture( event, true ); 2881 sortable._mouseStart( event, true, true ); 2882 2883 // Because the browser event is way off the new appended portlet, 2884 // modify necessary variables to reflect the changes 2885 sortable.offset.click.top = draggable.offset.click.top; 2886 sortable.offset.click.left = draggable.offset.click.left; 2887 sortable.offset.parent.left -= draggable.offset.parent.left - 2888 sortable.offset.parent.left; 2889 sortable.offset.parent.top -= draggable.offset.parent.top - 2890 sortable.offset.parent.top; 2891 2892 draggable._trigger( "toSortable", event ); 2893 2894 // Inform draggable that the helper is in a valid drop zone, 2895 // used solely in the revert option to handle "valid/invalid". 2896 draggable.dropped = sortable.element; 2897 2898 // Need to refreshPositions of all sortables in the case that 2899 // adding to one sortable changes the location of the other sortables (#9675) 2900 $.each( draggable.sortables, function() { 2901 this.refreshPositions(); 2902 } ); 2903 2904 // Hack so receive/update callbacks work (mostly) 2905 draggable.currentItem = draggable.element; 2906 sortable.fromOutside = draggable; 2907 } 2908 2909 if ( sortable.currentItem ) { 2910 sortable._mouseDrag( event ); 2911 2912 // Copy the sortable's position because the draggable's can potentially reflect 2913 // a relative position, while sortable is always absolute, which the dragged 2914 // element has now become. (#8809) 2915 ui.position = sortable.position; 2916 } 2917 } else { 2918 2919 // If it doesn't intersect with the sortable, and it intersected before, 2920 // we fake the drag stop of the sortable, but make sure it doesn't remove 2921 // the helper by using cancelHelperRemoval. 2922 if ( sortable.isOver ) { 2923 2924 sortable.isOver = 0; 2925 sortable.cancelHelperRemoval = true; 2926 2927 // Calling sortable's mouseStop would trigger a revert, 2928 // so revert must be temporarily false until after mouseStop is called. 2929 sortable.options._revert = sortable.options.revert; 2930 sortable.options.revert = false; 2931 2932 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 2933 sortable._mouseStop( event, true ); 2934 2935 // Restore sortable behaviors that were modfied 2936 // when the draggable entered the sortable area (#9481) 2937 sortable.options.revert = sortable.options._revert; 2938 sortable.options.helper = sortable.options._helper; 2939 2940 if ( sortable.placeholder ) { 2941 sortable.placeholder.remove(); 2942 } 2943 2944 // Restore and recalculate the draggable's offset considering the sortable 2945 // may have modified them in unexpected ways. (#8809, #10669) 2946 ui.helper.appendTo( draggable._parent ); 2947 draggable._refreshOffsets( event ); 2948 ui.position = draggable._generatePosition( event, true ); 2949 2950 draggable._trigger( "fromSortable", event ); 2951 2952 // Inform draggable that the helper is no longer in a valid drop zone 2953 draggable.dropped = false; 2954 2955 // Need to refreshPositions of all sortables just in case removing 2956 // from one sortable changes the location of other sortables (#9675) 2957 $.each( draggable.sortables, function() { 2958 this.refreshPositions(); 2959 } ); 2960 } 2961 } 2962 } ); 2963 } 2964} ); 2965 2966$.ui.plugin.add( "draggable", "cursor", { 2967 start: function( event, ui, instance ) { 2968 var t = $( "body" ), 2969 o = instance.options; 2970 2971 if ( t.css( "cursor" ) ) { 2972 o._cursor = t.css( "cursor" ); 2973 } 2974 t.css( "cursor", o.cursor ); 2975 }, 2976 stop: function( event, ui, instance ) { 2977 var o = instance.options; 2978 if ( o._cursor ) { 2979 $( "body" ).css( "cursor", o._cursor ); 2980 } 2981 } 2982} ); 2983 2984$.ui.plugin.add( "draggable", "opacity", { 2985 start: function( event, ui, instance ) { 2986 var t = $( ui.helper ), 2987 o = instance.options; 2988 if ( t.css( "opacity" ) ) { 2989 o._opacity = t.css( "opacity" ); 2990 } 2991 t.css( "opacity", o.opacity ); 2992 }, 2993 stop: function( event, ui, instance ) { 2994 var o = instance.options; 2995 if ( o._opacity ) { 2996 $( ui.helper ).css( "opacity", o._opacity ); 2997 } 2998 } 2999} ); 3000 3001$.ui.plugin.add( "draggable", "scroll", { 3002 start: function( event, ui, i ) { 3003 if ( !i.scrollParentNotHidden ) { 3004 i.scrollParentNotHidden = i.helper.scrollParent( false ); 3005 } 3006 3007 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 3008 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 3009 i.overflowOffset = i.scrollParentNotHidden.offset(); 3010 } 3011 }, 3012 drag: function( event, ui, i ) { 3013 3014 var o = i.options, 3015 scrolled = false, 3016 scrollParent = i.scrollParentNotHidden[ 0 ], 3017 document = i.document[ 0 ]; 3018 3019 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 3020 if ( !o.axis || o.axis !== "x" ) { 3021 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 3022 o.scrollSensitivity ) { 3023 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 3024 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 3025 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 3026 } 3027 } 3028 3029 if ( !o.axis || o.axis !== "y" ) { 3030 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 3031 o.scrollSensitivity ) { 3032 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 3033 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 3034 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 3035 } 3036 } 3037 3038 } else { 3039 3040 if ( !o.axis || o.axis !== "x" ) { 3041 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 3042 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 3043 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 3044 o.scrollSensitivity ) { 3045 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 3046 } 3047 } 3048 3049 if ( !o.axis || o.axis !== "y" ) { 3050 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 3051 scrolled = $( document ).scrollLeft( 3052 $( document ).scrollLeft() - o.scrollSpeed 3053 ); 3054 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 3055 o.scrollSensitivity ) { 3056 scrolled = $( document ).scrollLeft( 3057 $( document ).scrollLeft() + o.scrollSpeed 3058 ); 3059 } 3060 } 3061 3062 } 3063 3064 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 3065 $.ui.ddmanager.prepareOffsets( i, event ); 3066 } 3067 3068 } 3069} ); 3070 3071$.ui.plugin.add( "draggable", "snap", { 3072 start: function( event, ui, i ) { 3073 3074 var o = i.options; 3075 3076 i.snapElements = []; 3077 3078 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 3079 .each( function() { 3080 var $t = $( this ), 3081 $o = $t.offset(); 3082 if ( this !== i.element[ 0 ] ) { 3083 i.snapElements.push( { 3084 item: this, 3085 width: $t.outerWidth(), height: $t.outerHeight(), 3086 top: $o.top, left: $o.left 3087 } ); 3088 } 3089 } ); 3090 3091 }, 3092 drag: function( event, ui, inst ) { 3093 3094 var ts, bs, ls, rs, l, r, t, b, i, first, 3095 o = inst.options, 3096 d = o.snapTolerance, 3097 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 3098 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 3099 3100 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 3101 3102 l = inst.snapElements[ i ].left - inst.margins.left; 3103 r = l + inst.snapElements[ i ].width; 3104 t = inst.snapElements[ i ].top - inst.margins.top; 3105 b = t + inst.snapElements[ i ].height; 3106 3107 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 3108 !$.contains( inst.snapElements[ i ].item.ownerDocument, 3109 inst.snapElements[ i ].item ) ) { 3110 if ( inst.snapElements[ i ].snapping ) { 3111 ( inst.options.snap.release && 3112 inst.options.snap.release.call( 3113 inst.element, 3114 event, 3115 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 3116 ) ); 3117 } 3118 inst.snapElements[ i ].snapping = false; 3119 continue; 3120 } 3121 3122 if ( o.snapMode !== "inner" ) { 3123 ts = Math.abs( t - y2 ) <= d; 3124 bs = Math.abs( b - y1 ) <= d; 3125 ls = Math.abs( l - x2 ) <= d; 3126 rs = Math.abs( r - x1 ) <= d; 3127 if ( ts ) { 3128 ui.position.top = inst._convertPositionTo( "relative", { 3129 top: t - inst.helperProportions.height, 3130 left: 0 3131 } ).top; 3132 } 3133 if ( bs ) { 3134 ui.position.top = inst._convertPositionTo( "relative", { 3135 top: b, 3136 left: 0 3137 } ).top; 3138 } 3139 if ( ls ) { 3140 ui.position.left = inst._convertPositionTo( "relative", { 3141 top: 0, 3142 left: l - inst.helperProportions.width 3143 } ).left; 3144 } 3145 if ( rs ) { 3146 ui.position.left = inst._convertPositionTo( "relative", { 3147 top: 0, 3148 left: r 3149 } ).left; 3150 } 3151 } 3152 3153 first = ( ts || bs || ls || rs ); 3154 3155 if ( o.snapMode !== "outer" ) { 3156 ts = Math.abs( t - y1 ) <= d; 3157 bs = Math.abs( b - y2 ) <= d; 3158 ls = Math.abs( l - x1 ) <= d; 3159 rs = Math.abs( r - x2 ) <= d; 3160 if ( ts ) { 3161 ui.position.top = inst._convertPositionTo( "relative", { 3162 top: t, 3163 left: 0 3164 } ).top; 3165 } 3166 if ( bs ) { 3167 ui.position.top = inst._convertPositionTo( "relative", { 3168 top: b - inst.helperProportions.height, 3169 left: 0 3170 } ).top; 3171 } 3172 if ( ls ) { 3173 ui.position.left = inst._convertPositionTo( "relative", { 3174 top: 0, 3175 left: l 3176 } ).left; 3177 } 3178 if ( rs ) { 3179 ui.position.left = inst._convertPositionTo( "relative", { 3180 top: 0, 3181 left: r - inst.helperProportions.width 3182 } ).left; 3183 } 3184 } 3185 3186 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 3187 ( inst.options.snap.snap && 3188 inst.options.snap.snap.call( 3189 inst.element, 3190 event, 3191 $.extend( inst._uiHash(), { 3192 snapItem: inst.snapElements[ i ].item 3193 } ) ) ); 3194 } 3195 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 3196 3197 } 3198 3199 } 3200} ); 3201 3202$.ui.plugin.add( "draggable", "stack", { 3203 start: function( event, ui, instance ) { 3204 var min, 3205 o = instance.options, 3206 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 3207 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 3208 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 3209 } ); 3210 3211 if ( !group.length ) { return; } 3212 3213 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 3214 $( group ).each( function( i ) { 3215 $( this ).css( "zIndex", min + i ); 3216 } ); 3217 this.css( "zIndex", ( min + group.length ) ); 3218 } 3219} ); 3220 3221$.ui.plugin.add( "draggable", "zIndex", { 3222 start: function( event, ui, instance ) { 3223 var t = $( ui.helper ), 3224 o = instance.options; 3225 3226 if ( t.css( "zIndex" ) ) { 3227 o._zIndex = t.css( "zIndex" ); 3228 } 3229 t.css( "zIndex", o.zIndex ); 3230 }, 3231 stop: function( event, ui, instance ) { 3232 var o = instance.options; 3233 3234 if ( o._zIndex ) { 3235 $( ui.helper ).css( "zIndex", o._zIndex ); 3236 } 3237 } 3238} ); 3239 3240var widgetsDraggable = $.ui.draggable; 3241 3242 3243/*! 3244 * jQuery UI Droppable 1.12.1 3245 * http://jqueryui.com 3246 * 3247 * Copyright jQuery Foundation and other contributors 3248 * Released under the MIT license. 3249 * http://jquery.org/license 3250 */ 3251 3252//>>label: Droppable 3253//>>group: Interactions 3254//>>description: Enables drop targets for draggable elements. 3255//>>docs: http://api.jqueryui.com/droppable/ 3256//>>demos: http://jqueryui.com/droppable/ 3257 3258 3259 3260$.widget( "ui.droppable", { 3261 version: "1.12.1", 3262 widgetEventPrefix: "drop", 3263 options: { 3264 accept: "*", 3265 addClasses: true, 3266 greedy: false, 3267 scope: "default", 3268 tolerance: "intersect", 3269 3270 // Callbacks 3271 activate: null, 3272 deactivate: null, 3273 drop: null, 3274 out: null, 3275 over: null 3276 }, 3277 _create: function() { 3278 3279 var proportions, 3280 o = this.options, 3281 accept = o.accept; 3282 3283 this.isover = false; 3284 this.isout = true; 3285 3286 this.accept = $.isFunction( accept ) ? accept : function( d ) { 3287 return d.is( accept ); 3288 }; 3289 3290 this.proportions = function( /* valueToWrite */ ) { 3291 if ( arguments.length ) { 3292 3293 // Store the droppable's proportions 3294 proportions = arguments[ 0 ]; 3295 } else { 3296 3297 // Retrieve or derive the droppable's proportions 3298 return proportions ? 3299 proportions : 3300 proportions = { 3301 width: this.element[ 0 ].offsetWidth, 3302 height: this.element[ 0 ].offsetHeight 3303 }; 3304 } 3305 }; 3306 3307 this._addToManager( o.scope ); 3308 3309 o.addClasses && this._addClass( "ui-droppable" ); 3310 3311 }, 3312 3313 _addToManager: function( scope ) { 3314 3315 // Add the reference and positions to the manager 3316 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 3317 $.ui.ddmanager.droppables[ scope ].push( this ); 3318 }, 3319 3320 _splice: function( drop ) { 3321 var i = 0; 3322 for ( ; i < drop.length; i++ ) { 3323 if ( drop[ i ] === this ) { 3324 drop.splice( i, 1 ); 3325 } 3326 } 3327 }, 3328 3329 _destroy: function() { 3330 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3331 3332 this._splice( drop ); 3333 }, 3334 3335 _setOption: function( key, value ) { 3336 3337 if ( key === "accept" ) { 3338 this.accept = $.isFunction( value ) ? value : function( d ) { 3339 return d.is( value ); 3340 }; 3341 } else if ( key === "scope" ) { 3342 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 3343 3344 this._splice( drop ); 3345 this._addToManager( value ); 3346 } 3347 3348 this._super( key, value ); 3349 }, 3350 3351 _activate: function( event ) { 3352 var draggable = $.ui.ddmanager.current; 3353 3354 this._addActiveClass(); 3355 if ( draggable ) { 3356 this._trigger( "activate", event, this.ui( draggable ) ); 3357 } 3358 }, 3359 3360 _deactivate: function( event ) { 3361 var draggable = $.ui.ddmanager.current; 3362 3363 this._removeActiveClass(); 3364 if ( draggable ) { 3365 this._trigger( "deactivate", event, this.ui( draggable ) ); 3366 } 3367 }, 3368 3369 _over: function( event ) { 3370 3371 var draggable = $.ui.ddmanager.current; 3372 3373 // Bail if draggable and droppable are same element 3374 if ( !draggable || ( draggable.currentItem || 3375 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3376 return; 3377 } 3378 3379 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3380 draggable.element ) ) ) { 3381 this._addHoverClass(); 3382 this._trigger( "over", event, this.ui( draggable ) ); 3383 } 3384 3385 }, 3386 3387 _out: function( event ) { 3388 3389 var draggable = $.ui.ddmanager.current; 3390 3391 // Bail if draggable and droppable are same element 3392 if ( !draggable || ( draggable.currentItem || 3393 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3394 return; 3395 } 3396 3397 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 3398 draggable.element ) ) ) { 3399 this._removeHoverClass(); 3400 this._trigger( "out", event, this.ui( draggable ) ); 3401 } 3402 3403 }, 3404 3405 _drop: function( event, custom ) { 3406 3407 var draggable = custom || $.ui.ddmanager.current, 3408 childrenIntersection = false;
vendor: 4,744 bytes, lines 3409-3581
3409 3410 // Bail if draggable and droppable are same element 3411 if ( !draggable || ( draggable.currentItem || 3412 draggable.element )[ 0 ] === this.element[ 0 ] ) { 3413 return false; 3414 } 3415 3416 this.element 3417 .find( ":data(ui-droppable)" ) 3418 .not( ".ui-draggable-dragging" ) 3419 .each( function() { 3420 var inst = $( this ).droppable( "instance" ); 3421 if ( 3422 inst.options.greedy && 3423 !inst.options.disabled && 3424 inst.options.scope === draggable.options.scope && 3425 inst.accept.call( 3426 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 3427 ) && 3428 intersect( 3429 draggable, 3430 $.extend( inst, { offset: inst.element.offset() } ), 3431 inst.options.tolerance, event 3432 ) 3433 ) { 3434 childrenIntersection = true; 3435 return false; } 3436 } ); 3437 if ( childrenIntersection ) { 3438 return false; 3439 } 3440 3441 if ( this.accept.call( this.element[ 0 ], 3442 ( draggable.currentItem || draggable.element ) ) ) { 3443 this._removeActiveClass(); 3444 this._removeHoverClass(); 3445 3446 this._trigger( "drop", event, this.ui( draggable ) ); 3447 return this.element; 3448 } 3449 3450 return false; 3451 3452 }, 3453 3454 ui: function( c ) { 3455 return { 3456 draggable: ( c.currentItem || c.element ), 3457 helper: c.helper, 3458 position: c.position, 3459 offset: c.positionAbs 3460 }; 3461 }, 3462 3463 // Extension points just to make backcompat sane and avoid duplicating logic 3464 // TODO: Remove in 1.13 along with call to it below 3465 _addHoverClass: function() { 3466 this._addClass( "ui-droppable-hover" ); 3467 }, 3468 3469 _removeHoverClass: function() { 3470 this._removeClass( "ui-droppable-hover" ); 3471 }, 3472 3473 _addActiveClass: function() { 3474 this._addClass( "ui-droppable-active" ); 3475 }, 3476 3477 _removeActiveClass: function() { 3478 this._removeClass( "ui-droppable-active" ); 3479 } 3480} ); 3481 3482var intersect = $.ui.intersect = ( function() { 3483 function isOverAxis( x, reference, size ) { 3484 return ( x >= reference ) && ( x < ( reference + size ) ); 3485 } 3486 3487 return function( draggable, droppable, toleranceMode, event ) { 3488 3489 if ( !droppable.offset ) { 3490 return false; 3491 } 3492 3493 var x1 = ( draggable.positionAbs || 3494 draggable.position.absolute ).left + draggable.margins.left, 3495 y1 = ( draggable.positionAbs || 3496 draggable.position.absolute ).top + draggable.margins.top, 3497 x2 = x1 + draggable.helperProportions.width, 3498 y2 = y1 + draggable.helperProportions.height, 3499 l = droppable.offset.left, 3500 t = droppable.offset.top, 3501 r = l + droppable.proportions().width, 3502 b = t + droppable.proportions().height; 3503 3504 switch ( toleranceMode ) { 3505 case "fit": 3506 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 3507 case "intersect": 3508 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 3509 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 3510 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 3511 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 3512 case "pointer": 3513 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 3514 isOverAxis( event.pageX, l, droppable.proportions().width ); 3515 case "touch": 3516 return ( 3517 ( y1 >= t && y1 <= b ) || // Top edge touching 3518 ( y2 >= t && y2 <= b ) || // Bottom edge touching 3519 ( y1 < t && y2 > b ) // Surrounded vertically 3520 ) && ( 3521 ( x1 >= l && x1 <= r ) || // Left edge touching 3522 ( x2 >= l && x2 <= r ) || // Right edge touching 3523 ( x1 < l && x2 > r ) // Surrounded horizontally 3524 ); 3525 default: 3526 return false; 3527 } 3528 }; 3529} )(); 3530 3531/* 3532 This manager tracks offsets of draggables and droppables 3533*/ 3534$.ui.ddmanager = { 3535 current: null, 3536 droppables: { "default": [] }, 3537 prepareOffsets: function( t, event ) { 3538 3539 var i, j, 3540 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 3541 type = event ? event.type : null, // workaround for #2317 3542 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 3543 3544 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 3545 3546 // No disabled and non-accepted 3547 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 3548 ( t.currentItem || t.element ) ) ) ) { 3549 continue; 3550 } 3551 3552 // Filter out elements in the current dragged item 3553 for ( j = 0; j < list.length; j++ ) { 3554 if ( list[ j ] === m[ i ].element[ 0 ] ) { 3555 m[ i ].proportions().height = 0; 3556 continue droppablesLoop; 3557 } 3558 } 3559 3560 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 3561 if ( !m[ i ].visible ) { 3562 continue; 3563 } 3564 3565 // Activate the droppable if used directly from draggables 3566 if ( type === "mousedown" ) { 3567 m[ i ]._activate.call( m[ i ], event ); 3568 } 3569 3570 m[ i ].offset = m[ i ].element.offset(); 3571 m[ i ].proportions( { 3572 width: m[ i ].element[ 0 ].offsetWidth, 3573 height: m[ i ].element[ 0 ].offsetHeight 3574 } ); 3575 3576 } 3577 3578 }, 3579 drop: function( draggable, event ) { 3580 3581 var dropped = false;
vendor: 5,516 bytes, lines 3582-3787
3582 3583 // Create a copy of the droppables in case the list changes during the drop (#9116) 3584 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 3585 3586 if ( !this.options ) { 3587 return; 3588 } 3589 if ( !this.options.disabled && this.visible && 3590 intersect( draggable, this, this.options.tolerance, event ) ) { 3591 dropped = this._drop.call( this, event ) || dropped; 3592 } 3593 3594 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 3595 ( draggable.currentItem || draggable.element ) ) ) { 3596 this.isout = true; 3597 this.isover = false; 3598 this._deactivate.call( this, event ); 3599 } 3600 3601 } ); 3602 return dropped; 3603 3604 }, 3605 dragStart: function( draggable, event ) { 3606 3607 // Listen for scrolling so that if the dragging causes scrolling the position of the 3608 // droppables can be recalculated (see #5003) 3609 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 3610 if ( !draggable.options.refreshPositions ) { 3611 $.ui.ddmanager.prepareOffsets( draggable, event ); 3612 } 3613 } ); 3614 }, 3615 drag: function( draggable, event ) { 3616 3617 // If you have a highly dynamic page, you might try this option. It renders positions 3618 // every time you move the mouse. 3619 if ( draggable.options.refreshPositions ) { 3620 $.ui.ddmanager.prepareOffsets( draggable, event ); 3621 } 3622 3623 // Run through all droppables and check their positions based on specific tolerance options 3624 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 3625 3626 if ( this.options.disabled || this.greedyChild || !this.visible ) { 3627 return; 3628 } 3629 3630 var parentInstance, scope, parent, 3631 intersects = intersect( draggable, this, this.options.tolerance, event ), 3632 c = !intersects && this.isover ? 3633 "isout" : 3634 ( intersects && !this.isover ? "isover" : null ); 3635 if ( !c ) { 3636 return; 3637 } 3638 3639 if ( this.options.greedy ) { 3640 3641 // find droppable parents with same scope 3642 scope = this.options.scope; 3643 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 3644 return $( this ).droppable( "instance" ).options.scope === scope; 3645 } ); 3646 3647 if ( parent.length ) { 3648 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 3649 parentInstance.greedyChild = ( c === "isover" ); 3650 } 3651 } 3652 3653 // We just moved into a greedy child 3654 if ( parentInstance && c === "isover" ) { 3655 parentInstance.isover = false; 3656 parentInstance.isout = true; 3657 parentInstance._out.call( parentInstance, event ); 3658 } 3659 3660 this[ c ] = true; 3661 this[ c === "isout" ? "isover" : "isout" ] = false; 3662 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 3663 3664 // We just moved out of a greedy child 3665 if ( parentInstance && c === "isout" ) { 3666 parentInstance.isout = false; 3667 parentInstance.isover = true; 3668 parentInstance._over.call( parentInstance, event ); 3669 } 3670 } ); 3671 3672 }, 3673 dragStop: function( draggable, event ) { 3674 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 3675 3676 // Call prepareOffsets one final time since IE does not fire return scroll events when 3677 // overflow was caused by drag (see #5003) 3678 if ( !draggable.options.refreshPositions ) { 3679 $.ui.ddmanager.prepareOffsets( draggable, event ); 3680 } 3681 } 3682}; 3683 3684// DEPRECATED 3685// TODO: switch return back to widget declaration at top of file when this is removed 3686if ( $.uiBackCompat !== false ) { 3687 3688 // Backcompat for activeClass and hoverClass options 3689 $.widget( "ui.droppable", $.ui.droppable, { 3690 options: { 3691 hoverClass: false, 3692 activeClass: false 3693 }, 3694 _addActiveClass: function() { 3695 this._super(); 3696 if ( this.options.activeClass ) { 3697 this.element.addClass( this.options.activeClass ); 3698 } 3699 }, 3700 _removeActiveClass: function() { 3701 this._super(); 3702 if ( this.options.activeClass ) { 3703 this.element.removeClass( this.options.activeClass ); 3704 } 3705 }, 3706 _addHoverClass: function() { 3707 this._super(); 3708 if ( this.options.hoverClass ) { 3709 this.element.addClass( this.options.hoverClass ); 3710 } 3711 }, 3712 _removeHoverClass: function() { 3713 this._super(); 3714 if ( this.options.hoverClass ) { 3715 this.element.removeClass( this.options.hoverClass ); 3716 } 3717 } 3718 } ); 3719} 3720 3721var widgetsDroppable = $.ui.droppable; 3722 3723 3724/*! 3725 * jQuery UI Resizable 1.12.1 3726 * http://jqueryui.com 3727 * 3728 * Copyright jQuery Foundation and other contributors 3729 * Released under the MIT license. 3730 * http://jquery.org/license 3731 */ 3732 3733//>>label: Resizable 3734//>>group: Interactions 3735//>>description: Enables resize functionality for any element. 3736//>>docs: http://api.jqueryui.com/resizable/ 3737//>>demos: http://jqueryui.com/resizable/ 3738//>>css.structure: ../../themes/base/core.css 3739//>>css.structure: ../../themes/base/resizable.css 3740//>>css.theme: ../../themes/base/theme.css 3741 3742 3743 3744$.widget( "ui.resizable", $.ui.mouse, { 3745 version: "1.12.1", 3746 widgetEventPrefix: "resize", 3747 options: { 3748 alsoResize: false, 3749 animate: false, 3750 animateDuration: "slow", 3751 animateEasing: "swing", 3752 aspectRatio: false, 3753 autoHide: false, 3754 classes: { 3755 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 3756 }, 3757 containment: false, 3758 ghost: false, 3759 grid: false, 3760 handles: "e,s,se", 3761 helper: false, 3762 maxHeight: null, 3763 maxWidth: null, 3764 minHeight: 10, 3765 minWidth: 10, 3766 3767 // See #7960 3768 zIndex: 90, 3769 3770 // Callbacks 3771 resize: null, 3772 start: null, 3773 stop: null 3774 }, 3775 3776 _num: function( value ) { 3777 return parseFloat( value ) || 0; 3778 }, 3779 3780 _isNumber: function( value ) { 3781 return !isNaN( parseFloat( value ) ); 3782 }, 3783 3784 _hasScroll: function( el, a ) { 3785 3786 if ( $( el ).css( "overflow" ) === "hidden" ) { 3787 return false;
vendor: 26,006 bytes, lines 3788-4816
3788 } 3789 3790 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3791 has = false; 3792 3793 if ( el[ scroll ] > 0 ) { 3794 return true; 3795 } 3796 3797 // TODO: determine which cases actually cause this to happen 3798 // if the element doesn't have the scroll set, see if it's possible to 3799 // set the scroll 3800 el[ scroll ] = 1; 3801 has = ( el[ scroll ] > 0 ); 3802 el[ scroll ] = 0; 3803 return has; 3804 }, 3805 3806 _create: function() { 3807 3808 var margins, 3809 o = this.options, 3810 that = this; 3811 this._addClass( "ui-resizable" ); 3812 3813 $.extend( this, { 3814 _aspectRatio: !!( o.aspectRatio ), 3815 aspectRatio: o.aspectRatio, 3816 originalElement: this.element, 3817 _proportionallyResizeElements: [], 3818 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 3819 } ); 3820 3821 // Wrap the element if it cannot hold child nodes 3822 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 3823 3824 this.element.wrap( 3825 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( { 3826 position: this.element.css( "position" ), 3827 width: this.element.outerWidth(), 3828 height: this.element.outerHeight(), 3829 top: this.element.css( "top" ), 3830 left: this.element.css( "left" ) 3831 } ) 3832 ); 3833 3834 this.element = this.element.parent().data( 3835 "ui-resizable", this.element.resizable( "instance" ) 3836 ); 3837 3838 this.elementIsWrapper = true; 3839 3840 margins = { 3841 marginTop: this.originalElement.css( "marginTop" ), 3842 marginRight: this.originalElement.css( "marginRight" ), 3843 marginBottom: this.originalElement.css( "marginBottom" ), 3844 marginLeft: this.originalElement.css( "marginLeft" ) 3845 }; 3846 3847 this.element.css( margins ); 3848 this.originalElement.css( "margin", 0 ); 3849 3850 // support: Safari 3851 // Prevent Safari textarea resize 3852 this.originalResizeStyle = this.originalElement.css( "resize" ); 3853 this.originalElement.css( "resize", "none" ); 3854 3855 this._proportionallyResizeElements.push( this.originalElement.css( { 3856 position: "static", 3857 zoom: 1, 3858 display: "block" 3859 } ) ); 3860 3861 // Support: IE9 3862 // avoid IE jump (hard set the margin) 3863 this.originalElement.css( margins ); 3864 3865 this._proportionallyResize(); 3866 } 3867 3868 this._setupHandles(); 3869 3870 if ( o.autoHide ) { 3871 $( this.element ) 3872 .on( "mouseenter", function() { 3873 if ( o.disabled ) { 3874 return; 3875 } 3876 that._removeClass( "ui-resizable-autohide" ); 3877 that._handles.show(); 3878 } ) 3879 .on( "mouseleave", function() { 3880 if ( o.disabled ) { 3881 return; 3882 } 3883 if ( !that.resizing ) { 3884 that._addClass( "ui-resizable-autohide" ); 3885 that._handles.hide(); 3886 } 3887 } ); 3888 } 3889 3890 this._mouseInit(); 3891 }, 3892 3893 _destroy: function() { 3894 3895 this._mouseDestroy(); 3896 3897 var wrapper, 3898 _destroy = function( exp ) { 3899 $( exp ) 3900 .removeData( "resizable" ) 3901 .removeData( "ui-resizable" ) 3902 .off( ".resizable" ) 3903 .find( ".ui-resizable-handle" ) 3904 .remove(); 3905 }; 3906 3907 // TODO: Unwrap at same DOM position 3908 if ( this.elementIsWrapper ) { 3909 _destroy( this.element ); 3910 wrapper = this.element; 3911 this.originalElement.css( { 3912 position: wrapper.css( "position" ), 3913 width: wrapper.outerWidth(), 3914 height: wrapper.outerHeight(), 3915 top: wrapper.css( "top" ), 3916 left: wrapper.css( "left" ) 3917 } ).insertAfter( wrapper ); 3918 wrapper.remove(); 3919 } 3920 3921 this.originalElement.css( "resize", this.originalResizeStyle ); 3922 _destroy( this.originalElement ); 3923 3924 return this; 3925 }, 3926 3927 _setOption: function( key, value ) { 3928 this._super( key, value ); 3929 3930 switch ( key ) { 3931 case "handles": 3932 this._removeHandles(); 3933 this._setupHandles(); 3934 break; 3935 default: 3936 break; 3937 } 3938 }, 3939 3940 _setupHandles: function() { 3941 var o = this.options, handle, i, n, hname, axis, that = this; 3942 this.handles = o.handles || 3943 ( !$( ".ui-resizable-handle", this.element ).length ? 3944 "e,s,se" : { 3945 n: ".ui-resizable-n", 3946 e: ".ui-resizable-e", 3947 s: ".ui-resizable-s", 3948 w: ".ui-resizable-w", 3949 se: ".ui-resizable-se", 3950 sw: ".ui-resizable-sw", 3951 ne: ".ui-resizable-ne", 3952 nw: ".ui-resizable-nw" 3953 } ); 3954 3955 this._handles = $(); 3956 if ( this.handles.constructor === String ) { 3957 3958 if ( this.handles === "all" ) { 3959 this.handles = "n,e,s,w,se,sw,ne,nw"; 3960 } 3961 3962 n = this.handles.split( "," ); 3963 this.handles = {}; 3964 3965 for ( i = 0; i < n.length; i++ ) { 3966 3967 handle = $.trim( n[ i ] ); 3968 hname = "ui-resizable-" + handle; 3969 axis = $( "<div>" ); 3970 this._addClass( axis, "ui-resizable-handle " + hname ); 3971 3972 axis.css( { zIndex: o.zIndex } ); 3973 3974 this.handles[ handle ] = ".ui-resizable-" + handle; 3975 this.element.append( axis ); 3976 } 3977 3978 } 3979 3980 this._renderAxis = function( target ) { 3981 3982 var i, axis, padPos, padWrapper; 3983 3984 target = target || this.element; 3985 3986 for ( i in this.handles ) { 3987 3988 if ( this.handles[ i ].constructor === String ) { 3989 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 3990 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 3991 this.handles[ i ] = $( this.handles[ i ] ); 3992 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 3993 } 3994 3995 if ( this.elementIsWrapper && 3996 this.originalElement[ 0 ] 3997 .nodeName 3998 .match( /^(textarea|input|select|button)$/i ) ) { 3999 axis = $( this.handles[ i ], this.element ); 4000 4001 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 4002 axis.outerHeight() : 4003 axis.outerWidth(); 4004 4005 padPos = [ "padding", 4006 /ne|nw|n/.test( i ) ? "Top" : 4007 /se|sw|s/.test( i ) ? "Bottom" : 4008 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 4009 4010 target.css( padPos, padWrapper ); 4011 4012 this._proportionallyResize(); 4013 } 4014 4015 this._handles = this._handles.add( this.handles[ i ] ); 4016 } 4017 }; 4018 4019 // TODO: make renderAxis a prototype function 4020 this._renderAxis( this.element ); 4021 4022 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 4023 this._handles.disableSelection(); 4024 4025 this._handles.on( "mouseover", function() { 4026 if ( !that.resizing ) { 4027 if ( this.className ) { 4028 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 4029 } 4030 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 4031 } 4032 } ); 4033 4034 if ( o.autoHide ) { 4035 this._handles.hide(); 4036 this._addClass( "ui-resizable-autohide" ); 4037 } 4038 }, 4039 4040 _removeHandles: function() { 4041 this._handles.remove(); 4042 }, 4043 4044 _mouseCapture: function( event ) { 4045 var i, handle, 4046 capture = false; 4047 4048 for ( i in this.handles ) { 4049 handle = $( this.handles[ i ] )[ 0 ]; 4050 if ( handle === event.target || $.contains( handle, event.target ) ) { 4051 capture = true; 4052 } 4053 } 4054 4055 return !this.options.disabled && capture; 4056 }, 4057 4058 _mouseStart: function( event ) { 4059 4060 var curleft, curtop, cursor, 4061 o = this.options, 4062 el = this.element; 4063 4064 this.resizing = true; 4065 4066 this._renderProxy(); 4067 4068 curleft = this._num( this.helper.css( "left" ) ); 4069 curtop = this._num( this.helper.css( "top" ) ); 4070 4071 if ( o.containment ) { 4072 curleft += $( o.containment ).scrollLeft() || 0; 4073 curtop += $( o.containment ).scrollTop() || 0; 4074 } 4075 4076 this.offset = this.helper.offset(); 4077 this.position = { left: curleft, top: curtop }; 4078 4079 this.size = this._helper ? { 4080 width: this.helper.width(), 4081 height: this.helper.height() 4082 } : { 4083 width: el.width(), 4084 height: el.height() 4085 }; 4086 4087 this.originalSize = this._helper ? { 4088 width: el.outerWidth(), 4089 height: el.outerHeight() 4090 } : { 4091 width: el.width(), 4092 height: el.height() 4093 }; 4094 4095 this.sizeDiff = { 4096 width: el.outerWidth() - el.width(), 4097 height: el.outerHeight() - el.height() 4098 }; 4099 4100 this.originalPosition = { left: curleft, top: curtop }; 4101 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 4102 4103 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 4104 o.aspectRatio : 4105 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 4106 4107 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 4108 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 4109 4110 this._addClass( "ui-resizable-resizing" ); 4111 this._propagate( "start", event ); 4112 return true; 4113 }, 4114 4115 _mouseDrag: function( event ) { 4116 4117 var data, props, 4118 smp = this.originalMousePosition, 4119 a = this.axis, 4120 dx = ( event.pageX - smp.left ) || 0, 4121 dy = ( event.pageY - smp.top ) || 0, 4122 trigger = this._change[ a ]; 4123 4124 this._updatePrevProperties(); 4125 4126 if ( !trigger ) { 4127 return false; 4128 } 4129 4130 data = trigger.apply( this, [ event, dx, dy ] ); 4131 4132 this._updateVirtualBoundaries( event.shiftKey ); 4133 if ( this._aspectRatio || event.shiftKey ) { 4134 data = this._updateRatio( data, event ); 4135 } 4136 4137 data = this._respectSize( data, event ); 4138 4139 this._updateCache( data ); 4140 4141 this._propagate( "resize", event ); 4142 4143 props = this._applyChanges(); 4144 4145 if ( !this._helper && this._proportionallyResizeElements.length ) { 4146 this._proportionallyResize(); 4147 } 4148 4149 if ( !$.isEmptyObject( props ) ) { 4150 this._updatePrevProperties(); 4151 this._trigger( "resize", event, this.ui() ); 4152 this._applyChanges(); 4153 } 4154 4155 return false; 4156 }, 4157 4158 _mouseStop: function( event ) { 4159 4160 this.resizing = false; 4161 var pr, ista, soffseth, soffsetw, s, left, top, 4162 o = this.options, that = this; 4163 4164 if ( this._helper ) { 4165 4166 pr = this._proportionallyResizeElements; 4167 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 4168 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 4169 soffsetw = ista ? 0 : that.sizeDiff.width; 4170 4171 s = { 4172 width: ( that.helper.width() - soffsetw ), 4173 height: ( that.helper.height() - soffseth ) 4174 }; 4175 left = ( parseFloat( that.element.css( "left" ) ) + 4176 ( that.position.left - that.originalPosition.left ) ) || null; 4177 top = ( parseFloat( that.element.css( "top" ) ) + 4178 ( that.position.top - that.originalPosition.top ) ) || null; 4179 4180 if ( !o.animate ) { 4181 this.element.css( $.extend( s, { top: top, left: left } ) ); 4182 } 4183 4184 that.helper.height( that.size.height ); 4185 that.helper.width( that.size.width ); 4186 4187 if ( this._helper && !o.animate ) { 4188 this._proportionallyResize(); 4189 } 4190 } 4191 4192 $( "body" ).css( "cursor", "auto" ); 4193 4194 this._removeClass( "ui-resizable-resizing" ); 4195 4196 this._propagate( "stop", event ); 4197 4198 if ( this._helper ) { 4199 this.helper.remove(); 4200 } 4201 4202 return false; 4203 4204 }, 4205 4206 _updatePrevProperties: function() { 4207 this.prevPosition = { 4208 top: this.position.top, 4209 left: this.position.left 4210 }; 4211 this.prevSize = { 4212 width: this.size.width, 4213 height: this.size.height 4214 }; 4215 }, 4216 4217 _applyChanges: function() { 4218 var props = {}; 4219 4220 if ( this.position.top !== this.prevPosition.top ) { 4221 props.top = this.position.top + "px"; 4222 } 4223 if ( this.position.left !== this.prevPosition.left ) { 4224 props.left = this.position.left + "px"; 4225 } 4226 if ( this.size.width !== this.prevSize.width ) { 4227 props.width = this.size.width + "px"; 4228 } 4229 if ( this.size.height !== this.prevSize.height ) { 4230 props.height = this.size.height + "px"; 4231 } 4232 4233 this.helper.css( props ); 4234 4235 return props; 4236 }, 4237 4238 _updateVirtualBoundaries: function( forceAspectRatio ) { 4239 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 4240 o = this.options; 4241 4242 b = { 4243 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 4244 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 4245 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 4246 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 4247 }; 4248 4249 if ( this._aspectRatio || forceAspectRatio ) { 4250 pMinWidth = b.minHeight * this.aspectRatio; 4251 pMinHeight = b.minWidth / this.aspectRatio; 4252 pMaxWidth = b.maxHeight * this.aspectRatio; 4253 pMaxHeight = b.maxWidth / this.aspectRatio; 4254 4255 if ( pMinWidth > b.minWidth ) { 4256 b.minWidth = pMinWidth; 4257 } 4258 if ( pMinHeight > b.minHeight ) { 4259 b.minHeight = pMinHeight; 4260 } 4261 if ( pMaxWidth < b.maxWidth ) { 4262 b.maxWidth = pMaxWidth; 4263 } 4264 if ( pMaxHeight < b.maxHeight ) { 4265 b.maxHeight = pMaxHeight; 4266 } 4267 } 4268 this._vBoundaries = b; 4269 }, 4270 4271 _updateCache: function( data ) { 4272 this.offset = this.helper.offset(); 4273 if ( this._isNumber( data.left ) ) { 4274 this.position.left = data.left; 4275 } 4276 if ( this._isNumber( data.top ) ) { 4277 this.position.top = data.top; 4278 } 4279 if ( this._isNumber( data.height ) ) { 4280 this.size.height = data.height; 4281 } 4282 if ( this._isNumber( data.width ) ) { 4283 this.size.width = data.width; 4284 } 4285 }, 4286 4287 _updateRatio: function( data ) { 4288 4289 var cpos = this.position, 4290 csize = this.size, 4291 a = this.axis; 4292 4293 if ( this._isNumber( data.height ) ) { 4294 data.width = ( data.height * this.aspectRatio ); 4295 } else if ( this._isNumber( data.width ) ) { 4296 data.height = ( data.width / this.aspectRatio ); 4297 } 4298 4299 if ( a === "sw" ) { 4300 data.left = cpos.left + ( csize.width - data.width ); 4301 data.top = null; 4302 } 4303 if ( a === "nw" ) { 4304 data.top = cpos.top + ( csize.height - data.height ); 4305 data.left = cpos.left + ( csize.width - data.width ); 4306 } 4307 4308 return data; 4309 }, 4310 4311 _respectSize: function( data ) { 4312 4313 var o = this._vBoundaries, 4314 a = this.axis, 4315 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 4316 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 4317 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 4318 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 4319 dw = this.originalPosition.left + this.originalSize.width, 4320 dh = this.originalPosition.top + this.originalSize.height, 4321 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 4322 if ( isminw ) { 4323 data.width = o.minWidth; 4324 } 4325 if ( isminh ) { 4326 data.height = o.minHeight; 4327 } 4328 if ( ismaxw ) { 4329 data.width = o.maxWidth; 4330 } 4331 if ( ismaxh ) { 4332 data.height = o.maxHeight; 4333 } 4334 4335 if ( isminw && cw ) { 4336 data.left = dw - o.minWidth; 4337 } 4338 if ( ismaxw && cw ) { 4339 data.left = dw - o.maxWidth; 4340 } 4341 if ( isminh && ch ) { 4342 data.top = dh - o.minHeight; 4343 } 4344 if ( ismaxh && ch ) { 4345 data.top = dh - o.maxHeight; 4346 } 4347 4348 // Fixing jump error on top/left - bug #2330 4349 if ( !data.width && !data.height && !data.left && data.top ) { 4350 data.top = null; 4351 } else if ( !data.width && !data.height && !data.top && data.left ) { 4352 data.left = null; 4353 } 4354 4355 return data; 4356 }, 4357 4358 _getPaddingPlusBorderDimensions: function( element ) { 4359 var i = 0, 4360 widths = [], 4361 borders = [ 4362 element.css( "borderTopWidth" ), 4363 element.css( "borderRightWidth" ), 4364 element.css( "borderBottomWidth" ), 4365 element.css( "borderLeftWidth" ) 4366 ], 4367 paddings = [ 4368 element.css( "paddingTop" ), 4369 element.css( "paddingRight" ), 4370 element.css( "paddingBottom" ), 4371 element.css( "paddingLeft" ) 4372 ]; 4373 4374 for ( ; i < 4; i++ ) { 4375 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 4376 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 4377 } 4378 4379 return { 4380 height: widths[ 0 ] + widths[ 2 ], 4381 width: widths[ 1 ] + widths[ 3 ] 4382 }; 4383 }, 4384 4385 _proportionallyResize: function() { 4386 4387 if ( !this._proportionallyResizeElements.length ) { 4388 return; 4389 } 4390 4391 var prel, 4392 i = 0, 4393 element = this.helper || this.element; 4394 4395 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 4396 4397 prel = this._proportionallyResizeElements[ i ]; 4398 4399 // TODO: Seems like a bug to cache this.outerDimensions 4400 // considering that we are in a loop. 4401 if ( !this.outerDimensions ) { 4402 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 4403 } 4404 4405 prel.css( { 4406 height: ( element.height() - this.outerDimensions.height ) || 0, 4407 width: ( element.width() - this.outerDimensions.width ) || 0 4408 } ); 4409 4410 } 4411 4412 }, 4413 4414 _renderProxy: function() { 4415 4416 var el = this.element, o = this.options; 4417 this.elementOffset = el.offset(); 4418 4419 if ( this._helper ) { 4420 4421 this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" ); 4422 4423 this._addClass( this.helper, this._helper ); 4424 this.helper.css( { 4425 width: this.element.outerWidth(), 4426 height: this.element.outerHeight(), 4427 position: "absolute", 4428 left: this.elementOffset.left + "px", 4429 top: this.elementOffset.top + "px", 4430 zIndex: ++o.zIndex //TODO: Don't modify option 4431 } ); 4432 4433 this.helper 4434 .appendTo( "body" ) 4435 .disableSelection(); 4436 4437 } else { 4438 this.helper = this.element; 4439 } 4440 4441 }, 4442 4443 _change: { 4444 e: function( event, dx ) { 4445 return { width: this.originalSize.width + dx }; 4446 }, 4447 w: function( event, dx ) { 4448 var cs = this.originalSize, sp = this.originalPosition; 4449 return { left: sp.left + dx, width: cs.width - dx }; 4450 }, 4451 n: function( event, dx, dy ) { 4452 var cs = this.originalSize, sp = this.originalPosition; 4453 return { top: sp.top + dy, height: cs.height - dy }; 4454 }, 4455 s: function( event, dx, dy ) { 4456 return { height: this.originalSize.height + dy }; 4457 }, 4458 se: function( event, dx, dy ) { 4459 return $.extend( this._change.s.apply( this, arguments ), 4460 this._change.e.apply( this, [ event, dx, dy ] ) ); 4461 }, 4462 sw: function( event, dx, dy ) { 4463 return $.extend( this._change.s.apply( this, arguments ), 4464 this._change.w.apply( this, [ event, dx, dy ] ) ); 4465 }, 4466 ne: function( event, dx, dy ) { 4467 return $.extend( this._change.n.apply( this, arguments ), 4468 this._change.e.apply( this, [ event, dx, dy ] ) ); 4469 }, 4470 nw: function( event, dx, dy ) { 4471 return $.extend( this._change.n.apply( this, arguments ), 4472 this._change.w.apply( this, [ event, dx, dy ] ) ); 4473 } 4474 }, 4475 4476 _propagate: function( n, event ) { 4477 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 4478 ( n !== "resize" && this._trigger( n, event, this.ui() ) ); 4479 }, 4480 4481 plugins: {}, 4482 4483 ui: function() { 4484 return { 4485 originalElement: this.originalElement, 4486 element: this.element, 4487 helper: this.helper, 4488 position: this.position, 4489 size: this.size, 4490 originalSize: this.originalSize, 4491 originalPosition: this.originalPosition 4492 }; 4493 } 4494 4495} ); 4496 4497/* 4498 * Resizable Extensions 4499 */ 4500 4501$.ui.plugin.add( "resizable", "animate", { 4502 4503 stop: function( event ) { 4504 var that = $( this ).resizable( "instance" ), 4505 o = that.options, 4506 pr = that._proportionallyResizeElements, 4507 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 4508 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 4509 soffsetw = ista ? 0 : that.sizeDiff.width, 4510 style = { 4511 width: ( that.size.width - soffsetw ), 4512 height: ( that.size.height - soffseth ) 4513 }, 4514 left = ( parseFloat( that.element.css( "left" ) ) + 4515 ( that.position.left - that.originalPosition.left ) ) || null, 4516 top = ( parseFloat( that.element.css( "top" ) ) + 4517 ( that.position.top - that.originalPosition.top ) ) || null; 4518 4519 that.element.animate( 4520 $.extend( style, top && left ? { top: top, left: left } : {} ), { 4521 duration: o.animateDuration, 4522 easing: o.animateEasing, 4523 step: function() { 4524 4525 var data = { 4526 width: parseFloat( that.element.css( "width" ) ), 4527 height: parseFloat( that.element.css( "height" ) ), 4528 top: parseFloat( that.element.css( "top" ) ), 4529 left: parseFloat( that.element.css( "left" ) ) 4530 }; 4531 4532 if ( pr && pr.length ) { 4533 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 4534 } 4535 4536 // Propagating resize, and updating values for each animation step 4537 that._updateCache( data ); 4538 that._propagate( "resize", event ); 4539 4540 } 4541 } 4542 ); 4543 } 4544 4545} ); 4546 4547$.ui.plugin.add( "resizable", "containment", { 4548 4549 start: function() { 4550 var element, p, co, ch, cw, width, height, 4551 that = $( this ).resizable( "instance" ), 4552 o = that.options, 4553 el = that.element, 4554 oc = o.containment, 4555 ce = ( oc instanceof $ ) ? 4556 oc.get( 0 ) : 4557 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 4558 4559 if ( !ce ) { 4560 return; 4561 } 4562 4563 that.containerElement = $( ce ); 4564 4565 if ( /document/.test( oc ) || oc === document ) { 4566 that.containerOffset = { 4567 left: 0, 4568 top: 0 4569 }; 4570 that.containerPosition = { 4571 left: 0, 4572 top: 0 4573 }; 4574 4575 that.parentData = { 4576 element: $( document ), 4577 left: 0, 4578 top: 0, 4579 width: $( document ).width(), 4580 height: $( document ).height() || document.body.parentNode.scrollHeight 4581 }; 4582 } else { 4583 element = $( ce ); 4584 p = []; 4585 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 4586 p[ i ] = that._num( element.css( "padding" + name ) ); 4587 } ); 4588 4589 that.containerOffset = element.offset(); 4590 that.containerPosition = element.position(); 4591 that.containerSize = { 4592 height: ( element.innerHeight() - p[ 3 ] ), 4593 width: ( element.innerWidth() - p[ 1 ] ) 4594 }; 4595 4596 co = that.containerOffset; 4597 ch = that.containerSize.height; 4598 cw = that.containerSize.width; 4599 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 4600 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 4601 4602 that.parentData = { 4603 element: ce, 4604 left: co.left, 4605 top: co.top, 4606 width: width, 4607 height: height 4608 }; 4609 } 4610 }, 4611 4612 resize: function( event ) { 4613 var woset, hoset, isParent, isOffsetRelative, 4614 that = $( this ).resizable( "instance" ), 4615 o = that.options, 4616 co = that.containerOffset, 4617 cp = that.position, 4618 pRatio = that._aspectRatio || event.shiftKey, 4619 cop = { 4620 top: 0, 4621 left: 0 4622 }, 4623 ce = that.containerElement, 4624 continueResize = true; 4625 4626 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 4627 cop = co; 4628 } 4629 4630 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 4631 that.size.width = that.size.width + 4632 ( that._helper ? 4633 ( that.position.left - co.left ) : 4634 ( that.position.left - cop.left ) ); 4635 4636 if ( pRatio ) { 4637 that.size.height = that.size.width / that.aspectRatio; 4638 continueResize = false; 4639 } 4640 that.position.left = o.helper ? co.left : 0; 4641 } 4642 4643 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 4644 that.size.height = that.size.height + 4645 ( that._helper ? 4646 ( that.position.top - co.top ) : 4647 that.position.top ); 4648 4649 if ( pRatio ) { 4650 that.size.width = that.size.height * that.aspectRatio; 4651 continueResize = false; 4652 } 4653 that.position.top = that._helper ? co.top : 0; 4654 } 4655 4656 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 4657 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 4658 4659 if ( isParent && isOffsetRelative ) { 4660 that.offset.left = that.parentData.left + that.position.left; 4661 that.offset.top = that.parentData.top + that.position.top; 4662 } else { 4663 that.offset.left = that.element.offset().left; 4664 that.offset.top = that.element.offset().top; 4665 } 4666 4667 woset = Math.abs( that.sizeDiff.width + 4668 ( that._helper ? 4669 that.offset.left - cop.left : 4670 ( that.offset.left - co.left ) ) ); 4671 4672 hoset = Math.abs( that.sizeDiff.height + 4673 ( that._helper ? 4674 that.offset.top - cop.top : 4675 ( that.offset.top - co.top ) ) ); 4676 4677 if ( woset + that.size.width >= that.parentData.width ) { 4678 that.size.width = that.parentData.width - woset; 4679 if ( pRatio ) { 4680 that.size.height = that.size.width / that.aspectRatio; 4681 continueResize = false; 4682 } 4683 } 4684 4685 if ( hoset + that.size.height >= that.parentData.height ) { 4686 that.size.height = that.parentData.height - hoset; 4687 if ( pRatio ) { 4688 that.size.width = that.size.height * that.aspectRatio; 4689 continueResize = false; 4690 } 4691 } 4692 4693 if ( !continueResize ) { 4694 that.position.left = that.prevPosition.left; 4695 that.position.top = that.prevPosition.top; 4696 that.size.width = that.prevSize.width; 4697 that.size.height = that.prevSize.height; 4698 } 4699 }, 4700 4701 stop: function() { 4702 var that = $( this ).resizable( "instance" ), 4703 o = that.options, 4704 co = that.containerOffset, 4705 cop = that.containerPosition, 4706 ce = that.containerElement, 4707 helper = $( that.helper ), 4708 ho = helper.offset(), 4709 w = helper.outerWidth() - that.sizeDiff.width, 4710 h = helper.outerHeight() - that.sizeDiff.height; 4711 4712 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 4713 $( this ).css( { 4714 left: ho.left - cop.left - co.left, 4715 width: w, 4716 height: h 4717 } ); 4718 } 4719 4720 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 4721 $( this ).css( { 4722 left: ho.left - cop.left - co.left, 4723 width: w, 4724 height: h 4725 } ); 4726 } 4727 } 4728} ); 4729 4730$.ui.plugin.add( "resizable", "alsoResize", { 4731 4732 start: function() { 4733 var that = $( this ).resizable( "instance" ), 4734 o = that.options; 4735 4736 $( o.alsoResize ).each( function() { 4737 var el = $( this ); 4738 el.data( "ui-resizable-alsoresize", { 4739 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 4740 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 4741 } ); 4742 } ); 4743 }, 4744 4745 resize: function( event, ui ) { 4746 var that = $( this ).resizable( "instance" ), 4747 o = that.options, 4748 os = that.originalSize, 4749 op = that.originalPosition, 4750 delta = { 4751 height: ( that.size.height - os.height ) || 0, 4752 width: ( that.size.width - os.width ) || 0, 4753 top: ( that.position.top - op.top ) || 0, 4754 left: ( that.position.left - op.left ) || 0 4755 }; 4756 4757 $( o.alsoResize ).each( function() { 4758 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 4759 css = el.parents( ui.originalElement[ 0 ] ).length ? 4760 [ "width", "height" ] : 4761 [ "width", "height", "top", "left" ]; 4762 4763 $.each( css, function( i, prop ) { 4764 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 4765 if ( sum && sum >= 0 ) { 4766 style[ prop ] = sum || null; 4767 } 4768 } ); 4769 4770 el.css( style ); 4771 } ); 4772 }, 4773 4774 stop: function() { 4775 $( this ).removeData( "ui-resizable-alsoresize" ); 4776 } 4777} ); 4778 4779$.ui.plugin.add( "resizable", "ghost", { 4780 4781 start: function() { 4782 4783 var that = $( this ).resizable( "instance" ), cs = that.size; 4784 4785 that.ghost = that.originalElement.clone(); 4786 that.ghost.css( { 4787 opacity: 0.25, 4788 display: "block", 4789 position: "relative", 4790 height: cs.height, 4791 width: cs.width, 4792 margin: 0, 4793 left: 0, 4794 top: 0 4795 } ); 4796 4797 that._addClass( that.ghost, "ui-resizable-ghost" ); 4798 4799 // DEPRECATED 4800 // TODO: remove after 1.12 4801 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 4802 4803 // Ghost option 4804 that.ghost.addClass( this.options.ghost ); 4805 } 4806 4807 that.ghost.appendTo( that.helper ); 4808 4809 }, 4810 4811 resize: function() { 4812 var that = $( this ).resizable( "instance" ); 4813 if ( that.ghost ) { 4814 that.ghost.css( { 4815 position: "relative", 4816 height: that.size.height,
vendor: 13,664 bytes, lines 4817-5361
4817 width: that.size.width 4818 } ); 4819 } 4820 }, 4821 4822 stop: function() { 4823 var that = $( this ).resizable( "instance" ); 4824 if ( that.ghost && that.helper ) { 4825 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 4826 } 4827 } 4828 4829} ); 4830 4831$.ui.plugin.add( "resizable", "grid", { 4832 4833 resize: function() { 4834 var outerDimensions, 4835 that = $( this ).resizable( "instance" ), 4836 o = that.options, 4837 cs = that.size, 4838 os = that.originalSize, 4839 op = that.originalPosition, 4840 a = that.axis, 4841 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4842 gridX = ( grid[ 0 ] || 1 ), 4843 gridY = ( grid[ 1 ] || 1 ), 4844 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 4845 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 4846 newWidth = os.width + ox, 4847 newHeight = os.height + oy, 4848 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 4849 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 4850 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 4851 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 4852 4853 o.grid = grid; 4854 4855 if ( isMinWidth ) { 4856 newWidth += gridX; 4857 } 4858 if ( isMinHeight ) { 4859 newHeight += gridY; 4860 } 4861 if ( isMaxWidth ) { 4862 newWidth -= gridX; 4863 } 4864 if ( isMaxHeight ) { 4865 newHeight -= gridY; 4866 } 4867 4868 if ( /^(se|s|e)$/.test( a ) ) { 4869 that.size.width = newWidth; 4870 that.size.height = newHeight; 4871 } else if ( /^(ne)$/.test( a ) ) { 4872 that.size.width = newWidth; 4873 that.size.height = newHeight; 4874 that.position.top = op.top - oy; 4875 } else if ( /^(sw)$/.test( a ) ) { 4876 that.size.width = newWidth; 4877 that.size.height = newHeight; 4878 that.position.left = op.left - ox; 4879 } else { 4880 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 4881 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4882 } 4883 4884 if ( newHeight - gridY > 0 ) { 4885 that.size.height = newHeight; 4886 that.position.top = op.top - oy; 4887 } else { 4888 newHeight = gridY - outerDimensions.height; 4889 that.size.height = newHeight; 4890 that.position.top = op.top + os.height - newHeight; 4891 } 4892 if ( newWidth - gridX > 0 ) { 4893 that.size.width = newWidth; 4894 that.position.left = op.left - ox; 4895 } else { 4896 newWidth = gridX - outerDimensions.width; 4897 that.size.width = newWidth; 4898 that.position.left = op.left + os.width - newWidth; 4899 } 4900 } 4901 } 4902 4903} ); 4904 4905var widgetsResizable = $.ui.resizable; 4906 4907 4908/*! 4909 * jQuery UI Selectable 1.12.1 4910 * http://jqueryui.com 4911 * 4912 * Copyright jQuery Foundation and other contributors 4913 * Released under the MIT license. 4914 * http://jquery.org/license 4915 */ 4916 4917//>>label: Selectable 4918//>>group: Interactions 4919//>>description: Allows groups of elements to be selected with the mouse. 4920//>>docs: http://api.jqueryui.com/selectable/ 4921//>>demos: http://jqueryui.com/selectable/ 4922//>>css.structure: ../../themes/base/selectable.css 4923 4924 4925 4926var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 4927 version: "1.12.1", 4928 options: { 4929 appendTo: "body", 4930 autoRefresh: true, 4931 distance: 0, 4932 filter: "*", 4933 tolerance: "touch", 4934 4935 // Callbacks 4936 selected: null, 4937 selecting: null, 4938 start: null, 4939 stop: null, 4940 unselected: null, 4941 unselecting: null 4942 }, 4943 _create: function() { 4944 var that = this; 4945 4946 this._addClass( "ui-selectable" ); 4947 4948 this.dragged = false; 4949 4950 // Cache selectee children based on filter 4951 this.refresh = function() { 4952 that.elementPos = $( that.element[ 0 ] ).offset(); 4953 that.selectees = $( that.options.filter, that.element[ 0 ] ); 4954 that._addClass( that.selectees, "ui-selectee" ); 4955 that.selectees.each( function() { 4956 var $this = $( this ), 4957 selecteeOffset = $this.offset(), 4958 pos = { 4959 left: selecteeOffset.left - that.elementPos.left, 4960 top: selecteeOffset.top - that.elementPos.top 4961 }; 4962 $.data( this, "selectable-item", { 4963 element: this, 4964 $element: $this, 4965 left: pos.left, 4966 top: pos.top, 4967 right: pos.left + $this.outerWidth(), 4968 bottom: pos.top + $this.outerHeight(), 4969 startselected: false, 4970 selected: $this.hasClass( "ui-selected" ), 4971 selecting: $this.hasClass( "ui-selecting" ), 4972 unselecting: $this.hasClass( "ui-unselecting" ) 4973 } ); 4974 } ); 4975 }; 4976 this.refresh(); 4977 4978 this._mouseInit(); 4979 4980 this.helper = $( "<div>" ); 4981 this._addClass( this.helper, "ui-selectable-helper" ); 4982 }, 4983 4984 _destroy: function() { 4985 this.selectees.removeData( "selectable-item" ); 4986 this._mouseDestroy(); 4987 }, 4988 4989 _mouseStart: function( event ) { 4990 var that = this, 4991 options = this.options; 4992 4993 this.opos = [ event.pageX, event.pageY ]; 4994 this.elementPos = $( this.element[ 0 ] ).offset(); 4995 4996 if ( this.options.disabled ) { 4997 return; 4998 } 4999 5000 this.selectees = $( options.filter, this.element[ 0 ] ); 5001 5002 this._trigger( "start", event ); 5003 5004 $( options.appendTo ).append( this.helper ); 5005 5006 // position helper (lasso) 5007 this.helper.css( { 5008 "left": event.pageX, 5009 "top": event.pageY, 5010 "width": 0, 5011 "height": 0 5012 } ); 5013 5014 if ( options.autoRefresh ) { 5015 this.refresh(); 5016 } 5017 5018 this.selectees.filter( ".ui-selected" ).each( function() { 5019 var selectee = $.data( this, "selectable-item" ); 5020 selectee.startselected = true; 5021 if ( !event.metaKey && !event.ctrlKey ) { 5022 that._removeClass( selectee.$element, "ui-selected" ); 5023 selectee.selected = false; 5024 that._addClass( selectee.$element, "ui-unselecting" ); 5025 selectee.unselecting = true; 5026 5027 // selectable UNSELECTING callback 5028 that._trigger( "unselecting", event, { 5029 unselecting: selectee.element 5030 } ); 5031 } 5032 } ); 5033 5034 $( event.target ).parents().addBack().each( function() { 5035 var doSelect, 5036 selectee = $.data( this, "selectable-item" ); 5037 if ( selectee ) { 5038 doSelect = ( !event.metaKey && !event.ctrlKey ) || 5039 !selectee.$element.hasClass( "ui-selected" ); 5040 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 5041 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 5042 selectee.unselecting = !doSelect; 5043 selectee.selecting = doSelect; 5044 selectee.selected = doSelect; 5045 5046 // selectable (UN)SELECTING callback 5047 if ( doSelect ) { 5048 that._trigger( "selecting", event, { 5049 selecting: selectee.element 5050 } ); 5051 } else { 5052 that._trigger( "unselecting", event, { 5053 unselecting: selectee.element 5054 } ); 5055 } 5056 return false; 5057 } 5058 } ); 5059 5060 }, 5061 5062 _mouseDrag: function( event ) { 5063 5064 this.dragged = true; 5065 5066 if ( this.options.disabled ) { 5067 return; 5068 } 5069 5070 var tmp, 5071 that = this, 5072 options = this.options, 5073 x1 = this.opos[ 0 ], 5074 y1 = this.opos[ 1 ], 5075 x2 = event.pageX, 5076 y2 = event.pageY; 5077 5078 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; } 5079 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; } 5080 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 5081 5082 this.selectees.each( function() { 5083 var selectee = $.data( this, "selectable-item" ), 5084 hit = false, 5085 offset = {}; 5086 5087 //prevent helper from being selected if appendTo: selectable 5088 if ( !selectee || selectee.element === that.element[ 0 ] ) { 5089 return; 5090 } 5091 5092 offset.left = selectee.left + that.elementPos.left; 5093 offset.right = selectee.right + that.elementPos.left; 5094 offset.top = selectee.top + that.elementPos.top; 5095 offset.bottom = selectee.bottom + that.elementPos.top; 5096 5097 if ( options.tolerance === "touch" ) { 5098 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 5099 offset.bottom < y1 ) ); 5100 } else if ( options.tolerance === "fit" ) { 5101 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 5102 offset.bottom < y2 ); 5103 } 5104 5105 if ( hit ) { 5106 5107 // SELECT 5108 if ( selectee.selected ) { 5109 that._removeClass( selectee.$element, "ui-selected" ); 5110 selectee.selected = false; 5111 } 5112 if ( selectee.unselecting ) { 5113 that._removeClass( selectee.$element, "ui-unselecting" ); 5114 selectee.unselecting = false; 5115 } 5116 if ( !selectee.selecting ) { 5117 that._addClass( selectee.$element, "ui-selecting" ); 5118 selectee.selecting = true; 5119 5120 // selectable SELECTING callback 5121 that._trigger( "selecting", event, { 5122 selecting: selectee.element 5123 } ); 5124 } 5125 } else { 5126 5127 // UNSELECT 5128 if ( selectee.selecting ) { 5129 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 5130 that._removeClass( selectee.$element, "ui-selecting" ); 5131 selectee.selecting = false; 5132 that._addClass( selectee.$element, "ui-selected" ); 5133 selectee.selected = true; 5134 } else { 5135 that._removeClass( selectee.$element, "ui-selecting" ); 5136 selectee.selecting = false; 5137 if ( selectee.startselected ) { 5138 that._addClass( selectee.$element, "ui-unselecting" ); 5139 selectee.unselecting = true; 5140 } 5141 5142 // selectable UNSELECTING callback 5143 that._trigger( "unselecting", event, { 5144 unselecting: selectee.element 5145 } ); 5146 } 5147 } 5148 if ( selectee.selected ) { 5149 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 5150 that._removeClass( selectee.$element, "ui-selected" ); 5151 selectee.selected = false; 5152 5153 that._addClass( selectee.$element, "ui-unselecting" ); 5154 selectee.unselecting = true; 5155 5156 // selectable UNSELECTING callback 5157 that._trigger( "unselecting", event, { 5158 unselecting: selectee.element 5159 } ); 5160 } 5161 } 5162 } 5163 } ); 5164 5165 return false; 5166 }, 5167 5168 _mouseStop: function( event ) { 5169 var that = this; 5170 5171 this.dragged = false; 5172 5173 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 5174 var selectee = $.data( this, "selectable-item" ); 5175 that._removeClass( selectee.$element, "ui-unselecting" ); 5176 selectee.unselecting = false; 5177 selectee.startselected = false; 5178 that._trigger( "unselected", event, { 5179 unselected: selectee.element 5180 } ); 5181 } ); 5182 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 5183 var selectee = $.data( this, "selectable-item" ); 5184 that._removeClass( selectee.$element, "ui-selecting" ) 5185 ._addClass( selectee.$element, "ui-selected" ); 5186 selectee.selecting = false; 5187 selectee.selected = true; 5188 selectee.startselected = true; 5189 that._trigger( "selected", event, { 5190 selected: selectee.element 5191 } ); 5192 } ); 5193 this._trigger( "stop", event ); 5194 5195 this.helper.remove(); 5196 5197 return false; 5198 } 5199 5200} ); 5201 5202 5203/*! 5204 * jQuery UI Sortable 1.12.1 5205 * http://jqueryui.com 5206 * 5207 * Copyright jQuery Foundation and other contributors 5208 * Released under the MIT license. 5209 * http://jquery.org/license 5210 */ 5211 5212//>>label: Sortable 5213//>>group: Interactions 5214//>>description: Enables items in a list to be sorted using the mouse. 5215//>>docs: http://api.jqueryui.com/sortable/ 5216//>>demos: http://jqueryui.com/sortable/ 5217//>>css.structure: ../../themes/base/sortable.css 5218 5219 5220 5221var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { 5222 version: "1.12.1", 5223 widgetEventPrefix: "sort", 5224 ready: false, 5225 options: { 5226 appendTo: "parent", 5227 axis: false, 5228 connectWith: false, 5229 containment: false, 5230 cursor: "auto", 5231 cursorAt: false, 5232 dropOnEmpty: true, 5233 forcePlaceholderSize: false, 5234 forceHelperSize: false, 5235 grid: false, 5236 handle: false, 5237 helper: "original", 5238 items: "> *", 5239 opacity: false, 5240 placeholder: false, 5241 revert: false, 5242 scroll: true, 5243 scrollSensitivity: 20, 5244 scrollSpeed: 20, 5245 scope: "default", 5246 tolerance: "intersect", 5247 zIndex: 1000, 5248 5249 // Callbacks 5250 activate: null, 5251 beforeStop: null, 5252 change: null, 5253 deactivate: null, 5254 out: null, 5255 over: null, 5256 receive: null, 5257 remove: null, 5258 sort: null, 5259 start: null, 5260 stop: null, 5261 update: null 5262 }, 5263 5264 _isOverAxis: function( x, reference, size ) { 5265 return ( x >= reference ) && ( x < ( reference + size ) ); 5266 }, 5267 5268 _isFloating: function( item ) { 5269 return ( /left|right/ ).test( item.css( "float" ) ) || 5270 ( /inline|table-cell/ ).test( item.css( "display" ) ); 5271 }, 5272 5273 _create: function() { 5274 this.containerCache = {}; 5275 this._addClass( "ui-sortable" ); 5276 5277 //Get the items 5278 this.refresh(); 5279 5280 //Let's determine the parent's offset 5281 this.offset = this.element.offset(); 5282 5283 //Initialize mouse events for interaction 5284 this._mouseInit(); 5285 5286 this._setHandleClassName(); 5287 5288 //We're ready to go 5289 this.ready = true; 5290 5291 }, 5292 5293 _setOption: function( key, value ) { 5294 this._super( key, value ); 5295 5296 if ( key === "handle" ) { 5297 this._setHandleClassName(); 5298 } 5299 }, 5300 5301 _setHandleClassName: function() { 5302 var that = this; 5303 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 5304 $.each( this.items, function() { 5305 that._addClass( 5306 this.instance.options.handle ? 5307 this.item.find( this.instance.options.handle ) : 5308 this.item, 5309 "ui-sortable-handle" 5310 ); 5311 } ); 5312 }, 5313 5314 _destroy: function() { 5315 this._mouseDestroy(); 5316 5317 for ( var i = this.items.length - 1; i >= 0; i-- ) { 5318 this.items[ i ].item.removeData( this.widgetName + "-item" ); 5319 } 5320 5321 return this; 5322 }, 5323 5324 _mouseCapture: function( event, overrideHandle ) { 5325 var currentItem = null, 5326 validHandle = false, 5327 that = this; 5328 5329 if ( this.reverting ) { 5330 return false; 5331 } 5332 5333 if ( this.options.disabled || this.options.type === "static" ) { 5334 return false; 5335 } 5336 5337 //We have to refresh the items data once first 5338 this._refreshItems( event ); 5339 5340 //Find out if the clicked node (or one of its parents) is a actual item in this.items 5341 $( event.target ).parents().each( function() { 5342 if ( $.data( this, that.widgetName + "-item" ) === that ) { 5343 currentItem = $( this ); 5344 return false; 5345 } 5346 } ); 5347 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 5348 currentItem = $( event.target ); 5349 } 5350 5351 if ( !currentItem ) { 5352 return false; 5353 } 5354 if ( this.options.handle && !overrideHandle ) { 5355 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 5356 if ( this === event.target ) { 5357 validHandle = true; 5358 } 5359 } ); 5360 if ( !validHandle ) { 5361 return false;
vendor: 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: 25,061 bytes, lines 13149-14131
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 Slider 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: Slider 13437//>>group: Widgets 13438//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 13439//>>docs: http://api.jqueryui.com/slider/ 13440//>>demos: http://jqueryui.com/slider/ 13441//>>css.structure: ../../themes/base/core.css 13442//>>css.structure: ../../themes/base/slider.css 13443//>>css.theme: ../../themes/base/theme.css 13444 13445 13446 13447var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 13448 version: "1.12.1", 13449 widgetEventPrefix: "slide", 13450 13451 options: { 13452 animate: false, 13453 classes: { 13454 "ui-slider": "ui-corner-all", 13455 "ui-slider-handle": "ui-corner-all", 13456 13457 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 13458 // element, but worked best visually with a variety of themes 13459 "ui-slider-range": "ui-corner-all ui-widget-header" 13460 }, 13461 distance: 0, 13462 max: 100, 13463 min: 0, 13464 orientation: "horizontal", 13465 range: false, 13466 step: 1, 13467 value: 0, 13468 values: null, 13469 13470 // Callbacks 13471 change: null, 13472 slide: null, 13473 start: null, 13474 stop: null 13475 }, 13476 13477 // Number of pages in a slider 13478 // (how many times can you page up/down to go through the whole range) 13479 numPages: 5, 13480 13481 _create: function() { 13482 this._keySliding = false; 13483 this._mouseSliding = false; 13484 this._animateOff = true; 13485 this._handleIndex = null; 13486 this._detectOrientation(); 13487 this._mouseInit(); 13488 this._calculateNewMax(); 13489 13490 this._addClass( "ui-slider ui-slider-" + this.orientation, 13491 "ui-widget ui-widget-content" ); 13492 13493 this._refresh(); 13494 13495 this._animateOff = false; 13496 }, 13497 13498 _refresh: function() { 13499 this._createRange(); 13500 this._createHandles(); 13501 this._setupEvents(); 13502 this._refreshValue(); 13503 }, 13504 13505 _createHandles: function() { 13506 var i, handleCount, 13507 options = this.options, 13508 existingHandles = this.element.find( ".ui-slider-handle" ), 13509 handle = "<span tabindex='0'></span>", 13510 handles = []; 13511 13512 handleCount = ( options.values && options.values.length ) || 1; 13513 13514 if ( existingHandles.length > handleCount ) { 13515 existingHandles.slice( handleCount ).remove(); 13516 existingHandles = existingHandles.slice( 0, handleCount ); 13517 } 13518 13519 for ( i = existingHandles.length; i < handleCount; i++ ) { 13520 handles.push( handle ); 13521 } 13522 13523 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13524 13525 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 13526 13527 this.handle = this.handles.eq( 0 ); 13528 13529 this.handles.each( function( i ) { 13530 $( this ) 13531 .data( "ui-slider-handle-index", i ) 13532 .attr( "tabIndex", 0 ); 13533 } ); 13534 }, 13535 13536 _createRange: function() { 13537 var options = this.options; 13538 13539 if ( options.range ) { 13540 if ( options.range === true ) { 13541 if ( !options.values ) { 13542 options.values = [ this._valueMin(), this._valueMin() ]; 13543 } else if ( options.values.length && options.values.length !== 2 ) { 13544 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 13545 } else if ( $.isArray( options.values ) ) { 13546 options.values = options.values.slice( 0 ); 13547 } 13548 } 13549 13550 if ( !this.range || !this.range.length ) { 13551 this.range = $( "<div>" ) 13552 .appendTo( this.element ); 13553 13554 this._addClass( this.range, "ui-slider-range" ); 13555 } else { 13556 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 13557 13558 // Handle range switching from true to min/max 13559 this.range.css( { 13560 "left": "", 13561 "bottom": "" 13562 } ); 13563 } 13564 if ( options.range === "min" || options.range === "max" ) { 13565 this._addClass( this.range, "ui-slider-range-" + options.range ); 13566 } 13567 } else { 13568 if ( this.range ) { 13569 this.range.remove(); 13570 } 13571 this.range = null; 13572 } 13573 }, 13574 13575 _setupEvents: function() { 13576 this._off( this.handles ); 13577 this._on( this.handles, this._handleEvents ); 13578 this._hoverable( this.handles ); 13579 this._focusable( this.handles ); 13580 }, 13581 13582 _destroy: function() { 13583 this.handles.remove(); 13584 if ( this.range ) { 13585 this.range.remove(); 13586 } 13587 13588 this._mouseDestroy(); 13589 }, 13590 13591 _mouseCapture: function( event ) { 13592 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 13593 that = this, 13594 o = this.options; 13595 13596 if ( o.disabled ) { 13597 return false; 13598 } 13599 13600 this.elementSize = { 13601 width: this.element.outerWidth(), 13602 height: this.element.outerHeight() 13603 }; 13604 this.elementOffset = this.element.offset(); 13605 13606 position = { x: event.pageX, y: event.pageY }; 13607 normValue = this._normValueFromMouse( position ); 13608 distance = this._valueMax() - this._valueMin() + 1; 13609 this.handles.each( function( i ) { 13610 var thisDistance = Math.abs( normValue - that.values( i ) ); 13611 if ( ( distance > thisDistance ) || 13612 ( distance === thisDistance && 13613 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 13614 distance = thisDistance; 13615 closestHandle = $( this ); 13616 index = i; 13617 } 13618 } ); 13619 13620 allowed = this._start( event, index ); 13621 if ( allowed === false ) { 13622 return false; 13623 } 13624 this._mouseSliding = true; 13625 13626 this._handleIndex = index; 13627 13628 this._addClass( closestHandle, null, "ui-state-active" ); 13629 closestHandle.trigger( "focus" ); 13630 13631 offset = closestHandle.offset(); 13632 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13633 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13634 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13635 top: event.pageY - offset.top - 13636 ( closestHandle.height() / 2 ) - 13637 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 13638 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 13639 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 13640 }; 13641 13642 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13643 this._slide( event, index, normValue ); 13644 } 13645 this._animateOff = true; 13646 return true; 13647 }, 13648 13649 _mouseStart: function() { 13650 return true; 13651 }, 13652 13653 _mouseDrag: function( event ) { 13654 var position = { x: event.pageX, y: event.pageY }, 13655 normValue = this._normValueFromMouse( position ); 13656 13657 this._slide( event, this._handleIndex, normValue ); 13658 13659 return false; 13660 }, 13661 13662 _mouseStop: function( event ) { 13663 this._removeClass( this.handles, null, "ui-state-active" ); 13664 this._mouseSliding = false; 13665 13666 this._stop( event, this._handleIndex ); 13667 this._change( event, this._handleIndex ); 13668 13669 this._handleIndex = null; 13670 this._clickOffset = null; 13671 this._animateOff = false; 13672 13673 return false; 13674 }, 13675 13676 _detectOrientation: function() { 13677 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13678 }, 13679 13680 _normValueFromMouse: function( position ) { 13681 var pixelTotal, 13682 pixelMouse, 13683 percentMouse, 13684 valueTotal, 13685 valueMouse; 13686 13687 if ( this.orientation === "horizontal" ) { 13688 pixelTotal = this.elementSize.width; 13689 pixelMouse = position.x - this.elementOffset.left - 13690 ( this._clickOffset ? this._clickOffset.left : 0 ); 13691 } else { 13692 pixelTotal = this.elementSize.height; 13693 pixelMouse = position.y - this.elementOffset.top - 13694 ( this._clickOffset ? this._clickOffset.top : 0 ); 13695 } 13696 13697 percentMouse = ( pixelMouse / pixelTotal ); 13698 if ( percentMouse > 1 ) { 13699 percentMouse = 1; 13700 } 13701 if ( percentMouse < 0 ) { 13702 percentMouse = 0; 13703 } 13704 if ( this.orientation === "vertical" ) { 13705 percentMouse = 1 - percentMouse; 13706 } 13707 13708 valueTotal = this._valueMax() - this._valueMin(); 13709 valueMouse = this._valueMin() + percentMouse * valueTotal; 13710 13711 return this._trimAlignValue( valueMouse ); 13712 }, 13713 13714 _uiHash: function( index, value, values ) { 13715 var uiHash = { 13716 handle: this.handles[ index ], 13717 handleIndex: index, 13718 value: value !== undefined ? value : this.value() 13719 }; 13720 13721 if ( this._hasMultipleValues() ) { 13722 uiHash.value = value !== undefined ? value : this.values( index ); 13723 uiHash.values = values || this.values(); 13724 } 13725 13726 return uiHash; 13727 }, 13728 13729 _hasMultipleValues: function() { 13730 return this.options.values && this.options.values.length; 13731 }, 13732 13733 _start: function( event, index ) { 13734 return this._trigger( "start", event, this._uiHash( index ) ); 13735 }, 13736 13737 _slide: function( event, index, newVal ) { 13738 var allowed, otherVal, 13739 currentValue = this.value(), 13740 newValues = this.values(); 13741 13742 if ( this._hasMultipleValues() ) { 13743 otherVal = this.values( index ? 0 : 1 ); 13744 currentValue = this.values( index ); 13745 13746 if ( this.options.values.length === 2 && this.options.range === true ) { 13747 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 13748 } 13749 13750 newValues[ index ] = newVal; 13751 } 13752 13753 if ( newVal === currentValue ) { 13754 return; 13755 } 13756 13757 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 13758 13759 // A slide can be canceled by returning false from the slide callback 13760 if ( allowed === false ) { 13761 return; 13762 } 13763 13764 if ( this._hasMultipleValues() ) { 13765 this.values( index, newVal ); 13766 } else { 13767 this.value( newVal ); 13768 } 13769 }, 13770 13771 _stop: function( event, index ) { 13772 this._trigger( "stop", event, this._uiHash( index ) ); 13773 }, 13774 13775 _change: function( event, index ) { 13776 if ( !this._keySliding && !this._mouseSliding ) { 13777 13778 //store the last changed value index for reference when handles overlap 13779 this._lastChangedValue = index; 13780 this._trigger( "change", event, this._uiHash( index ) ); 13781 } 13782 }, 13783 13784 value: function( newValue ) { 13785 if ( arguments.length ) { 13786 this.options.value = this._trimAlignValue( newValue ); 13787 this._refreshValue(); 13788 this._change( null, 0 ); 13789 return; 13790 } 13791 13792 return this._value(); 13793 }, 13794 13795 values: function( index, newValue ) { 13796 var vals, 13797 newValues, 13798 i; 13799 13800 if ( arguments.length > 1 ) { 13801 this.options.values[ index ] = this._trimAlignValue( newValue ); 13802 this._refreshValue(); 13803 this._change( null, index ); 13804 return; 13805 } 13806 13807 if ( arguments.length ) { 13808 if ( $.isArray( arguments[ 0 ] ) ) { 13809 vals = this.options.values; 13810 newValues = arguments[ 0 ]; 13811 for ( i = 0; i < vals.length; i += 1 ) { 13812 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13813 this._change( null, i ); 13814 } 13815 this._refreshValue(); 13816 } else { 13817 if ( this._hasMultipleValues() ) { 13818 return this._values( index ); 13819 } else { 13820 return this.value(); 13821 } 13822 } 13823 } else { 13824 return this._values(); 13825 } 13826 }, 13827 13828 _setOption: function( key, value ) { 13829 var i, 13830 valsLength = 0; 13831 13832 if ( key === "range" && this.options.range === true ) { 13833 if ( value === "min" ) { 13834 this.options.value = this._values( 0 ); 13835 this.options.values = null; 13836 } else if ( value === "max" ) { 13837 this.options.value = this._values( this.options.values.length - 1 ); 13838 this.options.values = null; 13839 } 13840 } 13841 13842 if ( $.isArray( this.options.values ) ) { 13843 valsLength = this.options.values.length; 13844 } 13845 13846 this._super( key, value ); 13847 13848 switch ( key ) { 13849 case "orientation": 13850 this._detectOrientation(); 13851 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13852 ._addClass( "ui-slider-" + this.orientation ); 13853 this._refreshValue(); 13854 if ( this.options.range ) { 13855 this._refreshRange( value ); 13856 } 13857 13858 // Reset positioning from previous orientation 13859 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 13860 break; 13861 case "value": 13862 this._animateOff = true; 13863 this._refreshValue(); 13864 this._change( null, 0 ); 13865 this._animateOff = false; 13866 break; 13867 case "values": 13868 this._animateOff = true; 13869 this._refreshValue(); 13870 13871 // Start from the last handle to prevent unreachable handles (#9046) 13872 for ( i = valsLength - 1; i >= 0; i-- ) { 13873 this._change( null, i ); 13874 } 13875 this._animateOff = false; 13876 break; 13877 case "step": 13878 case "min": 13879 case "max": 13880 this._animateOff = true; 13881 this._calculateNewMax(); 13882 this._refreshValue(); 13883 this._animateOff = false; 13884 break; 13885 case "range": 13886 this._animateOff = true; 13887 this._refresh(); 13888 this._animateOff = false; 13889 break; 13890 } 13891 }, 13892 13893 _setOptionDisabled: function( value ) { 13894 this._super( value ); 13895 13896 this._toggleClass( null, "ui-state-disabled", !!value ); 13897 }, 13898 13899 //internal value getter 13900 // _value() returns value trimmed by min and max, aligned by step 13901 _value: function() { 13902 var val = this.options.value; 13903 val = this._trimAlignValue( val ); 13904 13905 return val; 13906 }, 13907 13908 //internal values getter 13909 // _values() returns array of values trimmed by min and max, aligned by step 13910 // _values( index ) returns single value trimmed by min and max, aligned by step 13911 _values: function( index ) { 13912 var val, 13913 vals, 13914 i; 13915 13916 if ( arguments.length ) { 13917 val = this.options.values[ index ]; 13918 val = this._trimAlignValue( val ); 13919 13920 return val; 13921 } else if ( this._hasMultipleValues() ) { 13922 13923 // .slice() creates a copy of the array 13924 // this copy gets trimmed by min and max and then returned 13925 vals = this.options.values.slice(); 13926 for ( i = 0; i < vals.length; i += 1 ) { 13927 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13928 } 13929 13930 return vals; 13931 } else { 13932 return []; 13933 } 13934 }, 13935 13936 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 13937 _trimAlignValue: function( val ) { 13938 if ( val <= this._valueMin() ) { 13939 return this._valueMin(); 13940 } 13941 if ( val >= this._valueMax() ) { 13942 return this._valueMax(); 13943 } 13944 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13945 valModStep = ( val - this._valueMin() ) % step, 13946 alignValue = val - valModStep; 13947 13948 if ( Math.abs( valModStep ) * 2 >= step ) { 13949 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13950 } 13951 13952 // Since JavaScript has problems with large floats, round 13953 // the final value to 5 digits after the decimal point (see #4124) 13954 return parseFloat( alignValue.toFixed( 5 ) ); 13955 }, 13956 13957 _calculateNewMax: function() { 13958 var max = this.options.max, 13959 min = this._valueMin(), 13960 step = this.options.step, 13961 aboveMin = Math.round( ( max - min ) / step ) * step; 13962 max = aboveMin + min; 13963 if ( max > this.options.max ) { 13964 13965 //If max is not divisible by step, rounding off may increase its value 13966 max -= step; 13967 } 13968 this.max = parseFloat( max.toFixed( this._precision() ) ); 13969 }, 13970 13971 _precision: function() { 13972 var precision = this._precisionOf( this.options.step ); 13973 if ( this.options.min !== null ) { 13974 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13975 } 13976 return precision; 13977 }, 13978 13979 _precisionOf: function( num ) { 13980 var str = num.toString(), 13981 decimal = str.indexOf( "." ); 13982 return decimal === -1 ? 0 : str.length - decimal - 1; 13983 }, 13984 13985 _valueMin: function() { 13986 return this.options.min; 13987 }, 13988 13989 _valueMax: function() { 13990 return this.max; 13991 }, 13992 13993 _refreshRange: function( orientation ) { 13994 if ( orientation === "vertical" ) { 13995 this.range.css( { "width": "", "left": "" } ); 13996 } 13997 if ( orientation === "horizontal" ) { 13998 this.range.css( { "height": "", "bottom": "" } ); 13999 } 14000 }, 14001 14002 _refreshValue: function() { 14003 var lastValPercent, valPercent, value, valueMin, valueMax, 14004 oRange = this.options.range, 14005 o = this.options, 14006 that = this, 14007 animate = ( !this._animateOff ) ? o.animate : false, 14008 _set = {}; 14009 14010 if ( this._hasMultipleValues() ) { 14011 this.handles.each( function( i ) { 14012 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 14013 that._valueMin() ) * 100; 14014 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14015 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14016 if ( that.options.range === true ) { 14017 if ( that.orientation === "horizontal" ) { 14018 if ( i === 0 ) { 14019 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14020 left: valPercent + "%" 14021 }, o.animate ); 14022 } 14023 if ( i === 1 ) { 14024 that.range[ animate ? "animate" : "css" ]( { 14025 width: ( valPercent - lastValPercent ) + "%" 14026 }, { 14027 queue: false, 14028 duration: o.animate 14029 } ); 14030 } 14031 } else { 14032 if ( i === 0 ) { 14033 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14034 bottom: ( valPercent ) + "%" 14035 }, o.animate ); 14036 } 14037 if ( i === 1 ) { 14038 that.range[ animate ? "animate" : "css" ]( { 14039 height: ( valPercent - lastValPercent ) + "%" 14040 }, { 14041 queue: false, 14042 duration: o.animate 14043 } ); 14044 } 14045 } 14046 } 14047 lastValPercent = valPercent; 14048 } ); 14049 } else { 14050 value = this.value(); 14051 valueMin = this._valueMin(); 14052 valueMax = this._valueMax(); 14053 valPercent = ( valueMax !== valueMin ) ? 14054 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 14055 0; 14056 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 14057 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 14058 14059 if ( oRange === "min" && this.orientation === "horizontal" ) { 14060 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14061 width: valPercent + "%" 14062 }, o.animate ); 14063 } 14064 if ( oRange === "max" && this.orientation === "horizontal" ) { 14065 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14066 width: ( 100 - valPercent ) + "%" 14067 }, o.animate ); 14068 } 14069 if ( oRange === "min" && this.orientation === "vertical" ) { 14070 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14071 height: valPercent + "%" 14072 }, o.animate ); 14073 } 14074 if ( oRange === "max" && this.orientation === "vertical" ) { 14075 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 14076 height: ( 100 - valPercent ) + "%" 14077 }, o.animate ); 14078 } 14079 } 14080 }, 14081 14082 _handleEvents: { 14083 keydown: function( event ) { 14084 var allowed, curVal, newVal, step, 14085 index = $( event.target ).data( "ui-slider-handle-index" ); 14086 14087 switch ( event.keyCode ) { 14088 case $.ui.keyCode.HOME: 14089 case $.ui.keyCode.END: 14090 case $.ui.keyCode.PAGE_UP: 14091 case $.ui.keyCode.PAGE_DOWN: 14092 case $.ui.keyCode.UP: 14093 case $.ui.keyCode.RIGHT: 14094 case $.ui.keyCode.DOWN: 14095 case $.ui.keyCode.LEFT: 14096 event.preventDefault(); 14097 if ( !this._keySliding ) { 14098 this._keySliding = true; 14099 this._addClass( $( event.target ), null, "ui-state-active" ); 14100 allowed = this._start( event, index ); 14101 if ( allowed === false ) { 14102 return; 14103 } 14104 } 14105 break; 14106 } 14107 14108 step = this.options.step; 14109 if ( this._hasMultipleValues() ) { 14110 curVal = newVal = this.values( index ); 14111 } else { 14112 curVal = newVal = this.value(); 14113 } 14114 14115 switch ( event.keyCode ) { 14116 case $.ui.keyCode.HOME: 14117 newVal = this._valueMin(); 14118 break; 14119 case $.ui.keyCode.END: 14120 newVal = this._valueMax(); 14121 break; 14122 case $.ui.keyCode.PAGE_UP: 14123 newVal = this._trimAlignValue( 14124 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 14125 ); 14126 break; 14127 case $.ui.keyCode.PAGE_DOWN: 14128 newVal = this._trimAlignValue( 14129 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 14130 break; 14131 case $.ui.keyCode.UP:
vendor: 5,058 bytes, lines 14132-14330
14132 case $.ui.keyCode.RIGHT: 14133 if ( curVal === this._valueMax() ) { 14134 return; 14135 } 14136 newVal = this._trimAlignValue( curVal + step ); 14137 break; 14138 case $.ui.keyCode.DOWN: 14139 case $.ui.keyCode.LEFT: 14140 if ( curVal === this._valueMin() ) { 14141 return; 14142 } 14143 newVal = this._trimAlignValue( curVal - step ); 14144 break; 14145 } 14146 14147 this._slide( event, index, newVal ); 14148 }, 14149 keyup: function( event ) { 14150 var index = $( event.target ).data( "ui-slider-handle-index" ); 14151 14152 if ( this._keySliding ) { 14153 this._keySliding = false; 14154 this._stop( event, index ); 14155 this._change( event, index ); 14156 this._removeClass( $( event.target ), null, "ui-state-active" ); 14157 } 14158 } 14159 } 14160} ); 14161 14162 14163/*! 14164 * jQuery UI Spinner 1.12.1 14165 * http://jqueryui.com 14166 * 14167 * Copyright jQuery Foundation and other contributors 14168 * Released under the MIT license. 14169 * http://jquery.org/license 14170 */ 14171 14172//>>label: Spinner 14173//>>group: Widgets 14174//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 14175//>>docs: http://api.jqueryui.com/spinner/ 14176//>>demos: http://jqueryui.com/spinner/ 14177//>>css.structure: ../../themes/base/core.css 14178//>>css.structure: ../../themes/base/spinner.css 14179//>>css.theme: ../../themes/base/theme.css 14180 14181 14182 14183function spinnerModifer( fn ) { 14184 return function() { 14185 var previous = this.element.val(); 14186 fn.apply( this, arguments ); 14187 this._refresh(); 14188 if ( previous !== this.element.val() ) { 14189 this._trigger( "change" ); 14190 } 14191 }; 14192} 14193 14194$.widget( "ui.spinner", { 14195 version: "1.12.1", 14196 defaultElement: "<input>", 14197 widgetEventPrefix: "spin", 14198 options: { 14199 classes: { 14200 "ui-spinner": "ui-corner-all", 14201 "ui-spinner-down": "ui-corner-br", 14202 "ui-spinner-up": "ui-corner-tr" 14203 }, 14204 culture: null, 14205 icons: { 14206 down: "ui-icon-triangle-1-s", 14207 up: "ui-icon-triangle-1-n" 14208 }, 14209 incremental: true, 14210 max: null, 14211 min: null, 14212 numberFormat: null, 14213 page: 10, 14214 step: 1, 14215 14216 change: null, 14217 spin: null, 14218 start: null, 14219 stop: null 14220 }, 14221 14222 _create: function() { 14223 14224 // handle string values that need to be parsed 14225 this._setOption( "max", this.options.max ); 14226 this._setOption( "min", this.options.min ); 14227 this._setOption( "step", this.options.step ); 14228 14229 // Only format if there is a value, prevents the field from being marked 14230 // as invalid in Firefox, see #9573. 14231 if ( this.value() !== "" ) { 14232 14233 // Format the value, but don't constrain. 14234 this._value( this.element.val(), true ); 14235 } 14236 14237 this._draw(); 14238 this._on( this._events ); 14239 this._refresh(); 14240 14241 // Turning off autocomplete prevents the browser from remembering the 14242 // value when navigating through history, so we re-enable autocomplete 14243 // if the page is unloaded before the widget is destroyed. #7790 14244 this._on( this.window, { 14245 beforeunload: function() { 14246 this.element.removeAttr( "autocomplete" ); 14247 } 14248 } ); 14249 }, 14250 14251 _getCreateOptions: function() { 14252 var options = this._super(); 14253 var element = this.element; 14254 14255 $.each( [ "min", "max", "step" ], function( i, option ) { 14256 var value = element.attr( option ); 14257 if ( value != null && value.length ) { 14258 options[ option ] = value; 14259 } 14260 } ); 14261 14262 return options; 14263 }, 14264 14265 _events: { 14266 keydown: function( event ) { 14267 if ( this._start( event ) && this._keydown( event ) ) { 14268 event.preventDefault(); 14269 } 14270 }, 14271 keyup: "_stop", 14272 focus: function() { 14273 this.previous = this.element.val(); 14274 }, 14275 blur: function( event ) { 14276 if ( this.cancelBlur ) { 14277 delete this.cancelBlur; 14278 return; 14279 } 14280 14281 this._stop(); 14282 this._refresh(); 14283 if ( this.previous !== this.element.val() ) { 14284 this._trigger( "change", event ); 14285 } 14286 }, 14287 mousewheel: function( event, delta ) { 14288 if ( !delta ) { 14289 return; 14290 } 14291 if ( !this.spinning && !this._start( event ) ) { 14292 return false; 14293 } 14294 14295 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 14296 clearTimeout( this.mousewheelTimer ); 14297 this.mousewheelTimer = this._delay( function() { 14298 if ( this.spinning ) { 14299 this._stop( event ); 14300 } 14301 }, 100 ); 14302 event.preventDefault(); 14303 }, 14304 "mousedown .ui-spinner-button": function( event ) { 14305 var previous; 14306 14307 // We never want the buttons to have focus; whenever the user is 14308 // interacting with the spinner, the focus should be on the input. 14309 // If the input is focused then this.previous is properly set from 14310 // when the input first received focus. If the input is not focused 14311 // then we need to set this.previous based on the value before spinning. 14312 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? 14313 this.previous : this.element.val(); 14314 function checkFocus() { 14315 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); 14316 if ( !isActive ) { 14317 this.element.trigger( "focus" ); 14318 this.previous = previous; 14319 14320 // support: IE 14321 // IE sets focus asynchronously, so we need to check if focus 14322 // moved off of the input because the user clicked on the button. 14323 this._delay( function() { 14324 this.previous = previous; 14325 } ); 14326 } 14327 } 14328 14329 // Ensure focus is on (or stays on) the text field 14330 event.preventDefault();
vendor: 42,977 bytes, lines 14331-15985
14331 checkFocus.call( this ); 14332 14333 // Support: IE 14334 // IE doesn't prevent moving focus even with event.preventDefault() 14335 // so we set a flag to know when we should ignore the blur event 14336 // and check (again) if focus moved off of the input. 14337 this.cancelBlur = true; 14338 this._delay( function() { 14339 delete this.cancelBlur; 14340 checkFocus.call( this ); 14341 } ); 14342 14343 if ( this._start( event ) === false ) { 14344 return; 14345 } 14346 14347 this._repeat( null, $( event.currentTarget ) 14348 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14349 }, 14350 "mouseup .ui-spinner-button": "_stop", 14351 "mouseenter .ui-spinner-button": function( event ) { 14352 14353 // button will add ui-state-active if mouse was down while mouseleave and kept down 14354 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14355 return; 14356 } 14357 14358 if ( this._start( event ) === false ) { 14359 return false; 14360 } 14361 this._repeat( null, $( event.currentTarget ) 14362 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14363 }, 14364 14365 // TODO: do we really want to consider this a stop? 14366 // shouldn't we just stop the repeater and wait until mouseup before 14367 // we trigger the stop event? 14368 "mouseleave .ui-spinner-button": "_stop" 14369 }, 14370 14371 // Support mobile enhanced option and make backcompat more sane 14372 _enhance: function() { 14373 this.uiSpinner = this.element 14374 .attr( "autocomplete", "off" ) 14375 .wrap( "<span>" ) 14376 .parent() 14377 14378 // Add buttons 14379 .append( 14380 "<a></a><a></a>" 14381 ); 14382 }, 14383 14384 _draw: function() { 14385 this._enhance(); 14386 14387 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 14388 this._addClass( "ui-spinner-input" ); 14389 14390 this.element.attr( "role", "spinbutton" ); 14391 14392 // Button bindings 14393 this.buttons = this.uiSpinner.children( "a" ) 14394 .attr( "tabIndex", -1 ) 14395 .attr( "aria-hidden", true ) 14396 .button( { 14397 classes: { 14398 "ui-button": "" 14399 } 14400 } ); 14401 14402 // TODO: Right now button does not support classes this is already updated in button PR 14403 this._removeClass( this.buttons, "ui-corner-all" ); 14404 14405 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 14406 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 14407 this.buttons.first().button( { 14408 "icon": this.options.icons.up, 14409 "showLabel": false 14410 } ); 14411 this.buttons.last().button( { 14412 "icon": this.options.icons.down, 14413 "showLabel": false 14414 } ); 14415 14416 // IE 6 doesn't understand height: 50% for the buttons 14417 // unless the wrapper has an explicit height 14418 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 14419 this.uiSpinner.height() > 0 ) { 14420 this.uiSpinner.height( this.uiSpinner.height() ); 14421 } 14422 }, 14423 14424 _keydown: function( event ) { 14425 var options = this.options, 14426 keyCode = $.ui.keyCode; 14427 14428 switch ( event.keyCode ) { 14429 case keyCode.UP: 14430 this._repeat( null, 1, event ); 14431 return true; 14432 case keyCode.DOWN: 14433 this._repeat( null, -1, event ); 14434 return true; 14435 case keyCode.PAGE_UP: 14436 this._repeat( null, options.page, event ); 14437 return true; 14438 case keyCode.PAGE_DOWN: 14439 this._repeat( null, -options.page, event ); 14440 return true; 14441 } 14442 14443 return false; 14444 }, 14445 14446 _start: function( event ) { 14447 if ( !this.spinning && this._trigger( "start", event ) === false ) { 14448 return false; 14449 } 14450 14451 if ( !this.counter ) { 14452 this.counter = 1; 14453 } 14454 this.spinning = true; 14455 return true; 14456 }, 14457 14458 _repeat: function( i, steps, event ) { 14459 i = i || 500; 14460 14461 clearTimeout( this.timer ); 14462 this.timer = this._delay( function() { 14463 this._repeat( 40, steps, event ); 14464 }, i ); 14465 14466 this._spin( steps * this.options.step, event ); 14467 }, 14468 14469 _spin: function( step, event ) { 14470 var value = this.value() || 0; 14471 14472 if ( !this.counter ) { 14473 this.counter = 1; 14474 } 14475 14476 value = this._adjustValue( value + step * this._increment( this.counter ) ); 14477 14478 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 14479 this._value( value ); 14480 this.counter++; 14481 } 14482 }, 14483 14484 _increment: function( i ) { 14485 var incremental = this.options.incremental; 14486 14487 if ( incremental ) { 14488 return $.isFunction( incremental ) ? 14489 incremental( i ) : 14490 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 14491 } 14492 14493 return 1; 14494 }, 14495 14496 _precision: function() { 14497 var precision = this._precisionOf( this.options.step ); 14498 if ( this.options.min !== null ) { 14499 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 14500 } 14501 return precision; 14502 }, 14503 14504 _precisionOf: function( num ) { 14505 var str = num.toString(), 14506 decimal = str.indexOf( "." ); 14507 return decimal === -1 ? 0 : str.length - decimal - 1; 14508 }, 14509 14510 _adjustValue: function( value ) { 14511 var base, aboveMin, 14512 options = this.options; 14513 14514 // Make sure we're at a valid step 14515 // - find out where we are relative to the base (min or 0) 14516 base = options.min !== null ? options.min : 0; 14517 aboveMin = value - base; 14518 14519 // - round to the nearest step 14520 aboveMin = Math.round( aboveMin / options.step ) * options.step; 14521 14522 // - rounding is based on 0, so adjust back to our base 14523 value = base + aboveMin; 14524 14525 // Fix precision from bad JS floating point math 14526 value = parseFloat( value.toFixed( this._precision() ) ); 14527 14528 // Clamp the value 14529 if ( options.max !== null && value > options.max ) { 14530 return options.max; 14531 } 14532 if ( options.min !== null && value < options.min ) { 14533 return options.min; 14534 } 14535 14536 return value; 14537 }, 14538 14539 _stop: function( event ) { 14540 if ( !this.spinning ) { 14541 return; 14542 } 14543 14544 clearTimeout( this.timer ); 14545 clearTimeout( this.mousewheelTimer ); 14546 this.counter = 0; 14547 this.spinning = false; 14548 this._trigger( "stop", event ); 14549 }, 14550 14551 _setOption: function( key, value ) { 14552 var prevValue, first, last; 14553 14554 if ( key === "culture" || key === "numberFormat" ) { 14555 prevValue = this._parse( this.element.val() ); 14556 this.options[ key ] = value; 14557 this.element.val( this._format( prevValue ) ); 14558 return; 14559 } 14560 14561 if ( key === "max" || key === "min" || key === "step" ) { 14562 if ( typeof value === "string" ) { 14563 value = this._parse( value ); 14564 } 14565 } 14566 if ( key === "icons" ) { 14567 first = this.buttons.first().find( ".ui-icon" ); 14568 this._removeClass( first, null, this.options.icons.up ); 14569 this._addClass( first, null, value.up ); 14570 last = this.buttons.last().find( ".ui-icon" ); 14571 this._removeClass( last, null, this.options.icons.down ); 14572 this._addClass( last, null, value.down ); 14573 } 14574 14575 this._super( key, value ); 14576 }, 14577 14578 _setOptionDisabled: function( value ) { 14579 this._super( value ); 14580 14581 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 14582 this.element.prop( "disabled", !!value ); 14583 this.buttons.button( value ? "disable" : "enable" ); 14584 }, 14585 14586 _setOptions: spinnerModifer( function( options ) { 14587 this._super( options ); 14588 } ), 14589 14590 _parse: function( val ) { 14591 if ( typeof val === "string" && val !== "" ) { 14592 val = window.Globalize && this.options.numberFormat ? 14593 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 14594 } 14595 return val === "" || isNaN( val ) ? null : val; 14596 }, 14597 14598 _format: function( value ) { 14599 if ( value === "" ) { 14600 return ""; 14601 } 14602 return window.Globalize && this.options.numberFormat ? 14603 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 14604 value; 14605 }, 14606 14607 _refresh: function() { 14608 this.element.attr( { 14609 "aria-valuemin": this.options.min, 14610 "aria-valuemax": this.options.max, 14611 14612 // TODO: what should we do with values that can't be parsed? 14613 "aria-valuenow": this._parse( this.element.val() ) 14614 } ); 14615 }, 14616 14617 isValid: function() { 14618 var value = this.value(); 14619 14620 // Null is invalid 14621 if ( value === null ) { 14622 return false; 14623 } 14624 14625 // If value gets adjusted, it's invalid 14626 return value === this._adjustValue( value ); 14627 }, 14628 14629 // Update the value without triggering change 14630 _value: function( value, allowAny ) { 14631 var parsed; 14632 if ( value !== "" ) { 14633 parsed = this._parse( value ); 14634 if ( parsed !== null ) { 14635 if ( !allowAny ) { 14636 parsed = this._adjustValue( parsed ); 14637 } 14638 value = this._format( parsed ); 14639 } 14640 } 14641 this.element.val( value ); 14642 this._refresh(); 14643 }, 14644 14645 _destroy: function() { 14646 this.element 14647 .prop( "disabled", false ) 14648 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 14649 14650 this.uiSpinner.replaceWith( this.element ); 14651 }, 14652 14653 stepUp: spinnerModifer( function( steps ) { 14654 this._stepUp( steps ); 14655 } ), 14656 _stepUp: function( steps ) { 14657 if ( this._start() ) { 14658 this._spin( ( steps || 1 ) * this.options.step ); 14659 this._stop(); 14660 } 14661 }, 14662 14663 stepDown: spinnerModifer( function( steps ) { 14664 this._stepDown( steps ); 14665 } ), 14666 _stepDown: function( steps ) { 14667 if ( this._start() ) { 14668 this._spin( ( steps || 1 ) * -this.options.step ); 14669 this._stop(); 14670 } 14671 }, 14672 14673 pageUp: spinnerModifer( function( pages ) { 14674 this._stepUp( ( pages || 1 ) * this.options.page ); 14675 } ), 14676 14677 pageDown: spinnerModifer( function( pages ) { 14678 this._stepDown( ( pages || 1 ) * this.options.page ); 14679 } ), 14680 14681 value: function( newVal ) { 14682 if ( !arguments.length ) { 14683 return this._parse( this.element.val() ); 14684 } 14685 spinnerModifer( this._value ).call( this, newVal ); 14686 }, 14687 14688 widget: function() { 14689 return this.uiSpinner; 14690 } 14691} ); 14692 14693// DEPRECATED 14694// TODO: switch return back to widget declaration at top of file when this is removed 14695if ( $.uiBackCompat !== false ) { 14696 14697 // Backcompat for spinner html extension points 14698 $.widget( "ui.spinner", $.ui.spinner, { 14699 _enhance: function() { 14700 this.uiSpinner = this.element 14701 .attr( "autocomplete", "off" ) 14702 .wrap( this._uiSpinnerHtml() ) 14703 .parent() 14704 14705 // Add buttons 14706 .append( this._buttonHtml() ); 14707 }, 14708 _uiSpinnerHtml: function() { 14709 return "<span>"; 14710 }, 14711 14712 _buttonHtml: function() { 14713 return "<a></a><a></a>"; 14714 } 14715 } ); 14716} 14717 14718var widgetsSpinner = $.ui.spinner; 14719 14720 14721/*! 14722 * jQuery UI Tabs 1.12.1 14723 * http://jqueryui.com 14724 * 14725 * Copyright jQuery Foundation and other contributors 14726 * Released under the MIT license. 14727 * http://jquery.org/license 14728 */ 14729 14730//>>label: Tabs 14731//>>group: Widgets 14732//>>description: Transforms a set of container elements into a tab structure. 14733//>>docs: http://api.jqueryui.com/tabs/ 14734//>>demos: http://jqueryui.com/tabs/ 14735//>>css.structure: ../../themes/base/core.css 14736//>>css.structure: ../../themes/base/tabs.css 14737//>>css.theme: ../../themes/base/theme.css 14738 14739 14740 14741$.widget( "ui.tabs", { 14742 version: "1.12.1", 14743 delay: 300, 14744 options: { 14745 active: null, 14746 classes: { 14747 "ui-tabs": "ui-corner-all", 14748 "ui-tabs-nav": "ui-corner-all", 14749 "ui-tabs-panel": "ui-corner-bottom", 14750 "ui-tabs-tab": "ui-corner-top" 14751 }, 14752 collapsible: false, 14753 event: "click", 14754 heightStyle: "content", 14755 hide: null, 14756 show: null, 14757 14758 // Callbacks 14759 activate: null, 14760 beforeActivate: null, 14761 beforeLoad: null, 14762 load: null 14763 }, 14764 14765 _isLocal: ( function() { 14766 var rhash = /#.*$/; 14767 14768 return function( anchor ) { 14769 var anchorUrl, locationUrl; 14770 14771 anchorUrl = anchor.href.replace( rhash, "" ); 14772 locationUrl = location.href.replace( rhash, "" ); 14773 14774 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 14775 try { 14776 anchorUrl = decodeURIComponent( anchorUrl ); 14777 } catch ( error ) {} 14778 try { 14779 locationUrl = decodeURIComponent( locationUrl ); 14780 } catch ( error ) {} 14781 14782 return anchor.hash.length > 1 && anchorUrl === locationUrl; 14783 }; 14784 } )(), 14785 14786 _create: function() { 14787 var that = this, 14788 options = this.options; 14789 14790 this.running = false; 14791 14792 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 14793 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 14794 14795 this._processTabs(); 14796 options.active = this._initialActive(); 14797 14798 // Take disabling tabs via class attribute from HTML 14799 // into account and update option properly. 14800 if ( $.isArray( options.disabled ) ) { 14801 options.disabled = $.unique( options.disabled.concat( 14802 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 14803 return that.tabs.index( li ); 14804 } ) 14805 ) ).sort(); 14806 } 14807 14808 // Check for length avoids error when initializing empty list 14809 if ( this.options.active !== false && this.anchors.length ) { 14810 this.active = this._findActive( options.active ); 14811 } else { 14812 this.active = $(); 14813 } 14814 14815 this._refresh(); 14816 14817 if ( this.active.length ) { 14818 this.load( options.active ); 14819 } 14820 }, 14821 14822 _initialActive: function() { 14823 var active = this.options.active, 14824 collapsible = this.options.collapsible, 14825 locationHash = location.hash.substring( 1 ); 14826 14827 if ( active === null ) { 14828 14829 // check the fragment identifier in the URL 14830 if ( locationHash ) { 14831 this.tabs.each( function( i, tab ) { 14832 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 14833 active = i; 14834 return false; 14835 } 14836 } ); 14837 } 14838 14839 // Check for a tab marked active via a class 14840 if ( active === null ) { 14841 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 14842 } 14843 14844 // No active tab, set to false 14845 if ( active === null || active === -1 ) { 14846 active = this.tabs.length ? 0 : false; 14847 } 14848 } 14849 14850 // Handle numbers: negative, out of range 14851 if ( active !== false ) { 14852 active = this.tabs.index( this.tabs.eq( active ) ); 14853 if ( active === -1 ) { 14854 active = collapsible ? false : 0; 14855 } 14856 } 14857 14858 // Don't allow collapsible: false and active: false 14859 if ( !collapsible && active === false && this.anchors.length ) { 14860 active = 0; 14861 } 14862 14863 return active; 14864 }, 14865 14866 _getCreateEventData: function() { 14867 return { 14868 tab: this.active, 14869 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 14870 }; 14871 }, 14872 14873 _tabKeydown: function( event ) { 14874 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), 14875 selectedIndex = this.tabs.index( focusedTab ), 14876 goingForward = true; 14877 14878 if ( this._handlePageNav( event ) ) { 14879 return; 14880 } 14881 14882 switch ( event.keyCode ) { 14883 case $.ui.keyCode.RIGHT: 14884 case $.ui.keyCode.DOWN: 14885 selectedIndex++; 14886 break; 14887 case $.ui.keyCode.UP: 14888 case $.ui.keyCode.LEFT: 14889 goingForward = false; 14890 selectedIndex--; 14891 break; 14892 case $.ui.keyCode.END: 14893 selectedIndex = this.anchors.length - 1; 14894 break; 14895 case $.ui.keyCode.HOME: 14896 selectedIndex = 0; 14897 break; 14898 case $.ui.keyCode.SPACE: 14899 14900 // Activate only, no collapsing 14901 event.preventDefault(); 14902 clearTimeout( this.activating ); 14903 this._activate( selectedIndex ); 14904 return; 14905 case $.ui.keyCode.ENTER: 14906 14907 // Toggle (cancel delayed activation, allow collapsing) 14908 event.preventDefault(); 14909 clearTimeout( this.activating ); 14910 14911 // Determine if we should collapse or activate 14912 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 14913 return; 14914 default: 14915 return; 14916 } 14917 14918 // Focus the appropriate tab, based on which key was pressed 14919 event.preventDefault(); 14920 clearTimeout( this.activating ); 14921 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 14922 14923 // Navigating with control/command key will prevent automatic activation 14924 if ( !event.ctrlKey && !event.metaKey ) { 14925 14926 // Update aria-selected immediately so that AT think the tab is already selected. 14927 // Otherwise AT may confuse the user by stating that they need to activate the tab, 14928 // but the tab will already be activated by the time the announcement finishes. 14929 focusedTab.attr( "aria-selected", "false" ); 14930 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 14931 14932 this.activating = this._delay( function() { 14933 this.option( "active", selectedIndex ); 14934 }, this.delay ); 14935 } 14936 }, 14937 14938 _panelKeydown: function( event ) { 14939 if ( this._handlePageNav( event ) ) { 14940 return; 14941 } 14942 14943 // Ctrl+up moves focus to the current tab 14944 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 14945 event.preventDefault(); 14946 this.active.trigger( "focus" ); 14947 } 14948 }, 14949 14950 // Alt+page up/down moves focus to the previous/next tab (and activates) 14951 _handlePageNav: function( event ) { 14952 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 14953 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 14954 return true; 14955 } 14956 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14957 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14958 return true; 14959 } 14960 }, 14961 14962 _findNextTab: function( index, goingForward ) { 14963 var lastTabIndex = this.tabs.length - 1; 14964 14965 function constrain() { 14966 if ( index > lastTabIndex ) { 14967 index = 0; 14968 } 14969 if ( index < 0 ) { 14970 index = lastTabIndex; 14971 } 14972 return index; 14973 } 14974 14975 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14976 index = goingForward ? index + 1 : index - 1; 14977 } 14978 14979 return index; 14980 }, 14981 14982 _focusNextTab: function( index, goingForward ) { 14983 index = this._findNextTab( index, goingForward ); 14984 this.tabs.eq( index ).trigger( "focus" ); 14985 return index; 14986 }, 14987 14988 _setOption: function( key, value ) { 14989 if ( key === "active" ) { 14990 14991 // _activate() will handle invalid values and update this.options 14992 this._activate( value ); 14993 return; 14994 } 14995 14996 this._super( key, value ); 14997 14998 if ( key === "collapsible" ) { 14999 this._toggleClass( "ui-tabs-collapsible", null, value ); 15000 15001 // Setting collapsible: false while collapsed; open first panel 15002 if ( !value && this.options.active === false ) { 15003 this._activate( 0 ); 15004 } 15005 } 15006 15007 if ( key === "event" ) { 15008 this._setupEvents( value ); 15009 } 15010 15011 if ( key === "heightStyle" ) { 15012 this._setupHeightStyle( value ); 15013 } 15014 }, 15015 15016 _sanitizeSelector: function( hash ) { 15017 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 15018 }, 15019 15020 refresh: function() { 15021 var options = this.options, 15022 lis = this.tablist.children( ":has(a[href])" ); 15023 15024 // Get disabled tabs from class attribute from HTML 15025 // this will get converted to a boolean if needed in _refresh() 15026 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15027 return lis.index( tab ); 15028 } ); 15029 15030 this._processTabs(); 15031 15032 // Was collapsed or no tabs 15033 if ( options.active === false || !this.anchors.length ) { 15034 options.active = false; 15035 this.active = $(); 15036 15037 // was active, but active tab is gone 15038 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15039 15040 // all remaining tabs are disabled 15041 if ( this.tabs.length === options.disabled.length ) { 15042 options.active = false; 15043 this.active = $(); 15044 15045 // activate previous tab 15046 } else { 15047 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15048 } 15049 15050 // was active, active tab still exists 15051 } else { 15052 15053 // make sure active index is correct 15054 options.active = this.tabs.index( this.active ); 15055 } 15056 15057 this._refresh(); 15058 }, 15059 15060 _refresh: function() { 15061 this._setOptionDisabled( this.options.disabled ); 15062 this._setupEvents( this.options.event ); 15063 this._setupHeightStyle( this.options.heightStyle ); 15064 15065 this.tabs.not( this.active ).attr( { 15066 "aria-selected": "false", 15067 "aria-expanded": "false", 15068 tabIndex: -1 15069 } ); 15070 this.panels.not( this._getPanelForTab( this.active ) ) 15071 .hide() 15072 .attr( { 15073 "aria-hidden": "true" 15074 } ); 15075 15076 // Make sure one tab is in the tab order 15077 if ( !this.active.length ) { 15078 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15079 } else { 15080 this.active 15081 .attr( { 15082 "aria-selected": "true", 15083 "aria-expanded": "true", 15084 tabIndex: 0 15085 } ); 15086 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 15087 this._getPanelForTab( this.active ) 15088 .show() 15089 .attr( { 15090 "aria-hidden": "false" 15091 } ); 15092 } 15093 }, 15094 15095 _processTabs: function() { 15096 var that = this, 15097 prevTabs = this.tabs, 15098 prevAnchors = this.anchors, 15099 prevPanels = this.panels; 15100 15101 this.tablist = this._getList().attr( "role", "tablist" ); 15102 this._addClass( this.tablist, "ui-tabs-nav", 15103 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 15104 15105 // Prevent users from focusing disabled tabs via click 15106 this.tablist 15107 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 15108 if ( $( this ).is( ".ui-state-disabled" ) ) { 15109 event.preventDefault(); 15110 } 15111 } ) 15112 15113 // Support: IE <9 15114 // Preventing the default action in mousedown doesn't prevent IE 15115 // from focusing the element, so if the anchor gets focused, blur. 15116 // We don't have to worry about focusing the previously focused 15117 // element since clicking on a non-focusable element should focus 15118 // the body anyway. 15119 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { 15120 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 15121 this.blur(); 15122 } 15123 } ); 15124 15125 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15126 .attr( { 15127 role: "tab", 15128 tabIndex: -1 15129 } ); 15130 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 15131 15132 this.anchors = this.tabs.map( function() { 15133 return $( "a", this )[ 0 ]; 15134 } ) 15135 .attr( { 15136 role: "presentation", 15137 tabIndex: -1 15138 } ); 15139 this._addClass( this.anchors, "ui-tabs-anchor" ); 15140 15141 this.panels = $(); 15142 15143 this.anchors.each( function( i, anchor ) { 15144 var selector, panel, panelId, 15145 anchorId = $( anchor ).uniqueId().attr( "id" ), 15146 tab = $( anchor ).closest( "li" ), 15147 originalAriaControls = tab.attr( "aria-controls" ); 15148 15149 // Inline tab 15150 if ( that._isLocal( anchor ) ) { 15151 selector = anchor.hash; 15152 panelId = selector.substring( 1 ); 15153 panel = that.element.find( that._sanitizeSelector( selector ) ); 15154 15155 // remote tab 15156 } else { 15157 15158 // If the tab doesn't already have aria-controls, 15159 // generate an id by using a throw-away element 15160 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15161 selector = "#" + panelId; 15162 panel = that.element.find( selector ); 15163 if ( !panel.length ) { 15164 panel = that._createPanel( panelId ); 15165 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15166 } 15167 panel.attr( "aria-live", "polite" ); 15168 } 15169 15170 if ( panel.length ) { 15171 that.panels = that.panels.add( panel ); 15172 } 15173 if ( originalAriaControls ) { 15174 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15175 } 15176 tab.attr( { 15177 "aria-controls": panelId, 15178 "aria-labelledby": anchorId 15179 } ); 15180 panel.attr( "aria-labelledby", anchorId ); 15181 } ); 15182 15183 this.panels.attr( "role", "tabpanel" ); 15184 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 15185 15186 // Avoid memory leaks (#10056) 15187 if ( prevTabs ) { 15188 this._off( prevTabs.not( this.tabs ) ); 15189 this._off( prevAnchors.not( this.anchors ) ); 15190 this._off( prevPanels.not( this.panels ) ); 15191 } 15192 }, 15193 15194 // Allow overriding how to find the list for rare usage scenarios (#7715) 15195 _getList: function() { 15196 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 15197 }, 15198 15199 _createPanel: function( id ) { 15200 return $( "<div>" ) 15201 .attr( "id", id ) 15202 .data( "ui-tabs-destroy", true ); 15203 }, 15204 15205 _setOptionDisabled: function( disabled ) { 15206 var currentItem, li, i; 15207 15208 if ( $.isArray( disabled ) ) { 15209 if ( !disabled.length ) { 15210 disabled = false; 15211 } else if ( disabled.length === this.anchors.length ) { 15212 disabled = true; 15213 } 15214 } 15215 15216 // Disable tabs 15217 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 15218 currentItem = $( li ); 15219 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15220 currentItem.attr( "aria-disabled", "true" ); 15221 this._addClass( currentItem, null, "ui-state-disabled" ); 15222 } else { 15223 currentItem.removeAttr( "aria-disabled" ); 15224 this._removeClass( currentItem, null, "ui-state-disabled" ); 15225 } 15226 } 15227 15228 this.options.disabled = disabled; 15229 15230 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 15231 disabled === true ); 15232 }, 15233 15234 _setupEvents: function( event ) { 15235 var events = {}; 15236 if ( event ) { 15237 $.each( event.split( " " ), function( index, eventName ) { 15238 events[ eventName ] = "_eventHandler"; 15239 } ); 15240 } 15241 15242 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15243 15244 // Always prevent the default action, even when disabled 15245 this._on( true, this.anchors, { 15246 click: function( event ) { 15247 event.preventDefault(); 15248 } 15249 } ); 15250 this._on( this.anchors, events ); 15251 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15252 this._on( this.panels, { keydown: "_panelKeydown" } ); 15253 15254 this._focusable( this.tabs ); 15255 this._hoverable( this.tabs ); 15256 }, 15257 15258 _setupHeightStyle: function( heightStyle ) { 15259 var maxHeight, 15260 parent = this.element.parent(); 15261 15262 if ( heightStyle === "fill" ) { 15263 maxHeight = parent.height(); 15264 maxHeight -= this.element.outerHeight() - this.element.height(); 15265 15266 this.element.siblings( ":visible" ).each( function() { 15267 var elem = $( this ), 15268 position = elem.css( "position" ); 15269 15270 if ( position === "absolute" || position === "fixed" ) { 15271 return; 15272 } 15273 maxHeight -= elem.outerHeight( true ); 15274 } ); 15275 15276 this.element.children().not( this.panels ).each( function() { 15277 maxHeight -= $( this ).outerHeight( true ); 15278 } ); 15279 15280 this.panels.each( function() { 15281 $( this ).height( Math.max( 0, maxHeight - 15282 $( this ).innerHeight() + $( this ).height() ) ); 15283 } ) 15284 .css( "overflow", "auto" ); 15285 } else if ( heightStyle === "auto" ) { 15286 maxHeight = 0; 15287 this.panels.each( function() { 15288 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15289 } ).height( maxHeight ); 15290 } 15291 }, 15292 15293 _eventHandler: function( event ) { 15294 var options = this.options, 15295 active = this.active, 15296 anchor = $( event.currentTarget ), 15297 tab = anchor.closest( "li" ), 15298 clickedIsActive = tab[ 0 ] === active[ 0 ], 15299 collapsing = clickedIsActive && options.collapsible, 15300 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15301 toHide = !active.length ? $() : this._getPanelForTab( active ), 15302 eventData = { 15303 oldTab: active, 15304 oldPanel: toHide, 15305 newTab: collapsing ? $() : tab, 15306 newPanel: toShow 15307 }; 15308 15309 event.preventDefault(); 15310 15311 if ( tab.hasClass( "ui-state-disabled" ) || 15312 15313 // tab is already loading 15314 tab.hasClass( "ui-tabs-loading" ) || 15315 15316 // can't switch durning an animation 15317 this.running || 15318 15319 // click on active header, but not collapsible 15320 ( clickedIsActive && !options.collapsible ) || 15321 15322 // allow canceling activation 15323 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15324 return; 15325 } 15326 15327 options.active = collapsing ? false : this.tabs.index( tab ); 15328 15329 this.active = clickedIsActive ? $() : tab; 15330 if ( this.xhr ) { 15331 this.xhr.abort(); 15332 } 15333 15334 if ( !toHide.length && !toShow.length ) { 15335 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15336 } 15337 15338 if ( toShow.length ) { 15339 this.load( this.tabs.index( tab ), event ); 15340 } 15341 this._toggle( event, eventData ); 15342 }, 15343 15344 // Handles show/hide for selecting tabs 15345 _toggle: function( event, eventData ) { 15346 var that = this, 15347 toShow = eventData.newPanel, 15348 toHide = eventData.oldPanel; 15349 15350 this.running = true; 15351 15352 function complete() { 15353 that.running = false; 15354 that._trigger( "activate", event, eventData ); 15355 } 15356 15357 function show() { 15358 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 15359 15360 if ( toShow.length && that.options.show ) { 15361 that._show( toShow, that.options.show, complete ); 15362 } else { 15363 toShow.show(); 15364 complete(); 15365 } 15366 } 15367 15368 // Start out by hiding, then showing, then completing 15369 if ( toHide.length && this.options.hide ) { 15370 this._hide( toHide, this.options.hide, function() { 15371 that._removeClass( eventData.oldTab.closest( "li" ), 15372 "ui-tabs-active", "ui-state-active" ); 15373 show(); 15374 } ); 15375 } else { 15376 this._removeClass( eventData.oldTab.closest( "li" ), 15377 "ui-tabs-active", "ui-state-active" ); 15378 toHide.hide(); 15379 show(); 15380 } 15381 15382 toHide.attr( "aria-hidden", "true" ); 15383 eventData.oldTab.attr( { 15384 "aria-selected": "false", 15385 "aria-expanded": "false" 15386 } ); 15387 15388 // If we're switching tabs, remove the old tab from the tab order. 15389 // If we're opening from collapsed state, remove the previous tab from the tab order. 15390 // If we're collapsing, then keep the collapsing tab in the tab order. 15391 if ( toShow.length && toHide.length ) { 15392 eventData.oldTab.attr( "tabIndex", -1 ); 15393 } else if ( toShow.length ) { 15394 this.tabs.filter( function() { 15395 return $( this ).attr( "tabIndex" ) === 0; 15396 } ) 15397 .attr( "tabIndex", -1 ); 15398 } 15399 15400 toShow.attr( "aria-hidden", "false" ); 15401 eventData.newTab.attr( { 15402 "aria-selected": "true", 15403 "aria-expanded": "true", 15404 tabIndex: 0 15405 } ); 15406 }, 15407 15408 _activate: function( index ) { 15409 var anchor, 15410 active = this._findActive( index ); 15411 15412 // Trying to activate the already active panel 15413 if ( active[ 0 ] === this.active[ 0 ] ) { 15414 return; 15415 } 15416 15417 // Trying to collapse, simulate a click on the current active header 15418 if ( !active.length ) { 15419 active = this.active; 15420 } 15421 15422 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15423 this._eventHandler( { 15424 target: anchor, 15425 currentTarget: anchor, 15426 preventDefault: $.noop 15427 } ); 15428 }, 15429 15430 _findActive: function( index ) { 15431 return index === false ? $() : this.tabs.eq( index ); 15432 }, 15433 15434 _getIndex: function( index ) { 15435 15436 // meta-function to give users option to provide a href string instead of a numerical index. 15437 if ( typeof index === "string" ) { 15438 index = this.anchors.index( this.anchors.filter( "[href$='" + 15439 $.ui.escapeSelector( index ) + "']" ) ); 15440 } 15441 15442 return index; 15443 }, 15444 15445 _destroy: function() { 15446 if ( this.xhr ) { 15447 this.xhr.abort(); 15448 } 15449 15450 this.tablist 15451 .removeAttr( "role" ) 15452 .off( this.eventNamespace ); 15453 15454 this.anchors 15455 .removeAttr( "role tabIndex" ) 15456 .removeUniqueId(); 15457 15458 this.tabs.add( this.panels ).each( function() { 15459 if ( $.data( this, "ui-tabs-destroy" ) ) { 15460 $( this ).remove(); 15461 } else { 15462 $( this ).removeAttr( "role tabIndex " + 15463 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 15464 } 15465 } ); 15466 15467 this.tabs.each( function() { 15468 var li = $( this ), 15469 prev = li.data( "ui-tabs-aria-controls" ); 15470 if ( prev ) { 15471 li 15472 .attr( "aria-controls", prev ) 15473 .removeData( "ui-tabs-aria-controls" ); 15474 } else { 15475 li.removeAttr( "aria-controls" ); 15476 } 15477 } ); 15478 15479 this.panels.show(); 15480 15481 if ( this.options.heightStyle !== "content" ) { 15482 this.panels.css( "height", "" ); 15483 } 15484 }, 15485 15486 enable: function( index ) { 15487 var disabled = this.options.disabled; 15488 if ( disabled === false ) { 15489 return; 15490 } 15491 15492 if ( index === undefined ) { 15493 disabled = false; 15494 } else { 15495 index = this._getIndex( index ); 15496 if ( $.isArray( disabled ) ) { 15497 disabled = $.map( disabled, function( num ) { 15498 return num !== index ? num : null; 15499 } ); 15500 } else { 15501 disabled = $.map( this.tabs, function( li, num ) { 15502 return num !== index ? num : null; 15503 } ); 15504 } 15505 } 15506 this._setOptionDisabled( disabled ); 15507 }, 15508 15509 disable: function( index ) { 15510 var disabled = this.options.disabled; 15511 if ( disabled === true ) { 15512 return; 15513 } 15514 15515 if ( index === undefined ) { 15516 disabled = true; 15517 } else { 15518 index = this._getIndex( index ); 15519 if ( $.inArray( index, disabled ) !== -1 ) { 15520 return; 15521 } 15522 if ( $.isArray( disabled ) ) { 15523 disabled = $.merge( [ index ], disabled ).sort(); 15524 } else { 15525 disabled = [ index ]; 15526 } 15527 } 15528 this._setOptionDisabled( disabled ); 15529 }, 15530 15531 load: function( index, event ) { 15532 index = this._getIndex( index ); 15533 var that = this, 15534 tab = this.tabs.eq( index ), 15535 anchor = tab.find( ".ui-tabs-anchor" ), 15536 panel = this._getPanelForTab( tab ), 15537 eventData = { 15538 tab: tab, 15539 panel: panel 15540 }, 15541 complete = function( jqXHR, status ) { 15542 if ( status === "abort" ) { 15543 that.panels.stop( false, true ); 15544 } 15545 15546 that._removeClass( tab, "ui-tabs-loading" ); 15547 panel.removeAttr( "aria-busy" ); 15548 15549 if ( jqXHR === that.xhr ) { 15550 delete that.xhr; 15551 } 15552 }; 15553 15554 // Not remote 15555 if ( this._isLocal( anchor[ 0 ] ) ) { 15556 return; 15557 } 15558 15559 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 15560 15561 // Support: jQuery <1.8 15562 // jQuery <1.8 returns false if the request is canceled in beforeSend, 15563 // but as of 1.8, $.ajax() always returns a jqXHR object. 15564 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 15565 this._addClass( tab, "ui-tabs-loading" ); 15566 panel.attr( "aria-busy", "true" ); 15567 15568 this.xhr 15569 .done( function( response, status, jqXHR ) { 15570 15571 // support: jQuery <1.8 15572 // http://bugs.jquery.com/ticket/11778 15573 setTimeout( function() { 15574 panel.html( response ); 15575 that._trigger( "load", event, eventData ); 15576 15577 complete( jqXHR, status ); 15578 }, 1 ); 15579 } ) 15580 .fail( function( jqXHR, status ) { 15581 15582 // support: jQuery <1.8 15583 // http://bugs.jquery.com/ticket/11778 15584 setTimeout( function() { 15585 complete( jqXHR, status ); 15586 }, 1 ); 15587 } ); 15588 } 15589 }, 15590 15591 _ajaxSettings: function( anchor, event, eventData ) { 15592 var that = this; 15593 return { 15594 15595 // Support: IE <11 only 15596 // Strip any hash that exists to prevent errors with the Ajax request 15597 url: anchor.attr( "href" ).replace( /#.*$/, "" ), 15598 beforeSend: function( jqXHR, settings ) { 15599 return that._trigger( "beforeLoad", event, 15600 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 15601 } 15602 }; 15603 }, 15604 15605 _getPanelForTab: function( tab ) { 15606 var id = $( tab ).attr( "aria-controls" ); 15607 return this.element.find( this._sanitizeSelector( "#" + id ) ); 15608 } 15609} ); 15610 15611// DEPRECATED 15612// TODO: Switch return back to widget declaration at top of file when this is removed 15613if ( $.uiBackCompat !== false ) { 15614 15615 // Backcompat for ui-tab class (now ui-tabs-tab) 15616 $.widget( "ui.tabs", $.ui.tabs, { 15617 _processTabs: function() { 15618 this._superApply( arguments ); 15619 this._addClass( this.tabs, "ui-tab" ); 15620 } 15621 } ); 15622} 15623 15624var widgetsTabs = $.ui.tabs; 15625 15626 15627/*! 15628 * jQuery UI Tooltip 1.12.1 15629 * http://jqueryui.com 15630 * 15631 * Copyright jQuery Foundation and other contributors 15632 * Released under the MIT license. 15633 * http://jquery.org/license 15634 */ 15635 15636//>>label: Tooltip 15637//>>group: Widgets 15638//>>description: Shows additional information for any element on hover or focus. 15639//>>docs: http://api.jqueryui.com/tooltip/ 15640//>>demos: http://jqueryui.com/tooltip/ 15641//>>css.structure: ../../themes/base/core.css 15642//>>css.structure: ../../themes/base/tooltip.css 15643//>>css.theme: ../../themes/base/theme.css 15644 15645 15646 15647$.widget( "ui.tooltip", { 15648 version: "1.12.1", 15649 options: { 15650 classes: { 15651 "ui-tooltip": "ui-corner-all ui-widget-shadow" 15652 }, 15653 content: function() { 15654 15655 // support: IE<9, Opera in jQuery <1.7 15656 // .text() can't accept undefined, so coerce to a string 15657 var title = $( this ).attr( "title" ) || ""; 15658 15659 // Escape title, since we're going from an attribute to raw HTML 15660 return $( "<a>" ).text( title ).html(); 15661 }, 15662 hide: true, 15663 15664 // Disabled elements have inconsistent behavior across browsers (#8661) 15665 items: "[title]:not([disabled])", 15666 position: { 15667 my: "left top+15", 15668 at: "left bottom", 15669 collision: "flipfit flip" 15670 }, 15671 show: true, 15672 track: false, 15673 15674 // Callbacks 15675 close: null, 15676 open: null 15677 }, 15678 15679 _addDescribedBy: function( elem, id ) { 15680 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 15681 describedby.push( id ); 15682 elem 15683 .data( "ui-tooltip-id", id ) 15684 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 15685 }, 15686 15687 _removeDescribedBy: function( elem ) { 15688 var id = elem.data( "ui-tooltip-id" ), 15689 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 15690 index = $.inArray( id, describedby ); 15691 15692 if ( index !== -1 ) { 15693 describedby.splice( index, 1 ); 15694 } 15695 15696 elem.removeData( "ui-tooltip-id" ); 15697 describedby = $.trim( describedby.join( " " ) ); 15698 if ( describedby ) { 15699 elem.attr( "aria-describedby", describedby ); 15700 } else { 15701 elem.removeAttr( "aria-describedby" ); 15702 } 15703 }, 15704 15705 _create: function() { 15706 this._on( { 15707 mouseover: "open", 15708 focusin: "open" 15709 } ); 15710 15711 // IDs of generated tooltips, needed for destroy 15712 this.tooltips = {}; 15713 15714 // IDs of parent tooltips where we removed the title attribute 15715 this.parents = {}; 15716 15717 // Append the aria-live region so tooltips announce correctly 15718 this.liveRegion = $( "<div>" ) 15719 .attr( { 15720 role: "log", 15721 "aria-live": "assertive", 15722 "aria-relevant": "additions" 15723 } ) 15724 .appendTo( this.document[ 0 ].body ); 15725 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 15726 15727 this.disabledTitles = $( [] ); 15728 }, 15729 15730 _setOption: function( key, value ) { 15731 var that = this; 15732 15733 this._super( key, value ); 15734 15735 if ( key === "content" ) { 15736 $.each( this.tooltips, function( id, tooltipData ) { 15737 that._updateContent( tooltipData.element ); 15738 } ); 15739 } 15740 }, 15741 15742 _setOptionDisabled: function( value ) { 15743 this[ value ? "_disable" : "_enable" ](); 15744 }, 15745 15746 _disable: function() { 15747 var that = this; 15748 15749 // Close open tooltips 15750 $.each( this.tooltips, function( id, tooltipData ) { 15751 var event = $.Event( "blur" ); 15752 event.target = event.currentTarget = tooltipData.element[ 0 ]; 15753 that.close( event, true ); 15754 } ); 15755 15756 // Remove title attributes to prevent native tooltips 15757 this.disabledTitles = this.disabledTitles.add( 15758 this.element.find( this.options.items ).addBack() 15759 .filter( function() { 15760 var element = $( this ); 15761 if ( element.is( "[title]" ) ) { 15762 return element 15763 .data( "ui-tooltip-title", element.attr( "title" ) ) 15764 .removeAttr( "title" ); 15765 } 15766 } ) 15767 ); 15768 }, 15769 15770 _enable: function() { 15771 15772 // restore title attributes 15773 this.disabledTitles.each( function() { 15774 var element = $( this ); 15775 if ( element.data( "ui-tooltip-title" ) ) { 15776 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15777 } 15778 } ); 15779 this.disabledTitles = $( [] ); 15780 }, 15781 15782 open: function( event ) { 15783 var that = this, 15784 target = $( event ? event.target : this.element ) 15785 15786 // we need closest here due to mouseover bubbling, 15787 // but always pointing at the same event target 15788 .closest( this.options.items ); 15789 15790 // No element to show a tooltip for or the tooltip is already open 15791 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 15792 return; 15793 } 15794 15795 if ( target.attr( "title" ) ) { 15796 target.data( "ui-tooltip-title", target.attr( "title" ) ); 15797 } 15798 15799 target.data( "ui-tooltip-open", true ); 15800 15801 // Kill parent tooltips, custom or native, for hover 15802 if ( event && event.type === "mouseover" ) { 15803 target.parents().each( function() { 15804 var parent = $( this ), 15805 blurEvent; 15806 if ( parent.data( "ui-tooltip-open" ) ) { 15807 blurEvent = $.Event( "blur" ); 15808 blurEvent.target = blurEvent.currentTarget = this; 15809 that.close( blurEvent, true ); 15810 } 15811 if ( parent.attr( "title" ) ) { 15812 parent.uniqueId(); 15813 that.parents[ this.id ] = { 15814 element: this, 15815 title: parent.attr( "title" ) 15816 }; 15817 parent.attr( "title", "" ); 15818 } 15819 } ); 15820 } 15821 15822 this._registerCloseHandlers( event, target ); 15823 this._updateContent( target, event ); 15824 }, 15825 15826 _updateContent: function( target, event ) { 15827 var content, 15828 contentOption = this.options.content, 15829 that = this, 15830 eventType = event ? event.type : null; 15831 15832 if ( typeof contentOption === "string" || contentOption.nodeType || 15833 contentOption.jquery ) { 15834 return this._open( event, target, contentOption ); 15835 } 15836 15837 content = contentOption.call( target[ 0 ], function( response ) { 15838 15839 // IE may instantly serve a cached response for ajax requests 15840 // delay this call to _open so the other call to _open runs first 15841 that._delay( function() { 15842 15843 // Ignore async response if tooltip was closed already 15844 if ( !target.data( "ui-tooltip-open" ) ) { 15845 return; 15846 } 15847 15848 // JQuery creates a special event for focusin when it doesn't 15849 // exist natively. To improve performance, the native event 15850 // object is reused and the type is changed. Therefore, we can't 15851 // rely on the type being correct after the event finished 15852 // bubbling, so we set it back to the previous value. (#8740) 15853 if ( event ) { 15854 event.type = eventType; 15855 } 15856 this._open( event, target, response ); 15857 } ); 15858 } ); 15859 if ( content ) { 15860 this._open( event, target, content ); 15861 } 15862 }, 15863 15864 _open: function( event, target, content ) { 15865 var tooltipData, tooltip, delayedShow, a11yContent, 15866 positionOption = $.extend( {}, this.options.position ); 15867 15868 if ( !content ) { 15869 return; 15870 } 15871 15872 // Content can be updated multiple times. If the tooltip already 15873 // exists, then just update the content and bail. 15874 tooltipData = this._find( target ); 15875 if ( tooltipData ) { 15876 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 15877 return; 15878 } 15879 15880 // If we have a title, clear it to prevent the native tooltip 15881 // we have to check first to avoid defining a title if none exists 15882 // (we don't want to cause an element to start matching [title]) 15883 // 15884 // We use removeAttr only for key events, to allow IE to export the correct 15885 // accessible attributes. For mouse events, set to empty string to avoid 15886 // native tooltip showing up (happens only when removing inside mouseover). 15887 if ( target.is( "[title]" ) ) { 15888 if ( event && event.type === "mouseover" ) { 15889 target.attr( "title", "" ); 15890 } else { 15891 target.removeAttr( "title" ); 15892 } 15893 } 15894 15895 tooltipData = this._tooltip( target ); 15896 tooltip = tooltipData.tooltip; 15897 this._addDescribedBy( target, tooltip.attr( "id" ) ); 15898 tooltip.find( ".ui-tooltip-content" ).html( content ); 15899 15900 // Support: Voiceover on OS X, JAWS on IE <= 9 15901 // JAWS announces deletions even when aria-relevant="additions" 15902 // Voiceover will sometimes re-read the entire log region's contents from the beginning 15903 this.liveRegion.children().hide(); 15904 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 15905 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 15906 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 15907 a11yContent.appendTo( this.liveRegion ); 15908 15909 function position( event ) { 15910 positionOption.of = event; 15911 if ( tooltip.is( ":hidden" ) ) { 15912 return; 15913 } 15914 tooltip.position( positionOption ); 15915 } 15916 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 15917 this._on( this.document, { 15918 mousemove: position 15919 } ); 15920 15921 // trigger once to override element-relative positioning 15922 position( event ); 15923 } else { 15924 tooltip.position( $.extend( { 15925 of: target 15926 }, this.options.position ) ); 15927 } 15928 15929 tooltip.hide(); 15930 15931 this._show( tooltip, this.options.show ); 15932 15933 // Handle tracking tooltips that are shown with a delay (#8644). As soon 15934 // as the tooltip is visible, position the tooltip using the most recent 15935 // event. 15936 // Adds the check to add the timers only when both delay and track options are set (#14682) 15937 if ( this.options.track && this.options.show && this.options.show.delay ) { 15938 delayedShow = this.delayedShow = setInterval( function() { 15939 if ( tooltip.is( ":visible" ) ) { 15940 position( positionOption.of ); 15941 clearInterval( delayedShow ); 15942 } 15943 }, $.fx.interval ); 15944 } 15945 15946 this._trigger( "open", event, { tooltip: tooltip } ); 15947 }, 15948 15949 _registerCloseHandlers: function( event, target ) { 15950 var events = { 15951 keyup: function( event ) { 15952 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 15953 var fakeEvent = $.Event( event ); 15954 fakeEvent.currentTarget = target[ 0 ]; 15955 this.close( fakeEvent, true ); 15956 } 15957 } 15958 }; 15959 15960 // Only bind remove handler for delegated targets. Non-delegated 15961 // tooltips will handle this in destroy. 15962 if ( target[ 0 ] !== this.element[ 0 ] ) { 15963 events.remove = function() { 15964 this._removeTooltip( this._find( target ).tooltip ); 15965 }; 15966 } 15967 15968 if ( !event || event.type === "mouseover" ) { 15969 events.mouseleave = "close"; 15970 } 15971 if ( !event || event.type === "focusin" ) { 15972 events.focusout = "close"; 15973 } 15974 this._on( true, target, events ); 15975 }, 15976 15977 close: function( event ) { 15978 var tooltip, 15979 that = this, 15980 target = $( event ? event.currentTarget : this.element ), 15981 tooltipData = this._find( target ); 15982 15983 // The tooltip may already be closed 15984 if ( !tooltipData ) { 15985
vendor: 17,492 bytes, lines 15986-16686
15986 // We set ui-tooltip-open immediately upon open (in open()), but only set the 15987 // additional data once there's actually content to show (in _open()). So even if the 15988 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 15989 // the period between open() and _open(). 15990 target.removeData( "ui-tooltip-open" ); 15991 return; 15992 } 15993 15994 tooltip = tooltipData.tooltip; 15995 15996 // Disabling closes the tooltip, so we need to track when we're closing 15997 // to avoid an infinite loop in case the tooltip becomes disabled on close 15998 if ( tooltipData.closing ) { 15999 return; 16000 } 16001 16002 // Clear the interval for delayed tracking tooltips 16003 clearInterval( this.delayedShow ); 16004 16005 // Only set title if we had one before (see comment in _open()) 16006 // If the title attribute has changed since open(), don't restore 16007 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16008 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16009 } 16010 16011 this._removeDescribedBy( target ); 16012 16013 tooltipData.hiding = true; 16014 tooltip.stop( true ); 16015 this._hide( tooltip, this.options.hide, function() { 16016 that._removeTooltip( $( this ) ); 16017 } ); 16018 16019 target.removeData( "ui-tooltip-open" ); 16020 this._off( target, "mouseleave focusout keyup" ); 16021 16022 // Remove 'remove' binding only on delegated targets 16023 if ( target[ 0 ] !== this.element[ 0 ] ) { 16024 this._off( target, "remove" ); 16025 } 16026 this._off( this.document, "mousemove" ); 16027 16028 if ( event && event.type === "mouseleave" ) { 16029 $.each( this.parents, function( id, parent ) { 16030 $( parent.element ).attr( "title", parent.title ); 16031 delete that.parents[ id ]; 16032 } ); 16033 } 16034 16035 tooltipData.closing = true; 16036 this._trigger( "close", event, { tooltip: tooltip } ); 16037 if ( !tooltipData.hiding ) { 16038 tooltipData.closing = false; 16039 } 16040 }, 16041 16042 _tooltip: function( element ) { 16043 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 16044 content = $( "<div>" ).appendTo( tooltip ), 16045 id = tooltip.uniqueId().attr( "id" ); 16046 16047 this._addClass( content, "ui-tooltip-content" ); 16048 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 16049 16050 tooltip.appendTo( this._appendTo( element ) ); 16051 16052 return this.tooltips[ id ] = { 16053 element: element, 16054 tooltip: tooltip 16055 }; 16056 }, 16057 16058 _find: function( target ) { 16059 var id = target.data( "ui-tooltip-id" ); 16060 return id ? this.tooltips[ id ] : null; 16061 }, 16062 16063 _removeTooltip: function( tooltip ) { 16064 tooltip.remove(); 16065 delete this.tooltips[ tooltip.attr( "id" ) ]; 16066 }, 16067 16068 _appendTo: function( target ) { 16069 var element = target.closest( ".ui-front, dialog" ); 16070 16071 if ( !element.length ) { 16072 element = this.document[ 0 ].body; 16073 } 16074 16075 return element; 16076 }, 16077 16078 _destroy: function() { 16079 var that = this; 16080 16081 // Close open tooltips 16082 $.each( this.tooltips, function( id, tooltipData ) { 16083 16084 // Delegate to close method to handle common cleanup 16085 var event = $.Event( "blur" ), 16086 element = tooltipData.element; 16087 event.target = event.currentTarget = element[ 0 ]; 16088 that.close( event, true ); 16089 16090 // Remove immediately; destroying an open tooltip doesn't use the 16091 // hide animation 16092 $( "#" + id ).remove(); 16093 16094 // Restore the title 16095 if ( element.data( "ui-tooltip-title" ) ) { 16096 16097 // If the title attribute has changed since open(), don't restore 16098 if ( !element.attr( "title" ) ) { 16099 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16100 } 16101 element.removeData( "ui-tooltip-title" ); 16102 } 16103 } ); 16104 this.liveRegion.remove(); 16105 } 16106} ); 16107 16108// DEPRECATED 16109// TODO: Switch return back to widget declaration at top of file when this is removed 16110if ( $.uiBackCompat !== false ) { 16111 16112 // Backcompat for tooltipClass option 16113 $.widget( "ui.tooltip", $.ui.tooltip, { 16114 options: { 16115 tooltipClass: null 16116 }, 16117 _tooltip: function() { 16118 var tooltipData = this._superApply( arguments ); 16119 if ( this.options.tooltipClass ) { 16120 tooltipData.tooltip.addClass( this.options.tooltipClass ); 16121 } 16122 return tooltipData; 16123 } 16124 } ); 16125} 16126 16127var widgetsTooltip = $.ui.tooltip; 16128 16129 16130/*! 16131 * jQuery UI Effects 1.12.1 16132 * http://jqueryui.com 16133 * 16134 * Copyright jQuery Foundation and other contributors 16135 * Released under the MIT license. 16136 * http://jquery.org/license 16137 */ 16138 16139//>>label: Effects Core 16140//>>group: Effects 16141// jscs:disable maximumLineLength 16142//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 16143// jscs:enable maximumLineLength 16144//>>docs: http://api.jqueryui.com/category/effects-core/ 16145//>>demos: http://jqueryui.com/effect/ 16146 16147 16148 16149var dataSpace = "ui-effects-", 16150 dataSpaceStyle = "ui-effects-style", 16151 dataSpaceAnimated = "ui-effects-animated", 16152 16153 // Create a local jQuery because jQuery Color relies on it and the 16154 // global may not exist with AMD and a custom build (#10199) 16155 jQuery = $; 16156 16157$.effects = { 16158 effect: {} 16159}; 16160 16161/*! 16162 * jQuery Color Animations v2.1.2 16163 * https://github.com/jquery/jquery-color 16164 * 16165 * Copyright 2014 jQuery Foundation and other contributors 16166 * Released under the MIT license. 16167 * http://jquery.org/license 16168 * 16169 * Date: Wed Jan 16 08:47:09 2013 -0600 16170 */ 16171( function( jQuery, undefined ) { 16172 16173 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 16174 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 16175 16176 // Plusequals test for += 100 -= 100 16177 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 16178 16179 // A set of RE's that can match strings and generate color tuples. 16180 stringParsers = [ { 16181 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16182 parse: function( execResult ) { 16183 return [ 16184 execResult[ 1 ], 16185 execResult[ 2 ], 16186 execResult[ 3 ], 16187 execResult[ 4 ] 16188 ]; 16189 } 16190 }, { 16191 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16192 parse: function( execResult ) { 16193 return [ 16194 execResult[ 1 ] * 2.55, 16195 execResult[ 2 ] * 2.55, 16196 execResult[ 3 ] * 2.55, 16197 execResult[ 4 ] 16198 ]; 16199 } 16200 }, { 16201 16202 // This regex ignores A-F because it's compared against an already lowercased string 16203 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 16204 parse: function( execResult ) { 16205 return [ 16206 parseInt( execResult[ 1 ], 16 ), 16207 parseInt( execResult[ 2 ], 16 ), 16208 parseInt( execResult[ 3 ], 16 ) 16209 ]; 16210 } 16211 }, { 16212 16213 // This regex ignores A-F because it's compared against an already lowercased string 16214 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 16215 parse: function( execResult ) { 16216 return [ 16217 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 16218 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 16219 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 16220 ]; 16221 } 16222 }, { 16223 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 16224 space: "hsla", 16225 parse: function( execResult ) { 16226 return [ 16227 execResult[ 1 ], 16228 execResult[ 2 ] / 100, 16229 execResult[ 3 ] / 100, 16230 execResult[ 4 ] 16231 ]; 16232 } 16233 } ], 16234 16235 // JQuery.Color( ) 16236 color = jQuery.Color = function( color, green, blue, alpha ) { 16237 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 16238 }, 16239 spaces = { 16240 rgba: { 16241 props: { 16242 red: { 16243 idx: 0, 16244 type: "byte" 16245 }, 16246 green: { 16247 idx: 1, 16248 type: "byte" 16249 }, 16250 blue: { 16251 idx: 2, 16252 type: "byte" 16253 } 16254 } 16255 }, 16256 16257 hsla: { 16258 props: { 16259 hue: { 16260 idx: 0, 16261 type: "degrees" 16262 }, 16263 saturation: { 16264 idx: 1, 16265 type: "percent" 16266 }, 16267 lightness: { 16268 idx: 2, 16269 type: "percent" 16270 } 16271 } 16272 } 16273 }, 16274 propTypes = { 16275 "byte": { 16276 floor: true, 16277 max: 255 16278 }, 16279 "percent": { 16280 max: 1 16281 }, 16282 "degrees": { 16283 mod: 360, 16284 floor: true 16285 } 16286 }, 16287 support = color.support = {}, 16288 16289 // Element for support tests 16290 supportElem = jQuery( "<p>" )[ 0 ], 16291 16292 // Colors = jQuery.Color.names 16293 colors, 16294 16295 // Local aliases of functions called often 16296 each = jQuery.each; 16297 16298// Determine rgba support immediately 16299supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 16300support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 16301 16302// Define cache name and alpha properties 16303// for rgba and hsla spaces 16304each( spaces, function( spaceName, space ) { 16305 space.cache = "_" + spaceName; 16306 space.props.alpha = { 16307 idx: 3, 16308 type: "percent", 16309 def: 1 16310 }; 16311} ); 16312 16313function clamp( value, prop, allowEmpty ) { 16314 var type = propTypes[ prop.type ] || {}; 16315 16316 if ( value == null ) { 16317 return ( allowEmpty || !prop.def ) ? null : prop.def; 16318 } 16319 16320 // ~~ is an short way of doing floor for positive numbers 16321 value = type.floor ? ~~value : parseFloat( value ); 16322 16323 // IE will pass in empty strings as value for alpha, 16324 // which will hit this case 16325 if ( isNaN( value ) ) { 16326 return prop.def; 16327 } 16328 16329 if ( type.mod ) { 16330 16331 // We add mod before modding to make sure that negatives values 16332 // get converted properly: -10 -> 350 16333 return ( value + type.mod ) % type.mod; 16334 } 16335 16336 // For now all property types without mod have min and max 16337 return 0 > value ? 0 : type.max < value ? type.max : value; 16338} 16339 16340function stringParse( string ) { 16341 var inst = color(), 16342 rgba = inst._rgba = []; 16343 16344 string = string.toLowerCase(); 16345 16346 each( stringParsers, function( i, parser ) { 16347 var parsed, 16348 match = parser.re.exec( string ), 16349 values = match && parser.parse( match ), 16350 spaceName = parser.space || "rgba"; 16351 16352 if ( values ) { 16353 parsed = inst[ spaceName ]( values ); 16354 16355 // If this was an rgba parse the assignment might happen twice 16356 // oh well.... 16357 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 16358 rgba = inst._rgba = parsed._rgba; 16359 16360 // Exit each( stringParsers ) here because we matched 16361 return false; 16362 } 16363 } ); 16364 16365 // Found a stringParser that handled it 16366 if ( rgba.length ) { 16367 16368 // If this came from a parsed string, force "transparent" when alpha is 0 16369 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 16370 if ( rgba.join() === "0,0,0,0" ) { 16371 jQuery.extend( rgba, colors.transparent ); 16372 } 16373 return inst; 16374 } 16375 16376 // Named colors 16377 return colors[ string ]; 16378} 16379 16380color.fn = jQuery.extend( color.prototype, { 16381 parse: function( red, green, blue, alpha ) { 16382 if ( red === undefined ) { 16383 this._rgba = [ null, null, null, null ]; 16384 return this; 16385 } 16386 if ( red.jquery || red.nodeType ) { 16387 red = jQuery( red ).css( green ); 16388 green = undefined; 16389 } 16390 16391 var inst = this, 16392 type = jQuery.type( red ), 16393 rgba = this._rgba = []; 16394 16395 // More than 1 argument specified - assume ( red, green, blue, alpha ) 16396 if ( green !== undefined ) { 16397 red = [ red, green, blue, alpha ]; 16398 type = "array"; 16399 } 16400 16401 if ( type === "string" ) { 16402 return this.parse( stringParse( red ) || colors._default ); 16403 } 16404 16405 if ( type === "array" ) { 16406 each( spaces.rgba.props, function( key, prop ) { 16407 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 16408 } ); 16409 return this; 16410 } 16411 16412 if ( type === "object" ) { 16413 if ( red instanceof color ) { 16414 each( spaces, function( spaceName, space ) { 16415 if ( red[ space.cache ] ) { 16416 inst[ space.cache ] = red[ space.cache ].slice(); 16417 } 16418 } ); 16419 } else { 16420 each( spaces, function( spaceName, space ) { 16421 var cache = space.cache; 16422 each( space.props, function( key, prop ) { 16423 16424 // If the cache doesn't exist, and we know how to convert 16425 if ( !inst[ cache ] && space.to ) { 16426 16427 // If the value was null, we don't need to copy it 16428 // if the key was alpha, we don't need to copy it either 16429 if ( key === "alpha" || red[ key ] == null ) { 16430 return; 16431 } 16432 inst[ cache ] = space.to( inst._rgba ); 16433 } 16434 16435 // This is the only case where we allow nulls for ALL properties. 16436 // call clamp with alwaysAllowEmpty 16437 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 16438 } ); 16439 16440 // Everything defined but alpha? 16441 if ( inst[ cache ] && 16442 jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 16443 16444 // Use the default of 1 16445 inst[ cache ][ 3 ] = 1; 16446 if ( space.from ) { 16447 inst._rgba = space.from( inst[ cache ] ); 16448 } 16449 } 16450 } ); 16451 } 16452 return this; 16453 } 16454 }, 16455 is: function( compare ) { 16456 var is = color( compare ), 16457 same = true, 16458 inst = this; 16459 16460 each( spaces, function( _, space ) { 16461 var localCache, 16462 isCache = is[ space.cache ]; 16463 if ( isCache ) { 16464 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 16465 each( space.props, function( _, prop ) { 16466 if ( isCache[ prop.idx ] != null ) { 16467 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 16468 return same; 16469 } 16470 } ); 16471 } 16472 return same; 16473 } ); 16474 return same; 16475 }, 16476 _space: function() { 16477 var used = [], 16478 inst = this; 16479 each( spaces, function( spaceName, space ) { 16480 if ( inst[ space.cache ] ) { 16481 used.push( spaceName ); 16482 } 16483 } ); 16484 return used.pop(); 16485 }, 16486 transition: function( other, distance ) { 16487 var end = color( other ), 16488 spaceName = end._space(), 16489 space = spaces[ spaceName ], 16490 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 16491 start = startColor[ space.cache ] || space.to( startColor._rgba ), 16492 result = start.slice(); 16493 16494 end = end[ space.cache ]; 16495 each( space.props, function( key, prop ) { 16496 var index = prop.idx, 16497 startValue = start[ index ], 16498 endValue = end[ index ], 16499 type = propTypes[ prop.type ] || {}; 16500 16501 // If null, don't override start value 16502 if ( endValue === null ) { 16503 return; 16504 } 16505 16506 // If null - use end 16507 if ( startValue === null ) { 16508 result[ index ] = endValue; 16509 } else { 16510 if ( type.mod ) { 16511 if ( endValue - startValue > type.mod / 2 ) { 16512 startValue += type.mod; 16513 } else if ( startValue - endValue > type.mod / 2 ) { 16514 startValue -= type.mod; 16515 } 16516 } 16517 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 16518 } 16519 } ); 16520 return this[ spaceName ]( result ); 16521 }, 16522 blend: function( opaque ) { 16523 16524 // If we are already opaque - return ourself 16525 if ( this._rgba[ 3 ] === 1 ) { 16526 return this; 16527 } 16528 16529 var rgb = this._rgba.slice(), 16530 a = rgb.pop(), 16531 blend = color( opaque )._rgba; 16532 16533 return color( jQuery.map( rgb, function( v, i ) { 16534 return ( 1 - a ) * blend[ i ] + a * v; 16535 } ) ); 16536 }, 16537 toRgbaString: function() { 16538 var prefix = "rgba(", 16539 rgba = jQuery.map( this._rgba, function( v, i ) { 16540 return v == null ? ( i > 2 ? 1 : 0 ) : v; 16541 } ); 16542 16543 if ( rgba[ 3 ] === 1 ) { 16544 rgba.pop(); 16545 prefix = "rgb("; 16546 } 16547 16548 return prefix + rgba.join() + ")"; 16549 }, 16550 toHslaString: function() { 16551 var prefix = "hsla(", 16552 hsla = jQuery.map( this.hsla(), function( v, i ) { 16553 if ( v == null ) { 16554 v = i > 2 ? 1 : 0; 16555 } 16556 16557 // Catch 1 and 2 16558 if ( i && i < 3 ) { 16559 v = Math.round( v * 100 ) + "%"; 16560 } 16561 return v; 16562 } ); 16563 16564 if ( hsla[ 3 ] === 1 ) { 16565 hsla.pop(); 16566 prefix = "hsl("; 16567 } 16568 return prefix + hsla.join() + ")"; 16569 }, 16570 toHexString: function( includeAlpha ) { 16571 var rgba = this._rgba.slice(), 16572 alpha = rgba.pop(); 16573 16574 if ( includeAlpha ) { 16575 rgba.push( ~~( alpha * 255 ) ); 16576 } 16577 16578 return "#" + jQuery.map( rgba, function( v ) { 16579 16580 // Default to 0 when nulls exist 16581 v = ( v || 0 ).toString( 16 ); 16582 return v.length === 1 ? "0" + v : v; 16583 } ).join( "" ); 16584 }, 16585 toString: function() { 16586 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 16587 } 16588} ); 16589color.fn.parse.prototype = color.fn; 16590 16591// Hsla conversions adapted from: 16592// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 16593 16594function hue2rgb( p, q, h ) { 16595 h = ( h + 1 ) % 1; 16596 if ( h * 6 < 1 ) { 16597 return p + ( q - p ) * h * 6; 16598 } 16599 if ( h * 2 < 1 ) { 16600 return q; 16601 } 16602 if ( h * 3 < 2 ) { 16603 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 16604 } 16605 return p; 16606} 16607 16608spaces.hsla.to = function( rgba ) { 16609 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 16610 return [ null, null, null, rgba[ 3 ] ]; 16611 } 16612 var r = rgba[ 0 ] / 255, 16613 g = rgba[ 1 ] / 255, 16614 b = rgba[ 2 ] / 255, 16615 a = rgba[ 3 ], 16616 max = Math.max( r, g, b ), 16617 min = Math.min( r, g, b ), 16618 diff = max - min, 16619 add = max + min, 16620 l = add * 0.5, 16621 h, s; 16622 16623 if ( min === max ) { 16624 h = 0; 16625 } else if ( r === max ) { 16626 h = ( 60 * ( g - b ) / diff ) + 360; 16627 } else if ( g === max ) { 16628 h = ( 60 * ( b - r ) / diff ) + 120; 16629 } else { 16630 h = ( 60 * ( r - g ) / diff ) + 240; 16631 } 16632 16633 // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 16634 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 16635 if ( diff === 0 ) { 16636 s = 0; 16637 } else if ( l <= 0.5 ) { 16638 s = diff / add; 16639 } else { 16640 s = diff / ( 2 - add ); 16641 } 16642 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 16643}; 16644 16645spaces.hsla.from = function( hsla ) { 16646 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 16647 return [ null, null, null, hsla[ 3 ] ]; 16648 } 16649 var h = hsla[ 0 ] / 360, 16650 s = hsla[ 1 ], 16651 l = hsla[ 2 ], 16652 a = hsla[ 3 ], 16653 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 16654 p = 2 * l - q; 16655 16656 return [ 16657 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 16658 Math.round( hue2rgb( p, q, h ) * 255 ), 16659 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 16660 a 16661 ]; 16662}; 16663 16664each( spaces, function( spaceName, space ) { 16665 var props = space.props, 16666 cache = space.cache, 16667 to = space.to, 16668 from = space.from; 16669 16670 // Makes rgba() and hsla() 16671 color.fn[ spaceName ] = function( value ) { 16672 16673 // Generate a cache for this space if it doesn't exist 16674 if ( to && !this[ cache ] ) { 16675 this[ cache ] = to( this._rgba ); 16676 } 16677 if ( value === undefined ) { 16678 return this[ cache ].slice(); 16679 } 16680 16681 var ret, 16682 type = jQuery.type( value ), 16683 arr = ( type === "array" || type === "object" ) ? value : arguments, 16684 local = this[ cache ].slice(); 16685 16686 each( props, function( key, prop ) {
vendor: 50,833 bytes, lines 16687-18672
16687 var val = arr[ type === "object" ? key : prop.idx ]; 16688 if ( val == null ) { 16689 val = local[ prop.idx ]; 16690 } 16691 local[ prop.idx ] = clamp( val, prop ); 16692 } ); 16693 16694 if ( from ) { 16695 ret = color( from( local ) ); 16696 ret[ cache ] = local; 16697 return ret; 16698 } else { 16699 return color( local ); 16700 } 16701 }; 16702 16703 // Makes red() green() blue() alpha() hue() saturation() lightness() 16704 each( props, function( key, prop ) { 16705 16706 // Alpha is included in more than one space 16707 if ( color.fn[ key ] ) { 16708 return; 16709 } 16710 color.fn[ key ] = function( value ) { 16711 var vtype = jQuery.type( value ), 16712 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 16713 local = this[ fn ](), 16714 cur = local[ prop.idx ], 16715 match; 16716 16717 if ( vtype === "undefined" ) { 16718 return cur; 16719 } 16720 16721 if ( vtype === "function" ) { 16722 value = value.call( this, cur ); 16723 vtype = jQuery.type( value ); 16724 } 16725 if ( value == null && prop.empty ) { 16726 return this; 16727 } 16728 if ( vtype === "string" ) { 16729 match = rplusequals.exec( value ); 16730 if ( match ) { 16731 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 16732 } 16733 } 16734 local[ prop.idx ] = value; 16735 return this[ fn ]( local ); 16736 }; 16737 } ); 16738} ); 16739 16740// Add cssHook and .fx.step function for each named hook. 16741// accept a space separated string of properties 16742color.hook = function( hook ) { 16743 var hooks = hook.split( " " ); 16744 each( hooks, function( i, hook ) { 16745 jQuery.cssHooks[ hook ] = { 16746 set: function( elem, value ) { 16747 var parsed, curElem, 16748 backgroundColor = ""; 16749 16750 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || 16751 ( parsed = stringParse( value ) ) ) ) { 16752 value = color( parsed || value ); 16753 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 16754 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 16755 while ( 16756 ( backgroundColor === "" || backgroundColor === "transparent" ) && 16757 curElem && curElem.style 16758 ) { 16759 try { 16760 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 16761 curElem = curElem.parentNode; 16762 } catch ( e ) { 16763 } 16764 } 16765 16766 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 16767 backgroundColor : 16768 "_default" ); 16769 } 16770 16771 value = value.toRgbaString(); 16772 } 16773 try { 16774 elem.style[ hook ] = value; 16775 } catch ( e ) { 16776 16777 // Wrapped to prevent IE from throwing errors on "invalid" values like 16778 // 'auto' or 'inherit' 16779 } 16780 } 16781 }; 16782 jQuery.fx.step[ hook ] = function( fx ) { 16783 if ( !fx.colorInit ) { 16784 fx.start = color( fx.elem, hook ); 16785 fx.end = color( fx.end ); 16786 fx.colorInit = true; 16787 } 16788 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 16789 }; 16790 } ); 16791 16792}; 16793 16794color.hook( stepHooks ); 16795 16796jQuery.cssHooks.borderColor = { 16797 expand: function( value ) { 16798 var expanded = {}; 16799 16800 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 16801 expanded[ "border" + part + "Color" ] = value; 16802 } ); 16803 return expanded; 16804 } 16805}; 16806 16807// Basic color names only. 16808// Usage of any of the other color names requires adding yourself or including 16809// jquery.color.svg-names.js. 16810colors = jQuery.Color.names = { 16811 16812 // 4.1. Basic color keywords 16813 aqua: "#00ffff", 16814 black: "#000000", 16815 blue: "#0000ff", 16816 fuchsia: "#ff00ff", 16817 gray: "#808080", 16818 green: "#008000", 16819 lime: "#00ff00", 16820 maroon: "#800000", 16821 navy: "#000080", 16822 olive: "#808000", 16823 purple: "#800080", 16824 red: "#ff0000", 16825 silver: "#c0c0c0", 16826 teal: "#008080", 16827 white: "#ffffff", 16828 yellow: "#ffff00", 16829 16830 // 4.2.3. "transparent" color keyword 16831 transparent: [ null, null, null, 0 ], 16832 16833 _default: "#ffffff" 16834}; 16835 16836} )( jQuery ); 16837 16838/******************************************************************************/ 16839/****************************** CLASS ANIMATIONS ******************************/ 16840/******************************************************************************/ 16841( function() { 16842 16843var classAnimationActions = [ "add", "remove", "toggle" ], 16844 shorthandStyles = { 16845 border: 1, 16846 borderBottom: 1, 16847 borderColor: 1, 16848 borderLeft: 1, 16849 borderRight: 1, 16850 borderTop: 1, 16851 borderWidth: 1, 16852 margin: 1, 16853 padding: 1 16854 }; 16855 16856$.each( 16857 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 16858 function( _, prop ) { 16859 $.fx.step[ prop ] = function( fx ) { 16860 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 16861 jQuery.style( fx.elem, prop, fx.end ); 16862 fx.setAttr = true; 16863 } 16864 }; 16865 } 16866); 16867 16868function getElementStyles( elem ) { 16869 var key, len, 16870 style = elem.ownerDocument.defaultView ? 16871 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 16872 elem.currentStyle, 16873 styles = {}; 16874 16875 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 16876 len = style.length; 16877 while ( len-- ) { 16878 key = style[ len ]; 16879 if ( typeof style[ key ] === "string" ) { 16880 styles[ $.camelCase( key ) ] = style[ key ]; 16881 } 16882 } 16883 16884 // Support: Opera, IE <9 16885 } else { 16886 for ( key in style ) { 16887 if ( typeof style[ key ] === "string" ) { 16888 styles[ key ] = style[ key ]; 16889 } 16890 } 16891 } 16892 16893 return styles; 16894} 16895 16896function styleDifference( oldStyle, newStyle ) { 16897 var diff = {}, 16898 name, value; 16899 16900 for ( name in newStyle ) { 16901 value = newStyle[ name ]; 16902 if ( oldStyle[ name ] !== value ) { 16903 if ( !shorthandStyles[ name ] ) { 16904 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 16905 diff[ name ] = value; 16906 } 16907 } 16908 } 16909 } 16910 16911 return diff; 16912} 16913 16914// Support: jQuery <1.8 16915if ( !$.fn.addBack ) { 16916 $.fn.addBack = function( selector ) { 16917 return this.add( selector == null ? 16918 this.prevObject : this.prevObject.filter( selector ) 16919 ); 16920 }; 16921} 16922 16923$.effects.animateClass = function( value, duration, easing, callback ) { 16924 var o = $.speed( duration, easing, callback ); 16925 16926 return this.queue( function() { 16927 var animated = $( this ), 16928 baseClass = animated.attr( "class" ) || "", 16929 applyClassChange, 16930 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 16931 16932 // Map the animated objects to store the original styles. 16933 allAnimations = allAnimations.map( function() { 16934 var el = $( this ); 16935 return { 16936 el: el, 16937 start: getElementStyles( this ) 16938 }; 16939 } ); 16940 16941 // Apply class change 16942 applyClassChange = function() { 16943 $.each( classAnimationActions, function( i, action ) { 16944 if ( value[ action ] ) { 16945 animated[ action + "Class" ]( value[ action ] ); 16946 } 16947 } ); 16948 }; 16949 applyClassChange(); 16950 16951 // Map all animated objects again - calculate new styles and diff 16952 allAnimations = allAnimations.map( function() { 16953 this.end = getElementStyles( this.el[ 0 ] ); 16954 this.diff = styleDifference( this.start, this.end ); 16955 return this; 16956 } ); 16957 16958 // Apply original class 16959 animated.attr( "class", baseClass ); 16960 16961 // Map all animated objects again - this time collecting a promise 16962 allAnimations = allAnimations.map( function() { 16963 var styleInfo = this, 16964 dfd = $.Deferred(), 16965 opts = $.extend( {}, o, { 16966 queue: false, 16967 complete: function() { 16968 dfd.resolve( styleInfo ); 16969 } 16970 } ); 16971 16972 this.el.animate( this.diff, opts ); 16973 return dfd.promise(); 16974 } ); 16975 16976 // Once all animations have completed: 16977 $.when.apply( $, allAnimations.get() ).done( function() { 16978 16979 // Set the final class 16980 applyClassChange(); 16981 16982 // For each animated element, 16983 // clear all css properties that were animated 16984 $.each( arguments, function() { 16985 var el = this.el; 16986 $.each( this.diff, function( key ) { 16987 el.css( key, "" ); 16988 } ); 16989 } ); 16990 16991 // This is guarnteed to be there if you use jQuery.speed() 16992 // it also handles dequeuing the next anim... 16993 o.complete.call( animated[ 0 ] ); 16994 } ); 16995 } ); 16996}; 16997 16998$.fn.extend( { 16999 addClass: ( function( orig ) { 17000 return function( classNames, speed, easing, callback ) { 17001 return speed ? 17002 $.effects.animateClass.call( this, 17003 { add: classNames }, speed, easing, callback ) : 17004 orig.apply( this, arguments ); 17005 }; 17006 } )( $.fn.addClass ), 17007 17008 removeClass: ( function( orig ) { 17009 return function( classNames, speed, easing, callback ) { 17010 return arguments.length > 1 ? 17011 $.effects.animateClass.call( this, 17012 { remove: classNames }, speed, easing, callback ) : 17013 orig.apply( this, arguments ); 17014 }; 17015 } )( $.fn.removeClass ), 17016 17017 toggleClass: ( function( orig ) { 17018 return function( classNames, force, speed, easing, callback ) { 17019 if ( typeof force === "boolean" || force === undefined ) { 17020 if ( !speed ) { 17021 17022 // Without speed parameter 17023 return orig.apply( this, arguments ); 17024 } else { 17025 return $.effects.animateClass.call( this, 17026 ( force ? { add: classNames } : { remove: classNames } ), 17027 speed, easing, callback ); 17028 } 17029 } else { 17030 17031 // Without force parameter 17032 return $.effects.animateClass.call( this, 17033 { toggle: classNames }, force, speed, easing ); 17034 } 17035 }; 17036 } )( $.fn.toggleClass ), 17037 17038 switchClass: function( remove, add, speed, easing, callback ) { 17039 return $.effects.animateClass.call( this, { 17040 add: add, 17041 remove: remove 17042 }, speed, easing, callback ); 17043 } 17044} ); 17045 17046} )(); 17047 17048/******************************************************************************/ 17049/*********************************** EFFECTS **********************************/ 17050/******************************************************************************/ 17051 17052( function() { 17053 17054if ( $.expr && $.expr.filters && $.expr.filters.animated ) { 17055 $.expr.filters.animated = ( function( orig ) { 17056 return function( elem ) { 17057 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 17058 }; 17059 } )( $.expr.filters.animated ); 17060} 17061 17062if ( $.uiBackCompat !== false ) { 17063 $.extend( $.effects, { 17064 17065 // Saves a set of properties in a data storage 17066 save: function( element, set ) { 17067 var i = 0, length = set.length; 17068 for ( ; i < length; i++ ) { 17069 if ( set[ i ] !== null ) { 17070 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 17071 } 17072 } 17073 }, 17074 17075 // Restores a set of previously saved properties from a data storage 17076 restore: function( element, set ) { 17077 var val, i = 0, length = set.length; 17078 for ( ; i < length; i++ ) { 17079 if ( set[ i ] !== null ) { 17080 val = element.data( dataSpace + set[ i ] ); 17081 element.css( set[ i ], val ); 17082 } 17083 } 17084 }, 17085 17086 setMode: function( el, mode ) { 17087 if ( mode === "toggle" ) { 17088 mode = el.is( ":hidden" ) ? "show" : "hide"; 17089 } 17090 return mode; 17091 }, 17092 17093 // Wraps the element around a wrapper that copies position properties 17094 createWrapper: function( element ) { 17095 17096 // If the element is already wrapped, return it 17097 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17098 return element.parent(); 17099 } 17100 17101 // Wrap the element 17102 var props = { 17103 width: element.outerWidth( true ), 17104 height: element.outerHeight( true ), 17105 "float": element.css( "float" ) 17106 }, 17107 wrapper = $( "<div></div>" ) 17108 .addClass( "ui-effects-wrapper" ) 17109 .css( { 17110 fontSize: "100%", 17111 background: "transparent", 17112 border: "none", 17113 margin: 0, 17114 padding: 0 17115 } ), 17116 17117 // Store the size in case width/height are defined in % - Fixes #5245 17118 size = { 17119 width: element.width(), 17120 height: element.height() 17121 }, 17122 active = document.activeElement; 17123 17124 // Support: Firefox 17125 // Firefox incorrectly exposes anonymous content 17126 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 17127 try { 17128 active.id; 17129 } catch ( e ) { 17130 active = document.body; 17131 } 17132 17133 element.wrap( wrapper ); 17134 17135 // Fixes #7595 - Elements lose focus when wrapped. 17136 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17137 $( active ).trigger( "focus" ); 17138 } 17139 17140 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 17141 // lose the reference to the wrapped element 17142 wrapper = element.parent(); 17143 17144 // Transfer positioning properties to the wrapper 17145 if ( element.css( "position" ) === "static" ) { 17146 wrapper.css( { position: "relative" } ); 17147 element.css( { position: "relative" } ); 17148 } else { 17149 $.extend( props, { 17150 position: element.css( "position" ), 17151 zIndex: element.css( "z-index" ) 17152 } ); 17153 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 17154 props[ pos ] = element.css( pos ); 17155 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 17156 props[ pos ] = "auto"; 17157 } 17158 } ); 17159 element.css( { 17160 position: "relative", 17161 top: 0, 17162 left: 0, 17163 right: "auto", 17164 bottom: "auto" 17165 } ); 17166 } 17167 element.css( size ); 17168 17169 return wrapper.css( props ).show(); 17170 }, 17171 17172 removeWrapper: function( element ) { 17173 var active = document.activeElement; 17174 17175 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 17176 element.parent().replaceWith( element ); 17177 17178 // Fixes #7595 - Elements lose focus when wrapped. 17179 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 17180 $( active ).trigger( "focus" ); 17181 } 17182 } 17183 17184 return element; 17185 } 17186 } ); 17187} 17188 17189$.extend( $.effects, { 17190 version: "1.12.1", 17191 17192 define: function( name, mode, effect ) { 17193 if ( !effect ) { 17194 effect = mode; 17195 mode = "effect"; 17196 } 17197 17198 $.effects.effect[ name ] = effect; 17199 $.effects.effect[ name ].mode = mode; 17200 17201 return effect; 17202 }, 17203 17204 scaledDimensions: function( element, percent, direction ) { 17205 if ( percent === 0 ) { 17206 return { 17207 height: 0, 17208 width: 0, 17209 outerHeight: 0, 17210 outerWidth: 0 17211 }; 17212 } 17213 17214 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 17215 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 17216 17217 return { 17218 height: element.height() * y, 17219 width: element.width() * x, 17220 outerHeight: element.outerHeight() * y, 17221 outerWidth: element.outerWidth() * x 17222 }; 17223 17224 }, 17225 17226 clipToBox: function( animation ) { 17227 return { 17228 width: animation.clip.right - animation.clip.left, 17229 height: animation.clip.bottom - animation.clip.top, 17230 left: animation.clip.left, 17231 top: animation.clip.top 17232 }; 17233 }, 17234 17235 // Injects recently queued functions to be first in line (after "inprogress") 17236 unshift: function( element, queueLength, count ) { 17237 var queue = element.queue(); 17238 17239 if ( queueLength > 1 ) { 17240 queue.splice.apply( queue, 17241 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 17242 } 17243 element.dequeue(); 17244 }, 17245 17246 saveStyle: function( element ) { 17247 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 17248 }, 17249 17250 restoreStyle: function( element ) { 17251 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 17252 element.removeData( dataSpaceStyle ); 17253 }, 17254 17255 mode: function( element, mode ) { 17256 var hidden = element.is( ":hidden" ); 17257 17258 if ( mode === "toggle" ) { 17259 mode = hidden ? "show" : "hide"; 17260 } 17261 if ( hidden ? mode === "hide" : mode === "show" ) { 17262 mode = "none"; 17263 } 17264 return mode; 17265 }, 17266 17267 // Translates a [top,left] array into a baseline value 17268 getBaseline: function( origin, original ) { 17269 var y, x; 17270 17271 switch ( origin[ 0 ] ) { 17272 case "top": 17273 y = 0; 17274 break; 17275 case "middle": 17276 y = 0.5; 17277 break; 17278 case "bottom": 17279 y = 1; 17280 break; 17281 default: 17282 y = origin[ 0 ] / original.height; 17283 } 17284 17285 switch ( origin[ 1 ] ) { 17286 case "left": 17287 x = 0; 17288 break; 17289 case "center": 17290 x = 0.5; 17291 break; 17292 case "right": 17293 x = 1; 17294 break; 17295 default: 17296 x = origin[ 1 ] / original.width; 17297 } 17298 17299 return { 17300 x: x, 17301 y: y 17302 }; 17303 }, 17304 17305 // Creates a placeholder element so that the original element can be made absolute 17306 createPlaceholder: function( element ) { 17307 var placeholder, 17308 cssPosition = element.css( "position" ), 17309 position = element.position(); 17310 17311 // Lock in margins first to account for form elements, which 17312 // will change margin if you explicitly set height 17313 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 17314 // Support: Safari 17315 element.css( { 17316 marginTop: element.css( "marginTop" ), 17317 marginBottom: element.css( "marginBottom" ), 17318 marginLeft: element.css( "marginLeft" ), 17319 marginRight: element.css( "marginRight" ) 17320 } ) 17321 .outerWidth( element.outerWidth() ) 17322 .outerHeight( element.outerHeight() ); 17323 17324 if ( /^(static|relative)/.test( cssPosition ) ) { 17325 cssPosition = "absolute"; 17326 17327 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 17328 17329 // Convert inline to inline block to account for inline elements 17330 // that turn to inline block based on content (like img) 17331 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 17332 "inline-block" : 17333 "block", 17334 visibility: "hidden", 17335 17336 // Margins need to be set to account for margin collapse 17337 marginTop: element.css( "marginTop" ), 17338 marginBottom: element.css( "marginBottom" ), 17339 marginLeft: element.css( "marginLeft" ), 17340 marginRight: element.css( "marginRight" ), 17341 "float": element.css( "float" ) 17342 } ) 17343 .outerWidth( element.outerWidth() ) 17344 .outerHeight( element.outerHeight() ) 17345 .addClass( "ui-effects-placeholder" ); 17346 17347 element.data( dataSpace + "placeholder", placeholder ); 17348 } 17349 17350 element.css( { 17351 position: cssPosition, 17352 left: position.left, 17353 top: position.top 17354 } ); 17355 17356 return placeholder; 17357 }, 17358 17359 removePlaceholder: function( element ) { 17360 var dataKey = dataSpace + "placeholder", 17361 placeholder = element.data( dataKey ); 17362 17363 if ( placeholder ) { 17364 placeholder.remove(); 17365 element.removeData( dataKey ); 17366 } 17367 }, 17368 17369 // Removes a placeholder if it exists and restores 17370 // properties that were modified during placeholder creation 17371 cleanUp: function( element ) { 17372 $.effects.restoreStyle( element ); 17373 $.effects.removePlaceholder( element ); 17374 }, 17375 17376 setTransition: function( element, list, factor, value ) { 17377 value = value || {}; 17378 $.each( list, function( i, x ) { 17379 var unit = element.cssUnit( x ); 17380 if ( unit[ 0 ] > 0 ) { 17381 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 17382 } 17383 } ); 17384 return value; 17385 } 17386} ); 17387 17388// Return an effect options object for the given parameters: 17389function _normalizeArguments( effect, options, speed, callback ) { 17390 17391 // Allow passing all options as the first parameter 17392 if ( $.isPlainObject( effect ) ) { 17393 options = effect; 17394 effect = effect.effect; 17395 } 17396 17397 // Convert to an object 17398 effect = { effect: effect }; 17399 17400 // Catch (effect, null, ...) 17401 if ( options == null ) { 17402 options = {}; 17403 } 17404 17405 // Catch (effect, callback) 17406 if ( $.isFunction( options ) ) { 17407 callback = options; 17408 speed = null; 17409 options = {}; 17410 } 17411 17412 // Catch (effect, speed, ?) 17413 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 17414 callback = speed; 17415 speed = options; 17416 options = {}; 17417 } 17418 17419 // Catch (effect, options, callback) 17420 if ( $.isFunction( speed ) ) { 17421 callback = speed; 17422 speed = null; 17423 } 17424 17425 // Add options to effect 17426 if ( options ) { 17427 $.extend( effect, options ); 17428 } 17429 17430 speed = speed || options.duration; 17431 effect.duration = $.fx.off ? 0 : 17432 typeof speed === "number" ? speed : 17433 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 17434 $.fx.speeds._default; 17435 17436 effect.complete = callback || options.complete; 17437 17438 return effect; 17439} 17440 17441function standardAnimationOption( option ) { 17442 17443 // Valid standard speeds (nothing, number, named speed) 17444 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 17445 return true; 17446 } 17447 17448 // Invalid strings - treat as "normal" speed 17449 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 17450 return true; 17451 } 17452 17453 // Complete callback 17454 if ( $.isFunction( option ) ) { 17455 return true; 17456 } 17457 17458 // Options hash (but not naming an effect) 17459 if ( typeof option === "object" && !option.effect ) { 17460 return true; 17461 } 17462 17463 // Didn't match any standard API 17464 return false; 17465} 17466 17467$.fn.extend( { 17468 effect: function( /* effect, options, speed, callback */ ) { 17469 var args = _normalizeArguments.apply( this, arguments ), 17470 effectMethod = $.effects.effect[ args.effect ], 17471 defaultMode = effectMethod.mode, 17472 queue = args.queue, 17473 queueName = queue || "fx", 17474 complete = args.complete, 17475 mode = args.mode, 17476 modes = [], 17477 prefilter = function( next ) { 17478 var el = $( this ), 17479 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 17480 17481 // Sentinel for duck-punching the :animated psuedo-selector 17482 el.data( dataSpaceAnimated, true ); 17483 17484 // Save effect mode for later use, 17485 // we can't just call $.effects.mode again later, 17486 // as the .show() below destroys the initial state 17487 modes.push( normalizedMode ); 17488 17489 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13 17490 if ( defaultMode && ( normalizedMode === "show" || 17491 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 17492 el.show(); 17493 } 17494 17495 if ( !defaultMode || normalizedMode !== "none" ) { 17496 $.effects.saveStyle( el ); 17497 } 17498 17499 if ( $.isFunction( next ) ) { 17500 next(); 17501 } 17502 }; 17503 17504 if ( $.fx.off || !effectMethod ) { 17505 17506 // Delegate to the original method (e.g., .show()) if possible 17507 if ( mode ) { 17508 return this[ mode ]( args.duration, complete ); 17509 } else { 17510 return this.each( function() { 17511 if ( complete ) { 17512 complete.call( this ); 17513 } 17514 } ); 17515 } 17516 } 17517 17518 function run( next ) { 17519 var elem = $( this ); 17520 17521 function cleanup() { 17522 elem.removeData( dataSpaceAnimated ); 17523 17524 $.effects.cleanUp( elem ); 17525 17526 if ( args.mode === "hide" ) { 17527 elem.hide(); 17528 } 17529 17530 done(); 17531 } 17532 17533 function done() { 17534 if ( $.isFunction( complete ) ) { 17535 complete.call( elem[ 0 ] ); 17536 } 17537 17538 if ( $.isFunction( next ) ) { 17539 next(); 17540 } 17541 } 17542 17543 // Override mode option on a per element basis, 17544 // as toggle can be either show or hide depending on element state 17545 args.mode = modes.shift(); 17546 17547 if ( $.uiBackCompat !== false && !defaultMode ) { 17548 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 17549 17550 // Call the core method to track "olddisplay" properly 17551 elem[ mode ](); 17552 done(); 17553 } else { 17554 effectMethod.call( elem[ 0 ], args, done ); 17555 } 17556 } else { 17557 if ( args.mode === "none" ) { 17558 17559 // Call the core method to track "olddisplay" properly 17560 elem[ mode ](); 17561 done(); 17562 } else { 17563 effectMethod.call( elem[ 0 ], args, cleanup ); 17564 } 17565 } 17566 } 17567 17568 // Run prefilter on all elements first to ensure that 17569 // any showing or hiding happens before placeholder creation, 17570 // which ensures that any layout changes are correctly captured. 17571 return queue === false ? 17572 this.each( prefilter ).each( run ) : 17573 this.queue( queueName, prefilter ).queue( queueName, run ); 17574 }, 17575 17576 show: ( function( orig ) { 17577 return function( option ) { 17578 if ( standardAnimationOption( option ) ) { 17579 return orig.apply( this, arguments ); 17580 } else { 17581 var args = _normalizeArguments.apply( this, arguments ); 17582 args.mode = "show"; 17583 return this.effect.call( this, args ); 17584 } 17585 }; 17586 } )( $.fn.show ), 17587 17588 hide: ( function( orig ) { 17589 return function( option ) { 17590 if ( standardAnimationOption( option ) ) { 17591 return orig.apply( this, arguments ); 17592 } else { 17593 var args = _normalizeArguments.apply( this, arguments ); 17594 args.mode = "hide"; 17595 return this.effect.call( this, args ); 17596 } 17597 }; 17598 } )( $.fn.hide ), 17599 17600 toggle: ( function( orig ) { 17601 return function( option ) { 17602 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 17603 return orig.apply( this, arguments ); 17604 } else { 17605 var args = _normalizeArguments.apply( this, arguments ); 17606 args.mode = "toggle"; 17607 return this.effect.call( this, args ); 17608 } 17609 }; 17610 } )( $.fn.toggle ), 17611 17612 cssUnit: function( key ) { 17613 var style = this.css( key ), 17614 val = []; 17615 17616 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 17617 if ( style.indexOf( unit ) > 0 ) { 17618 val = [ parseFloat( style ), unit ]; 17619 } 17620 } ); 17621 return val; 17622 }, 17623 17624 cssClip: function( clipObj ) { 17625 if ( clipObj ) { 17626 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 17627 clipObj.bottom + "px " + clipObj.left + "px)" ); 17628 } 17629 return parseClip( this.css( "clip" ), this ); 17630 }, 17631 17632 transfer: function( options, done ) { 17633 var element = $( this ), 17634 target = $( options.to ), 17635 targetFixed = target.css( "position" ) === "fixed", 17636 body = $( "body" ), 17637 fixTop = targetFixed ? body.scrollTop() : 0, 17638 fixLeft = targetFixed ? body.scrollLeft() : 0, 17639 endPosition = target.offset(), 17640 animation = { 17641 top: endPosition.top - fixTop, 17642 left: endPosition.left - fixLeft, 17643 height: target.innerHeight(), 17644 width: target.innerWidth() 17645 }, 17646 startPosition = element.offset(), 17647 transfer = $( "<div class='ui-effects-transfer'></div>" ) 17648 .appendTo( "body" ) 17649 .addClass( options.className ) 17650 .css( { 17651 top: startPosition.top - fixTop, 17652 left: startPosition.left - fixLeft, 17653 height: element.innerHeight(), 17654 width: element.innerWidth(), 17655 position: targetFixed ? "fixed" : "absolute" 17656 } ) 17657 .animate( animation, options.duration, options.easing, function() { 17658 transfer.remove(); 17659 if ( $.isFunction( done ) ) { 17660 done(); 17661 } 17662 } ); 17663 } 17664} ); 17665 17666function parseClip( str, element ) { 17667 var outerWidth = element.outerWidth(), 17668 outerHeight = element.outerHeight(), 17669 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)\)$/, 17670 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 17671 17672 return { 17673 top: parseFloat( values[ 1 ] ) || 0, 17674 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 17675 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 17676 left: parseFloat( values[ 4 ] ) || 0 17677 }; 17678} 17679 17680$.fx.step.clip = function( fx ) { 17681 if ( !fx.clipInit ) { 17682 fx.start = $( fx.elem ).cssClip(); 17683 if ( typeof fx.end === "string" ) { 17684 fx.end = parseClip( fx.end, fx.elem ); 17685 } 17686 fx.clipInit = true; 17687 } 17688 17689 $( fx.elem ).cssClip( { 17690 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 17691 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 17692 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 17693 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 17694 } ); 17695}; 17696 17697} )(); 17698 17699/******************************************************************************/ 17700/*********************************** EASING ***********************************/ 17701/******************************************************************************/ 17702 17703( function() { 17704 17705// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 17706 17707var baseEasings = {}; 17708 17709$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 17710 baseEasings[ name ] = function( p ) { 17711 return Math.pow( p, i + 2 ); 17712 }; 17713} ); 17714 17715$.extend( baseEasings, { 17716 Sine: function( p ) { 17717 return 1 - Math.cos( p * Math.PI / 2 ); 17718 }, 17719 Circ: function( p ) { 17720 return 1 - Math.sqrt( 1 - p * p ); 17721 }, 17722 Elastic: function( p ) { 17723 return p === 0 || p === 1 ? p : 17724 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 17725 }, 17726 Back: function( p ) { 17727 return p * p * ( 3 * p - 2 ); 17728 }, 17729 Bounce: function( p ) { 17730 var pow2, 17731 bounce = 4; 17732 17733 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 17734 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 17735 } 17736} ); 17737 17738$.each( baseEasings, function( name, easeIn ) { 17739 $.easing[ "easeIn" + name ] = easeIn; 17740 $.easing[ "easeOut" + name ] = function( p ) { 17741 return 1 - easeIn( 1 - p ); 17742 }; 17743 $.easing[ "easeInOut" + name ] = function( p ) { 17744 return p < 0.5 ? 17745 easeIn( p * 2 ) / 2 : 17746 1 - easeIn( p * -2 + 2 ) / 2; 17747 }; 17748} ); 17749 17750} )(); 17751 17752var effect = $.effects; 17753 17754 17755/*! 17756 * jQuery UI Effects Blind 1.12.1 17757 * http://jqueryui.com 17758 * 17759 * Copyright jQuery Foundation and other contributors 17760 * Released under the MIT license. 17761 * http://jquery.org/license 17762 */ 17763 17764//>>label: Blind Effect 17765//>>group: Effects 17766//>>description: Blinds the element. 17767//>>docs: http://api.jqueryui.com/blind-effect/ 17768//>>demos: http://jqueryui.com/effect/ 17769 17770 17771 17772var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 17773 var map = { 17774 up: [ "bottom", "top" ], 17775 vertical: [ "bottom", "top" ], 17776 down: [ "top", "bottom" ], 17777 left: [ "right", "left" ], 17778 horizontal: [ "right", "left" ], 17779 right: [ "left", "right" ] 17780 }, 17781 element = $( this ), 17782 direction = options.direction || "up", 17783 start = element.cssClip(), 17784 animate = { clip: $.extend( {}, start ) }, 17785 placeholder = $.effects.createPlaceholder( element ); 17786 17787 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 17788 17789 if ( options.mode === "show" ) { 17790 element.cssClip( animate.clip ); 17791 if ( placeholder ) { 17792 placeholder.css( $.effects.clipToBox( animate ) ); 17793 } 17794 17795 animate.clip = start; 17796 } 17797 17798 if ( placeholder ) { 17799 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 17800 } 17801 17802 element.animate( animate, { 17803 queue: false, 17804 duration: options.duration, 17805 easing: options.easing, 17806 complete: done 17807 } ); 17808} ); 17809 17810 17811/*! 17812 * jQuery UI Effects Bounce 1.12.1 17813 * http://jqueryui.com 17814 * 17815 * Copyright jQuery Foundation and other contributors 17816 * Released under the MIT license. 17817 * http://jquery.org/license 17818 */ 17819 17820//>>label: Bounce Effect 17821//>>group: Effects 17822//>>description: Bounces an element horizontally or vertically n times. 17823//>>docs: http://api.jqueryui.com/bounce-effect/ 17824//>>demos: http://jqueryui.com/effect/ 17825 17826 17827 17828var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 17829 var upAnim, downAnim, refValue, 17830 element = $( this ), 17831 17832 // Defaults: 17833 mode = options.mode, 17834 hide = mode === "hide", 17835 show = mode === "show", 17836 direction = options.direction || "up", 17837 distance = options.distance, 17838 times = options.times || 5, 17839 17840 // Number of internal animations 17841 anims = times * 2 + ( show || hide ? 1 : 0 ), 17842 speed = options.duration / anims, 17843 easing = options.easing, 17844 17845 // Utility: 17846 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17847 motion = ( direction === "up" || direction === "left" ), 17848 i = 0, 17849 17850 queuelen = element.queue().length; 17851 17852 $.effects.createPlaceholder( element ); 17853 17854 refValue = element.css( ref ); 17855 17856 // Default distance for the BIGGEST bounce is the outer Distance / 3 17857 if ( !distance ) { 17858 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 17859 } 17860 17861 if ( show ) { 17862 downAnim = { opacity: 1 }; 17863 downAnim[ ref ] = refValue; 17864 17865 // If we are showing, force opacity 0 and set the initial position 17866 // then do the "first" animation 17867 element 17868 .css( "opacity", 0 ) 17869 .css( ref, motion ? -distance * 2 : distance * 2 ) 17870 .animate( downAnim, speed, easing ); 17871 } 17872 17873 // Start at the smallest distance if we are hiding 17874 if ( hide ) { 17875 distance = distance / Math.pow( 2, times - 1 ); 17876 } 17877 17878 downAnim = {}; 17879 downAnim[ ref ] = refValue; 17880 17881 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 17882 for ( ; i < times; i++ ) { 17883 upAnim = {}; 17884 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 17885 17886 element 17887 .animate( upAnim, speed, easing ) 17888 .animate( downAnim, speed, easing ); 17889 17890 distance = hide ? distance * 2 : distance / 2; 17891 } 17892 17893 // Last Bounce when Hiding 17894 if ( hide ) { 17895 upAnim = { opacity: 0 }; 17896 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 17897 17898 element.animate( upAnim, speed, easing ); 17899 } 17900 17901 element.queue( done ); 17902 17903 $.effects.unshift( element, queuelen, anims + 1 ); 17904} ); 17905 17906 17907/*! 17908 * jQuery UI Effects Clip 1.12.1 17909 * http://jqueryui.com 17910 * 17911 * Copyright jQuery Foundation and other contributors 17912 * Released under the MIT license. 17913 * http://jquery.org/license 17914 */ 17915 17916//>>label: Clip Effect 17917//>>group: Effects 17918//>>description: Clips the element on and off like an old TV. 17919//>>docs: http://api.jqueryui.com/clip-effect/ 17920//>>demos: http://jqueryui.com/effect/ 17921 17922 17923 17924var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 17925 var start, 17926 animate = {}, 17927 element = $( this ), 17928 direction = options.direction || "vertical", 17929 both = direction === "both", 17930 horizontal = both || direction === "horizontal", 17931 vertical = both || direction === "vertical"; 17932 17933 start = element.cssClip(); 17934 animate.clip = { 17935 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 17936 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 17937 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 17938 left: horizontal ? ( start.right - start.left ) / 2 : start.left 17939 }; 17940 17941 $.effects.createPlaceholder( element ); 17942 17943 if ( options.mode === "show" ) { 17944 element.cssClip( animate.clip ); 17945 animate.clip = start; 17946 } 17947 17948 element.animate( animate, { 17949 queue: false, 17950 duration: options.duration, 17951 easing: options.easing, 17952 complete: done 17953 } ); 17954 17955} ); 17956 17957 17958/*! 17959 * jQuery UI Effects Drop 1.12.1 17960 * http://jqueryui.com 17961 * 17962 * Copyright jQuery Foundation and other contributors 17963 * Released under the MIT license. 17964 * http://jquery.org/license 17965 */ 17966 17967//>>label: Drop Effect 17968//>>group: Effects 17969//>>description: Moves an element in one direction and hides it at the same time. 17970//>>docs: http://api.jqueryui.com/drop-effect/ 17971//>>demos: http://jqueryui.com/effect/ 17972 17973 17974 17975var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 17976 17977 var distance, 17978 element = $( this ), 17979 mode = options.mode, 17980 show = mode === "show", 17981 direction = options.direction || "left", 17982 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 17983 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 17984 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 17985 animation = { 17986 opacity: 0 17987 }; 17988 17989 $.effects.createPlaceholder( element ); 17990 17991 distance = options.distance || 17992 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 17993 17994 animation[ ref ] = motion + distance; 17995 17996 if ( show ) { 17997 element.css( animation ); 17998 17999 animation[ ref ] = oppositeMotion + distance; 18000 animation.opacity = 1; 18001 } 18002 18003 // Animate 18004 element.animate( animation, { 18005 queue: false, 18006 duration: options.duration, 18007 easing: options.easing, 18008 complete: done 18009 } ); 18010} ); 18011 18012 18013/*! 18014 * jQuery UI Effects Explode 1.12.1 18015 * http://jqueryui.com 18016 * 18017 * Copyright jQuery Foundation and other contributors 18018 * Released under the MIT license. 18019 * http://jquery.org/license 18020 */ 18021 18022//>>label: Explode Effect 18023//>>group: Effects 18024// jscs:disable maximumLineLength 18025//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 18026// jscs:enable maximumLineLength 18027//>>docs: http://api.jqueryui.com/explode-effect/ 18028//>>demos: http://jqueryui.com/effect/ 18029 18030 18031 18032var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 18033 18034 var i, j, left, top, mx, my, 18035 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 18036 cells = rows, 18037 element = $( this ), 18038 mode = options.mode, 18039 show = mode === "show", 18040 18041 // Show and then visibility:hidden the element before calculating offset 18042 offset = element.show().css( "visibility", "hidden" ).offset(), 18043 18044 // Width and height of a piece 18045 width = Math.ceil( element.outerWidth() / cells ), 18046 height = Math.ceil( element.outerHeight() / rows ), 18047 pieces = []; 18048 18049 // Children animate complete: 18050 function childComplete() { 18051 pieces.push( this ); 18052 if ( pieces.length === rows * cells ) { 18053 animComplete(); 18054 } 18055 } 18056 18057 // Clone the element for each row and cell. 18058 for ( i = 0; i < rows; i++ ) { // ===> 18059 top = offset.top + i * height; 18060 my = i - ( rows - 1 ) / 2; 18061 18062 for ( j = 0; j < cells; j++ ) { // ||| 18063 left = offset.left + j * width; 18064 mx = j - ( cells - 1 ) / 2; 18065 18066 // Create a clone of the now hidden main element that will be absolute positioned 18067 // within a wrapper div off the -left and -top equal to size of our pieces 18068 element 18069 .clone() 18070 .appendTo( "body" ) 18071 .wrap( "<div></div>" ) 18072 .css( { 18073 position: "absolute", 18074 visibility: "visible", 18075 left: -j * width, 18076 top: -i * height 18077 } ) 18078 18079 // Select the wrapper - make it overflow: hidden and absolute positioned based on 18080 // where the original was located +left and +top equal to the size of pieces 18081 .parent() 18082 .addClass( "ui-effects-explode" ) 18083 .css( { 18084 position: "absolute", 18085 overflow: "hidden", 18086 width: width, 18087 height: height, 18088 left: left + ( show ? mx * width : 0 ), 18089 top: top + ( show ? my * height : 0 ), 18090 opacity: show ? 0 : 1 18091 } ) 18092 .animate( { 18093 left: left + ( show ? 0 : mx * width ), 18094 top: top + ( show ? 0 : my * height ), 18095 opacity: show ? 1 : 0 18096 }, options.duration || 500, options.easing, childComplete ); 18097 } 18098 } 18099 18100 function animComplete() { 18101 element.css( { 18102 visibility: "visible" 18103 } ); 18104 $( pieces ).remove(); 18105 done(); 18106 } 18107} ); 18108 18109 18110/*! 18111 * jQuery UI Effects Fade 1.12.1 18112 * http://jqueryui.com 18113 * 18114 * Copyright jQuery Foundation and other contributors 18115 * Released under the MIT license. 18116 * http://jquery.org/license 18117 */ 18118 18119//>>label: Fade Effect 18120//>>group: Effects 18121//>>description: Fades the element. 18122//>>docs: http://api.jqueryui.com/fade-effect/ 18123//>>demos: http://jqueryui.com/effect/ 18124 18125 18126 18127var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 18128 var show = options.mode === "show"; 18129 18130 $( this ) 18131 .css( "opacity", show ? 0 : 1 ) 18132 .animate( { 18133 opacity: show ? 1 : 0 18134 }, { 18135 queue: false, 18136 duration: options.duration, 18137 easing: options.easing, 18138 complete: done 18139 } ); 18140} ); 18141 18142 18143/*! 18144 * jQuery UI Effects Fold 1.12.1 18145 * http://jqueryui.com 18146 * 18147 * Copyright jQuery Foundation and other contributors 18148 * Released under the MIT license. 18149 * http://jquery.org/license 18150 */ 18151 18152//>>label: Fold Effect 18153//>>group: Effects 18154//>>description: Folds an element first horizontally and then vertically. 18155//>>docs: http://api.jqueryui.com/fold-effect/ 18156//>>demos: http://jqueryui.com/effect/ 18157 18158 18159 18160var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 18161 18162 // Create element 18163 var element = $( this ), 18164 mode = options.mode, 18165 show = mode === "show", 18166 hide = mode === "hide", 18167 size = options.size || 15, 18168 percent = /([0-9]+)%/.exec( size ), 18169 horizFirst = !!options.horizFirst, 18170 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 18171 duration = options.duration / 2, 18172 18173 placeholder = $.effects.createPlaceholder( element ), 18174 18175 start = element.cssClip(), 18176 animation1 = { clip: $.extend( {}, start ) }, 18177 animation2 = { clip: $.extend( {}, start ) }, 18178 18179 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 18180 18181 queuelen = element.queue().length; 18182 18183 if ( percent ) { 18184 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 18185 } 18186 animation1.clip[ ref[ 0 ] ] = size; 18187 animation2.clip[ ref[ 0 ] ] = size; 18188 animation2.clip[ ref[ 1 ] ] = 0; 18189 18190 if ( show ) { 18191 element.cssClip( animation2.clip ); 18192 if ( placeholder ) { 18193 placeholder.css( $.effects.clipToBox( animation2 ) ); 18194 } 18195 18196 animation2.clip = start; 18197 } 18198 18199 // Animate 18200 element 18201 .queue( function( next ) { 18202 if ( placeholder ) { 18203 placeholder 18204 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 18205 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 18206 } 18207 18208 next(); 18209 } ) 18210 .animate( animation1, duration, options.easing ) 18211 .animate( animation2, duration, options.easing ) 18212 .queue( done ); 18213 18214 $.effects.unshift( element, queuelen, 4 ); 18215} ); 18216 18217 18218/*! 18219 * jQuery UI Effects Highlight 1.12.1 18220 * http://jqueryui.com 18221 * 18222 * Copyright jQuery Foundation and other contributors 18223 * Released under the MIT license. 18224 * http://jquery.org/license 18225 */ 18226 18227//>>label: Highlight Effect 18228//>>group: Effects 18229//>>description: Highlights the background of an element in a defined color for a custom duration. 18230//>>docs: http://api.jqueryui.com/highlight-effect/ 18231//>>demos: http://jqueryui.com/effect/ 18232 18233 18234 18235var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 18236 var element = $( this ), 18237 animation = { 18238 backgroundColor: element.css( "backgroundColor" ) 18239 }; 18240 18241 if ( options.mode === "hide" ) { 18242 animation.opacity = 0; 18243 } 18244 18245 $.effects.saveStyle( element ); 18246 18247 element 18248 .css( { 18249 backgroundImage: "none", 18250 backgroundColor: options.color || "#ffff99" 18251 } ) 18252 .animate( animation, { 18253 queue: false, 18254 duration: options.duration, 18255 easing: options.easing, 18256 complete: done 18257 } ); 18258} ); 18259 18260 18261/*! 18262 * jQuery UI Effects Size 1.12.1 18263 * http://jqueryui.com 18264 * 18265 * Copyright jQuery Foundation and other contributors 18266 * Released under the MIT license. 18267 * http://jquery.org/license 18268 */ 18269 18270//>>label: Size Effect 18271//>>group: Effects 18272//>>description: Resize an element to a specified width and height. 18273//>>docs: http://api.jqueryui.com/size-effect/ 18274//>>demos: http://jqueryui.com/effect/ 18275 18276 18277 18278var effectsEffectSize = $.effects.define( "size", function( options, done ) { 18279 18280 // Create element 18281 var baseline, factor, temp, 18282 element = $( this ), 18283 18284 // Copy for children 18285 cProps = [ "fontSize" ], 18286 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 18287 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 18288 18289 // Set options 18290 mode = options.mode, 18291 restore = mode !== "effect", 18292 scale = options.scale || "both", 18293 origin = options.origin || [ "middle", "center" ], 18294 position = element.css( "position" ), 18295 pos = element.position(), 18296 original = $.effects.scaledDimensions( element ), 18297 from = options.from || original, 18298 to = options.to || $.effects.scaledDimensions( element, 0 ); 18299 18300 $.effects.createPlaceholder( element ); 18301 18302 if ( mode === "show" ) { 18303 temp = from; 18304 from = to; 18305 to = temp; 18306 } 18307 18308 // Set scaling factor 18309 factor = { 18310 from: { 18311 y: from.height / original.height, 18312 x: from.width / original.width 18313 }, 18314 to: { 18315 y: to.height / original.height, 18316 x: to.width / original.width 18317 } 18318 }; 18319 18320 // Scale the css box 18321 if ( scale === "box" || scale === "both" ) { 18322 18323 // Vertical props scaling 18324 if ( factor.from.y !== factor.to.y ) { 18325 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 18326 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 18327 } 18328 18329 // Horizontal props scaling 18330 if ( factor.from.x !== factor.to.x ) { 18331 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 18332 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 18333 } 18334 } 18335 18336 // Scale the content 18337 if ( scale === "content" || scale === "both" ) { 18338 18339 // Vertical props scaling 18340 if ( factor.from.y !== factor.to.y ) { 18341 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 18342 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 18343 } 18344 } 18345 18346 // Adjust the position properties based on the provided origin points 18347 if ( origin ) { 18348 baseline = $.effects.getBaseline( origin, original ); 18349 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 18350 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 18351 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 18352 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 18353 } 18354 element.css( from ); 18355 18356 // Animate the children if desired 18357 if ( scale === "content" || scale === "both" ) { 18358 18359 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 18360 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 18361 18362 // Only animate children with width attributes specified 18363 // TODO: is this right? should we include anything with css width specified as well 18364 element.find( "*[width]" ).each( function() { 18365 var child = $( this ), 18366 childOriginal = $.effects.scaledDimensions( child ), 18367 childFrom = { 18368 height: childOriginal.height * factor.from.y, 18369 width: childOriginal.width * factor.from.x, 18370 outerHeight: childOriginal.outerHeight * factor.from.y, 18371 outerWidth: childOriginal.outerWidth * factor.from.x 18372 }, 18373 childTo = { 18374 height: childOriginal.height * factor.to.y, 18375 width: childOriginal.width * factor.to.x, 18376 outerHeight: childOriginal.height * factor.to.y, 18377 outerWidth: childOriginal.width * factor.to.x 18378 }; 18379 18380 // Vertical props scaling 18381 if ( factor.from.y !== factor.to.y ) { 18382 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 18383 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 18384 } 18385 18386 // Horizontal props scaling 18387 if ( factor.from.x !== factor.to.x ) { 18388 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 18389 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 18390 } 18391 18392 if ( restore ) { 18393 $.effects.saveStyle( child ); 18394 } 18395 18396 // Animate children 18397 child.css( childFrom ); 18398 child.animate( childTo, options.duration, options.easing, function() { 18399 18400 // Restore children 18401 if ( restore ) { 18402 $.effects.restoreStyle( child ); 18403 } 18404 } ); 18405 } ); 18406 } 18407 18408 // Animate 18409 element.animate( to, { 18410 queue: false, 18411 duration: options.duration, 18412 easing: options.easing, 18413 complete: function() { 18414 18415 var offset = element.offset(); 18416 18417 if ( to.opacity === 0 ) { 18418 element.css( "opacity", from.opacity ); 18419 } 18420 18421 if ( !restore ) { 18422 element 18423 .css( "position", position === "static" ? "relative" : position ) 18424 .offset( offset ); 18425 18426 // Need to save style here so that automatic style restoration 18427 // doesn't restore to the original styles from before the animation. 18428 $.effects.saveStyle( element ); 18429 } 18430 18431 done(); 18432 } 18433 } ); 18434 18435} ); 18436 18437 18438/*! 18439 * jQuery UI Effects Scale 1.12.1 18440 * http://jqueryui.com 18441 * 18442 * Copyright jQuery Foundation and other contributors 18443 * Released under the MIT license. 18444 * http://jquery.org/license 18445 */ 18446 18447//>>label: Scale Effect 18448//>>group: Effects 18449//>>description: Grows or shrinks an element and its content. 18450//>>docs: http://api.jqueryui.com/scale-effect/ 18451//>>demos: http://jqueryui.com/effect/ 18452 18453 18454 18455var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 18456 18457 // Create element 18458 var el = $( this ), 18459 mode = options.mode, 18460 percent = parseInt( options.percent, 10 ) || 18461 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 18462 18463 newOptions = $.extend( true, { 18464 from: $.effects.scaledDimensions( el ), 18465 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 18466 origin: options.origin || [ "middle", "center" ] 18467 }, options ); 18468 18469 // Fade option to support puff 18470 if ( options.fade ) { 18471 newOptions.from.opacity = 1; 18472 newOptions.to.opacity = 0; 18473 } 18474 18475 $.effects.effect.size.call( this, newOptions, done ); 18476} ); 18477 18478 18479/*! 18480 * jQuery UI Effects Puff 1.12.1 18481 * http://jqueryui.com 18482 * 18483 * Copyright jQuery Foundation and other contributors 18484 * Released under the MIT license. 18485 * http://jquery.org/license 18486 */ 18487 18488//>>label: Puff Effect 18489//>>group: Effects 18490//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 18491//>>docs: http://api.jqueryui.com/puff-effect/ 18492//>>demos: http://jqueryui.com/effect/ 18493 18494 18495 18496var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 18497 var newOptions = $.extend( true, {}, options, { 18498 fade: true, 18499 percent: parseInt( options.percent, 10 ) || 150 18500 } ); 18501 18502 $.effects.effect.scale.call( this, newOptions, done ); 18503} ); 18504 18505 18506/*! 18507 * jQuery UI Effects Pulsate 1.12.1 18508 * http://jqueryui.com 18509 * 18510 * Copyright jQuery Foundation and other contributors 18511 * Released under the MIT license. 18512 * http://jquery.org/license 18513 */ 18514 18515//>>label: Pulsate Effect 18516//>>group: Effects 18517//>>description: Pulsates an element n times by changing the opacity to zero and back. 18518//>>docs: http://api.jqueryui.com/pulsate-effect/ 18519//>>demos: http://jqueryui.com/effect/ 18520 18521 18522 18523var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 18524 var element = $( this ), 18525 mode = options.mode, 18526 show = mode === "show", 18527 hide = mode === "hide", 18528 showhide = show || hide, 18529 18530 // Showing or hiding leaves off the "last" animation 18531 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 18532 duration = options.duration / anims, 18533 animateTo = 0, 18534 i = 1, 18535 queuelen = element.queue().length; 18536 18537 if ( show || !element.is( ":visible" ) ) { 18538 element.css( "opacity", 0 ).show(); 18539 animateTo = 1; 18540 } 18541 18542 // Anims - 1 opacity "toggles" 18543 for ( ; i < anims; i++ ) { 18544 element.animate( { opacity: animateTo }, duration, options.easing ); 18545 animateTo = 1 - animateTo; 18546 } 18547 18548 element.animate( { opacity: animateTo }, duration, options.easing ); 18549 18550 element.queue( done ); 18551 18552 $.effects.unshift( element, queuelen, anims + 1 ); 18553} ); 18554 18555 18556/*! 18557 * jQuery UI Effects Shake 1.12.1 18558 * http://jqueryui.com 18559 * 18560 * Copyright jQuery Foundation and other contributors 18561 * Released under the MIT license. 18562 * http://jquery.org/license 18563 */ 18564 18565//>>label: Shake Effect 18566//>>group: Effects 18567//>>description: Shakes an element horizontally or vertically n times. 18568//>>docs: http://api.jqueryui.com/shake-effect/ 18569//>>demos: http://jqueryui.com/effect/ 18570 18571 18572 18573var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 18574 18575 var i = 1, 18576 element = $( this ), 18577 direction = options.direction || "left", 18578 distance = options.distance || 20, 18579 times = options.times || 3, 18580 anims = times * 2 + 1, 18581 speed = Math.round( options.duration / anims ), 18582 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18583 positiveMotion = ( direction === "up" || direction === "left" ), 18584 animation = {}, 18585 animation1 = {}, 18586 animation2 = {}, 18587 18588 queuelen = element.queue().length; 18589 18590 $.effects.createPlaceholder( element ); 18591 18592 // Animation 18593 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 18594 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 18595 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 18596 18597 // Animate 18598 element.animate( animation, speed, options.easing ); 18599 18600 // Shakes 18601 for ( ; i < times; i++ ) { 18602 element 18603 .animate( animation1, speed, options.easing ) 18604 .animate( animation2, speed, options.easing ); 18605 } 18606 18607 element 18608 .animate( animation1, speed, options.easing ) 18609 .animate( animation, speed / 2, options.easing ) 18610 .queue( done ); 18611 18612 $.effects.unshift( element, queuelen, anims + 1 ); 18613} ); 18614 18615 18616/*! 18617 * jQuery UI Effects Slide 1.12.1 18618 * http://jqueryui.com 18619 * 18620 * Copyright jQuery Foundation and other contributors 18621 * Released under the MIT license. 18622 * http://jquery.org/license 18623 */ 18624 18625//>>label: Slide Effect 18626//>>group: Effects 18627//>>description: Slides an element in and out of the viewport. 18628//>>docs: http://api.jqueryui.com/slide-effect/ 18629//>>demos: http://jqueryui.com/effect/ 18630 18631 18632 18633var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 18634 var startClip, startRef, 18635 element = $( this ), 18636 map = { 18637 up: [ "bottom", "top" ], 18638 down: [ "top", "bottom" ], 18639 left: [ "right", "left" ], 18640 right: [ "left", "right" ] 18641 }, 18642 mode = options.mode, 18643 direction = options.direction || "left", 18644 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 18645 positiveMotion = ( direction === "up" || direction === "left" ), 18646 distance = options.distance || 18647 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 18648 animation = {}; 18649 18650 $.effects.createPlaceholder( element ); 18651 18652 startClip = element.cssClip(); 18653 startRef = element.position()[ ref ]; 18654 18655 // Define hide animation 18656 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 18657 animation.clip = element.cssClip(); 18658 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 18659 18660 // Reverse the animation if we're showing 18661 if ( mode === "show" ) { 18662 element.cssClip( animation.clip ); 18663 element.css( ref, animation[ ref ] ); 18664 animation.clip = startClip; 18665 animation[ ref ] = startRef; 18666 } 18667 18668 // Actually animate 18669 element.animate( animation, { 18670 queue: false, 18671 duration: options.duration, 18672 easing: options.easing,
vendor: 637 bytes, lines 18673-18706
18673 complete: done 18674 } ); 18675} ); 18676 18677 18678/*! 18679 * jQuery UI Effects Transfer 1.12.1 18680 * http://jqueryui.com 18681 * 18682 * Copyright jQuery Foundation and other contributors 18683 * Released under the MIT license. 18684 * http://jquery.org/license 18685 */ 18686 18687//>>label: Transfer Effect 18688//>>group: Effects 18689//>>description: Displays a transfer effect from one element to another. 18690//>>docs: http://api.jqueryui.com/transfer-effect/ 18691//>>demos: http://jqueryui.com/effect/ 18692 18693 18694 18695var effect; 18696if ( $.uiBackCompat !== false ) { 18697 effect = $.effects.define( "transfer", function( options, done ) { 18698 $( this ).transfer( options, done ); 18699 } ); 18700} 18701var effectsEffectTransfer = effect; 18702 18703 18704 18705 18706}));
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.