1/*! jQuery UI - v1.12.1 - 2024-08-07 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/resizable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js, effect
vendor: 8,818 bytes, lines 3-330
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
vendor: 37,850 bytes, lines 331-1721
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: 3,607 bytes, lines 1722-1851
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
vendor: 3,125 bytes, lines 1852-1969
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}
vendor: 105,867 bytes, lines 1969-6129
1969; 1970 1971 1972/*! 1973 * jQuery UI Resizable 1.12.1 1974 * http://jqueryui.com 1975 * 1976 * Copyright jQuery Foundation and other contributors 1977 * Released under the MIT license. 1978 * http://jquery.org/license 1979 */ 1980 1981//>>label: Resizable 1982//>>group: Interactions 1983//>>description: Enables resize functionality for any element. 1984//>>docs: http://api.jqueryui.com/resizable/ 1985//>>demos: http://jqueryui.com/resizable/ 1986//>>css.structure: ../../themes/base/core.css 1987//>>css.structure: ../../themes/base/resizable.css 1988//>>css.theme: ../../themes/base/theme.css 1989 1990 1991 1992$.widget( "ui.resizable", $.ui.mouse, { 1993 version: "1.12.1", 1994 widgetEventPrefix: "resize", 1995 options: { 1996 alsoResize: false, 1997 animate: false, 1998 animateDuration: "slow", 1999 animateEasing: "swing", 2000 aspectRatio: false, 2001 autoHide: false, 2002 classes: { 2003 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 2004 }, 2005 containment: false, 2006 ghost: false, 2007 grid: false, 2008 handles: "e,s,se", 2009 helper: false, 2010 maxHeight: null, 2011 maxWidth: null, 2012 minHeight: 10, 2013 minWidth: 10, 2014 2015 // See #7960 2016 zIndex: 90, 2017 2018 // Callbacks 2019 resize: null, 2020 start: null, 2021 stop: null 2022 }, 2023 2024 _num: function( value ) { 2025 return parseFloat( value ) || 0; 2026 }, 2027 2028 _isNumber: function( value ) { 2029 return !isNaN( parseFloat( value ) ); 2030 }, 2031 2032 _hasScroll: function( el, a ) { 2033 2034 if ( $( el ).css( "overflow" ) === "hidden" ) { 2035 return false; 2036 } 2037 2038 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 2039 has = false; 2040 2041 if ( el[ scroll ] > 0 ) { 2042 return true; 2043 } 2044 2045 // TODO: determine which cases actually cause this to happen 2046 // if the element doesn't have the scroll set, see if it's possible to 2047 // set the scroll 2048 el[ scroll ] = 1; 2049 has = ( el[ scroll ] > 0 ); 2050 el[ scroll ] = 0; 2051 return has; 2052 }, 2053 2054 _create: function() { 2055 2056 var margins, 2057 o = this.options, 2058 that = this; 2059 this._addClass( "ui-resizable" ); 2060 2061 $.extend( this, { 2062 _aspectRatio: !!( o.aspectRatio ), 2063 aspectRatio: o.aspectRatio, 2064 originalElement: this.element, 2065 _proportionallyResizeElements: [], 2066 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2067 } ); 2068 2069 // Wrap the element if it cannot hold child nodes 2070 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 2071 2072 this.element.wrap( 2073 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( { 2074 position: this.element.css( "position" ), 2075 width: this.element.outerWidth(), 2076 height: this.element.outerHeight(), 2077 top: this.element.css( "top" ), 2078 left: this.element.css( "left" ) 2079 } ) 2080 ); 2081 2082 this.element = this.element.parent().data( 2083 "ui-resizable", this.element.resizable( "instance" ) 2084 ); 2085 2086 this.elementIsWrapper = true; 2087 2088 margins = { 2089 marginTop: this.originalElement.css( "marginTop" ), 2090 marginRight: this.originalElement.css( "marginRight" ), 2091 marginBottom: this.originalElement.css( "marginBottom" ), 2092 marginLeft: this.originalElement.css( "marginLeft" ) 2093 }; 2094 2095 this.element.css( margins ); 2096 this.originalElement.css( "margin", 0 ); 2097 2098 // support: Safari 2099 // Prevent Safari textarea resize 2100 this.originalResizeStyle = this.originalElement.css( "resize" ); 2101 this.originalElement.css( "resize", "none" ); 2102 2103 this._proportionallyResizeElements.push( this.originalElement.css( { 2104 position: "static", 2105 zoom: 1, 2106 display: "block" 2107 } ) ); 2108 2109 // Support: IE9 2110 // avoid IE jump (hard set the margin) 2111 this.originalElement.css( margins ); 2112 2113 this._proportionallyResize(); 2114 } 2115 2116 this._setupHandles(); 2117 2118 if ( o.autoHide ) { 2119 $( this.element ) 2120 .on( "mouseenter", function() { 2121 if ( o.disabled ) { 2122 return; 2123 } 2124 that._removeClass( "ui-resizable-autohide" ); 2125 that._handles.show(); 2126 } ) 2127 .on( "mouseleave", function() { 2128 if ( o.disabled ) { 2129 return; 2130 } 2131 if ( !that.resizing ) { 2132 that._addClass( "ui-resizable-autohide" ); 2133 that._handles.hide(); 2134 } 2135 } ); 2136 } 2137 2138 this._mouseInit(); 2139 }, 2140 2141 _destroy: function() { 2142 2143 this._mouseDestroy(); 2144 2145 var wrapper, 2146 _destroy = function( exp ) { 2147 $( exp ) 2148 .removeData( "resizable" ) 2149 .removeData( "ui-resizable" ) 2150 .off( ".resizable" ) 2151 .find( ".ui-resizable-handle" ) 2152 .remove(); 2153 }; 2154 2155 // TODO: Unwrap at same DOM position 2156 if ( this.elementIsWrapper ) { 2157 _destroy( this.element ); 2158 wrapper = this.element; 2159 this.originalElement.css( { 2160 position: wrapper.css( "position" ), 2161 width: wrapper.outerWidth(), 2162 height: wrapper.outerHeight(), 2163 top: wrapper.css( "top" ), 2164 left: wrapper.css( "left" ) 2165 } ).insertAfter( wrapper ); 2166 wrapper.remove(); 2167 } 2168 2169 this.originalElement.css( "resize", this.originalResizeStyle ); 2170 _destroy( this.originalElement ); 2171 2172 return this; 2173 }, 2174 2175 _setOption: function( key, value ) { 2176 this._super( key, value ); 2177 2178 switch ( key ) { 2179 case "handles": 2180 this._removeHandles(); 2181 this._setupHandles(); 2182 break; 2183 default: 2184 break; 2185 } 2186 }, 2187 2188 _setupHandles: function() { 2189 var o = this.options, handle, i, n, hname, axis, that = this; 2190 this.handles = o.handles || 2191 ( !$( ".ui-resizable-handle", this.element ).length ? 2192 "e,s,se" : { 2193 n: ".ui-resizable-n", 2194 e: ".ui-resizable-e", 2195 s: ".ui-resizable-s", 2196 w: ".ui-resizable-w", 2197 se: ".ui-resizable-se", 2198 sw: ".ui-resizable-sw", 2199 ne: ".ui-resizable-ne", 2200 nw: ".ui-resizable-nw" 2201 } ); 2202 2203 this._handles = $(); 2204 if ( this.handles.constructor === String ) { 2205 2206 if ( this.handles === "all" ) { 2207 this.handles = "n,e,s,w,se,sw,ne,nw"; 2208 } 2209 2210 n = this.handles.split( "," ); 2211 this.handles = {}; 2212 2213 for ( i = 0; i < n.length; i++ ) { 2214 2215 handle = $.trim( n[ i ] ); 2216 hname = "ui-resizable-" + handle; 2217 axis = $( "<div>" ); 2218 this._addClass( axis, "ui-resizable-handle " + hname ); 2219 2220 axis.css( { zIndex: o.zIndex } ); 2221 2222 this.handles[ handle ] = ".ui-resizable-" + handle; 2223 this.element.append( axis ); 2224 } 2225 2226 } 2227 2228 this._renderAxis = function( target ) { 2229 2230 var i, axis, padPos, padWrapper; 2231 2232 target = target || this.element; 2233 2234 for ( i in this.handles ) { 2235 2236 if ( this.handles[ i ].constructor === String ) { 2237 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 2238 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 2239 this.handles[ i ] = $( this.handles[ i ] ); 2240 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 2241 } 2242 2243 if ( this.elementIsWrapper && 2244 this.originalElement[ 0 ] 2245 .nodeName 2246 .match( /^(textarea|input|select|button)$/i ) ) { 2247 axis = $( this.handles[ i ], this.element ); 2248 2249 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 2250 axis.outerHeight() : 2251 axis.outerWidth(); 2252 2253 padPos = [ "padding", 2254 /ne|nw|n/.test( i ) ? "Top" : 2255 /se|sw|s/.test( i ) ? "Bottom" : 2256 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 2257 2258 target.css( padPos, padWrapper ); 2259 2260 this._proportionallyResize(); 2261 } 2262 2263 this._handles = this._handles.add( this.handles[ i ] ); 2264 } 2265 }; 2266 2267 // TODO: make renderAxis a prototype function 2268 this._renderAxis( this.element ); 2269 2270 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 2271 this._handles.disableSelection(); 2272 2273 this._handles.on( "mouseover", function() { 2274 if ( !that.resizing ) { 2275 if ( this.className ) { 2276 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 2277 } 2278 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 2279 } 2280 } ); 2281 2282 if ( o.autoHide ) { 2283 this._handles.hide(); 2284 this._addClass( "ui-resizable-autohide" ); 2285 } 2286 }, 2287 2288 _removeHandles: function() { 2289 this._handles.remove(); 2290 }, 2291 2292 _mouseCapture: function( event ) { 2293 var i, handle, 2294 capture = false; 2295 2296 for ( i in this.handles ) { 2297 handle = $( this.handles[ i ] )[ 0 ]; 2298 if ( handle === event.target || $.contains( handle, event.target ) ) { 2299 capture = true; 2300 } 2301 } 2302 2303 return !this.options.disabled && capture; 2304 }, 2305 2306 _mouseStart: function( event ) { 2307 2308 var curleft, curtop, cursor, 2309 o = this.options, 2310 el = this.element; 2311 2312 this.resizing = true; 2313 2314 this._renderProxy(); 2315 2316 curleft = this._num( this.helper.css( "left" ) ); 2317 curtop = this._num( this.helper.css( "top" ) ); 2318 2319 if ( o.containment ) { 2320 curleft += $( o.containment ).scrollLeft() || 0; 2321 curtop += $( o.containment ).scrollTop() || 0; 2322 } 2323 2324 this.offset = this.helper.offset(); 2325 this.position = { left: curleft, top: curtop }; 2326 2327 this.size = this._helper ? { 2328 width: this.helper.width(), 2329 height: this.helper.height() 2330 } : { 2331 width: el.width(), 2332 height: el.height() 2333 }; 2334 2335 this.originalSize = this._helper ? { 2336 width: el.outerWidth(), 2337 height: el.outerHeight() 2338 } : { 2339 width: el.width(), 2340 height: el.height() 2341 }; 2342 2343 this.sizeDiff = { 2344 width: el.outerWidth() - el.width(), 2345 height: el.outerHeight() - el.height() 2346 }; 2347 2348 this.originalPosition = { left: curleft, top: curtop }; 2349 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2350 2351 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 2352 o.aspectRatio : 2353 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 2354 2355 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 2356 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 2357 2358 this._addClass( "ui-resizable-resizing" ); 2359 this._propagate( "start", event ); 2360 return true; 2361 }, 2362 2363 _mouseDrag: function( event ) { 2364 2365 var data, props, 2366 smp = this.originalMousePosition, 2367 a = this.axis, 2368 dx = ( event.pageX - smp.left ) || 0, 2369 dy = ( event.pageY - smp.top ) || 0, 2370 trigger = this._change[ a ]; 2371 2372 this._updatePrevProperties(); 2373 2374 if ( !trigger ) { 2375 return false; 2376 } 2377 2378 data = trigger.apply( this, [ event, dx, dy ] ); 2379 2380 this._updateVirtualBoundaries( event.shiftKey ); 2381 if ( this._aspectRatio || event.shiftKey ) { 2382 data = this._updateRatio( data, event ); 2383 } 2384 2385 data = this._respectSize( data, event ); 2386 2387 this._updateCache( data ); 2388 2389 this._propagate( "resize", event ); 2390 2391 props = this._applyChanges(); 2392 2393 if ( !this._helper && this._proportionallyResizeElements.length ) { 2394 this._proportionallyResize(); 2395 } 2396 2397 if ( !$.isEmptyObject( props ) ) { 2398 this._updatePrevProperties(); 2399 this._trigger( "resize", event, this.ui() ); 2400 this._applyChanges(); 2401 } 2402 2403 return false; 2404 }, 2405 2406 _mouseStop: function( event ) { 2407 2408 this.resizing = false; 2409 var pr, ista, soffseth, soffsetw, s, left, top, 2410 o = this.options, that = this; 2411 2412 if ( this._helper ) { 2413 2414 pr = this._proportionallyResizeElements; 2415 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 2416 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 2417 soffsetw = ista ? 0 : that.sizeDiff.width; 2418 2419 s = { 2420 width: ( that.helper.width() - soffsetw ), 2421 height: ( that.helper.height() - soffseth ) 2422 }; 2423 left = ( parseFloat( that.element.css( "left" ) ) + 2424 ( that.position.left - that.originalPosition.left ) ) || null; 2425 top = ( parseFloat( that.element.css( "top" ) ) + 2426 ( that.position.top - that.originalPosition.top ) ) || null; 2427 2428 if ( !o.animate ) { 2429 this.element.css( $.extend( s, { top: top, left: left } ) ); 2430 } 2431 2432 that.helper.height( that.size.height ); 2433 that.helper.width( that.size.width ); 2434 2435 if ( this._helper && !o.animate ) { 2436 this._proportionallyResize(); 2437 } 2438 } 2439 2440 $( "body" ).css( "cursor", "auto" ); 2441 2442 this._removeClass( "ui-resizable-resizing" ); 2443 2444 this._propagate( "stop", event ); 2445 2446 if ( this._helper ) { 2447 this.helper.remove(); 2448 } 2449 2450 return false; 2451 2452 }, 2453 2454 _updatePrevProperties: function() { 2455 this.prevPosition = { 2456 top: this.position.top, 2457 left: this.position.left 2458 }; 2459 this.prevSize = { 2460 width: this.size.width, 2461 height: this.size.height 2462 }; 2463 }, 2464 2465 _applyChanges: function() { 2466 var props = {}; 2467 2468 if ( this.position.top !== this.prevPosition.top ) { 2469 props.top = this.position.top + "px"; 2470 } 2471 if ( this.position.left !== this.prevPosition.left ) { 2472 props.left = this.position.left + "px"; 2473 } 2474 if ( this.size.width !== this.prevSize.width ) { 2475 props.width = this.size.width + "px"; 2476 } 2477 if ( this.size.height !== this.prevSize.height ) { 2478 props.height = this.size.height + "px"; 2479 } 2480 2481 this.helper.css( props ); 2482 2483 return props; 2484 }, 2485 2486 _updateVirtualBoundaries: function( forceAspectRatio ) { 2487 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2488 o = this.options; 2489 2490 b = { 2491 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 2492 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 2493 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 2494 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 2495 }; 2496 2497 if ( this._aspectRatio || forceAspectRatio ) { 2498 pMinWidth = b.minHeight * this.aspectRatio; 2499 pMinHeight = b.minWidth / this.aspectRatio; 2500 pMaxWidth = b.maxHeight * this.aspectRatio; 2501 pMaxHeight = b.maxWidth / this.aspectRatio; 2502 2503 if ( pMinWidth > b.minWidth ) { 2504 b.minWidth = pMinWidth; 2505 } 2506 if ( pMinHeight > b.minHeight ) { 2507 b.minHeight = pMinHeight; 2508 } 2509 if ( pMaxWidth < b.maxWidth ) { 2510 b.maxWidth = pMaxWidth; 2511 } 2512 if ( pMaxHeight < b.maxHeight ) { 2513 b.maxHeight = pMaxHeight; 2514 } 2515 } 2516 this._vBoundaries = b; 2517 }, 2518 2519 _updateCache: function( data ) { 2520 this.offset = this.helper.offset(); 2521 if ( this._isNumber( data.left ) ) { 2522 this.position.left = data.left; 2523 } 2524 if ( this._isNumber( data.top ) ) { 2525 this.position.top = data.top; 2526 } 2527 if ( this._isNumber( data.height ) ) { 2528 this.size.height = data.height; 2529 } 2530 if ( this._isNumber( data.width ) ) { 2531 this.size.width = data.width; 2532 } 2533 }, 2534 2535 _updateRatio: function( data ) { 2536 2537 var cpos = this.position, 2538 csize = this.size, 2539 a = this.axis; 2540 2541 if ( this._isNumber( data.height ) ) { 2542 data.width = ( data.height * this.aspectRatio ); 2543 } else if ( this._isNumber( data.width ) ) { 2544 data.height = ( data.width / this.aspectRatio ); 2545 } 2546 2547 if ( a === "sw" ) { 2548 data.left = cpos.left + ( csize.width - data.width ); 2549 data.top = null; 2550 } 2551 if ( a === "nw" ) { 2552 data.top = cpos.top + ( csize.height - data.height ); 2553 data.left = cpos.left + ( csize.width - data.width ); 2554 } 2555 2556 return data; 2557 }, 2558 2559 _respectSize: function( data ) { 2560 2561 var o = this._vBoundaries, 2562 a = this.axis, 2563 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 2564 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 2565 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 2566 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 2567 dw = this.originalPosition.left + this.originalSize.width, 2568 dh = this.originalPosition.top + this.originalSize.height, 2569 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 2570 if ( isminw ) { 2571 data.width = o.minWidth; 2572 } 2573 if ( isminh ) { 2574 data.height = o.minHeight; 2575 } 2576 if ( ismaxw ) { 2577 data.width = o.maxWidth; 2578 } 2579 if ( ismaxh ) { 2580 data.height = o.maxHeight; 2581 } 2582 2583 if ( isminw && cw ) { 2584 data.left = dw - o.minWidth; 2585 } 2586 if ( ismaxw && cw ) { 2587 data.left = dw - o.maxWidth; 2588 } 2589 if ( isminh && ch ) { 2590 data.top = dh - o.minHeight; 2591 } 2592 if ( ismaxh && ch ) { 2593 data.top = dh - o.maxHeight; 2594 } 2595 2596 // Fixing jump error on top/left - bug #2330 2597 if ( !data.width && !data.height && !data.left && data.top ) { 2598 data.top = null; 2599 } else if ( !data.width && !data.height && !data.top && data.left ) { 2600 data.left = null; 2601 } 2602 2603 return data; 2604 }, 2605 2606 _getPaddingPlusBorderDimensions: function( element ) { 2607 var i = 0, 2608 widths = [], 2609 borders = [ 2610 element.css( "borderTopWidth" ), 2611 element.css( "borderRightWidth" ), 2612 element.css( "borderBottomWidth" ), 2613 element.css( "borderLeftWidth" ) 2614 ], 2615 paddings = [ 2616 element.css( "paddingTop" ), 2617 element.css( "paddingRight" ), 2618 element.css( "paddingBottom" ), 2619 element.css( "paddingLeft" ) 2620 ]; 2621 2622 for ( ; i < 4; i++ ) { 2623 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 2624 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 2625 } 2626 2627 return { 2628 height: widths[ 0 ] + widths[ 2 ], 2629 width: widths[ 1 ] + widths[ 3 ] 2630 }; 2631 }, 2632 2633 _proportionallyResize: function() { 2634 2635 if ( !this._proportionallyResizeElements.length ) { 2636 return; 2637 } 2638 2639 var prel, 2640 i = 0, 2641 element = this.helper || this.element; 2642 2643 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 2644 2645 prel = this._proportionallyResizeElements[ i ]; 2646 2647 // TODO: Seems like a bug to cache this.outerDimensions 2648 // considering that we are in a loop. 2649 if ( !this.outerDimensions ) { 2650 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 2651 } 2652 2653 prel.css( { 2654 height: ( element.height() - this.outerDimensions.height ) || 0, 2655 width: ( element.width() - this.outerDimensions.width ) || 0 2656 } ); 2657 2658 } 2659 2660 }, 2661 2662 _renderProxy: function() { 2663 2664 var el = this.element, o = this.options; 2665 this.elementOffset = el.offset(); 2666 2667 if ( this._helper ) { 2668 2669 this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" ); 2670 2671 this._addClass( this.helper, this._helper ); 2672 this.helper.css( { 2673 width: this.element.outerWidth(), 2674 height: this.element.outerHeight(), 2675 position: "absolute", 2676 left: this.elementOffset.left + "px", 2677 top: this.elementOffset.top + "px", 2678 zIndex: ++o.zIndex //TODO: Don't modify option 2679 } ); 2680 2681 this.helper 2682 .appendTo( "body" ) 2683 .disableSelection(); 2684 2685 } else { 2686 this.helper = this.element; 2687 } 2688 2689 }, 2690 2691 _change: { 2692 e: function( event, dx ) { 2693 return { width: this.originalSize.width + dx }; 2694 }, 2695 w: function( event, dx ) { 2696 var cs = this.originalSize, sp = this.originalPosition; 2697 return { left: sp.left + dx, width: cs.width - dx }; 2698 }, 2699 n: function( event, dx, dy ) { 2700 var cs = this.originalSize, sp = this.originalPosition; 2701 return { top: sp.top + dy, height: cs.height - dy }; 2702 }, 2703 s: function( event, dx, dy ) { 2704 return { height: this.originalSize.height + dy }; 2705 }, 2706 se: function( event, dx, dy ) { 2707 return $.extend( this._change.s.apply( this, arguments ), 2708 this._change.e.apply( this, [ event, dx, dy ] ) ); 2709 }, 2710 sw: function( event, dx, dy ) { 2711 return $.extend( this._change.s.apply( this, arguments ), 2712 this._change.w.apply( this, [ event, dx, dy ] ) ); 2713 }, 2714 ne: function( event, dx, dy ) { 2715 return $.extend( this._change.n.apply( this, arguments ), 2716 this._change.e.apply( this, [ event, dx, dy ] ) ); 2717 }, 2718 nw: function( event, dx, dy ) { 2719 return $.extend( this._change.n.apply( this, arguments ), 2720 this._change.w.apply( this, [ event, dx, dy ] ) ); 2721 } 2722 }, 2723 2724 _propagate: function( n, event ) { 2725 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 2726 ( n !== "resize" && this._trigger( n, event, this.ui() ) ); 2727 }, 2728 2729 plugins: {}, 2730 2731 ui: function() { 2732 return { 2733 originalElement: this.originalElement, 2734 element: this.element, 2735 helper: this.helper, 2736 position: this.position, 2737 size: this.size, 2738 originalSize: this.originalSize, 2739 originalPosition: this.originalPosition 2740 }; 2741 } 2742 2743} ); 2744 2745/* 2746 * Resizable Extensions 2747 */ 2748 2749$.ui.plugin.add( "resizable", "animate", { 2750 2751 stop: function( event ) { 2752 var that = $( this ).resizable( "instance" ), 2753 o = that.options, 2754 pr = that._proportionallyResizeElements, 2755 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 2756 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 2757 soffsetw = ista ? 0 : that.sizeDiff.width, 2758 style = { 2759 width: ( that.size.width - soffsetw ), 2760 height: ( that.size.height - soffseth ) 2761 }, 2762 left = ( parseFloat( that.element.css( "left" ) ) + 2763 ( that.position.left - that.originalPosition.left ) ) || null, 2764 top = ( parseFloat( that.element.css( "top" ) ) + 2765 ( that.position.top - that.originalPosition.top ) ) || null; 2766 2767 that.element.animate( 2768 $.extend( style, top && left ? { top: top, left: left } : {} ), { 2769 duration: o.animateDuration, 2770 easing: o.animateEasing, 2771 step: function() { 2772 2773 var data = { 2774 width: parseFloat( that.element.css( "width" ) ), 2775 height: parseFloat( that.element.css( "height" ) ), 2776 top: parseFloat( that.element.css( "top" ) ), 2777 left: parseFloat( that.element.css( "left" ) ) 2778 }; 2779 2780 if ( pr && pr.length ) { 2781 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 2782 } 2783 2784 // Propagating resize, and updating values for each animation step 2785 that._updateCache( data ); 2786 that._propagate( "resize", event ); 2787 2788 } 2789 } 2790 ); 2791 } 2792 2793} ); 2794 2795$.ui.plugin.add( "resizable", "containment", { 2796 2797 start: function() { 2798 var element, p, co, ch, cw, width, height, 2799 that = $( this ).resizable( "instance" ), 2800 o = that.options, 2801 el = that.element, 2802 oc = o.containment, 2803 ce = ( oc instanceof $ ) ? 2804 oc.get( 0 ) : 2805 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 2806 2807 if ( !ce ) { 2808 return; 2809 } 2810 2811 that.containerElement = $( ce ); 2812 2813 if ( /document/.test( oc ) || oc === document ) { 2814 that.containerOffset = { 2815 left: 0, 2816 top: 0 2817 }; 2818 that.containerPosition = { 2819 left: 0, 2820 top: 0 2821 }; 2822 2823 that.parentData = { 2824 element: $( document ), 2825 left: 0, 2826 top: 0, 2827 width: $( document ).width(), 2828 height: $( document ).height() || document.body.parentNode.scrollHeight 2829 }; 2830 } else { 2831 element = $( ce ); 2832 p = []; 2833 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 2834 p[ i ] = that._num( element.css( "padding" + name ) ); 2835 } ); 2836 2837 that.containerOffset = element.offset(); 2838 that.containerPosition = element.position(); 2839 that.containerSize = { 2840 height: ( element.innerHeight() - p[ 3 ] ), 2841 width: ( element.innerWidth() - p[ 1 ] ) 2842 }; 2843 2844 co = that.containerOffset; 2845 ch = that.containerSize.height; 2846 cw = that.containerSize.width; 2847 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 2848 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 2849 2850 that.parentData = { 2851 element: ce, 2852 left: co.left, 2853 top: co.top, 2854 width: width, 2855 height: height 2856 }; 2857 } 2858 }, 2859 2860 resize: function( event ) { 2861 var woset, hoset, isParent, isOffsetRelative, 2862 that = $( this ).resizable( "instance" ), 2863 o = that.options, 2864 co = that.containerOffset, 2865 cp = that.position, 2866 pRatio = that._aspectRatio || event.shiftKey, 2867 cop = { 2868 top: 0, 2869 left: 0 2870 }, 2871 ce = that.containerElement, 2872 continueResize = true; 2873 2874 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 2875 cop = co; 2876 } 2877 2878 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 2879 that.size.width = that.size.width + 2880 ( that._helper ? 2881 ( that.position.left - co.left ) : 2882 ( that.position.left - cop.left ) ); 2883 2884 if ( pRatio ) { 2885 that.size.height = that.size.width / that.aspectRatio; 2886 continueResize = false; 2887 } 2888 that.position.left = o.helper ? co.left : 0; 2889 } 2890 2891 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 2892 that.size.height = that.size.height + 2893 ( that._helper ? 2894 ( that.position.top - co.top ) : 2895 that.position.top ); 2896 2897 if ( pRatio ) { 2898 that.size.width = that.size.height * that.aspectRatio; 2899 continueResize = false; 2900 } 2901 that.position.top = that._helper ? co.top : 0; 2902 } 2903 2904 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 2905 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 2906 2907 if ( isParent && isOffsetRelative ) { 2908 that.offset.left = that.parentData.left + that.position.left; 2909 that.offset.top = that.parentData.top + that.position.top; 2910 } else { 2911 that.offset.left = that.element.offset().left; 2912 that.offset.top = that.element.offset().top; 2913 } 2914 2915 woset = Math.abs( that.sizeDiff.width + 2916 ( that._helper ? 2917 that.offset.left - cop.left : 2918 ( that.offset.left - co.left ) ) ); 2919 2920 hoset = Math.abs( that.sizeDiff.height + 2921 ( that._helper ? 2922 that.offset.top - cop.top : 2923 ( that.offset.top - co.top ) ) ); 2924 2925 if ( woset + that.size.width >= that.parentData.width ) { 2926 that.size.width = that.parentData.width - woset; 2927 if ( pRatio ) { 2928 that.size.height = that.size.width / that.aspectRatio; 2929 continueResize = false; 2930 } 2931 } 2932 2933 if ( hoset + that.size.height >= that.parentData.height ) { 2934 that.size.height = that.parentData.height - hoset; 2935 if ( pRatio ) { 2936 that.size.width = that.size.height * that.aspectRatio; 2937 continueResize = false; 2938 } 2939 } 2940 2941 if ( !continueResize ) { 2942 that.position.left = that.prevPosition.left; 2943 that.position.top = that.prevPosition.top; 2944 that.size.width = that.prevSize.width; 2945 that.size.height = that.prevSize.height; 2946 } 2947 }, 2948 2949 stop: function() { 2950 var that = $( this ).resizable( "instance" ), 2951 o = that.options, 2952 co = that.containerOffset, 2953 cop = that.containerPosition, 2954 ce = that.containerElement, 2955 helper = $( that.helper ), 2956 ho = helper.offset(), 2957 w = helper.outerWidth() - that.sizeDiff.width, 2958 h = helper.outerHeight() - that.sizeDiff.height; 2959 2960 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 2961 $( this ).css( { 2962 left: ho.left - cop.left - co.left, 2963 width: w, 2964 height: h 2965 } ); 2966 } 2967 2968 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 2969 $( this ).css( { 2970 left: ho.left - cop.left - co.left, 2971 width: w, 2972 height: h 2973 } ); 2974 } 2975 } 2976} ); 2977 2978$.ui.plugin.add( "resizable", "alsoResize", { 2979 2980 start: function() { 2981 var that = $( this ).resizable( "instance" ), 2982 o = that.options; 2983 2984 $( o.alsoResize ).each( function() { 2985 var el = $( this ); 2986 el.data( "ui-resizable-alsoresize", { 2987 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 2988 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 2989 } ); 2990 } ); 2991 }, 2992 2993 resize: function( event, ui ) { 2994 var that = $( this ).resizable( "instance" ), 2995 o = that.options, 2996 os = that.originalSize, 2997 op = that.originalPosition, 2998 delta = { 2999 height: ( that.size.height - os.height ) || 0, 3000 width: ( that.size.width - os.width ) || 0, 3001 top: ( that.position.top - op.top ) || 0, 3002 left: ( that.position.left - op.left ) || 0 3003 }; 3004 3005 $( o.alsoResize ).each( function() { 3006 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 3007 css = el.parents( ui.originalElement[ 0 ] ).length ? 3008 [ "width", "height" ] : 3009 [ "width", "height", "top", "left" ]; 3010 3011 $.each( css, function( i, prop ) { 3012 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 3013 if ( sum && sum >= 0 ) { 3014 style[ prop ] = sum || null; 3015 } 3016 } ); 3017 3018 el.css( style ); 3019 } ); 3020 }, 3021 3022 stop: function() { 3023 $( this ).removeData( "ui-resizable-alsoresize" ); 3024 } 3025} ); 3026 3027$.ui.plugin.add( "resizable", "ghost", { 3028 3029 start: function() { 3030 3031 var that = $( this ).resizable( "instance" ), cs = that.size; 3032 3033 that.ghost = that.originalElement.clone(); 3034 that.ghost.css( { 3035 opacity: 0.25, 3036 display: "block", 3037 position: "relative", 3038 height: cs.height, 3039 width: cs.width, 3040 margin: 0, 3041 left: 0, 3042 top: 0 3043 } ); 3044 3045 that._addClass( that.ghost, "ui-resizable-ghost" ); 3046 3047 // DEPRECATED 3048 // TODO: remove after 1.12 3049 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 3050 3051 // Ghost option 3052 that.ghost.addClass( this.options.ghost ); 3053 } 3054 3055 that.ghost.appendTo( that.helper ); 3056 3057 }, 3058 3059 resize: function() { 3060 var that = $( this ).resizable( "instance" ); 3061 if ( that.ghost ) { 3062 that.ghost.css( { 3063 position: "relative", 3064 height: that.size.height, 3065 width: that.size.width 3066 } ); 3067 } 3068 }, 3069 3070 stop: function() { 3071 var that = $( this ).resizable( "instance" ); 3072 if ( that.ghost && that.helper ) { 3073 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 3074 } 3075 } 3076 3077} ); 3078 3079$.ui.plugin.add( "resizable", "grid", { 3080 3081 resize: function() { 3082 var outerDimensions, 3083 that = $( this ).resizable( "instance" ), 3084 o = that.options, 3085 cs = that.size, 3086 os = that.originalSize, 3087 op = that.originalPosition, 3088 a = that.axis, 3089 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 3090 gridX = ( grid[ 0 ] || 1 ), 3091 gridY = ( grid[ 1 ] || 1 ), 3092 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 3093 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 3094 newWidth = os.width + ox, 3095 newHeight = os.height + oy, 3096 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 3097 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 3098 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 3099 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 3100 3101 o.grid = grid; 3102 3103 if ( isMinWidth ) { 3104 newWidth += gridX; 3105 } 3106 if ( isMinHeight ) { 3107 newHeight += gridY; 3108 } 3109 if ( isMaxWidth ) { 3110 newWidth -= gridX; 3111 } 3112 if ( isMaxHeight ) { 3113 newHeight -= gridY; 3114 } 3115 3116 if ( /^(se|s|e)$/.test( a ) ) { 3117 that.size.width = newWidth; 3118 that.size.height = newHeight; 3119 } else if ( /^(ne)$/.test( a ) ) { 3120 that.size.width = newWidth; 3121 that.size.height = newHeight; 3122 that.position.top = op.top - oy; 3123 } else if ( /^(sw)$/.test( a ) ) { 3124 that.size.width = newWidth; 3125 that.size.height = newHeight; 3126 that.position.left = op.left - ox; 3127 } else { 3128 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 3129 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 3130 } 3131 3132 if ( newHeight - gridY > 0 ) { 3133 that.size.height = newHeight; 3134 that.position.top = op.top - oy; 3135 } else { 3136 newHeight = gridY - outerDimensions.height; 3137 that.size.height = newHeight; 3138 that.position.top = op.top + os.height - newHeight; 3139 } 3140 if ( newWidth - gridX > 0 ) { 3141 that.size.width = newWidth; 3142 that.position.left = op.left - ox; 3143 } else { 3144 newWidth = gridX - outerDimensions.width; 3145 that.size.width = newWidth; 3146 that.position.left = op.left + os.width - newWidth; 3147 } 3148 } 3149 } 3150 3151} ); 3152 3153var widgetsResizable = $.ui.resizable; 3154 3155 3156 3157var safeActiveElement = $.ui.safeActiveElement = function( document ) { 3158 var activeElement; 3159 3160 // Support: IE 9 only 3161 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 3162 try { 3163 activeElement = document.activeElement; 3164 } catch ( error ) { 3165 activeElement = document.body; 3166 } 3167 3168 // Support: IE 9 - 11 only 3169 // IE may return null instead of an element 3170 // Interestingly, this only seems to occur when NOT in an iframe 3171 if ( !activeElement ) { 3172 activeElement = document.body; 3173 } 3174 3175 // Support: IE 11 only 3176 // IE11 returns a seemingly empty object in some cases when accessing 3177 // document.activeElement from an <iframe> 3178 if ( !activeElement.nodeName ) { 3179 activeElement = document.body; 3180 } 3181 3182 return activeElement; 3183}; 3184 3185 3186/*! 3187 * jQuery UI Menu 1.12.1 3188 * http://jqueryui.com 3189 * 3190 * Copyright jQuery Foundation and other contributors 3191 * Released under the MIT license. 3192 * http://jquery.org/license 3193 */ 3194 3195//>>label: Menu 3196//>>group: Widgets 3197//>>description: Creates nestable menus. 3198//>>docs: http://api.jqueryui.com/menu/ 3199//>>demos: http://jqueryui.com/menu/ 3200//>>css.structure: ../../themes/base/core.css 3201//>>css.structure: ../../themes/base/menu.css 3202//>>css.theme: ../../themes/base/theme.css 3203 3204 3205 3206var widgetsMenu = $.widget( "ui.menu", { 3207 version: "1.12.1", 3208 defaultElement: "<ul>", 3209 delay: 300, 3210 options: { 3211 icons: { 3212 submenu: "ui-icon-caret-1-e" 3213 }, 3214 items: "> *", 3215 menus: "ul", 3216 position: { 3217 my: "left top", 3218 at: "right top" 3219 }, 3220 role: "menu", 3221 3222 // Callbacks 3223 blur: null, 3224 focus: null, 3225 select: null 3226 }, 3227 3228 _create: function() { 3229 this.activeMenu = this.element; 3230 3231 // Flag used to prevent firing of the click handler 3232 // as the event bubbles up through nested menus 3233 this.mouseHandled = false; 3234 this.element 3235 .uniqueId() 3236 .attr( { 3237 role: this.options.role, 3238 tabIndex: 0 3239 } ); 3240 3241 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 3242 this._on( { 3243 3244 // Prevent focus from sticking to links inside menu after clicking 3245 // them (focus should always stay on UL during navigation). 3246 "mousedown .ui-menu-item": function( event ) { 3247 event.preventDefault(); 3248 }, 3249 "click .ui-menu-item": function( event ) { 3250 var target = $( event.target ); 3251 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 3252 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 3253 this.select( event ); 3254 3255 // Only set the mouseHandled flag if the event will bubble, see #9469. 3256 if ( !event.isPropagationStopped() ) { 3257 this.mouseHandled = true; 3258 } 3259 3260 // Open submenu on click 3261 if ( target.has( ".ui-menu" ).length ) { 3262 this.expand( event ); 3263 } else if ( !this.element.is( ":focus" ) && 3264 active.closest( ".ui-menu" ).length ) { 3265 3266 // Redirect focus to the menu 3267 this.element.trigger( "focus", [ true ] ); 3268 3269 // If the active item is on the top level, let it stay active. 3270 // Otherwise, blur the active item since it is no longer visible. 3271 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 3272 clearTimeout( this.timer ); 3273 } 3274 } 3275 } 3276 }, 3277 "mouseenter .ui-menu-item": function( event ) { 3278 3279 // Ignore mouse events while typeahead is active, see #10458. 3280 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 3281 // is over an item in the menu 3282 if ( this.previousFilter ) { 3283 return; 3284 } 3285 3286 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 3287 target = $( event.currentTarget ); 3288 3289 // Ignore bubbled events on parent items, see #11641 3290 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 3291 return; 3292 } 3293 3294 // Remove ui-state-active class from siblings of the newly focused menu item 3295 // to avoid a jump caused by adjacent elements both having a class with a border 3296 this._removeClass( target.siblings().children( ".ui-state-active" ), 3297 null, "ui-state-active" ); 3298 this.focus( event, target ); 3299 }, 3300 mouseleave: "collapseAll", 3301 "mouseleave .ui-menu": "collapseAll", 3302 focus: function( event, keepActiveItem ) { 3303 3304 // If there's already an active item, keep it active 3305 // If not, activate the first item 3306 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 3307 3308 if ( !keepActiveItem ) { 3309 this.focus( event, item ); 3310 } 3311 }, 3312 blur: function( event ) { 3313 this._delay( function() { 3314 var notContained = !$.contains( 3315 this.element[ 0 ], 3316 $.ui.safeActiveElement( this.document[ 0 ] ) 3317 ); 3318 if ( notContained ) { 3319 this.collapseAll( event ); 3320 } 3321 } ); 3322 }, 3323 keydown: "_keydown" 3324 } ); 3325 3326 this.refresh(); 3327 3328 // Clicks outside of a menu collapse any open menus 3329 this._on( this.document, { 3330 click: function( event ) { 3331 if ( this._closeOnDocumentClick( event ) ) { 3332 this.collapseAll( event ); 3333 } 3334 3335 // Reset the mouseHandled flag 3336 this.mouseHandled = false; 3337 } 3338 } ); 3339 }, 3340 3341 _destroy: function() { 3342 var items = this.element.find( ".ui-menu-item" ) 3343 .removeAttr( "role aria-disabled" ), 3344 submenus = items.children( ".ui-menu-item-wrapper" ) 3345 .removeUniqueId() 3346 .removeAttr( "tabIndex role aria-haspopup" ); 3347 3348 // Destroy (sub)menus 3349 this.element 3350 .removeAttr( "aria-activedescendant" ) 3351 .find( ".ui-menu" ).addBack() 3352 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 3353 "tabIndex" ) 3354 .removeUniqueId() 3355 .show(); 3356 3357 submenus.children().each( function() { 3358 var elem = $( this ); 3359 if ( elem.data( "ui-menu-submenu-caret" ) ) { 3360 elem.remove(); 3361 } 3362 } ); 3363 }, 3364 3365 _keydown: function( event ) { 3366 var match, prev, character, skip, 3367 preventDefault = true; 3368 3369 switch ( event.keyCode ) { 3370 case $.ui.keyCode.PAGE_UP: 3371 this.previousPage( event ); 3372 break; 3373 case $.ui.keyCode.PAGE_DOWN: 3374 this.nextPage( event ); 3375 break; 3376 case $.ui.keyCode.HOME: 3377 this._move( "first", "first", event ); 3378 break; 3379 case $.ui.keyCode.END: 3380 this._move( "last", "last", event ); 3381 break; 3382 case $.ui.keyCode.UP: 3383 this.previous( event ); 3384 break; 3385 case $.ui.keyCode.DOWN: 3386 this.next( event ); 3387 break; 3388 case $.ui.keyCode.LEFT: 3389 this.collapse( event ); 3390 break; 3391 case $.ui.keyCode.RIGHT: 3392 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 3393 this.expand( event ); 3394 } 3395 break; 3396 case $.ui.keyCode.ENTER: 3397 case $.ui.keyCode.SPACE: 3398 this._activate( event ); 3399 break; 3400 case $.ui.keyCode.ESCAPE: 3401 this.collapse( event ); 3402 break; 3403 default: 3404 preventDefault = false; 3405 prev = this.previousFilter || ""; 3406 skip = false; 3407 3408 // Support number pad values 3409 character = event.keyCode >= 96 && event.keyCode <= 105 ? 3410 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 3411 3412 clearTimeout( this.filterTimer ); 3413 3414 if ( character === prev ) { 3415 skip = true; 3416 } else { 3417 character = prev + character; 3418 } 3419 3420 match = this._filterMenuItems( character ); 3421 match = skip && match.index( this.active.next() ) !== -1 ? 3422 this.active.nextAll( ".ui-menu-item" ) : 3423 match; 3424 3425 // If no matches on the current filter, reset to the last character pressed 3426 // to move down the menu to the first item that starts with that character 3427 if ( !match.length ) { 3428 character = String.fromCharCode( event.keyCode ); 3429 match = this._filterMenuItems( character ); 3430 } 3431 3432 if ( match.length ) { 3433 this.focus( event, match ); 3434 this.previousFilter = character; 3435 this.filterTimer = this._delay( function() { 3436 delete this.previousFilter; 3437 }, 1000 ); 3438 } else { 3439 delete this.previousFilter; 3440 } 3441 } 3442 3443 if ( preventDefault ) { 3444 event.preventDefault(); 3445 } 3446 }, 3447 3448 _activate: function( event ) { 3449 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 3450 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 3451 this.expand( event ); 3452 } else { 3453 this.select( event ); 3454 } 3455 } 3456 }, 3457 3458 refresh: function() { 3459 var menus, items, newSubmenus, newItems, newWrappers, 3460 that = this, 3461 icon = this.options.icons.submenu, 3462 submenus = this.element.find( this.options.menus ); 3463 3464 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 3465 3466 // Initialize nested menus 3467 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 3468 .hide() 3469 .attr( { 3470 role: this.options.role, 3471 "aria-hidden": "true", 3472 "aria-expanded": "false" 3473 } ) 3474 .each( function() { 3475 var menu = $( this ), 3476 item = menu.prev(), 3477 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 3478 3479 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 3480 item 3481 .attr( "aria-haspopup", "true" ) 3482 .prepend( submenuCaret ); 3483 menu.attr( "aria-labelledby", item.attr( "id" ) ); 3484 } ); 3485 3486 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 3487 3488 menus = submenus.add( this.element ); 3489 items = menus.find( this.options.items ); 3490 3491 // Initialize menu-items containing spaces and/or dashes only as dividers 3492 items.not( ".ui-menu-item" ).each( function() { 3493 var item = $( this ); 3494 if ( that._isDivider( item ) ) { 3495 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 3496 } 3497 } ); 3498 3499 // Don't refresh list items that are already adapted 3500 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 3501 newWrappers = newItems.children() 3502 .not( ".ui-menu" ) 3503 .uniqueId() 3504 .attr( { 3505 tabIndex: -1, 3506 role: this._itemRole() 3507 } ); 3508 this._addClass( newItems, "ui-menu-item" ) 3509 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 3510 3511 // Add aria-disabled attribute to any disabled menu item 3512 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 3513 3514 // If the active item has been removed, blur the menu 3515 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 3516 this.blur(); 3517 } 3518 }, 3519 3520 _itemRole: function() { 3521 return { 3522 menu: "menuitem", 3523 listbox: "option" 3524 }[ this.options.role ]; 3525 }, 3526 3527 _setOption: function( key, value ) { 3528 if ( key === "icons" ) { 3529 var icons = this.element.find( ".ui-menu-icon" ); 3530 this._removeClass( icons, null, this.options.icons.submenu ) 3531 ._addClass( icons, null, value.submenu ); 3532 } 3533 this._super( key, value ); 3534 }, 3535 3536 _setOptionDisabled: function( value ) { 3537 this._super( value ); 3538 3539 this.element.attr( "aria-disabled", String( value ) ); 3540 this._toggleClass( null, "ui-state-disabled", !!value ); 3541 }, 3542 3543 focus: function( event, item ) { 3544 var nested, focused, activeParent; 3545 this.blur( event, event && event.type === "focus" ); 3546 3547 this._scrollIntoView( item ); 3548 3549 this.active = item.first(); 3550 3551 focused = this.active.children( ".ui-menu-item-wrapper" ); 3552 this._addClass( focused, null, "ui-state-active" ); 3553 3554 // Only update aria-activedescendant if there's a role 3555 // otherwise we assume focus is managed elsewhere 3556 if ( this.options.role ) { 3557 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 3558 } 3559 3560 // Highlight active parent menu item, if any 3561 activeParent = this.active 3562 .parent() 3563 .closest( ".ui-menu-item" ) 3564 .children( ".ui-menu-item-wrapper" ); 3565 this._addClass( activeParent, null, "ui-state-active" ); 3566 3567 if ( event && event.type === "keydown" ) { 3568 this._close(); 3569 } else { 3570 this.timer = this._delay( function() { 3571 this._close(); 3572 }, this.delay ); 3573 } 3574 3575 nested = item.children( ".ui-menu" ); 3576 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 3577 this._startOpening( nested ); 3578 } 3579 this.activeMenu = item.parent(); 3580 3581 this._trigger( "focus", event, { item: item } ); 3582 }, 3583 3584 _scrollIntoView: function( item ) { 3585 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 3586 if ( this._hasScroll() ) { 3587 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 3588 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 3589 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 3590 scroll = this.activeMenu.scrollTop(); 3591 elementHeight = this.activeMenu.height(); 3592 itemHeight = item.outerHeight(); 3593 3594 if ( offset < 0 ) { 3595 this.activeMenu.scrollTop( scroll + offset ); 3596 } else if ( offset + itemHeight > elementHeight ) { 3597 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 3598 } 3599 } 3600 }, 3601 3602 blur: function( event, fromFocus ) { 3603 if ( !fromFocus ) { 3604 clearTimeout( this.timer ); 3605 } 3606 3607 if ( !this.active ) { 3608 return; 3609 } 3610 3611 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 3612 null, "ui-state-active" ); 3613 3614 this._trigger( "blur", event, { item: this.active } ); 3615 this.active = null; 3616 }, 3617 3618 _startOpening: function( submenu ) { 3619 clearTimeout( this.timer ); 3620 3621 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 3622 // shift in the submenu position when mousing over the caret icon 3623 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 3624 return; 3625 } 3626 3627 this.timer = this._delay( function() { 3628 this._close(); 3629 this._open( submenu ); 3630 }, this.delay ); 3631 }, 3632 3633 _open: function( submenu ) { 3634 var position = $.extend( { 3635 of: this.active 3636 }, this.options.position ); 3637 3638 clearTimeout( this.timer ); 3639 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 3640 .hide() 3641 .attr( "aria-hidden", "true" ); 3642 3643 submenu 3644 .show() 3645 .removeAttr( "aria-hidden" ) 3646 .attr( "aria-expanded", "true" ) 3647 .position( position ); 3648 }, 3649 3650 collapseAll: function( event, all ) { 3651 clearTimeout( this.timer ); 3652 this.timer = this._delay( function() { 3653 3654 // If we were passed an event, look for the submenu that contains the event 3655 var currentMenu = all ? this.element : 3656 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 3657 3658 // If we found no valid submenu ancestor, use the main menu to close all 3659 // sub menus anyway 3660 if ( !currentMenu.length ) { 3661 currentMenu = this.element; 3662 } 3663 3664 this._close( currentMenu ); 3665 3666 this.blur( event ); 3667 3668 // Work around active item staying active after menu is blurred 3669 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 3670 3671 this.activeMenu = currentMenu; 3672 }, this.delay ); 3673 }, 3674 3675 // With no arguments, closes the currently active menu - if nothing is active 3676 // it closes all menus. If passed an argument, it will search for menus BELOW 3677 _close: function( startMenu ) { 3678 if ( !startMenu ) { 3679 startMenu = this.active ? this.active.parent() : this.element; 3680 } 3681 3682 startMenu.find( ".ui-menu" ) 3683 .hide() 3684 .attr( "aria-hidden", "true" ) 3685 .attr( "aria-expanded", "false" ); 3686 }, 3687 3688 _closeOnDocumentClick: function( event ) { 3689 return !$( event.target ).closest( ".ui-menu" ).length; 3690 }, 3691 3692 _isDivider: function( item ) { 3693 3694 // Match hyphen, em dash, en dash 3695 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 3696 }, 3697 3698 collapse: function( event ) { 3699 var newItem = this.active && 3700 this.active.parent().closest( ".ui-menu-item", this.element ); 3701 if ( newItem && newItem.length ) { 3702 this._close(); 3703 this.focus( event, newItem ); 3704 } 3705 }, 3706 3707 expand: function( event ) { 3708 var newItem = this.active && 3709 this.active 3710 .children( ".ui-menu " ) 3711 .find( this.options.items ) 3712 .first(); 3713 3714 if ( newItem && newItem.length ) { 3715 this._open( newItem.parent() ); 3716 3717 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 3718 this._delay( function() { 3719 this.focus( event, newItem ); 3720 } ); 3721 } 3722 }, 3723 3724 next: function( event ) { 3725 this._move( "next", "first", event ); 3726 }, 3727 3728 previous: function( event ) { 3729 this._move( "prev", "last", event ); 3730 }, 3731 3732 isFirstItem: function() { 3733 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 3734 }, 3735 3736 isLastItem: function() { 3737 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 3738 }, 3739 3740 _move: function( direction, filter, event ) { 3741 var next; 3742 if ( this.active ) { 3743 if ( direction === "first" || direction === "last" ) { 3744 next = this.active 3745 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 3746 .eq( -1 ); 3747 } else { 3748 next = this.active 3749 [ direction + "All" ]( ".ui-menu-item" ) 3750 .eq( 0 ); 3751 } 3752 } 3753 if ( !next || !next.length || !this.active ) { 3754 next = this.activeMenu.find( this.options.items )[ filter ](); 3755 } 3756 3757 this.focus( event, next ); 3758 }, 3759 3760 nextPage: function( event ) { 3761 var item, base, height; 3762 3763 if ( !this.active ) { 3764 this.next( event ); 3765 return; 3766 } 3767 if ( this.isLastItem() ) { 3768 return; 3769 } 3770 if ( this._hasScroll() ) { 3771 base = this.active.offset().top; 3772 height = this.element.height(); 3773 this.active.nextAll( ".ui-menu-item" ).each( function() { 3774 item = $( this ); 3775 return item.offset().top - base - height < 0; 3776 } ); 3777 3778 this.focus( event, item ); 3779 } else { 3780 this.focus( event, this.activeMenu.find( this.options.items ) 3781 [ !this.active ? "first" : "last" ]() ); 3782 } 3783 }, 3784 3785 previousPage: function( event ) { 3786 var item, base, height; 3787 if ( !this.active ) { 3788 this.next( event ); 3789 return; 3790 } 3791 if ( this.isFirstItem() ) { 3792 return; 3793 } 3794 if ( this._hasScroll() ) { 3795 base = this.active.offset().top; 3796 height = this.element.height(); 3797 this.active.prevAll( ".ui-menu-item" ).each( function() { 3798 item = $( this ); 3799 return item.offset().top - base + height > 0; 3800 } ); 3801 3802 this.focus( event, item ); 3803 } else { 3804 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 3805 } 3806 }, 3807 3808 _hasScroll: function() { 3809 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 3810 }, 3811 3812 select: function( event ) { 3813 3814 // TODO: It should never be possible to not have an active item at this 3815 // point, but the tests don't trigger mouseenter before click. 3816 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 3817 var ui = { item: this.active }; 3818 if ( !this.active.has( ".ui-menu" ).length ) { 3819 this.collapseAll( event, true ); 3820 } 3821 this._trigger( "select", event, ui ); 3822 }, 3823 3824 _filterMenuItems: function( character ) { 3825 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 3826 regex = new RegExp( "^" + escapedCharacter, "i" ); 3827 3828 return this.activeMenu 3829 .find( this.options.items ) 3830 3831 // Only match on items, not dividers or other content (#10571) 3832 .filter( ".ui-menu-item" ) 3833 .filter( function() { 3834 return regex.test( 3835 $.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 3836 } ); 3837 } 3838} ); 3839 3840 3841/*! 3842 * jQuery UI Autocomplete 1.12.1 3843 * http://jqueryui.com 3844 * 3845 * Copyright jQuery Foundation and other contributors 3846 * Released under the MIT license. 3847 * http://jquery.org/license 3848 */ 3849 3850//>>label: Autocomplete 3851//>>group: Widgets 3852//>>description: Lists suggested words as the user is typing. 3853//>>docs: http://api.jqueryui.com/autocomplete/ 3854//>>demos: http://jqueryui.com/autocomplete/ 3855//>>css.structure: ../../themes/base/core.css 3856//>>css.structure: ../../themes/base/autocomplete.css 3857//>>css.theme: ../../themes/base/theme.css 3858 3859 3860 3861$.widget( "ui.autocomplete", { 3862 version: "1.12.1", 3863 defaultElement: "<input>", 3864 options: { 3865 appendTo: null, 3866 autoFocus: false, 3867 delay: 300, 3868 minLength: 1, 3869 position: { 3870 my: "left top", 3871 at: "left bottom", 3872 collision: "none" 3873 }, 3874 source: null, 3875 3876 // Callbacks 3877 change: null, 3878 close: null, 3879 focus: null, 3880 open: null, 3881 response: null, 3882 search: null, 3883 select: null 3884 }, 3885 3886 requestIndex: 0, 3887 pending: 0, 3888 3889 _create: function() { 3890 3891 // Some browsers only repeat keydown events, not keypress events, 3892 // so we use the suppressKeyPress flag to determine if we've already 3893 // handled the keydown event. #7269 3894 // Unfortunately the code for & in keypress is the same as the up arrow, 3895 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 3896 // events when we know the keydown event was used to modify the 3897 // search term. #7799 3898 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 3899 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 3900 isTextarea = nodeName === "textarea", 3901 isInput = nodeName === "input"; 3902 3903 // Textareas are always multi-line 3904 // Inputs are always single-line, even if inside a contentEditable element 3905 // IE also treats inputs as contentEditable 3906 // All other element types are determined by whether or not they're contentEditable 3907 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 3908 3909 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 3910 this.isNewMenu = true; 3911 3912 this._addClass( "ui-autocomplete-input" ); 3913 this.element.attr( "autocomplete", "off" ); 3914 3915 this._on( this.element, { 3916 keydown: function( event ) { 3917 if ( this.element.prop( "readOnly" ) ) { 3918 suppressKeyPress = true; 3919 suppressInput = true; 3920 suppressKeyPressRepeat = true; 3921 return; 3922 } 3923 3924 suppressKeyPress = false; 3925 suppressInput = false; 3926 suppressKeyPressRepeat = false; 3927 var keyCode = $.ui.keyCode; 3928 switch ( event.keyCode ) { 3929 case keyCode.PAGE_UP: 3930 suppressKeyPress = true; 3931 this._move( "previousPage", event ); 3932 break; 3933 case keyCode.PAGE_DOWN: 3934 suppressKeyPress = true; 3935 this._move( "nextPage", event ); 3936 break; 3937 case keyCode.UP: 3938 suppressKeyPress = true; 3939 this._keyEvent( "previous", event ); 3940 break; 3941 case keyCode.DOWN: 3942 suppressKeyPress = true; 3943 this._keyEvent( "next", event ); 3944 break; 3945 case keyCode.ENTER: 3946 3947 // when menu is open and has focus 3948 if ( this.menu.active ) { 3949 3950 // #6055 - Opera still allows the keypress to occur 3951 // which causes forms to submit 3952 suppressKeyPress = true; 3953 event.preventDefault(); 3954 this.menu.select( event ); 3955 } 3956 break; 3957 case keyCode.TAB: 3958 if ( this.menu.active ) { 3959 this.menu.select( event ); 3960 } 3961 break; 3962 case keyCode.ESCAPE: 3963 if ( this.menu.element.is( ":visible" ) ) { 3964 if ( !this.isMultiLine ) { 3965 this._value( this.term ); 3966 } 3967 this.close( event ); 3968 3969 // Different browsers have different default behavior for escape 3970 // Single press can mean undo or clear 3971 // Double press in IE means clear the whole form 3972 event.preventDefault(); 3973 } 3974 break; 3975 default: 3976 suppressKeyPressRepeat = true; 3977 3978 // search timeout should be triggered before the input value is changed 3979 this._searchTimeout( event ); 3980 break; 3981 } 3982 }, 3983 keypress: function( event ) { 3984 if ( suppressKeyPress ) { 3985 suppressKeyPress = false; 3986 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 3987 event.preventDefault(); 3988 } 3989 return; 3990 } 3991 if ( suppressKeyPressRepeat ) { 3992 return; 3993 } 3994 3995 // Replicate some key handlers to allow them to repeat in Firefox and Opera 3996 var keyCode = $.ui.keyCode; 3997 switch ( event.keyCode ) { 3998 case keyCode.PAGE_UP: 3999 this._move( "previousPage", event ); 4000 break; 4001 case keyCode.PAGE_DOWN: 4002 this._move( "nextPage", event ); 4003 break; 4004 case keyCode.UP: 4005 this._keyEvent( "previous", event ); 4006 break; 4007 case keyCode.DOWN: 4008 this._keyEvent( "next", event ); 4009 break; 4010 } 4011 }, 4012 input: function( event ) { 4013 if ( suppressInput ) { 4014 suppressInput = false; 4015 event.preventDefault(); 4016 return; 4017 } 4018 this._searchTimeout( event ); 4019 }, 4020 focus: function() { 4021 this.selectedItem = null; 4022 this.previous = this._value(); 4023 }, 4024 blur: function( event ) { 4025 if ( this.cancelBlur ) { 4026 delete this.cancelBlur; 4027 return; 4028 } 4029 4030 clearTimeout( this.searching ); 4031 this.close( event ); 4032 this._change( event ); 4033 } 4034 } ); 4035 4036 this._initSource(); 4037 this.menu = $( "<ul>" ) 4038 .appendTo( this._appendTo() ) 4039 .menu( { 4040 4041 // disable ARIA support, the live region takes care of that 4042 role: null 4043 } ) 4044 .hide() 4045 .menu( "instance" ); 4046 4047 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 4048 this._on( this.menu.element, { 4049 mousedown: function( event ) { 4050 4051 // prevent moving focus out of the text field 4052 event.preventDefault(); 4053 4054 // IE doesn't prevent moving focus even with event.preventDefault() 4055 // so we set a flag to know when we should ignore the blur event 4056 this.cancelBlur = true; 4057 this._delay( function() { 4058 delete this.cancelBlur; 4059 4060 // Support: IE 8 only 4061 // Right clicking a menu item or selecting text from the menu items will 4062 // result in focus moving out of the input. However, we've already received 4063 // and ignored the blur event because of the cancelBlur flag set above. So 4064 // we restore focus to ensure that the menu closes properly based on the user's 4065 // next actions. 4066 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 4067 this.element.trigger( "focus" ); 4068 } 4069 } ); 4070 }, 4071 menufocus: function( event, ui ) { 4072 var label, item; 4073 4074 // support: Firefox 4075 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 4076 if ( this.isNewMenu ) { 4077 this.isNewMenu = false; 4078 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 4079 this.menu.blur(); 4080 4081 this.document.one( "mousemove", function() { 4082 $( event.target ).trigger( event.originalEvent ); 4083 } ); 4084 4085 return; 4086 } 4087 } 4088 4089 item = ui.item.data( "ui-autocomplete-item" ); 4090 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 4091 4092 // use value to match what will end up in the input, if it was a key event 4093 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 4094 this._value( item.value ); 4095 } 4096 } 4097 4098 // Announce the value in the liveRegion 4099 label = ui.item.attr( "aria-label" ) || item.value; 4100 if ( label && $.trim( label ).length ) { 4101 this.liveRegion.children().hide(); 4102 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 4103 } 4104 }, 4105 menuselect: function( event, ui ) { 4106 var item = ui.item.data( "ui-autocomplete-item" ), 4107 previous = this.previous; 4108 4109 // Only trigger when focus was lost (click on menu) 4110 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 4111 this.element.trigger( "focus" ); 4112 this.previous = previous; 4113 4114 // #6109 - IE triggers two focus events and the second 4115 // is asynchronous, so we need to reset the previous 4116 // term synchronously and asynchronously :-( 4117 this._delay( function() { 4118 this.previous = previous; 4119 this.selectedItem = item; 4120 } ); 4121 } 4122 4123 if ( false !== this._trigger( "select", event, { item: item } ) ) { 4124 this._value( item.value ); 4125 } 4126 4127 // reset the term after the select event 4128 // this allows custom select handling to work properly 4129 this.term = this._value(); 4130 4131 this.close( event ); 4132 this.selectedItem = item; 4133 } 4134 } ); 4135 4136 this.liveRegion = $( "<div>", { 4137 role: "status", 4138 "aria-live": "assertive", 4139 "aria-relevant": "additions" 4140 } ) 4141 .appendTo( this.document[ 0 ].body ); 4142 4143 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 4144 4145 // Turning off autocomplete prevents the browser from remembering the 4146 // value when navigating through history, so we re-enable autocomplete 4147 // if the page is unloaded before the widget is destroyed. #7790 4148 this._on( this.window, { 4149 beforeunload: function() { 4150 this.element.removeAttr( "autocomplete" ); 4151 } 4152 } ); 4153 }, 4154 4155 _destroy: function() { 4156 clearTimeout( this.searching ); 4157 this.element.removeAttr( "autocomplete" ); 4158 this.menu.element.remove(); 4159 this.liveRegion.remove(); 4160 }, 4161 4162 _setOption: function( key, value ) { 4163 this._super( key, value ); 4164 if ( key === "source" ) { 4165 this._initSource(); 4166 } 4167 if ( key === "appendTo" ) { 4168 this.menu.element.appendTo( this._appendTo() ); 4169 } 4170 if ( key === "disabled" && value && this.xhr ) { 4171 this.xhr.abort(); 4172 } 4173 }, 4174 4175 _isEventTargetInWidget: function( event ) { 4176 var menuElement = this.menu.element[ 0 ]; 4177 4178 return event.target === this.element[ 0 ] || 4179 event.target === menuElement || 4180 $.contains( menuElement, event.target ); 4181 }, 4182 4183 _closeOnClickOutside: function( event ) { 4184 if ( !this._isEventTargetInWidget( event ) ) { 4185 this.close(); 4186 } 4187 }, 4188 4189 _appendTo: function() { 4190 var element = this.options.appendTo; 4191 4192 if ( element ) { 4193 element = element.jquery || element.nodeType ? 4194 $( element ) : 4195 this.document.find( element ).eq( 0 ); 4196 } 4197 4198 if ( !element || !element[ 0 ] ) { 4199 element = this.element.closest( ".ui-front, dialog" ); 4200 } 4201 4202 if ( !element.length ) { 4203 element = this.document[ 0 ].body; 4204 } 4205 4206 return element; 4207 }, 4208 4209 _initSource: function() { 4210 var array, url, 4211 that = this; 4212 if ( $.isArray( this.options.source ) ) { 4213 array = this.options.source; 4214 this.source = function( request, response ) { 4215 response( $.ui.autocomplete.filter( array, request.term ) ); 4216 }; 4217 } else if ( typeof this.options.source === "string" ) { 4218 url = this.options.source; 4219 this.source = function( request, response ) { 4220 if ( that.xhr ) { 4221 that.xhr.abort(); 4222 } 4223 that.xhr = $.ajax( { 4224 url: url, 4225 data: request, 4226 dataType: "json", 4227 success: function( data ) { 4228 response( data ); 4229 }, 4230 error: function() { 4231 response( [] ); 4232 } 4233 } ); 4234 }; 4235 } else { 4236 this.source = this.options.source; 4237 } 4238 }, 4239 4240 _searchTimeout: function( event ) { 4241 clearTimeout( this.searching ); 4242 this.searching = this._delay( function() { 4243 4244 // Search if the value has changed, or if the user retypes the same value (see #7434) 4245 var equalValues = this.term === this._value(), 4246 menuVisible = this.menu.element.is( ":visible" ), 4247 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 4248 4249 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 4250 this.selectedItem = null; 4251 this.search( null, event ); 4252 } 4253 }, this.options.delay ); 4254 }, 4255 4256 search: function( value, event ) { 4257 value = value != null ? value : this._value(); 4258 4259 // Always save the actual value, not the one passed as an argument 4260 this.term = this._value(); 4261 4262 if ( value.length < this.options.minLength ) { 4263 return this.close( event ); 4264 } 4265 4266 if ( this._trigger( "search", event ) === false ) { 4267 return; 4268 } 4269 4270 return this._search( value ); 4271 }, 4272 4273 _search: function( value ) { 4274 this.pending++; 4275 this._addClass( "ui-autocomplete-loading" ); 4276 this.cancelSearch = false; 4277 4278 this.source( { term: value }, this._response() ); 4279 }, 4280 4281 _response: function() { 4282 var index = ++this.requestIndex; 4283 4284 return $.proxy( function( content ) { 4285 if ( index === this.requestIndex ) { 4286 this.__response( content ); 4287 } 4288 4289 this.pending--; 4290 if ( !this.pending ) { 4291 this._removeClass( "ui-autocomplete-loading" ); 4292 } 4293 }, this ); 4294 }, 4295 4296 __response: function( content ) { 4297 if ( content ) { 4298 content = this._normalize( content ); 4299 } 4300 this._trigger( "response", null, { content: content } ); 4301 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 4302 this._suggest( content ); 4303 this._trigger( "open" ); 4304 } else { 4305 4306 // use ._close() instead of .close() so we don't cancel future searches 4307 this._close(); 4308 } 4309 }, 4310 4311 close: function( event ) { 4312 this.cancelSearch = true; 4313 this._close( event ); 4314 }, 4315 4316 _close: function( event ) { 4317 4318 // Remove the handler that closes the menu on outside clicks 4319 this._off( this.document, "mousedown" ); 4320 4321 if ( this.menu.element.is( ":visible" ) ) { 4322 this.menu.element.hide(); 4323 this.menu.blur(); 4324 this.isNewMenu = true; 4325 this._trigger( "close", event ); 4326 } 4327 }, 4328 4329 _change: function( event ) { 4330 if ( this.previous !== this._value() ) { 4331 this._trigger( "change", event, { item: this.selectedItem } ); 4332 } 4333 }, 4334 4335 _normalize: function( items ) { 4336 4337 // assume all items have the right format when the first item is complete 4338 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 4339 return items; 4340 } 4341 return $.map( items, function( item ) { 4342 if ( typeof item === "string" ) { 4343 return { 4344 label: item, 4345 value: item 4346 }; 4347 } 4348 return $.extend( {}, item, { 4349 label: item.label || item.value, 4350 value: item.value || item.label 4351 } ); 4352 } ); 4353 }, 4354 4355 _suggest: function( items ) { 4356 var ul = this.menu.element.empty(); 4357 this._renderMenu( ul, items ); 4358 this.isNewMenu = true; 4359 this.menu.refresh(); 4360 4361 // Size and position menu 4362 ul.show(); 4363 this._resizeMenu(); 4364 ul.position( $.extend( { 4365 of: this.element 4366 }, this.options.position ) ); 4367 4368 if ( this.options.autoFocus ) { 4369 this.menu.next(); 4370 } 4371 4372 // Listen for interactions outside of the widget (#6642) 4373 this._on( this.document, { 4374 mousedown: "_closeOnClickOutside" 4375 } ); 4376 }, 4377 4378 _resizeMenu: function() { 4379 var ul = this.menu.element; 4380 ul.outerWidth( Math.max( 4381 4382 // Firefox wraps long text (possibly a rounding bug) 4383 // so we add 1px to avoid the wrapping (#7513) 4384 ul.width( "" ).outerWidth() + 1, 4385 this.element.outerWidth() 4386 ) ); 4387 }, 4388 4389 _renderMenu: function( ul, items ) { 4390 var that = this; 4391 $.each( items, function( index, item ) { 4392 that._renderItemData( ul, item ); 4393 } ); 4394 }, 4395 4396 _renderItemData: function( ul, item ) { 4397 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 4398 }, 4399 4400 _renderItem: function( ul, item ) { 4401 return $( "<li>" ) 4402 .append( $( "<div>" ).text( item.label ) ) 4403 .appendTo( ul ); 4404 }, 4405 4406 _move: function( direction, event ) { 4407 if ( !this.menu.element.is( ":visible" ) ) { 4408 this.search( null, event ); 4409 return; 4410 } 4411 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 4412 this.menu.isLastItem() && /^next/.test( direction ) ) { 4413 4414 if ( !this.isMultiLine ) { 4415 this._value( this.term ); 4416 } 4417 4418 this.menu.blur(); 4419 return; 4420 } 4421 this.menu[ direction ]( event ); 4422 }, 4423 4424 widget: function() { 4425 return this.menu.element; 4426 }, 4427 4428 _value: function() { 4429 return this.valueMethod.apply( this.element, arguments ); 4430 }, 4431 4432 _keyEvent: function( keyEvent, event ) { 4433 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 4434 this._move( keyEvent, event ); 4435 4436 // Prevents moving cursor to beginning/end of the text field in some browsers 4437 event.preventDefault(); 4438 } 4439 }, 4440 4441 // Support: Chrome <=50 4442 // We should be able to just use this.element.prop( "isContentEditable" ) 4443 // but hidden elements always report false in Chrome. 4444 // https://code.google.com/p/chromium/issues/detail?id=313082 4445 _isContentEditable: function( element ) { 4446 if ( !element.length ) { 4447 return false; 4448 } 4449 4450 var editable = element.prop( "contentEditable" ); 4451 4452 if ( editable === "inherit" ) { 4453 return this._isContentEditable( element.parent() ); 4454 } 4455 4456 return editable === "true"; 4457 } 4458} ); 4459 4460$.extend( $.ui.autocomplete, { 4461 escapeRegex: function( value ) { 4462 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 4463 }, 4464 filter: function( array, term ) { 4465 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 4466 return $.grep( array, function( value ) { 4467 return matcher.test( value.label || value.value || value ); 4468 } ); 4469 } 4470} ); 4471 4472// Live region extension, adding a `messages` option 4473// NOTE: This is an experimental API. We are still investigating 4474// a full solution for string manipulation and internationalization. 4475$.widget( "ui.autocomplete", $.ui.autocomplete, { 4476 options: { 4477 messages: { 4478 noResults: "No search results.", 4479 results: function( amount ) { 4480 return amount + ( amount > 1 ? " results are" : " result is" ) + 4481 " available, use up and down arrow keys to navigate."; 4482 } 4483 } 4484 }, 4485 4486 __response: function( content ) { 4487 var message; 4488 this._superApply( arguments ); 4489 if ( this.options.disabled || this.cancelSearch ) { 4490 return; 4491 } 4492 if ( content && content.length ) { 4493 message = this.options.messages.results( content.length ); 4494 } else { 4495 message = this.options.messages.noResults; 4496 } 4497 this.liveRegion.children().hide(); 4498 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 4499 } 4500} ); 4501 4502var widgetsAutocomplete = $.ui.autocomplete; 4503 4504 4505/*! 4506 * jQuery UI Effects 1.12.1 4507 * http://jqueryui.com 4508 * 4509 * Copyright jQuery Foundation and other contributors 4510 * Released under the MIT license. 4511 * http://jquery.org/license 4512 */ 4513 4514//>>label: Effects Core 4515//>>group: Effects 4516// jscs:disable maximumLineLength 4517//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 4518// jscs:enable maximumLineLength 4519//>>docs: http://api.jqueryui.com/category/effects-core/ 4520//>>demos: http://jqueryui.com/effect/ 4521 4522 4523 4524var dataSpace = "ui-effects-", 4525 dataSpaceStyle = "ui-effects-style", 4526 dataSpaceAnimated = "ui-effects-animated", 4527 4528 // Create a local jQuery because jQuery Color relies on it and the 4529 // global may not exist with AMD and a custom build (#10199) 4530 jQuery = $; 4531 4532$.effects = { 4533 effect: {} 4534}; 4535 4536/*! 4537 * jQuery Color Animations v2.1.2 4538 * https://github.com/jquery/jquery-color 4539 * 4540 * Copyright 2014 jQuery Foundation and other contributors 4541 * Released under the MIT license. 4542 * http://jquery.org/license 4543 * 4544 * Date: Wed Jan 16 08:47:09 2013 -0600 4545 */ 4546( function( jQuery, undefined ) { 4547 4548 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 4549 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4550 4551 // Plusequals test for += 100 -= 100 4552 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4553 4554 // A set of RE's that can match strings and generate color tuples. 4555 stringParsers = [ { 4556 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4557 parse: function( execResult ) { 4558 return [ 4559 execResult[ 1 ], 4560 execResult[ 2 ], 4561 execResult[ 3 ], 4562 execResult[ 4 ] 4563 ]; 4564 } 4565 }, { 4566 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4567 parse: function( execResult ) { 4568 return [ 4569 execResult[ 1 ] * 2.55, 4570 execResult[ 2 ] * 2.55, 4571 execResult[ 3 ] * 2.55, 4572 execResult[ 4 ] 4573 ]; 4574 } 4575 }, { 4576 4577 // This regex ignores A-F because it's compared against an already lowercased string 4578 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4579 parse: function( execResult ) { 4580 return [ 4581 parseInt( execResult[ 1 ], 16 ), 4582 parseInt( execResult[ 2 ], 16 ), 4583 parseInt( execResult[ 3 ], 16 ) 4584 ]; 4585 } 4586 }, { 4587 4588 // This regex ignores A-F because it's compared against an already lowercased string 4589 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4590 parse: function( execResult ) { 4591 return [ 4592 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4593 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4594 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4595 ]; 4596 } 4597 }, { 4598 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4599 space: "hsla", 4600 parse: function( execResult ) { 4601 return [ 4602 execResult[ 1 ], 4603 execResult[ 2 ] / 100, 4604 execResult[ 3 ] / 100, 4605 execResult[ 4 ] 4606 ]; 4607 } 4608 } ], 4609 4610 // JQuery.Color( ) 4611 color = jQuery.Color = function( color, green, blue, alpha ) { 4612 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4613 }, 4614 spaces = { 4615 rgba: { 4616 props: { 4617 red: { 4618 idx: 0, 4619 type: "byte" 4620 }, 4621 green: { 4622 idx: 1, 4623 type: "byte" 4624 }, 4625 blue: { 4626 idx: 2, 4627 type: "byte" 4628 } 4629 } 4630 }, 4631 4632 hsla: { 4633 props: { 4634 hue: { 4635 idx: 0, 4636 type: "degrees" 4637 }, 4638 saturation: { 4639 idx: 1, 4640 type: "percent" 4641 }, 4642 lightness: { 4643 idx: 2, 4644 type: "percent" 4645 } 4646 } 4647 } 4648 }, 4649 propTypes = { 4650 "byte": { 4651 floor: true, 4652 max: 255 4653 }, 4654 "percent": { 4655 max: 1 4656 }, 4657 "degrees": { 4658 mod: 360, 4659 floor: true 4660 } 4661 }, 4662 support = color.support = {}, 4663 4664 // Element for support tests 4665 supportElem = jQuery( "<p>" )[ 0 ], 4666 4667 // Colors = jQuery.Color.names 4668 colors, 4669 4670 // Local aliases of functions called often 4671 each = jQuery.each; 4672 4673// Determine rgba support immediately 4674supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4675support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4676 4677// Define cache name and alpha properties 4678// for rgba and hsla spaces 4679each( spaces, function( spaceName, space ) { 4680 space.cache = "_" + spaceName; 4681 space.props.alpha = { 4682 idx: 3, 4683 type: "percent", 4684 def: 1 4685 }; 4686} ); 4687 4688function clamp( value, prop, allowEmpty ) { 4689 var type = propTypes[ prop.type ] || {}; 4690 4691 if ( value == null ) { 4692 return ( allowEmpty || !prop.def ) ? null : prop.def; 4693 } 4694 4695 // ~~ is an short way of doing floor for positive numbers 4696 value = type.floor ? ~~value : parseFloat( value ); 4697 4698 // IE will pass in empty strings as value for alpha, 4699 // which will hit this case 4700 if ( isNaN( value ) ) { 4701 return prop.def; 4702 } 4703 4704 if ( type.mod ) { 4705 4706 // We add mod before modding to make sure that negatives values 4707 // get converted properly: -10 -> 350 4708 return ( value + type.mod ) % type.mod; 4709 } 4710 4711 // For now all property types without mod have min and max 4712 return 0 > value ? 0 : type.max < value ? type.max : value; 4713} 4714 4715function stringParse( string ) { 4716 var inst = color(), 4717 rgba = inst._rgba = []; 4718 4719 string = string.toLowerCase(); 4720 4721 each( stringParsers, function( i, parser ) { 4722 var parsed, 4723 match = parser.re.exec( string ), 4724 values = match && parser.parse( match ), 4725 spaceName = parser.space || "rgba"; 4726 4727 if ( values ) { 4728 parsed = inst[ spaceName ]( values ); 4729 4730 // If this was an rgba parse the assignment might happen twice 4731 // oh well.... 4732 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4733 rgba = inst._rgba = parsed._rgba; 4734 4735 // Exit each( stringParsers ) here because we matched 4736 return false; 4737 } 4738 } ); 4739 4740 // Found a stringParser that handled it 4741 if ( rgba.length ) { 4742 4743 // If this came from a parsed string, force "transparent" when alpha is 0 4744 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4745 if ( rgba.join() === "0,0,0,0" ) { 4746 jQuery.extend( rgba, colors.transparent ); 4747 } 4748 return inst; 4749 } 4750 4751 // Named colors 4752 return colors[ string ]; 4753} 4754 4755color.fn = jQuery.extend( color.prototype, { 4756 parse: function( red, green, blue, alpha ) { 4757 if ( red === undefined ) { 4758 this._rgba = [ null, null, null, null ]; 4759 return this; 4760 } 4761 if ( red.jquery || red.nodeType ) { 4762 red = jQuery( red ).css( green ); 4763 green = undefined; 4764 } 4765 4766 var inst = this, 4767 type = jQuery.type( red ), 4768 rgba = this._rgba = []; 4769 4770 // More than 1 argument specified - assume ( red, green, blue, alpha ) 4771 if ( green !== undefined ) { 4772 red = [ red, green, blue, alpha ]; 4773 type = "array"; 4774 } 4775 4776 if ( type === "string" ) { 4777 return this.parse( stringParse( red ) || colors._default ); 4778 } 4779 4780 if ( type === "array" ) { 4781 each( spaces.rgba.props, function( key, prop ) { 4782 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 4783 } ); 4784 return this; 4785 } 4786 4787 if ( type === "object" ) { 4788 if ( red instanceof color ) { 4789 each( spaces, function( spaceName, space ) { 4790 if ( red[ space.cache ] ) { 4791 inst[ space.cache ] = red[ space.cache ].slice(); 4792 } 4793 } ); 4794 } else { 4795 each( spaces, function( spaceName, space ) { 4796 var cache = space.cache; 4797 each( space.props, function( key, prop ) { 4798 4799 // If the cache doesn't exist, and we know how to convert 4800 if ( !inst[ cache ] && space.to ) { 4801 4802 // If the value was null, we don't need to copy it 4803 // if the key was alpha, we don't need to copy it either 4804 if ( key === "alpha" || red[ key ] == null ) { 4805 return; 4806 } 4807 inst[ cache ] = space.to( inst._rgba ); 4808 } 4809 4810 // This is the only case where we allow nulls for ALL properties. 4811 // call clamp with alwaysAllowEmpty 4812 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 4813 } ); 4814 4815 // Everything defined but alpha? 4816 if ( inst[ cache ] && 4817 jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 4818 4819 // Use the default of 1 4820 inst[ cache ][ 3 ] = 1; 4821 if ( space.from ) { 4822 inst._rgba = space.from( inst[ cache ] ); 4823 } 4824 } 4825 } ); 4826 } 4827 return this; 4828 } 4829 }, 4830 is: function( compare ) { 4831 var is = color( compare ), 4832 same = true, 4833 inst = this; 4834 4835 each( spaces, function( _, space ) { 4836 var localCache, 4837 isCache = is[ space.cache ]; 4838 if ( isCache ) { 4839 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 4840 each( space.props, function( _, prop ) { 4841 if ( isCache[ prop.idx ] != null ) { 4842 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 4843 return same; 4844 } 4845 } ); 4846 } 4847 return same; 4848 } ); 4849 return same; 4850 }, 4851 _space: function() { 4852 var used = [], 4853 inst = this; 4854 each( spaces, function( spaceName, space ) { 4855 if ( inst[ space.cache ] ) { 4856 used.push( spaceName ); 4857 } 4858 } ); 4859 return used.pop(); 4860 }, 4861 transition: function( other, distance ) { 4862 var end = color( other ), 4863 spaceName = end._space(), 4864 space = spaces[ spaceName ], 4865 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 4866 start = startColor[ space.cache ] || space.to( startColor._rgba ), 4867 result = start.slice(); 4868 4869 end = end[ space.cache ]; 4870 each( space.props, function( key, prop ) { 4871 var index = prop.idx, 4872 startValue = start[ index ], 4873 endValue = end[ index ], 4874 type = propTypes[ prop.type ] || {}; 4875 4876 // If null, don't override start value 4877 if ( endValue === null ) { 4878 return; 4879 } 4880 4881 // If null - use end 4882 if ( startValue === null ) { 4883 result[ index ] = endValue; 4884 } else { 4885 if ( type.mod ) { 4886 if ( endValue - startValue > type.mod / 2 ) { 4887 startValue += type.mod; 4888 } else if ( startValue - endValue > type.mod / 2 ) { 4889 startValue -= type.mod; 4890 } 4891 } 4892 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 4893 } 4894 } ); 4895 return this[ spaceName ]( result ); 4896 }, 4897 blend: function( opaque ) { 4898 4899 // If we are already opaque - return ourself 4900 if ( this._rgba[ 3 ] === 1 ) { 4901 return this; 4902 } 4903 4904 var rgb = this._rgba.slice(), 4905 a = rgb.pop(), 4906 blend = color( opaque )._rgba; 4907 4908 return color( jQuery.map( rgb, function( v, i ) { 4909 return ( 1 - a ) * blend[ i ] + a * v; 4910 } ) ); 4911 }, 4912 toRgbaString: function() { 4913 var prefix = "rgba(", 4914 rgba = jQuery.map( this._rgba, function( v, i ) { 4915 return v == null ? ( i > 2 ? 1 : 0 ) : v; 4916 } ); 4917 4918 if ( rgba[ 3 ] === 1 ) { 4919 rgba.pop(); 4920 prefix = "rgb("; 4921 } 4922 4923 return prefix + rgba.join() + ")"; 4924 }, 4925 toHslaString: function() { 4926 var prefix = "hsla(", 4927 hsla = jQuery.map( this.hsla(), function( v, i ) { 4928 if ( v == null ) { 4929 v = i > 2 ? 1 : 0; 4930 } 4931 4932 // Catch 1 and 2 4933 if ( i && i < 3 ) { 4934 v = Math.round( v * 100 ) + "%"; 4935 } 4936 return v; 4937 } ); 4938 4939 if ( hsla[ 3 ] === 1 ) { 4940 hsla.pop(); 4941 prefix = "hsl("; 4942 } 4943 return prefix + hsla.join() + ")"; 4944 }, 4945 toHexString: function( includeAlpha ) { 4946 var rgba = this._rgba.slice(), 4947 alpha = rgba.pop(); 4948 4949 if ( includeAlpha ) { 4950 rgba.push( ~~( alpha * 255 ) ); 4951 } 4952 4953 return "#" + jQuery.map( rgba, function( v ) { 4954 4955 // Default to 0 when nulls exist 4956 v = ( v || 0 ).toString( 16 ); 4957 return v.length === 1 ? "0" + v : v; 4958 } ).join( "" ); 4959 }, 4960 toString: function() { 4961 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 4962 } 4963} ); 4964color.fn.parse.prototype = color.fn; 4965 4966// Hsla conversions adapted from: 4967// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 4968 4969function hue2rgb( p, q, h ) { 4970 h = ( h + 1 ) % 1; 4971 if ( h * 6 < 1 ) { 4972 return p + ( q - p ) * h * 6; 4973 } 4974 if ( h * 2 < 1 ) { 4975 return q; 4976 } 4977 if ( h * 3 < 2 ) { 4978 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 4979 } 4980 return p; 4981} 4982 4983spaces.hsla.to = function( rgba ) { 4984 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 4985 return [ null, null, null, rgba[ 3 ] ]; 4986 } 4987 var r = rgba[ 0 ] / 255, 4988 g = rgba[ 1 ] / 255, 4989 b = rgba[ 2 ] / 255, 4990 a = rgba[ 3 ], 4991 max = Math.max( r, g, b ), 4992 min = Math.min( r, g, b ), 4993 diff = max - min, 4994 add = max + min, 4995 l = add * 0.5, 4996 h, s; 4997 4998 if ( min === max ) { 4999 h = 0; 5000 } else if ( r === max ) { 5001 h = ( 60 * ( g - b ) / diff ) + 360; 5002 } else if ( g === max ) { 5003 h = ( 60 * ( b - r ) / diff ) + 120; 5004 } else { 5005 h = ( 60 * ( r - g ) / diff ) + 240; 5006 } 5007 5008 // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5009 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5010 if ( diff === 0 ) { 5011 s = 0; 5012 } else if ( l <= 0.5 ) { 5013 s = diff / add; 5014 } else { 5015 s = diff / ( 2 - add ); 5016 } 5017 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 5018}; 5019 5020spaces.hsla.from = function( hsla ) { 5021 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5022 return [ null, null, null, hsla[ 3 ] ]; 5023 } 5024 var h = hsla[ 0 ] / 360, 5025 s = hsla[ 1 ], 5026 l = hsla[ 2 ], 5027 a = hsla[ 3 ], 5028 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5029 p = 2 * l - q; 5030 5031 return [ 5032 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5033 Math.round( hue2rgb( p, q, h ) * 255 ), 5034 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5035 a 5036 ]; 5037}; 5038 5039each( spaces, function( spaceName, space ) { 5040 var props = space.props, 5041 cache = space.cache, 5042 to = space.to, 5043 from = space.from; 5044 5045 // Makes rgba() and hsla() 5046 color.fn[ spaceName ] = function( value ) { 5047 5048 // Generate a cache for this space if it doesn't exist 5049 if ( to && !this[ cache ] ) { 5050 this[ cache ] = to( this._rgba ); 5051 } 5052 if ( value === undefined ) { 5053 return this[ cache ].slice(); 5054 } 5055 5056 var ret, 5057 type = jQuery.type( value ), 5058 arr = ( type === "array" || type === "object" ) ? value : arguments, 5059 local = this[ cache ].slice(); 5060 5061 each( props, function( key, prop ) { 5062 var val = arr[ type === "object" ? key : prop.idx ]; 5063 if ( val == null ) { 5064 val = local[ prop.idx ]; 5065 } 5066 local[ prop.idx ] = clamp( val, prop ); 5067 } ); 5068 5069 if ( from ) { 5070 ret = color( from( local ) ); 5071 ret[ cache ] = local; 5072 return ret; 5073 } else { 5074 return color( local ); 5075 } 5076 }; 5077 5078 // Makes red() green() blue() alpha() hue() saturation() lightness() 5079 each( props, function( key, prop ) { 5080 5081 // Alpha is included in more than one space 5082 if ( color.fn[ key ] ) { 5083 return; 5084 } 5085 color.fn[ key ] = function( value ) { 5086 var vtype = jQuery.type( value ), 5087 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5088 local = this[ fn ](), 5089 cur = local[ prop.idx ], 5090 match; 5091 5092 if ( vtype === "undefined" ) { 5093 return cur; 5094 } 5095 5096 if ( vtype === "function" ) { 5097 value = value.call( this, cur ); 5098 vtype = jQuery.type( value ); 5099 } 5100 if ( value == null && prop.empty ) { 5101 return this; 5102 } 5103 if ( vtype === "string" ) { 5104 match = rplusequals.exec( value ); 5105 if ( match ) { 5106 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5107 } 5108 } 5109 local[ prop.idx ] = value; 5110 return this[ fn ]( local ); 5111 }; 5112 } ); 5113} ); 5114 5115// Add cssHook and .fx.step function for each named hook. 5116// accept a space separated string of properties 5117color.hook = function( hook ) { 5118 var hooks = hook.split( " " ); 5119 each( hooks, function( i, hook ) { 5120 jQuery.cssHooks[ hook ] = { 5121 set: function( elem, value ) { 5122 var parsed, curElem, 5123 backgroundColor = ""; 5124 5125 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || 5126 ( parsed = stringParse( value ) ) ) ) { 5127 value = color( parsed || value ); 5128 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5129 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5130 while ( 5131 ( backgroundColor === "" || backgroundColor === "transparent" ) && 5132 curElem && curElem.style 5133 ) { 5134 try { 5135 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5136 curElem = curElem.parentNode; 5137 } catch ( e ) { 5138 } 5139 } 5140 5141 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5142 backgroundColor : 5143 "_default" ); 5144 } 5145 5146 value = value.toRgbaString(); 5147 } 5148 try { 5149 elem.style[ hook ] = value; 5150 } catch ( e ) { 5151 5152 // Wrapped to prevent IE from throwing errors on "invalid" values like 5153 // 'auto' or 'inherit' 5154 } 5155 } 5156 }; 5157 jQuery.fx.step[ hook ] = function( fx ) { 5158 if ( !fx.colorInit ) { 5159 fx.start = color( fx.elem, hook ); 5160 fx.end = color( fx.end ); 5161 fx.colorInit = true; 5162 } 5163 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5164 }; 5165 } ); 5166 5167}; 5168 5169color.hook( stepHooks ); 5170 5171jQuery.cssHooks.borderColor = { 5172 expand: function( value ) { 5173 var expanded = {}; 5174 5175 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5176 expanded[ "border" + part + "Color" ] = value; 5177 } ); 5178 return expanded; 5179 } 5180}; 5181 5182// Basic color names only. 5183// Usage of any of the other color names requires adding yourself or including 5184// jquery.color.svg-names.js. 5185colors = jQuery.Color.names = { 5186 5187 // 4.1. Basic color keywords 5188 aqua: "#00ffff", 5189 black: "#000000", 5190 blue: "#0000ff", 5191 fuchsia: "#ff00ff", 5192 gray: "#808080", 5193 green: "#008000", 5194 lime: "#00ff00", 5195 maroon: "#800000", 5196 navy: "#000080", 5197 olive: "#808000", 5198 purple: "#800080", 5199 red: "#ff0000", 5200 silver: "#c0c0c0", 5201 teal: "#008080", 5202 white: "#ffffff", 5203 yellow: "#ffff00", 5204 5205 // 4.2.3. "transparent" color keyword 5206 transparent: [ null, null, null, 0 ], 5207 5208 _default: "#ffffff" 5209}; 5210 5211} )( jQuery ); 5212 5213/******************************************************************************/ 5214/****************************** CLASS ANIMATIONS ******************************/ 5215/******************************************************************************/ 5216( function() { 5217 5218var classAnimationActions = [ "add", "remove", "toggle" ], 5219 shorthandStyles = { 5220 border: 1, 5221 borderBottom: 1, 5222 borderColor: 1, 5223 borderLeft: 1, 5224 borderRight: 1, 5225 borderTop: 1, 5226 borderWidth: 1, 5227 margin: 1, 5228 padding: 1 5229 }; 5230 5231$.each( 5232 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 5233 function( _, prop ) { 5234 $.fx.step[ prop ] = function( fx ) { 5235 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5236 jQuery.style( fx.elem, prop, fx.end ); 5237 fx.setAttr = true; 5238 } 5239 }; 5240 } 5241); 5242 5243function getElementStyles( elem ) { 5244 var key, len, 5245 style = elem.ownerDocument.defaultView ? 5246 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5247 elem.currentStyle, 5248 styles = {}; 5249 5250 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5251 len = style.length; 5252 while ( len-- ) { 5253 key = style[ len ]; 5254 if ( typeof style[ key ] === "string" ) { 5255 styles[ $.camelCase( key ) ] = style[ key ]; 5256 } 5257 } 5258 5259 // Support: Opera, IE <9 5260 } else { 5261 for ( key in style ) { 5262 if ( typeof style[ key ] === "string" ) { 5263 styles[ key ] = style[ key ]; 5264 } 5265 } 5266 } 5267 5268 return styles; 5269} 5270 5271function styleDifference( oldStyle, newStyle ) { 5272 var diff = {}, 5273 name, value; 5274 5275 for ( name in newStyle ) { 5276 value = newStyle[ name ]; 5277 if ( oldStyle[ name ] !== value ) { 5278 if ( !shorthandStyles[ name ] ) { 5279 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5280 diff[ name ] = value; 5281 } 5282 } 5283 } 5284 } 5285 5286 return diff; 5287} 5288 5289// Support: jQuery <1.8 5290if ( !$.fn.addBack ) { 5291 $.fn.addBack = function( selector ) { 5292 return this.add( selector == null ? 5293 this.prevObject : this.prevObject.filter( selector ) 5294 ); 5295 }; 5296} 5297 5298$.effects.animateClass = function( value, duration, easing, callback ) { 5299 var o = $.speed( duration, easing, callback ); 5300 5301 return this.queue( function() { 5302 var animated = $( this ), 5303 baseClass = animated.attr( "class" ) || "", 5304 applyClassChange, 5305 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5306 5307 // Map the animated objects to store the original styles. 5308 allAnimations = allAnimations.map( function() { 5309 var el = $( this ); 5310 return { 5311 el: el, 5312 start: getElementStyles( this ) 5313 }; 5314 } ); 5315 5316 // Apply class change 5317 applyClassChange = function() { 5318 $.each( classAnimationActions, function( i, action ) { 5319 if ( value[ action ] ) { 5320 animated[ action + "Class" ]( value[ action ] ); 5321 } 5322 } ); 5323 }; 5324 applyClassChange(); 5325 5326 // Map all animated objects again - calculate new styles and diff 5327 allAnimations = allAnimations.map( function() { 5328 this.end = getElementStyles( this.el[ 0 ] ); 5329 this.diff = styleDifference( this.start, this.end ); 5330 return this; 5331 } ); 5332 5333 // Apply original class 5334 animated.attr( "class", baseClass ); 5335 5336 // Map all animated objects again - this time collecting a promise 5337 allAnimations = allAnimations.map( function() { 5338 var styleInfo = this, 5339 dfd = $.Deferred(), 5340 opts = $.extend( {}, o, { 5341 queue: false, 5342 complete: function() { 5343 dfd.resolve( styleInfo ); 5344 } 5345 } ); 5346 5347 this.el.animate( this.diff, opts ); 5348 return dfd.promise(); 5349 } ); 5350 5351 // Once all animations have completed: 5352 $.when.apply( $, allAnimations.get() ).done( function() { 5353 5354 // Set the final class 5355 applyClassChange(); 5356 5357 // For each animated element, 5358 // clear all css properties that were animated 5359 $.each( arguments, function() { 5360 var el = this.el; 5361 $.each( this.diff, function( key ) { 5362 el.css( key, "" ); 5363 } ); 5364 } ); 5365 5366 // This is guarnteed to be there if you use jQuery.speed() 5367 // it also handles dequeuing the next anim... 5368 o.complete.call( animated[ 0 ] ); 5369 } ); 5370 } ); 5371}; 5372 5373$.fn.extend( { 5374 addClass: ( function( orig ) { 5375 return function( classNames, speed, easing, callback ) { 5376 return speed ? 5377 $.effects.animateClass.call( this, 5378 { add: classNames }, speed, easing, callback ) : 5379 orig.apply( this, arguments ); 5380 }; 5381 } )( $.fn.addClass ), 5382 5383 removeClass: ( function( orig ) { 5384 return function( classNames, speed, easing, callback ) { 5385 return arguments.length > 1 ? 5386 $.effects.animateClass.call( this, 5387 { remove: classNames }, speed, easing, callback ) : 5388 orig.apply( this, arguments ); 5389 }; 5390 } )( $.fn.removeClass ), 5391 5392 toggleClass: ( function( orig ) { 5393 return function( classNames, force, speed, easing, callback ) { 5394 if ( typeof force === "boolean" || force === undefined ) { 5395 if ( !speed ) { 5396 5397 // Without speed parameter 5398 return orig.apply( this, arguments ); 5399 } else { 5400 return $.effects.animateClass.call( this, 5401 ( force ? { add: classNames } : { remove: classNames } ), 5402 speed, easing, callback ); 5403 } 5404 } else { 5405 5406 // Without force parameter 5407 return $.effects.animateClass.call( this, 5408 { toggle: classNames }, force, speed, easing ); 5409 } 5410 }; 5411 } )( $.fn.toggleClass ), 5412 5413 switchClass: function( remove, add, speed, easing, callback ) { 5414 return $.effects.animateClass.call( this, { 5415 add: add, 5416 remove: remove 5417 }, speed, easing, callback ); 5418 } 5419} ); 5420 5421} )(); 5422 5423/******************************************************************************/ 5424/*********************************** EFFECTS **********************************/ 5425/******************************************************************************/ 5426 5427( function() { 5428 5429if ( $.expr && $.expr.filters && $.expr.filters.animated ) { 5430 $.expr.filters.animated = ( function( orig ) { 5431 return function( elem ) { 5432 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 5433 }; 5434 } )( $.expr.filters.animated ); 5435} 5436 5437if ( $.uiBackCompat !== false ) { 5438 $.extend( $.effects, { 5439 5440 // Saves a set of properties in a data storage 5441 save: function( element, set ) { 5442 var i = 0, length = set.length; 5443 for ( ; i < length; i++ ) { 5444 if ( set[ i ] !== null ) { 5445 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5446 } 5447 } 5448 }, 5449 5450 // Restores a set of previously saved properties from a data storage 5451 restore: function( element, set ) { 5452 var val, i = 0, length = set.length; 5453 for ( ; i < length; i++ ) { 5454 if ( set[ i ] !== null ) { 5455 val = element.data( dataSpace + set[ i ] ); 5456 element.css( set[ i ], val ); 5457 } 5458 } 5459 }, 5460 5461 setMode: function( el, mode ) { 5462 if ( mode === "toggle" ) { 5463 mode = el.is( ":hidden" ) ? "show" : "hide"; 5464 } 5465 return mode; 5466 }, 5467 5468 // Wraps the element around a wrapper that copies position properties 5469 createWrapper: function( element ) { 5470 5471 // If the element is already wrapped, return it 5472 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5473 return element.parent(); 5474 } 5475 5476 // Wrap the element 5477 var props = { 5478 width: element.outerWidth( true ), 5479 height: element.outerHeight( true ), 5480 "float": element.css( "float" ) 5481 }, 5482 wrapper = $( "<div></div>" ) 5483 .addClass( "ui-effects-wrapper" ) 5484 .css( { 5485 fontSize: "100%", 5486 background: "transparent", 5487 border: "none", 5488 margin: 0, 5489 padding: 0 5490 } ), 5491 5492 // Store the size in case width/height are defined in % - Fixes #5245 5493 size = { 5494 width: element.width(), 5495 height: element.height() 5496 }, 5497 active = document.activeElement; 5498 5499 // Support: Firefox 5500 // Firefox incorrectly exposes anonymous content 5501 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5502 try { 5503 active.id; 5504 } catch ( e ) { 5505 active = document.body; 5506 } 5507 5508 element.wrap( wrapper ); 5509 5510 // Fixes #7595 - Elements lose focus when wrapped. 5511 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5512 $( active ).trigger( "focus" ); 5513 } 5514 5515 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 5516 // lose the reference to the wrapped element 5517 wrapper = element.parent(); 5518 5519 // Transfer positioning properties to the wrapper 5520 if ( element.css( "position" ) === "static" ) { 5521 wrapper.css( { position: "relative" } ); 5522 element.css( { position: "relative" } ); 5523 } else { 5524 $.extend( props, { 5525 position: element.css( "position" ), 5526 zIndex: element.css( "z-index" ) 5527 } ); 5528 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 5529 props[ pos ] = element.css( pos ); 5530 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5531 props[ pos ] = "auto"; 5532 } 5533 } ); 5534 element.css( { 5535 position: "relative", 5536 top: 0, 5537 left: 0, 5538 right: "auto", 5539 bottom: "auto" 5540 } ); 5541 } 5542 element.css( size ); 5543 5544 return wrapper.css( props ).show(); 5545 }, 5546 5547 removeWrapper: function( element ) { 5548 var active = document.activeElement; 5549 5550 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5551 element.parent().replaceWith( element ); 5552 5553 // Fixes #7595 - Elements lose focus when wrapped. 5554 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5555 $( active ).trigger( "focus" ); 5556 } 5557 } 5558 5559 return element; 5560 } 5561 } ); 5562} 5563 5564$.extend( $.effects, { 5565 version: "1.12.1", 5566 5567 define: function( name, mode, effect ) { 5568 if ( !effect ) { 5569 effect = mode; 5570 mode = "effect"; 5571 } 5572 5573 $.effects.effect[ name ] = effect; 5574 $.effects.effect[ name ].mode = mode; 5575 5576 return effect; 5577 }, 5578 5579 scaledDimensions: function( element, percent, direction ) { 5580 if ( percent === 0 ) { 5581 return { 5582 height: 0, 5583 width: 0, 5584 outerHeight: 0, 5585 outerWidth: 0 5586 }; 5587 } 5588 5589 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 5590 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 5591 5592 return { 5593 height: element.height() * y, 5594 width: element.width() * x, 5595 outerHeight: element.outerHeight() * y, 5596 outerWidth: element.outerWidth() * x 5597 }; 5598 5599 }, 5600 5601 clipToBox: function( animation ) { 5602 return { 5603 width: animation.clip.right - animation.clip.left, 5604 height: animation.clip.bottom - animation.clip.top, 5605 left: animation.clip.left, 5606 top: animation.clip.top 5607 }; 5608 }, 5609 5610 // Injects recently queued functions to be first in line (after "inprogress") 5611 unshift: function( element, queueLength, count ) { 5612 var queue = element.queue(); 5613 5614 if ( queueLength > 1 ) { 5615 queue.splice.apply( queue, 5616 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 5617 } 5618 element.dequeue(); 5619 }, 5620 5621 saveStyle: function( element ) { 5622 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 5623 }, 5624 5625 restoreStyle: function( element ) { 5626 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 5627 element.removeData( dataSpaceStyle ); 5628 }, 5629 5630 mode: function( element, mode ) { 5631 var hidden = element.is( ":hidden" ); 5632 5633 if ( mode === "toggle" ) { 5634 mode = hidden ? "show" : "hide"; 5635 } 5636 if ( hidden ? mode === "hide" : mode === "show" ) { 5637 mode = "none"; 5638 } 5639 return mode; 5640 }, 5641 5642 // Translates a [top,left] array into a baseline value 5643 getBaseline: function( origin, original ) { 5644 var y, x; 5645 5646 switch ( origin[ 0 ] ) { 5647 case "top": 5648 y = 0; 5649 break; 5650 case "middle": 5651 y = 0.5; 5652 break; 5653 case "bottom": 5654 y = 1; 5655 break; 5656 default: 5657 y = origin[ 0 ] / original.height; 5658 } 5659 5660 switch ( origin[ 1 ] ) { 5661 case "left": 5662 x = 0; 5663 break; 5664 case "center": 5665 x = 0.5; 5666 break; 5667 case "right": 5668 x = 1; 5669 break; 5670 default: 5671 x = origin[ 1 ] / original.width; 5672 } 5673 5674 return { 5675 x: x, 5676 y: y 5677 }; 5678 }, 5679 5680 // Creates a placeholder element so that the original element can be made absolute 5681 createPlaceholder: function( element ) { 5682 var placeholder, 5683 cssPosition = element.css( "position" ), 5684 position = element.position(); 5685 5686 // Lock in margins first to account for form elements, which 5687 // will change margin if you explicitly set height 5688 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 5689 // Support: Safari 5690 element.css( { 5691 marginTop: element.css( "marginTop" ), 5692 marginBottom: element.css( "marginBottom" ), 5693 marginLeft: element.css( "marginLeft" ), 5694 marginRight: element.css( "marginRight" ) 5695 } ) 5696 .outerWidth( element.outerWidth() ) 5697 .outerHeight( element.outerHeight() ); 5698 5699 if ( /^(static|relative)/.test( cssPosition ) ) { 5700 cssPosition = "absolute"; 5701 5702 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 5703 5704 // Convert inline to inline block to account for inline elements 5705 // that turn to inline block based on content (like img) 5706 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 5707 "inline-block" : 5708 "block", 5709 visibility: "hidden", 5710 5711 // Margins need to be set to account for margin collapse 5712 marginTop: element.css( "marginTop" ), 5713 marginBottom: element.css( "marginBottom" ), 5714 marginLeft: element.css( "marginLeft" ), 5715 marginRight: element.css( "marginRight" ), 5716 "float": element.css( "float" ) 5717 } ) 5718 .outerWidth( element.outerWidth() ) 5719 .outerHeight( element.outerHeight() ) 5720 .addClass( "ui-effects-placeholder" ); 5721 5722 element.data( dataSpace + "placeholder", placeholder ); 5723 } 5724 5725 element.css( { 5726 position: cssPosition, 5727 left: position.left, 5728 top: position.top 5729 } ); 5730 5731 return placeholder; 5732 }, 5733 5734 removePlaceholder: function( element ) { 5735 var dataKey = dataSpace + "placeholder", 5736 placeholder = element.data( dataKey ); 5737 5738 if ( placeholder ) { 5739 placeholder.remove(); 5740 element.removeData( dataKey ); 5741 } 5742 }, 5743 5744 // Removes a placeholder if it exists and restores 5745 // properties that were modified during placeholder creation 5746 cleanUp: function( element ) { 5747 $.effects.restoreStyle( element ); 5748 $.effects.removePlaceholder( element ); 5749 }, 5750 5751 setTransition: function( element, list, factor, value ) { 5752 value = value || {}; 5753 $.each( list, function( i, x ) { 5754 var unit = element.cssUnit( x ); 5755 if ( unit[ 0 ] > 0 ) { 5756 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5757 } 5758 } ); 5759 return value; 5760 } 5761} ); 5762 5763// Return an effect options object for the given parameters: 5764function _normalizeArguments( effect, options, speed, callback ) { 5765 5766 // Allow passing all options as the first parameter 5767 if ( $.isPlainObject( effect ) ) { 5768 options = effect; 5769 effect = effect.effect; 5770 } 5771 5772 // Convert to an object 5773 effect = { effect: effect }; 5774 5775 // Catch (effect, null, ...) 5776 if ( options == null ) { 5777 options = {}; 5778 } 5779 5780 // Catch (effect, callback) 5781 if ( $.isFunction( options ) ) { 5782 callback = options; 5783 speed = null; 5784 options = {}; 5785 } 5786 5787 // Catch (effect, speed, ?) 5788 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5789 callback = speed; 5790 speed = options; 5791 options = {}; 5792 } 5793 5794 // Catch (effect, options, callback) 5795 if ( $.isFunction( speed ) ) { 5796 callback = speed; 5797 speed = null; 5798 } 5799 5800 // Add options to effect 5801 if ( options ) { 5802 $.extend( effect, options ); 5803 } 5804 5805 speed = speed || options.duration; 5806 effect.duration = $.fx.off ? 0 : 5807 typeof speed === "number" ? speed : 5808 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5809 $.fx.speeds._default; 5810 5811 effect.complete = callback || options.complete; 5812 5813 return effect; 5814} 5815 5816function standardAnimationOption( option ) { 5817 5818 // Valid standard speeds (nothing, number, named speed) 5819 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 5820 return true; 5821 } 5822 5823 // Invalid strings - treat as "normal" speed 5824 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 5825 return true; 5826 } 5827 5828 // Complete callback 5829 if ( $.isFunction( option ) ) { 5830 return true; 5831 } 5832 5833 // Options hash (but not naming an effect) 5834 if ( typeof option === "object" && !option.effect ) { 5835 return true; 5836 } 5837 5838 // Didn't match any standard API 5839 return false; 5840} 5841 5842$.fn.extend( { 5843 effect: function( /* effect, options, speed, callback */ ) { 5844 var args = _normalizeArguments.apply( this, arguments ), 5845 effectMethod = $.effects.effect[ args.effect ], 5846 defaultMode = effectMethod.mode, 5847 queue = args.queue, 5848 queueName = queue || "fx", 5849 complete = args.complete, 5850 mode = args.mode, 5851 modes = [], 5852 prefilter = function( next ) { 5853 var el = $( this ), 5854 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 5855 5856 // Sentinel for duck-punching the :animated psuedo-selector 5857 el.data( dataSpaceAnimated, true ); 5858 5859 // Save effect mode for later use, 5860 // we can't just call $.effects.mode again later, 5861 // as the .show() below destroys the initial state 5862 modes.push( normalizedMode ); 5863 5864 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13 5865 if ( defaultMode && ( normalizedMode === "show" || 5866 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 5867 el.show(); 5868 } 5869 5870 if ( !defaultMode || normalizedMode !== "none" ) { 5871 $.effects.saveStyle( el ); 5872 } 5873 5874 if ( $.isFunction( next ) ) { 5875 next(); 5876 } 5877 }; 5878 5879 if ( $.fx.off || !effectMethod ) { 5880 5881 // Delegate to the original method (e.g., .show()) if possible 5882 if ( mode ) { 5883 return this[ mode ]( args.duration, complete ); 5884 } else { 5885 return this.each( function() { 5886 if ( complete ) { 5887 complete.call( this ); 5888 } 5889 } ); 5890 } 5891 } 5892 5893 function run( next ) { 5894 var elem = $( this ); 5895 5896 function cleanup() { 5897 elem.removeData( dataSpaceAnimated ); 5898 5899 $.effects.cleanUp( elem ); 5900 5901 if ( args.mode === "hide" ) { 5902 elem.hide(); 5903 } 5904 5905 done(); 5906 } 5907 5908 function done() { 5909 if ( $.isFunction( complete ) ) { 5910 complete.call( elem[ 0 ] ); 5911 } 5912 5913 if ( $.isFunction( next ) ) { 5914 next(); 5915 } 5916 } 5917 5918 // Override mode option on a per element basis, 5919 // as toggle can be either show or hide depending on element state 5920 args.mode = modes.shift(); 5921 5922 if ( $.uiBackCompat !== false && !defaultMode ) { 5923 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5924 5925 // Call the core method to track "olddisplay" properly 5926 elem[ mode ](); 5927 done(); 5928 } else { 5929 effectMethod.call( elem[ 0 ], args, done ); 5930 } 5931 } else { 5932 if ( args.mode === "none" ) { 5933 5934 // Call the core method to track "olddisplay" properly 5935 elem[ mode ](); 5936 done(); 5937 } else { 5938 effectMethod.call( elem[ 0 ], args, cleanup ); 5939 } 5940 } 5941 } 5942 5943 // Run prefilter on all elements first to ensure that 5944 // any showing or hiding happens before placeholder creation, 5945 // which ensures that any layout changes are correctly captured. 5946 return queue === false ? 5947 this.each( prefilter ).each( run ) : 5948 this.queue( queueName, prefilter ).queue( queueName, run ); 5949 }, 5950 5951 show: ( function( orig ) { 5952 return function( option ) { 5953 if ( standardAnimationOption( option ) ) { 5954 return orig.apply( this, arguments ); 5955 } else { 5956 var args = _normalizeArguments.apply( this, arguments ); 5957 args.mode = "show"; 5958 return this.effect.call( this, args ); 5959 } 5960 }; 5961 } )( $.fn.show ), 5962 5963 hide: ( function( orig ) { 5964 return function( option ) { 5965 if ( standardAnimationOption( option ) ) { 5966 return orig.apply( this, arguments ); 5967 } else { 5968 var args = _normalizeArguments.apply( this, arguments ); 5969 args.mode = "hide"; 5970 return this.effect.call( this, args ); 5971 } 5972 }; 5973 } )( $.fn.hide ), 5974 5975 toggle: ( function( orig ) { 5976 return function( option ) { 5977 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 5978 return orig.apply( this, arguments ); 5979 } else { 5980 var args = _normalizeArguments.apply( this, arguments ); 5981 args.mode = "toggle"; 5982 return this.effect.call( this, args ); 5983 } 5984 }; 5985 } )( $.fn.toggle ), 5986 5987 cssUnit: function( key ) { 5988 var style = this.css( key ), 5989 val = []; 5990 5991 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5992 if ( style.indexOf( unit ) > 0 ) { 5993 val = [ parseFloat( style ), unit ]; 5994 } 5995 } ); 5996 return val; 5997 }, 5998 5999 cssClip: function( clipObj ) { 6000 if ( clipObj ) { 6001 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 6002 clipObj.bottom + "px " + clipObj.left + "px)" ); 6003 } 6004 return parseClip( this.css( "clip" ), this ); 6005 }, 6006 6007 transfer: function( options, done ) { 6008 var element = $( this ), 6009 target = $( options.to ), 6010 targetFixed = target.css( "position" ) === "fixed", 6011 body = $( "body" ), 6012 fixTop = targetFixed ? body.scrollTop() : 0, 6013 fixLeft = targetFixed ? body.scrollLeft() : 0, 6014 endPosition = target.offset(), 6015 animation = { 6016 top: endPosition.top - fixTop, 6017 left: endPosition.left - fixLeft, 6018 height: target.innerHeight(), 6019 width: target.innerWidth() 6020 }, 6021 startPosition = element.offset(), 6022 transfer = $( "<div class='ui-effects-transfer'></div>" ) 6023 .appendTo( "body" ) 6024 .addClass( options.className ) 6025 .css( { 6026 top: startPosition.top - fixTop, 6027 left: startPosition.left - fixLeft, 6028 height: element.innerHeight(), 6029 width: element.innerWidth(), 6030 position: targetFixed ? "fixed" : "absolute" 6031 } ) 6032 .animate( animation, options.duration, options.easing, function() { 6033 transfer.remove(); 6034 if ( $.isFunction( done ) ) { 6035 done(); 6036 } 6037 } ); 6038 } 6039} ); 6040 6041function parseClip( str, element ) { 6042 var outerWidth = element.outerWidth(), 6043 outerHeight = element.outerHeight(), 6044 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)\)$/, 6045 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 6046 6047 return { 6048 top: parseFloat( values[ 1 ] ) || 0, 6049 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 6050 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 6051 left: parseFloat( values[ 4 ] ) || 0 6052 }; 6053} 6054 6055$.fx.step.clip = function( fx ) { 6056 if ( !fx.clipInit ) { 6057 fx.start = $( fx.elem ).cssClip(); 6058 if ( typeof fx.end === "string" ) { 6059 fx.end = parseClip( fx.end, fx.elem ); 6060 } 6061 fx.clipInit = true; 6062 } 6063 6064 $( fx.elem ).cssClip( { 6065 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 6066 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 6067 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 6068 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 6069 } ); 6070}; 6071 6072} )(); 6073 6074/******************************************************************************/ 6075/*********************************** EASING ***********************************/ 6076/******************************************************************************/ 6077 6078( function() { 6079 6080// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 6081 6082var baseEasings = {}; 6083 6084$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 6085 baseEasings[ name ] = function( p ) { 6086 return Math.pow( p, i + 2 ); 6087 }; 6088} ); 6089 6090$.extend( baseEasings, { 6091 Sine: function( p ) { 6092 return 1 - Math.cos( p * Math.PI / 2 ); 6093 }, 6094 Circ: function( p ) { 6095 return 1 - Math.sqrt( 1 - p * p ); 6096 }, 6097 Elastic: function( p ) { 6098 return p === 0 || p === 1 ? p : 6099 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 6100 }, 6101 Back: function( p ) { 6102 return p * p * ( 3 * p - 2 ); 6103 }, 6104 Bounce: function( p ) { 6105 var pow2, 6106 bounce = 4; 6107 6108 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 6109 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 6110 } 6111} ); 6112 6113$.each( baseEasings, function( name, easeIn ) { 6114 $.easing[ "easeIn" + name ] = easeIn; 6115 $.easing[ "easeOut" + name ] = function( p ) { 6116 return 1 - easeIn( 1 - p ); 6117 }; 6118 $.easing[ "easeInOut" + name ] = function( p ) { 6119 return p < 0.5 ? 6120 easeIn( p * 2 ) / 2 : 6121 1 - easeIn( p * -2 + 2 ) / 2; 6122 }; 6123} ); 6124 6125} )(); 6126 6127var effect = $.effects; 6128 6129
6130 6131 6132}));
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.