vendor: 11,815 bytes, lines 1-414
1/*! jQuery UI - v1.11.4 - 2015-03-11 2* http://jqueryui.com 3* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js 4* Copyright 2015 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 * jQuery UI Core 1.11.4 19 * http://jqueryui.com 20 * 21 * Copyright jQuery Foundation and other contributors 22 * Released under the MIT license. 23 * http://jquery.org/license 24 * 25 * http://api.jqueryui.com/category/ui-core/ 26 */ 27 28 29// $.ui might exist from components with no dependencies, e.g., $.ui.position 30$.ui = $.ui || {}; 31 32$.extend( $.ui, { 33 version: "1.11.4", 34 35 keyCode: { 36 BACKSPACE: 8, 37 COMMA: 188, 38 DELETE: 46, 39 DOWN: 40, 40 END: 35, 41 ENTER: 13, 42 ESCAPE: 27, 43 HOME: 36, 44 LEFT: 37, 45 PAGE_DOWN: 34, 46 PAGE_UP: 33, 47 PERIOD: 190, 48 RIGHT: 39, 49 SPACE: 32, 50 TAB: 9, 51 UP: 38 52 } 53}); 54 55// plugins 56$.fn.extend({ 57 scrollParent: function( includeHidden ) { 58 var position = this.css( "position" ), 59 excludeStaticParent = position === "absolute", 60 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 61 scrollParent = this.parents().filter( function() { 62 var parent = $( this ); 63 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 64 return false; 65 } 66 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); 67 }).eq( 0 ); 68 69 return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; 70 }, 71 72 uniqueId: (function() { 73 var uuid = 0; 74 75 return function() { 76 return this.each(function() { 77 if ( !this.id ) { 78 this.id = "ui-id-" + ( ++uuid ); 79 } 80 }); 81 }; 82 })(), 83 84 removeUniqueId: function() { 85 return this.each(function() { 86 if ( /^ui-id-\d+$/.test( this.id ) ) { 87 $( this ).removeAttr( "id" ); 88 } 89 }); 90 } 91}); 92 93// selectors 94function focusable( element, isTabIndexNotNaN ) { 95 var map, mapName, img, 96 nodeName = element.nodeName.toLowerCase(); 97 if ( "area" === nodeName ) { 98 map = element.parentNode; 99 mapName = map.name; 100 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 101 return false; 102 } 103 img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; 104 return !!img && visible( img ); 105 } 106 return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ? 107 !element.disabled : 108 "a" === nodeName ? 109 element.href || isTabIndexNotNaN : 110 isTabIndexNotNaN) && 111 // the element and all of its ancestors must be visible 112 visible( element ); 113} 114 115function visible( element ) { 116 return $.expr.filters.visible( element ) && 117 !$( element ).parents().addBack().filter(function() { 118 return $.css( this, "visibility" ) === "hidden"; 119 }).length; 120} 121 122$.extend( $.expr[ ":" ], { 123 data: $.expr.createPseudo ? 124 $.expr.createPseudo(function( dataName ) { 125 return function( elem ) { 126 return !!$.data( elem, dataName ); 127 }; 128 }) : 129 // support: jQuery <1.8 130 function( elem, i, match ) { 131 return !!$.data( elem, match[ 3 ] ); 132 }, 133 134 focusable: function( element ) { 135 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 136 }, 137 138 tabbable: function( element ) { 139 var tabIndex = $.attr( element, "tabindex" ), 140 isTabIndexNaN = isNaN( tabIndex ); 141 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 142 } 143}); 144 145// support: jQuery <1.8 146if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 147 $.each( [ "Width", "Height" ], function( i, name ) { 148 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 149 type = name.toLowerCase(), 150 orig = { 151 innerWidth: $.fn.innerWidth, 152 innerHeight: $.fn.innerHeight, 153 outerWidth: $.fn.outerWidth, 154 outerHeight: $.fn.outerHeight 155 }; 156 157 function reduce( elem, size, border, margin ) { 158 $.each( side, function() { 159 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 160 if ( border ) { 161 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 162 } 163 if ( margin ) { 164 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 165 } 166 }); 167 return size; 168 } 169 170 $.fn[ "inner" + name ] = function( size ) { 171 if ( size === undefined ) { 172 return orig[ "inner" + name ].call( this ); 173 } 174 175 return this.each(function() { 176 $( this ).css( type, reduce( this, size ) + "px" ); 177 }); 178 }; 179 180 $.fn[ "outer" + name] = function( size, margin ) { 181 if ( typeof size !== "number" ) { 182 return orig[ "outer" + name ].call( this, size ); 183 } 184 185 return this.each(function() { 186 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 187 }); 188 }; 189 }); 190} 191 192// support: jQuery <1.8 193if ( !$.fn.addBack ) { 194 $.fn.addBack = function( selector ) { 195 return this.add( selector == null ? 196 this.prevObject : this.prevObject.filter( selector ) 197 ); 198 }; 199} 200 201// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 202if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 203 $.fn.removeData = (function( removeData ) { 204 return function( key ) { 205 if ( arguments.length ) { 206 return removeData.call( this, $.camelCase( key ) ); 207 } else { 208 return removeData.call( this ); 209 } 210 }; 211 })( $.fn.removeData ); 212} 213 214// deprecated 215$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 216 217$.fn.extend({ 218 focus: (function( orig ) { 219 return function( delay, fn ) { 220 return typeof delay === "number" ? 221 this.each(function() { 222 var elem = this; 223 setTimeout(function() { 224 $( elem ).focus(); 225 if ( fn ) { 226 fn.call( elem ); 227 } 228 }, delay ); 229 }) : 230 orig.apply( this, arguments ); 231 }; 232 })( $.fn.focus ), 233 234 disableSelection: (function() { 235 var eventType = "onselectstart" in document.createElement( "div" ) ? 236 "selectstart" : 237 "mousedown"; 238 239 return function() { 240 return this.bind( eventType + ".ui-disableSelection", function( event ) { 241 event.preventDefault(); 242 }); 243 }; 244 })(), 245 246 enableSelection: function() { 247 return this.unbind( ".ui-disableSelection" ); 248 }, 249 250 zIndex: function( zIndex ) { 251 if ( zIndex !== undefined ) { 252 return this.css( "zIndex", zIndex ); 253 } 254 255 if ( this.length ) { 256 var elem = $( this[ 0 ] ), position, value; 257 while ( elem.length && elem[ 0 ] !== document ) { 258 // Ignore z-index if position is set to a value where z-index is ignored by the browser 259 // This makes behavior of this function consistent across browsers 260 // WebKit always returns auto if the element is positioned 261 position = elem.css( "position" ); 262 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 263 // IE returns 0 when zIndex is not specified 264 // other browsers return a string 265 // we ignore the case of nested elements with an explicit value of 0 266 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 267 value = parseInt( elem.css( "zIndex" ), 10 ); 268 if ( !isNaN( value ) && value !== 0 ) { 269 return value; 270 } 271 } 272 elem = elem.parent(); 273 } 274 } 275 276 return 0; 277 } 278}); 279 280// $.ui.plugin is deprecated. Use $.widget() extensions instead. 281$.ui.plugin = { 282 add: function( module, option, set ) { 283 var i, 284 proto = $.ui[ module ].prototype; 285 for ( i in set ) { 286 proto.plugins[ i ] = proto.plugins[ i ] || []; 287 proto.plugins[ i ].push( [ option, set[ i ] ] ); 288 } 289 }, 290 call: function( instance, name, args, allowDisconnected ) { 291 var i, 292 set = instance.plugins[ name ]; 293 294 if ( !set ) { 295 return; 296 } 297 298 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 299 return; 300 } 301 302 for ( i = 0; i < set.length; i++ ) { 303 if ( instance.options[ set[ i ][ 0 ] ] ) { 304 set[ i ][ 1 ].apply( instance.element, args ); 305 } 306 } 307 } 308}; 309 310 311/*! 312 * jQuery UI Widget 1.11.4 313 * http://jqueryui.com 314 * 315 * Copyright jQuery Foundation and other contributors 316 * Released under the MIT license. 317 * http://jquery.org/license 318 * 319 * http://api.jqueryui.com/jQuery.widget/ 320 */ 321 322 323var widget_uuid = 0, 324 widget_slice = Array.prototype.slice; 325 326$.cleanData = (function( orig ) { 327 return function( elems ) { 328 var events, elem, i; 329 for ( i = 0; (elem = elems[i]) != null; i++ ) { 330 try { 331 332 // Only trigger remove when necessary to save time 333 events = $._data( elem, "events" ); 334 if ( events && events.remove ) { 335 $( elem ).triggerHandler( "remove" ); 336 } 337 338 // http://bugs.jquery.com/ticket/8235 339 } catch ( e ) {} 340 } 341 orig( elems ); 342 }; 343})( $.cleanData ); 344 345$.widget = function( name, base, prototype ) { 346 var fullName, existingConstructor, constructor, basePrototype, 347 // proxiedPrototype allows the provided prototype to remain unmodified 348 // so that it can be used as a mixin for multiple widgets (#8876) 349 proxiedPrototype = {}, 350 namespace = name.split( "." )[ 0 ]; 351 352 name = name.split( "." )[ 1 ]; 353 fullName = namespace + "-" + name; 354 355 if ( !prototype ) { 356 prototype = base; 357 base = $.Widget; 358 } 359 360 // create selector for plugin 361 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 362 return !!$.data( elem, fullName ); 363 }; 364 365 $[ namespace ] = $[ namespace ] || {}; 366 existingConstructor = $[ namespace ][ name ]; 367 constructor = $[ namespace ][ name ] = function( options, element ) { 368 // allow instantiation without "new" keyword 369 if ( !this._createWidget ) { 370 return new constructor( options, element ); 371 } 372 373 // allow instantiation without initializing for simple inheritance 374 // must use "new" keyword (the code above always passes args) 375 if ( arguments.length ) { 376 this._createWidget( options, element ); 377 } 378 }; 379 // extend with the existing constructor to carry over any static properties 380 $.extend( constructor, existingConstructor, { 381 version: prototype.version, 382 // copy the object used to create the prototype in case we need to 383 // redefine the widget later 384 _proto: $.extend( {}, prototype ), 385 // track widgets that inherit from this widget in case this widget is 386 // redefined after a widget inherits from it 387 _childConstructors: [] 388 }); 389 390 basePrototype = new base(); 391 // we need to make the options hash a property directly on the new instance 392 // otherwise we'll modify the options hash on the prototype that we're 393 // inheriting from 394 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 395 $.each( prototype, function( prop, value ) { 396 if ( !$.isFunction( value ) ) { 397 proxiedPrototype[ prop ] = value; 398 return; 399 } 400 proxiedPrototype[ prop ] = (function() { 401 var _super = function() { 402 return base.prototype[ prop ].apply( this, arguments ); 403 }, 404 _superApply = function( args ) { 405 return base.prototype[ prop ].apply( this, args ); 406 }; 407 return function() { 408 var __super = this._super, 409 __superApply = this._superApply, 410 returnValue; 411 412 this._super = _super; 413 this._superApply = _superApply; 414
vendor: 21,283 bytes, lines 415-1156
415 returnValue = value.apply( this, arguments ); 416 417 this._super = __super; 418 this._superApply = __superApply; 419 420 return returnValue; 421 }; 422 })(); 423 }); 424 constructor.prototype = $.widget.extend( basePrototype, { 425 // TODO: remove support for widgetEventPrefix 426 // always use the name + a colon as the prefix, e.g., draggable:start 427 // don't prefix for widgets that aren't DOM-based 428 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name 429 }, proxiedPrototype, { 430 constructor: constructor, 431 namespace: namespace, 432 widgetName: name, 433 widgetFullName: fullName 434 }); 435 436 // If this widget is being redefined then we need to find all widgets that 437 // are inheriting from it and redefine all of them so that they inherit from 438 // the new version of this widget. We're essentially trying to replace one 439 // level in the prototype chain. 440 if ( existingConstructor ) { 441 $.each( existingConstructor._childConstructors, function( i, child ) { 442 var childPrototype = child.prototype; 443 444 // redefine the child widget using the same prototype that was 445 // originally used, but inherit from the new version of the base 446 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 447 }); 448 // remove the list of existing child constructors from the old constructor 449 // so the old child constructors can be garbage collected 450 delete existingConstructor._childConstructors; 451 } else { 452 base._childConstructors.push( constructor ); 453 } 454 455 $.widget.bridge( name, constructor ); 456 457 return constructor; 458}; 459 460$.widget.extend = function( target ) { 461 var input = widget_slice.call( arguments, 1 ), 462 inputIndex = 0, 463 inputLength = input.length, 464 key, 465 value; 466 for ( ; inputIndex < inputLength; inputIndex++ ) { 467 for ( key in input[ inputIndex ] ) { 468 value = input[ inputIndex ][ key ]; 469 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 470 // Clone objects 471 if ( $.isPlainObject( value ) ) { 472 target[ key ] = $.isPlainObject( target[ key ] ) ? 473 $.widget.extend( {}, target[ key ], value ) : 474 // Don't extend strings, arrays, etc. with objects 475 $.widget.extend( {}, value ); 476 // Copy everything else by reference 477 } else { 478 target[ key ] = value; 479 } 480 } 481 } 482 } 483 return target; 484}; 485 486$.widget.bridge = function( name, object ) { 487 var fullName = object.prototype.widgetFullName || name; 488 $.fn[ name ] = function( options ) { 489 var isMethodCall = typeof options === "string", 490 args = widget_slice.call( arguments, 1 ), 491 returnValue = this; 492 493 if ( isMethodCall ) { 494 this.each(function() { 495 var methodValue, 496 instance = $.data( this, fullName ); 497 if ( options === "instance" ) { 498 returnValue = instance; 499 return false; 500 } 501 if ( !instance ) { 502 return $.error( "cannot call methods on " + name + " prior to initialization; " + 503 "attempted to call method '" + options + "'" ); 504 } 505 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 506 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 507 } 508 methodValue = instance[ options ].apply( instance, args ); 509 if ( methodValue !== instance && methodValue !== undefined ) { 510 returnValue = methodValue && methodValue.jquery ? 511 returnValue.pushStack( methodValue.get() ) : 512 methodValue; 513 return false; 514 } 515 }); 516 } else { 517 518 // Allow multiple hashes to be passed on init 519 if ( args.length ) { 520 options = $.widget.extend.apply( null, [ options ].concat(args) ); 521 } 522 523 this.each(function() { 524 var instance = $.data( this, fullName ); 525 if ( instance ) { 526 instance.option( options || {} ); 527 if ( instance._init ) { 528 instance._init(); 529 } 530 } else { 531 $.data( this, fullName, new object( options, this ) ); 532 } 533 }); 534 } 535 536 return returnValue; 537 }; 538}; 539 540$.Widget = function( /* options, element */ ) {}; 541$.Widget._childConstructors = []; 542 543$.Widget.prototype = { 544 widgetName: "widget", 545 widgetEventPrefix: "", 546 defaultElement: "<div>", 547 options: { 548 disabled: false, 549 550 // callbacks 551 create: null 552 }, 553 _createWidget: function( options, element ) { 554 element = $( element || this.defaultElement || this )[ 0 ]; 555 this.element = $( element ); 556 this.uuid = widget_uuid++; 557 this.eventNamespace = "." + this.widgetName + this.uuid; 558 559 this.bindings = $(); 560 this.hoverable = $(); 561 this.focusable = $(); 562 563 if ( element !== this ) { 564 $.data( element, this.widgetFullName, this ); 565 this._on( true, this.element, { 566 remove: function( event ) { 567 if ( event.target === element ) { 568 this.destroy(); 569 } 570 } 571 }); 572 this.document = $( element.style ? 573 // element within the document 574 element.ownerDocument : 575 // element is window or document 576 element.document || element ); 577 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 578 } 579 580 this.options = $.widget.extend( {}, 581 this.options, 582 this._getCreateOptions(), 583 options ); 584 585 this._create(); 586 this._trigger( "create", null, this._getCreateEventData() ); 587 this._init(); 588 }, 589 _getCreateOptions: $.noop, 590 _getCreateEventData: $.noop, 591 _create: $.noop, 592 _init: $.noop, 593 594 destroy: function() { 595 this._destroy(); 596 // we can probably remove the unbind calls in 2.0 597 // all event bindings should go through this._on() 598 this.element 599 .unbind( this.eventNamespace ) 600 .removeData( this.widgetFullName ) 601 // support: jquery <1.6.3 602 // http://bugs.jquery.com/ticket/9413 603 .removeData( $.camelCase( this.widgetFullName ) ); 604 this.widget() 605 .unbind( this.eventNamespace ) 606 .removeAttr( "aria-disabled" ) 607 .removeClass( 608 this.widgetFullName + "-disabled " + 609 "ui-state-disabled" ); 610 611 // clean up events and states 612 this.bindings.unbind( this.eventNamespace ); 613 this.hoverable.removeClass( "ui-state-hover" ); 614 this.focusable.removeClass( "ui-state-focus" ); 615 }, 616 _destroy: $.noop, 617 618 widget: function() { 619 return this.element; 620 }, 621 622 option: function( key, value ) { 623 var options = key, 624 parts, 625 curOption, 626 i; 627 628 if ( arguments.length === 0 ) { 629 // don't return a reference to the internal hash 630 return $.widget.extend( {}, this.options ); 631 } 632 633 if ( typeof key === "string" ) { 634 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 635 options = {}; 636 parts = key.split( "." ); 637 key = parts.shift(); 638 if ( parts.length ) { 639 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 640 for ( i = 0; i < parts.length - 1; i++ ) { 641 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 642 curOption = curOption[ parts[ i ] ]; 643 } 644 key = parts.pop(); 645 if ( arguments.length === 1 ) { 646 return curOption[ key ] === undefined ? null : curOption[ key ]; 647 } 648 curOption[ key ] = value; 649 } else { 650 if ( arguments.length === 1 ) { 651 return this.options[ key ] === undefined ? null : this.options[ key ]; 652 } 653 options[ key ] = value; 654 } 655 } 656 657 this._setOptions( options ); 658 659 return this; 660 }, 661 _setOptions: function( options ) { 662 var key; 663 664 for ( key in options ) { 665 this._setOption( key, options[ key ] ); 666 } 667 668 return this; 669 }, 670 _setOption: function( key, value ) { 671 this.options[ key ] = value; 672 673 if ( key === "disabled" ) { 674 this.widget() 675 .toggleClass( this.widgetFullName + "-disabled", !!value ); 676 677 // If the widget is becoming disabled, then nothing is interactive 678 if ( value ) { 679 this.hoverable.removeClass( "ui-state-hover" ); 680 this.focusable.removeClass( "ui-state-focus" ); 681 } 682 } 683 684 return this; 685 }, 686 687 enable: function() { 688 return this._setOptions({ disabled: false }); 689 }, 690 disable: function() { 691 return this._setOptions({ disabled: true }); 692 }, 693 694 _on: function( suppressDisabledCheck, element, handlers ) { 695 var delegateElement, 696 instance = this; 697 698 // no suppressDisabledCheck flag, shuffle arguments 699 if ( typeof suppressDisabledCheck !== "boolean" ) { 700 handlers = element; 701 element = suppressDisabledCheck; 702 suppressDisabledCheck = false; 703 } 704 705 // no element argument, shuffle and use this.element 706 if ( !handlers ) { 707 handlers = element; 708 element = this.element; 709 delegateElement = this.widget(); 710 } else { 711 element = delegateElement = $( element ); 712 this.bindings = this.bindings.add( element ); 713 } 714 715 $.each( handlers, function( event, handler ) { 716 function handlerProxy() { 717 // allow widgets to customize the disabled handling 718 // - disabled as an array instead of boolean 719 // - disabled class as method for disabling individual parts 720 if ( !suppressDisabledCheck && 721 ( instance.options.disabled === true || 722 $( this ).hasClass( "ui-state-disabled" ) ) ) { 723 return; 724 } 725 return ( typeof handler === "string" ? instance[ handler ] : handler ) 726 .apply( instance, arguments ); 727 } 728 729 // copy the guid so direct unbinding works 730 if ( typeof handler !== "string" ) { 731 handlerProxy.guid = handler.guid = 732 handler.guid || handlerProxy.guid || $.guid++; 733 } 734 735 var match = event.match( /^([\w:-]*)\s*(.*)$/ ), 736 eventName = match[1] + instance.eventNamespace, 737 selector = match[2]; 738 if ( selector ) { 739 delegateElement.delegate( selector, eventName, handlerProxy ); 740 } else { 741 element.bind( eventName, handlerProxy ); 742 } 743 }); 744 }, 745 746 _off: function( element, eventName ) { 747 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + 748 this.eventNamespace; 749 element.unbind( eventName ).undelegate( eventName ); 750 751 // Clear the stack to avoid memory leaks (#10056) 752 this.bindings = $( this.bindings.not( element ).get() ); 753 this.focusable = $( this.focusable.not( element ).get() ); 754 this.hoverable = $( this.hoverable.not( element ).get() ); 755 }, 756 757 _delay: function( handler, delay ) { 758 function handlerProxy() { 759 return ( typeof handler === "string" ? instance[ handler ] : handler ) 760 .apply( instance, arguments ); 761 } 762 var instance = this; 763 return setTimeout( handlerProxy, delay || 0 ); 764 }, 765 766 _hoverable: function( element ) { 767 this.hoverable = this.hoverable.add( element ); 768 this._on( element, { 769 mouseenter: function( event ) { 770 $( event.currentTarget ).addClass( "ui-state-hover" ); 771 }, 772 mouseleave: function( event ) { 773 $( event.currentTarget ).removeClass( "ui-state-hover" ); 774 } 775 }); 776 }, 777 778 _focusable: function( element ) { 779 this.focusable = this.focusable.add( element ); 780 this._on( element, { 781 focusin: function( event ) { 782 $( event.currentTarget ).addClass( "ui-state-focus" ); 783 }, 784 focusout: function( event ) { 785 $( event.currentTarget ).removeClass( "ui-state-focus" ); 786 } 787 }); 788 }, 789 790 _trigger: function( type, event, data ) { 791 var prop, orig, 792 callback = this.options[ type ]; 793 794 data = data || {}; 795 event = $.Event( event ); 796 event.type = ( type === this.widgetEventPrefix ? 797 type : 798 this.widgetEventPrefix + type ).toLowerCase(); 799 // the original event may come from any element 800 // so we need to reset the target on the new event 801 event.target = this.element[ 0 ]; 802 803 // copy original event properties over to the new event 804 orig = event.originalEvent; 805 if ( orig ) { 806 for ( prop in orig ) { 807 if ( !( prop in event ) ) { 808 event[ prop ] = orig[ prop ]; 809 } 810 } 811 } 812 813 this.element.trigger( event, data ); 814 return !( $.isFunction( callback ) && 815 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 816 event.isDefaultPrevented() ); 817 } 818}; 819 820$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 821 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 822 if ( typeof options === "string" ) { 823 options = { effect: options }; 824 } 825 var hasOptions, 826 effectName = !options ? 827 method : 828 options === true || typeof options === "number" ? 829 defaultEffect : 830 options.effect || defaultEffect; 831 options = options || {}; 832 if ( typeof options === "number" ) { 833 options = { duration: options }; 834 } 835 hasOptions = !$.isEmptyObject( options ); 836 options.complete = callback; 837 if ( options.delay ) { 838 element.delay( options.delay ); 839 } 840 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 841 element[ method ]( options ); 842 } else if ( effectName !== method && element[ effectName ] ) { 843 element[ effectName ]( options.duration, options.easing, callback ); 844 } else { 845 element.queue(function( next ) { 846 $( this )[ method ](); 847 if ( callback ) { 848 callback.call( element[ 0 ] ); 849 } 850 next(); 851 }); 852 } 853 }; 854}); 855 856var widget = $.widget; 857 858 859/*! 860 * jQuery UI Mouse 1.11.4 861 * http://jqueryui.com 862 * 863 * Copyright jQuery Foundation and other contributors 864 * Released under the MIT license. 865 * http://jquery.org/license 866 * 867 * http://api.jqueryui.com/mouse/ 868 */ 869 870 871var mouseHandled = false; 872$( document ).mouseup( function() { 873 mouseHandled = false; 874}); 875 876var mouse = $.widget("ui.mouse", { 877 version: "1.11.4", 878 options: { 879 cancel: "input,textarea,button,select,option", 880 distance: 1, 881 delay: 0 882 }, 883 _mouseInit: function() { 884 var that = this; 885 886 this.element 887 .bind("mousedown." + this.widgetName, function(event) { 888 return that._mouseDown(event); 889 }) 890 .bind("click." + this.widgetName, function(event) { 891 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 892 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 893 event.stopImmediatePropagation(); 894 return false; 895 } 896 }); 897 898 this.started = false; 899 }, 900 901 // TODO: make sure destroying one instance of mouse doesn't mess with 902 // other instances of mouse 903 _mouseDestroy: function() { 904 this.element.unbind("." + this.widgetName); 905 if ( this._mouseMoveDelegate ) { 906 this.document 907 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) 908 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); 909 } 910 }, 911 912 _mouseDown: function(event) { 913 // don't let more than one widget handle mouseStart 914 if ( mouseHandled ) { 915 return; 916 } 917 918 this._mouseMoved = false; 919 920 // we may have missed mouseup (out of window) 921 (this._mouseStarted && this._mouseUp(event)); 922 923 this._mouseDownEvent = event; 924 925 var that = this, 926 btnIsLeft = (event.which === 1), 927 // event.target.nodeName works around a bug in IE 8 with 928 // disabled inputs (#7620) 929 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 930 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 931 return true; 932 } 933 934 this.mouseDelayMet = !this.options.delay; 935 if (!this.mouseDelayMet) { 936 this._mouseDelayTimer = setTimeout(function() { 937 that.mouseDelayMet = true; 938 }, this.options.delay); 939 } 940 941 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 942 this._mouseStarted = (this._mouseStart(event) !== false); 943 if (!this._mouseStarted) { 944 event.preventDefault(); 945 return true; 946 } 947 } 948 949 // Click event may never have fired (Gecko & Opera) 950 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 951 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 952 } 953 954 // these delegates are required to keep context 955 this._mouseMoveDelegate = function(event) { 956 return that._mouseMove(event); 957 }; 958 this._mouseUpDelegate = function(event) { 959 return that._mouseUp(event); 960 }; 961 962 this.document 963 .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 964 .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 965 966 event.preventDefault(); 967 968 mouseHandled = true; 969 return true; 970 }, 971 972 _mouseMove: function(event) { 973 // Only check for mouseups outside the document if you've moved inside the document 974 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 975 // fire a mousemove event if content is placed under the cursor. See #7778 976 // Support: IE <9 977 if ( this._mouseMoved ) { 978 // IE mouseup check - mouseup happened when mouse was out of window 979 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 980 return this._mouseUp(event); 981 982 // Iframe mouseup check - mouseup occurred in another document 983 } else if ( !event.which ) { 984 return this._mouseUp( event ); 985 } 986 } 987 988 if ( event.which || event.button ) { 989 this._mouseMoved = true; 990 } 991 992 if (this._mouseStarted) { 993 this._mouseDrag(event); 994 return event.preventDefault(); 995 } 996 997 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 998 this._mouseStarted = 999 (this._mouseStart(this._mouseDownEvent, event) !== false); 1000 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 1001 } 1002 1003 return !this._mouseStarted; 1004 }, 1005 1006 _mouseUp: function(event) { 1007 this.document 1008 .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1009 .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1010 1011 if (this._mouseStarted) { 1012 this._mouseStarted = false; 1013 1014 if (event.target === this._mouseDownEvent.target) { 1015 $.data(event.target, this.widgetName + ".preventClickEvent", true); 1016 } 1017 1018 this._mouseStop(event); 1019 } 1020 1021 mouseHandled = false; 1022 return false; 1023 }, 1024 1025 _mouseDistanceMet: function(event) { 1026 return (Math.max( 1027 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1028 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1029 ) >= this.options.distance 1030 ); 1031 }, 1032 1033 _mouseDelayMet: function(/* event */) { 1034 return this.mouseDelayMet; 1035 }, 1036 1037 // These are placeholder methods, to be overriden by extending plugin 1038 _mouseStart: function(/* event */) {}, 1039 _mouseDrag: function(/* event */) {}, 1040 _mouseStop: function(/* event */) {}, 1041 _mouseCapture: function(/* event */) { return true; } 1042}); 1043 1044 1045/*! 1046 * jQuery UI Position 1.11.4 1047 * http://jqueryui.com 1048 * 1049 * Copyright jQuery Foundation and other contributors 1050 * Released under the MIT license. 1051 * http://jquery.org/license 1052 * 1053 * http://api.jqueryui.com/position/ 1054 */ 1055 1056(function() { 1057 1058$.ui = $.ui || {}; 1059 1060var cachedScrollbarWidth, supportsOffsetFractions, 1061 max = Math.max, 1062 abs = Math.abs, 1063 round = Math.round, 1064 rhorizontal = /left|center|right/, 1065 rvertical = /top|center|bottom/, 1066 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 1067 rposition = /^\w+/, 1068 rpercent = /%$/, 1069 _position = $.fn.position; 1070 1071function getOffsets( offsets, width, height ) { 1072 return [ 1073 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1074 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1075 ]; 1076} 1077 1078function parseCss( element, property ) { 1079 return parseInt( $.css( element, property ), 10 ) || 0; 1080} 1081 1082function getDimensions( elem ) { 1083 var raw = elem[0]; 1084 if ( raw.nodeType === 9 ) { 1085 return { 1086 width: elem.width(), 1087 height: elem.height(), 1088 offset: { top: 0, left: 0 } 1089 }; 1090 } 1091 if ( $.isWindow( raw ) ) { 1092 return { 1093 width: elem.width(), 1094 height: elem.height(), 1095 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1096 }; 1097 } 1098 if ( raw.preventDefault ) { 1099 return { 1100 width: 0, 1101 height: 0, 1102 offset: { top: raw.pageY, left: raw.pageX } 1103 }; 1104 } 1105 return { 1106 width: elem.outerWidth(), 1107 height: elem.outerHeight(), 1108 offset: elem.offset() 1109 }; 1110} 1111 1112$.position = { 1113 scrollbarWidth: function() { 1114 if ( cachedScrollbarWidth !== undefined ) { 1115 return cachedScrollbarWidth; 1116 } 1117 var w1, w2, 1118 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1119 innerDiv = div.children()[0]; 1120 1121 $( "body" ).append( div ); 1122 w1 = innerDiv.offsetWidth; 1123 div.css( "overflow", "scroll" ); 1124 1125 w2 = innerDiv.offsetWidth; 1126 1127 if ( w1 === w2 ) { 1128 w2 = div[0].clientWidth; 1129 } 1130 1131 div.remove(); 1132 1133 return (cachedScrollbarWidth = w1 - w2); 1134 }, 1135 getScrollInfo: function( within ) { 1136 var overflowX = within.isWindow || within.isDocument ? "" : 1137 within.element.css( "overflow-x" ), 1138 overflowY = within.isWindow || within.isDocument ? "" : 1139 within.element.css( "overflow-y" ), 1140 hasOverflowX = overflowX === "scroll" || 1141 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1142 hasOverflowY = overflowY === "scroll" || 1143 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1144 return { 1145 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1146 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1147 }; 1148 }, 1149 getWithinInfo: function( element ) { 1150 var withinElement = $( element || window ), 1151 isWindow = $.isWindow( withinElement[0] ), 1152 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1153 return { 1154 element: withinElement, 1155 isWindow: isWindow, 1156 isDocument: isDocument,
vendor: 17,721 bytes, lines 1157-1726
1157 offset: withinElement.offset() || { left: 0, top: 0 }, 1158 scrollLeft: withinElement.scrollLeft(), 1159 scrollTop: withinElement.scrollTop(), 1160 1161 // support: jQuery 1.6.x 1162 // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows 1163 width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), 1164 height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() 1165 }; 1166 } 1167}; 1168 1169$.fn.position = function( options ) { 1170 if ( !options || !options.of ) { 1171 return _position.apply( this, arguments ); 1172 } 1173 1174 // make a copy, we don't want to modify arguments 1175 options = $.extend( {}, options ); 1176 1177 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1178 target = $( options.of ), 1179 within = $.position.getWithinInfo( options.within ), 1180 scrollInfo = $.position.getScrollInfo( within ), 1181 collision = ( options.collision || "flip" ).split( " " ), 1182 offsets = {}; 1183 1184 dimensions = getDimensions( target ); 1185 if ( target[0].preventDefault ) { 1186 // force left top to allow flipping 1187 options.at = "left top"; 1188 } 1189 targetWidth = dimensions.width; 1190 targetHeight = dimensions.height; 1191 targetOffset = dimensions.offset; 1192 // clone to reuse original targetOffset later 1193 basePosition = $.extend( {}, targetOffset ); 1194 1195 // force my and at to have valid horizontal and vertical positions 1196 // if a value is missing or invalid, it will be converted to center 1197 $.each( [ "my", "at" ], function() { 1198 var pos = ( options[ this ] || "" ).split( " " ), 1199 horizontalOffset, 1200 verticalOffset; 1201 1202 if ( pos.length === 1) { 1203 pos = rhorizontal.test( pos[ 0 ] ) ? 1204 pos.concat( [ "center" ] ) : 1205 rvertical.test( pos[ 0 ] ) ? 1206 [ "center" ].concat( pos ) : 1207 [ "center", "center" ]; 1208 } 1209 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1210 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1211 1212 // calculate offsets 1213 horizontalOffset = roffset.exec( pos[ 0 ] ); 1214 verticalOffset = roffset.exec( pos[ 1 ] ); 1215 offsets[ this ] = [ 1216 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1217 verticalOffset ? verticalOffset[ 0 ] : 0 1218 ]; 1219 1220 // reduce to just the positions without the offsets 1221 options[ this ] = [ 1222 rposition.exec( pos[ 0 ] )[ 0 ], 1223 rposition.exec( pos[ 1 ] )[ 0 ] 1224 ]; 1225 }); 1226 1227 // normalize collision option 1228 if ( collision.length === 1 ) { 1229 collision[ 1 ] = collision[ 0 ]; 1230 } 1231 1232 if ( options.at[ 0 ] === "right" ) { 1233 basePosition.left += targetWidth; 1234 } else if ( options.at[ 0 ] === "center" ) { 1235 basePosition.left += targetWidth / 2; 1236 } 1237 1238 if ( options.at[ 1 ] === "bottom" ) { 1239 basePosition.top += targetHeight; 1240 } else if ( options.at[ 1 ] === "center" ) { 1241 basePosition.top += targetHeight / 2; 1242 } 1243 1244 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1245 basePosition.left += atOffset[ 0 ]; 1246 basePosition.top += atOffset[ 1 ]; 1247 1248 return this.each(function() { 1249 var collisionPosition, using, 1250 elem = $( this ), 1251 elemWidth = elem.outerWidth(), 1252 elemHeight = elem.outerHeight(), 1253 marginLeft = parseCss( this, "marginLeft" ), 1254 marginTop = parseCss( this, "marginTop" ), 1255 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1256 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1257 position = $.extend( {}, basePosition ), 1258 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1259 1260 if ( options.my[ 0 ] === "right" ) { 1261 position.left -= elemWidth; 1262 } else if ( options.my[ 0 ] === "center" ) { 1263 position.left -= elemWidth / 2; 1264 } 1265 1266 if ( options.my[ 1 ] === "bottom" ) { 1267 position.top -= elemHeight; 1268 } else if ( options.my[ 1 ] === "center" ) { 1269 position.top -= elemHeight / 2; 1270 } 1271 1272 position.left += myOffset[ 0 ]; 1273 position.top += myOffset[ 1 ]; 1274 1275 // if the browser doesn't support fractions, then round for consistent results 1276 if ( !supportsOffsetFractions ) { 1277 position.left = round( position.left ); 1278 position.top = round( position.top ); 1279 } 1280 1281 collisionPosition = { 1282 marginLeft: marginLeft, 1283 marginTop: marginTop 1284 }; 1285 1286 $.each( [ "left", "top" ], function( i, dir ) { 1287 if ( $.ui.position[ collision[ i ] ] ) { 1288 $.ui.position[ collision[ i ] ][ dir ]( position, { 1289 targetWidth: targetWidth, 1290 targetHeight: targetHeight, 1291 elemWidth: elemWidth, 1292 elemHeight: elemHeight, 1293 collisionPosition: collisionPosition, 1294 collisionWidth: collisionWidth, 1295 collisionHeight: collisionHeight, 1296 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1297 my: options.my, 1298 at: options.at, 1299 within: within, 1300 elem: elem 1301 }); 1302 } 1303 }); 1304 1305 if ( options.using ) { 1306 // adds feedback as second argument to using callback, if present 1307 using = function( props ) { 1308 var left = targetOffset.left - position.left, 1309 right = left + targetWidth - elemWidth, 1310 top = targetOffset.top - position.top, 1311 bottom = top + targetHeight - elemHeight, 1312 feedback = { 1313 target: { 1314 element: target, 1315 left: targetOffset.left, 1316 top: targetOffset.top, 1317 width: targetWidth, 1318 height: targetHeight 1319 }, 1320 element: { 1321 element: elem, 1322 left: position.left, 1323 top: position.top, 1324 width: elemWidth, 1325 height: elemHeight 1326 }, 1327 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1328 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1329 }; 1330 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1331 feedback.horizontal = "center"; 1332 } 1333 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1334 feedback.vertical = "middle"; 1335 } 1336 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1337 feedback.important = "horizontal"; 1338 } else { 1339 feedback.important = "vertical"; 1340 } 1341 options.using.call( this, props, feedback ); 1342 }; 1343 } 1344 1345 elem.offset( $.extend( position, { using: using } ) ); 1346 }); 1347}; 1348 1349$.ui.position = { 1350 fit: { 1351 left: function( position, data ) { 1352 var within = data.within, 1353 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1354 outerWidth = within.width, 1355 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1356 overLeft = withinOffset - collisionPosLeft, 1357 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1358 newOverRight; 1359 1360 // element is wider than within 1361 if ( data.collisionWidth > outerWidth ) { 1362 // element is initially over the left side of within 1363 if ( overLeft > 0 && overRight <= 0 ) { 1364 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1365 position.left += overLeft - newOverRight; 1366 // element is initially over right side of within 1367 } else if ( overRight > 0 && overLeft <= 0 ) { 1368 position.left = withinOffset; 1369 // element is initially over both left and right sides of within 1370 } else { 1371 if ( overLeft > overRight ) { 1372 position.left = withinOffset + outerWidth - data.collisionWidth; 1373 } else { 1374 position.left = withinOffset; 1375 } 1376 } 1377 // too far left -> align with left edge 1378 } else if ( overLeft > 0 ) { 1379 position.left += overLeft; 1380 // too far right -> align with right edge 1381 } else if ( overRight > 0 ) { 1382 position.left -= overRight; 1383 // adjust based on position and margin 1384 } else { 1385 position.left = max( position.left - collisionPosLeft, position.left ); 1386 } 1387 }, 1388 top: function( position, data ) { 1389 var within = data.within, 1390 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1391 outerHeight = data.within.height, 1392 collisionPosTop = position.top - data.collisionPosition.marginTop, 1393 overTop = withinOffset - collisionPosTop, 1394 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1395 newOverBottom; 1396 1397 // element is taller than within 1398 if ( data.collisionHeight > outerHeight ) { 1399 // element is initially over the top of within 1400 if ( overTop > 0 && overBottom <= 0 ) { 1401 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1402 position.top += overTop - newOverBottom; 1403 // element is initially over bottom of within 1404 } else if ( overBottom > 0 && overTop <= 0 ) { 1405 position.top = withinOffset; 1406 // element is initially over both top and bottom of within 1407 } else { 1408 if ( overTop > overBottom ) { 1409 position.top = withinOffset + outerHeight - data.collisionHeight; 1410 } else { 1411 position.top = withinOffset; 1412 } 1413 } 1414 // too far up -> align with top 1415 } else if ( overTop > 0 ) { 1416 position.top += overTop; 1417 // too far down -> align with bottom edge 1418 } else if ( overBottom > 0 ) { 1419 position.top -= overBottom; 1420 // adjust based on position and margin 1421 } else { 1422 position.top = max( position.top - collisionPosTop, position.top ); 1423 } 1424 } 1425 }, 1426 flip: { 1427 left: function( position, data ) { 1428 var within = data.within, 1429 withinOffset = within.offset.left + within.scrollLeft, 1430 outerWidth = within.width, 1431 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1432 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1433 overLeft = collisionPosLeft - offsetLeft, 1434 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1435 myOffset = data.my[ 0 ] === "left" ? 1436 -data.elemWidth : 1437 data.my[ 0 ] === "right" ? 1438 data.elemWidth : 1439 0, 1440 atOffset = data.at[ 0 ] === "left" ? 1441 data.targetWidth : 1442 data.at[ 0 ] === "right" ? 1443 -data.targetWidth : 1444 0, 1445 offset = -2 * data.offset[ 0 ], 1446 newOverRight, 1447 newOverLeft; 1448 1449 if ( overLeft < 0 ) { 1450 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1451 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1452 position.left += myOffset + atOffset + offset; 1453 } 1454 } else if ( overRight > 0 ) { 1455 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1456 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1457 position.left += myOffset + atOffset + offset; 1458 } 1459 } 1460 }, 1461 top: function( position, data ) { 1462 var within = data.within, 1463 withinOffset = within.offset.top + within.scrollTop, 1464 outerHeight = within.height, 1465 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1466 collisionPosTop = position.top - data.collisionPosition.marginTop, 1467 overTop = collisionPosTop - offsetTop, 1468 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1469 top = data.my[ 1 ] === "top", 1470 myOffset = top ? 1471 -data.elemHeight : 1472 data.my[ 1 ] === "bottom" ? 1473 data.elemHeight : 1474 0, 1475 atOffset = data.at[ 1 ] === "top" ? 1476 data.targetHeight : 1477 data.at[ 1 ] === "bottom" ? 1478 -data.targetHeight : 1479 0, 1480 offset = -2 * data.offset[ 1 ], 1481 newOverTop, 1482 newOverBottom; 1483 if ( overTop < 0 ) { 1484 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1485 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1486 position.top += myOffset + atOffset + offset; 1487 } 1488 } else if ( overBottom > 0 ) { 1489 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1490 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1491 position.top += myOffset + atOffset + offset; 1492 } 1493 } 1494 } 1495 }, 1496 flipfit: { 1497 left: function() { 1498 $.ui.position.flip.left.apply( this, arguments ); 1499 $.ui.position.fit.left.apply( this, arguments ); 1500 }, 1501 top: function() { 1502 $.ui.position.flip.top.apply( this, arguments ); 1503 $.ui.position.fit.top.apply( this, arguments ); 1504 } 1505 } 1506}; 1507 1508// fraction support test 1509(function() { 1510 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1511 body = document.getElementsByTagName( "body" )[ 0 ], 1512 div = document.createElement( "div" ); 1513 1514 //Create a "fake body" for testing based on method used in jQuery.support 1515 testElement = document.createElement( body ? "div" : "body" ); 1516 testElementStyle = { 1517 visibility: "hidden", 1518 width: 0, 1519 height: 0, 1520 border: 0, 1521 margin: 0, 1522 background: "none" 1523 }; 1524 if ( body ) { 1525 $.extend( testElementStyle, { 1526 position: "absolute", 1527 left: "-1000px", 1528 top: "-1000px" 1529 }); 1530 } 1531 for ( i in testElementStyle ) { 1532 testElement.style[ i ] = testElementStyle[ i ]; 1533 } 1534 testElement.appendChild( div ); 1535 testElementParent = body || document.documentElement; 1536 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1537 1538 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1539 1540 offsetLeft = $( div ).offset().left; 1541 supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; 1542 1543 testElement.innerHTML = ""; 1544 testElementParent.removeChild( testElement ); 1545})(); 1546 1547})(); 1548 1549var position = $.ui.position; 1550 1551 1552/*! 1553 * jQuery UI Accordion 1.11.4 1554 * http://jqueryui.com 1555 * 1556 * Copyright jQuery Foundation and other contributors 1557 * Released under the MIT license. 1558 * http://jquery.org/license 1559 * 1560 * http://api.jqueryui.com/accordion/ 1561 */ 1562 1563 1564var accordion = $.widget( "ui.accordion", { 1565 version: "1.11.4", 1566 options: { 1567 active: 0, 1568 animate: {}, 1569 collapsible: false, 1570 event: "click", 1571 header: "> li > :first-child,> :not(li):even", 1572 heightStyle: "auto", 1573 icons: { 1574 activeHeader: "ui-icon-triangle-1-s", 1575 header: "ui-icon-triangle-1-e" 1576 }, 1577 1578 // callbacks 1579 activate: null, 1580 beforeActivate: null 1581 }, 1582 1583 hideProps: { 1584 borderTopWidth: "hide", 1585 borderBottomWidth: "hide", 1586 paddingTop: "hide", 1587 paddingBottom: "hide", 1588 height: "hide" 1589 }, 1590 1591 showProps: { 1592 borderTopWidth: "show", 1593 borderBottomWidth: "show", 1594 paddingTop: "show", 1595 paddingBottom: "show", 1596 height: "show" 1597 }, 1598 1599 _create: function() { 1600 var options = this.options; 1601 this.prevShow = this.prevHide = $(); 1602 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 1603 // ARIA 1604 .attr( "role", "tablist" ); 1605 1606 // don't allow collapsible: false and active: false / null 1607 if ( !options.collapsible && (options.active === false || options.active == null) ) { 1608 options.active = 0; 1609 } 1610 1611 this._processPanels(); 1612 // handle negative values 1613 if ( options.active < 0 ) { 1614 options.active += this.headers.length; 1615 } 1616 this._refresh(); 1617 }, 1618 1619 _getCreateEventData: function() { 1620 return { 1621 header: this.active, 1622 panel: !this.active.length ? $() : this.active.next() 1623 }; 1624 }, 1625 1626 _createIcons: function() { 1627 var icons = this.options.icons; 1628 if ( icons ) { 1629 $( "<span>" ) 1630 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 1631 .prependTo( this.headers ); 1632 this.active.children( ".ui-accordion-header-icon" ) 1633 .removeClass( icons.header ) 1634 .addClass( icons.activeHeader ); 1635 this.headers.addClass( "ui-accordion-icons" ); 1636 } 1637 }, 1638 1639 _destroyIcons: function() { 1640 this.headers 1641 .removeClass( "ui-accordion-icons" ) 1642 .children( ".ui-accordion-header-icon" ) 1643 .remove(); 1644 }, 1645 1646 _destroy: function() { 1647 var contents; 1648 1649 // clean up main element 1650 this.element 1651 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 1652 .removeAttr( "role" ); 1653 1654 // clean up headers 1655 this.headers 1656 .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + 1657 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 1658 .removeAttr( "role" ) 1659 .removeAttr( "aria-expanded" ) 1660 .removeAttr( "aria-selected" ) 1661 .removeAttr( "aria-controls" ) 1662 .removeAttr( "tabIndex" ) 1663 .removeUniqueId(); 1664 1665 this._destroyIcons(); 1666 1667 // clean up content panels 1668 contents = this.headers.next() 1669 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + 1670 "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 1671 .css( "display", "" ) 1672 .removeAttr( "role" ) 1673 .removeAttr( "aria-hidden" ) 1674 .removeAttr( "aria-labelledby" ) 1675 .removeUniqueId(); 1676 1677 if ( this.options.heightStyle !== "content" ) { 1678 contents.css( "height", "" ); 1679 } 1680 }, 1681 1682 _setOption: function( key, value ) { 1683 if ( key === "active" ) { 1684 // _activate() will handle invalid values and update this.options 1685 this._activate( value ); 1686 return; 1687 } 1688 1689 if ( key === "event" ) { 1690 if ( this.options.event ) { 1691 this._off( this.headers, this.options.event ); 1692 } 1693 this._setupEvents( value ); 1694 } 1695 1696 this._super( key, value ); 1697 1698 // setting collapsible: false while collapsed; open first panel 1699 if ( key === "collapsible" && !value && this.options.active === false ) { 1700 this._activate( 0 ); 1701 } 1702 1703 if ( key === "icons" ) { 1704 this._destroyIcons(); 1705 if ( value ) { 1706 this._createIcons(); 1707 } 1708 } 1709 1710 // #5332 - opacity doesn't cascade to positioned elements in IE 1711 // so we need to add the disabled class to the headers and panels 1712 if ( key === "disabled" ) { 1713 this.element 1714 .toggleClass( "ui-state-disabled", !!value ) 1715 .attr( "aria-disabled", value ); 1716 this.headers.add( this.headers.next() ) 1717 .toggleClass( "ui-state-disabled", !!value ); 1718 } 1719 }, 1720 1721 _keydown: function( event ) { 1722 if ( event.altKey || event.ctrlKey ) { 1723 return; 1724 } 1725 1726 var keyCode = $.ui.keyCode,
vendor: 19,108 bytes, lines 1727-2422
1727 length = this.headers.length, 1728 currentIndex = this.headers.index( event.target ), 1729 toFocus = false; 1730 1731 switch ( event.keyCode ) { 1732 case keyCode.RIGHT: 1733 case keyCode.DOWN: 1734 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 1735 break; 1736 case keyCode.LEFT: 1737 case keyCode.UP: 1738 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 1739 break; 1740 case keyCode.SPACE: 1741 case keyCode.ENTER: 1742 this._eventHandler( event ); 1743 break; 1744 case keyCode.HOME: 1745 toFocus = this.headers[ 0 ]; 1746 break; 1747 case keyCode.END: 1748 toFocus = this.headers[ length - 1 ]; 1749 break; 1750 } 1751 1752 if ( toFocus ) { 1753 $( event.target ).attr( "tabIndex", -1 ); 1754 $( toFocus ).attr( "tabIndex", 0 ); 1755 toFocus.focus(); 1756 event.preventDefault(); 1757 } 1758 }, 1759 1760 _panelKeyDown: function( event ) { 1761 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 1762 $( event.currentTarget ).prev().focus(); 1763 } 1764 }, 1765 1766 refresh: function() { 1767 var options = this.options; 1768 this._processPanels(); 1769 1770 // was collapsed or no panel 1771 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 1772 options.active = false; 1773 this.active = $(); 1774 // active false only when collapsible is true 1775 } else if ( options.active === false ) { 1776 this._activate( 0 ); 1777 // was active, but active panel is gone 1778 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 1779 // all remaining panel are disabled 1780 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 1781 options.active = false; 1782 this.active = $(); 1783 // activate previous panel 1784 } else { 1785 this._activate( Math.max( 0, options.active - 1 ) ); 1786 } 1787 // was active, active panel still exists 1788 } else { 1789 // make sure active index is correct 1790 options.active = this.headers.index( this.active ); 1791 } 1792 1793 this._destroyIcons(); 1794 1795 this._refresh(); 1796 }, 1797 1798 _processPanels: function() { 1799 var prevHeaders = this.headers, 1800 prevPanels = this.panels; 1801 1802 this.headers = this.element.find( this.options.header ) 1803 .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); 1804 1805 this.panels = this.headers.next() 1806 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 1807 .filter( ":not(.ui-accordion-content-active)" ) 1808 .hide(); 1809 1810 // Avoid memory leaks (#10056) 1811 if ( prevPanels ) { 1812 this._off( prevHeaders.not( this.headers ) ); 1813 this._off( prevPanels.not( this.panels ) ); 1814 } 1815 }, 1816 1817 _refresh: function() { 1818 var maxHeight, 1819 options = this.options, 1820 heightStyle = options.heightStyle, 1821 parent = this.element.parent(); 1822 1823 this.active = this._findActive( options.active ) 1824 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 1825 .removeClass( "ui-corner-all" ); 1826 this.active.next() 1827 .addClass( "ui-accordion-content-active" ) 1828 .show(); 1829 1830 this.headers 1831 .attr( "role", "tab" ) 1832 .each(function() { 1833 var header = $( this ), 1834 headerId = header.uniqueId().attr( "id" ), 1835 panel = header.next(), 1836 panelId = panel.uniqueId().attr( "id" ); 1837 header.attr( "aria-controls", panelId ); 1838 panel.attr( "aria-labelledby", headerId ); 1839 }) 1840 .next() 1841 .attr( "role", "tabpanel" ); 1842 1843 this.headers 1844 .not( this.active ) 1845 .attr({ 1846 "aria-selected": "false", 1847 "aria-expanded": "false", 1848 tabIndex: -1 1849 }) 1850 .next() 1851 .attr({ 1852 "aria-hidden": "true" 1853 }) 1854 .hide(); 1855 1856 // make sure at least one header is in the tab order 1857 if ( !this.active.length ) { 1858 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 1859 } else { 1860 this.active.attr({ 1861 "aria-selected": "true", 1862 "aria-expanded": "true", 1863 tabIndex: 0 1864 }) 1865 .next() 1866 .attr({ 1867 "aria-hidden": "false" 1868 }); 1869 } 1870 1871 this._createIcons(); 1872 1873 this._setupEvents( options.event ); 1874 1875 if ( heightStyle === "fill" ) { 1876 maxHeight = parent.height(); 1877 this.element.siblings( ":visible" ).each(function() { 1878 var elem = $( this ), 1879 position = elem.css( "position" ); 1880 1881 if ( position === "absolute" || position === "fixed" ) { 1882 return; 1883 } 1884 maxHeight -= elem.outerHeight( true ); 1885 }); 1886 1887 this.headers.each(function() { 1888 maxHeight -= $( this ).outerHeight( true ); 1889 }); 1890 1891 this.headers.next() 1892 .each(function() { 1893 $( this ).height( Math.max( 0, maxHeight - 1894 $( this ).innerHeight() + $( this ).height() ) ); 1895 }) 1896 .css( "overflow", "auto" ); 1897 } else if ( heightStyle === "auto" ) { 1898 maxHeight = 0; 1899 this.headers.next() 1900 .each(function() { 1901 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 1902 }) 1903 .height( maxHeight ); 1904 } 1905 }, 1906 1907 _activate: function( index ) { 1908 var active = this._findActive( index )[ 0 ]; 1909 1910 // trying to activate the already active panel 1911 if ( active === this.active[ 0 ] ) { 1912 return; 1913 } 1914 1915 // trying to collapse, simulate a click on the currently active header 1916 active = active || this.active[ 0 ]; 1917 1918 this._eventHandler({ 1919 target: active, 1920 currentTarget: active, 1921 preventDefault: $.noop 1922 }); 1923 }, 1924 1925 _findActive: function( selector ) { 1926 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 1927 }, 1928 1929 _setupEvents: function( event ) { 1930 var events = { 1931 keydown: "_keydown" 1932 }; 1933 if ( event ) { 1934 $.each( event.split( " " ), function( index, eventName ) { 1935 events[ eventName ] = "_eventHandler"; 1936 }); 1937 } 1938 1939 this._off( this.headers.add( this.headers.next() ) ); 1940 this._on( this.headers, events ); 1941 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 1942 this._hoverable( this.headers ); 1943 this._focusable( this.headers ); 1944 }, 1945 1946 _eventHandler: function( event ) { 1947 var options = this.options, 1948 active = this.active, 1949 clicked = $( event.currentTarget ), 1950 clickedIsActive = clicked[ 0 ] === active[ 0 ], 1951 collapsing = clickedIsActive && options.collapsible, 1952 toShow = collapsing ? $() : clicked.next(), 1953 toHide = active.next(), 1954 eventData = { 1955 oldHeader: active, 1956 oldPanel: toHide, 1957 newHeader: collapsing ? $() : clicked, 1958 newPanel: toShow 1959 }; 1960 1961 event.preventDefault(); 1962 1963 if ( 1964 // click on active header, but not collapsible 1965 ( clickedIsActive && !options.collapsible ) || 1966 // allow canceling activation 1967 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 1968 return; 1969 } 1970 1971 options.active = collapsing ? false : this.headers.index( clicked ); 1972 1973 // when the call to ._toggle() comes after the class changes 1974 // it causes a very odd bug in IE 8 (see #6720) 1975 this.active = clickedIsActive ? $() : clicked; 1976 this._toggle( eventData ); 1977 1978 // switch classes 1979 // corner classes on the previously active header stay after the animation 1980 active.removeClass( "ui-accordion-header-active ui-state-active" ); 1981 if ( options.icons ) { 1982 active.children( ".ui-accordion-header-icon" ) 1983 .removeClass( options.icons.activeHeader ) 1984 .addClass( options.icons.header ); 1985 } 1986 1987 if ( !clickedIsActive ) { 1988 clicked 1989 .removeClass( "ui-corner-all" ) 1990 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 1991 if ( options.icons ) { 1992 clicked.children( ".ui-accordion-header-icon" ) 1993 .removeClass( options.icons.header ) 1994 .addClass( options.icons.activeHeader ); 1995 } 1996 1997 clicked 1998 .next() 1999 .addClass( "ui-accordion-content-active" ); 2000 } 2001 }, 2002 2003 _toggle: function( data ) { 2004 var toShow = data.newPanel, 2005 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 2006 2007 // handle activating a panel during the animation for another activation 2008 this.prevShow.add( this.prevHide ).stop( true, true ); 2009 this.prevShow = toShow; 2010 this.prevHide = toHide; 2011 2012 if ( this.options.animate ) { 2013 this._animate( toShow, toHide, data ); 2014 } else { 2015 toHide.hide(); 2016 toShow.show(); 2017 this._toggleComplete( data ); 2018 } 2019 2020 toHide.attr({ 2021 "aria-hidden": "true" 2022 }); 2023 toHide.prev().attr({ 2024 "aria-selected": "false", 2025 "aria-expanded": "false" 2026 }); 2027 // if we're switching panels, remove the old header from the tab order 2028 // if we're opening from collapsed state, remove the previous header from the tab order 2029 // if we're collapsing, then keep the collapsing header in the tab order 2030 if ( toShow.length && toHide.length ) { 2031 toHide.prev().attr({ 2032 "tabIndex": -1, 2033 "aria-expanded": "false" 2034 }); 2035 } else if ( toShow.length ) { 2036 this.headers.filter(function() { 2037 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 2038 }) 2039 .attr( "tabIndex", -1 ); 2040 } 2041 2042 toShow 2043 .attr( "aria-hidden", "false" ) 2044 .prev() 2045 .attr({ 2046 "aria-selected": "true", 2047 "aria-expanded": "true", 2048 tabIndex: 0 2049 }); 2050 }, 2051 2052 _animate: function( toShow, toHide, data ) { 2053 var total, easing, duration, 2054 that = this, 2055 adjust = 0, 2056 boxSizing = toShow.css( "box-sizing" ), 2057 down = toShow.length && 2058 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 2059 animate = this.options.animate || {}, 2060 options = down && animate.down || animate, 2061 complete = function() { 2062 that._toggleComplete( data ); 2063 }; 2064 2065 if ( typeof options === "number" ) { 2066 duration = options; 2067 } 2068 if ( typeof options === "string" ) { 2069 easing = options; 2070 } 2071 // fall back from options to animation in case of partial down settings 2072 easing = easing || options.easing || animate.easing; 2073 duration = duration || options.duration || animate.duration; 2074 2075 if ( !toHide.length ) { 2076 return toShow.animate( this.showProps, duration, easing, complete ); 2077 } 2078 if ( !toShow.length ) { 2079 return toHide.animate( this.hideProps, duration, easing, complete ); 2080 } 2081 2082 total = toShow.show().outerHeight(); 2083 toHide.animate( this.hideProps, { 2084 duration: duration, 2085 easing: easing, 2086 step: function( now, fx ) { 2087 fx.now = Math.round( now ); 2088 } 2089 }); 2090 toShow 2091 .hide() 2092 .animate( this.showProps, { 2093 duration: duration, 2094 easing: easing, 2095 complete: complete, 2096 step: function( now, fx ) { 2097 fx.now = Math.round( now ); 2098 if ( fx.prop !== "height" ) { 2099 if ( boxSizing === "content-box" ) { 2100 adjust += fx.now; 2101 } 2102 } else if ( that.options.heightStyle !== "content" ) { 2103 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 2104 adjust = 0; 2105 } 2106 } 2107 }); 2108 }, 2109 2110 _toggleComplete: function( data ) { 2111 var toHide = data.oldPanel; 2112 2113 toHide 2114 .removeClass( "ui-accordion-content-active" ) 2115 .prev() 2116 .removeClass( "ui-corner-top" ) 2117 .addClass( "ui-corner-all" ); 2118 2119 // Work around for rendering bug in IE (#5421) 2120 if ( toHide.length ) { 2121 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 2122 } 2123 this._trigger( "activate", null, data ); 2124 } 2125}); 2126 2127 2128/*! 2129 * jQuery UI Menu 1.11.4 2130 * http://jqueryui.com 2131 * 2132 * Copyright jQuery Foundation and other contributors 2133 * Released under the MIT license. 2134 * http://jquery.org/license 2135 * 2136 * http://api.jqueryui.com/menu/ 2137 */ 2138 2139 2140var menu = $.widget( "ui.menu", { 2141 version: "1.11.4", 2142 defaultElement: "<ul>", 2143 delay: 300, 2144 options: { 2145 icons: { 2146 submenu: "ui-icon-carat-1-e" 2147 }, 2148 items: "> *", 2149 menus: "ul", 2150 position: { 2151 my: "left-1 top", 2152 at: "right top" 2153 }, 2154 role: "menu", 2155 2156 // callbacks 2157 blur: null, 2158 focus: null, 2159 select: null 2160 }, 2161 2162 _create: function() { 2163 this.activeMenu = this.element; 2164 2165 // Flag used to prevent firing of the click handler 2166 // as the event bubbles up through nested menus 2167 this.mouseHandled = false; 2168 this.element 2169 .uniqueId() 2170 .addClass( "ui-menu ui-widget ui-widget-content" ) 2171 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 2172 .attr({ 2173 role: this.options.role, 2174 tabIndex: 0 2175 }); 2176 2177 if ( this.options.disabled ) { 2178 this.element 2179 .addClass( "ui-state-disabled" ) 2180 .attr( "aria-disabled", "true" ); 2181 } 2182 2183 this._on({ 2184 // Prevent focus from sticking to links inside menu after clicking 2185 // them (focus should always stay on UL during navigation). 2186 "mousedown .ui-menu-item": function( event ) { 2187 event.preventDefault(); 2188 }, 2189 "click .ui-menu-item": function( event ) { 2190 var target = $( event.target ); 2191 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 2192 this.select( event ); 2193 2194 // Only set the mouseHandled flag if the event will bubble, see #9469. 2195 if ( !event.isPropagationStopped() ) { 2196 this.mouseHandled = true; 2197 } 2198 2199 // Open submenu on click 2200 if ( target.has( ".ui-menu" ).length ) { 2201 this.expand( event ); 2202 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 2203 2204 // Redirect focus to the menu 2205 this.element.trigger( "focus", [ true ] ); 2206 2207 // If the active item is on the top level, let it stay active. 2208 // Otherwise, blur the active item since it is no longer visible. 2209 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 2210 clearTimeout( this.timer ); 2211 } 2212 } 2213 } 2214 }, 2215 "mouseenter .ui-menu-item": function( event ) { 2216 // Ignore mouse events while typeahead is active, see #10458. 2217 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 2218 // is over an item in the menu 2219 if ( this.previousFilter ) { 2220 return; 2221 } 2222 var target = $( event.currentTarget ); 2223 // Remove ui-state-active class from siblings of the newly focused menu item 2224 // to avoid a jump caused by adjacent elements both having a class with a border 2225 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); 2226 this.focus( event, target ); 2227 }, 2228 mouseleave: "collapseAll", 2229 "mouseleave .ui-menu": "collapseAll", 2230 focus: function( event, keepActiveItem ) { 2231 // If there's already an active item, keep it active 2232 // If not, activate the first item 2233 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 2234 2235 if ( !keepActiveItem ) { 2236 this.focus( event, item ); 2237 } 2238 }, 2239 blur: function( event ) { 2240 this._delay(function() { 2241 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 2242 this.collapseAll( event ); 2243 } 2244 }); 2245 }, 2246 keydown: "_keydown" 2247 }); 2248 2249 this.refresh(); 2250 2251 // Clicks outside of a menu collapse any open menus 2252 this._on( this.document, { 2253 click: function( event ) { 2254 if ( this._closeOnDocumentClick( event ) ) { 2255 this.collapseAll( event ); 2256 } 2257 2258 // Reset the mouseHandled flag 2259 this.mouseHandled = false; 2260 } 2261 }); 2262 }, 2263 2264 _destroy: function() { 2265 // Destroy (sub)menus 2266 this.element 2267 .removeAttr( "aria-activedescendant" ) 2268 .find( ".ui-menu" ).addBack() 2269 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) 2270 .removeAttr( "role" ) 2271 .removeAttr( "tabIndex" ) 2272 .removeAttr( "aria-labelledby" ) 2273 .removeAttr( "aria-expanded" ) 2274 .removeAttr( "aria-hidden" ) 2275 .removeAttr( "aria-disabled" ) 2276 .removeUniqueId() 2277 .show(); 2278 2279 // Destroy menu items 2280 this.element.find( ".ui-menu-item" ) 2281 .removeClass( "ui-menu-item" ) 2282 .removeAttr( "role" ) 2283 .removeAttr( "aria-disabled" ) 2284 .removeUniqueId() 2285 .removeClass( "ui-state-hover" ) 2286 .removeAttr( "tabIndex" ) 2287 .removeAttr( "role" ) 2288 .removeAttr( "aria-haspopup" ) 2289 .children().each( function() { 2290 var elem = $( this ); 2291 if ( elem.data( "ui-menu-submenu-carat" ) ) { 2292 elem.remove(); 2293 } 2294 }); 2295 2296 // Destroy menu dividers 2297 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 2298 }, 2299 2300 _keydown: function( event ) { 2301 var match, prev, character, skip, 2302 preventDefault = true; 2303 2304 switch ( event.keyCode ) { 2305 case $.ui.keyCode.PAGE_UP: 2306 this.previousPage( event ); 2307 break; 2308 case $.ui.keyCode.PAGE_DOWN: 2309 this.nextPage( event ); 2310 break; 2311 case $.ui.keyCode.HOME: 2312 this._move( "first", "first", event ); 2313 break; 2314 case $.ui.keyCode.END: 2315 this._move( "last", "last", event ); 2316 break; 2317 case $.ui.keyCode.UP: 2318 this.previous( event ); 2319 break; 2320 case $.ui.keyCode.DOWN: 2321 this.next( event ); 2322 break; 2323 case $.ui.keyCode.LEFT: 2324 this.collapse( event ); 2325 break; 2326 case $.ui.keyCode.RIGHT: 2327 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 2328 this.expand( event ); 2329 } 2330 break; 2331 case $.ui.keyCode.ENTER: 2332 case $.ui.keyCode.SPACE: 2333 this._activate( event ); 2334 break; 2335 case $.ui.keyCode.ESCAPE: 2336 this.collapse( event ); 2337 break; 2338 default: 2339 preventDefault = false; 2340 prev = this.previousFilter || ""; 2341 character = String.fromCharCode( event.keyCode ); 2342 skip = false; 2343 2344 clearTimeout( this.filterTimer ); 2345 2346 if ( character === prev ) { 2347 skip = true; 2348 } else { 2349 character = prev + character; 2350 } 2351 2352 match = this._filterMenuItems( character ); 2353 match = skip && match.index( this.active.next() ) !== -1 ? 2354 this.active.nextAll( ".ui-menu-item" ) : 2355 match; 2356 2357 // If no matches on the current filter, reset to the last character pressed 2358 // to move down the menu to the first item that starts with that character 2359 if ( !match.length ) { 2360 character = String.fromCharCode( event.keyCode ); 2361 match = this._filterMenuItems( character ); 2362 } 2363 2364 if ( match.length ) { 2365 this.focus( event, match ); 2366 this.previousFilter = character; 2367 this.filterTimer = this._delay(function() { 2368 delete this.previousFilter; 2369 }, 1000 ); 2370 } else { 2371 delete this.previousFilter; 2372 } 2373 } 2374 2375 if ( preventDefault ) { 2376 event.preventDefault(); 2377 } 2378 }, 2379 2380 _activate: function( event ) { 2381 if ( !this.active.is( ".ui-state-disabled" ) ) { 2382 if ( this.active.is( "[aria-haspopup='true']" ) ) { 2383 this.expand( event ); 2384 } else { 2385 this.select( event ); 2386 } 2387 } 2388 }, 2389 2390 refresh: function() { 2391 var menus, items, 2392 that = this, 2393 icon = this.options.icons.submenu, 2394 submenus = this.element.find( this.options.menus ); 2395 2396 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 2397 2398 // Initialize nested menus 2399 submenus.filter( ":not(.ui-menu)" ) 2400 .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) 2401 .hide() 2402 .attr({ 2403 role: this.options.role, 2404 "aria-hidden": "true", 2405 "aria-expanded": "false" 2406 }) 2407 .each(function() { 2408 var menu = $( this ), 2409 item = menu.parent(), 2410 submenuCarat = $( "<span>" ) 2411 .addClass( "ui-menu-icon ui-icon " + icon ) 2412 .data( "ui-menu-submenu-carat", true ); 2413 2414 item 2415 .attr( "aria-haspopup", "true" ) 2416 .prepend( submenuCarat ); 2417 menu.attr( "aria-labelledby", item.attr( "id" ) ); 2418 }); 2419 2420 menus = submenus.add( this.element ); 2421 items = menus.find( this.options.items ); 2422
vendor: 8,751 bytes, lines 2423-2742
2423 // Initialize menu-items containing spaces and/or dashes only as dividers 2424 items.not( ".ui-menu-item" ).each(function() { 2425 var item = $( this ); 2426 if ( that._isDivider( item ) ) { 2427 item.addClass( "ui-widget-content ui-menu-divider" ); 2428 } 2429 }); 2430 2431 // Don't refresh list items that are already adapted 2432 items.not( ".ui-menu-item, .ui-menu-divider" ) 2433 .addClass( "ui-menu-item" ) 2434 .uniqueId() 2435 .attr({ 2436 tabIndex: -1, 2437 role: this._itemRole() 2438 }); 2439 2440 // Add aria-disabled attribute to any disabled menu item 2441 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 2442 2443 // If the active item has been removed, blur the menu 2444 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 2445 this.blur(); 2446 } 2447 }, 2448 2449 _itemRole: function() { 2450 return { 2451 menu: "menuitem", 2452 listbox: "option" 2453 }[ this.options.role ]; 2454 }, 2455 2456 _setOption: function( key, value ) { 2457 if ( key === "icons" ) { 2458 this.element.find( ".ui-menu-icon" ) 2459 .removeClass( this.options.icons.submenu ) 2460 .addClass( value.submenu ); 2461 } 2462 if ( key === "disabled" ) { 2463 this.element 2464 .toggleClass( "ui-state-disabled", !!value ) 2465 .attr( "aria-disabled", value ); 2466 } 2467 this._super( key, value ); 2468 }, 2469 2470 focus: function( event, item ) { 2471 var nested, focused; 2472 this.blur( event, event && event.type === "focus" ); 2473 2474 this._scrollIntoView( item ); 2475 2476 this.active = item.first(); 2477 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); 2478 // Only update aria-activedescendant if there's a role 2479 // otherwise we assume focus is managed elsewhere 2480 if ( this.options.role ) { 2481 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 2482 } 2483 2484 // Highlight active parent menu item, if any 2485 this.active 2486 .parent() 2487 .closest( ".ui-menu-item" ) 2488 .addClass( "ui-state-active" ); 2489 2490 if ( event && event.type === "keydown" ) { 2491 this._close(); 2492 } else { 2493 this.timer = this._delay(function() { 2494 this._close(); 2495 }, this.delay ); 2496 } 2497 2498 nested = item.children( ".ui-menu" ); 2499 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 2500 this._startOpening(nested); 2501 } 2502 this.activeMenu = item.parent(); 2503 2504 this._trigger( "focus", event, { item: item } ); 2505 }, 2506 2507 _scrollIntoView: function( item ) { 2508 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 2509 if ( this._hasScroll() ) { 2510 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 2511 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 2512 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 2513 scroll = this.activeMenu.scrollTop(); 2514 elementHeight = this.activeMenu.height(); 2515 itemHeight = item.outerHeight(); 2516 2517 if ( offset < 0 ) { 2518 this.activeMenu.scrollTop( scroll + offset ); 2519 } else if ( offset + itemHeight > elementHeight ) { 2520 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 2521 } 2522 } 2523 }, 2524 2525 blur: function( event, fromFocus ) { 2526 if ( !fromFocus ) { 2527 clearTimeout( this.timer ); 2528 } 2529 2530 if ( !this.active ) { 2531 return; 2532 } 2533 2534 this.active.removeClass( "ui-state-focus" ); 2535 this.active = null; 2536 2537 this._trigger( "blur", event, { item: this.active } ); 2538 }, 2539 2540 _startOpening: function( submenu ) { 2541 clearTimeout( this.timer ); 2542 2543 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 2544 // shift in the submenu position when mousing over the carat icon 2545 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 2546 return; 2547 } 2548 2549 this.timer = this._delay(function() { 2550 this._close(); 2551 this._open( submenu ); 2552 }, this.delay ); 2553 }, 2554 2555 _open: function( submenu ) { 2556 var position = $.extend({ 2557 of: this.active 2558 }, this.options.position ); 2559 2560 clearTimeout( this.timer ); 2561 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 2562 .hide() 2563 .attr( "aria-hidden", "true" ); 2564 2565 submenu 2566 .show() 2567 .removeAttr( "aria-hidden" ) 2568 .attr( "aria-expanded", "true" ) 2569 .position( position ); 2570 }, 2571 2572 collapseAll: function( event, all ) { 2573 clearTimeout( this.timer ); 2574 this.timer = this._delay(function() { 2575 // If we were passed an event, look for the submenu that contains the event 2576 var currentMenu = all ? this.element : 2577 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 2578 2579 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 2580 if ( !currentMenu.length ) { 2581 currentMenu = this.element; 2582 } 2583 2584 this._close( currentMenu ); 2585 2586 this.blur( event ); 2587 this.activeMenu = currentMenu; 2588 }, this.delay ); 2589 }, 2590 2591 // With no arguments, closes the currently active menu - if nothing is active 2592 // it closes all menus. If passed an argument, it will search for menus BELOW 2593 _close: function( startMenu ) { 2594 if ( !startMenu ) { 2595 startMenu = this.active ? this.active.parent() : this.element; 2596 } 2597 2598 startMenu 2599 .find( ".ui-menu" ) 2600 .hide() 2601 .attr( "aria-hidden", "true" ) 2602 .attr( "aria-expanded", "false" ) 2603 .end() 2604 .find( ".ui-state-active" ).not( ".ui-state-focus" ) 2605 .removeClass( "ui-state-active" ); 2606 }, 2607 2608 _closeOnDocumentClick: function( event ) { 2609 return !$( event.target ).closest( ".ui-menu" ).length; 2610 }, 2611 2612 _isDivider: function( item ) { 2613 2614 // Match hyphen, em dash, en dash 2615 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 2616 }, 2617 2618 collapse: function( event ) { 2619 var newItem = this.active && 2620 this.active.parent().closest( ".ui-menu-item", this.element ); 2621 if ( newItem && newItem.length ) { 2622 this._close(); 2623 this.focus( event, newItem ); 2624 } 2625 }, 2626 2627 expand: function( event ) { 2628 var newItem = this.active && 2629 this.active 2630 .children( ".ui-menu " ) 2631 .find( this.options.items ) 2632 .first(); 2633 2634 if ( newItem && newItem.length ) { 2635 this._open( newItem.parent() ); 2636 2637 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 2638 this._delay(function() { 2639 this.focus( event, newItem ); 2640 }); 2641 } 2642 }, 2643 2644 next: function( event ) { 2645 this._move( "next", "first", event ); 2646 }, 2647 2648 previous: function( event ) { 2649 this._move( "prev", "last", event ); 2650 }, 2651 2652 isFirstItem: function() { 2653 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 2654 }, 2655 2656 isLastItem: function() { 2657 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 2658 }, 2659 2660 _move: function( direction, filter, event ) { 2661 var next; 2662 if ( this.active ) { 2663 if ( direction === "first" || direction === "last" ) { 2664 next = this.active 2665 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 2666 .eq( -1 ); 2667 } else { 2668 next = this.active 2669 [ direction + "All" ]( ".ui-menu-item" ) 2670 .eq( 0 ); 2671 } 2672 } 2673 if ( !next || !next.length || !this.active ) { 2674 next = this.activeMenu.find( this.options.items )[ filter ](); 2675 } 2676 2677 this.focus( event, next ); 2678 }, 2679 2680 nextPage: function( event ) { 2681 var item, base, height; 2682 2683 if ( !this.active ) { 2684 this.next( event ); 2685 return; 2686 } 2687 if ( this.isLastItem() ) { 2688 return; 2689 } 2690 if ( this._hasScroll() ) { 2691 base = this.active.offset().top; 2692 height = this.element.height(); 2693 this.active.nextAll( ".ui-menu-item" ).each(function() { 2694 item = $( this ); 2695 return item.offset().top - base - height < 0; 2696 }); 2697 2698 this.focus( event, item ); 2699 } else { 2700 this.focus( event, this.activeMenu.find( this.options.items ) 2701 [ !this.active ? "first" : "last" ]() ); 2702 } 2703 }, 2704 2705 previousPage: function( event ) { 2706 var item, base, height; 2707 if ( !this.active ) { 2708 this.next( event ); 2709 return; 2710 } 2711 if ( this.isFirstItem() ) { 2712 return; 2713 } 2714 if ( this._hasScroll() ) { 2715 base = this.active.offset().top; 2716 height = this.element.height(); 2717 this.active.prevAll( ".ui-menu-item" ).each(function() { 2718 item = $( this ); 2719 return item.offset().top - base + height > 0; 2720 }); 2721 2722 this.focus( event, item ); 2723 } else { 2724 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 2725 } 2726 }, 2727 2728 _hasScroll: function() { 2729 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 2730 }, 2731 2732 select: function( event ) { 2733 // TODO: It should never be possible to not have an active item at this 2734 // point, but the tests don't trigger mouseenter before click. 2735 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 2736 var ui = { item: this.active }; 2737 if ( !this.active.has( ".ui-menu" ).length ) { 2738 this.collapseAll( event, true ); 2739 } 2740 this._trigger( "select", event, ui ); 2741 }, 2742
vendor: 4,970 bytes, lines 2743-2920
2743 _filterMenuItems: function(character) { 2744 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 2745 regex = new RegExp( "^" + escapedCharacter, "i" ); 2746 2747 return this.activeMenu 2748 .find( this.options.items ) 2749 2750 // Only match on items, not dividers or other content (#10571) 2751 .filter( ".ui-menu-item" ) 2752 .filter(function() { 2753 return regex.test( $.trim( $( this ).text() ) ); 2754 }); 2755 } 2756}); 2757 2758 2759/*! 2760 * jQuery UI Autocomplete 1.11.4 2761 * http://jqueryui.com 2762 * 2763 * Copyright jQuery Foundation and other contributors 2764 * Released under the MIT license. 2765 * http://jquery.org/license 2766 * 2767 * http://api.jqueryui.com/autocomplete/ 2768 */ 2769 2770 2771$.widget( "ui.autocomplete", { 2772 version: "1.11.4", 2773 defaultElement: "<input>", 2774 options: { 2775 appendTo: null, 2776 autoFocus: false, 2777 delay: 300, 2778 minLength: 1, 2779 position: { 2780 my: "left top", 2781 at: "left bottom", 2782 collision: "none" 2783 }, 2784 source: null, 2785 2786 // callbacks 2787 change: null, 2788 close: null, 2789 focus: null, 2790 open: null, 2791 response: null, 2792 search: null, 2793 select: null 2794 }, 2795 2796 requestIndex: 0, 2797 pending: 0, 2798 2799 _create: function() { 2800 // Some browsers only repeat keydown events, not keypress events, 2801 // so we use the suppressKeyPress flag to determine if we've already 2802 // handled the keydown event. #7269 2803 // Unfortunately the code for & in keypress is the same as the up arrow, 2804 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 2805 // events when we know the keydown event was used to modify the 2806 // search term. #7799 2807 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 2808 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 2809 isTextarea = nodeName === "textarea", 2810 isInput = nodeName === "input"; 2811 2812 this.isMultiLine = 2813 // Textareas are always multi-line 2814 isTextarea ? true : 2815 // Inputs are always single-line, even if inside a contentEditable element 2816 // IE also treats inputs as contentEditable 2817 isInput ? false : 2818 // All other element types are determined by whether or not they're contentEditable 2819 this.element.prop( "isContentEditable" ); 2820 2821 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 2822 this.isNewMenu = true; 2823 2824 this.element 2825 .addClass( "ui-autocomplete-input" ) 2826 .attr( "autocomplete", "off" ); 2827 2828 this._on( this.element, { 2829 keydown: function( event ) { 2830 if ( this.element.prop( "readOnly" ) ) { 2831 suppressKeyPress = true; 2832 suppressInput = true; 2833 suppressKeyPressRepeat = true; 2834 return; 2835 } 2836 2837 suppressKeyPress = false; 2838 suppressInput = false; 2839 suppressKeyPressRepeat = false; 2840 var keyCode = $.ui.keyCode; 2841 switch ( event.keyCode ) { 2842 case keyCode.PAGE_UP: 2843 suppressKeyPress = true; 2844 this._move( "previousPage", event ); 2845 break; 2846 case keyCode.PAGE_DOWN: 2847 suppressKeyPress = true; 2848 this._move( "nextPage", event ); 2849 break; 2850 case keyCode.UP: 2851 suppressKeyPress = true; 2852 this._keyEvent( "previous", event ); 2853 break; 2854 case keyCode.DOWN: 2855 suppressKeyPress = true; 2856 this._keyEvent( "next", event ); 2857 break; 2858 case keyCode.ENTER: 2859 // when menu is open and has focus 2860 if ( this.menu.active ) { 2861 // #6055 - Opera still allows the keypress to occur 2862 // which causes forms to submit 2863 suppressKeyPress = true; 2864 event.preventDefault(); 2865 this.menu.select( event ); 2866 } 2867 break; 2868 case keyCode.TAB: 2869 if ( this.menu.active ) { 2870 this.menu.select( event ); 2871 } 2872 break; 2873 case keyCode.ESCAPE: 2874 if ( this.menu.element.is( ":visible" ) ) { 2875 if ( !this.isMultiLine ) { 2876 this._value( this.term ); 2877 } 2878 this.close( event ); 2879 // Different browsers have different default behavior for escape 2880 // Single press can mean undo or clear 2881 // Double press in IE means clear the whole form 2882 event.preventDefault(); 2883 } 2884 break; 2885 default: 2886 suppressKeyPressRepeat = true; 2887 // search timeout should be triggered before the input value is changed 2888 this._searchTimeout( event ); 2889 break; 2890 } 2891 }, 2892 keypress: function( event ) { 2893 if ( suppressKeyPress ) { 2894 suppressKeyPress = false; 2895 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 2896 event.preventDefault(); 2897 } 2898 return; 2899 } 2900 if ( suppressKeyPressRepeat ) { 2901 return; 2902 } 2903 2904 // replicate some key handlers to allow them to repeat in Firefox and Opera 2905 var keyCode = $.ui.keyCode; 2906 switch ( event.keyCode ) { 2907 case keyCode.PAGE_UP: 2908 this._move( "previousPage", event ); 2909 break; 2910 case keyCode.PAGE_DOWN: 2911 this._move( "nextPage", event ); 2912 break; 2913 case keyCode.UP: 2914 this._keyEvent( "previous", event ); 2915 break; 2916 case keyCode.DOWN: 2917 this._keyEvent( "next", event ); 2918 break; 2919 } 2920 },
vendor: 27,902 bytes, lines 2921-3848
2921 input: function( event ) { 2922 if ( suppressInput ) { 2923 suppressInput = false; 2924 event.preventDefault(); 2925 return; 2926 } 2927 this._searchTimeout( event ); 2928 }, 2929 focus: function() { 2930 this.selectedItem = null; 2931 this.previous = this._value(); 2932 }, 2933 blur: function( event ) { 2934 if ( this.cancelBlur ) { 2935 delete this.cancelBlur; 2936 return; 2937 } 2938 2939 clearTimeout( this.searching ); 2940 this.close( event ); 2941 this._change( event ); 2942 } 2943 }); 2944 2945 this._initSource(); 2946 this.menu = $( "<ul>" ) 2947 .addClass( "ui-autocomplete ui-front" ) 2948 .appendTo( this._appendTo() ) 2949 .menu({ 2950 // disable ARIA support, the live region takes care of that 2951 role: null 2952 }) 2953 .hide() 2954 .menu( "instance" ); 2955 2956 this._on( this.menu.element, { 2957 mousedown: function( event ) { 2958 // prevent moving focus out of the text field 2959 event.preventDefault(); 2960 2961 // IE doesn't prevent moving focus even with event.preventDefault() 2962 // so we set a flag to know when we should ignore the blur event 2963 this.cancelBlur = true; 2964 this._delay(function() { 2965 delete this.cancelBlur; 2966 }); 2967 2968 // clicking on the scrollbar causes focus to shift to the body 2969 // but we can't detect a mouseup or a click immediately afterward 2970 // so we have to track the next mousedown and close the menu if 2971 // the user clicks somewhere outside of the autocomplete 2972 var menuElement = this.menu.element[ 0 ]; 2973 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 2974 this._delay(function() { 2975 var that = this; 2976 this.document.one( "mousedown", function( event ) { 2977 if ( event.target !== that.element[ 0 ] && 2978 event.target !== menuElement && 2979 !$.contains( menuElement, event.target ) ) { 2980 that.close(); 2981 } 2982 }); 2983 }); 2984 } 2985 }, 2986 menufocus: function( event, ui ) { 2987 var label, item; 2988 // support: Firefox 2989 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 2990 if ( this.isNewMenu ) { 2991 this.isNewMenu = false; 2992 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 2993 this.menu.blur(); 2994 2995 this.document.one( "mousemove", function() { 2996 $( event.target ).trigger( event.originalEvent ); 2997 }); 2998 2999 return; 3000 } 3001 } 3002 3003 item = ui.item.data( "ui-autocomplete-item" ); 3004 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 3005 // use value to match what will end up in the input, if it was a key event 3006 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 3007 this._value( item.value ); 3008 } 3009 } 3010 3011 // Announce the value in the liveRegion 3012 label = ui.item.attr( "aria-label" ) || item.value; 3013 if ( label && $.trim( label ).length ) { 3014 this.liveRegion.children().hide(); 3015 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 3016 } 3017 }, 3018 menuselect: function( event, ui ) { 3019 var item = ui.item.data( "ui-autocomplete-item" ), 3020 previous = this.previous; 3021 3022 // only trigger when focus was lost (click on menu) 3023 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 3024 this.element.focus(); 3025 this.previous = previous; 3026 // #6109 - IE triggers two focus events and the second 3027 // is asynchronous, so we need to reset the previous 3028 // term synchronously and asynchronously :-( 3029 this._delay(function() { 3030 this.previous = previous; 3031 this.selectedItem = item; 3032 }); 3033 } 3034 3035 if ( false !== this._trigger( "select", event, { item: item } ) ) { 3036 this._value( item.value ); 3037 } 3038 // reset the term after the select event 3039 // this allows custom select handling to work properly 3040 this.term = this._value(); 3041 3042 this.close( event ); 3043 this.selectedItem = item; 3044 } 3045 }); 3046 3047 this.liveRegion = $( "<span>", { 3048 role: "status", 3049 "aria-live": "assertive", 3050 "aria-relevant": "additions" 3051 }) 3052 .addClass( "ui-helper-hidden-accessible" ) 3053 .appendTo( this.document[ 0 ].body ); 3054 3055 // turning off autocomplete prevents the browser from remembering the 3056 // value when navigating through history, so we re-enable autocomplete 3057 // if the page is unloaded before the widget is destroyed. #7790 3058 this._on( this.window, { 3059 beforeunload: function() { 3060 this.element.removeAttr( "autocomplete" ); 3061 } 3062 }); 3063 }, 3064 3065 _destroy: function() { 3066 clearTimeout( this.searching ); 3067 this.element 3068 .removeClass( "ui-autocomplete-input" ) 3069 .removeAttr( "autocomplete" ); 3070 this.menu.element.remove(); 3071 this.liveRegion.remove(); 3072 }, 3073 3074 _setOption: function( key, value ) { 3075 this._super( key, value ); 3076 if ( key === "source" ) { 3077 this._initSource(); 3078 } 3079 if ( key === "appendTo" ) { 3080 this.menu.element.appendTo( this._appendTo() ); 3081 } 3082 if ( key === "disabled" && value && this.xhr ) { 3083 this.xhr.abort(); 3084 } 3085 }, 3086 3087 _appendTo: function() { 3088 var element = this.options.appendTo; 3089 3090 if ( element ) { 3091 element = element.jquery || element.nodeType ? 3092 $( element ) : 3093 this.document.find( element ).eq( 0 ); 3094 } 3095 3096 if ( !element || !element[ 0 ] ) { 3097 element = this.element.closest( ".ui-front" ); 3098 } 3099 3100 if ( !element.length ) { 3101 element = this.document[ 0 ].body; 3102 } 3103 3104 return element; 3105 }, 3106 3107 _initSource: function() { 3108 var array, url, 3109 that = this; 3110 if ( $.isArray( this.options.source ) ) { 3111 array = this.options.source; 3112 this.source = function( request, response ) { 3113 response( $.ui.autocomplete.filter( array, request.term ) ); 3114 }; 3115 } else if ( typeof this.options.source === "string" ) { 3116 url = this.options.source; 3117 this.source = function( request, response ) { 3118 if ( that.xhr ) { 3119 that.xhr.abort(); 3120 } 3121 that.xhr = $.ajax({ 3122 url: url, 3123 data: request, 3124 dataType: "json", 3125 success: function( data ) { 3126 response( data ); 3127 }, 3128 error: function() { 3129 response([]); 3130 } 3131 }); 3132 }; 3133 } else { 3134 this.source = this.options.source; 3135 } 3136 }, 3137 3138 _searchTimeout: function( event ) { 3139 clearTimeout( this.searching ); 3140 this.searching = this._delay(function() { 3141 3142 // Search if the value has changed, or if the user retypes the same value (see #7434) 3143 var equalValues = this.term === this._value(), 3144 menuVisible = this.menu.element.is( ":visible" ), 3145 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 3146 3147 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 3148 this.selectedItem = null; 3149 this.search( null, event ); 3150 } 3151 }, this.options.delay ); 3152 }, 3153 3154 search: function( value, event ) { 3155 value = value != null ? value : this._value(); 3156 3157 // always save the actual value, not the one passed as an argument 3158 this.term = this._value(); 3159 3160 if ( value.length < this.options.minLength ) { 3161 return this.close( event ); 3162 } 3163 3164 if ( this._trigger( "search", event ) === false ) { 3165 return; 3166 } 3167 3168 return this._search( value ); 3169 }, 3170 3171 _search: function( value ) { 3172 this.pending++; 3173 this.element.addClass( "ui-autocomplete-loading" ); 3174 this.cancelSearch = false; 3175 3176 this.source( { term: value }, this._response() ); 3177 }, 3178 3179 _response: function() { 3180 var index = ++this.requestIndex; 3181 3182 return $.proxy(function( content ) { 3183 if ( index === this.requestIndex ) { 3184 this.__response( content ); 3185 } 3186 3187 this.pending--; 3188 if ( !this.pending ) { 3189 this.element.removeClass( "ui-autocomplete-loading" ); 3190 } 3191 }, this ); 3192 }, 3193 3194 __response: function( content ) { 3195 if ( content ) { 3196 content = this._normalize( content ); 3197 } 3198 this._trigger( "response", null, { content: content } ); 3199 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 3200 this._suggest( content ); 3201 this._trigger( "open" ); 3202 } else { 3203 // use ._close() instead of .close() so we don't cancel future searches 3204 this._close(); 3205 } 3206 }, 3207 3208 close: function( event ) { 3209 this.cancelSearch = true; 3210 this._close( event ); 3211 }, 3212 3213 _close: function( event ) { 3214 if ( this.menu.element.is( ":visible" ) ) { 3215 this.menu.element.hide(); 3216 this.menu.blur(); 3217 this.isNewMenu = true; 3218 this._trigger( "close", event ); 3219 } 3220 }, 3221 3222 _change: function( event ) { 3223 if ( this.previous !== this._value() ) { 3224 this._trigger( "change", event, { item: this.selectedItem } ); 3225 } 3226 }, 3227 3228 _normalize: function( items ) { 3229 // assume all items have the right format when the first item is complete 3230 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 3231 return items; 3232 } 3233 return $.map( items, function( item ) { 3234 if ( typeof item === "string" ) { 3235 return { 3236 label: item, 3237 value: item 3238 }; 3239 } 3240 return $.extend( {}, item, { 3241 label: item.label || item.value, 3242 value: item.value || item.label 3243 }); 3244 }); 3245 }, 3246 3247 _suggest: function( items ) { 3248 var ul = this.menu.element.empty(); 3249 this._renderMenu( ul, items ); 3250 this.isNewMenu = true; 3251 this.menu.refresh(); 3252 3253 // size and position menu 3254 ul.show(); 3255 this._resizeMenu(); 3256 ul.position( $.extend({ 3257 of: this.element 3258 }, this.options.position ) ); 3259 3260 if ( this.options.autoFocus ) { 3261 this.menu.next(); 3262 } 3263 }, 3264 3265 _resizeMenu: function() { 3266 var ul = this.menu.element; 3267 ul.outerWidth( Math.max( 3268 // Firefox wraps long text (possibly a rounding bug) 3269 // so we add 1px to avoid the wrapping (#7513) 3270 ul.width( "" ).outerWidth() + 1, 3271 this.element.outerWidth() 3272 ) ); 3273 }, 3274 3275 _renderMenu: function( ul, items ) { 3276 var that = this; 3277 $.each( items, function( index, item ) { 3278 that._renderItemData( ul, item ); 3279 }); 3280 }, 3281 3282 _renderItemData: function( ul, item ) { 3283 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 3284 }, 3285 3286 _renderItem: function( ul, item ) { 3287 return $( "<li>" ).text( item.label ).appendTo( ul ); 3288 }, 3289 3290 _move: function( direction, event ) { 3291 if ( !this.menu.element.is( ":visible" ) ) { 3292 this.search( null, event ); 3293 return; 3294 } 3295 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 3296 this.menu.isLastItem() && /^next/.test( direction ) ) { 3297 3298 if ( !this.isMultiLine ) { 3299 this._value( this.term ); 3300 } 3301 3302 this.menu.blur(); 3303 return; 3304 } 3305 this.menu[ direction ]( event ); 3306 }, 3307 3308 widget: function() { 3309 return this.menu.element; 3310 }, 3311 3312 _value: function() { 3313 return this.valueMethod.apply( this.element, arguments ); 3314 }, 3315 3316 _keyEvent: function( keyEvent, event ) { 3317 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 3318 this._move( keyEvent, event ); 3319 3320 // prevents moving cursor to beginning/end of the text field in some browsers 3321 event.preventDefault(); 3322 } 3323 } 3324}); 3325 3326$.extend( $.ui.autocomplete, { 3327 escapeRegex: function( value ) { 3328 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 3329 }, 3330 filter: function( array, term ) { 3331 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 3332 return $.grep( array, function( value ) { 3333 return matcher.test( value.label || value.value || value ); 3334 }); 3335 } 3336}); 3337 3338// live region extension, adding a `messages` option 3339// NOTE: This is an experimental API. We are still investigating 3340// a full solution for string manipulation and internationalization. 3341$.widget( "ui.autocomplete", $.ui.autocomplete, { 3342 options: { 3343 messages: { 3344 noResults: "No search results.", 3345 results: function( amount ) { 3346 return amount + ( amount > 1 ? " results are" : " result is" ) + 3347 " available, use up and down arrow keys to navigate."; 3348 } 3349 } 3350 }, 3351 3352 __response: function( content ) { 3353 var message; 3354 this._superApply( arguments ); 3355 if ( this.options.disabled || this.cancelSearch ) { 3356 return; 3357 } 3358 if ( content && content.length ) { 3359 message = this.options.messages.results( content.length ); 3360 } else { 3361 message = this.options.messages.noResults; 3362 } 3363 this.liveRegion.children().hide(); 3364 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 3365 } 3366}); 3367 3368var autocomplete = $.ui.autocomplete; 3369 3370 3371/*! 3372 * jQuery UI Button 1.11.4 3373 * http://jqueryui.com 3374 * 3375 * Copyright jQuery Foundation and other contributors 3376 * Released under the MIT license. 3377 * http://jquery.org/license 3378 * 3379 * http://api.jqueryui.com/button/ 3380 */ 3381 3382 3383var lastActive, 3384 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 3385 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", 3386 formResetHandler = function() { 3387 var form = $( this ); 3388 setTimeout(function() { 3389 form.find( ":ui-button" ).button( "refresh" ); 3390 }, 1 ); 3391 }, 3392 radioGroup = function( radio ) { 3393 var name = radio.name, 3394 form = radio.form, 3395 radios = $( [] ); 3396 if ( name ) { 3397 name = name.replace( /'/g, "\\'" ); 3398 if ( form ) { 3399 radios = $( form ).find( "[name='" + name + "'][type=radio]" ); 3400 } else { 3401 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) 3402 .filter(function() { 3403 return !this.form; 3404 }); 3405 } 3406 } 3407 return radios; 3408 }; 3409 3410$.widget( "ui.button", { 3411 version: "1.11.4", 3412 defaultElement: "<button>", 3413 options: { 3414 disabled: null, 3415 text: true, 3416 label: null, 3417 icons: { 3418 primary: null, 3419 secondary: null 3420 } 3421 }, 3422 _create: function() { 3423 this.element.closest( "form" ) 3424 .unbind( "reset" + this.eventNamespace ) 3425 .bind( "reset" + this.eventNamespace, formResetHandler ); 3426 3427 if ( typeof this.options.disabled !== "boolean" ) { 3428 this.options.disabled = !!this.element.prop( "disabled" ); 3429 } else { 3430 this.element.prop( "disabled", this.options.disabled ); 3431 } 3432 3433 this._determineButtonType(); 3434 this.hasTitle = !!this.buttonElement.attr( "title" ); 3435 3436 var that = this, 3437 options = this.options, 3438 toggleButton = this.type === "checkbox" || this.type === "radio", 3439 activeClass = !toggleButton ? "ui-state-active" : ""; 3440 3441 if ( options.label === null ) { 3442 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 3443 } 3444 3445 this._hoverable( this.buttonElement ); 3446 3447 this.buttonElement 3448 .addClass( baseClasses ) 3449 .attr( "role", "button" ) 3450 .bind( "mouseenter" + this.eventNamespace, function() { 3451 if ( options.disabled ) { 3452 return; 3453 } 3454 if ( this === lastActive ) { 3455 $( this ).addClass( "ui-state-active" ); 3456 } 3457 }) 3458 .bind( "mouseleave" + this.eventNamespace, function() { 3459 if ( options.disabled ) { 3460 return; 3461 } 3462 $( this ).removeClass( activeClass ); 3463 }) 3464 .bind( "click" + this.eventNamespace, function( event ) { 3465 if ( options.disabled ) { 3466 event.preventDefault(); 3467 event.stopImmediatePropagation(); 3468 } 3469 }); 3470 3471 // Can't use _focusable() because the element that receives focus 3472 // and the element that gets the ui-state-focus class are different 3473 this._on({ 3474 focus: function() { 3475 this.buttonElement.addClass( "ui-state-focus" ); 3476 }, 3477 blur: function() { 3478 this.buttonElement.removeClass( "ui-state-focus" ); 3479 } 3480 }); 3481 3482 if ( toggleButton ) { 3483 this.element.bind( "change" + this.eventNamespace, function() { 3484 that.refresh(); 3485 }); 3486 } 3487 3488 if ( this.type === "checkbox" ) { 3489 this.buttonElement.bind( "click" + this.eventNamespace, function() { 3490 if ( options.disabled ) { 3491 return false; 3492 } 3493 }); 3494 } else if ( this.type === "radio" ) { 3495 this.buttonElement.bind( "click" + this.eventNamespace, function() { 3496 if ( options.disabled ) { 3497 return false; 3498 } 3499 $( this ).addClass( "ui-state-active" ); 3500 that.buttonElement.attr( "aria-pressed", "true" ); 3501 3502 var radio = that.element[ 0 ]; 3503 radioGroup( radio ) 3504 .not( radio ) 3505 .map(function() { 3506 return $( this ).button( "widget" )[ 0 ]; 3507 }) 3508 .removeClass( "ui-state-active" ) 3509 .attr( "aria-pressed", "false" ); 3510 }); 3511 } else { 3512 this.buttonElement 3513 .bind( "mousedown" + this.eventNamespace, function() { 3514 if ( options.disabled ) { 3515 return false; 3516 } 3517 $( this ).addClass( "ui-state-active" ); 3518 lastActive = this; 3519 that.document.one( "mouseup", function() { 3520 lastActive = null; 3521 }); 3522 }) 3523 .bind( "mouseup" + this.eventNamespace, function() { 3524 if ( options.disabled ) { 3525 return false; 3526 } 3527 $( this ).removeClass( "ui-state-active" ); 3528 }) 3529 .bind( "keydown" + this.eventNamespace, function(event) { 3530 if ( options.disabled ) { 3531 return false; 3532 } 3533 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 3534 $( this ).addClass( "ui-state-active" ); 3535 } 3536 }) 3537 // see #8559, we bind to blur here in case the button element loses 3538 // focus between keydown and keyup, it would be left in an "active" state 3539 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 3540 $( this ).removeClass( "ui-state-active" ); 3541 }); 3542 3543 if ( this.buttonElement.is("a") ) { 3544 this.buttonElement.keyup(function(event) { 3545 if ( event.keyCode === $.ui.keyCode.SPACE ) { 3546 // TODO pass through original event correctly (just as 2nd argument doesn't work) 3547 $( this ).click(); 3548 } 3549 }); 3550 } 3551 } 3552 3553 this._setOption( "disabled", options.disabled ); 3554 this._resetButton(); 3555 }, 3556 3557 _determineButtonType: function() { 3558 var ancestor, labelSelector, checked; 3559 3560 if ( this.element.is("[type=checkbox]") ) { 3561 this.type = "checkbox"; 3562 } else if ( this.element.is("[type=radio]") ) { 3563 this.type = "radio"; 3564 } else if ( this.element.is("input") ) { 3565 this.type = "input"; 3566 } else { 3567 this.type = "button"; 3568 } 3569 3570 if ( this.type === "checkbox" || this.type === "radio" ) { 3571 // we don't search against the document in case the element 3572 // is disconnected from the DOM 3573 ancestor = this.element.parents().last(); 3574 labelSelector = "label[for='" + this.element.attr("id") + "']"; 3575 this.buttonElement = ancestor.find( labelSelector ); 3576 if ( !this.buttonElement.length ) { 3577 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 3578 this.buttonElement = ancestor.filter( labelSelector ); 3579 if ( !this.buttonElement.length ) { 3580 this.buttonElement = ancestor.find( labelSelector ); 3581 } 3582 } 3583 this.element.addClass( "ui-helper-hidden-accessible" ); 3584 3585 checked = this.element.is( ":checked" ); 3586 if ( checked ) { 3587 this.buttonElement.addClass( "ui-state-active" ); 3588 } 3589 this.buttonElement.prop( "aria-pressed", checked ); 3590 } else { 3591 this.buttonElement = this.element; 3592 } 3593 }, 3594 3595 widget: function() { 3596 return this.buttonElement; 3597 }, 3598 3599 _destroy: function() { 3600 this.element 3601 .removeClass( "ui-helper-hidden-accessible" ); 3602 this.buttonElement 3603 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 3604 .removeAttr( "role" ) 3605 .removeAttr( "aria-pressed" ) 3606 .html( this.buttonElement.find(".ui-button-text").html() ); 3607 3608 if ( !this.hasTitle ) { 3609 this.buttonElement.removeAttr( "title" ); 3610 } 3611 }, 3612 3613 _setOption: function( key, value ) { 3614 this._super( key, value ); 3615 if ( key === "disabled" ) { 3616 this.widget().toggleClass( "ui-state-disabled", !!value ); 3617 this.element.prop( "disabled", !!value ); 3618 if ( value ) { 3619 if ( this.type === "checkbox" || this.type === "radio" ) { 3620 this.buttonElement.removeClass( "ui-state-focus" ); 3621 } else { 3622 this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); 3623 } 3624 } 3625 return; 3626 } 3627 this._resetButton(); 3628 }, 3629 3630 refresh: function() { 3631 //See #8237 & #8828 3632 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 3633 3634 if ( isDisabled !== this.options.disabled ) { 3635 this._setOption( "disabled", isDisabled ); 3636 } 3637 if ( this.type === "radio" ) { 3638 radioGroup( this.element[0] ).each(function() { 3639 if ( $( this ).is( ":checked" ) ) { 3640 $( this ).button( "widget" ) 3641 .addClass( "ui-state-active" ) 3642 .attr( "aria-pressed", "true" ); 3643 } else { 3644 $( this ).button( "widget" ) 3645 .removeClass( "ui-state-active" ) 3646 .attr( "aria-pressed", "false" ); 3647 } 3648 }); 3649 } else if ( this.type === "checkbox" ) { 3650 if ( this.element.is( ":checked" ) ) { 3651 this.buttonElement 3652 .addClass( "ui-state-active" ) 3653 .attr( "aria-pressed", "true" ); 3654 } else { 3655 this.buttonElement 3656 .removeClass( "ui-state-active" ) 3657 .attr( "aria-pressed", "false" ); 3658 } 3659 } 3660 }, 3661 3662 _resetButton: function() { 3663 if ( this.type === "input" ) { 3664 if ( this.options.label ) { 3665 this.element.val( this.options.label ); 3666 } 3667 return; 3668 } 3669 var buttonElement = this.buttonElement.removeClass( typeClasses ), 3670 buttonText = $( "<span></span>", this.document[0] ) 3671 .addClass( "ui-button-text" ) 3672 .html( this.options.label ) 3673 .appendTo( buttonElement.empty() ) 3674 .text(), 3675 icons = this.options.icons, 3676 multipleIcons = icons.primary && icons.secondary, 3677 buttonClasses = []; 3678 3679 if ( icons.primary || icons.secondary ) { 3680 if ( this.options.text ) { 3681 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 3682 } 3683 3684 if ( icons.primary ) { 3685 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 3686 } 3687 3688 if ( icons.secondary ) { 3689 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 3690 } 3691 3692 if ( !this.options.text ) { 3693 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 3694 3695 if ( !this.hasTitle ) { 3696 buttonElement.attr( "title", $.trim( buttonText ) ); 3697 } 3698 } 3699 } else { 3700 buttonClasses.push( "ui-button-text-only" ); 3701 } 3702 buttonElement.addClass( buttonClasses.join( " " ) ); 3703 } 3704}); 3705 3706$.widget( "ui.buttonset", { 3707 version: "1.11.4", 3708 options: { 3709 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 3710 }, 3711 3712 _create: function() { 3713 this.element.addClass( "ui-buttonset" ); 3714 }, 3715 3716 _init: function() { 3717 this.refresh(); 3718 }, 3719 3720 _setOption: function( key, value ) { 3721 if ( key === "disabled" ) { 3722 this.buttons.button( "option", key, value ); 3723 } 3724 3725 this._super( key, value ); 3726 }, 3727 3728 refresh: function() { 3729 var rtl = this.element.css( "direction" ) === "rtl", 3730 allButtons = this.element.find( this.options.items ), 3731 existingButtons = allButtons.filter( ":ui-button" ); 3732 3733 // Initialize new buttons 3734 allButtons.not( ":ui-button" ).button(); 3735 3736 // Refresh existing buttons 3737 existingButtons.button( "refresh" ); 3738 3739 this.buttons = allButtons 3740 .map(function() { 3741 return $( this ).button( "widget" )[ 0 ]; 3742 }) 3743 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 3744 .filter( ":first" ) 3745 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 3746 .end() 3747 .filter( ":last" ) 3748 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 3749 .end() 3750 .end(); 3751 }, 3752 3753 _destroy: function() { 3754 this.element.removeClass( "ui-buttonset" ); 3755 this.buttons 3756 .map(function() { 3757 return $( this ).button( "widget" )[ 0 ]; 3758 }) 3759 .removeClass( "ui-corner-left ui-corner-right" ) 3760 .end() 3761 .button( "destroy" ); 3762 } 3763}); 3764 3765var button = $.ui.button; 3766 3767 3768/*! 3769 * jQuery UI Datepicker 1.11.4 3770 * http://jqueryui.com 3771 * 3772 * Copyright jQuery Foundation and other contributors 3773 * Released under the MIT license. 3774 * http://jquery.org/license 3775 * 3776 * http://api.jqueryui.com/datepicker/ 3777 */ 3778 3779 3780$.extend($.ui, { datepicker: { version: "1.11.4" } }); 3781 3782var datepicker_instActive; 3783 3784function datepicker_getZindex( elem ) { 3785 var position, value; 3786 while ( elem.length && elem[ 0 ] !== document ) { 3787 // Ignore z-index if position is set to a value where z-index is ignored by the browser 3788 // This makes behavior of this function consistent across browsers 3789 // WebKit always returns auto if the element is positioned 3790 position = elem.css( "position" ); 3791 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 3792 // IE returns 0 when zIndex is not specified 3793 // other browsers return a string 3794 // we ignore the case of nested elements with an explicit value of 0 3795 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 3796 value = parseInt( elem.css( "zIndex" ), 10 ); 3797 if ( !isNaN( value ) && value !== 0 ) { 3798 return value; 3799 } 3800 } 3801 elem = elem.parent(); 3802 } 3803 3804 return 0; 3805} 3806/* Date picker manager. 3807 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 3808 Settings for (groups of) date pickers are maintained in an instance object, 3809 allowing multiple different settings on the same page. */ 3810 3811function Datepicker() { 3812 this._curInst = null; // The current instance in use 3813 this._keyEvent = false; // If the last event was a key event 3814 this._disabledInputs = []; // List of date picker inputs that have been disabled 3815 this._datepickerShowing = false; // True if the popup picker is showing , false if not 3816 this._inDialog = false; // True if showing within a "dialog", false if not 3817 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 3818 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 3819 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 3820 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 3821 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 3822 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 3823 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 3824 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 3825 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 3826 this.regional = []; // Available regional settings, indexed by language code 3827 this.regional[""] = { // Default regional settings 3828 closeText: "ë«ê¸°", // Display text for close link 3829 prevText: "Prev", // Display text for previous month link 3830 nextText: "Next", // Display text for next month link 3831 currentText: "Today", // Display text for current month link 3832 monthNames: ["1ì","2ì","3ì","4ì","5ì","6ì", 3833 "7ì","8ì","9ì","10ì","11ì","12ì"], // Names of months for drop-down and formatting 3834 monthNamesShort: ["1ì","2ì","3ì","4ì","5ì","6ì", 3835 "7ì","8ì","9ì","10ì","11ì","12ì"], // For formatting 3836 dayNames: ["ì¼", "ì", "í", "ì", "목", "ê¸", "í "], // For formatting 3837 dayNamesShort: ["ì¼", "ì", "í", "ì", "목", "ê¸", "í "], // For formatting 3838 dayNamesMin: ["ì¼", "ì", "í", "ì", "목", "ê¸", "í "], // Column headings for days starting at Sunday 3839 weekHeader: "Wk", // Column header for week of the year 3840 dateFormat: "mm/dd/yy", // See format options on parseDate 3841 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 3842 isRTL: false, // True if right-to-left language, false if left-to-right 3843 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 3844 yearSuffix: "" // Additional text to append to the year in the month headers 3845 }; 3846 this._defaults = { // Global defaults for all the date picker instances 3847 showOn: "focus", // "focus" for popup on focus, 3848 // "button" for trigger button, or "both" for either
vendor: 6,658 bytes, lines 3849-3980
3849 showAnim: "fadeIn", // Name of jQuery animation for popup 3850 showOptions: {}, // Options for enhanced animations 3851 defaultDate: null, // Used when field is blank: actual date, 3852 // +/-number for offset from today, null for today 3853 appendText: "", // Display text following the input box, e.g. showing the format 3854 buttonText: "...", // Text for trigger button 3855 buttonImage: "", // URL for trigger button image 3856 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 3857 hideIfNoPrevNext: false, // True to hide next/previous month links 3858 // if not applicable, false to just disable them 3859 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 3860 gotoCurrent: false, // True if today link goes back to current selection instead 3861 changeMonth: false, // True if month can be selected directly, false if only prev/next 3862 changeYear: false, // True if year can be selected directly, false if only prev/next 3863 yearRange: "c-10:c+10", // Range of years to display in drop-down, 3864 // either relative to today's year (-nn:+nn), relative to currently displayed year 3865 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 3866 showOtherMonths: false, // True to show dates in other months, false to leave blank 3867 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 3868 showWeek: false, // True to show week of the year, false to not show it 3869 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 3870 // takes a Date and returns the number of the week for it 3871 shortYearCutoff: "+10", // Short year values < this are in the current century, 3872 // > this are in the previous century, 3873 // string value starting with "+" for current year + value 3874 minDate: null, // The earliest selectable date, or null for no limit 3875 maxDate: null, // The latest selectable date, or null for no limit 3876 duration: "fast", // Duration of display/closure 3877 beforeShowDay: null, // Function that takes a date and returns an array with 3878 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 3879 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 3880 beforeShow: null, // Function that takes an input field and 3881 // returns a set of custom settings for the date picker 3882 onSelect: null, // Define a callback function when a date is selected 3883 onChangeMonthYear: null, // Define a callback function when the month or year is changed 3884 onClose: null, // Define a callback function when the datepicker is closed 3885 numberOfMonths: 1, // Number of months to show at a time 3886 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 3887 stepMonths: 1, // Number of months to step back/forward 3888 stepBigMonths: 12, // Number of months to step back/forward for the big links 3889 altField: "", // Selector for an alternate field to store selected dates into 3890 altFormat: "", // The date format to use for the alternate field 3891 constrainInput: true, // The input is constrained by the current date format 3892 showButtonPanel: false, // True to show button panel, false to not show it 3893 autoSize: false, // True to size the input for the date format, false to leave as is 3894 disabled: false // The initial disabled state 3895 }; 3896 $.extend(this._defaults, this.regional[""]); 3897 this.regional.en = $.extend( true, {}, this.regional[ "" ]); 3898 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 3899 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 3900} 3901 3902$.extend(Datepicker.prototype, { 3903 /* Class name added to elements to indicate already configured with a date picker. */ 3904 markerClassName: "hasDatepicker", 3905 3906 //Keep track of the maximum number of rows displayed (see #7043) 3907 maxRows: 4, 3908 3909 // TODO rename to "widget" when switching to widget factory 3910 _widgetDatepicker: function() { 3911 return this.dpDiv; 3912 }, 3913 3914 /* Override the default settings for all instances of the date picker. 3915 * @param settings object - the new settings to use as defaults (anonymous object) 3916 * @return the manager object 3917 */ 3918 setDefaults: function(settings) { 3919 datepicker_extendRemove(this._defaults, settings || {}); 3920 return this; 3921 }, 3922 3923 /* Attach the date picker to a jQuery selection. 3924 * @param target element - the target input field or division or span 3925 * @param settings object - the new settings to use for this date picker instance (anonymous) 3926 */ 3927 _attachDatepicker: function(target, settings) { 3928 var nodeName, inline, inst; 3929 nodeName = target.nodeName.toLowerCase(); 3930 inline = (nodeName === "div" || nodeName === "span"); 3931 if (!target.id) { 3932 this.uuid += 1; 3933 target.id = "dp" + this.uuid; 3934 } 3935 inst = this._newInst($(target), inline); 3936 inst.settings = $.extend({}, settings || {}); 3937 if (nodeName === "input") { 3938 this._connectDatepicker(target, inst); 3939 } else if (inline) { 3940 this._inlineDatepicker(target, inst); 3941 } 3942 }, 3943 3944 /* Create a new instance object. */ 3945 _newInst: function(target, inline) { 3946 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 3947 return {id: id, input: target, // associated target 3948 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 3949 drawMonth: 0, drawYear: 0, // month being drawn 3950 inline: inline, // is datepicker inline or not 3951 dpDiv: (!inline ? this.dpDiv : // presentation div 3952 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 3953 }, 3954 3955 /* Attach the date picker to an input field. */ 3956 _connectDatepicker: function(target, inst) { 3957 var input = $(target); 3958 inst.append = $([]); 3959 inst.trigger = $([]); 3960 if (input.hasClass(this.markerClassName)) { 3961 return; 3962 } 3963 this._attachments(input, inst); 3964 input.addClass(this.markerClassName).keydown(this._doKeyDown). 3965 keypress(this._doKeyPress).keyup(this._doKeyUp); 3966 this._autoSize(inst); 3967 $.data(target, "datepicker", inst); 3968 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 3969 if( inst.settings.disabled ) { 3970 this._disableDatepicker( target ); 3971 } 3972 }, 3973 3974 /* Make attachments based on settings. */ 3975 _attachments: function(input, inst) { 3976 var showOn, buttonText, buttonImage, 3977 appendText = this._get(inst, "appendText"), 3978 isRTL = this._get(inst, "isRTL"); 3979 3980 if (inst.append) {
vendor: 5,959 bytes, lines 3981-4136
3981 inst.append.remove(); 3982 } 3983 if (appendText) { 3984 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 3985 input[isRTL ? "before" : "after"](inst.append); 3986 } 3987 3988 input.unbind("focus", this._showDatepicker); 3989 3990 if (inst.trigger) { 3991 inst.trigger.remove(); 3992 } 3993 3994 showOn = this._get(inst, "showOn"); 3995 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 3996 input.focus(this._showDatepicker); 3997 } 3998 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 3999 buttonText = this._get(inst, "buttonText"); 4000 buttonImage = this._get(inst, "buttonImage"); 4001 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 4002 $("<img/>").addClass(this._triggerClass). 4003 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 4004 $("<button type='button'></button>").addClass(this._triggerClass). 4005 html(!buttonImage ? buttonText : $("<img/>").attr( 4006 { src:buttonImage, alt:buttonText, title:buttonText }))); 4007 input[isRTL ? "before" : "after"](inst.trigger); 4008 inst.trigger.click(function() { 4009 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 4010 $.datepicker._hideDatepicker(); 4011 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 4012 $.datepicker._hideDatepicker(); 4013 $.datepicker._showDatepicker(input[0]); 4014 } else { 4015 $.datepicker._showDatepicker(input[0]); 4016 } 4017 return false; 4018 }); 4019 } 4020 }, 4021 4022 /* Apply the maximum length for the date format. */ 4023 _autoSize: function(inst) { 4024 if (this._get(inst, "autoSize") && !inst.inline) { 4025 var findMax, max, maxI, i, 4026 date = new Date(2009, 12 - 1, 20), // Ensure double digits 4027 dateFormat = this._get(inst, "dateFormat"); 4028 4029 if (dateFormat.match(/[DM]/)) { 4030 findMax = function(names) { 4031 max = 0; 4032 maxI = 0; 4033 for (i = 0; i < names.length; i++) { 4034 if (names[i].length > max) { 4035 max = names[i].length; 4036 maxI = i; 4037 } 4038 } 4039 return maxI; 4040 }; 4041 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 4042 "monthNames" : "monthNamesShort")))); 4043 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 4044 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 4045 } 4046 inst.input.attr("size", this._formatDate(inst, date).length); 4047 } 4048 }, 4049 4050 /* Attach an inline date picker to a div. */ 4051 _inlineDatepicker: function(target, inst) { 4052 var divSpan = $(target); 4053 if (divSpan.hasClass(this.markerClassName)) { 4054 return; 4055 } 4056 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 4057 $.data(target, "datepicker", inst); 4058 this._setDate(inst, this._getDefaultDate(inst), true); 4059 this._updateDatepicker(inst); 4060 this._updateAlternate(inst); 4061 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 4062 if( inst.settings.disabled ) { 4063 this._disableDatepicker( target ); 4064 } 4065 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 4066 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 4067 inst.dpDiv.css( "display", "block" ); 4068 }, 4069 4070 /* Pop-up the date picker in a "dialog" box. 4071 * @param input element - ignored 4072 * @param date string or Date - the initial date to display 4073 * @param onSelect function - the function to call when a date is selected 4074 * @param settings object - update the dialog date picker instance's settings (anonymous object) 4075 * @param pos int[2] - coordinates for the dialog's position within the screen or 4076 * event - with x/y coordinates or 4077 * leave empty for default (screen centre) 4078 * @return the manager object 4079 */ 4080 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 4081 var id, browserWidth, browserHeight, scrollX, scrollY, 4082 inst = this._dialogInst; // internal instance 4083 4084 if (!inst) { 4085 this.uuid += 1; 4086 id = "dp" + this.uuid; 4087 this._dialogInput = $("<input type='text' id='" + id + 4088 "' style='position: absolute; top: -100px; width: 0px;'/>"); 4089 this._dialogInput.keydown(this._doKeyDown); 4090 $("body").append(this._dialogInput); 4091 inst = this._dialogInst = this._newInst(this._dialogInput, false); 4092 inst.settings = {}; 4093 $.data(this._dialogInput[0], "datepicker", inst); 4094 } 4095 datepicker_extendRemove(inst.settings, settings || {}); 4096 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 4097 this._dialogInput.val(date); 4098 4099 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 4100 if (!this._pos) { 4101 browserWidth = document.documentElement.clientWidth; 4102 browserHeight = document.documentElement.clientHeight; 4103 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 4104 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 4105 this._pos = // should use actual width/height below 4106 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 4107 } 4108 4109 // move input on screen for focus, but hidden behind dialog 4110 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 4111 inst.settings.onSelect = onSelect; 4112 this._inDialog = true; 4113 this.dpDiv.addClass(this._dialogClass); 4114 this._showDatepicker(this._dialogInput[0]); 4115 if ($.blockUI) { 4116 $.blockUI(this.dpDiv); 4117 } 4118 $.data(this._dialogInput[0], "datepicker", inst); 4119 return this; 4120 }, 4121 4122 /* Detach a datepicker from its control. 4123 * @param target element - the target input field or division or span 4124 */ 4125 _destroyDatepicker: function(target) { 4126 var nodeName, 4127 $target = $(target), 4128 inst = $.data(target, "datepicker"); 4129 4130 if (!$target.hasClass(this.markerClassName)) { 4131 return; 4132 } 4133 4134 nodeName = target.nodeName.toLowerCase(); 4135 $.removeData(target, "datepicker"); 4136 if (nodeName === "input") {
vendor: 11,765 bytes, lines 4137-4472
4137 inst.append.remove(); 4138 inst.trigger.remove(); 4139 $target.removeClass(this.markerClassName). 4140 unbind("focus", this._showDatepicker). 4141 unbind("keydown", this._doKeyDown). 4142 unbind("keypress", this._doKeyPress). 4143 unbind("keyup", this._doKeyUp); 4144 } else if (nodeName === "div" || nodeName === "span") { 4145 $target.removeClass(this.markerClassName).empty(); 4146 } 4147 4148 if ( datepicker_instActive === inst ) { 4149 datepicker_instActive = null; 4150 } 4151 }, 4152 4153 /* Enable the date picker to a jQuery selection. 4154 * @param target element - the target input field or division or span 4155 */ 4156 _enableDatepicker: function(target) { 4157 var nodeName, inline, 4158 $target = $(target), 4159 inst = $.data(target, "datepicker"); 4160 4161 if (!$target.hasClass(this.markerClassName)) { 4162 return; 4163 } 4164 4165 nodeName = target.nodeName.toLowerCase(); 4166 if (nodeName === "input") { 4167 target.disabled = false; 4168 inst.trigger.filter("button"). 4169 each(function() { this.disabled = false; }).end(). 4170 filter("img").css({opacity: "1.0", cursor: ""}); 4171 } else if (nodeName === "div" || nodeName === "span") { 4172 inline = $target.children("." + this._inlineClass); 4173 inline.children().removeClass("ui-state-disabled"); 4174 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4175 prop("disabled", false); 4176 } 4177 this._disabledInputs = $.map(this._disabledInputs, 4178 function(value) { return (value === target ? null : value); }); // delete entry 4179 }, 4180 4181 /* Disable the date picker to a jQuery selection. 4182 * @param target element - the target input field or division or span 4183 */ 4184 _disableDatepicker: function(target) { 4185 var nodeName, inline, 4186 $target = $(target), 4187 inst = $.data(target, "datepicker"); 4188 4189 if (!$target.hasClass(this.markerClassName)) { 4190 return; 4191 } 4192 4193 nodeName = target.nodeName.toLowerCase(); 4194 if (nodeName === "input") { 4195 target.disabled = true; 4196 inst.trigger.filter("button"). 4197 each(function() { this.disabled = true; }).end(). 4198 filter("img").css({opacity: "0.5", cursor: "default"}); 4199 } else if (nodeName === "div" || nodeName === "span") { 4200 inline = $target.children("." + this._inlineClass); 4201 inline.children().addClass("ui-state-disabled"); 4202 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4203 prop("disabled", true); 4204 } 4205 this._disabledInputs = $.map(this._disabledInputs, 4206 function(value) { return (value === target ? null : value); }); // delete entry 4207 this._disabledInputs[this._disabledInputs.length] = target; 4208 }, 4209 4210 /* Is the first field in a jQuery collection disabled as a datepicker? 4211 * @param target element - the target input field or division or span 4212 * @return boolean - true if disabled, false if enabled 4213 */ 4214 _isDisabledDatepicker: function(target) { 4215 if (!target) { 4216 return false; 4217 } 4218 for (var i = 0; i < this._disabledInputs.length; i++) { 4219 if (this._disabledInputs[i] === target) { 4220 return true; 4221 } 4222 } 4223 return false; 4224 }, 4225 4226 /* Retrieve the instance data for the target control. 4227 * @param target element - the target input field or division or span 4228 * @return object - the associated instance data 4229 * @throws error if a jQuery problem getting data 4230 */ 4231 _getInst: function(target) { 4232 try { 4233 return $.data(target, "datepicker"); 4234 } 4235 catch (err) { 4236 throw "Missing instance data for this datepicker"; 4237 } 4238 }, 4239 4240 /* Update or retrieve the settings for a date picker attached to an input field or division. 4241 * @param target element - the target input field or division or span 4242 * @param name object - the new settings to update or 4243 * string - the name of the setting to change or retrieve, 4244 * when retrieving also "all" for all instance settings or 4245 * "defaults" for all global defaults 4246 * @param value any - the new value for the setting 4247 * (omit if above is an object or to retrieve a value) 4248 */ 4249 _optionDatepicker: function(target, name, value) { 4250 var settings, date, minDate, maxDate, 4251 inst = this._getInst(target); 4252 4253 if (arguments.length === 2 && typeof name === "string") { 4254 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 4255 (inst ? (name === "all" ? $.extend({}, inst.settings) : 4256 this._get(inst, name)) : null)); 4257 } 4258 4259 settings = name || {}; 4260 if (typeof name === "string") { 4261 settings = {}; 4262 settings[name] = value; 4263 } 4264 4265 if (inst) { 4266 if (this._curInst === inst) { 4267 this._hideDatepicker(); 4268 } 4269 4270 date = this._getDateDatepicker(target, true); 4271 minDate = this._getMinMaxDate(inst, "min"); 4272 maxDate = this._getMinMaxDate(inst, "max"); 4273 datepicker_extendRemove(inst.settings, settings); 4274 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 4275 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 4276 inst.settings.minDate = this._formatDate(inst, minDate); 4277 } 4278 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 4279 inst.settings.maxDate = this._formatDate(inst, maxDate); 4280 } 4281 if ( "disabled" in settings ) { 4282 if ( settings.disabled ) { 4283 this._disableDatepicker(target); 4284 } else { 4285 this._enableDatepicker(target); 4286 } 4287 } 4288 this._attachments($(target), inst); 4289 this._autoSize(inst); 4290 this._setDate(inst, date); 4291 this._updateAlternate(inst); 4292 this._updateDatepicker(inst); 4293 } 4294 }, 4295 4296 // change method deprecated 4297 _changeDatepicker: function(target, name, value) { 4298 this._optionDatepicker(target, name, value); 4299 }, 4300 4301 /* Redraw the date picker attached to an input field or division. 4302 * @param target element - the target input field or division or span 4303 */ 4304 _refreshDatepicker: function(target) { 4305 var inst = this._getInst(target); 4306 if (inst) { 4307 this._updateDatepicker(inst); 4308 } 4309 }, 4310 4311 /* Set the dates for a jQuery selection. 4312 * @param target element - the target input field or division or span 4313 * @param date Date - the new date 4314 */ 4315 _setDateDatepicker: function(target, date) { 4316 var inst = this._getInst(target); 4317 if (inst) { 4318 this._setDate(inst, date); 4319 this._updateDatepicker(inst); 4320 this._updateAlternate(inst); 4321 } 4322 }, 4323 4324 /* Get the date(s) for the first entry in a jQuery selection. 4325 * @param target element - the target input field or division or span 4326 * @param noDefault boolean - true if no default date is to be used 4327 * @return Date - the current date 4328 */ 4329 _getDateDatepicker: function(target, noDefault) { 4330 var inst = this._getInst(target); 4331 if (inst && !inst.inline) { 4332 this._setDateFromField(inst, noDefault); 4333 } 4334 return (inst ? this._getDate(inst) : null); 4335 }, 4336 4337 /* Handle keystrokes. */ 4338 _doKeyDown: function(event) { 4339 var onSelect, dateStr, sel, 4340 inst = $.datepicker._getInst(event.target), 4341 handled = true, 4342 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 4343 4344 inst._keyEvent = true; 4345 if ($.datepicker._datepickerShowing) { 4346 switch (event.keyCode) { 4347 case 9: $.datepicker._hideDatepicker(); 4348 handled = false; 4349 break; // hide on tab out 4350 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 4351 $.datepicker._currentClass + ")", inst.dpDiv); 4352 if (sel[0]) { 4353 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 4354 } 4355 4356 onSelect = $.datepicker._get(inst, "onSelect"); 4357 if (onSelect) { 4358 dateStr = $.datepicker._formatDate(inst); 4359 4360 // trigger custom callback 4361 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 4362 } else { 4363 $.datepicker._hideDatepicker(); 4364 } 4365 4366 return false; // don't submit the form 4367 case 27: $.datepicker._hideDatepicker(); 4368 break; // hide on escape 4369 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4370 -$.datepicker._get(inst, "stepBigMonths") : 4371 -$.datepicker._get(inst, "stepMonths")), "M"); 4372 break; // previous month/year on page up/+ ctrl 4373 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4374 +$.datepicker._get(inst, "stepBigMonths") : 4375 +$.datepicker._get(inst, "stepMonths")), "M"); 4376 break; // next month/year on page down/+ ctrl 4377 case 35: if (event.ctrlKey || event.metaKey) { 4378 $.datepicker._clearDate(event.target); 4379 } 4380 handled = event.ctrlKey || event.metaKey; 4381 break; // clear on ctrl or command +end 4382 case 36: if (event.ctrlKey || event.metaKey) { 4383 $.datepicker._gotoToday(event.target); 4384 } 4385 handled = event.ctrlKey || event.metaKey; 4386 break; // current on ctrl or command +home 4387 case 37: if (event.ctrlKey || event.metaKey) { 4388 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 4389 } 4390 handled = event.ctrlKey || event.metaKey; 4391 // -1 day on ctrl or command +left 4392 if (event.originalEvent.altKey) { 4393 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4394 -$.datepicker._get(inst, "stepBigMonths") : 4395 -$.datepicker._get(inst, "stepMonths")), "M"); 4396 } 4397 // next month/year on alt +left on Mac 4398 break; 4399 case 38: if (event.ctrlKey || event.metaKey) { 4400 $.datepicker._adjustDate(event.target, -7, "D"); 4401 } 4402 handled = event.ctrlKey || event.metaKey; 4403 break; // -1 week on ctrl or command +up 4404 case 39: if (event.ctrlKey || event.metaKey) { 4405 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 4406 } 4407 handled = event.ctrlKey || event.metaKey; 4408 // +1 day on ctrl or command +right 4409 if (event.originalEvent.altKey) { 4410 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4411 +$.datepicker._get(inst, "stepBigMonths") : 4412 +$.datepicker._get(inst, "stepMonths")), "M"); 4413 } 4414 // next month/year on alt +right 4415 break; 4416 case 40: if (event.ctrlKey || event.metaKey) { 4417 $.datepicker._adjustDate(event.target, +7, "D"); 4418 } 4419 handled = event.ctrlKey || event.metaKey; 4420 break; // +1 week on ctrl or command +down 4421 default: handled = false; 4422 } 4423 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 4424 $.datepicker._showDatepicker(this); 4425 } else { 4426 handled = false; 4427 } 4428 4429 if (handled) { 4430 event.preventDefault(); 4431 event.stopPropagation(); 4432 } 4433 }, 4434 4435 /* Filter entered characters - based on date format. */ 4436 _doKeyPress: function(event) { 4437 var chars, chr, 4438 inst = $.datepicker._getInst(event.target); 4439 4440 if ($.datepicker._get(inst, "constrainInput")) { 4441 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 4442 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 4443 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 4444 } 4445 }, 4446 4447 /* Synchronise manual entry and field/alternate field. */ 4448 _doKeyUp: function(event) { 4449 var date, 4450 inst = $.datepicker._getInst(event.target); 4451 4452 if (inst.input.val() !== inst.lastVal) { 4453 try { 4454 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 4455 (inst.input ? inst.input.val() : null), 4456 $.datepicker._getFormatConfig(inst)); 4457 4458 if (date) { // only if valid 4459 $.datepicker._setDateFromField(inst); 4460 $.datepicker._updateAlternate(inst); 4461 $.datepicker._updateDatepicker(inst); 4462 } 4463 } 4464 catch (err) { 4465 } 4466 } 4467 return true; 4468 }, 4469 4470 /* Pop-up the date picker for a given input field. 4471 * If false returned from beforeShow event handler do not show. 4472 * @param input element - the input field attached to the date picker or
vendor: 14,240 bytes, lines 4473-4879
4473 * event - if triggered by focus 4474 */ 4475 _showDatepicker: function(input) { 4476 input = input.target || input; 4477 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 4478 input = $("input", input.parentNode)[0]; 4479 } 4480 4481 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 4482 return; 4483 } 4484 4485 var inst, beforeShow, beforeShowSettings, isFixed, 4486 offset, showAnim, duration; 4487 4488 inst = $.datepicker._getInst(input); 4489 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 4490 $.datepicker._curInst.dpDiv.stop(true, true); 4491 if ( inst && $.datepicker._datepickerShowing ) { 4492 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 4493 } 4494 } 4495 4496 beforeShow = $.datepicker._get(inst, "beforeShow"); 4497 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 4498 if(beforeShowSettings === false){ 4499 return; 4500 } 4501 datepicker_extendRemove(inst.settings, beforeShowSettings); 4502 4503 inst.lastVal = null; 4504 $.datepicker._lastInput = input; 4505 $.datepicker._setDateFromField(inst); 4506 4507 if ($.datepicker._inDialog) { // hide cursor 4508 input.value = ""; 4509 } 4510 if (!$.datepicker._pos) { // position below input 4511 $.datepicker._pos = $.datepicker._findPos(input); 4512 $.datepicker._pos[1] += input.offsetHeight; // add the height 4513 } 4514 4515 isFixed = false; 4516 $(input).parents().each(function() { 4517 isFixed |= $(this).css("position") === "fixed"; 4518 return !isFixed; 4519 }); 4520 4521 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 4522 $.datepicker._pos = null; 4523 //to avoid flashes on Firefox 4524 inst.dpDiv.empty(); 4525 // determine sizing offscreen 4526 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 4527 $.datepicker._updateDatepicker(inst); 4528 // fix width for dynamic number of date pickers 4529 // and adjust position before showing 4530 offset = $.datepicker._checkOffset(inst, offset, isFixed); 4531 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 4532 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 4533 left: offset.left + "px", top: offset.top + "px"}); 4534 4535 if (!inst.inline) { 4536 showAnim = $.datepicker._get(inst, "showAnim"); 4537 duration = $.datepicker._get(inst, "duration"); 4538 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 4539 $.datepicker._datepickerShowing = true; 4540 4541 if ( $.effects && $.effects.effect[ showAnim ] ) { 4542 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 4543 } else { 4544 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 4545 } 4546 4547 if ( $.datepicker._shouldFocusInput( inst ) ) { 4548 inst.input.focus(); 4549 } 4550 4551 $.datepicker._curInst = inst; 4552 } 4553 }, 4554 4555 /* Generate the date picker content. */ 4556 _updateDatepicker: function(inst) { 4557 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 4558 datepicker_instActive = inst; // for delegate hover events 4559 inst.dpDiv.empty().append(this._generateHTML(inst)); 4560 this._attachHandlers(inst); 4561 4562 var origyearshtml, 4563 numMonths = this._getNumberOfMonths(inst), 4564 cols = numMonths[1], 4565 width = 17, 4566 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 4567 4568 if ( activeCell.length > 0 ) { 4569 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 4570 } 4571 4572 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 4573 if (cols > 1) { 4574 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 4575 } 4576 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 4577 "Class"]("ui-datepicker-multi"); 4578 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 4579 "Class"]("ui-datepicker-rtl"); 4580 4581 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 4582 inst.input.focus(); 4583 } 4584 4585 // deffered render of the years select (to avoid flashes on Firefox) 4586 if( inst.yearshtml ){ 4587 origyearshtml = inst.yearshtml; 4588 setTimeout(function(){ 4589 //assure that inst.yearshtml didn't change. 4590 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 4591 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 4592 } 4593 origyearshtml = inst.yearshtml = null; 4594 }, 0); 4595 } 4596 }, 4597 4598 // #6694 - don't focus the input if it's already focused 4599 // this breaks the change event in IE 4600 // Support: IE and jQuery <1.9 4601 _shouldFocusInput: function( inst ) { 4602 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 4603 }, 4604 4605 /* Check positioning to remain on screen. */ 4606 _checkOffset: function(inst, offset, isFixed) { 4607 var dpWidth = inst.dpDiv.outerWidth(), 4608 dpHeight = inst.dpDiv.outerHeight(), 4609 inputWidth = inst.input ? inst.input.outerWidth() : 0, 4610 inputHeight = inst.input ? inst.input.outerHeight() : 0, 4611 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 4612 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 4613 4614 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 4615 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 4616 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 4617 4618 // now check if datepicker is showing outside window viewport - move to a better place if so. 4619 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 4620 Math.abs(offset.left + dpWidth - viewWidth) : 0); 4621 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 4622 Math.abs(dpHeight + inputHeight) : 0); 4623 4624 return offset; 4625 }, 4626 4627 /* Find an object's position on the screen. */ 4628 _findPos: function(obj) { 4629 var position, 4630 inst = this._getInst(obj), 4631 isRTL = this._get(inst, "isRTL"); 4632 4633 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 4634 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 4635 } 4636 4637 position = $(obj).offset(); 4638 return [position.left, position.top]; 4639 }, 4640 4641 /* Hide the date picker from view. 4642 * @param input element - the input field attached to the date picker 4643 */ 4644 _hideDatepicker: function(input) { 4645 var showAnim, duration, postProcess, onClose, 4646 inst = this._curInst; 4647 4648 if (!inst || (input && inst !== $.data(input, "datepicker"))) { 4649 return; 4650 } 4651 4652 if (this._datepickerShowing) { 4653 showAnim = this._get(inst, "showAnim"); 4654 duration = this._get(inst, "duration"); 4655 postProcess = function() { 4656 $.datepicker._tidyDialog(inst); 4657 }; 4658 4659 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 4660 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 4661 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 4662 } else { 4663 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 4664 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 4665 } 4666 4667 if (!showAnim) { 4668 postProcess(); 4669 } 4670 this._datepickerShowing = false; 4671 4672 onClose = this._get(inst, "onClose"); 4673 if (onClose) { 4674 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 4675 } 4676 4677 this._lastInput = null; 4678 if (this._inDialog) { 4679 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 4680 if ($.blockUI) { 4681 $.unblockUI(); 4682 $("body").append(this.dpDiv); 4683 } 4684 } 4685 this._inDialog = false; 4686 } 4687 }, 4688 4689 /* Tidy up after a dialog display. */ 4690 _tidyDialog: function(inst) { 4691 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 4692 }, 4693 4694 /* Close date picker if clicked elsewhere. */ 4695 _checkExternalClick: function(event) { 4696 if (!$.datepicker._curInst) { 4697 return; 4698 } 4699 4700 var $target = $(event.target), 4701 inst = $.datepicker._getInst($target[0]); 4702 4703 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 4704 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 4705 !$target.hasClass($.datepicker.markerClassName) && 4706 !$target.closest("." + $.datepicker._triggerClass).length && 4707 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 4708 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 4709 $.datepicker._hideDatepicker(); 4710 } 4711 }, 4712 4713 /* Adjust one of the date sub-fields. */ 4714 _adjustDate: function(id, offset, period) { 4715 var target = $(id), 4716 inst = this._getInst(target[0]); 4717 4718 if (this._isDisabledDatepicker(target[0])) { 4719 return; 4720 } 4721 this._adjustInstDate(inst, offset + 4722 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 4723 period); 4724 this._updateDatepicker(inst); 4725 }, 4726 4727 /* Action for current link. */ 4728 _gotoToday: function(id) { 4729 var date, 4730 target = $(id), 4731 inst = this._getInst(target[0]); 4732 4733 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 4734 inst.selectedDay = inst.currentDay; 4735 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 4736 inst.drawYear = inst.selectedYear = inst.currentYear; 4737 } else { 4738 date = new Date(); 4739 inst.selectedDay = date.getDate(); 4740 inst.drawMonth = inst.selectedMonth = date.getMonth(); 4741 inst.drawYear = inst.selectedYear = date.getFullYear(); 4742 } 4743 this._notifyChange(inst); 4744 this._adjustDate(target); 4745 }, 4746 4747 /* Action for selecting a new month/year. */ 4748 _selectMonthYear: function(id, select, period) { 4749 var target = $(id), 4750 inst = this._getInst(target[0]); 4751 4752 inst["selected" + (period === "M" ? "Month" : "Year")] = 4753 inst["draw" + (period === "M" ? "Month" : "Year")] = 4754 parseInt(select.options[select.selectedIndex].value,10); 4755 4756 this._notifyChange(inst); 4757 this._adjustDate(target); 4758 }, 4759 4760 /* Action for selecting a day. */ 4761 _selectDay: function(id, month, year, td) { 4762 var inst, 4763 target = $(id); 4764 4765 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 4766 return; 4767 } 4768 4769 inst = this._getInst(target[0]); 4770 inst.selectedDay = inst.currentDay = $("a", td).html(); 4771 inst.selectedMonth = inst.currentMonth = month; 4772 inst.selectedYear = inst.currentYear = year; 4773 this._selectDate(id, this._formatDate(inst, 4774 inst.currentDay, inst.currentMonth, inst.currentYear)); 4775 }, 4776 4777 /* Erase the input field and hide the date picker. */ 4778 _clearDate: function(id) { 4779 var target = $(id); 4780 this._selectDate(target, ""); 4781 }, 4782 4783 /* Update the input field with the selected date. */ 4784 _selectDate: function(id, dateStr) { 4785 var onSelect, 4786 target = $(id), 4787 inst = this._getInst(target[0]); 4788 4789 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 4790 if (inst.input) { 4791 inst.input.val(dateStr); 4792 } 4793 this._updateAlternate(inst); 4794 4795 onSelect = this._get(inst, "onSelect"); 4796 if (onSelect) { 4797 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 4798 } else if (inst.input) { 4799 inst.input.trigger("change"); // fire the change event 4800 } 4801 4802 if (inst.inline){ 4803 this._updateDatepicker(inst); 4804 } else { 4805 this._hideDatepicker(); 4806 this._lastInput = inst.input[0]; 4807 if (typeof(inst.input[0]) !== "object") { 4808 inst.input.focus(); // restore focus 4809 } 4810 this._lastInput = null; 4811 } 4812 }, 4813 4814 /* Update any alternate field to synchronise with the main field. */ 4815 _updateAlternate: function(inst) { 4816 var altFormat, date, dateStr, 4817 altField = this._get(inst, "altField"); 4818 4819 if (altField) { // update alternate field too 4820 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 4821 date = this._getDate(inst); 4822 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 4823 $(altField).each(function() { $(this).val(dateStr); }); 4824 } 4825 }, 4826 4827 /* Set as beforeShowDay function to prevent selection of weekends. 4828 * @param date Date - the date to customise 4829 * @return [boolean, string] - is this date selectable?, what is its CSS class? 4830 */ 4831 noWeekends: function(date) { 4832 var day = date.getDay(); 4833 return [(day > 0 && day < 6), ""]; 4834 }, 4835 4836 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 4837 * @param date Date - the date to get the week for 4838 * @return number - the number of the week within the year that contains this date 4839 */ 4840 iso8601Week: function(date) { 4841 var time, 4842 checkDate = new Date(date.getTime()); 4843 4844 // Find Thursday of this week starting on Monday 4845 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 4846 4847 time = checkDate.getTime(); 4848 checkDate.setMonth(0); // Compare with Jan 1 4849 checkDate.setDate(1); 4850 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 4851 }, 4852 4853 /* Parse a string value into a date object. 4854 * See formatDate below for the possible formats. 4855 * 4856 * @param format string - the expected format of the date 4857 * @param value string - the date in the above format 4858 * @param settings Object - attributes include: 4859 * shortYearCutoff number - the cutoff year for determining the century (optional) 4860 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 4861 * dayNames string[7] - names of the days from Sunday (optional) 4862 * monthNamesShort string[12] - abbreviated names of the months (optional) 4863 * monthNames string[12] - names of the months (optional) 4864 * @return Date - the extracted date value or null if value is blank 4865 */ 4866 parseDate: function (format, value, settings) { 4867 if (format == null || value == null) { 4868 throw "Invalid arguments"; 4869 } 4870 4871 value = (typeof value === "object" ? value.toString() : value + ""); 4872 if (value === "") { 4873 return null; 4874 } 4875 4876 var iFormat, dim, extra, 4877 iValue = 0, 4878 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 4879 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 15,764 bytes, lines 4879-5380
4879: 4880 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 4881 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 4882 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 4883 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 4884 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 4885 year = -1, 4886 month = -1, 4887 day = -1, 4888 doy = -1, 4889 literal = false, 4890 date, 4891 // Check whether a format character is doubled 4892 lookAhead = function(match) { 4893 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 4894 if (matches) { 4895 iFormat++; 4896 } 4897 return matches; 4898 }, 4899 // Extract a number from the string value 4900 getNumber = function(match) { 4901 var isDoubled = lookAhead(match), 4902 size = (match === "@" ? 14 : (match === "!" ? 20 : 4903 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 4904 minSize = (match === "y" ? size : 1), 4905 digits = new RegExp("^\\d{" + minSize + "," + size + "}"), 4906 num = value.substring(iValue).match(digits); 4907 if (!num) { 4908 throw "Missing number at position " + iValue; 4909 } 4910 iValue += num[0].length; 4911 return parseInt(num[0], 10); 4912 }, 4913 // Extract a name from the string value and convert to an index 4914 getName = function(match, shortNames, longNames) { 4915 var index = -1, 4916 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 4917 return [ [k, v] ]; 4918 }).sort(function (a, b) { 4919 return -(a[1].length - b[1].length); 4920 }); 4921 4922 $.each(names, function (i, pair) { 4923 var name = pair[1]; 4924 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 4925 index = pair[0]; 4926 iValue += name.length; 4927 return false; 4928 } 4929 }); 4930 if (index !== -1) { 4931 return index + 1; 4932 } else { 4933 throw "Unknown name at position " + iValue; 4934 } 4935 }, 4936 // Confirm that a literal character matches the string value 4937 checkLiteral = function() { 4938 if (value.charAt(iValue) !== format.charAt(iFormat)) { 4939 throw "Unexpected literal at position " + iValue; 4940 } 4941 iValue++; 4942 }; 4943 4944 for (iFormat = 0; iFormat < format.length; iFormat++) { 4945 if (literal) { 4946 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 4947 literal = false; 4948 } else { 4949 checkLiteral(); 4950 } 4951 } else { 4952 switch (format.charAt(iFormat)) { 4953 case "d": 4954 day = getNumber("d"); 4955 break; 4956 case "D": 4957 getName("D", dayNamesShort, dayNames); 4958 break; 4959 case "o": 4960 doy = getNumber("o"); 4961 break; 4962 case "m": 4963 month = getNumber("m"); 4964 break; 4965 case "M": 4966 month = getName("M", monthNamesShort, monthNames); 4967 break; 4968 case "y": 4969 year = getNumber("y"); 4970 break; 4971 case "@": 4972 date = new Date(getNumber("@")); 4973 year = date.getFullYear(); 4974 month = date.getMonth() + 1; 4975 day = date.getDate(); 4976 break; 4977 case "!": 4978 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 4979 year = date.getFullYear(); 4980 month = date.getMonth() + 1; 4981 day = date.getDate(); 4982 break; 4983 case "'": 4984 if (lookAhead("'")){ 4985 checkLiteral(); 4986 } else { 4987 literal = true; 4988 } 4989 break; 4990 default: 4991 checkLiteral(); 4992 } 4993 } 4994 } 4995 4996 if (iValue < value.length){ 4997 extra = value.substr(iValue); 4998 if (!/^\s+/.test(extra)) { 4999 throw "Extra/unparsed characters found in date: " + extra; 5000 } 5001 } 5002 5003 if (year === -1) { 5004 year = new Date().getFullYear(); 5005 } else if (year < 100) { 5006 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 5007 (year <= shortYearCutoff ? 0 : -100); 5008 } 5009 5010 if (doy > -1) { 5011 month = 1; 5012 day = doy; 5013 do { 5014 dim = this._getDaysInMonth(year, month - 1); 5015 if (day <= dim) { 5016 break; 5017 } 5018 month++; 5019 day -= dim; 5020 } while (true); 5021 } 5022 5023 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 5024 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 5025 throw "Invalid date"; // E.g. 31/02/00 5026 } 5027 return date; 5028 }, 5029 5030 /* Standard date formats. */ 5031 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 5032 COOKIE: "D, dd M yy", 5033 ISO_8601: "yy-mm-dd", 5034 RFC_822: "D, d M y", 5035 RFC_850: "DD, dd-M-y", 5036 RFC_1036: "D, d M y", 5037 RFC_1123: "D, d M yy", 5038 RFC_2822: "D, d M yy", 5039 RSS: "D, d M y", // RFC 822 5040 TICKS: "!", 5041 TIMESTAMP: "@", 5042 W3C: "yy-mm-dd", // ISO 8601 5043 5044 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 5045 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 5046 5047 /* Format a date object into a string value. 5048 * The format can be combinations of the following: 5049 * d - day of month (no leading zero) 5050 * dd - day of month (two digit) 5051 * o - day of year (no leading zeros) 5052 * oo - day of year (three digit) 5053 * D - day name short 5054 * DD - day name long 5055 * m - month of year (no leading zero) 5056 * mm - month of year (two digit) 5057 * M - month name short 5058 * MM - month name long 5059 * y - year (two digit) 5060 * yy - year (four digit) 5061 * @ - Unix timestamp (ms since 01/01/1970) 5062 * ! - Windows ticks (100ns since 01/01/0001) 5063 * "..." - literal text 5064 * '' - single quote 5065 * 5066 * @param format string - the desired format of the date 5067 * @param date Date - the date value to format 5068 * @param settings Object - attributes include: 5069 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5070 * dayNames string[7] - names of the days from Sunday (optional) 5071 * monthNamesShort string[12] - abbreviated names of the months (optional) 5072 * monthNames string[12] - names of the months (optional) 5073 * @return string - the date in the above format 5074 */ 5075 formatDate: function (format, date, settings) { 5076 if (!date) { 5077 return ""; 5078 } 5079 5080 var iFormat, 5081 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 5082 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 5083 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 5084 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 5085 // Check whether a format character is doubled 5086 lookAhead = function(match) { 5087 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5088 if (matches) { 5089 iFormat++; 5090 } 5091 return matches; 5092 }, 5093 // Format a number, with leading zero if necessary 5094 formatNumber = function(match, value, len) { 5095 var num = "" + value; 5096 if (lookAhead(match)) { 5097 while (num.length < len) { 5098 num = "0" + num; 5099 } 5100 } 5101 return num; 5102 }, 5103 // Format a name, short or long as requested 5104 formatName = function(match, value, shortNames, longNames) { 5105 return (lookAhead(match) ? longNames[value] : shortNames[value]); 5106 }, 5107 output = "", 5108 literal = false; 5109 5110 if (date) { 5111 for (iFormat = 0; iFormat < format.length; iFormat++) { 5112 if (literal) { 5113 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5114 literal = false; 5115 } else { 5116 output += format.charAt(iFormat); 5117 } 5118 } else { 5119 switch (format.charAt(iFormat)) { 5120 case "d": 5121 output += formatNumber("d", date.getDate(), 2); 5122 break; 5123 case "D": 5124 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 5125 break; 5126 case "o": 5127 output += formatNumber("o", 5128 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 5129 break; 5130 case "m": 5131 output += formatNumber("m", date.getMonth() + 1, 2); 5132 break; 5133 case "M": 5134 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 5135 break; 5136 case "y": 5137 output += (lookAhead("y") ? date.getFullYear() : 5138 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 5139 break; 5140 case "@": 5141 output += date.getTime(); 5142 break; 5143 case "!": 5144 output += date.getTime() * 10000 + this._ticksTo1970; 5145 break; 5146 case "'": 5147 if (lookAhead("'")) { 5148 output += "'"; 5149 } else { 5150 literal = true; 5151 } 5152 break; 5153 default: 5154 output += format.charAt(iFormat); 5155 } 5156 } 5157 } 5158 } 5159 return output; 5160 }, 5161 5162 /* Extract all possible characters from the date format. */ 5163 _possibleChars: function (format) { 5164 var iFormat, 5165 chars = "", 5166 literal = false, 5167 // Check whether a format character is doubled 5168 lookAhead = function(match) { 5169 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5170 if (matches) { 5171 iFormat++; 5172 } 5173 return matches; 5174 }; 5175 5176 for (iFormat = 0; iFormat < format.length; iFormat++) { 5177 if (literal) { 5178 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5179 literal = false; 5180 } else { 5181 chars += format.charAt(iFormat); 5182 } 5183 } else { 5184 switch (format.charAt(iFormat)) { 5185 case "d": case "m": case "y": case "@": 5186 chars += "0123456789"; 5187 break; 5188 case "D": case "M": 5189 return null; // Accept anything 5190 case "'": 5191 if (lookAhead("'")) { 5192 chars += "'"; 5193 } else { 5194 literal = true; 5195 } 5196 break; 5197 default: 5198 chars += format.charAt(iFormat); 5199 } 5200 } 5201 } 5202 return chars; 5203 }, 5204 5205 /* Get a setting value, defaulting if necessary. */ 5206 _get: function(inst, name) { 5207 return inst.settings[name] !== undefined ? 5208 inst.settings[name] : this._defaults[name]; 5209 }, 5210 5211 /* Parse existing date and initialise date picker. */ 5212 _setDateFromField: function(inst, noDefault) { 5213 if (inst.input.val() === inst.lastVal) { 5214 return; 5215 } 5216 5217 var dateFormat = this._get(inst, "dateFormat"), 5218 dates = inst.lastVal = inst.input ? inst.input.val() : null, 5219 defaultDate = this._getDefaultDate(inst), 5220 date = defaultDate, 5221 settings = this._getFormatConfig(inst); 5222 5223 try { 5224 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 5225 } catch (event) { 5226 dates = (noDefault ? "" : dates); 5227 } 5228 inst.selectedDay = date.getDate(); 5229 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5230 inst.drawYear = inst.selectedYear = date.getFullYear(); 5231 inst.currentDay = (dates ? date.getDate() : 0); 5232 inst.currentMonth = (dates ? date.getMonth() : 0); 5233 inst.currentYear = (dates ? date.getFullYear() : 0); 5234 this._adjustInstDate(inst); 5235 }, 5236 5237 /* Retrieve the default date shown on opening. */ 5238 _getDefaultDate: function(inst) { 5239 return this._restrictMinMax(inst, 5240 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 5241 }, 5242 5243 /* A date may be specified as an exact value or a relative one. */ 5244 _determineDate: function(inst, date, defaultDate) { 5245 var offsetNumeric = function(offset) { 5246 var date = new Date(); 5247 date.setDate(date.getDate() + offset); 5248 return date; 5249 }, 5250 offsetString = function(offset) { 5251 try { 5252 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 5253 offset, $.datepicker._getFormatConfig(inst)); 5254 } 5255 catch (e) { 5256 // Ignore 5257 } 5258 5259 var date = (offset.toLowerCase().match(/^c/) ? 5260 $.datepicker._getDate(inst) : null) || new Date(), 5261 year = date.getFullYear(), 5262 month = date.getMonth(), 5263 day = date.getDate(), 5264 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 5265 matches = pattern.exec(offset); 5266 5267 while (matches) { 5268 switch (matches[2] || "d") { 5269 case "d" : case "D" : 5270 day += parseInt(matches[1],10); break; 5271 case "w" : case "W" : 5272 day += parseInt(matches[1],10) * 7; break; 5273 case "m" : case "M" : 5274 month += parseInt(matches[1],10); 5275 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5276 break; 5277 case "y": case "Y" : 5278 year += parseInt(matches[1],10); 5279 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5280 break; 5281 } 5282 matches = pattern.exec(offset); 5283 } 5284 return new Date(year, month, day); 5285 }, 5286 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 5287 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 5288 5289 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 5290 if (newDate) { 5291 newDate.setHours(0); 5292 newDate.setMinutes(0); 5293 newDate.setSeconds(0); 5294 newDate.setMilliseconds(0); 5295 } 5296 return this._daylightSavingAdjust(newDate); 5297 }, 5298 5299 /* Handle switch to/from daylight saving. 5300 * Hours may be non-zero on daylight saving cut-over: 5301 * > 12 when midnight changeover, but then cannot generate 5302 * midnight datetime, so jump to 1AM, otherwise reset. 5303 * @param date (Date) the date to check 5304 * @return (Date) the corrected date 5305 */ 5306 _daylightSavingAdjust: function(date) { 5307 if (!date) { 5308 return null; 5309 } 5310 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 5311 return date; 5312 }, 5313 5314 /* Set the date(s) directly. */ 5315 _setDate: function(inst, date, noChange) { 5316 var clear = !date, 5317 origMonth = inst.selectedMonth, 5318 origYear = inst.selectedYear, 5319 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 5320 5321 inst.selectedDay = inst.currentDay = newDate.getDate(); 5322 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 5323 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 5324 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 5325 this._notifyChange(inst); 5326 } 5327 this._adjustInstDate(inst); 5328 if (inst.input) { 5329 inst.input.val(clear ? "" : this._formatDate(inst)); 5330 } 5331 }, 5332 5333 /* Retrieve the date(s) directly. */ 5334 _getDate: function(inst) { 5335 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 5336 this._daylightSavingAdjust(new Date( 5337 inst.currentYear, inst.currentMonth, inst.currentDay))); 5338 return startDate; 5339 }, 5340 5341 /* Attach the onxxx handlers. These are declared statically so 5342 * they work with static code transformers like Caja. 5343 */ 5344 _attachHandlers: function(inst) { 5345 var stepMonths = this._get(inst, "stepMonths"), 5346 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 5347 inst.dpDiv.find("[data-handler]").map(function () { 5348 var handler = { 5349 prev: function () { 5350 $.datepicker._adjustDate(id, -stepMonths, "M"); 5351 }, 5352 next: function () { 5353 $.datepicker._adjustDate(id, +stepMonths, "M"); 5354 }, 5355 hide: function () { 5356 $.datepicker._hideDatepicker(); 5357 }, 5358 today: function () { 5359 $.datepicker._gotoToday(id); 5360 }, 5361 selectDay: function () { 5362 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 5363 return false; 5364 }, 5365 selectMonth: function () { 5366 $.datepicker._selectMonthYear(id, this, "M"); 5367 return false; 5368 }, 5369 selectYear: function () { 5370 $.datepicker._selectMonthYear(id, this, "Y"); 5371 return false; 5372 } 5373 }; 5374 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 5375 }); 5376 }, 5377 5378 /* Generate the HTML for the current state of the date picker. */ 5379 _generateHTML: function(inst) { 5380 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
vendor: 21,214 bytes, lines 5381-5846
5381 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 5382 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 5383 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 5384 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 5385 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 5386 tempDate = new Date(), 5387 today = this._daylightSavingAdjust( 5388 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 5389 isRTL = this._get(inst, "isRTL"), 5390 showButtonPanel = this._get(inst, "showButtonPanel"), 5391 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 5392 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 5393 numMonths = this._getNumberOfMonths(inst), 5394 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 5395 stepMonths = this._get(inst, "stepMonths"), 5396 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 5397 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 5398 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 5399 minDate = this._getMinMaxDate(inst, "min"), 5400 maxDate = this._getMinMaxDate(inst, "max"), 5401 drawMonth = inst.drawMonth - showCurrentAtPos, 5402 drawYear = inst.drawYear; 5403 5404 if (drawMonth < 0) { 5405 drawMonth += 12; 5406 drawYear--; 5407 } 5408 if (maxDate) { 5409 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 5410 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 5411 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 5412 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 5413 drawMonth--; 5414 if (drawMonth < 0) { 5415 drawMonth = 11; 5416 drawYear--; 5417 } 5418 } 5419 } 5420 inst.drawMonth = drawMonth; 5421 inst.drawYear = drawYear; 5422 5423 prevText = this._get(inst, "prevText"); 5424 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 5425 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 5426 this._getFormatConfig(inst))); 5427 5428 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 5429 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 5430 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 5431 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); 5432 5433 nextText = this._get(inst, "nextText"); 5434 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 5435 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 5436 this._getFormatConfig(inst))); 5437 5438 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 5439 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 5440 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 5441 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); 5442 5443 currentText = this._get(inst, "currentText"); 5444 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 5445 currentText = (!navigationAsDateFormat ? currentText : 5446 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 5447 5448 controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + 5449 this._get(inst, "closeText") + "</button>" : ""); 5450 5451 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 5452 (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + 5453 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 5454 5455 firstDay = parseInt(this._get(inst, "firstDay"),10); 5456 firstDay = (isNaN(firstDay) ? 0 : firstDay); 5457 5458 showWeek = this._get(inst, "showWeek"); 5459 dayNames = this._get(inst, "dayNames"); 5460 dayNamesMin = this._get(inst, "dayNamesMin"); 5461 monthNames = this._get(inst, "monthNames"); 5462 monthNamesShort = this._get(inst, "monthNamesShort"); 5463 beforeShowDay = this._get(inst, "beforeShowDay"); 5464 showOtherMonths = this._get(inst, "showOtherMonths"); 5465 selectOtherMonths = this._get(inst, "selectOtherMonths"); 5466 defaultDate = this._getDefaultDate(inst); 5467 html = ""; 5468 dow; 5469 for (row = 0; row < numMonths[0]; row++) { 5470 group = ""; 5471 this.maxRows = 4; 5472 for (col = 0; col < numMonths[1]; col++) { 5473 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 5474 cornerClass = " ui-corner-all"; 5475 calender = ""; 5476 if (isMultiMonth) { 5477 calender += "<div class='ui-datepicker-group"; 5478 if (numMonths[1] > 1) { 5479 switch (col) { 5480 case 0: calender += " ui-datepicker-group-first"; 5481 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 5482 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 5483 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 5484 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 5485 } 5486 } 5487 calender += "'>"; 5488 } 5489 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 5490 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 5491 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 5492 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 5493 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 5494 "</div><table class='ui-datepicker-calendar'><thead>" + 5495 "<tr>"; 5496 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 5497 for (dow = 0; dow < 7; dow++) { // days of the week 5498 day = (dow + firstDay) % 7; 5499 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 5500 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 5501 } 5502 calender += thead + "</tr></thead><tbody>"; 5503 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 5504 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 5505 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 5506 } 5507 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 5508 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 5509 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 5510 this.maxRows = numRows; 5511 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 5512 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 5513 calender += "<tr>"; 5514 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 5515 this._get(inst, "calculateWeek")(printDate) + "</td>"); 5516 for (dow = 0; dow < 7; dow++) { // create date picker days 5517 daySettings = (beforeShowDay ? 5518 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 5519 otherMonth = (printDate.getMonth() !== drawMonth); 5520 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 5521 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 5522 tbody += "<td class='" + 5523 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 5524 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 5525 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 5526 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 5527 // or defaultDate is current printedDate and defaultDate is selectedDate 5528 " " + this._dayOverClass : "") + // highlight selected day 5529 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 5530 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 5531 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 5532 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 5533 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 5534 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 5535 (otherMonth && !showOtherMonths ? " " : // display for other months 5536 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 5537 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 5538 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 5539 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 5540 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 5541 printDate.setDate(printDate.getDate() + 1); 5542 printDate = this._daylightSavingAdjust(printDate); 5543 } 5544 calender += tbody + "</tr>"; 5545 } 5546 drawMonth++; 5547 if (drawMonth > 11) { 5548 drawMonth = 0; 5549 drawYear++; 5550 } 5551 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 5552 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 5553 group += calender; 5554 } 5555 html += group; 5556 } 5557 html += buttonPanel; 5558 inst._keyEvent = false; 5559 return html; 5560 }, 5561 5562 /* Generate the month and year header. */ 5563 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 5564 secondary, monthNames, monthNamesShort) { 5565 5566 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 5567 changeMonth = this._get(inst, "changeMonth"), 5568 changeYear = this._get(inst, "changeYear"), 5569 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 5570 html = "<div class='ui-datepicker-title'>", 5571 monthHtml = ""; 5572 5573 5574 // year selection 5575 if ( !inst.yearshtml ) { 5576 inst.yearshtml = ""; 5577 if (secondary || !changeYear) { 5578 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 5579 } else { 5580 // determine range of years to display 5581 years = this._get(inst, "yearRange").split(":"); 5582 thisYear = new Date().getFullYear(); 5583 determineYear = function(value) { 5584 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 5585 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 5586 parseInt(value, 10))); 5587 return (isNaN(year) ? thisYear : year); 5588 }; 5589 year = determineYear(years[0]); 5590 endYear = Math.max(year, determineYear(years[1] || "")); 5591 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 5592 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 5593 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 5594 for (; year <= endYear; year++) { 5595 inst.yearshtml += "<option value='" + year + "'" + 5596 (year === drawYear ? " selected='selected'" : "") + 5597 ">" + year + "</option>"; 5598 } 5599 inst.yearshtml += "</select>"; 5600 5601 html += inst.yearshtml; 5602 inst.yearshtml = null; 5603 } 5604 } 5605 5606 html += this._get(inst, "yearSuffix"); 5607 if (showMonthAfterYear) { 5608 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 5609 } 5610 5611 5612 // month selection 5613 if (secondary || !changeMonth) { 5614 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 5615 } else { 5616 inMinYear = (minDate && minDate.getFullYear() === drawYear); 5617 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 5618 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 5619 for ( month = 0; month < 12; month++) { 5620 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 5621 monthHtml += "<option value='" + month + "'" + 5622 (month === drawMonth ? " selected='selected'" : "") + 5623 ">" + monthNamesShort[month] + "</option>"; 5624 } 5625 } 5626 monthHtml += "</select>"; 5627 } 5628 5629 if (!showMonthAfterYear) { 5630 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 5631 } 5632 5633 5634 html += "</div>"; // Close datepicker_header 5635 return html; 5636 }, 5637 5638 /* Adjust one of the date sub-fields. */ 5639 _adjustInstDate: function(inst, offset, period) { 5640 var year = inst.drawYear + (period === "Y" ? offset : 0), 5641 month = inst.drawMonth + (period === "M" ? offset : 0), 5642 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 5643 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 5644 5645 inst.selectedDay = date.getDate(); 5646 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5647 inst.drawYear = inst.selectedYear = date.getFullYear(); 5648 if (period === "M" || period === "Y") { 5649 this._notifyChange(inst); 5650 } 5651 }, 5652 5653 /* Ensure a date is within any min/max bounds. */ 5654 _restrictMinMax: function(inst, date) { 5655 var minDate = this._getMinMaxDate(inst, "min"), 5656 maxDate = this._getMinMaxDate(inst, "max"), 5657 newDate = (minDate && date < minDate ? minDate : date); 5658 return (maxDate && newDate > maxDate ? maxDate : newDate); 5659 }, 5660 5661 /* Notify change of month/year. */ 5662 _notifyChange: function(inst) { 5663 var onChange = this._get(inst, "onChangeMonthYear"); 5664 if (onChange) { 5665 onChange.apply((inst.input ? inst.input[0] : null), 5666 [inst.selectedYear, inst.selectedMonth + 1, inst]); 5667 } 5668 }, 5669 5670 /* Determine the number of months to show. */ 5671 _getNumberOfMonths: function(inst) { 5672 var numMonths = this._get(inst, "numberOfMonths"); 5673 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 5674 }, 5675 5676 /* Determine the current maximum date - ensure no time components are set. */ 5677 _getMinMaxDate: function(inst, minMax) { 5678 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 5679 }, 5680 5681 /* Find the number of days in a given month. */ 5682 _getDaysInMonth: function(year, month) { 5683 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 5684 }, 5685 5686 /* Find the day of the week of the first of a month. */ 5687 _getFirstDayOfMonth: function(year, month) { 5688 return new Date(year, month, 1).getDay(); 5689 }, 5690 5691 /* Determines if we should allow a "next/prev" month display change. */ 5692 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 5693 var numMonths = this._getNumberOfMonths(inst), 5694 date = this._daylightSavingAdjust(new Date(curYear, 5695 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 5696 5697 if (offset < 0) { 5698 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 5699 } 5700 return this._isInRange(inst, date); 5701 }, 5702 5703 /* Is the given date in the accepted range? */ 5704 _isInRange: function(inst, date) { 5705 var yearSplit, currentYear, 5706 minDate = this._getMinMaxDate(inst, "min"), 5707 maxDate = this._getMinMaxDate(inst, "max"), 5708 minYear = null, 5709 maxYear = null, 5710 years = this._get(inst, "yearRange"); 5711 if (years){ 5712 yearSplit = years.split(":"); 5713 currentYear = new Date().getFullYear(); 5714 minYear = parseInt(yearSplit[0], 10); 5715 maxYear = parseInt(yearSplit[1], 10); 5716 if ( yearSplit[0].match(/[+\-].*/) ) { 5717 minYear += currentYear; 5718 } 5719 if ( yearSplit[1].match(/[+\-].*/) ) { 5720 maxYear += currentYear; 5721 } 5722 } 5723 5724 return ((!minDate || date.getTime() >= minDate.getTime()) && 5725 (!maxDate || date.getTime() <= maxDate.getTime()) && 5726 (!minYear || date.getFullYear() >= minYear) && 5727 (!maxYear || date.getFullYear() <= maxYear)); 5728 }, 5729 5730 /* Provide the configuration settings for formatting/parsing. */ 5731 _getFormatConfig: function(inst) { 5732 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 5733 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 5734 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 5735 return {shortYearCutoff: shortYearCutoff, 5736 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 5737 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 5738 }, 5739 5740 /* Format the given date for display. */ 5741 _formatDate: function(inst, day, month, year) { 5742 if (!day) { 5743 inst.currentDay = inst.selectedDay; 5744 inst.currentMonth = inst.selectedMonth; 5745 inst.currentYear = inst.selectedYear; 5746 } 5747 var date = (day ? (typeof day === "object" ? day : 5748 this._daylightSavingAdjust(new Date(year, month, day))) : 5749 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 5750 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 5751 } 5752}); 5753 5754/* 5755 * Bind hover events for datepicker elements. 5756 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 5757 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 5758 */ 5759function datepicker_bindHover(dpDiv) { 5760 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 5761 return dpDiv.delegate(selector, "mouseout", function() { 5762 $(this).removeClass("ui-state-hover"); 5763 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 5764 $(this).removeClass("ui-datepicker-prev-hover"); 5765 } 5766 if (this.className.indexOf("ui-datepicker-next") !== -1) { 5767 $(this).removeClass("ui-datepicker-next-hover"); 5768 } 5769 }) 5770 .delegate( selector, "mouseover", datepicker_handleMouseover ); 5771} 5772 5773function datepicker_handleMouseover() { 5774 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { 5775 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 5776 $(this).addClass("ui-state-hover"); 5777 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 5778 $(this).addClass("ui-datepicker-prev-hover"); 5779 } 5780 if (this.className.indexOf("ui-datepicker-next") !== -1) { 5781 $(this).addClass("ui-datepicker-next-hover"); 5782 } 5783 } 5784} 5785 5786/* jQuery extend now ignores nulls! */ 5787function datepicker_extendRemove(target, props) { 5788 $.extend(target, props); 5789 for (var name in props) { 5790 if (props[name] == null) { 5791 target[name] = props[name]; 5792 } 5793 } 5794 return target; 5795} 5796 5797/* Invoke the datepicker functionality. 5798 @param options string - a command, optionally followed by additional parameters or 5799 Object - settings for attaching new datepicker functionality 5800 @return jQuery object */ 5801$.fn.datepicker = function(options){ 5802 5803 /* Verify an empty collection wasn't passed - Fixes #6976 */ 5804 if ( !this.length ) { 5805 return this; 5806 } 5807 5808 /* Initialise the date picker. */ 5809 if (!$.datepicker.initialized) { 5810 $(document).mousedown($.datepicker._checkExternalClick); 5811 $.datepicker.initialized = true; 5812 } 5813 5814 /* Append datepicker main container to body if not exist. */ 5815 if ($("#"+$.datepicker._mainDivId).length === 0) { 5816 $("body").append($.datepicker.dpDiv); 5817 } 5818 5819 var otherArgs = Array.prototype.slice.call(arguments, 1); 5820 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 5821 return $.datepicker["_" + options + "Datepicker"]. 5822 apply($.datepicker, [this[0]].concat(otherArgs)); 5823 } 5824 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 5825 return $.datepicker["_" + options + "Datepicker"]. 5826 apply($.datepicker, [this[0]].concat(otherArgs)); 5827 } 5828 return this.each(function() { 5829 typeof options === "string" ? 5830 $.datepicker["_" + options + "Datepicker"]. 5831 apply($.datepicker, [this].concat(otherArgs)) : 5832 $.datepicker._attachDatepicker(this, options); 5833 }); 5834}; 5835 5836$.datepicker = new Datepicker(); // singleton instance 5837$.datepicker.initialized = false; 5838$.datepicker.uuid = new Date().getTime(); 5839$.datepicker.version = "1.11.4"; 5840 5841var datepicker = $.datepicker; 5842 5843 5844/*! 5845 * jQuery UI Draggable 1.11.4 5846 * http://jqueryui.com
vendor: 9,640 bytes, lines 5847-6199
5847 * 5848 * Copyright jQuery Foundation and other contributors 5849 * Released under the MIT license. 5850 * http://jquery.org/license 5851 * 5852 * http://api.jqueryui.com/draggable/ 5853 */ 5854 5855 5856$.widget("ui.draggable", $.ui.mouse, { 5857 version: "1.11.4", 5858 widgetEventPrefix: "drag", 5859 options: { 5860 addClasses: true, 5861 appendTo: "parent", 5862 axis: false, 5863 connectToSortable: false, 5864 containment: false, 5865 cursor: "auto", 5866 cursorAt: false, 5867 grid: false, 5868 handle: false, 5869 helper: "original", 5870 iframeFix: false, 5871 opacity: false, 5872 refreshPositions: false, 5873 revert: false, 5874 revertDuration: 500, 5875 scope: "default", 5876 scroll: true, 5877 scrollSensitivity: 20, 5878 scrollSpeed: 20, 5879 snap: false, 5880 snapMode: "both", 5881 snapTolerance: 20, 5882 stack: false, 5883 zIndex: false, 5884 5885 // callbacks 5886 drag: null, 5887 start: null, 5888 stop: null 5889 }, 5890 _create: function() { 5891 5892 if ( this.options.helper === "original" ) { 5893 this._setPositionRelative(); 5894 } 5895 if (this.options.addClasses){ 5896 this.element.addClass("ui-draggable"); 5897 } 5898 if (this.options.disabled){ 5899 this.element.addClass("ui-draggable-disabled"); 5900 } 5901 this._setHandleClassName(); 5902 5903 this._mouseInit(); 5904 }, 5905 5906 _setOption: function( key, value ) { 5907 this._super( key, value ); 5908 if ( key === "handle" ) { 5909 this._removeHandleClassName(); 5910 this._setHandleClassName(); 5911 } 5912 }, 5913 5914 _destroy: function() { 5915 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 5916 this.destroyOnClear = true; 5917 return; 5918 } 5919 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 5920 this._removeHandleClassName(); 5921 this._mouseDestroy(); 5922 }, 5923 5924 _mouseCapture: function(event) { 5925 var o = this.options; 5926 5927 this._blurActiveElement( event ); 5928 5929 // among others, prevent a drag on a resizable-handle 5930 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 5931 return false; 5932 } 5933 5934 //Quit if we're not on a valid handle 5935 this.handle = this._getHandle(event); 5936 if (!this.handle) { 5937 return false; 5938 } 5939 5940 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 5941 5942 return true; 5943 5944 }, 5945 5946 _blockFrames: function( selector ) { 5947 this.iframeBlocks = this.document.find( selector ).map(function() { 5948 var iframe = $( this ); 5949 5950 return $( "<div>" ) 5951 .css( "position", "absolute" ) 5952 .appendTo( iframe.parent() ) 5953 .outerWidth( iframe.outerWidth() ) 5954 .outerHeight( iframe.outerHeight() ) 5955 .offset( iframe.offset() )[ 0 ]; 5956 }); 5957 }, 5958 5959 _unblockFrames: function() { 5960 if ( this.iframeBlocks ) { 5961 this.iframeBlocks.remove(); 5962 delete this.iframeBlocks; 5963 } 5964 }, 5965 5966 _blurActiveElement: function( event ) { 5967 var document = this.document[ 0 ]; 5968 5969 // Only need to blur if the event occurred on the draggable itself, see #10527 5970 if ( !this.handleElement.is( event.target ) ) { 5971 return; 5972 } 5973 5974 // support: IE9 5975 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 5976 try { 5977 5978 // Support: IE9, IE10 5979 // If the <body> is blurred, IE will switch windows, see #9520 5980 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { 5981 5982 // Blur any element that currently has focus, see #4261 5983 $( document.activeElement ).blur(); 5984 } 5985 } catch ( error ) {} 5986 }, 5987 5988 _mouseStart: function(event) { 5989 5990 var o = this.options; 5991 5992 //Create and append the visible helper 5993 this.helper = this._createHelper(event); 5994 5995 this.helper.addClass("ui-draggable-dragging"); 5996 5997 //Cache the helper size 5998 this._cacheHelperProportions(); 5999 6000 //If ddmanager is used for droppables, set the global draggable 6001 if ($.ui.ddmanager) { 6002 $.ui.ddmanager.current = this; 6003 } 6004 6005 /* 6006 * - Position generation - 6007 * This block generates everything position related - it's the core of draggables. 6008 */ 6009 6010 //Cache the margins of the original element 6011 this._cacheMargins(); 6012 6013 //Store the helper's css position 6014 this.cssPosition = this.helper.css( "position" ); 6015 this.scrollParent = this.helper.scrollParent( true ); 6016 this.offsetParent = this.helper.offsetParent(); 6017 this.hasFixedAncestor = this.helper.parents().filter(function() { 6018 return $( this ).css( "position" ) === "fixed"; 6019 }).length > 0; 6020 6021 //The element's absolute position on the page minus margins 6022 this.positionAbs = this.element.offset(); 6023 this._refreshOffsets( event ); 6024 6025 //Generate the original position 6026 this.originalPosition = this.position = this._generatePosition( event, false ); 6027 this.originalPageX = event.pageX; 6028 this.originalPageY = event.pageY; 6029 6030 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 6031 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 6032 6033 //Set a containment if given in the options 6034 this._setContainment(); 6035 6036 //Trigger event + callbacks 6037 if (this._trigger("start", event) === false) { 6038 this._clear(); 6039 return false; 6040 } 6041 6042 //Recache the helper size 6043 this._cacheHelperProportions(); 6044 6045 //Prepare the droppable offsets 6046 if ($.ui.ddmanager && !o.dropBehaviour) { 6047 $.ui.ddmanager.prepareOffsets(this, event); 6048 } 6049 6050 // Reset helper's right/bottom css if they're set and set explicit width/height instead 6051 // as this prevents resizing of elements with right/bottom set (see #7772) 6052 this._normalizeRightBottom(); 6053 6054 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 6055 6056 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 6057 if ( $.ui.ddmanager ) { 6058 $.ui.ddmanager.dragStart(this, event); 6059 } 6060 6061 return true; 6062 }, 6063 6064 _refreshOffsets: function( event ) { 6065 this.offset = { 6066 top: this.positionAbs.top - this.margins.top, 6067 left: this.positionAbs.left - this.margins.left, 6068 scroll: false, 6069 parent: this._getParentOffset(), 6070 relative: this._getRelativeOffset() 6071 }; 6072 6073 this.offset.click = { 6074 left: event.pageX - this.offset.left, 6075 top: event.pageY - this.offset.top 6076 }; 6077 }, 6078 6079 _mouseDrag: function(event, noPropagation) { 6080 // reset any necessary cached properties (see #5009) 6081 if ( this.hasFixedAncestor ) { 6082 this.offset.parent = this._getParentOffset(); 6083 } 6084 6085 //Compute the helpers position 6086 this.position = this._generatePosition( event, true ); 6087 this.positionAbs = this._convertPositionTo("absolute"); 6088 6089 //Call plugins and callbacks and use the resulting position if something is returned 6090 if (!noPropagation) { 6091 var ui = this._uiHash(); 6092 if (this._trigger("drag", event, ui) === false) { 6093 this._mouseUp({}); 6094 return false; 6095 } 6096 this.position = ui.position; 6097 } 6098 6099 this.helper[ 0 ].style.left = this.position.left + "px"; 6100 this.helper[ 0 ].style.top = this.position.top + "px"; 6101 6102 if ($.ui.ddmanager) { 6103 $.ui.ddmanager.drag(this, event); 6104 } 6105 6106 return false; 6107 }, 6108 6109 _mouseStop: function(event) { 6110 6111 //If we are using droppables, inform the manager about the drop 6112 var that = this, 6113 dropped = false; 6114 if ($.ui.ddmanager && !this.options.dropBehaviour) { 6115 dropped = $.ui.ddmanager.drop(this, event); 6116 } 6117 6118 //if a drop comes from outside (a sortable) 6119 if (this.dropped) { 6120 dropped = this.dropped; 6121 this.dropped = false; 6122 } 6123 6124 if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { 6125 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 6126 if (that._trigger("stop", event) !== false) { 6127 that._clear(); 6128 } 6129 }); 6130 } else { 6131 if (this._trigger("stop", event) !== false) { 6132 this._clear(); 6133 } 6134 } 6135 6136 return false; 6137 }, 6138 6139 _mouseUp: function( event ) { 6140 this._unblockFrames(); 6141 6142 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 6143 if ( $.ui.ddmanager ) { 6144 $.ui.ddmanager.dragStop(this, event); 6145 } 6146 6147 // Only need to focus if the event occurred on the draggable itself, see #10527 6148 if ( this.handleElement.is( event.target ) ) { 6149 // The interaction is over; whether or not the click resulted in a drag, focus the element 6150 this.element.focus(); 6151 } 6152 6153 return $.ui.mouse.prototype._mouseUp.call(this, event); 6154 }, 6155 6156 cancel: function() { 6157 6158 if (this.helper.is(".ui-draggable-dragging")) { 6159 this._mouseUp({}); 6160 } else { 6161 this._clear(); 6162 } 6163 6164 return this; 6165 6166 }, 6167 6168 _getHandle: function(event) { 6169 return this.options.handle ? 6170 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 6171 true; 6172 }, 6173 6174 _setHandleClassName: function() { 6175 this.handleElement = this.options.handle ? 6176 this.element.find( this.options.handle ) : this.element; 6177 this.handleElement.addClass( "ui-draggable-handle" ); 6178 }, 6179 6180 _removeHandleClassName: function() { 6181 this.handleElement.removeClass( "ui-draggable-handle" ); 6182 }, 6183 6184 _createHelper: function(event) { 6185 6186 var o = this.options, 6187 helperIsFunction = $.isFunction( o.helper ), 6188 helper = helperIsFunction ? 6189 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 6190 ( o.helper === "clone" ? 6191 this.element.clone().removeAttr( "id" ) : 6192 this.element ); 6193 6194 if (!helper.parents("body").length) { 6195 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 6196 } 6197 6198 // http://bugs.jqueryui.com/ticket/9446 6199 // a helper function can return the original element
vendor: 4,479 bytes, lines 6200-6334
6200 // which wouldn't have been set to relative in _create 6201 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 6202 this._setPositionRelative(); 6203 } 6204 6205 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 6206 helper.css("position", "absolute"); 6207 } 6208 6209 return helper; 6210 6211 }, 6212 6213 _setPositionRelative: function() { 6214 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 6215 this.element[ 0 ].style.position = "relative"; 6216 } 6217 }, 6218 6219 _adjustOffsetFromHelper: function(obj) { 6220 if (typeof obj === "string") { 6221 obj = obj.split(" "); 6222 } 6223 if ($.isArray(obj)) { 6224 obj = { left: +obj[0], top: +obj[1] || 0 }; 6225 } 6226 if ("left" in obj) { 6227 this.offset.click.left = obj.left + this.margins.left; 6228 } 6229 if ("right" in obj) { 6230 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6231 } 6232 if ("top" in obj) { 6233 this.offset.click.top = obj.top + this.margins.top; 6234 } 6235 if ("bottom" in obj) { 6236 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6237 } 6238 }, 6239 6240 _isRootNode: function( element ) { 6241 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 6242 }, 6243 6244 _getParentOffset: function() { 6245 6246 //Get the offsetParent and cache its position 6247 var po = this.offsetParent.offset(), 6248 document = this.document[ 0 ]; 6249 6250 // This is a special case where we need to modify a offset calculated on start, since the following happened: 6251 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 6252 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 6253 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 6254 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 6255 po.left += this.scrollParent.scrollLeft(); 6256 po.top += this.scrollParent.scrollTop(); 6257 } 6258 6259 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 6260 po = { top: 0, left: 0 }; 6261 } 6262 6263 return { 6264 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 6265 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 6266 }; 6267 6268 }, 6269 6270 _getRelativeOffset: function() { 6271 if ( this.cssPosition !== "relative" ) { 6272 return { top: 0, left: 0 }; 6273 } 6274 6275 var p = this.element.position(), 6276 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6277 6278 return { 6279 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 6280 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 6281 }; 6282 6283 }, 6284 6285 _cacheMargins: function() { 6286 this.margins = { 6287 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 6288 top: (parseInt(this.element.css("marginTop"), 10) || 0), 6289 right: (parseInt(this.element.css("marginRight"), 10) || 0), 6290 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 6291 }; 6292 }, 6293 6294 _cacheHelperProportions: function() { 6295 this.helperProportions = { 6296 width: this.helper.outerWidth(), 6297 height: this.helper.outerHeight() 6298 }; 6299 }, 6300 6301 _setContainment: function() { 6302 6303 var isUserScrollable, c, ce, 6304 o = this.options, 6305 document = this.document[ 0 ]; 6306 6307 this.relativeContainer = null; 6308 6309 if ( !o.containment ) { 6310 this.containment = null; 6311 return; 6312 } 6313 6314 if ( o.containment === "window" ) { 6315 this.containment = [ 6316 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 6317 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 6318 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 6319 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6320 ]; 6321 return; 6322 } 6323 6324 if ( o.containment === "document") { 6325 this.containment = [ 6326 0, 6327 0, 6328 $( document ).width() - this.helperProportions.width - this.margins.left, 6329 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6330 ]; 6331 return; 6332 } 6333 6334 if ( o.containment.constructor === Array ) {
vendor: 6,831 bytes, lines 6335-6513
6335 this.containment = o.containment; 6336 return; 6337 } 6338 6339 if ( o.containment === "parent" ) { 6340 o.containment = this.helper[ 0 ].parentNode; 6341 } 6342 6343 c = $( o.containment ); 6344 ce = c[ 0 ]; 6345 6346 if ( !ce ) { 6347 return; 6348 } 6349 6350 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 6351 6352 this.containment = [ 6353 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 6354 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 6355 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 6356 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 6357 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 6358 this.helperProportions.width - 6359 this.margins.left - 6360 this.margins.right, 6361 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 6362 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 6363 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 6364 this.helperProportions.height - 6365 this.margins.top - 6366 this.margins.bottom 6367 ]; 6368 this.relativeContainer = c; 6369 }, 6370 6371 _convertPositionTo: function(d, pos) { 6372 6373 if (!pos) { 6374 pos = this.position; 6375 } 6376 6377 var mod = d === "absolute" ? 1 : -1, 6378 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6379 6380 return { 6381 top: ( 6382 pos.top + // The absolute mouse position 6383 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6384 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 6385 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) 6386 ), 6387 left: ( 6388 pos.left + // The absolute mouse position 6389 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6390 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 6391 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) 6392 ) 6393 }; 6394 6395 }, 6396 6397 _generatePosition: function( event, constrainPosition ) { 6398 6399 var containment, co, top, left, 6400 o = this.options, 6401 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 6402 pageX = event.pageX, 6403 pageY = event.pageY; 6404 6405 // Cache the scroll 6406 if ( !scrollIsRootNode || !this.offset.scroll ) { 6407 this.offset.scroll = { 6408 top: this.scrollParent.scrollTop(), 6409 left: this.scrollParent.scrollLeft() 6410 }; 6411 } 6412 6413 /* 6414 * - Position constraining - 6415 * Constrain the position to a mix of grid, containment. 6416 */ 6417 6418 // If we are not dragging yet, we won't check for options 6419 if ( constrainPosition ) { 6420 if ( this.containment ) { 6421 if ( this.relativeContainer ){ 6422 co = this.relativeContainer.offset(); 6423 containment = [ 6424 this.containment[ 0 ] + co.left, 6425 this.containment[ 1 ] + co.top, 6426 this.containment[ 2 ] + co.left, 6427 this.containment[ 3 ] + co.top 6428 ]; 6429 } else { 6430 containment = this.containment; 6431 } 6432 6433 if (event.pageX - this.offset.click.left < containment[0]) { 6434 pageX = containment[0] + this.offset.click.left; 6435 } 6436 if (event.pageY - this.offset.click.top < containment[1]) { 6437 pageY = containment[1] + this.offset.click.top; 6438 } 6439 if (event.pageX - this.offset.click.left > containment[2]) { 6440 pageX = containment[2] + this.offset.click.left; 6441 } 6442 if (event.pageY - this.offset.click.top > containment[3]) { 6443 pageY = containment[3] + this.offset.click.top; 6444 } 6445 } 6446 6447 if (o.grid) { 6448 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 6449 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 6450 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 6451 6452 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 6453 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 6454 } 6455 6456 if ( o.axis === "y" ) { 6457 pageX = this.originalPageX; 6458 } 6459 6460 if ( o.axis === "x" ) { 6461 pageY = this.originalPageY; 6462 } 6463 } 6464 6465 return { 6466 top: ( 6467 pageY - // The absolute mouse position 6468 this.offset.click.top - // Click offset (relative to the element) 6469 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 6470 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 6471 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 6472 ), 6473 left: ( 6474 pageX - // The absolute mouse position 6475 this.offset.click.left - // Click offset (relative to the element) 6476 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 6477 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 6478 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 6479 ) 6480 }; 6481 6482 }, 6483 6484 _clear: function() { 6485 this.helper.removeClass("ui-draggable-dragging"); 6486 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 6487 this.helper.remove(); 6488 } 6489 this.helper = null; 6490 this.cancelHelperRemoval = false; 6491 if ( this.destroyOnClear ) { 6492 this.destroy(); 6493 } 6494 }, 6495 6496 _normalizeRightBottom: function() { 6497 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { 6498 this.helper.width( this.helper.width() ); 6499 this.helper.css( "right", "auto" ); 6500 } 6501 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { 6502 this.helper.height( this.helper.height() ); 6503 this.helper.css( "bottom", "auto" ); 6504 } 6505 }, 6506 6507 // From now on bulk stuff - mainly helpers 6508 6509 _trigger: function( type, event, ui ) { 6510 ui = ui || this._uiHash(); 6511 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 6512 6513 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
vendor: 4,077 bytes, lines 6514-6638
6514 if ( /^(drag|start|stop)/.test( type ) ) { 6515 this.positionAbs = this._convertPositionTo( "absolute" ); 6516 ui.offset = this.positionAbs; 6517 } 6518 return $.Widget.prototype._trigger.call( this, type, event, ui ); 6519 }, 6520 6521 plugins: {}, 6522 6523 _uiHash: function() { 6524 return { 6525 helper: this.helper, 6526 position: this.position, 6527 originalPosition: this.originalPosition, 6528 offset: this.positionAbs 6529 }; 6530 } 6531 6532}); 6533 6534$.ui.plugin.add( "draggable", "connectToSortable", { 6535 start: function( event, ui, draggable ) { 6536 var uiSortable = $.extend( {}, ui, { 6537 item: draggable.element 6538 }); 6539 6540 draggable.sortables = []; 6541 $( draggable.options.connectToSortable ).each(function() { 6542 var sortable = $( this ).sortable( "instance" ); 6543 6544 if ( sortable && !sortable.options.disabled ) { 6545 draggable.sortables.push( sortable ); 6546 6547 // refreshPositions is called at drag start to refresh the containerCache 6548 // which is used in drag. This ensures it's initialized and synchronized 6549 // with any changes that might have happened on the page since initialization. 6550 sortable.refreshPositions(); 6551 sortable._trigger("activate", event, uiSortable); 6552 } 6553 }); 6554 }, 6555 stop: function( event, ui, draggable ) { 6556 var uiSortable = $.extend( {}, ui, { 6557 item: draggable.element 6558 }); 6559 6560 draggable.cancelHelperRemoval = false; 6561 6562 $.each( draggable.sortables, function() { 6563 var sortable = this; 6564 6565 if ( sortable.isOver ) { 6566 sortable.isOver = 0; 6567 6568 // Allow this sortable to handle removing the helper 6569 draggable.cancelHelperRemoval = true; 6570 sortable.cancelHelperRemoval = false; 6571 6572 // Use _storedCSS To restore properties in the sortable, 6573 // as this also handles revert (#9675) since the draggable 6574 // may have modified them in unexpected ways (#8809) 6575 sortable._storedCSS = { 6576 position: sortable.placeholder.css( "position" ), 6577 top: sortable.placeholder.css( "top" ), 6578 left: sortable.placeholder.css( "left" ) 6579 }; 6580 6581 sortable._mouseStop(event); 6582 6583 // Once drag has ended, the sortable should return to using 6584 // its original helper, not the shared helper from draggable 6585 sortable.options.helper = sortable.options._helper; 6586 } else { 6587 // Prevent this Sortable from removing the helper. 6588 // However, don't set the draggable to remove the helper 6589 // either as another connected Sortable may yet handle the removal. 6590 sortable.cancelHelperRemoval = true; 6591 6592 sortable._trigger( "deactivate", event, uiSortable ); 6593 } 6594 }); 6595 }, 6596 drag: function( event, ui, draggable ) { 6597 $.each( draggable.sortables, function() { 6598 var innermostIntersecting = false, 6599 sortable = this; 6600 6601 // Copy over variables that sortable's _intersectsWith uses 6602 sortable.positionAbs = draggable.positionAbs; 6603 sortable.helperProportions = draggable.helperProportions; 6604 sortable.offset.click = draggable.offset.click; 6605 6606 if ( sortable._intersectsWith( sortable.containerCache ) ) { 6607 innermostIntersecting = true; 6608 6609 $.each( draggable.sortables, function() { 6610 // Copy over variables that sortable's _intersectsWith uses 6611 this.positionAbs = draggable.positionAbs; 6612 this.helperProportions = draggable.helperProportions; 6613 this.offset.click = draggable.offset.click; 6614 6615 if ( this !== sortable && 6616 this._intersectsWith( this.containerCache ) && 6617 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 6618 innermostIntersecting = false; 6619 } 6620 6621 return innermostIntersecting; 6622 }); 6623 } 6624 6625 if ( innermostIntersecting ) { 6626 // If it intersects, we use a little isOver variable and set it once, 6627 // so that the move-in stuff gets fired only once. 6628 if ( !sortable.isOver ) { 6629 sortable.isOver = 1; 6630 6631 // Store draggable's parent in case we need to reappend to it later. 6632 draggable._parent = ui.helper.parent(); 6633 6634 sortable.currentItem = ui.helper 6635 .appendTo( sortable.element ) 6636 .data( "ui-sortable-item", true ); 6637 6638 // Store helper option to later restore it
vendor: 21,599 bytes, lines 6639-7389
6639 sortable.options._helper = sortable.options.helper; 6640 6641 sortable.options.helper = function() { 6642 return ui.helper[ 0 ]; 6643 }; 6644 6645 // Fire the start events of the sortable with our passed browser event, 6646 // and our own helper (so it doesn't create a new one) 6647 event.target = sortable.currentItem[ 0 ]; 6648 sortable._mouseCapture( event, true ); 6649 sortable._mouseStart( event, true, true ); 6650 6651 // Because the browser event is way off the new appended portlet, 6652 // modify necessary variables to reflect the changes 6653 sortable.offset.click.top = draggable.offset.click.top; 6654 sortable.offset.click.left = draggable.offset.click.left; 6655 sortable.offset.parent.left -= draggable.offset.parent.left - 6656 sortable.offset.parent.left; 6657 sortable.offset.parent.top -= draggable.offset.parent.top - 6658 sortable.offset.parent.top; 6659 6660 draggable._trigger( "toSortable", event ); 6661 6662 // Inform draggable that the helper is in a valid drop zone, 6663 // used solely in the revert option to handle "valid/invalid". 6664 draggable.dropped = sortable.element; 6665 6666 // Need to refreshPositions of all sortables in the case that 6667 // adding to one sortable changes the location of the other sortables (#9675) 6668 $.each( draggable.sortables, function() { 6669 this.refreshPositions(); 6670 }); 6671 6672 // hack so receive/update callbacks work (mostly) 6673 draggable.currentItem = draggable.element; 6674 sortable.fromOutside = draggable; 6675 } 6676 6677 if ( sortable.currentItem ) { 6678 sortable._mouseDrag( event ); 6679 // Copy the sortable's position because the draggable's can potentially reflect 6680 // a relative position, while sortable is always absolute, which the dragged 6681 // element has now become. (#8809) 6682 ui.position = sortable.position; 6683 } 6684 } else { 6685 // If it doesn't intersect with the sortable, and it intersected before, 6686 // we fake the drag stop of the sortable, but make sure it doesn't remove 6687 // the helper by using cancelHelperRemoval. 6688 if ( sortable.isOver ) { 6689 6690 sortable.isOver = 0; 6691 sortable.cancelHelperRemoval = true; 6692 6693 // Calling sortable's mouseStop would trigger a revert, 6694 // so revert must be temporarily false until after mouseStop is called. 6695 sortable.options._revert = sortable.options.revert; 6696 sortable.options.revert = false; 6697 6698 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 6699 sortable._mouseStop( event, true ); 6700 6701 // restore sortable behaviors that were modfied 6702 // when the draggable entered the sortable area (#9481) 6703 sortable.options.revert = sortable.options._revert; 6704 sortable.options.helper = sortable.options._helper; 6705 6706 if ( sortable.placeholder ) { 6707 sortable.placeholder.remove(); 6708 } 6709 6710 // Restore and recalculate the draggable's offset considering the sortable 6711 // may have modified them in unexpected ways. (#8809, #10669) 6712 ui.helper.appendTo( draggable._parent ); 6713 draggable._refreshOffsets( event ); 6714 ui.position = draggable._generatePosition( event, true ); 6715 6716 draggable._trigger( "fromSortable", event ); 6717 6718 // Inform draggable that the helper is no longer in a valid drop zone 6719 draggable.dropped = false; 6720 6721 // Need to refreshPositions of all sortables just in case removing 6722 // from one sortable changes the location of other sortables (#9675) 6723 $.each( draggable.sortables, function() { 6724 this.refreshPositions(); 6725 }); 6726 } 6727 } 6728 }); 6729 } 6730}); 6731 6732$.ui.plugin.add("draggable", "cursor", { 6733 start: function( event, ui, instance ) { 6734 var t = $( "body" ), 6735 o = instance.options; 6736 6737 if (t.css("cursor")) { 6738 o._cursor = t.css("cursor"); 6739 } 6740 t.css("cursor", o.cursor); 6741 }, 6742 stop: function( event, ui, instance ) { 6743 var o = instance.options; 6744 if (o._cursor) { 6745 $("body").css("cursor", o._cursor); 6746 } 6747 } 6748}); 6749 6750$.ui.plugin.add("draggable", "opacity", { 6751 start: function( event, ui, instance ) { 6752 var t = $( ui.helper ), 6753 o = instance.options; 6754 if (t.css("opacity")) { 6755 o._opacity = t.css("opacity"); 6756 } 6757 t.css("opacity", o.opacity); 6758 }, 6759 stop: function( event, ui, instance ) { 6760 var o = instance.options; 6761 if (o._opacity) { 6762 $(ui.helper).css("opacity", o._opacity); 6763 } 6764 } 6765}); 6766 6767$.ui.plugin.add("draggable", "scroll", { 6768 start: function( event, ui, i ) { 6769 if ( !i.scrollParentNotHidden ) { 6770 i.scrollParentNotHidden = i.helper.scrollParent( false ); 6771 } 6772 6773 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 6774 i.overflowOffset = i.scrollParentNotHidden.offset(); 6775 } 6776 }, 6777 drag: function( event, ui, i ) { 6778 6779 var o = i.options, 6780 scrolled = false, 6781 scrollParent = i.scrollParentNotHidden[ 0 ], 6782 document = i.document[ 0 ]; 6783 6784 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 6785 if ( !o.axis || o.axis !== "x" ) { 6786 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { 6787 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 6788 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 6789 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 6790 } 6791 } 6792 6793 if ( !o.axis || o.axis !== "y" ) { 6794 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { 6795 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 6796 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 6797 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 6798 } 6799 } 6800 6801 } else { 6802 6803 if (!o.axis || o.axis !== "x") { 6804 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 6805 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 6806 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 6807 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 6808 } 6809 } 6810 6811 if (!o.axis || o.axis !== "y") { 6812 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 6813 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 6814 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 6815 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 6816 } 6817 } 6818 6819 } 6820 6821 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 6822 $.ui.ddmanager.prepareOffsets(i, event); 6823 } 6824 6825 } 6826}); 6827 6828$.ui.plugin.add("draggable", "snap", { 6829 start: function( event, ui, i ) { 6830 6831 var o = i.options; 6832 6833 i.snapElements = []; 6834 6835 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 6836 var $t = $(this), 6837 $o = $t.offset(); 6838 if (this !== i.element[0]) { 6839 i.snapElements.push({ 6840 item: this, 6841 width: $t.outerWidth(), height: $t.outerHeight(), 6842 top: $o.top, left: $o.left 6843 }); 6844 } 6845 }); 6846 6847 }, 6848 drag: function( event, ui, inst ) { 6849 6850 var ts, bs, ls, rs, l, r, t, b, i, first, 6851 o = inst.options, 6852 d = o.snapTolerance, 6853 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 6854 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 6855 6856 for (i = inst.snapElements.length - 1; i >= 0; i--){ 6857 6858 l = inst.snapElements[i].left - inst.margins.left; 6859 r = l + inst.snapElements[i].width; 6860 t = inst.snapElements[i].top - inst.margins.top; 6861 b = t + inst.snapElements[i].height; 6862 6863 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 6864 if (inst.snapElements[i].snapping) { 6865 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6866 } 6867 inst.snapElements[i].snapping = false; 6868 continue; 6869 } 6870 6871 if (o.snapMode !== "inner") { 6872 ts = Math.abs(t - y2) <= d; 6873 bs = Math.abs(b - y1) <= d; 6874 ls = Math.abs(l - x2) <= d; 6875 rs = Math.abs(r - x1) <= d; 6876 if (ts) { 6877 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; 6878 } 6879 if (bs) { 6880 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; 6881 } 6882 if (ls) { 6883 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; 6884 } 6885 if (rs) { 6886 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; 6887 } 6888 } 6889 6890 first = (ts || bs || ls || rs); 6891 6892 if (o.snapMode !== "outer") { 6893 ts = Math.abs(t - y1) <= d; 6894 bs = Math.abs(b - y2) <= d; 6895 ls = Math.abs(l - x1) <= d; 6896 rs = Math.abs(r - x2) <= d; 6897 if (ts) { 6898 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; 6899 } 6900 if (bs) { 6901 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; 6902 } 6903 if (ls) { 6904 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; 6905 } 6906 if (rs) { 6907 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; 6908 } 6909 } 6910 6911 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 6912 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6913 } 6914 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 6915 6916 } 6917 6918 } 6919}); 6920 6921$.ui.plugin.add("draggable", "stack", { 6922 start: function( event, ui, instance ) { 6923 var min, 6924 o = instance.options, 6925 group = $.makeArray($(o.stack)).sort(function(a, b) { 6926 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 6927 }); 6928 6929 if (!group.length) { return; } 6930 6931 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 6932 $(group).each(function(i) { 6933 $(this).css("zIndex", min + i); 6934 }); 6935 this.css("zIndex", (min + group.length)); 6936 } 6937}); 6938 6939$.ui.plugin.add("draggable", "zIndex", { 6940 start: function( event, ui, instance ) { 6941 var t = $( ui.helper ), 6942 o = instance.options; 6943 6944 if (t.css("zIndex")) { 6945 o._zIndex = t.css("zIndex"); 6946 } 6947 t.css("zIndex", o.zIndex); 6948 }, 6949 stop: function( event, ui, instance ) { 6950 var o = instance.options; 6951 6952 if (o._zIndex) { 6953 $(ui.helper).css("zIndex", o._zIndex); 6954 } 6955 } 6956}); 6957 6958var draggable = $.ui.draggable; 6959 6960 6961/*! 6962 * jQuery UI Resizable 1.11.4 6963 * http://jqueryui.com 6964 * 6965 * Copyright jQuery Foundation and other contributors 6966 * Released under the MIT license. 6967 * http://jquery.org/license 6968 * 6969 * http://api.jqueryui.com/resizable/ 6970 */ 6971 6972 6973$.widget("ui.resizable", $.ui.mouse, { 6974 version: "1.11.4", 6975 widgetEventPrefix: "resize", 6976 options: { 6977 alsoResize: false, 6978 animate: false, 6979 animateDuration: "slow", 6980 animateEasing: "swing", 6981 aspectRatio: false, 6982 autoHide: false, 6983 containment: false, 6984 ghost: false, 6985 grid: false, 6986 handles: "e,s,se", 6987 helper: false, 6988 maxHeight: null, 6989 maxWidth: null, 6990 minHeight: 10, 6991 minWidth: 10, 6992 // See #7960 6993 zIndex: 90, 6994 6995 // callbacks 6996 resize: null, 6997 start: null, 6998 stop: null 6999 }, 7000 7001 _num: function( value ) { 7002 return parseInt( value, 10 ) || 0; 7003 }, 7004 7005 _isNumber: function( value ) { 7006 return !isNaN( parseInt( value, 10 ) ); 7007 }, 7008 7009 _hasScroll: function( el, a ) { 7010 7011 if ( $( el ).css( "overflow" ) === "hidden") { 7012 return false; 7013 } 7014 7015 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 7016 has = false; 7017 7018 if ( el[ scroll ] > 0 ) { 7019 return true; 7020 } 7021 7022 // TODO: determine which cases actually cause this to happen 7023 // if the element doesn't have the scroll set, see if it's possible to 7024 // set the scroll 7025 el[ scroll ] = 1; 7026 has = ( el[ scroll ] > 0 ); 7027 el[ scroll ] = 0; 7028 return has; 7029 }, 7030 7031 _create: function() { 7032 7033 var n, i, handle, axis, hname, 7034 that = this, 7035 o = this.options; 7036 this.element.addClass("ui-resizable"); 7037 7038 $.extend(this, { 7039 _aspectRatio: !!(o.aspectRatio), 7040 aspectRatio: o.aspectRatio, 7041 originalElement: this.element, 7042 _proportionallyResizeElements: [], 7043 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 7044 }); 7045 7046 // Wrap the element if it cannot hold child nodes 7047 if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) { 7048 7049 this.element.wrap( 7050 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 7051 position: this.element.css("position"), 7052 width: this.element.outerWidth(), 7053 height: this.element.outerHeight(), 7054 top: this.element.css("top"), 7055 left: this.element.css("left") 7056 }) 7057 ); 7058 7059 this.element = this.element.parent().data( 7060 "ui-resizable", this.element.resizable( "instance" ) 7061 ); 7062 7063 this.elementIsWrapper = true; 7064 7065 this.element.css({ 7066 marginLeft: this.originalElement.css("marginLeft"), 7067 marginTop: this.originalElement.css("marginTop"), 7068 marginRight: this.originalElement.css("marginRight"), 7069 marginBottom: this.originalElement.css("marginBottom") 7070 }); 7071 this.originalElement.css({ 7072 marginLeft: 0, 7073 marginTop: 0, 7074 marginRight: 0, 7075 marginBottom: 0 7076 }); 7077 // support: Safari 7078 // Prevent Safari textarea resize 7079 this.originalResizeStyle = this.originalElement.css("resize"); 7080 this.originalElement.css("resize", "none"); 7081 7082 this._proportionallyResizeElements.push( this.originalElement.css({ 7083 position: "static", 7084 zoom: 1, 7085 display: "block" 7086 }) ); 7087 7088 // support: IE9 7089 // avoid IE jump (hard set the margin) 7090 this.originalElement.css({ margin: this.originalElement.css("margin") }); 7091 7092 this._proportionallyResize(); 7093 } 7094 7095 this.handles = o.handles || 7096 ( !$(".ui-resizable-handle", this.element).length ? 7097 "e,s,se" : { 7098 n: ".ui-resizable-n", 7099 e: ".ui-resizable-e", 7100 s: ".ui-resizable-s", 7101 w: ".ui-resizable-w", 7102 se: ".ui-resizable-se", 7103 sw: ".ui-resizable-sw", 7104 ne: ".ui-resizable-ne", 7105 nw: ".ui-resizable-nw" 7106 } ); 7107 7108 this._handles = $(); 7109 if ( this.handles.constructor === String ) { 7110 7111 if ( this.handles === "all") { 7112 this.handles = "n,e,s,w,se,sw,ne,nw"; 7113 } 7114 7115 n = this.handles.split(","); 7116 this.handles = {}; 7117 7118 for (i = 0; i < n.length; i++) { 7119 7120 handle = $.trim(n[i]); 7121 hname = "ui-resizable-" + handle; 7122 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 7123 7124 axis.css({ zIndex: o.zIndex }); 7125 7126 // TODO : What's going on here? 7127 if ("se" === handle) { 7128 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 7129 } 7130 7131 this.handles[handle] = ".ui-resizable-" + handle; 7132 this.element.append(axis); 7133 } 7134 7135 } 7136 7137 this._renderAxis = function(target) { 7138 7139 var i, axis, padPos, padWrapper; 7140 7141 target = target || this.element; 7142 7143 for (i in this.handles) { 7144 7145 if (this.handles[i].constructor === String) { 7146 this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); 7147 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 7148 this.handles[ i ] = $( this.handles[ i ] ); 7149 this._on( this.handles[ i ], { "mousedown": that._mouseDown }); 7150 } 7151 7152 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) { 7153 7154 axis = $(this.handles[i], this.element); 7155 7156 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 7157 7158 padPos = [ "padding", 7159 /ne|nw|n/.test(i) ? "Top" : 7160 /se|sw|s/.test(i) ? "Bottom" : 7161 /^e$/.test(i) ? "Right" : "Left" ].join(""); 7162 7163 target.css(padPos, padWrapper); 7164 7165 this._proportionallyResize(); 7166 } 7167 7168 this._handles = this._handles.add( this.handles[ i ] ); 7169 } 7170 }; 7171 7172 // TODO: make renderAxis a prototype function 7173 this._renderAxis(this.element); 7174 7175 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 7176 this._handles.disableSelection(); 7177 7178 this._handles.mouseover(function() { 7179 if (!that.resizing) { 7180 if (this.className) { 7181 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 7182 } 7183 that.axis = axis && axis[1] ? axis[1] : "se"; 7184 } 7185 }); 7186 7187 if (o.autoHide) { 7188 this._handles.hide(); 7189 $(this.element) 7190 .addClass("ui-resizable-autohide") 7191 .mouseenter(function() { 7192 if (o.disabled) { 7193 return; 7194 } 7195 $(this).removeClass("ui-resizable-autohide"); 7196 that._handles.show(); 7197 }) 7198 .mouseleave(function() { 7199 if (o.disabled) { 7200 return; 7201 } 7202 if (!that.resizing) { 7203 $(this).addClass("ui-resizable-autohide"); 7204 that._handles.hide(); 7205 } 7206 }); 7207 } 7208 7209 this._mouseInit(); 7210 }, 7211 7212 _destroy: function() { 7213 7214 this._mouseDestroy(); 7215 7216 var wrapper, 7217 _destroy = function(exp) { 7218 $(exp) 7219 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 7220 .removeData("resizable") 7221 .removeData("ui-resizable") 7222 .unbind(".resizable") 7223 .find(".ui-resizable-handle") 7224 .remove(); 7225 }; 7226 7227 // TODO: Unwrap at same DOM position 7228 if (this.elementIsWrapper) { 7229 _destroy(this.element); 7230 wrapper = this.element; 7231 this.originalElement.css({ 7232 position: wrapper.css("position"), 7233 width: wrapper.outerWidth(), 7234 height: wrapper.outerHeight(), 7235 top: wrapper.css("top"), 7236 left: wrapper.css("left") 7237 }).insertAfter( wrapper ); 7238 wrapper.remove(); 7239 } 7240 7241 this.originalElement.css("resize", this.originalResizeStyle); 7242 _destroy(this.originalElement); 7243 7244 return this; 7245 }, 7246 7247 _mouseCapture: function(event) { 7248 var i, handle, 7249 capture = false; 7250 7251 for (i in this.handles) { 7252 handle = $(this.handles[i])[0]; 7253 if (handle === event.target || $.contains(handle, event.target)) { 7254 capture = true; 7255 } 7256 } 7257 7258 return !this.options.disabled && capture; 7259 }, 7260 7261 _mouseStart: function(event) { 7262 7263 var curleft, curtop, cursor, 7264 o = this.options, 7265 el = this.element; 7266 7267 this.resizing = true; 7268 7269 this._renderProxy(); 7270 7271 curleft = this._num(this.helper.css("left")); 7272 curtop = this._num(this.helper.css("top")); 7273 7274 if (o.containment) { 7275 curleft += $(o.containment).scrollLeft() || 0; 7276 curtop += $(o.containment).scrollTop() || 0; 7277 } 7278 7279 this.offset = this.helper.offset(); 7280 this.position = { left: curleft, top: curtop }; 7281 7282 this.size = this._helper ? { 7283 width: this.helper.width(), 7284 height: this.helper.height() 7285 } : { 7286 width: el.width(), 7287 height: el.height() 7288 }; 7289 7290 this.originalSize = this._helper ? { 7291 width: el.outerWidth(), 7292 height: el.outerHeight() 7293 } : { 7294 width: el.width(), 7295 height: el.height() 7296 }; 7297 7298 this.sizeDiff = { 7299 width: el.outerWidth() - el.width(), 7300 height: el.outerHeight() - el.height() 7301 }; 7302 7303 this.originalPosition = { left: curleft, top: curtop }; 7304 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 7305 7306 this.aspectRatio = (typeof o.aspectRatio === "number") ? 7307 o.aspectRatio : 7308 ((this.originalSize.width / this.originalSize.height) || 1); 7309 7310 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 7311 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 7312 7313 el.addClass("ui-resizable-resizing"); 7314 this._propagate("start", event); 7315 return true; 7316 }, 7317 7318 _mouseDrag: function(event) { 7319 7320 var data, props, 7321 smp = this.originalMousePosition, 7322 a = this.axis, 7323 dx = (event.pageX - smp.left) || 0, 7324 dy = (event.pageY - smp.top) || 0, 7325 trigger = this._change[a]; 7326 7327 this._updatePrevProperties(); 7328 7329 if (!trigger) { 7330 return false; 7331 } 7332 7333 data = trigger.apply(this, [ event, dx, dy ]); 7334 7335 this._updateVirtualBoundaries(event.shiftKey); 7336 if (this._aspectRatio || event.shiftKey) { 7337 data = this._updateRatio(data, event); 7338 } 7339 7340 data = this._respectSize(data, event); 7341 7342 this._updateCache(data); 7343 7344 this._propagate("resize", event); 7345 7346 props = this._applyChanges(); 7347 7348 if ( !this._helper && this._proportionallyResizeElements.length ) { 7349 this._proportionallyResize(); 7350 } 7351 7352 if ( !$.isEmptyObject( props ) ) { 7353 this._updatePrevProperties(); 7354 this._trigger( "resize", event, this.ui() ); 7355 this._applyChanges(); 7356 } 7357 7358 return false; 7359 }, 7360 7361 _mouseStop: function(event) { 7362 7363 this.resizing = false; 7364 var pr, ista, soffseth, soffsetw, s, left, top, 7365 o = this.options, that = this; 7366 7367 if (this._helper) { 7368 7369 pr = this._proportionallyResizeElements; 7370 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 7371 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; 7372 soffsetw = ista ? 0 : that.sizeDiff.width; 7373 7374 s = { 7375 width: (that.helper.width() - soffsetw), 7376 height: (that.helper.height() - soffseth) 7377 }; 7378 left = (parseInt(that.element.css("left"), 10) + 7379 (that.position.left - that.originalPosition.left)) || null; 7380 top = (parseInt(that.element.css("top"), 10) + 7381 (that.position.top - that.originalPosition.top)) || null; 7382 7383 if (!o.animate) { 7384 this.element.css($.extend(s, { top: top, left: left })); 7385 } 7386 7387 that.helper.height(that.size.height); 7388 that.helper.width(that.size.width); 7389
vendor: 6,015 bytes, lines 7390-7629
7390 if (this._helper && !o.animate) { 7391 this._proportionallyResize(); 7392 } 7393 } 7394 7395 $("body").css("cursor", "auto"); 7396 7397 this.element.removeClass("ui-resizable-resizing"); 7398 7399 this._propagate("stop", event); 7400 7401 if (this._helper) { 7402 this.helper.remove(); 7403 } 7404 7405 return false; 7406 7407 }, 7408 7409 _updatePrevProperties: function() { 7410 this.prevPosition = { 7411 top: this.position.top, 7412 left: this.position.left 7413 }; 7414 this.prevSize = { 7415 width: this.size.width, 7416 height: this.size.height 7417 }; 7418 }, 7419 7420 _applyChanges: function() { 7421 var props = {}; 7422 7423 if ( this.position.top !== this.prevPosition.top ) { 7424 props.top = this.position.top + "px"; 7425 } 7426 if ( this.position.left !== this.prevPosition.left ) { 7427 props.left = this.position.left + "px"; 7428 } 7429 if ( this.size.width !== this.prevSize.width ) { 7430 props.width = this.size.width + "px"; 7431 } 7432 if ( this.size.height !== this.prevSize.height ) { 7433 props.height = this.size.height + "px"; 7434 } 7435 7436 this.helper.css( props ); 7437 7438 return props; 7439 }, 7440 7441 _updateVirtualBoundaries: function(forceAspectRatio) { 7442 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 7443 o = this.options; 7444 7445 b = { 7446 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, 7447 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, 7448 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, 7449 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity 7450 }; 7451 7452 if (this._aspectRatio || forceAspectRatio) { 7453 pMinWidth = b.minHeight * this.aspectRatio; 7454 pMinHeight = b.minWidth / this.aspectRatio; 7455 pMaxWidth = b.maxHeight * this.aspectRatio; 7456 pMaxHeight = b.maxWidth / this.aspectRatio; 7457 7458 if (pMinWidth > b.minWidth) { 7459 b.minWidth = pMinWidth; 7460 } 7461 if (pMinHeight > b.minHeight) { 7462 b.minHeight = pMinHeight; 7463 } 7464 if (pMaxWidth < b.maxWidth) { 7465 b.maxWidth = pMaxWidth; 7466 } 7467 if (pMaxHeight < b.maxHeight) { 7468 b.maxHeight = pMaxHeight; 7469 } 7470 } 7471 this._vBoundaries = b; 7472 }, 7473 7474 _updateCache: function(data) { 7475 this.offset = this.helper.offset(); 7476 if (this._isNumber(data.left)) { 7477 this.position.left = data.left; 7478 } 7479 if (this._isNumber(data.top)) { 7480 this.position.top = data.top; 7481 } 7482 if (this._isNumber(data.height)) { 7483 this.size.height = data.height; 7484 } 7485 if (this._isNumber(data.width)) { 7486 this.size.width = data.width; 7487 } 7488 }, 7489 7490 _updateRatio: function( data ) { 7491 7492 var cpos = this.position, 7493 csize = this.size, 7494 a = this.axis; 7495 7496 if (this._isNumber(data.height)) { 7497 data.width = (data.height * this.aspectRatio); 7498 } else if (this._isNumber(data.width)) { 7499 data.height = (data.width / this.aspectRatio); 7500 } 7501 7502 if (a === "sw") { 7503 data.left = cpos.left + (csize.width - data.width); 7504 data.top = null; 7505 } 7506 if (a === "nw") { 7507 data.top = cpos.top + (csize.height - data.height); 7508 data.left = cpos.left + (csize.width - data.width); 7509 } 7510 7511 return data; 7512 }, 7513 7514 _respectSize: function( data ) { 7515 7516 var o = this._vBoundaries, 7517 a = this.axis, 7518 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), 7519 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 7520 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), 7521 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 7522 dw = this.originalPosition.left + this.originalSize.width, 7523 dh = this.position.top + this.size.height, 7524 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 7525 if (isminw) { 7526 data.width = o.minWidth; 7527 } 7528 if (isminh) { 7529 data.height = o.minHeight; 7530 } 7531 if (ismaxw) { 7532 data.width = o.maxWidth; 7533 } 7534 if (ismaxh) { 7535 data.height = o.maxHeight; 7536 } 7537 7538 if (isminw && cw) { 7539 data.left = dw - o.minWidth; 7540 } 7541 if (ismaxw && cw) { 7542 data.left = dw - o.maxWidth; 7543 } 7544 if (isminh && ch) { 7545 data.top = dh - o.minHeight; 7546 } 7547 if (ismaxh && ch) { 7548 data.top = dh - o.maxHeight; 7549 } 7550 7551 // Fixing jump error on top/left - bug #2330 7552 if (!data.width && !data.height && !data.left && data.top) { 7553 data.top = null; 7554 } else if (!data.width && !data.height && !data.top && data.left) { 7555 data.left = null; 7556 } 7557 7558 return data; 7559 }, 7560 7561 _getPaddingPlusBorderDimensions: function( element ) { 7562 var i = 0, 7563 widths = [], 7564 borders = [ 7565 element.css( "borderTopWidth" ), 7566 element.css( "borderRightWidth" ), 7567 element.css( "borderBottomWidth" ), 7568 element.css( "borderLeftWidth" ) 7569 ], 7570 paddings = [ 7571 element.css( "paddingTop" ), 7572 element.css( "paddingRight" ), 7573 element.css( "paddingBottom" ), 7574 element.css( "paddingLeft" ) 7575 ]; 7576 7577 for ( ; i < 4; i++ ) { 7578 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); 7579 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); 7580 } 7581 7582 return { 7583 height: widths[ 0 ] + widths[ 2 ], 7584 width: widths[ 1 ] + widths[ 3 ] 7585 }; 7586 }, 7587 7588 _proportionallyResize: function() { 7589 7590 if (!this._proportionallyResizeElements.length) { 7591 return; 7592 } 7593 7594 var prel, 7595 i = 0, 7596 element = this.helper || this.element; 7597 7598 for ( ; i < this._proportionallyResizeElements.length; i++) { 7599 7600 prel = this._proportionallyResizeElements[i]; 7601 7602 // TODO: Seems like a bug to cache this.outerDimensions 7603 // considering that we are in a loop. 7604 if (!this.outerDimensions) { 7605 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 7606 } 7607 7608 prel.css({ 7609 height: (element.height() - this.outerDimensions.height) || 0, 7610 width: (element.width() - this.outerDimensions.width) || 0 7611 }); 7612 7613 } 7614 7615 }, 7616 7617 _renderProxy: function() { 7618 7619 var el = this.element, o = this.options; 7620 this.elementOffset = el.offset(); 7621 7622 if (this._helper) { 7623 7624 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 7625 7626 this.helper.addClass(this._helper).css({ 7627 width: this.element.outerWidth() - 1, 7628 height: this.element.outerHeight() - 1, 7629 position: "absolute",
vendor: 1,378 bytes, lines 7630-7677
7630 left: this.elementOffset.left + "px", 7631 top: this.elementOffset.top + "px", 7632 zIndex: ++o.zIndex //TODO: Don't modify option 7633 }); 7634 7635 this.helper 7636 .appendTo("body") 7637 .disableSelection(); 7638 7639 } else { 7640 this.helper = this.element; 7641 } 7642 7643 }, 7644 7645 _change: { 7646 e: function(event, dx) { 7647 return { width: this.originalSize.width + dx }; 7648 }, 7649 w: function(event, dx) { 7650 var cs = this.originalSize, sp = this.originalPosition; 7651 return { left: sp.left + dx, width: cs.width - dx }; 7652 }, 7653 n: function(event, dx, dy) { 7654 var cs = this.originalSize, sp = this.originalPosition; 7655 return { top: sp.top + dy, height: cs.height - dy }; 7656 }, 7657 s: function(event, dx, dy) { 7658 return { height: this.originalSize.height + dy }; 7659 }, 7660 se: function(event, dx, dy) { 7661 return $.extend(this._change.s.apply(this, arguments), 7662 this._change.e.apply(this, [ event, dx, dy ])); 7663 }, 7664 sw: function(event, dx, dy) { 7665 return $.extend(this._change.s.apply(this, arguments), 7666 this._change.w.apply(this, [ event, dx, dy ])); 7667 }, 7668 ne: function(event, dx, dy) { 7669 return $.extend(this._change.n.apply(this, arguments), 7670 this._change.e.apply(this, [ event, dx, dy ])); 7671 }, 7672 nw: function(event, dx, dy) { 7673 return $.extend(this._change.n.apply(this, arguments), 7674 this._change.w.apply(this, [ event, dx, dy ])); 7675 } 7676 }, 7677
vendor: 5,118 bytes, lines 7678-7863
7678 _propagate: function(n, event) { 7679 $.ui.plugin.call(this, n, [ event, this.ui() ]); 7680 (n !== "resize" && this._trigger(n, event, this.ui())); 7681 }, 7682 7683 plugins: {}, 7684 7685 ui: function() { 7686 return { 7687 originalElement: this.originalElement, 7688 element: this.element, 7689 helper: this.helper, 7690 position: this.position, 7691 size: this.size, 7692 originalSize: this.originalSize, 7693 originalPosition: this.originalPosition 7694 }; 7695 } 7696 7697}); 7698 7699/* 7700 * Resizable Extensions 7701 */ 7702 7703$.ui.plugin.add("resizable", "animate", { 7704 7705 stop: function( event ) { 7706 var that = $(this).resizable( "instance" ), 7707 o = that.options, 7708 pr = that._proportionallyResizeElements, 7709 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 7710 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, 7711 soffsetw = ista ? 0 : that.sizeDiff.width, 7712 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 7713 left = (parseInt(that.element.css("left"), 10) + 7714 (that.position.left - that.originalPosition.left)) || null, 7715 top = (parseInt(that.element.css("top"), 10) + 7716 (that.position.top - that.originalPosition.top)) || null; 7717 7718 that.element.animate( 7719 $.extend(style, top && left ? { top: top, left: left } : {}), { 7720 duration: o.animateDuration, 7721 easing: o.animateEasing, 7722 step: function() { 7723 7724 var data = { 7725 width: parseInt(that.element.css("width"), 10), 7726 height: parseInt(that.element.css("height"), 10), 7727 top: parseInt(that.element.css("top"), 10), 7728 left: parseInt(that.element.css("left"), 10) 7729 }; 7730 7731 if (pr && pr.length) { 7732 $(pr[0]).css({ width: data.width, height: data.height }); 7733 } 7734 7735 // propagating resize, and updating values for each animation step 7736 that._updateCache(data); 7737 that._propagate("resize", event); 7738 7739 } 7740 } 7741 ); 7742 } 7743 7744}); 7745 7746$.ui.plugin.add( "resizable", "containment", { 7747 7748 start: function() { 7749 var element, p, co, ch, cw, width, height, 7750 that = $( this ).resizable( "instance" ), 7751 o = that.options, 7752 el = that.element, 7753 oc = o.containment, 7754 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 7755 7756 if ( !ce ) { 7757 return; 7758 } 7759 7760 that.containerElement = $( ce ); 7761 7762 if ( /document/.test( oc ) || oc === document ) { 7763 that.containerOffset = { 7764 left: 0, 7765 top: 0 7766 }; 7767 that.containerPosition = { 7768 left: 0, 7769 top: 0 7770 }; 7771 7772 that.parentData = { 7773 element: $( document ), 7774 left: 0, 7775 top: 0, 7776 width: $( document ).width(), 7777 height: $( document ).height() || document.body.parentNode.scrollHeight 7778 }; 7779 } else { 7780 element = $( ce ); 7781 p = []; 7782 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { 7783 p[ i ] = that._num( element.css( "padding" + name ) ); 7784 }); 7785 7786 that.containerOffset = element.offset(); 7787 that.containerPosition = element.position(); 7788 that.containerSize = { 7789 height: ( element.innerHeight() - p[ 3 ] ), 7790 width: ( element.innerWidth() - p[ 1 ] ) 7791 }; 7792 7793 co = that.containerOffset; 7794 ch = that.containerSize.height; 7795 cw = that.containerSize.width; 7796 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 7797 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 7798 7799 that.parentData = { 7800 element: ce, 7801 left: co.left, 7802 top: co.top, 7803 width: width, 7804 height: height 7805 }; 7806 } 7807 }, 7808 7809 resize: function( event ) { 7810 var woset, hoset, isParent, isOffsetRelative, 7811 that = $( this ).resizable( "instance" ), 7812 o = that.options, 7813 co = that.containerOffset, 7814 cp = that.position, 7815 pRatio = that._aspectRatio || event.shiftKey, 7816 cop = { 7817 top: 0, 7818 left: 0 7819 }, 7820 ce = that.containerElement, 7821 continueResize = true; 7822 7823 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 7824 cop = co; 7825 } 7826 7827 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 7828 that.size.width = that.size.width + 7829 ( that._helper ? 7830 ( that.position.left - co.left ) : 7831 ( that.position.left - cop.left ) ); 7832 7833 if ( pRatio ) { 7834 that.size.height = that.size.width / that.aspectRatio; 7835 continueResize = false; 7836 } 7837 that.position.left = o.helper ? co.left : 0; 7838 } 7839 7840 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 7841 that.size.height = that.size.height + 7842 ( that._helper ? 7843 ( that.position.top - co.top ) : 7844 that.position.top ); 7845 7846 if ( pRatio ) { 7847 that.size.width = that.size.height * that.aspectRatio; 7848 continueResize = false; 7849 } 7850 that.position.top = that._helper ? co.top : 0; 7851 } 7852 7853 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 7854 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 7855 7856 if ( isParent && isOffsetRelative ) { 7857 that.offset.left = that.parentData.left + that.position.left; 7858 that.offset.top = that.parentData.top + that.position.top; 7859 } else { 7860 that.offset.left = that.element.offset().left; 7861 that.offset.top = that.element.offset().top; 7862 } 7863
vendor: 4,293 bytes, lines 7864-8031
7864 woset = Math.abs( that.sizeDiff.width + 7865 (that._helper ? 7866 that.offset.left - cop.left : 7867 (that.offset.left - co.left)) ); 7868 7869 hoset = Math.abs( that.sizeDiff.height + 7870 (that._helper ? 7871 that.offset.top - cop.top : 7872 (that.offset.top - co.top)) ); 7873 7874 if ( woset + that.size.width >= that.parentData.width ) { 7875 that.size.width = that.parentData.width - woset; 7876 if ( pRatio ) { 7877 that.size.height = that.size.width / that.aspectRatio; 7878 continueResize = false; 7879 } 7880 } 7881 7882 if ( hoset + that.size.height >= that.parentData.height ) { 7883 that.size.height = that.parentData.height - hoset; 7884 if ( pRatio ) { 7885 that.size.width = that.size.height * that.aspectRatio; 7886 continueResize = false; 7887 } 7888 } 7889 7890 if ( !continueResize ) { 7891 that.position.left = that.prevPosition.left; 7892 that.position.top = that.prevPosition.top; 7893 that.size.width = that.prevSize.width; 7894 that.size.height = that.prevSize.height; 7895 } 7896 }, 7897 7898 stop: function() { 7899 var that = $( this ).resizable( "instance" ), 7900 o = that.options, 7901 co = that.containerOffset, 7902 cop = that.containerPosition, 7903 ce = that.containerElement, 7904 helper = $( that.helper ), 7905 ho = helper.offset(), 7906 w = helper.outerWidth() - that.sizeDiff.width, 7907 h = helper.outerHeight() - that.sizeDiff.height; 7908 7909 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 7910 $( this ).css({ 7911 left: ho.left - cop.left - co.left, 7912 width: w, 7913 height: h 7914 }); 7915 } 7916 7917 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 7918 $( this ).css({ 7919 left: ho.left - cop.left - co.left, 7920 width: w, 7921 height: h 7922 }); 7923 } 7924 } 7925}); 7926 7927$.ui.plugin.add("resizable", "alsoResize", { 7928 7929 start: function() { 7930 var that = $(this).resizable( "instance" ), 7931 o = that.options; 7932 7933 $(o.alsoResize).each(function() { 7934 var el = $(this); 7935 el.data("ui-resizable-alsoresize", { 7936 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 7937 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 7938 }); 7939 }); 7940 }, 7941 7942 resize: function(event, ui) { 7943 var that = $(this).resizable( "instance" ), 7944 o = that.options, 7945 os = that.originalSize, 7946 op = that.originalPosition, 7947 delta = { 7948 height: (that.size.height - os.height) || 0, 7949 width: (that.size.width - os.width) || 0, 7950 top: (that.position.top - op.top) || 0, 7951 left: (that.position.left - op.left) || 0 7952 }; 7953 7954 $(o.alsoResize).each(function() { 7955 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 7956 css = el.parents(ui.originalElement[0]).length ? 7957 [ "width", "height" ] : 7958 [ "width", "height", "top", "left" ]; 7959 7960 $.each(css, function(i, prop) { 7961 var sum = (start[prop] || 0) + (delta[prop] || 0); 7962 if (sum && sum >= 0) { 7963 style[prop] = sum || null; 7964 } 7965 }); 7966 7967 el.css(style); 7968 }); 7969 }, 7970 7971 stop: function() { 7972 $(this).removeData("resizable-alsoresize"); 7973 } 7974}); 7975 7976$.ui.plugin.add("resizable", "ghost", { 7977 7978 start: function() { 7979 7980 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; 7981 7982 that.ghost = that.originalElement.clone(); 7983 that.ghost 7984 .css({ 7985 opacity: 0.25, 7986 display: "block", 7987 position: "relative", 7988 height: cs.height, 7989 width: cs.width, 7990 margin: 0, 7991 left: 0, 7992 top: 0 7993 }) 7994 .addClass("ui-resizable-ghost") 7995 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 7996 7997 that.ghost.appendTo(that.helper); 7998 7999 }, 8000 8001 resize: function() { 8002 var that = $(this).resizable( "instance" ); 8003 if (that.ghost) { 8004 that.ghost.css({ 8005 position: "relative", 8006 height: that.size.height, 8007 width: that.size.width 8008 }); 8009 } 8010 }, 8011 8012 stop: function() { 8013 var that = $(this).resizable( "instance" ); 8014 if (that.ghost && that.helper) { 8015 that.helper.get(0).removeChild(that.ghost.get(0)); 8016 } 8017 } 8018 8019}); 8020 8021$.ui.plugin.add("resizable", "grid", { 8022 8023 resize: function() { 8024 var outerDimensions, 8025 that = $(this).resizable( "instance" ), 8026 o = that.options, 8027 cs = that.size, 8028 os = that.originalSize, 8029 op = that.originalPosition, 8030 a = that.axis, 8031 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
vendor: 28,525 bytes, lines 8032-9129
8032 gridX = (grid[0] || 1), 8033 gridY = (grid[1] || 1), 8034 ox = Math.round((cs.width - os.width) / gridX) * gridX, 8035 oy = Math.round((cs.height - os.height) / gridY) * gridY, 8036 newWidth = os.width + ox, 8037 newHeight = os.height + oy, 8038 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 8039 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 8040 isMinWidth = o.minWidth && (o.minWidth > newWidth), 8041 isMinHeight = o.minHeight && (o.minHeight > newHeight); 8042 8043 o.grid = grid; 8044 8045 if (isMinWidth) { 8046 newWidth += gridX; 8047 } 8048 if (isMinHeight) { 8049 newHeight += gridY; 8050 } 8051 if (isMaxWidth) { 8052 newWidth -= gridX; 8053 } 8054 if (isMaxHeight) { 8055 newHeight -= gridY; 8056 } 8057 8058 if (/^(se|s|e)$/.test(a)) { 8059 that.size.width = newWidth; 8060 that.size.height = newHeight; 8061 } else if (/^(ne)$/.test(a)) { 8062 that.size.width = newWidth; 8063 that.size.height = newHeight; 8064 that.position.top = op.top - oy; 8065 } else if (/^(sw)$/.test(a)) { 8066 that.size.width = newWidth; 8067 that.size.height = newHeight; 8068 that.position.left = op.left - ox; 8069 } else { 8070 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { 8071 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 8072 } 8073 8074 if ( newHeight - gridY > 0 ) { 8075 that.size.height = newHeight; 8076 that.position.top = op.top - oy; 8077 } else { 8078 newHeight = gridY - outerDimensions.height; 8079 that.size.height = newHeight; 8080 that.position.top = op.top + os.height - newHeight; 8081 } 8082 if ( newWidth - gridX > 0 ) { 8083 that.size.width = newWidth; 8084 that.position.left = op.left - ox; 8085 } else { 8086 newWidth = gridX - outerDimensions.width; 8087 that.size.width = newWidth; 8088 that.position.left = op.left + os.width - newWidth; 8089 } 8090 } 8091 } 8092 8093}); 8094 8095var resizable = $.ui.resizable; 8096 8097 8098/*! 8099 * jQuery UI Dialog 1.11.4 8100 * http://jqueryui.com 8101 * 8102 * Copyright jQuery Foundation and other contributors 8103 * Released under the MIT license. 8104 * http://jquery.org/license 8105 * 8106 * http://api.jqueryui.com/dialog/ 8107 */ 8108 8109 8110var dialog = $.widget( "ui.dialog", { 8111 version: "1.11.4", 8112 options: { 8113 appendTo: "body", 8114 autoOpen: true, 8115 buttons: [], 8116 closeOnEscape: true, 8117 closeText: "Close", 8118 dialogClass: "", 8119 draggable: true, 8120 hide: null, 8121 height: "auto", 8122 maxHeight: null, 8123 maxWidth: null, 8124 minHeight: 150, 8125 minWidth: 150, 8126 modal: false, 8127 position: { 8128 my: "center", 8129 at: "center", 8130 of: window, 8131 collision: "fit", 8132 // Ensure the titlebar is always visible 8133 using: function( pos ) { 8134 var topOffset = $( this ).css( pos ).offset().top; 8135 if ( topOffset < 0 ) { 8136 $( this ).css( "top", pos.top - topOffset ); 8137 } 8138 } 8139 }, 8140 resizable: true, 8141 show: null, 8142 title: null, 8143 width: 300, 8144 8145 // callbacks 8146 beforeClose: null, 8147 close: null, 8148 drag: null, 8149 dragStart: null, 8150 dragStop: null, 8151 focus: null, 8152 open: null, 8153 resize: null, 8154 resizeStart: null, 8155 resizeStop: null 8156 }, 8157 8158 sizeRelatedOptions: { 8159 buttons: true, 8160 height: true, 8161 maxHeight: true, 8162 maxWidth: true, 8163 minHeight: true, 8164 minWidth: true, 8165 width: true 8166 }, 8167 8168 resizableRelatedOptions: { 8169 maxHeight: true, 8170 maxWidth: true, 8171 minHeight: true, 8172 minWidth: true 8173 }, 8174 8175 _create: function() { 8176 this.originalCss = { 8177 display: this.element[ 0 ].style.display, 8178 width: this.element[ 0 ].style.width, 8179 minHeight: this.element[ 0 ].style.minHeight, 8180 maxHeight: this.element[ 0 ].style.maxHeight, 8181 height: this.element[ 0 ].style.height 8182 }; 8183 this.originalPosition = { 8184 parent: this.element.parent(), 8185 index: this.element.parent().children().index( this.element ) 8186 }; 8187 this.originalTitle = this.element.attr( "title" ); 8188 this.options.title = this.options.title || this.originalTitle; 8189 8190 this._createWrapper(); 8191 8192 this.element 8193 .show() 8194 .removeAttr( "title" ) 8195 .addClass( "ui-dialog-content ui-widget-content" ) 8196 .appendTo( this.uiDialog ); 8197 8198 this._createTitlebar(); 8199 this._createButtonPane(); 8200 8201 if ( this.options.draggable && $.fn.draggable ) { 8202 this._makeDraggable(); 8203 } 8204 if ( this.options.resizable && $.fn.resizable ) { 8205 this._makeResizable(); 8206 } 8207 8208 this._isOpen = false; 8209 8210 this._trackFocus(); 8211 }, 8212 8213 _init: function() { 8214 if ( this.options.autoOpen ) { 8215 this.open(); 8216 } 8217 }, 8218 8219 _appendTo: function() { 8220 var element = this.options.appendTo; 8221 if ( element && (element.jquery || element.nodeType) ) { 8222 return $( element ); 8223 } 8224 return this.document.find( element || "body" ).eq( 0 ); 8225 }, 8226 8227 _destroy: function() { 8228 var next, 8229 originalPosition = this.originalPosition; 8230 8231 this._untrackInstance(); 8232 this._destroyOverlay(); 8233 8234 this.element 8235 .removeUniqueId() 8236 .removeClass( "ui-dialog-content ui-widget-content" ) 8237 .css( this.originalCss ) 8238 // Without detaching first, the following becomes really slow 8239 .detach(); 8240 8241 this.uiDialog.stop( true, true ).remove(); 8242 8243 if ( this.originalTitle ) { 8244 this.element.attr( "title", this.originalTitle ); 8245 } 8246 8247 next = originalPosition.parent.children().eq( originalPosition.index ); 8248 // Don't try to place the dialog next to itself (#8613) 8249 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 8250 next.before( this.element ); 8251 } else { 8252 originalPosition.parent.append( this.element ); 8253 } 8254 }, 8255 8256 widget: function() { 8257 return this.uiDialog; 8258 }, 8259 8260 disable: $.noop, 8261 enable: $.noop, 8262 8263 close: function( event ) { 8264 var activeElement, 8265 that = this; 8266 8267 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 8268 return; 8269 } 8270 8271 this._isOpen = false; 8272 this._focusedElement = null; 8273 this._destroyOverlay(); 8274 this._untrackInstance(); 8275 8276 if ( !this.opener.filter( ":focusable" ).focus().length ) { 8277 8278 // support: IE9 8279 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 8280 try { 8281 activeElement = this.document[ 0 ].activeElement; 8282 8283 // Support: IE9, IE10 8284 // If the <body> is blurred, IE will switch windows, see #4520 8285 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 8286 8287 // Hiding a focused element doesn't trigger blur in WebKit 8288 // so in case we have nothing to focus on, explicitly blur the active element 8289 // https://bugs.webkit.org/show_bug.cgi?id=47182 8290 $( activeElement ).blur(); 8291 } 8292 } catch ( error ) {} 8293 } 8294 8295 this._hide( this.uiDialog, this.options.hide, function() { 8296 that._trigger( "close", event ); 8297 }); 8298 }, 8299 8300 isOpen: function() { 8301 return this._isOpen; 8302 }, 8303 8304 moveToTop: function() { 8305 this._moveToTop(); 8306 }, 8307 8308 _moveToTop: function( event, silent ) { 8309 var moved = false, 8310 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { 8311 return +$( this ).css( "z-index" ); 8312 }).get(), 8313 zIndexMax = Math.max.apply( null, zIndices ); 8314 8315 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 8316 this.uiDialog.css( "z-index", zIndexMax + 1 ); 8317 moved = true; 8318 } 8319 8320 if ( moved && !silent ) { 8321 this._trigger( "focus", event ); 8322 } 8323 return moved; 8324 }, 8325 8326 open: function() { 8327 var that = this; 8328 if ( this._isOpen ) { 8329 if ( this._moveToTop() ) { 8330 this._focusTabbable(); 8331 } 8332 return; 8333 } 8334 8335 this._isOpen = true; 8336 this.opener = $( this.document[ 0 ].activeElement ); 8337 8338 this._size(); 8339 this._position(); 8340 this._createOverlay(); 8341 this._moveToTop( null, true ); 8342 8343 // Ensure the overlay is moved to the top with the dialog, but only when 8344 // opening. The overlay shouldn't move after the dialog is open so that 8345 // modeless dialogs opened after the modal dialog stack properly. 8346 if ( this.overlay ) { 8347 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 8348 } 8349 8350 this._show( this.uiDialog, this.options.show, function() { 8351 that._focusTabbable(); 8352 that._trigger( "focus" ); 8353 }); 8354 8355 // Track the dialog immediately upon openening in case a focus event 8356 // somehow occurs outside of the dialog before an element inside the 8357 // dialog is focused (#10152) 8358 this._makeFocusTarget(); 8359 8360 this._trigger( "open" ); 8361 }, 8362 8363 _focusTabbable: function() { 8364 // Set focus to the first match: 8365 // 1. An element that was focused previously 8366 // 2. First element inside the dialog matching [autofocus] 8367 // 3. Tabbable element inside the content element 8368 // 4. Tabbable element inside the buttonpane 8369 // 5. The close button 8370 // 6. The dialog itself 8371 var hasFocus = this._focusedElement; 8372 if ( !hasFocus ) { 8373 hasFocus = this.element.find( "[autofocus]" ); 8374 } 8375 if ( !hasFocus.length ) { 8376 hasFocus = this.element.find( ":tabbable" ); 8377 } 8378 if ( !hasFocus.length ) { 8379 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 8380 } 8381 if ( !hasFocus.length ) { 8382 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 8383 } 8384 if ( !hasFocus.length ) { 8385 hasFocus = this.uiDialog; 8386 } 8387 hasFocus.eq( 0 ).focus(); 8388 }, 8389 8390 _keepFocus: function( event ) { 8391 function checkFocus() { 8392 var activeElement = this.document[0].activeElement, 8393 isActive = this.uiDialog[0] === activeElement || 8394 $.contains( this.uiDialog[0], activeElement ); 8395 if ( !isActive ) { 8396 this._focusTabbable(); 8397 } 8398 } 8399 event.preventDefault(); 8400 checkFocus.call( this ); 8401 // support: IE 8402 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 8403 // so we check again later 8404 this._delay( checkFocus ); 8405 }, 8406 8407 _createWrapper: function() { 8408 this.uiDialog = $("<div>") 8409 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 8410 this.options.dialogClass ) 8411 .hide() 8412 .attr({ 8413 // Setting tabIndex makes the div focusable 8414 tabIndex: -1, 8415 role: "dialog" 8416 }) 8417 .appendTo( this._appendTo() ); 8418 8419 this._on( this.uiDialog, { 8420 keydown: function( event ) { 8421 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 8422 event.keyCode === $.ui.keyCode.ESCAPE ) { 8423 event.preventDefault(); 8424 this.close( event ); 8425 return; 8426 } 8427 8428 // prevent tabbing out of dialogs 8429 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 8430 return; 8431 } 8432 var tabbables = this.uiDialog.find( ":tabbable" ), 8433 first = tabbables.filter( ":first" ), 8434 last = tabbables.filter( ":last" ); 8435 8436 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 8437 this._delay(function() { 8438 first.focus(); 8439 }); 8440 event.preventDefault(); 8441 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 8442 this._delay(function() { 8443 last.focus(); 8444 }); 8445 event.preventDefault(); 8446 } 8447 }, 8448 mousedown: function( event ) { 8449 if ( this._moveToTop( event ) ) { 8450 this._focusTabbable(); 8451 } 8452 } 8453 }); 8454 8455 // We assume that any existing aria-describedby attribute means 8456 // that the dialog content is marked up properly 8457 // otherwise we brute force the content as the description 8458 if ( !this.element.find( "[aria-describedby]" ).length ) { 8459 this.uiDialog.attr({ 8460 "aria-describedby": this.element.uniqueId().attr( "id" ) 8461 }); 8462 } 8463 }, 8464 8465 _createTitlebar: function() { 8466 var uiDialogTitle; 8467 8468 this.uiDialogTitlebar = $( "<div>" ) 8469 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) 8470 .prependTo( this.uiDialog ); 8471 this._on( this.uiDialogTitlebar, { 8472 mousedown: function( event ) { 8473 // Don't prevent click on close button (#8838) 8474 // Focusing a dialog that is partially scrolled out of view 8475 // causes the browser to scroll it into view, preventing the click event 8476 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 8477 // Dialog isn't getting focus when dragging (#8063) 8478 this.uiDialog.focus(); 8479 } 8480 } 8481 }); 8482 8483 // support: IE 8484 // Use type="button" to prevent enter keypresses in textboxes from closing the 8485 // dialog in IE (#9312) 8486 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 8487 .button({ 8488 label: this.options.closeText, 8489 icons: { 8490 primary: "ui-icon-closethick" 8491 }, 8492 text: false 8493 }) 8494 .addClass( "ui-dialog-titlebar-close" ) 8495 .appendTo( this.uiDialogTitlebar ); 8496 this._on( this.uiDialogTitlebarClose, { 8497 click: function( event ) { 8498 event.preventDefault(); 8499 this.close( event ); 8500 } 8501 }); 8502 8503 uiDialogTitle = $( "<span>" ) 8504 .uniqueId() 8505 .addClass( "ui-dialog-title" ) 8506 .prependTo( this.uiDialogTitlebar ); 8507 this._title( uiDialogTitle ); 8508 8509 this.uiDialog.attr({ 8510 "aria-labelledby": uiDialogTitle.attr( "id" ) 8511 }); 8512 }, 8513 8514 _title: function( title ) { 8515 if ( !this.options.title ) { 8516 title.html( " " ); 8517 } 8518 title.text( this.options.title ); 8519 }, 8520 8521 _createButtonPane: function() { 8522 this.uiDialogButtonPane = $( "<div>" ) 8523 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 8524 8525 this.uiButtonSet = $( "<div>" ) 8526 .addClass( "ui-dialog-buttonset" ) 8527 .appendTo( this.uiDialogButtonPane ); 8528 8529 this._createButtons(); 8530 }, 8531 8532 _createButtons: function() { 8533 var that = this, 8534 buttons = this.options.buttons; 8535 8536 // if we already have a button pane, remove it 8537 this.uiDialogButtonPane.remove(); 8538 this.uiButtonSet.empty(); 8539 8540 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 8541 this.uiDialog.removeClass( "ui-dialog-buttons" ); 8542 return; 8543 } 8544 8545 $.each( buttons, function( name, props ) { 8546 var click, buttonOptions; 8547 props = $.isFunction( props ) ? 8548 { click: props, text: name } : 8549 props; 8550 // Default to a non-submitting button 8551 props = $.extend( { type: "button" }, props ); 8552 // Change the context for the click callback to be the main element 8553 click = props.click; 8554 props.click = function() { 8555 click.apply( that.element[ 0 ], arguments ); 8556 }; 8557 buttonOptions = { 8558 icons: props.icons, 8559 text: props.showText 8560 }; 8561 delete props.icons; 8562 delete props.showText; 8563 $( "<button></button>", props ) 8564 .button( buttonOptions ) 8565 .appendTo( that.uiButtonSet ); 8566 }); 8567 this.uiDialog.addClass( "ui-dialog-buttons" ); 8568 this.uiDialogButtonPane.appendTo( this.uiDialog ); 8569 }, 8570 8571 _makeDraggable: function() { 8572 var that = this, 8573 options = this.options; 8574 8575 function filteredUi( ui ) { 8576 return { 8577 position: ui.position, 8578 offset: ui.offset 8579 }; 8580 } 8581 8582 this.uiDialog.draggable({ 8583 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 8584 handle: ".ui-dialog-titlebar", 8585 containment: "document", 8586 start: function( event, ui ) { 8587 $( this ).addClass( "ui-dialog-dragging" ); 8588 that._blockFrames(); 8589 that._trigger( "dragStart", event, filteredUi( ui ) ); 8590 }, 8591 drag: function( event, ui ) { 8592 that._trigger( "drag", event, filteredUi( ui ) ); 8593 }, 8594 stop: function( event, ui ) { 8595 var left = ui.offset.left - that.document.scrollLeft(), 8596 top = ui.offset.top - that.document.scrollTop(); 8597 8598 options.position = { 8599 my: "left top", 8600 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8601 "top" + (top >= 0 ? "+" : "") + top, 8602 of: that.window 8603 }; 8604 $( this ).removeClass( "ui-dialog-dragging" ); 8605 that._unblockFrames(); 8606 that._trigger( "dragStop", event, filteredUi( ui ) ); 8607 } 8608 }); 8609 }, 8610 8611 _makeResizable: function() { 8612 var that = this, 8613 options = this.options, 8614 handles = options.resizable, 8615 // .ui-resizable has position: relative defined in the stylesheet 8616 // but dialogs have to use absolute or fixed positioning 8617 position = this.uiDialog.css("position"), 8618 resizeHandles = typeof handles === "string" ? 8619 handles : 8620 "n,e,s,w,se,sw,ne,nw"; 8621 8622 function filteredUi( ui ) { 8623 return { 8624 originalPosition: ui.originalPosition, 8625 originalSize: ui.originalSize, 8626 position: ui.position, 8627 size: ui.size 8628 }; 8629 } 8630 8631 this.uiDialog.resizable({ 8632 cancel: ".ui-dialog-content", 8633 containment: "document", 8634 alsoResize: this.element, 8635 maxWidth: options.maxWidth, 8636 maxHeight: options.maxHeight, 8637 minWidth: options.minWidth, 8638 minHeight: this._minHeight(), 8639 handles: resizeHandles, 8640 start: function( event, ui ) { 8641 $( this ).addClass( "ui-dialog-resizing" ); 8642 that._blockFrames(); 8643 that._trigger( "resizeStart", event, filteredUi( ui ) ); 8644 }, 8645 resize: function( event, ui ) { 8646 that._trigger( "resize", event, filteredUi( ui ) ); 8647 }, 8648 stop: function( event, ui ) { 8649 var offset = that.uiDialog.offset(), 8650 left = offset.left - that.document.scrollLeft(), 8651 top = offset.top - that.document.scrollTop(); 8652 8653 options.height = that.uiDialog.height(); 8654 options.width = that.uiDialog.width(); 8655 options.position = { 8656 my: "left top", 8657 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8658 "top" + (top >= 0 ? "+" : "") + top, 8659 of: that.window 8660 }; 8661 $( this ).removeClass( "ui-dialog-resizing" ); 8662 that._unblockFrames(); 8663 that._trigger( "resizeStop", event, filteredUi( ui ) ); 8664 } 8665 }) 8666 .css( "position", position ); 8667 }, 8668 8669 _trackFocus: function() { 8670 this._on( this.widget(), { 8671 focusin: function( event ) { 8672 this._makeFocusTarget(); 8673 this._focusedElement = $( event.target ); 8674 } 8675 }); 8676 }, 8677 8678 _makeFocusTarget: function() { 8679 this._untrackInstance(); 8680 this._trackingInstances().unshift( this ); 8681 }, 8682 8683 _untrackInstance: function() { 8684 var instances = this._trackingInstances(), 8685 exists = $.inArray( this, instances ); 8686 if ( exists !== -1 ) { 8687 instances.splice( exists, 1 ); 8688 } 8689 }, 8690 8691 _trackingInstances: function() { 8692 var instances = this.document.data( "ui-dialog-instances" ); 8693 if ( !instances ) { 8694 instances = []; 8695 this.document.data( "ui-dialog-instances", instances ); 8696 } 8697 return instances; 8698 }, 8699 8700 _minHeight: function() { 8701 var options = this.options; 8702 8703 return options.height === "auto" ? 8704 options.minHeight : 8705 Math.min( options.minHeight, options.height ); 8706 }, 8707 8708 _position: function() { 8709 // Need to show the dialog to get the actual offset in the position plugin 8710 var isVisible = this.uiDialog.is( ":visible" ); 8711 if ( !isVisible ) { 8712 this.uiDialog.show(); 8713 } 8714 this.uiDialog.position( this.options.position ); 8715 if ( !isVisible ) { 8716 this.uiDialog.hide(); 8717 } 8718 }, 8719 8720 _setOptions: function( options ) { 8721 var that = this, 8722 resize = false, 8723 resizableOptions = {}; 8724 8725 $.each( options, function( key, value ) { 8726 that._setOption( key, value ); 8727 8728 if ( key in that.sizeRelatedOptions ) { 8729 resize = true; 8730 } 8731 if ( key in that.resizableRelatedOptions ) { 8732 resizableOptions[ key ] = value; 8733 } 8734 }); 8735 8736 if ( resize ) { 8737 this._size(); 8738 this._position(); 8739 } 8740 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 8741 this.uiDialog.resizable( "option", resizableOptions ); 8742 } 8743 }, 8744 8745 _setOption: function( key, value ) { 8746 var isDraggable, isResizable, 8747 uiDialog = this.uiDialog; 8748 8749 if ( key === "dialogClass" ) { 8750 uiDialog 8751 .removeClass( this.options.dialogClass ) 8752 .addClass( value ); 8753 } 8754 8755 if ( key === "disabled" ) { 8756 return; 8757 } 8758 8759 this._super( key, value ); 8760 8761 if ( key === "appendTo" ) { 8762 this.uiDialog.appendTo( this._appendTo() ); 8763 } 8764 8765 if ( key === "buttons" ) { 8766 this._createButtons(); 8767 } 8768 8769 if ( key === "closeText" ) { 8770 this.uiDialogTitlebarClose.button({ 8771 // Ensure that we always pass a string 8772 label: "" + value 8773 }); 8774 } 8775 8776 if ( key === "draggable" ) { 8777 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 8778 if ( isDraggable && !value ) { 8779 uiDialog.draggable( "destroy" ); 8780 } 8781 8782 if ( !isDraggable && value ) { 8783 this._makeDraggable(); 8784 } 8785 } 8786 8787 if ( key === "position" ) { 8788 this._position(); 8789 } 8790 8791 if ( key === "resizable" ) { 8792 // currently resizable, becoming non-resizable 8793 isResizable = uiDialog.is( ":data(ui-resizable)" ); 8794 if ( isResizable && !value ) { 8795 uiDialog.resizable( "destroy" ); 8796 } 8797 8798 // currently resizable, changing handles 8799 if ( isResizable && typeof value === "string" ) { 8800 uiDialog.resizable( "option", "handles", value ); 8801 } 8802 8803 // currently non-resizable, becoming resizable 8804 if ( !isResizable && value !== false ) { 8805 this._makeResizable(); 8806 } 8807 } 8808 8809 if ( key === "title" ) { 8810 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 8811 } 8812 }, 8813 8814 _size: function() { 8815 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 8816 // divs will both have width and height set, so we need to reset them 8817 var nonContentHeight, minContentHeight, maxContentHeight, 8818 options = this.options; 8819 8820 // Reset content sizing 8821 this.element.show().css({ 8822 width: "auto", 8823 minHeight: 0, 8824 maxHeight: "none", 8825 height: 0 8826 }); 8827 8828 if ( options.minWidth > options.width ) { 8829 options.width = options.minWidth; 8830 } 8831 8832 // reset wrapper sizing 8833 // determine the height of all the non-content elements 8834 nonContentHeight = this.uiDialog.css({ 8835 height: "auto", 8836 width: options.width 8837 }) 8838 .outerHeight(); 8839 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 8840 maxContentHeight = typeof options.maxHeight === "number" ? 8841 Math.max( 0, options.maxHeight - nonContentHeight ) : 8842 "none"; 8843 8844 if ( options.height === "auto" ) { 8845 this.element.css({ 8846 minHeight: minContentHeight, 8847 maxHeight: maxContentHeight, 8848 height: "auto" 8849 }); 8850 } else { 8851 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 8852 } 8853 8854 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 8855 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 8856 } 8857 }, 8858 8859 _blockFrames: function() { 8860 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 8861 var iframe = $( this ); 8862 8863 return $( "<div>" ) 8864 .css({ 8865 position: "absolute", 8866 width: iframe.outerWidth(), 8867 height: iframe.outerHeight() 8868 }) 8869 .appendTo( iframe.parent() ) 8870 .offset( iframe.offset() )[0]; 8871 }); 8872 }, 8873 8874 _unblockFrames: function() { 8875 if ( this.iframeBlocks ) { 8876 this.iframeBlocks.remove(); 8877 delete this.iframeBlocks; 8878 } 8879 }, 8880 8881 _allowInteraction: function( event ) { 8882 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 8883 return true; 8884 } 8885 8886 // TODO: Remove hack when datepicker implements 8887 // the .ui-front logic (#8989) 8888 return !!$( event.target ).closest( ".ui-datepicker" ).length; 8889 }, 8890 8891 _createOverlay: function() { 8892 if ( !this.options.modal ) { 8893 return; 8894 } 8895 8896 // We use a delay in case the overlay is created from an 8897 // event that we're going to be cancelling (#2804) 8898 var isOpening = true; 8899 this._delay(function() { 8900 isOpening = false; 8901 }); 8902 8903 if ( !this.document.data( "ui-dialog-overlays" ) ) { 8904 8905 // Prevent use of anchors and inputs 8906 // Using _on() for an event handler shared across many instances is 8907 // safe because the dialogs stack and must be closed in reverse order 8908 this._on( this.document, { 8909 focusin: function( event ) { 8910 if ( isOpening ) { 8911 return; 8912 } 8913 8914 if ( !this._allowInteraction( event ) ) { 8915 event.preventDefault(); 8916 this._trackingInstances()[ 0 ]._focusTabbable(); 8917 } 8918 } 8919 }); 8920 } 8921 8922 this.overlay = $( "<div>" ) 8923 .addClass( "ui-widget-overlay ui-front" ) 8924 .appendTo( this._appendTo() ); 8925 this._on( this.overlay, { 8926 mousedown: "_keepFocus" 8927 }); 8928 this.document.data( "ui-dialog-overlays", 8929 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); 8930 }, 8931 8932 _destroyOverlay: function() { 8933 if ( !this.options.modal ) { 8934 return; 8935 } 8936 8937 if ( this.overlay ) { 8938 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 8939 8940 if ( !overlays ) { 8941 this.document 8942 .unbind( "focusin" ) 8943 .removeData( "ui-dialog-overlays" ); 8944 } else { 8945 this.document.data( "ui-dialog-overlays", overlays ); 8946 } 8947 8948 this.overlay.remove(); 8949 this.overlay = null; 8950 } 8951 } 8952}); 8953 8954 8955/*! 8956 * jQuery UI Droppable 1.11.4 8957 * http://jqueryui.com 8958 * 8959 * Copyright jQuery Foundation and other contributors 8960 * Released under the MIT license. 8961 * http://jquery.org/license 8962 * 8963 * http://api.jqueryui.com/droppable/ 8964 */ 8965 8966 8967$.widget( "ui.droppable", { 8968 version: "1.11.4", 8969 widgetEventPrefix: "drop", 8970 options: { 8971 accept: "*", 8972 activeClass: false, 8973 addClasses: true, 8974 greedy: false, 8975 hoverClass: false, 8976 scope: "default", 8977 tolerance: "intersect", 8978 8979 // callbacks 8980 activate: null, 8981 deactivate: null, 8982 drop: null, 8983 out: null, 8984 over: null 8985 }, 8986 _create: function() { 8987 8988 var proportions, 8989 o = this.options, 8990 accept = o.accept; 8991 8992 this.isover = false; 8993 this.isout = true; 8994 8995 this.accept = $.isFunction( accept ) ? accept : function( d ) { 8996 return d.is( accept ); 8997 }; 8998 8999 this.proportions = function( /* valueToWrite */ ) { 9000 if ( arguments.length ) { 9001 // Store the droppable's proportions 9002 proportions = arguments[ 0 ]; 9003 } else { 9004 // Retrieve or derive the droppable's proportions 9005 return proportions ? 9006 proportions : 9007 proportions = { 9008 width: this.element[ 0 ].offsetWidth, 9009 height: this.element[ 0 ].offsetHeight 9010 }; 9011 } 9012 }; 9013 9014 this._addToManager( o.scope ); 9015 9016 o.addClasses && this.element.addClass( "ui-droppable" ); 9017 9018 }, 9019 9020 _addToManager: function( scope ) { 9021 // Add the reference and positions to the manager 9022 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 9023 $.ui.ddmanager.droppables[ scope ].push( this ); 9024 }, 9025 9026 _splice: function( drop ) { 9027 var i = 0; 9028 for ( ; i < drop.length; i++ ) { 9029 if ( drop[ i ] === this ) { 9030 drop.splice( i, 1 ); 9031 } 9032 } 9033 }, 9034 9035 _destroy: function() { 9036 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9037 9038 this._splice( drop ); 9039 9040 this.element.removeClass( "ui-droppable ui-droppable-disabled" ); 9041 }, 9042 9043 _setOption: function( key, value ) { 9044 9045 if ( key === "accept" ) { 9046 this.accept = $.isFunction( value ) ? value : function( d ) { 9047 return d.is( value ); 9048 }; 9049 } else if ( key === "scope" ) { 9050 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9051 9052 this._splice( drop ); 9053 this._addToManager( value ); 9054 } 9055 9056 this._super( key, value ); 9057 }, 9058 9059 _activate: function( event ) { 9060 var draggable = $.ui.ddmanager.current; 9061 if ( this.options.activeClass ) { 9062 this.element.addClass( this.options.activeClass ); 9063 } 9064 if ( draggable ){ 9065 this._trigger( "activate", event, this.ui( draggable ) ); 9066 } 9067 }, 9068 9069 _deactivate: function( event ) { 9070 var draggable = $.ui.ddmanager.current; 9071 if ( this.options.activeClass ) { 9072 this.element.removeClass( this.options.activeClass ); 9073 } 9074 if ( draggable ){ 9075 this._trigger( "deactivate", event, this.ui( draggable ) ); 9076 } 9077 }, 9078 9079 _over: function( event ) { 9080 9081 var draggable = $.ui.ddmanager.current; 9082 9083 // Bail if draggable and droppable are same element 9084 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9085 return; 9086 } 9087 9088 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9089 if ( this.options.hoverClass ) { 9090 this.element.addClass( this.options.hoverClass ); 9091 } 9092 this._trigger( "over", event, this.ui( draggable ) ); 9093 } 9094 9095 }, 9096 9097 _out: function( event ) { 9098 9099 var draggable = $.ui.ddmanager.current; 9100 9101 // Bail if draggable and droppable are same element 9102 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9103 return; 9104 } 9105 9106 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9107 if ( this.options.hoverClass ) { 9108 this.element.removeClass( this.options.hoverClass ); 9109 } 9110 this._trigger( "out", event, this.ui( draggable ) ); 9111 } 9112 9113 }, 9114 9115 _drop: function( event, custom ) { 9116 9117 var draggable = custom || $.ui.ddmanager.current, 9118 childrenIntersection = false; 9119 9120 // Bail if draggable and droppable are same element 9121 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9122 return false; 9123 } 9124 9125 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { 9126 var inst = $( this ).droppable( "instance" ); 9127 if ( 9128 inst.options.greedy && 9129 !inst.options.disabled &&
vendor: 4,139 bytes, lines 9130-9258
9130 inst.options.scope === draggable.options.scope && 9131 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && 9132 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) 9133 ) { childrenIntersection = true; return false; } 9134 }); 9135 if ( childrenIntersection ) { 9136 return false; 9137 } 9138 9139 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9140 if ( this.options.activeClass ) { 9141 this.element.removeClass( this.options.activeClass ); 9142 } 9143 if ( this.options.hoverClass ) { 9144 this.element.removeClass( this.options.hoverClass ); 9145 } 9146 this._trigger( "drop", event, this.ui( draggable ) ); 9147 return this.element; 9148 } 9149 9150 return false; 9151 9152 }, 9153 9154 ui: function( c ) { 9155 return { 9156 draggable: ( c.currentItem || c.element ), 9157 helper: c.helper, 9158 position: c.position, 9159 offset: c.positionAbs 9160 }; 9161 } 9162 9163}); 9164 9165$.ui.intersect = (function() { 9166 function isOverAxis( x, reference, size ) { 9167 return ( x >= reference ) && ( x < ( reference + size ) ); 9168 } 9169 9170 return function( draggable, droppable, toleranceMode, event ) { 9171 9172 if ( !droppable.offset ) { 9173 return false; 9174 } 9175 9176 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, 9177 y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, 9178 x2 = x1 + draggable.helperProportions.width, 9179 y2 = y1 + draggable.helperProportions.height, 9180 l = droppable.offset.left, 9181 t = droppable.offset.top, 9182 r = l + droppable.proportions().width, 9183 b = t + droppable.proportions().height; 9184 9185 switch ( toleranceMode ) { 9186 case "fit": 9187 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 9188 case "intersect": 9189 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 9190 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 9191 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 9192 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 9193 case "pointer": 9194 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); 9195 case "touch": 9196 return ( 9197 ( y1 >= t && y1 <= b ) || // Top edge touching 9198 ( y2 >= t && y2 <= b ) || // Bottom edge touching 9199 ( y1 < t && y2 > b ) // Surrounded vertically 9200 ) && ( 9201 ( x1 >= l && x1 <= r ) || // Left edge touching 9202 ( x2 >= l && x2 <= r ) || // Right edge touching 9203 ( x1 < l && x2 > r ) // Surrounded horizontally 9204 ); 9205 default: 9206 return false; 9207 } 9208 }; 9209})(); 9210 9211/* 9212 This manager tracks offsets of draggables and droppables 9213*/ 9214$.ui.ddmanager = { 9215 current: null, 9216 droppables: { "default": [] }, 9217 prepareOffsets: function( t, event ) { 9218 9219 var i, j, 9220 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 9221 type = event ? event.type : null, // workaround for #2317 9222 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 9223 9224 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 9225 9226 // No disabled and non-accepted 9227 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { 9228 continue; 9229 } 9230 9231 // Filter out elements in the current dragged item 9232 for ( j = 0; j < list.length; j++ ) { 9233 if ( list[ j ] === m[ i ].element[ 0 ] ) { 9234 m[ i ].proportions().height = 0; 9235 continue droppablesLoop; 9236 } 9237 } 9238 9239 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 9240 if ( !m[ i ].visible ) { 9241 continue; 9242 } 9243 9244 // Activate the droppable if used directly from draggables 9245 if ( type === "mousedown" ) { 9246 m[ i ]._activate.call( m[ i ], event ); 9247 } 9248 9249 m[ i ].offset = m[ i ].element.offset(); 9250 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 9251 9252 } 9253 9254 }, 9255 drop: function( draggable, event ) { 9256 9257 var dropped = false; 9258 // Create a copy of the droppables in case the list changes during the drop (#9116)
vendor: 74,363 bytes, lines 9259-12135
9259 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 9260 9261 if ( !this.options ) { 9262 return; 9263 } 9264 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 9265 dropped = this._drop.call( this, event ) || dropped; 9266 } 9267 9268 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9269 this.isout = true; 9270 this.isover = false; 9271 this._deactivate.call( this, event ); 9272 } 9273 9274 }); 9275 return dropped; 9276 9277 }, 9278 dragStart: function( draggable, event ) { 9279 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 9280 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 9281 if ( !draggable.options.refreshPositions ) { 9282 $.ui.ddmanager.prepareOffsets( draggable, event ); 9283 } 9284 }); 9285 }, 9286 drag: function( draggable, event ) { 9287 9288 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 9289 if ( draggable.options.refreshPositions ) { 9290 $.ui.ddmanager.prepareOffsets( draggable, event ); 9291 } 9292 9293 // Run through all droppables and check their positions based on specific tolerance options 9294 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 9295 9296 if ( this.options.disabled || this.greedyChild || !this.visible ) { 9297 return; 9298 } 9299 9300 var parentInstance, scope, parent, 9301 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 9302 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); 9303 if ( !c ) { 9304 return; 9305 } 9306 9307 if ( this.options.greedy ) { 9308 // find droppable parents with same scope 9309 scope = this.options.scope; 9310 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { 9311 return $( this ).droppable( "instance" ).options.scope === scope; 9312 }); 9313 9314 if ( parent.length ) { 9315 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 9316 parentInstance.greedyChild = ( c === "isover" ); 9317 } 9318 } 9319 9320 // we just moved into a greedy child 9321 if ( parentInstance && c === "isover" ) { 9322 parentInstance.isover = false; 9323 parentInstance.isout = true; 9324 parentInstance._out.call( parentInstance, event ); 9325 } 9326 9327 this[ c ] = true; 9328 this[c === "isout" ? "isover" : "isout"] = false; 9329 this[c === "isover" ? "_over" : "_out"].call( this, event ); 9330 9331 // we just moved out of a greedy child 9332 if ( parentInstance && c === "isout" ) { 9333 parentInstance.isout = false; 9334 parentInstance.isover = true; 9335 parentInstance._over.call( parentInstance, event ); 9336 } 9337 }); 9338 9339 }, 9340 dragStop: function( draggable, event ) { 9341 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 9342 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 9343 if ( !draggable.options.refreshPositions ) { 9344 $.ui.ddmanager.prepareOffsets( draggable, event ); 9345 } 9346 } 9347}; 9348 9349var droppable = $.ui.droppable; 9350 9351 9352/*! 9353 * jQuery UI Effects 1.11.4 9354 * http://jqueryui.com 9355 * 9356 * Copyright jQuery Foundation and other contributors 9357 * Released under the MIT license. 9358 * http://jquery.org/license 9359 * 9360 * http://api.jqueryui.com/category/effects-core/ 9361 */ 9362 9363 9364var dataSpace = "ui-effects-", 9365 9366 // Create a local jQuery because jQuery Color relies on it and the 9367 // global may not exist with AMD and a custom build (#10199) 9368 jQuery = $; 9369 9370$.effects = { 9371 effect: {} 9372}; 9373 9374/*! 9375 * jQuery Color Animations v2.1.2 9376 * https://github.com/jquery/jquery-color 9377 * 9378 * Copyright 2014 jQuery Foundation and other contributors 9379 * Released under the MIT license. 9380 * http://jquery.org/license 9381 * 9382 * Date: Wed Jan 16 08:47:09 2013 -0600 9383 */ 9384(function( jQuery, undefined ) { 9385 9386 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 9387 9388 // plusequals test for += 100 -= 100 9389 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 9390 // a set of RE's that can match strings and generate color tuples. 9391 stringParsers = [ { 9392 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9393 parse: function( execResult ) { 9394 return [ 9395 execResult[ 1 ], 9396 execResult[ 2 ], 9397 execResult[ 3 ], 9398 execResult[ 4 ] 9399 ]; 9400 } 9401 }, { 9402 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9403 parse: function( execResult ) { 9404 return [ 9405 execResult[ 1 ] * 2.55, 9406 execResult[ 2 ] * 2.55, 9407 execResult[ 3 ] * 2.55, 9408 execResult[ 4 ] 9409 ]; 9410 } 9411 }, { 9412 // this regex ignores A-F because it's compared against an already lowercased string 9413 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 9414 parse: function( execResult ) { 9415 return [ 9416 parseInt( execResult[ 1 ], 16 ), 9417 parseInt( execResult[ 2 ], 16 ), 9418 parseInt( execResult[ 3 ], 16 ) 9419 ]; 9420 } 9421 }, { 9422 // this regex ignores A-F because it's compared against an already lowercased string 9423 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 9424 parse: function( execResult ) { 9425 return [ 9426 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 9427 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 9428 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 9429 ]; 9430 } 9431 }, { 9432 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9433 space: "hsla", 9434 parse: function( execResult ) { 9435 return [ 9436 execResult[ 1 ], 9437 execResult[ 2 ] / 100, 9438 execResult[ 3 ] / 100, 9439 execResult[ 4 ] 9440 ]; 9441 } 9442 } ], 9443 9444 // jQuery.Color( ) 9445 color = jQuery.Color = function( color, green, blue, alpha ) { 9446 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 9447 }, 9448 spaces = { 9449 rgba: { 9450 props: { 9451 red: { 9452 idx: 0, 9453 type: "byte" 9454 }, 9455 green: { 9456 idx: 1, 9457 type: "byte" 9458 }, 9459 blue: { 9460 idx: 2, 9461 type: "byte" 9462 } 9463 } 9464 }, 9465 9466 hsla: { 9467 props: { 9468 hue: { 9469 idx: 0, 9470 type: "degrees" 9471 }, 9472 saturation: { 9473 idx: 1, 9474 type: "percent" 9475 }, 9476 lightness: { 9477 idx: 2, 9478 type: "percent" 9479 } 9480 } 9481 } 9482 }, 9483 propTypes = { 9484 "byte": { 9485 floor: true, 9486 max: 255 9487 }, 9488 "percent": { 9489 max: 1 9490 }, 9491 "degrees": { 9492 mod: 360, 9493 floor: true 9494 } 9495 }, 9496 support = color.support = {}, 9497 9498 // element for support tests 9499 supportElem = jQuery( "<p>" )[ 0 ], 9500 9501 // colors = jQuery.Color.names 9502 colors, 9503 9504 // local aliases of functions called often 9505 each = jQuery.each; 9506 9507// determine rgba support immediately 9508supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 9509support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 9510 9511// define cache name and alpha properties 9512// for rgba and hsla spaces 9513each( spaces, function( spaceName, space ) { 9514 space.cache = "_" + spaceName; 9515 space.props.alpha = { 9516 idx: 3, 9517 type: "percent", 9518 def: 1 9519 }; 9520}); 9521 9522function clamp( value, prop, allowEmpty ) { 9523 var type = propTypes[ prop.type ] || {}; 9524 9525 if ( value == null ) { 9526 return (allowEmpty || !prop.def) ? null : prop.def; 9527 } 9528 9529 // ~~ is an short way of doing floor for positive numbers 9530 value = type.floor ? ~~value : parseFloat( value ); 9531 9532 // IE will pass in empty strings as value for alpha, 9533 // which will hit this case 9534 if ( isNaN( value ) ) { 9535 return prop.def; 9536 } 9537 9538 if ( type.mod ) { 9539 // we add mod before modding to make sure that negatives values 9540 // get converted properly: -10 -> 350 9541 return (value + type.mod) % type.mod; 9542 } 9543 9544 // for now all property types without mod have min and max 9545 return 0 > value ? 0 : type.max < value ? type.max : value; 9546} 9547 9548function stringParse( string ) { 9549 var inst = color(), 9550 rgba = inst._rgba = []; 9551 9552 string = string.toLowerCase(); 9553 9554 each( stringParsers, function( i, parser ) { 9555 var parsed, 9556 match = parser.re.exec( string ), 9557 values = match && parser.parse( match ), 9558 spaceName = parser.space || "rgba"; 9559 9560 if ( values ) { 9561 parsed = inst[ spaceName ]( values ); 9562 9563 // if this was an rgba parse the assignment might happen twice 9564 // oh well.... 9565 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 9566 rgba = inst._rgba = parsed._rgba; 9567 9568 // exit each( stringParsers ) here because we matched 9569 return false; 9570 } 9571 }); 9572 9573 // Found a stringParser that handled it 9574 if ( rgba.length ) { 9575 9576 // if this came from a parsed string, force "transparent" when alpha is 0 9577 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 9578 if ( rgba.join() === "0,0,0,0" ) { 9579 jQuery.extend( rgba, colors.transparent ); 9580 } 9581 return inst; 9582 } 9583 9584 // named colors 9585 return colors[ string ]; 9586} 9587 9588color.fn = jQuery.extend( color.prototype, { 9589 parse: function( red, green, blue, alpha ) { 9590 if ( red === undefined ) { 9591 this._rgba = [ null, null, null, null ]; 9592 return this; 9593 } 9594 if ( red.jquery || red.nodeType ) { 9595 red = jQuery( red ).css( green ); 9596 green = undefined; 9597 } 9598 9599 var inst = this, 9600 type = jQuery.type( red ), 9601 rgba = this._rgba = []; 9602 9603 // more than 1 argument specified - assume ( red, green, blue, alpha ) 9604 if ( green !== undefined ) { 9605 red = [ red, green, blue, alpha ]; 9606 type = "array"; 9607 } 9608 9609 if ( type === "string" ) { 9610 return this.parse( stringParse( red ) || colors._default ); 9611 } 9612 9613 if ( type === "array" ) { 9614 each( spaces.rgba.props, function( key, prop ) { 9615 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 9616 }); 9617 return this; 9618 } 9619 9620 if ( type === "object" ) { 9621 if ( red instanceof color ) { 9622 each( spaces, function( spaceName, space ) { 9623 if ( red[ space.cache ] ) { 9624 inst[ space.cache ] = red[ space.cache ].slice(); 9625 } 9626 }); 9627 } else { 9628 each( spaces, function( spaceName, space ) { 9629 var cache = space.cache; 9630 each( space.props, function( key, prop ) { 9631 9632 // if the cache doesn't exist, and we know how to convert 9633 if ( !inst[ cache ] && space.to ) { 9634 9635 // if the value was null, we don't need to copy it 9636 // if the key was alpha, we don't need to copy it either 9637 if ( key === "alpha" || red[ key ] == null ) { 9638 return; 9639 } 9640 inst[ cache ] = space.to( inst._rgba ); 9641 } 9642 9643 // this is the only case where we allow nulls for ALL properties. 9644 // call clamp with alwaysAllowEmpty 9645 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 9646 }); 9647 9648 // everything defined but alpha? 9649 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 9650 // use the default of 1 9651 inst[ cache ][ 3 ] = 1; 9652 if ( space.from ) { 9653 inst._rgba = space.from( inst[ cache ] ); 9654 } 9655 } 9656 }); 9657 } 9658 return this; 9659 } 9660 }, 9661 is: function( compare ) { 9662 var is = color( compare ), 9663 same = true, 9664 inst = this; 9665 9666 each( spaces, function( _, space ) { 9667 var localCache, 9668 isCache = is[ space.cache ]; 9669 if (isCache) { 9670 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 9671 each( space.props, function( _, prop ) { 9672 if ( isCache[ prop.idx ] != null ) { 9673 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 9674 return same; 9675 } 9676 }); 9677 } 9678 return same; 9679 }); 9680 return same; 9681 }, 9682 _space: function() { 9683 var used = [], 9684 inst = this; 9685 each( spaces, function( spaceName, space ) { 9686 if ( inst[ space.cache ] ) { 9687 used.push( spaceName ); 9688 } 9689 }); 9690 return used.pop(); 9691 }, 9692 transition: function( other, distance ) { 9693 var end = color( other ), 9694 spaceName = end._space(), 9695 space = spaces[ spaceName ], 9696 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 9697 start = startColor[ space.cache ] || space.to( startColor._rgba ), 9698 result = start.slice(); 9699 9700 end = end[ space.cache ]; 9701 each( space.props, function( key, prop ) { 9702 var index = prop.idx, 9703 startValue = start[ index ], 9704 endValue = end[ index ], 9705 type = propTypes[ prop.type ] || {}; 9706 9707 // if null, don't override start value 9708 if ( endValue === null ) { 9709 return; 9710 } 9711 // if null - use end 9712 if ( startValue === null ) { 9713 result[ index ] = endValue; 9714 } else { 9715 if ( type.mod ) { 9716 if ( endValue - startValue > type.mod / 2 ) { 9717 startValue += type.mod; 9718 } else if ( startValue - endValue > type.mod / 2 ) { 9719 startValue -= type.mod; 9720 } 9721 } 9722 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 9723 } 9724 }); 9725 return this[ spaceName ]( result ); 9726 }, 9727 blend: function( opaque ) { 9728 // if we are already opaque - return ourself 9729 if ( this._rgba[ 3 ] === 1 ) { 9730 return this; 9731 } 9732 9733 var rgb = this._rgba.slice(), 9734 a = rgb.pop(), 9735 blend = color( opaque )._rgba; 9736 9737 return color( jQuery.map( rgb, function( v, i ) { 9738 return ( 1 - a ) * blend[ i ] + a * v; 9739 })); 9740 }, 9741 toRgbaString: function() { 9742 var prefix = "rgba(", 9743 rgba = jQuery.map( this._rgba, function( v, i ) { 9744 return v == null ? ( i > 2 ? 1 : 0 ) : v; 9745 }); 9746 9747 if ( rgba[ 3 ] === 1 ) { 9748 rgba.pop(); 9749 prefix = "rgb("; 9750 } 9751 9752 return prefix + rgba.join() + ")"; 9753 }, 9754 toHslaString: function() { 9755 var prefix = "hsla(", 9756 hsla = jQuery.map( this.hsla(), function( v, i ) { 9757 if ( v == null ) { 9758 v = i > 2 ? 1 : 0; 9759 } 9760 9761 // catch 1 and 2 9762 if ( i && i < 3 ) { 9763 v = Math.round( v * 100 ) + "%"; 9764 } 9765 return v; 9766 }); 9767 9768 if ( hsla[ 3 ] === 1 ) { 9769 hsla.pop(); 9770 prefix = "hsl("; 9771 } 9772 return prefix + hsla.join() + ")"; 9773 }, 9774 toHexString: function( includeAlpha ) { 9775 var rgba = this._rgba.slice(), 9776 alpha = rgba.pop(); 9777 9778 if ( includeAlpha ) { 9779 rgba.push( ~~( alpha * 255 ) ); 9780 } 9781 9782 return "#" + jQuery.map( rgba, function( v ) { 9783 9784 // default to 0 when nulls exist 9785 v = ( v || 0 ).toString( 16 ); 9786 return v.length === 1 ? "0" + v : v; 9787 }).join(""); 9788 }, 9789 toString: function() { 9790 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 9791 } 9792}); 9793color.fn.parse.prototype = color.fn; 9794 9795// hsla conversions adapted from: 9796// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 9797 9798function hue2rgb( p, q, h ) { 9799 h = ( h + 1 ) % 1; 9800 if ( h * 6 < 1 ) { 9801 return p + ( q - p ) * h * 6; 9802 } 9803 if ( h * 2 < 1) { 9804 return q; 9805 } 9806 if ( h * 3 < 2 ) { 9807 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 9808 } 9809 return p; 9810} 9811 9812spaces.hsla.to = function( rgba ) { 9813 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 9814 return [ null, null, null, rgba[ 3 ] ]; 9815 } 9816 var r = rgba[ 0 ] / 255, 9817 g = rgba[ 1 ] / 255, 9818 b = rgba[ 2 ] / 255, 9819 a = rgba[ 3 ], 9820 max = Math.max( r, g, b ), 9821 min = Math.min( r, g, b ), 9822 diff = max - min, 9823 add = max + min, 9824 l = add * 0.5, 9825 h, s; 9826 9827 if ( min === max ) { 9828 h = 0; 9829 } else if ( r === max ) { 9830 h = ( 60 * ( g - b ) / diff ) + 360; 9831 } else if ( g === max ) { 9832 h = ( 60 * ( b - r ) / diff ) + 120; 9833 } else { 9834 h = ( 60 * ( r - g ) / diff ) + 240; 9835 } 9836 9837 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 9838 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 9839 if ( diff === 0 ) { 9840 s = 0; 9841 } else if ( l <= 0.5 ) { 9842 s = diff / add; 9843 } else { 9844 s = diff / ( 2 - add ); 9845 } 9846 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 9847}; 9848 9849spaces.hsla.from = function( hsla ) { 9850 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 9851 return [ null, null, null, hsla[ 3 ] ]; 9852 } 9853 var h = hsla[ 0 ] / 360, 9854 s = hsla[ 1 ], 9855 l = hsla[ 2 ], 9856 a = hsla[ 3 ], 9857 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 9858 p = 2 * l - q; 9859 9860 return [ 9861 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 9862 Math.round( hue2rgb( p, q, h ) * 255 ), 9863 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 9864 a 9865 ]; 9866}; 9867 9868each( spaces, function( spaceName, space ) { 9869 var props = space.props, 9870 cache = space.cache, 9871 to = space.to, 9872 from = space.from; 9873 9874 // makes rgba() and hsla() 9875 color.fn[ spaceName ] = function( value ) { 9876 9877 // generate a cache for this space if it doesn't exist 9878 if ( to && !this[ cache ] ) { 9879 this[ cache ] = to( this._rgba ); 9880 } 9881 if ( value === undefined ) { 9882 return this[ cache ].slice(); 9883 } 9884 9885 var ret, 9886 type = jQuery.type( value ), 9887 arr = ( type === "array" || type === "object" ) ? value : arguments, 9888 local = this[ cache ].slice(); 9889 9890 each( props, function( key, prop ) { 9891 var val = arr[ type === "object" ? key : prop.idx ]; 9892 if ( val == null ) { 9893 val = local[ prop.idx ]; 9894 } 9895 local[ prop.idx ] = clamp( val, prop ); 9896 }); 9897 9898 if ( from ) { 9899 ret = color( from( local ) ); 9900 ret[ cache ] = local; 9901 return ret; 9902 } else { 9903 return color( local ); 9904 } 9905 }; 9906 9907 // makes red() green() blue() alpha() hue() saturation() lightness() 9908 each( props, function( key, prop ) { 9909 // alpha is included in more than one space 9910 if ( color.fn[ key ] ) { 9911 return; 9912 } 9913 color.fn[ key ] = function( value ) { 9914 var vtype = jQuery.type( value ), 9915 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 9916 local = this[ fn ](), 9917 cur = local[ prop.idx ], 9918 match; 9919 9920 if ( vtype === "undefined" ) { 9921 return cur; 9922 } 9923 9924 if ( vtype === "function" ) { 9925 value = value.call( this, cur ); 9926 vtype = jQuery.type( value ); 9927 } 9928 if ( value == null && prop.empty ) { 9929 return this; 9930 } 9931 if ( vtype === "string" ) { 9932 match = rplusequals.exec( value ); 9933 if ( match ) { 9934 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 9935 } 9936 } 9937 local[ prop.idx ] = value; 9938 return this[ fn ]( local ); 9939 }; 9940 }); 9941}); 9942 9943// add cssHook and .fx.step function for each named hook. 9944// accept a space separated string of properties 9945color.hook = function( hook ) { 9946 var hooks = hook.split( " " ); 9947 each( hooks, function( i, hook ) { 9948 jQuery.cssHooks[ hook ] = { 9949 set: function( elem, value ) { 9950 var parsed, curElem, 9951 backgroundColor = ""; 9952 9953 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 9954 value = color( parsed || value ); 9955 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 9956 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 9957 while ( 9958 (backgroundColor === "" || backgroundColor === "transparent") && 9959 curElem && curElem.style 9960 ) { 9961 try { 9962 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 9963 curElem = curElem.parentNode; 9964 } catch ( e ) { 9965 } 9966 } 9967 9968 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 9969 backgroundColor : 9970 "_default" ); 9971 } 9972 9973 value = value.toRgbaString(); 9974 } 9975 try { 9976 elem.style[ hook ] = value; 9977 } catch ( e ) { 9978 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 9979 } 9980 } 9981 }; 9982 jQuery.fx.step[ hook ] = function( fx ) { 9983 if ( !fx.colorInit ) { 9984 fx.start = color( fx.elem, hook ); 9985 fx.end = color( fx.end ); 9986 fx.colorInit = true; 9987 } 9988 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 9989 }; 9990 }); 9991 9992}; 9993 9994color.hook( stepHooks ); 9995 9996jQuery.cssHooks.borderColor = { 9997 expand: function( value ) { 9998 var expanded = {}; 9999 10000 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 10001 expanded[ "border" + part + "Color" ] = value; 10002 }); 10003 return expanded; 10004 } 10005}; 10006 10007// Basic color names only. 10008// Usage of any of the other color names requires adding yourself or including 10009// jquery.color.svg-names.js. 10010colors = jQuery.Color.names = { 10011 // 4.1. Basic color keywords 10012 aqua: "#00ffff", 10013 black: "#000000", 10014 blue: "#0000ff", 10015 fuchsia: "#ff00ff", 10016 gray: "#808080", 10017 green: "#008000", 10018 lime: "#00ff00", 10019 maroon: "#800000", 10020 navy: "#000080", 10021 olive: "#808000", 10022 purple: "#800080", 10023 red: "#ff0000", 10024 silver: "#c0c0c0", 10025 teal: "#008080", 10026 white: "#ffffff", 10027 yellow: "#ffff00", 10028 10029 // 4.2.3. "transparent" color keyword 10030 transparent: [ null, null, null, 0 ], 10031 10032 _default: "#ffffff" 10033}; 10034 10035})( jQuery ); 10036 10037/******************************************************************************/ 10038/****************************** CLASS ANIMATIONS ******************************/ 10039/******************************************************************************/ 10040(function() { 10041 10042var classAnimationActions = [ "add", "remove", "toggle" ], 10043 shorthandStyles = { 10044 border: 1, 10045 borderBottom: 1, 10046 borderColor: 1, 10047 borderLeft: 1, 10048 borderRight: 1, 10049 borderTop: 1, 10050 borderWidth: 1, 10051 margin: 1, 10052 padding: 1 10053 }; 10054 10055$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 10056 $.fx.step[ prop ] = function( fx ) { 10057 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 10058 jQuery.style( fx.elem, prop, fx.end ); 10059 fx.setAttr = true; 10060 } 10061 }; 10062}); 10063 10064function getElementStyles( elem ) { 10065 var key, len, 10066 style = elem.ownerDocument.defaultView ? 10067 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 10068 elem.currentStyle, 10069 styles = {}; 10070 10071 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 10072 len = style.length; 10073 while ( len-- ) { 10074 key = style[ len ]; 10075 if ( typeof style[ key ] === "string" ) { 10076 styles[ $.camelCase( key ) ] = style[ key ]; 10077 } 10078 } 10079 // support: Opera, IE <9 10080 } else { 10081 for ( key in style ) { 10082 if ( typeof style[ key ] === "string" ) { 10083 styles[ key ] = style[ key ]; 10084 } 10085 } 10086 } 10087 10088 return styles; 10089} 10090 10091function styleDifference( oldStyle, newStyle ) { 10092 var diff = {}, 10093 name, value; 10094 10095 for ( name in newStyle ) { 10096 value = newStyle[ name ]; 10097 if ( oldStyle[ name ] !== value ) { 10098 if ( !shorthandStyles[ name ] ) { 10099 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 10100 diff[ name ] = value; 10101 } 10102 } 10103 } 10104 } 10105 10106 return diff; 10107} 10108 10109// support: jQuery <1.8 10110if ( !$.fn.addBack ) { 10111 $.fn.addBack = function( selector ) { 10112 return this.add( selector == null ? 10113 this.prevObject : this.prevObject.filter( selector ) 10114 ); 10115 }; 10116} 10117 10118$.effects.animateClass = function( value, duration, easing, callback ) { 10119 var o = $.speed( duration, easing, callback ); 10120 10121 return this.queue( function() { 10122 var animated = $( this ), 10123 baseClass = animated.attr( "class" ) || "", 10124 applyClassChange, 10125 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 10126 10127 // map the animated objects to store the original styles. 10128 allAnimations = allAnimations.map(function() { 10129 var el = $( this ); 10130 return { 10131 el: el, 10132 start: getElementStyles( this ) 10133 }; 10134 }); 10135 10136 // apply class change 10137 applyClassChange = function() { 10138 $.each( classAnimationActions, function(i, action) { 10139 if ( value[ action ] ) { 10140 animated[ action + "Class" ]( value[ action ] ); 10141 } 10142 }); 10143 }; 10144 applyClassChange(); 10145 10146 // map all animated objects again - calculate new styles and diff 10147 allAnimations = allAnimations.map(function() { 10148 this.end = getElementStyles( this.el[ 0 ] ); 10149 this.diff = styleDifference( this.start, this.end ); 10150 return this; 10151 }); 10152 10153 // apply original class 10154 animated.attr( "class", baseClass ); 10155 10156 // map all animated objects again - this time collecting a promise 10157 allAnimations = allAnimations.map(function() { 10158 var styleInfo = this, 10159 dfd = $.Deferred(), 10160 opts = $.extend({}, o, { 10161 queue: false, 10162 complete: function() { 10163 dfd.resolve( styleInfo ); 10164 } 10165 }); 10166 10167 this.el.animate( this.diff, opts ); 10168 return dfd.promise(); 10169 }); 10170 10171 // once all animations have completed: 10172 $.when.apply( $, allAnimations.get() ).done(function() { 10173 10174 // set the final class 10175 applyClassChange(); 10176 10177 // for each animated element, 10178 // clear all css properties that were animated 10179 $.each( arguments, function() { 10180 var el = this.el; 10181 $.each( this.diff, function(key) { 10182 el.css( key, "" ); 10183 }); 10184 }); 10185 10186 // this is guarnteed to be there if you use jQuery.speed() 10187 // it also handles dequeuing the next anim... 10188 o.complete.call( animated[ 0 ] ); 10189 }); 10190 }); 10191}; 10192 10193$.fn.extend({ 10194 addClass: (function( orig ) { 10195 return function( classNames, speed, easing, callback ) { 10196 return speed ? 10197 $.effects.animateClass.call( this, 10198 { add: classNames }, speed, easing, callback ) : 10199 orig.apply( this, arguments ); 10200 }; 10201 })( $.fn.addClass ), 10202 10203 removeClass: (function( orig ) { 10204 return function( classNames, speed, easing, callback ) { 10205 return arguments.length > 1 ? 10206 $.effects.animateClass.call( this, 10207 { remove: classNames }, speed, easing, callback ) : 10208 orig.apply( this, arguments ); 10209 }; 10210 })( $.fn.removeClass ), 10211 10212 toggleClass: (function( orig ) { 10213 return function( classNames, force, speed, easing, callback ) { 10214 if ( typeof force === "boolean" || force === undefined ) { 10215 if ( !speed ) { 10216 // without speed parameter 10217 return orig.apply( this, arguments ); 10218 } else { 10219 return $.effects.animateClass.call( this, 10220 (force ? { add: classNames } : { remove: classNames }), 10221 speed, easing, callback ); 10222 } 10223 } else { 10224 // without force parameter 10225 return $.effects.animateClass.call( this, 10226 { toggle: classNames }, force, speed, easing ); 10227 } 10228 }; 10229 })( $.fn.toggleClass ), 10230 10231 switchClass: function( remove, add, speed, easing, callback) { 10232 return $.effects.animateClass.call( this, { 10233 add: add, 10234 remove: remove 10235 }, speed, easing, callback ); 10236 } 10237}); 10238 10239})(); 10240 10241/******************************************************************************/ 10242/*********************************** EFFECTS **********************************/ 10243/******************************************************************************/ 10244 10245(function() { 10246 10247$.extend( $.effects, { 10248 version: "1.11.4", 10249 10250 // Saves a set of properties in a data storage 10251 save: function( element, set ) { 10252 for ( var i = 0; i < set.length; i++ ) { 10253 if ( set[ i ] !== null ) { 10254 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 10255 } 10256 } 10257 }, 10258 10259 // Restores a set of previously saved properties from a data storage 10260 restore: function( element, set ) { 10261 var val, i; 10262 for ( i = 0; i < set.length; i++ ) { 10263 if ( set[ i ] !== null ) { 10264 val = element.data( dataSpace + set[ i ] ); 10265 // support: jQuery 1.6.2 10266 // http://bugs.jquery.com/ticket/9917 10267 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 10268 // We can't differentiate between "" and 0 here, so we just assume 10269 // empty string since it's likely to be a more common value... 10270 if ( val === undefined ) { 10271 val = ""; 10272 } 10273 element.css( set[ i ], val ); 10274 } 10275 } 10276 }, 10277 10278 setMode: function( el, mode ) { 10279 if (mode === "toggle") { 10280 mode = el.is( ":hidden" ) ? "show" : "hide"; 10281 } 10282 return mode; 10283 }, 10284 10285 // Translates a [top,left] array into a baseline value 10286 // this should be a little more flexible in the future to handle a string & hash 10287 getBaseline: function( origin, original ) { 10288 var y, x; 10289 switch ( origin[ 0 ] ) { 10290 case "top": y = 0; break; 10291 case "middle": y = 0.5; break; 10292 case "bottom": y = 1; break; 10293 default: y = origin[ 0 ] / original.height; 10294 } 10295 switch ( origin[ 1 ] ) { 10296 case "left": x = 0; break; 10297 case "center": x = 0.5; break; 10298 case "right": x = 1; break; 10299 default: x = origin[ 1 ] / original.width; 10300 } 10301 return { 10302 x: x, 10303 y: y 10304 }; 10305 }, 10306 10307 // Wraps the element around a wrapper that copies position properties 10308 createWrapper: function( element ) { 10309 10310 // if the element is already wrapped, return it 10311 if ( element.parent().is( ".ui-effects-wrapper" )) { 10312 return element.parent(); 10313 } 10314 10315 // wrap the element 10316 var props = { 10317 width: element.outerWidth(true), 10318 height: element.outerHeight(true), 10319 "float": element.css( "float" ) 10320 }, 10321 wrapper = $( "<div></div>" ) 10322 .addClass( "ui-effects-wrapper" ) 10323 .css({ 10324 fontSize: "100%", 10325 background: "transparent", 10326 border: "none", 10327 margin: 0, 10328 padding: 0 10329 }), 10330 // Store the size in case width/height are defined in % - Fixes #5245 10331 size = { 10332 width: element.width(), 10333 height: element.height() 10334 }, 10335 active = document.activeElement; 10336 10337 // support: Firefox 10338 // Firefox incorrectly exposes anonymous content 10339 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 10340 try { 10341 active.id; 10342 } catch ( e ) { 10343 active = document.body; 10344 } 10345 10346 element.wrap( wrapper ); 10347 10348 // Fixes #7595 - Elements lose focus when wrapped. 10349 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10350 $( active ).focus(); 10351 } 10352 10353 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 10354 10355 // transfer positioning properties to the wrapper 10356 if ( element.css( "position" ) === "static" ) { 10357 wrapper.css({ position: "relative" }); 10358 element.css({ position: "relative" }); 10359 } else { 10360 $.extend( props, { 10361 position: element.css( "position" ), 10362 zIndex: element.css( "z-index" ) 10363 }); 10364 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 10365 props[ pos ] = element.css( pos ); 10366 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 10367 props[ pos ] = "auto"; 10368 } 10369 }); 10370 element.css({ 10371 position: "relative", 10372 top: 0, 10373 left: 0, 10374 right: "auto", 10375 bottom: "auto" 10376 }); 10377 } 10378 element.css(size); 10379 10380 return wrapper.css( props ).show(); 10381 }, 10382 10383 removeWrapper: function( element ) { 10384 var active = document.activeElement; 10385 10386 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 10387 element.parent().replaceWith( element ); 10388 10389 // Fixes #7595 - Elements lose focus when wrapped. 10390 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10391 $( active ).focus(); 10392 } 10393 } 10394 10395 return element; 10396 }, 10397 10398 setTransition: function( element, list, factor, value ) { 10399 value = value || {}; 10400 $.each( list, function( i, x ) { 10401 var unit = element.cssUnit( x ); 10402 if ( unit[ 0 ] > 0 ) { 10403 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 10404 } 10405 }); 10406 return value; 10407 } 10408}); 10409 10410// return an effect options object for the given parameters: 10411function _normalizeArguments( effect, options, speed, callback ) { 10412 10413 // allow passing all options as the first parameter 10414 if ( $.isPlainObject( effect ) ) { 10415 options = effect; 10416 effect = effect.effect; 10417 } 10418 10419 // convert to an object 10420 effect = { effect: effect }; 10421 10422 // catch (effect, null, ...) 10423 if ( options == null ) { 10424 options = {}; 10425 } 10426 10427 // catch (effect, callback) 10428 if ( $.isFunction( options ) ) { 10429 callback = options; 10430 speed = null; 10431 options = {}; 10432 } 10433 10434 // catch (effect, speed, ?) 10435 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 10436 callback = speed; 10437 speed = options; 10438 options = {}; 10439 } 10440 10441 // catch (effect, options, callback) 10442 if ( $.isFunction( speed ) ) { 10443 callback = speed; 10444 speed = null; 10445 } 10446 10447 // add options to effect 10448 if ( options ) { 10449 $.extend( effect, options ); 10450 } 10451 10452 speed = speed || options.duration; 10453 effect.duration = $.fx.off ? 0 : 10454 typeof speed === "number" ? speed : 10455 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 10456 $.fx.speeds._default; 10457 10458 effect.complete = callback || options.complete; 10459 10460 return effect; 10461} 10462 10463function standardAnimationOption( option ) { 10464 // Valid standard speeds (nothing, number, named speed) 10465 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 10466 return true; 10467 } 10468 10469 // Invalid strings - treat as "normal" speed 10470 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 10471 return true; 10472 } 10473 10474 // Complete callback 10475 if ( $.isFunction( option ) ) { 10476 return true; 10477 } 10478 10479 // Options hash (but not naming an effect) 10480 if ( typeof option === "object" && !option.effect ) { 10481 return true; 10482 } 10483 10484 // Didn't match any standard API 10485 return false; 10486} 10487 10488$.fn.extend({ 10489 effect: function( /* effect, options, speed, callback */ ) { 10490 var args = _normalizeArguments.apply( this, arguments ), 10491 mode = args.mode, 10492 queue = args.queue, 10493 effectMethod = $.effects.effect[ args.effect ]; 10494 10495 if ( $.fx.off || !effectMethod ) { 10496 // delegate to the original method (e.g., .show()) if possible 10497 if ( mode ) { 10498 return this[ mode ]( args.duration, args.complete ); 10499 } else { 10500 return this.each( function() { 10501 if ( args.complete ) { 10502 args.complete.call( this ); 10503 } 10504 }); 10505 } 10506 } 10507 10508 function run( next ) { 10509 var elem = $( this ), 10510 complete = args.complete, 10511 mode = args.mode; 10512 10513 function done() { 10514 if ( $.isFunction( complete ) ) { 10515 complete.call( elem[0] ); 10516 } 10517 if ( $.isFunction( next ) ) { 10518 next(); 10519 } 10520 } 10521 10522 // If the element already has the correct final state, delegate to 10523 // the core methods so the internal tracking of "olddisplay" works. 10524 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 10525 elem[ mode ](); 10526 done(); 10527 } else { 10528 effectMethod.call( elem[0], args, done ); 10529 } 10530 } 10531 10532 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 10533 }, 10534 10535 show: (function( orig ) { 10536 return function( option ) { 10537 if ( standardAnimationOption( option ) ) { 10538 return orig.apply( this, arguments ); 10539 } else { 10540 var args = _normalizeArguments.apply( this, arguments ); 10541 args.mode = "show"; 10542 return this.effect.call( this, args ); 10543 } 10544 }; 10545 })( $.fn.show ), 10546 10547 hide: (function( orig ) { 10548 return function( option ) { 10549 if ( standardAnimationOption( option ) ) { 10550 return orig.apply( this, arguments ); 10551 } else { 10552 var args = _normalizeArguments.apply( this, arguments ); 10553 args.mode = "hide"; 10554 return this.effect.call( this, args ); 10555 } 10556 }; 10557 })( $.fn.hide ), 10558 10559 toggle: (function( orig ) { 10560 return function( option ) { 10561 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 10562 return orig.apply( this, arguments ); 10563 } else { 10564 var args = _normalizeArguments.apply( this, arguments ); 10565 args.mode = "toggle"; 10566 return this.effect.call( this, args ); 10567 } 10568 }; 10569 })( $.fn.toggle ), 10570 10571 // helper functions 10572 cssUnit: function(key) { 10573 var style = this.css( key ), 10574 val = []; 10575 10576 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 10577 if ( style.indexOf( unit ) > 0 ) { 10578 val = [ parseFloat( style ), unit ]; 10579 } 10580 }); 10581 return val; 10582 } 10583}); 10584 10585})(); 10586 10587/******************************************************************************/ 10588/*********************************** EASING ***********************************/ 10589/******************************************************************************/ 10590 10591(function() { 10592 10593// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 10594 10595var baseEasings = {}; 10596 10597$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 10598 baseEasings[ name ] = function( p ) { 10599 return Math.pow( p, i + 2 ); 10600 }; 10601}); 10602 10603$.extend( baseEasings, { 10604 Sine: function( p ) { 10605 return 1 - Math.cos( p * Math.PI / 2 ); 10606 }, 10607 Circ: function( p ) { 10608 return 1 - Math.sqrt( 1 - p * p ); 10609 }, 10610 Elastic: function( p ) { 10611 return p === 0 || p === 1 ? p : 10612 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 10613 }, 10614 Back: function( p ) { 10615 return p * p * ( 3 * p - 2 ); 10616 }, 10617 Bounce: function( p ) { 10618 var pow2, 10619 bounce = 4; 10620 10621 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 10622 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 10623 } 10624}); 10625 10626$.each( baseEasings, function( name, easeIn ) { 10627 $.easing[ "easeIn" + name ] = easeIn; 10628 $.easing[ "easeOut" + name ] = function( p ) { 10629 return 1 - easeIn( 1 - p ); 10630 }; 10631 $.easing[ "easeInOut" + name ] = function( p ) { 10632 return p < 0.5 ? 10633 easeIn( p * 2 ) / 2 : 10634 1 - easeIn( p * -2 + 2 ) / 2; 10635 }; 10636}); 10637 10638})(); 10639 10640var effect = $.effects; 10641 10642 10643/*! 10644 * jQuery UI Effects Blind 1.11.4 10645 * http://jqueryui.com 10646 * 10647 * Copyright jQuery Foundation and other contributors 10648 * Released under the MIT license. 10649 * http://jquery.org/license 10650 * 10651 * http://api.jqueryui.com/blind-effect/ 10652 */ 10653 10654 10655var effectBlind = $.effects.effect.blind = function( o, done ) { 10656 // Create element 10657 var el = $( this ), 10658 rvertical = /up|down|vertical/, 10659 rpositivemotion = /up|left|vertical|horizontal/, 10660 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10661 mode = $.effects.setMode( el, o.mode || "hide" ), 10662 direction = o.direction || "up", 10663 vertical = rvertical.test( direction ), 10664 ref = vertical ? "height" : "width", 10665 ref2 = vertical ? "top" : "left", 10666 motion = rpositivemotion.test( direction ), 10667 animation = {}, 10668 show = mode === "show", 10669 wrapper, distance, margin; 10670 10671 // if already wrapped, the wrapper's properties are my property. #6245 10672 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10673 $.effects.save( el.parent(), props ); 10674 } else { 10675 $.effects.save( el, props ); 10676 } 10677 el.show(); 10678 wrapper = $.effects.createWrapper( el ).css({ 10679 overflow: "hidden" 10680 }); 10681 10682 distance = wrapper[ ref ](); 10683 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10684 10685 animation[ ref ] = show ? distance : 0; 10686 if ( !motion ) { 10687 el 10688 .css( vertical ? "bottom" : "right", 0 ) 10689 .css( vertical ? "top" : "left", "auto" ) 10690 .css({ position: "absolute" }); 10691 10692 animation[ ref2 ] = show ? margin : distance + margin; 10693 } 10694 10695 // start at 0 if we are showing 10696 if ( show ) { 10697 wrapper.css( ref, 0 ); 10698 if ( !motion ) { 10699 wrapper.css( ref2, margin + distance ); 10700 } 10701 } 10702 10703 // Animate 10704 wrapper.animate( animation, { 10705 duration: o.duration, 10706 easing: o.easing, 10707 queue: false, 10708 complete: function() { 10709 if ( mode === "hide" ) { 10710 el.hide(); 10711 } 10712 $.effects.restore( el, props ); 10713 $.effects.removeWrapper( el ); 10714 done(); 10715 } 10716 }); 10717}; 10718 10719 10720/*! 10721 * jQuery UI Effects Bounce 1.11.4 10722 * http://jqueryui.com 10723 * 10724 * Copyright jQuery Foundation and other contributors 10725 * Released under the MIT license. 10726 * http://jquery.org/license 10727 * 10728 * http://api.jqueryui.com/bounce-effect/ 10729 */ 10730 10731 10732var effectBounce = $.effects.effect.bounce = function( o, done ) { 10733 var el = $( this ), 10734 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10735 10736 // defaults: 10737 mode = $.effects.setMode( el, o.mode || "effect" ), 10738 hide = mode === "hide", 10739 show = mode === "show", 10740 direction = o.direction || "up", 10741 distance = o.distance, 10742 times = o.times || 5, 10743 10744 // number of internal animations 10745 anims = times * 2 + ( show || hide ? 1 : 0 ), 10746 speed = o.duration / anims, 10747 easing = o.easing, 10748 10749 // utility: 10750 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10751 motion = ( direction === "up" || direction === "left" ), 10752 i, 10753 upAnim, 10754 downAnim, 10755 10756 // we will need to re-assemble the queue to stack our animations in place 10757 queue = el.queue(), 10758 queuelen = queue.length; 10759 10760 // Avoid touching opacity to prevent clearType and PNG issues in IE 10761 if ( show || hide ) { 10762 props.push( "opacity" ); 10763 } 10764 10765 $.effects.save( el, props ); 10766 el.show(); 10767 $.effects.createWrapper( el ); // Create Wrapper 10768 10769 // default distance for the BIGGEST bounce is the outer Distance / 3 10770 if ( !distance ) { 10771 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10772 } 10773 10774 if ( show ) { 10775 downAnim = { opacity: 1 }; 10776 downAnim[ ref ] = 0; 10777 10778 // if we are showing, force opacity 0 and set the initial position 10779 // then do the "first" animation 10780 el.css( "opacity", 0 ) 10781 .css( ref, motion ? -distance * 2 : distance * 2 ) 10782 .animate( downAnim, speed, easing ); 10783 } 10784 10785 // start at the smallest distance if we are hiding 10786 if ( hide ) { 10787 distance = distance / Math.pow( 2, times - 1 ); 10788 } 10789 10790 downAnim = {}; 10791 downAnim[ ref ] = 0; 10792 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10793 for ( i = 0; i < times; i++ ) { 10794 upAnim = {}; 10795 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10796 10797 el.animate( upAnim, speed, easing ) 10798 .animate( downAnim, speed, easing ); 10799 10800 distance = hide ? distance * 2 : distance / 2; 10801 } 10802 10803 // Last Bounce when Hiding 10804 if ( hide ) { 10805 upAnim = { opacity: 0 }; 10806 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10807 10808 el.animate( upAnim, speed, easing ); 10809 } 10810 10811 el.queue(function() { 10812 if ( hide ) { 10813 el.hide(); 10814 } 10815 $.effects.restore( el, props ); 10816 $.effects.removeWrapper( el ); 10817 done(); 10818 }); 10819 10820 // inject all the animations we just queued to be first in line (after "inprogress") 10821 if ( queuelen > 1) { 10822 queue.splice.apply( queue, 10823 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10824 } 10825 el.dequeue(); 10826 10827}; 10828 10829 10830/*! 10831 * jQuery UI Effects Clip 1.11.4 10832 * http://jqueryui.com 10833 * 10834 * Copyright jQuery Foundation and other contributors 10835 * Released under the MIT license. 10836 * http://jquery.org/license 10837 * 10838 * http://api.jqueryui.com/clip-effect/ 10839 */ 10840 10841 10842var effectClip = $.effects.effect.clip = function( o, done ) { 10843 // Create element 10844 var el = $( this ), 10845 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10846 mode = $.effects.setMode( el, o.mode || "hide" ), 10847 show = mode === "show", 10848 direction = o.direction || "vertical", 10849 vert = direction === "vertical", 10850 size = vert ? "height" : "width", 10851 position = vert ? "top" : "left", 10852 animation = {}, 10853 wrapper, animate, distance; 10854 10855 // Save & Show 10856 $.effects.save( el, props ); 10857 el.show(); 10858 10859 // Create Wrapper 10860 wrapper = $.effects.createWrapper( el ).css({ 10861 overflow: "hidden" 10862 }); 10863 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10864 distance = animate[ size ](); 10865 10866 // Shift 10867 if ( show ) { 10868 animate.css( size, 0 ); 10869 animate.css( position, distance / 2 ); 10870 } 10871 10872 // Create Animation Object: 10873 animation[ size ] = show ? distance : 0; 10874 animation[ position ] = show ? 0 : distance / 2; 10875 10876 // Animate 10877 animate.animate( animation, { 10878 queue: false, 10879 duration: o.duration, 10880 easing: o.easing, 10881 complete: function() { 10882 if ( !show ) { 10883 el.hide(); 10884 } 10885 $.effects.restore( el, props ); 10886 $.effects.removeWrapper( el ); 10887 done(); 10888 } 10889 }); 10890 10891}; 10892 10893 10894/*! 10895 * jQuery UI Effects Drop 1.11.4 10896 * http://jqueryui.com 10897 * 10898 * Copyright jQuery Foundation and other contributors 10899 * Released under the MIT license. 10900 * http://jquery.org/license 10901 * 10902 * http://api.jqueryui.com/drop-effect/ 10903 */ 10904 10905 10906var effectDrop = $.effects.effect.drop = function( o, done ) { 10907 10908 var el = $( this ), 10909 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10910 mode = $.effects.setMode( el, o.mode || "hide" ), 10911 show = mode === "show", 10912 direction = o.direction || "left", 10913 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10914 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10915 animation = { 10916 opacity: show ? 1 : 0 10917 }, 10918 distance; 10919 10920 // Adjust 10921 $.effects.save( el, props ); 10922 el.show(); 10923 $.effects.createWrapper( el ); 10924 10925 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 10926 10927 if ( show ) { 10928 el 10929 .css( "opacity", 0 ) 10930 .css( ref, motion === "pos" ? -distance : distance ); 10931 } 10932 10933 // Animation 10934 animation[ ref ] = ( show ? 10935 ( motion === "pos" ? "+=" : "-=" ) : 10936 ( motion === "pos" ? "-=" : "+=" ) ) + 10937 distance; 10938 10939 // Animate 10940 el.animate( animation, { 10941 queue: false, 10942 duration: o.duration, 10943 easing: o.easing, 10944 complete: function() { 10945 if ( mode === "hide" ) { 10946 el.hide(); 10947 } 10948 $.effects.restore( el, props ); 10949 $.effects.removeWrapper( el ); 10950 done(); 10951 } 10952 }); 10953}; 10954 10955 10956/*! 10957 * jQuery UI Effects Explode 1.11.4 10958 * http://jqueryui.com 10959 * 10960 * Copyright jQuery Foundation and other contributors 10961 * Released under the MIT license. 10962 * http://jquery.org/license 10963 * 10964 * http://api.jqueryui.com/explode-effect/ 10965 */ 10966 10967 10968var effectExplode = $.effects.effect.explode = function( o, done ) { 10969 10970 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10971 cells = rows, 10972 el = $( this ), 10973 mode = $.effects.setMode( el, o.mode || "hide" ), 10974 show = mode === "show", 10975 10976 // show and then visibility:hidden the element before calculating offset 10977 offset = el.show().css( "visibility", "hidden" ).offset(), 10978 10979 // width and height of a piece 10980 width = Math.ceil( el.outerWidth() / cells ), 10981 height = Math.ceil( el.outerHeight() / rows ), 10982 pieces = [], 10983 10984 // loop 10985 i, j, left, top, mx, my; 10986 10987 // children animate complete: 10988 function childComplete() { 10989 pieces.push( this ); 10990 if ( pieces.length === rows * cells ) { 10991 animComplete(); 10992 } 10993 } 10994 10995 // clone the element for each row and cell. 10996 for ( i = 0; i < rows ; i++ ) { // ===> 10997 top = offset.top + i * height; 10998 my = i - ( rows - 1 ) / 2 ; 10999 11000 for ( j = 0; j < cells ; j++ ) { // ||| 11001 left = offset.left + j * width; 11002 mx = j - ( cells - 1 ) / 2 ; 11003 11004 // Create a clone of the now hidden main element that will be absolute positioned 11005 // within a wrapper div off the -left and -top equal to size of our pieces 11006 el 11007 .clone() 11008 .appendTo( "body" ) 11009 .wrap( "<div></div>" ) 11010 .css({ 11011 position: "absolute", 11012 visibility: "visible", 11013 left: -j * width, 11014 top: -i * height 11015 }) 11016 11017 // select the wrapper - make it overflow: hidden and absolute positioned based on 11018 // where the original was located +left and +top equal to the size of pieces 11019 .parent() 11020 .addClass( "ui-effects-explode" ) 11021 .css({ 11022 position: "absolute", 11023 overflow: "hidden", 11024 width: width, 11025 height: height, 11026 left: left + ( show ? mx * width : 0 ), 11027 top: top + ( show ? my * height : 0 ), 11028 opacity: show ? 0 : 1 11029 }).animate({ 11030 left: left + ( show ? 0 : mx * width ), 11031 top: top + ( show ? 0 : my * height ), 11032 opacity: show ? 1 : 0 11033 }, o.duration || 500, o.easing, childComplete ); 11034 } 11035 } 11036 11037 function animComplete() { 11038 el.css({ 11039 visibility: "visible" 11040 }); 11041 $( pieces ).remove(); 11042 if ( !show ) { 11043 el.hide(); 11044 } 11045 done(); 11046 } 11047}; 11048 11049 11050/*! 11051 * jQuery UI Effects Fade 1.11.4 11052 * http://jqueryui.com 11053 * 11054 * Copyright jQuery Foundation and other contributors 11055 * Released under the MIT license. 11056 * http://jquery.org/license 11057 * 11058 * http://api.jqueryui.com/fade-effect/ 11059 */ 11060 11061 11062var effectFade = $.effects.effect.fade = function( o, done ) { 11063 var el = $( this ), 11064 mode = $.effects.setMode( el, o.mode || "toggle" ); 11065 11066 el.animate({ 11067 opacity: mode 11068 }, { 11069 queue: false, 11070 duration: o.duration, 11071 easing: o.easing, 11072 complete: done 11073 }); 11074}; 11075 11076 11077/*! 11078 * jQuery UI Effects Fold 1.11.4 11079 * http://jqueryui.com 11080 * 11081 * Copyright jQuery Foundation and other contributors 11082 * Released under the MIT license. 11083 * http://jquery.org/license 11084 * 11085 * http://api.jqueryui.com/fold-effect/ 11086 */ 11087 11088 11089var effectFold = $.effects.effect.fold = function( o, done ) { 11090 11091 // Create element 11092 var el = $( this ), 11093 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11094 mode = $.effects.setMode( el, o.mode || "hide" ), 11095 show = mode === "show", 11096 hide = mode === "hide", 11097 size = o.size || 15, 11098 percent = /([0-9]+)%/.exec( size ), 11099 horizFirst = !!o.horizFirst, 11100 widthFirst = show !== horizFirst, 11101 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 11102 duration = o.duration / 2, 11103 wrapper, distance, 11104 animation1 = {}, 11105 animation2 = {}; 11106 11107 $.effects.save( el, props ); 11108 el.show(); 11109 11110 // Create Wrapper 11111 wrapper = $.effects.createWrapper( el ).css({ 11112 overflow: "hidden" 11113 }); 11114 distance = widthFirst ? 11115 [ wrapper.width(), wrapper.height() ] : 11116 [ wrapper.height(), wrapper.width() ]; 11117 11118 if ( percent ) { 11119 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 11120 } 11121 if ( show ) { 11122 wrapper.css( horizFirst ? { 11123 height: 0, 11124 width: size 11125 } : { 11126 height: size, 11127 width: 0 11128 }); 11129 } 11130 11131 // Animation 11132 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 11133 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 11134 11135 // Animate 11136 wrapper 11137 .animate( animation1, duration, o.easing ) 11138 .animate( animation2, duration, o.easing, function() { 11139 if ( hide ) { 11140 el.hide(); 11141 } 11142 $.effects.restore( el, props ); 11143 $.effects.removeWrapper( el ); 11144 done(); 11145 }); 11146 11147}; 11148 11149 11150/*! 11151 * jQuery UI Effects Highlight 1.11.4 11152 * http://jqueryui.com 11153 * 11154 * Copyright jQuery Foundation and other contributors 11155 * Released under the MIT license. 11156 * http://jquery.org/license 11157 * 11158 * http://api.jqueryui.com/highlight-effect/ 11159 */ 11160 11161 11162var effectHighlight = $.effects.effect.highlight = function( o, done ) { 11163 var elem = $( this ), 11164 props = [ "backgroundImage", "backgroundColor", "opacity" ], 11165 mode = $.effects.setMode( elem, o.mode || "show" ), 11166 animation = { 11167 backgroundColor: elem.css( "backgroundColor" ) 11168 }; 11169 11170 if (mode === "hide") { 11171 animation.opacity = 0; 11172 } 11173 11174 $.effects.save( elem, props ); 11175 11176 elem 11177 .show() 11178 .css({ 11179 backgroundImage: "none", 11180 backgroundColor: o.color || "#ffff99" 11181 }) 11182 .animate( animation, { 11183 queue: false, 11184 duration: o.duration, 11185 easing: o.easing, 11186 complete: function() { 11187 if ( mode === "hide" ) { 11188 elem.hide(); 11189 } 11190 $.effects.restore( elem, props ); 11191 done(); 11192 } 11193 }); 11194}; 11195 11196 11197/*! 11198 * jQuery UI Effects Size 1.11.4 11199 * http://jqueryui.com 11200 * 11201 * Copyright jQuery Foundation and other contributors 11202 * Released under the MIT license. 11203 * http://jquery.org/license 11204 * 11205 * http://api.jqueryui.com/size-effect/ 11206 */ 11207 11208 11209var effectSize = $.effects.effect.size = function( o, done ) { 11210 11211 // Create element 11212 var original, baseline, factor, 11213 el = $( this ), 11214 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11215 11216 // Always restore 11217 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11218 11219 // Copy for children 11220 props2 = [ "width", "height", "overflow" ], 11221 cProps = [ "fontSize" ], 11222 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11223 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11224 11225 // Set options 11226 mode = $.effects.setMode( el, o.mode || "effect" ), 11227 restore = o.restore || mode !== "effect", 11228 scale = o.scale || "both", 11229 origin = o.origin || [ "middle", "center" ], 11230 position = el.css( "position" ), 11231 props = restore ? props0 : props1, 11232 zero = { 11233 height: 0, 11234 width: 0, 11235 outerHeight: 0, 11236 outerWidth: 0 11237 }; 11238 11239 if ( mode === "show" ) { 11240 el.show(); 11241 } 11242 original = { 11243 height: el.height(), 11244 width: el.width(), 11245 outerHeight: el.outerHeight(), 11246 outerWidth: el.outerWidth() 11247 }; 11248 11249 if ( o.mode === "toggle" && mode === "show" ) { 11250 el.from = o.to || zero; 11251 el.to = o.from || original; 11252 } else { 11253 el.from = o.from || ( mode === "show" ? zero : original ); 11254 el.to = o.to || ( mode === "hide" ? zero : original ); 11255 } 11256 11257 // Set scaling factor 11258 factor = { 11259 from: { 11260 y: el.from.height / original.height, 11261 x: el.from.width / original.width 11262 }, 11263 to: { 11264 y: el.to.height / original.height, 11265 x: el.to.width / original.width 11266 } 11267 }; 11268 11269 // Scale the css box 11270 if ( scale === "box" || scale === "both" ) { 11271 11272 // Vertical props scaling 11273 if ( factor.from.y !== factor.to.y ) { 11274 props = props.concat( vProps ); 11275 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11276 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11277 } 11278 11279 // Horizontal props scaling 11280 if ( factor.from.x !== factor.to.x ) { 11281 props = props.concat( hProps ); 11282 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11283 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11284 } 11285 } 11286 11287 // Scale the content 11288 if ( scale === "content" || scale === "both" ) { 11289 11290 // Vertical props scaling 11291 if ( factor.from.y !== factor.to.y ) { 11292 props = props.concat( cProps ).concat( props2 ); 11293 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11294 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11295 } 11296 } 11297 11298 $.effects.save( el, props ); 11299 el.show(); 11300 $.effects.createWrapper( el ); 11301 el.css( "overflow", "hidden" ).css( el.from ); 11302 11303 // Adjust 11304 if (origin) { // Calculate baseline shifts 11305 baseline = $.effects.getBaseline( origin, original ); 11306 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11307 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11308 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11309 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11310 } 11311 el.css( el.from ); // set top & left 11312 11313 // Animate 11314 if ( scale === "content" || scale === "both" ) { // Scale the children 11315 11316 // Add margins/font-size 11317 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11318 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11319 props2 = props0.concat(vProps).concat(hProps); 11320 11321 el.find( "*[width]" ).each( function() { 11322 var child = $( this ), 11323 c_original = { 11324 height: child.height(), 11325 width: child.width(), 11326 outerHeight: child.outerHeight(), 11327 outerWidth: child.outerWidth() 11328 }; 11329 if (restore) { 11330 $.effects.save(child, props2); 11331 } 11332 11333 child.from = { 11334 height: c_original.height * factor.from.y, 11335 width: c_original.width * factor.from.x, 11336 outerHeight: c_original.outerHeight * factor.from.y, 11337 outerWidth: c_original.outerWidth * factor.from.x 11338 }; 11339 child.to = { 11340 height: c_original.height * factor.to.y, 11341 width: c_original.width * factor.to.x, 11342 outerHeight: c_original.height * factor.to.y, 11343 outerWidth: c_original.width * factor.to.x 11344 }; 11345 11346 // Vertical props scaling 11347 if ( factor.from.y !== factor.to.y ) { 11348 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11349 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11350 } 11351 11352 // Horizontal props scaling 11353 if ( factor.from.x !== factor.to.x ) { 11354 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11355 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11356 } 11357 11358 // Animate children 11359 child.css( child.from ); 11360 child.animate( child.to, o.duration, o.easing, function() { 11361 11362 // Restore children 11363 if ( restore ) { 11364 $.effects.restore( child, props2 ); 11365 } 11366 }); 11367 }); 11368 } 11369 11370 // Animate 11371 el.animate( el.to, { 11372 queue: false, 11373 duration: o.duration, 11374 easing: o.easing, 11375 complete: function() { 11376 if ( el.to.opacity === 0 ) { 11377 el.css( "opacity", el.from.opacity ); 11378 } 11379 if ( mode === "hide" ) { 11380 el.hide(); 11381 } 11382 $.effects.restore( el, props ); 11383 if ( !restore ) { 11384 11385 // we need to calculate our new positioning based on the scaling 11386 if ( position === "static" ) { 11387 el.css({ 11388 position: "relative", 11389 top: el.to.top, 11390 left: el.to.left 11391 }); 11392 } else { 11393 $.each([ "top", "left" ], function( idx, pos ) { 11394 el.css( pos, function( _, str ) { 11395 var val = parseInt( str, 10 ), 11396 toRef = idx ? el.to.left : el.to.top; 11397 11398 // if original was "auto", recalculate the new value from wrapper 11399 if ( str === "auto" ) { 11400 return toRef + "px"; 11401 } 11402 11403 return val + toRef + "px"; 11404 }); 11405 }); 11406 } 11407 } 11408 11409 $.effects.removeWrapper( el ); 11410 done(); 11411 } 11412 }); 11413 11414}; 11415 11416 11417/*! 11418 * jQuery UI Effects Scale 1.11.4 11419 * http://jqueryui.com 11420 * 11421 * Copyright jQuery Foundation and other contributors 11422 * Released under the MIT license. 11423 * http://jquery.org/license 11424 * 11425 * http://api.jqueryui.com/scale-effect/ 11426 */ 11427 11428 11429var effectScale = $.effects.effect.scale = function( o, done ) { 11430 11431 // Create element 11432 var el = $( this ), 11433 options = $.extend( true, {}, o ), 11434 mode = $.effects.setMode( el, o.mode || "effect" ), 11435 percent = parseInt( o.percent, 10 ) || 11436 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 11437 direction = o.direction || "both", 11438 origin = o.origin, 11439 original = { 11440 height: el.height(), 11441 width: el.width(), 11442 outerHeight: el.outerHeight(), 11443 outerWidth: el.outerWidth() 11444 }, 11445 factor = { 11446 y: direction !== "horizontal" ? (percent / 100) : 1, 11447 x: direction !== "vertical" ? (percent / 100) : 1 11448 }; 11449 11450 // We are going to pass this effect to the size effect: 11451 options.effect = "size"; 11452 options.queue = false; 11453 options.complete = done; 11454 11455 // Set default origin and restore for show/hide 11456 if ( mode !== "effect" ) { 11457 options.origin = origin || [ "middle", "center" ]; 11458 options.restore = true; 11459 } 11460 11461 options.from = o.from || ( mode === "show" ? { 11462 height: 0, 11463 width: 0, 11464 outerHeight: 0, 11465 outerWidth: 0 11466 } : original ); 11467 options.to = { 11468 height: original.height * factor.y, 11469 width: original.width * factor.x, 11470 outerHeight: original.outerHeight * factor.y, 11471 outerWidth: original.outerWidth * factor.x 11472 }; 11473 11474 // Fade option to support puff 11475 if ( options.fade ) { 11476 if ( mode === "show" ) { 11477 options.from.opacity = 0; 11478 options.to.opacity = 1; 11479 } 11480 if ( mode === "hide" ) { 11481 options.from.opacity = 1; 11482 options.to.opacity = 0; 11483 } 11484 } 11485 11486 // Animate 11487 el.effect( options ); 11488 11489}; 11490 11491 11492/*! 11493 * jQuery UI Effects Puff 1.11.4 11494 * http://jqueryui.com 11495 * 11496 * Copyright jQuery Foundation and other contributors 11497 * Released under the MIT license. 11498 * http://jquery.org/license 11499 * 11500 * http://api.jqueryui.com/puff-effect/ 11501 */ 11502 11503 11504var effectPuff = $.effects.effect.puff = function( o, done ) { 11505 var elem = $( this ), 11506 mode = $.effects.setMode( elem, o.mode || "hide" ), 11507 hide = mode === "hide", 11508 percent = parseInt( o.percent, 10 ) || 150, 11509 factor = percent / 100, 11510 original = { 11511 height: elem.height(), 11512 width: elem.width(), 11513 outerHeight: elem.outerHeight(), 11514 outerWidth: elem.outerWidth() 11515 }; 11516 11517 $.extend( o, { 11518 effect: "scale", 11519 queue: false, 11520 fade: true, 11521 mode: mode, 11522 complete: done, 11523 percent: hide ? percent : 100, 11524 from: hide ? 11525 original : 11526 { 11527 height: original.height * factor, 11528 width: original.width * factor, 11529 outerHeight: original.outerHeight * factor, 11530 outerWidth: original.outerWidth * factor 11531 } 11532 }); 11533 11534 elem.effect( o ); 11535}; 11536 11537 11538/*! 11539 * jQuery UI Effects Pulsate 1.11.4 11540 * http://jqueryui.com 11541 * 11542 * Copyright jQuery Foundation and other contributors 11543 * Released under the MIT license. 11544 * http://jquery.org/license 11545 * 11546 * http://api.jqueryui.com/pulsate-effect/ 11547 */ 11548 11549 11550var effectPulsate = $.effects.effect.pulsate = function( o, done ) { 11551 var elem = $( this ), 11552 mode = $.effects.setMode( elem, o.mode || "show" ), 11553 show = mode === "show", 11554 hide = mode === "hide", 11555 showhide = ( show || mode === "hide" ), 11556 11557 // showing or hiding leaves of the "last" animation 11558 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 11559 duration = o.duration / anims, 11560 animateTo = 0, 11561 queue = elem.queue(), 11562 queuelen = queue.length, 11563 i; 11564 11565 if ( show || !elem.is(":visible")) { 11566 elem.css( "opacity", 0 ).show(); 11567 animateTo = 1; 11568 } 11569 11570 // anims - 1 opacity "toggles" 11571 for ( i = 1; i < anims; i++ ) { 11572 elem.animate({ 11573 opacity: animateTo 11574 }, duration, o.easing ); 11575 animateTo = 1 - animateTo; 11576 } 11577 11578 elem.animate({ 11579 opacity: animateTo 11580 }, duration, o.easing); 11581 11582 elem.queue(function() { 11583 if ( hide ) { 11584 elem.hide(); 11585 } 11586 done(); 11587 }); 11588 11589 // We just queued up "anims" animations, we need to put them next in the queue 11590 if ( queuelen > 1 ) { 11591 queue.splice.apply( queue, 11592 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11593 } 11594 elem.dequeue(); 11595}; 11596 11597 11598/*! 11599 * jQuery UI Effects Shake 1.11.4 11600 * http://jqueryui.com 11601 * 11602 * Copyright jQuery Foundation and other contributors 11603 * Released under the MIT license. 11604 * http://jquery.org/license 11605 * 11606 * http://api.jqueryui.com/shake-effect/ 11607 */ 11608 11609 11610var effectShake = $.effects.effect.shake = function( o, done ) { 11611 11612 var el = $( this ), 11613 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11614 mode = $.effects.setMode( el, o.mode || "effect" ), 11615 direction = o.direction || "left", 11616 distance = o.distance || 20, 11617 times = o.times || 3, 11618 anims = times * 2 + 1, 11619 speed = Math.round( o.duration / anims ), 11620 ref = (direction === "up" || direction === "down") ? "top" : "left", 11621 positiveMotion = (direction === "up" || direction === "left"), 11622 animation = {}, 11623 animation1 = {}, 11624 animation2 = {}, 11625 i, 11626 11627 // we will need to re-assemble the queue to stack our animations in place 11628 queue = el.queue(), 11629 queuelen = queue.length; 11630 11631 $.effects.save( el, props ); 11632 el.show(); 11633 $.effects.createWrapper( el ); 11634 11635 // Animation 11636 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11637 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11638 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11639 11640 // Animate 11641 el.animate( animation, speed, o.easing ); 11642 11643 // Shakes 11644 for ( i = 1; i < times; i++ ) { 11645 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11646 } 11647 el 11648 .animate( animation1, speed, o.easing ) 11649 .animate( animation, speed / 2, o.easing ) 11650 .queue(function() { 11651 if ( mode === "hide" ) { 11652 el.hide(); 11653 } 11654 $.effects.restore( el, props ); 11655 $.effects.removeWrapper( el ); 11656 done(); 11657 }); 11658 11659 // inject all the animations we just queued to be first in line (after "inprogress") 11660 if ( queuelen > 1) { 11661 queue.splice.apply( queue, 11662 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11663 } 11664 el.dequeue(); 11665 11666}; 11667 11668 11669/*! 11670 * jQuery UI Effects Slide 1.11.4 11671 * http://jqueryui.com 11672 * 11673 * Copyright jQuery Foundation and other contributors 11674 * Released under the MIT license. 11675 * http://jquery.org/license 11676 * 11677 * http://api.jqueryui.com/slide-effect/ 11678 */ 11679 11680 11681var effectSlide = $.effects.effect.slide = function( o, done ) { 11682 11683 // Create element 11684 var el = $( this ), 11685 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11686 mode = $.effects.setMode( el, o.mode || "show" ), 11687 show = mode === "show", 11688 direction = o.direction || "left", 11689 ref = (direction === "up" || direction === "down") ? "top" : "left", 11690 positiveMotion = (direction === "up" || direction === "left"), 11691 distance, 11692 animation = {}; 11693 11694 // Adjust 11695 $.effects.save( el, props ); 11696 el.show(); 11697 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11698 11699 $.effects.createWrapper( el ).css({ 11700 overflow: "hidden" 11701 }); 11702 11703 if ( show ) { 11704 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11705 } 11706 11707 // Animation 11708 animation[ ref ] = ( show ? 11709 ( positiveMotion ? "+=" : "-=") : 11710 ( positiveMotion ? "-=" : "+=")) + 11711 distance; 11712 11713 // Animate 11714 el.animate( animation, { 11715 queue: false, 11716 duration: o.duration, 11717 easing: o.easing, 11718 complete: function() { 11719 if ( mode === "hide" ) { 11720 el.hide(); 11721 } 11722 $.effects.restore( el, props ); 11723 $.effects.removeWrapper( el ); 11724 done(); 11725 } 11726 }); 11727}; 11728 11729 11730/*! 11731 * jQuery UI Effects Transfer 1.11.4 11732 * http://jqueryui.com 11733 * 11734 * Copyright jQuery Foundation and other contributors 11735 * Released under the MIT license. 11736 * http://jquery.org/license 11737 * 11738 * http://api.jqueryui.com/transfer-effect/ 11739 */ 11740 11741 11742var effectTransfer = $.effects.effect.transfer = function( o, done ) { 11743 var elem = $( this ), 11744 target = $( o.to ), 11745 targetFixed = target.css( "position" ) === "fixed", 11746 body = $("body"), 11747 fixTop = targetFixed ? body.scrollTop() : 0, 11748 fixLeft = targetFixed ? body.scrollLeft() : 0, 11749 endPosition = target.offset(), 11750 animation = { 11751 top: endPosition.top - fixTop, 11752 left: endPosition.left - fixLeft, 11753 height: target.innerHeight(), 11754 width: target.innerWidth() 11755 }, 11756 startPosition = elem.offset(), 11757 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11758 .appendTo( document.body ) 11759 .addClass( o.className ) 11760 .css({ 11761 top: startPosition.top - fixTop, 11762 left: startPosition.left - fixLeft, 11763 height: elem.innerHeight(), 11764 width: elem.innerWidth(), 11765 position: targetFixed ? "fixed" : "absolute" 11766 }) 11767 .animate( animation, o.duration, o.easing, function() { 11768 transfer.remove(); 11769 done(); 11770 }); 11771}; 11772 11773 11774/*! 11775 * jQuery UI Progressbar 1.11.4 11776 * http://jqueryui.com 11777 * 11778 * Copyright jQuery Foundation and other contributors 11779 * Released under the MIT license. 11780 * http://jquery.org/license 11781 * 11782 * http://api.jqueryui.com/progressbar/ 11783 */ 11784 11785 11786var progressbar = $.widget( "ui.progressbar", { 11787 version: "1.11.4", 11788 options: { 11789 max: 100, 11790 value: 0, 11791 11792 change: null, 11793 complete: null 11794 }, 11795 11796 min: 0, 11797 11798 _create: function() { 11799 // Constrain initial value 11800 this.oldValue = this.options.value = this._constrainedValue(); 11801 11802 this.element 11803 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 11804 .attr({ 11805 // Only set static values, aria-valuenow and aria-valuemax are 11806 // set inside _refreshValue() 11807 role: "progressbar", 11808 "aria-valuemin": this.min 11809 }); 11810 11811 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 11812 .appendTo( this.element ); 11813 11814 this._refreshValue(); 11815 }, 11816 11817 _destroy: function() { 11818 this.element 11819 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 11820 .removeAttr( "role" ) 11821 .removeAttr( "aria-valuemin" ) 11822 .removeAttr( "aria-valuemax" ) 11823 .removeAttr( "aria-valuenow" ); 11824 11825 this.valueDiv.remove(); 11826 }, 11827 11828 value: function( newValue ) { 11829 if ( newValue === undefined ) { 11830 return this.options.value; 11831 } 11832 11833 this.options.value = this._constrainedValue( newValue ); 11834 this._refreshValue(); 11835 }, 11836 11837 _constrainedValue: function( newValue ) { 11838 if ( newValue === undefined ) { 11839 newValue = this.options.value; 11840 } 11841 11842 this.indeterminate = newValue === false; 11843 11844 // sanitize value 11845 if ( typeof newValue !== "number" ) { 11846 newValue = 0; 11847 } 11848 11849 return this.indeterminate ? false : 11850 Math.min( this.options.max, Math.max( this.min, newValue ) ); 11851 }, 11852 11853 _setOptions: function( options ) { 11854 // Ensure "value" option is set after other values (like max) 11855 var value = options.value; 11856 delete options.value; 11857 11858 this._super( options ); 11859 11860 this.options.value = this._constrainedValue( value ); 11861 this._refreshValue(); 11862 }, 11863 11864 _setOption: function( key, value ) { 11865 if ( key === "max" ) { 11866 // Don't allow a max less than min 11867 value = Math.max( this.min, value ); 11868 } 11869 if ( key === "disabled" ) { 11870 this.element 11871 .toggleClass( "ui-state-disabled", !!value ) 11872 .attr( "aria-disabled", value ); 11873 } 11874 this._super( key, value ); 11875 }, 11876 11877 _percentage: function() { 11878 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 11879 }, 11880 11881 _refreshValue: function() { 11882 var value = this.options.value, 11883 percentage = this._percentage(); 11884 11885 this.valueDiv 11886 .toggle( this.indeterminate || value > this.min ) 11887 .toggleClass( "ui-corner-right", value === this.options.max ) 11888 .width( percentage.toFixed(0) + "%" ); 11889 11890 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 11891 11892 if ( this.indeterminate ) { 11893 this.element.removeAttr( "aria-valuenow" ); 11894 if ( !this.overlayDiv ) { 11895 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 11896 } 11897 } else { 11898 this.element.attr({ 11899 "aria-valuemax": this.options.max, 11900 "aria-valuenow": value 11901 }); 11902 if ( this.overlayDiv ) { 11903 this.overlayDiv.remove(); 11904 this.overlayDiv = null; 11905 } 11906 } 11907 11908 if ( this.oldValue !== value ) { 11909 this.oldValue = value; 11910 this._trigger( "change" ); 11911 } 11912 if ( value === this.options.max ) { 11913 this._trigger( "complete" ); 11914 } 11915 } 11916}); 11917 11918 11919/*! 11920 * jQuery UI Selectable 1.11.4 11921 * http://jqueryui.com 11922 * 11923 * Copyright jQuery Foundation and other contributors 11924 * Released under the MIT license. 11925 * http://jquery.org/license 11926 * 11927 * http://api.jqueryui.com/selectable/ 11928 */ 11929 11930 11931var selectable = $.widget("ui.selectable", $.ui.mouse, { 11932 version: "1.11.4", 11933 options: { 11934 appendTo: "body", 11935 autoRefresh: true, 11936 distance: 0, 11937 filter: "*", 11938 tolerance: "touch", 11939 11940 // callbacks 11941 selected: null, 11942 selecting: null, 11943 start: null, 11944 stop: null, 11945 unselected: null, 11946 unselecting: null 11947 }, 11948 _create: function() { 11949 var selectees, 11950 that = this; 11951 11952 this.element.addClass("ui-selectable"); 11953 11954 this.dragged = false; 11955 11956 // cache selectee children based on filter 11957 this.refresh = function() { 11958 selectees = $(that.options.filter, that.element[0]); 11959 selectees.addClass("ui-selectee"); 11960 selectees.each(function() { 11961 var $this = $(this), 11962 pos = $this.offset(); 11963 $.data(this, "selectable-item", { 11964 element: this, 11965 $element: $this, 11966 left: pos.left, 11967 top: pos.top, 11968 right: pos.left + $this.outerWidth(), 11969 bottom: pos.top + $this.outerHeight(), 11970 startselected: false, 11971 selected: $this.hasClass("ui-selected"), 11972 selecting: $this.hasClass("ui-selecting"), 11973 unselecting: $this.hasClass("ui-unselecting") 11974 }); 11975 }); 11976 }; 11977 this.refresh(); 11978 11979 this.selectees = selectees.addClass("ui-selectee"); 11980 11981 this._mouseInit(); 11982 11983 this.helper = $("<div class='ui-selectable-helper'></div>"); 11984 }, 11985 11986 _destroy: function() { 11987 this.selectees 11988 .removeClass("ui-selectee") 11989 .removeData("selectable-item"); 11990 this.element 11991 .removeClass("ui-selectable ui-selectable-disabled"); 11992 this._mouseDestroy(); 11993 }, 11994 11995 _mouseStart: function(event) { 11996 var that = this, 11997 options = this.options; 11998 11999 this.opos = [ event.pageX, event.pageY ]; 12000 12001 if (this.options.disabled) { 12002 return; 12003 } 12004 12005 this.selectees = $(options.filter, this.element[0]); 12006 12007 this._trigger("start", event); 12008 12009 $(options.appendTo).append(this.helper); 12010 // position helper (lasso) 12011 this.helper.css({ 12012 "left": event.pageX, 12013 "top": event.pageY, 12014 "width": 0, 12015 "height": 0 12016 }); 12017 12018 if (options.autoRefresh) { 12019 this.refresh(); 12020 } 12021 12022 this.selectees.filter(".ui-selected").each(function() { 12023 var selectee = $.data(this, "selectable-item"); 12024 selectee.startselected = true; 12025 if (!event.metaKey && !event.ctrlKey) { 12026 selectee.$element.removeClass("ui-selected"); 12027 selectee.selected = false; 12028 selectee.$element.addClass("ui-unselecting"); 12029 selectee.unselecting = true; 12030 // selectable UNSELECTING callback 12031 that._trigger("unselecting", event, { 12032 unselecting: selectee.element 12033 }); 12034 } 12035 }); 12036 12037 $(event.target).parents().addBack().each(function() { 12038 var doSelect, 12039 selectee = $.data(this, "selectable-item"); 12040 if (selectee) { 12041 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 12042 selectee.$element 12043 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 12044 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 12045 selectee.unselecting = !doSelect; 12046 selectee.selecting = doSelect; 12047 selectee.selected = doSelect; 12048 // selectable (UN)SELECTING callback 12049 if (doSelect) { 12050 that._trigger("selecting", event, { 12051 selecting: selectee.element 12052 }); 12053 } else { 12054 that._trigger("unselecting", event, { 12055 unselecting: selectee.element 12056 }); 12057 } 12058 return false; 12059 } 12060 }); 12061 12062 }, 12063 12064 _mouseDrag: function(event) { 12065 12066 this.dragged = true; 12067 12068 if (this.options.disabled) { 12069 return; 12070 } 12071 12072 var tmp, 12073 that = this, 12074 options = this.options, 12075 x1 = this.opos[0], 12076 y1 = this.opos[1], 12077 x2 = event.pageX, 12078 y2 = event.pageY; 12079 12080 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 12081 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 12082 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 12083 12084 this.selectees.each(function() { 12085 var selectee = $.data(this, "selectable-item"), 12086 hit = false; 12087 12088 //prevent helper from being selected if appendTo: selectable 12089 if (!selectee || selectee.element === that.element[0]) { 12090 return; 12091 } 12092 12093 if (options.tolerance === "touch") { 12094 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 12095 } else if (options.tolerance === "fit") { 12096 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 12097 } 12098 12099 if (hit) { 12100 // SELECT 12101 if (selectee.selected) { 12102 selectee.$element.removeClass("ui-selected"); 12103 selectee.selected = false; 12104 } 12105 if (selectee.unselecting) { 12106 selectee.$element.removeClass("ui-unselecting"); 12107 selectee.unselecting = false; 12108 } 12109 if (!selectee.selecting) { 12110 selectee.$element.addClass("ui-selecting"); 12111 selectee.selecting = true; 12112 // selectable SELECTING callback 12113 that._trigger("selecting", event, { 12114 selecting: selectee.element 12115 }); 12116 } 12117 } else { 12118 // UNSELECT 12119 if (selectee.selecting) { 12120 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 12121 selectee.$element.removeClass("ui-selecting"); 12122 selectee.selecting = false; 12123 selectee.$element.addClass("ui-selected"); 12124 selectee.selected = true; 12125 } else { 12126 selectee.$element.removeClass("ui-selecting"); 12127 selectee.selecting = false; 12128 if (selectee.startselected) { 12129 selectee.$element.addClass("ui-unselecting"); 12130 selectee.unselecting = true; 12131 } 12132 // selectable UNSELECTING callback 12133 that._trigger("unselecting", event, { 12134 unselecting: selectee.element 12135 });
vendor: 15,488 bytes, lines 12136-12792
12136 } 12137 } 12138 if (selectee.selected) { 12139 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 12140 selectee.$element.removeClass("ui-selected"); 12141 selectee.selected = false; 12142 12143 selectee.$element.addClass("ui-unselecting"); 12144 selectee.unselecting = true; 12145 // selectable UNSELECTING callback 12146 that._trigger("unselecting", event, { 12147 unselecting: selectee.element 12148 }); 12149 } 12150 } 12151 } 12152 }); 12153 12154 return false; 12155 }, 12156 12157 _mouseStop: function(event) { 12158 var that = this; 12159 12160 this.dragged = false; 12161 12162 $(".ui-unselecting", this.element[0]).each(function() { 12163 var selectee = $.data(this, "selectable-item"); 12164 selectee.$element.removeClass("ui-unselecting"); 12165 selectee.unselecting = false; 12166 selectee.startselected = false; 12167 that._trigger("unselected", event, { 12168 unselected: selectee.element 12169 }); 12170 }); 12171 $(".ui-selecting", this.element[0]).each(function() { 12172 var selectee = $.data(this, "selectable-item"); 12173 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 12174 selectee.selecting = false; 12175 selectee.selected = true; 12176 selectee.startselected = true; 12177 that._trigger("selected", event, { 12178 selected: selectee.element 12179 }); 12180 }); 12181 this._trigger("stop", event); 12182 12183 this.helper.remove(); 12184 12185 return false; 12186 } 12187 12188}); 12189 12190 12191/*! 12192 * jQuery UI Selectmenu 1.11.4 12193 * http://jqueryui.com 12194 * 12195 * Copyright jQuery Foundation and other contributors 12196 * Released under the MIT license. 12197 * http://jquery.org/license 12198 * 12199 * http://api.jqueryui.com/selectmenu 12200 */ 12201 12202 12203var selectmenu = $.widget( "ui.selectmenu", { 12204 version: "1.11.4", 12205 defaultElement: "<select>", 12206 options: { 12207 appendTo: null, 12208 disabled: null, 12209 icons: { 12210 button: "ui-icon-triangle-1-s" 12211 }, 12212 position: { 12213 my: "left top", 12214 at: "left bottom", 12215 collision: "none" 12216 }, 12217 width: null, 12218 12219 // callbacks 12220 change: null, 12221 close: null, 12222 focus: null, 12223 open: null, 12224 select: null 12225 }, 12226 12227 _create: function() { 12228 var selectmenuId = this.element.uniqueId().attr( "id" ); 12229 this.ids = { 12230 element: selectmenuId, 12231 button: selectmenuId + "-button", 12232 menu: selectmenuId + "-menu" 12233 }; 12234 12235 this._drawButton(); 12236 this._drawMenu(); 12237 12238 if ( this.options.disabled ) { 12239 this.disable(); 12240 } 12241 }, 12242 12243 _drawButton: function() { 12244 var that = this; 12245 12246 // Associate existing label with the new button 12247 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); 12248 this._on( this.label, { 12249 click: function( event ) { 12250 this.button.focus(); 12251 event.preventDefault(); 12252 } 12253 }); 12254 12255 // Hide original select element 12256 this.element.hide(); 12257 12258 // Create button 12259 this.button = $( "<span>", { 12260 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", 12261 tabindex: this.options.disabled ? -1 : 0, 12262 id: this.ids.button, 12263 role: "combobox", 12264 "aria-expanded": "false", 12265 "aria-autocomplete": "list", 12266 "aria-owns": this.ids.menu, 12267 "aria-haspopup": "true" 12268 }) 12269 .insertAfter( this.element ); 12270 12271 $( "<span>", { 12272 "class": "ui-icon " + this.options.icons.button 12273 }) 12274 .prependTo( this.button ); 12275 12276 this.buttonText = $( "<span>", { 12277 "class": "ui-selectmenu-text" 12278 }) 12279 .appendTo( this.button ); 12280 12281 this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); 12282 this._resizeButton(); 12283 12284 this._on( this.button, this._buttonEvents ); 12285 this.button.one( "focusin", function() { 12286 12287 // Delay rendering the menu items until the button receives focus. 12288 // The menu may have already been rendered via a programmatic open. 12289 if ( !that.menuItems ) { 12290 that._refreshMenu(); 12291 } 12292 }); 12293 this._hoverable( this.button ); 12294 this._focusable( this.button ); 12295 }, 12296 12297 _drawMenu: function() { 12298 var that = this; 12299 12300 // Create menu 12301 this.menu = $( "<ul>", { 12302 "aria-hidden": "true", 12303 "aria-labelledby": this.ids.button, 12304 id: this.ids.menu 12305 }); 12306 12307 // Wrap menu 12308 this.menuWrap = $( "<div>", { 12309 "class": "ui-selectmenu-menu ui-front" 12310 }) 12311 .append( this.menu ) 12312 .appendTo( this._appendTo() ); 12313 12314 // Initialize menu widget 12315 this.menuInstance = this.menu 12316 .menu({ 12317 role: "listbox", 12318 select: function( event, ui ) { 12319 event.preventDefault(); 12320 12321 // support: IE8 12322 // If the item was selected via a click, the text selection 12323 // will be destroyed in IE 12324 that._setSelection(); 12325 12326 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 12327 }, 12328 focus: function( event, ui ) { 12329 var item = ui.item.data( "ui-selectmenu-item" ); 12330 12331 // Prevent inital focus from firing and check if its a newly focused item 12332 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 12333 that._trigger( "focus", event, { item: item } ); 12334 if ( !that.isOpen ) { 12335 that._select( item, event ); 12336 } 12337 } 12338 that.focusIndex = item.index; 12339 12340 that.button.attr( "aria-activedescendant", 12341 that.menuItems.eq( item.index ).attr( "id" ) ); 12342 } 12343 }) 12344 .menu( "instance" ); 12345 12346 // Adjust menu styles to dropdown 12347 this.menu 12348 .addClass( "ui-corner-bottom" ) 12349 .removeClass( "ui-corner-all" ); 12350 12351 // Don't close the menu on mouseleave 12352 this.menuInstance._off( this.menu, "mouseleave" ); 12353 12354 // Cancel the menu's collapseAll on document click 12355 this.menuInstance._closeOnDocumentClick = function() { 12356 return false; 12357 }; 12358 12359 // Selects often contain empty items, but never contain dividers 12360 this.menuInstance._isDivider = function() { 12361 return false; 12362 }; 12363 }, 12364 12365 refresh: function() { 12366 this._refreshMenu(); 12367 this._setText( this.buttonText, this._getSelectedItem().text() ); 12368 if ( !this.options.width ) { 12369 this._resizeButton(); 12370 } 12371 }, 12372 12373 _refreshMenu: function() { 12374 this.menu.empty(); 12375 12376 var item, 12377 options = this.element.find( "option" ); 12378 12379 if ( !options.length ) { 12380 return; 12381 } 12382 12383 this._parseOptions( options ); 12384 this._renderMenu( this.menu, this.items ); 12385 12386 this.menuInstance.refresh(); 12387 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); 12388 12389 item = this._getSelectedItem(); 12390 12391 // Update the menu to have the correct item focused 12392 this.menuInstance.focus( null, item ); 12393 this._setAria( item.data( "ui-selectmenu-item" ) ); 12394 12395 // Set disabled state 12396 this._setOption( "disabled", this.element.prop( "disabled" ) ); 12397 }, 12398 12399 open: function( event ) { 12400 if ( this.options.disabled ) { 12401 return; 12402 } 12403 12404 // If this is the first time the menu is being opened, render the items 12405 if ( !this.menuItems ) { 12406 this._refreshMenu(); 12407 } else { 12408 12409 // Menu clears focus on close, reset focus to selected item 12410 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); 12411 this.menuInstance.focus( null, this._getSelectedItem() ); 12412 } 12413 12414 this.isOpen = true; 12415 this._toggleAttr(); 12416 this._resizeMenu(); 12417 this._position(); 12418 12419 this._on( this.document, this._documentClick ); 12420 12421 this._trigger( "open", event ); 12422 }, 12423 12424 _position: function() { 12425 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 12426 }, 12427 12428 close: function( event ) { 12429 if ( !this.isOpen ) { 12430 return; 12431 } 12432 12433 this.isOpen = false; 12434 this._toggleAttr(); 12435 12436 this.range = null; 12437 this._off( this.document ); 12438 12439 this._trigger( "close", event ); 12440 }, 12441 12442 widget: function() { 12443 return this.button; 12444 }, 12445 12446 menuWidget: function() { 12447 return this.menu; 12448 }, 12449 12450 _renderMenu: function( ul, items ) { 12451 var that = this, 12452 currentOptgroup = ""; 12453 12454 $.each( items, function( index, item ) { 12455 if ( item.optgroup !== currentOptgroup ) { 12456 $( "<li>", { 12457 "class": "ui-selectmenu-optgroup ui-menu-divider" + 12458 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 12459 " ui-state-disabled" : 12460 "" ), 12461 text: item.optgroup 12462 }) 12463 .appendTo( ul ); 12464 12465 currentOptgroup = item.optgroup; 12466 } 12467 12468 that._renderItemData( ul, item ); 12469 }); 12470 }, 12471 12472 _renderItemData: function( ul, item ) { 12473 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 12474 }, 12475 12476 _renderItem: function( ul, item ) { 12477 var li = $( "<li>" ); 12478 12479 if ( item.disabled ) { 12480 li.addClass( "ui-state-disabled" ); 12481 } 12482 this._setText( li, item.label ); 12483 12484 return li.appendTo( ul ); 12485 }, 12486 12487 _setText: function( element, value ) { 12488 if ( value ) { 12489 element.text( value ); 12490 } else { 12491 element.html( " " ); 12492 } 12493 }, 12494 12495 _move: function( direction, event ) { 12496 var item, next, 12497 filter = ".ui-menu-item"; 12498 12499 if ( this.isOpen ) { 12500 item = this.menuItems.eq( this.focusIndex ); 12501 } else { 12502 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12503 filter += ":not(.ui-state-disabled)"; 12504 } 12505 12506 if ( direction === "first" || direction === "last" ) { 12507 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 12508 } else { 12509 next = item[ direction + "All" ]( filter ).eq( 0 ); 12510 } 12511 12512 if ( next.length ) { 12513 this.menuInstance.focus( event, next ); 12514 } 12515 }, 12516 12517 _getSelectedItem: function() { 12518 return this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12519 }, 12520 12521 _toggle: function( event ) { 12522 this[ this.isOpen ? "close" : "open" ]( event ); 12523 }, 12524 12525 _setSelection: function() { 12526 var selection; 12527 12528 if ( !this.range ) { 12529 return; 12530 } 12531 12532 if ( window.getSelection ) { 12533 selection = window.getSelection(); 12534 selection.removeAllRanges(); 12535 selection.addRange( this.range ); 12536 12537 // support: IE8 12538 } else { 12539 this.range.select(); 12540 } 12541 12542 // support: IE 12543 // Setting the text selection kills the button focus in IE, but 12544 // restoring the focus doesn't kill the selection. 12545 this.button.focus(); 12546 }, 12547 12548 _documentClick: { 12549 mousedown: function( event ) { 12550 if ( !this.isOpen ) { 12551 return; 12552 } 12553 12554 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { 12555 this.close( event ); 12556 } 12557 } 12558 }, 12559 12560 _buttonEvents: { 12561 12562 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 12563 mousedown: function() { 12564 var selection; 12565 12566 if ( window.getSelection ) { 12567 selection = window.getSelection(); 12568 if ( selection.rangeCount ) { 12569 this.range = selection.getRangeAt( 0 ); 12570 } 12571 12572 // support: IE8 12573 } else { 12574 this.range = document.selection.createRange(); 12575 } 12576 }, 12577 12578 click: function( event ) { 12579 this._setSelection(); 12580 this._toggle( event ); 12581 }, 12582 12583 keydown: function( event ) { 12584 var preventDefault = true; 12585 switch ( event.keyCode ) { 12586 case $.ui.keyCode.TAB: 12587 case $.ui.keyCode.ESCAPE: 12588 this.close( event ); 12589 preventDefault = false; 12590 break; 12591 case $.ui.keyCode.ENTER: 12592 if ( this.isOpen ) { 12593 this._selectFocusedItem( event ); 12594 } 12595 break; 12596 case $.ui.keyCode.UP: 12597 if ( event.altKey ) { 12598 this._toggle( event ); 12599 } else { 12600 this._move( "prev", event ); 12601 } 12602 break; 12603 case $.ui.keyCode.DOWN: 12604 if ( event.altKey ) { 12605 this._toggle( event ); 12606 } else { 12607 this._move( "next", event ); 12608 } 12609 break; 12610 case $.ui.keyCode.SPACE: 12611 if ( this.isOpen ) { 12612 this._selectFocusedItem( event ); 12613 } else { 12614 this._toggle( event ); 12615 } 12616 break; 12617 case $.ui.keyCode.LEFT: 12618 this._move( "prev", event ); 12619 break; 12620 case $.ui.keyCode.RIGHT: 12621 this._move( "next", event ); 12622 break; 12623 case $.ui.keyCode.HOME: 12624 case $.ui.keyCode.PAGE_UP: 12625 this._move( "first", event ); 12626 break; 12627 case $.ui.keyCode.END: 12628 case $.ui.keyCode.PAGE_DOWN: 12629 this._move( "last", event ); 12630 break; 12631 default: 12632 this.menu.trigger( event ); 12633 preventDefault = false; 12634 } 12635 12636 if ( preventDefault ) { 12637 event.preventDefault(); 12638 } 12639 } 12640 }, 12641 12642 _selectFocusedItem: function( event ) { 12643 var item = this.menuItems.eq( this.focusIndex ); 12644 if ( !item.hasClass( "ui-state-disabled" ) ) { 12645 this._select( item.data( "ui-selectmenu-item" ), event ); 12646 } 12647 }, 12648 12649 _select: function( item, event ) { 12650 var oldIndex = this.element[ 0 ].selectedIndex; 12651 12652 // Change native select element 12653 this.element[ 0 ].selectedIndex = item.index; 12654 this._setText( this.buttonText, item.label ); 12655 this._setAria( item ); 12656 this._trigger( "select", event, { item: item } ); 12657 12658 if ( item.index !== oldIndex ) { 12659 this._trigger( "change", event, { item: item } ); 12660 } 12661 12662 this.close( event ); 12663 }, 12664 12665 _setAria: function( item ) { 12666 var id = this.menuItems.eq( item.index ).attr( "id" ); 12667 12668 this.button.attr({ 12669 "aria-labelledby": id, 12670 "aria-activedescendant": id 12671 }); 12672 this.menu.attr( "aria-activedescendant", id ); 12673 }, 12674 12675 _setOption: function( key, value ) { 12676 if ( key === "icons" ) { 12677 this.button.find( "span.ui-icon" ) 12678 .removeClass( this.options.icons.button ) 12679 .addClass( value.button ); 12680 } 12681 12682 this._super( key, value ); 12683 12684 if ( key === "appendTo" ) { 12685 this.menuWrap.appendTo( this._appendTo() ); 12686 } 12687 12688 if ( key === "disabled" ) { 12689 this.menuInstance.option( "disabled", value ); 12690 this.button 12691 .toggleClass( "ui-state-disabled", value ) 12692 .attr( "aria-disabled", value ); 12693 12694 this.element.prop( "disabled", value ); 12695 if ( value ) { 12696 this.button.attr( "tabindex", -1 ); 12697 this.close(); 12698 } else { 12699 this.button.attr( "tabindex", 0 ); 12700 } 12701 } 12702 12703 if ( key === "width" ) { 12704 this._resizeButton(); 12705 } 12706 }, 12707 12708 _appendTo: function() { 12709 var element = this.options.appendTo; 12710 12711 if ( element ) { 12712 element = element.jquery || element.nodeType ? 12713 $( element ) : 12714 this.document.find( element ).eq( 0 ); 12715 } 12716 12717 if ( !element || !element[ 0 ] ) { 12718 element = this.element.closest( ".ui-front" ); 12719 } 12720 12721 if ( !element.length ) { 12722 element = this.document[ 0 ].body; 12723 } 12724 12725 return element; 12726 }, 12727 12728 _toggleAttr: function() { 12729 this.button 12730 .toggleClass( "ui-corner-top", this.isOpen ) 12731 .toggleClass( "ui-corner-all", !this.isOpen ) 12732 .attr( "aria-expanded", this.isOpen ); 12733 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); 12734 this.menu.attr( "aria-hidden", !this.isOpen ); 12735 }, 12736 12737 _resizeButton: function() { 12738 var width = this.options.width; 12739 12740 if ( !width ) { 12741 width = this.element.show().outerWidth(); 12742 this.element.hide(); 12743 } 12744 12745 this.button.outerWidth( width ); 12746 }, 12747 12748 _resizeMenu: function() { 12749 this.menu.outerWidth( Math.max( 12750 this.button.outerWidth(), 12751 12752 // support: IE10 12753 // IE10 wraps long text (possibly a rounding bug) 12754 // so we add 1px to avoid the wrapping 12755 this.menu.width( "" ).outerWidth() + 1 12756 ) ); 12757 }, 12758 12759 _getCreateOptions: function() { 12760 return { disabled: this.element.prop( "disabled" ) }; 12761 }, 12762 12763 _parseOptions: function( options ) { 12764 var data = []; 12765 options.each(function( index, item ) { 12766 var option = $( item ), 12767 optgroup = option.parent( "optgroup" ); 12768 data.push({ 12769 element: option, 12770 index: index, 12771 value: option.val(), 12772 label: option.text(), 12773 optgroup: optgroup.attr( "label" ) || "", 12774 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 12775 }); 12776 }); 12777 this.items = data; 12778 }, 12779 12780 _destroy: function() { 12781 this.menuWrap.remove(); 12782 this.button.remove(); 12783 this.element.show(); 12784 this.element.removeUniqueId(); 12785 this.label.attr( "for", this.ids.element ); 12786 } 12787}); 12788 12789 12790/*! 12791 * jQuery UI Slider 1.11.4 12792 * http://jqueryui.com
vendor: 9,525 bytes, lines 12793-13147
12793 * 12794 * Copyright jQuery Foundation and other contributors 12795 * Released under the MIT license. 12796 * http://jquery.org/license 12797 * 12798 * http://api.jqueryui.com/slider/ 12799 */ 12800 12801 12802var slider = $.widget( "ui.slider", $.ui.mouse, { 12803 version: "1.11.4", 12804 widgetEventPrefix: "slide", 12805 12806 options: { 12807 animate: false, 12808 distance: 0, 12809 max: 100, 12810 min: 0, 12811 orientation: "horizontal", 12812 range: false, 12813 step: 1, 12814 value: 0, 12815 values: null, 12816 12817 // callbacks 12818 change: null, 12819 slide: null, 12820 start: null, 12821 stop: null 12822 }, 12823 12824 // number of pages in a slider 12825 // (how many times can you page up/down to go through the whole range) 12826 numPages: 5, 12827 12828 _create: function() { 12829 this._keySliding = false; 12830 this._mouseSliding = false; 12831 this._animateOff = true; 12832 this._handleIndex = null; 12833 this._detectOrientation(); 12834 this._mouseInit(); 12835 this._calculateNewMax(); 12836 12837 this.element 12838 .addClass( "ui-slider" + 12839 " ui-slider-" + this.orientation + 12840 " ui-widget" + 12841 " ui-widget-content" + 12842 " ui-corner-all"); 12843 12844 this._refresh(); 12845 this._setOption( "disabled", this.options.disabled ); 12846 12847 this._animateOff = false; 12848 }, 12849 12850 _refresh: function() { 12851 this._createRange(); 12852 this._createHandles(); 12853 this._setupEvents(); 12854 this._refreshValue(); 12855 }, 12856 12857 _createHandles: function() { 12858 var i, handleCount, 12859 options = this.options, 12860 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12861 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", 12862 handles = []; 12863 12864 handleCount = ( options.values && options.values.length ) || 1; 12865 12866 if ( existingHandles.length > handleCount ) { 12867 existingHandles.slice( handleCount ).remove(); 12868 existingHandles = existingHandles.slice( 0, handleCount ); 12869 } 12870 12871 for ( i = existingHandles.length; i < handleCount; i++ ) { 12872 handles.push( handle ); 12873 } 12874 12875 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12876 12877 this.handle = this.handles.eq( 0 ); 12878 12879 this.handles.each(function( i ) { 12880 $( this ).data( "ui-slider-handle-index", i ); 12881 }); 12882 }, 12883 12884 _createRange: function() { 12885 var options = this.options, 12886 classes = ""; 12887 12888 if ( options.range ) { 12889 if ( options.range === true ) { 12890 if ( !options.values ) { 12891 options.values = [ this._valueMin(), this._valueMin() ]; 12892 } else if ( options.values.length && options.values.length !== 2 ) { 12893 options.values = [ options.values[0], options.values[0] ]; 12894 } else if ( $.isArray( options.values ) ) { 12895 options.values = options.values.slice(0); 12896 } 12897 } 12898 12899 if ( !this.range || !this.range.length ) { 12900 this.range = $( "<div></div>" ) 12901 .appendTo( this.element ); 12902 12903 classes = "ui-slider-range" + 12904 // note: this isn't the most fittingly semantic framework class for this element, 12905 // but worked best visually with a variety of themes 12906 " ui-widget-header ui-corner-all"; 12907 } else { 12908 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12909 // Handle range switching from true to min/max 12910 .css({ 12911 "left": "", 12912 "bottom": "" 12913 }); 12914 } 12915 12916 this.range.addClass( classes + 12917 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12918 } else { 12919 if ( this.range ) { 12920 this.range.remove(); 12921 } 12922 this.range = null; 12923 } 12924 }, 12925 12926 _setupEvents: function() { 12927 this._off( this.handles ); 12928 this._on( this.handles, this._handleEvents ); 12929 this._hoverable( this.handles ); 12930 this._focusable( this.handles ); 12931 }, 12932 12933 _destroy: function() { 12934 this.handles.remove(); 12935 if ( this.range ) { 12936 this.range.remove(); 12937 } 12938 12939 this.element 12940 .removeClass( "ui-slider" + 12941 " ui-slider-horizontal" + 12942 " ui-slider-vertical" + 12943 " ui-widget" + 12944 " ui-widget-content" + 12945 " ui-corner-all" ); 12946 12947 this._mouseDestroy(); 12948 }, 12949 12950 _mouseCapture: function( event ) { 12951 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12952 that = this, 12953 o = this.options; 12954 12955 if ( o.disabled ) { 12956 return false; 12957 } 12958 12959 this.elementSize = { 12960 width: this.element.outerWidth(), 12961 height: this.element.outerHeight() 12962 }; 12963 this.elementOffset = this.element.offset(); 12964 12965 position = { x: event.pageX, y: event.pageY }; 12966 normValue = this._normValueFromMouse( position ); 12967 distance = this._valueMax() - this._valueMin() + 1; 12968 this.handles.each(function( i ) { 12969 var thisDistance = Math.abs( normValue - that.values(i) ); 12970 if (( distance > thisDistance ) || 12971 ( distance === thisDistance && 12972 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12973 distance = thisDistance; 12974 closestHandle = $( this ); 12975 index = i; 12976 } 12977 }); 12978 12979 allowed = this._start( event, index ); 12980 if ( allowed === false ) { 12981 return false; 12982 } 12983 this._mouseSliding = true; 12984 12985 this._handleIndex = index; 12986 12987 closestHandle 12988 .addClass( "ui-state-active" ) 12989 .focus(); 12990 12991 offset = closestHandle.offset(); 12992 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12993 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12994 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12995 top: event.pageY - offset.top - 12996 ( closestHandle.height() / 2 ) - 12997 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12998 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12999 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 13000 }; 13001 13002 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13003 this._slide( event, index, normValue ); 13004 } 13005 this._animateOff = true; 13006 return true; 13007 }, 13008 13009 _mouseStart: function() { 13010 return true; 13011 }, 13012 13013 _mouseDrag: function( event ) { 13014 var position = { x: event.pageX, y: event.pageY }, 13015 normValue = this._normValueFromMouse( position ); 13016 13017 this._slide( event, this._handleIndex, normValue ); 13018 13019 return false; 13020 }, 13021 13022 _mouseStop: function( event ) { 13023 this.handles.removeClass( "ui-state-active" ); 13024 this._mouseSliding = false; 13025 13026 this._stop( event, this._handleIndex ); 13027 this._change( event, this._handleIndex ); 13028 13029 this._handleIndex = null; 13030 this._clickOffset = null; 13031 this._animateOff = false; 13032 13033 return false; 13034 }, 13035 13036 _detectOrientation: function() { 13037 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13038 }, 13039 13040 _normValueFromMouse: function( position ) { 13041 var pixelTotal, 13042 pixelMouse, 13043 percentMouse, 13044 valueTotal, 13045 valueMouse; 13046 13047 if ( this.orientation === "horizontal" ) { 13048 pixelTotal = this.elementSize.width; 13049 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 13050 } else { 13051 pixelTotal = this.elementSize.height; 13052 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 13053 } 13054 13055 percentMouse = ( pixelMouse / pixelTotal ); 13056 if ( percentMouse > 1 ) { 13057 percentMouse = 1; 13058 } 13059 if ( percentMouse < 0 ) { 13060 percentMouse = 0; 13061 } 13062 if ( this.orientation === "vertical" ) { 13063 percentMouse = 1 - percentMouse; 13064 } 13065 13066 valueTotal = this._valueMax() - this._valueMin(); 13067 valueMouse = this._valueMin() + percentMouse * valueTotal; 13068 13069 return this._trimAlignValue( valueMouse ); 13070 }, 13071 13072 _start: function( event, index ) { 13073 var uiHash = { 13074 handle: this.handles[ index ], 13075 value: this.value() 13076 }; 13077 if ( this.options.values && this.options.values.length ) { 13078 uiHash.value = this.values( index ); 13079 uiHash.values = this.values(); 13080 } 13081 return this._trigger( "start", event, uiHash ); 13082 }, 13083 13084 _slide: function( event, index, newVal ) { 13085 var otherVal, 13086 newValues, 13087 allowed; 13088 13089 if ( this.options.values && this.options.values.length ) { 13090 otherVal = this.values( index ? 0 : 1 ); 13091 13092 if ( ( this.options.values.length === 2 && this.options.range === true ) && 13093 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 13094 ) { 13095 newVal = otherVal; 13096 } 13097 13098 if ( newVal !== this.values( index ) ) { 13099 newValues = this.values(); 13100 newValues[ index ] = newVal; 13101 // A slide can be canceled by returning false from the slide callback 13102 allowed = this._trigger( "slide", event, { 13103 handle: this.handles[ index ], 13104 value: newVal, 13105 values: newValues 13106 } ); 13107 otherVal = this.values( index ? 0 : 1 ); 13108 if ( allowed !== false ) { 13109 this.values( index, newVal ); 13110 } 13111 } 13112 } else { 13113 if ( newVal !== this.value() ) { 13114 // A slide can be canceled by returning false from the slide callback 13115 allowed = this._trigger( "slide", event, { 13116 handle: this.handles[ index ], 13117 value: newVal 13118 } ); 13119 if ( allowed !== false ) { 13120 this.value( newVal ); 13121 } 13122 } 13123 } 13124 }, 13125 13126 _stop: function( event, index ) { 13127 var uiHash = { 13128 handle: this.handles[ index ], 13129 value: this.value() 13130 }; 13131 if ( this.options.values && this.options.values.length ) { 13132 uiHash.value = this.values( index ); 13133 uiHash.values = this.values(); 13134 } 13135 13136 this._trigger( "stop", event, uiHash ); 13137 }, 13138 13139 _change: function( event, index ) { 13140 if ( !this._keySliding && !this._mouseSliding ) { 13141 var uiHash = { 13142 handle: this.handles[ index ], 13143 value: this.value() 13144 }; 13145 if ( this.options.values && this.options.values.length ) { 13146 uiHash.value = this.values( index ); 13147 uiHash.values = this.values();
vendor: 23,287 bytes, lines 13148-13947
13148 } 13149 13150 //store the last changed value index for reference when handles overlap 13151 this._lastChangedValue = index; 13152 13153 this._trigger( "change", event, uiHash ); 13154 } 13155 }, 13156 13157 value: function( newValue ) { 13158 if ( arguments.length ) { 13159 this.options.value = this._trimAlignValue( newValue ); 13160 this._refreshValue(); 13161 this._change( null, 0 ); 13162 return; 13163 } 13164 13165 return this._value(); 13166 }, 13167 13168 values: function( index, newValue ) { 13169 var vals, 13170 newValues, 13171 i; 13172 13173 if ( arguments.length > 1 ) { 13174 this.options.values[ index ] = this._trimAlignValue( newValue ); 13175 this._refreshValue(); 13176 this._change( null, index ); 13177 return; 13178 } 13179 13180 if ( arguments.length ) { 13181 if ( $.isArray( arguments[ 0 ] ) ) { 13182 vals = this.options.values; 13183 newValues = arguments[ 0 ]; 13184 for ( i = 0; i < vals.length; i += 1 ) { 13185 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13186 this._change( null, i ); 13187 } 13188 this._refreshValue(); 13189 } else { 13190 if ( this.options.values && this.options.values.length ) { 13191 return this._values( index ); 13192 } else { 13193 return this.value(); 13194 } 13195 } 13196 } else { 13197 return this._values(); 13198 } 13199 }, 13200 13201 _setOption: function( key, value ) { 13202 var i, 13203 valsLength = 0; 13204 13205 if ( key === "range" && this.options.range === true ) { 13206 if ( value === "min" ) { 13207 this.options.value = this._values( 0 ); 13208 this.options.values = null; 13209 } else if ( value === "max" ) { 13210 this.options.value = this._values( this.options.values.length - 1 ); 13211 this.options.values = null; 13212 } 13213 } 13214 13215 if ( $.isArray( this.options.values ) ) { 13216 valsLength = this.options.values.length; 13217 } 13218 13219 if ( key === "disabled" ) { 13220 this.element.toggleClass( "ui-state-disabled", !!value ); 13221 } 13222 13223 this._super( key, value ); 13224 13225 switch ( key ) { 13226 case "orientation": 13227 this._detectOrientation(); 13228 this.element 13229 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13230 .addClass( "ui-slider-" + this.orientation ); 13231 this._refreshValue(); 13232 13233 // Reset positioning from previous orientation 13234 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 13235 break; 13236 case "value": 13237 this._animateOff = true; 13238 this._refreshValue(); 13239 this._change( null, 0 ); 13240 this._animateOff = false; 13241 break; 13242 case "values": 13243 this._animateOff = true; 13244 this._refreshValue(); 13245 for ( i = 0; i < valsLength; i += 1 ) { 13246 this._change( null, i ); 13247 } 13248 this._animateOff = false; 13249 break; 13250 case "step": 13251 case "min": 13252 case "max": 13253 this._animateOff = true; 13254 this._calculateNewMax(); 13255 this._refreshValue(); 13256 this._animateOff = false; 13257 break; 13258 case "range": 13259 this._animateOff = true; 13260 this._refresh(); 13261 this._animateOff = false; 13262 break; 13263 } 13264 }, 13265 13266 //internal value getter 13267 // _value() returns value trimmed by min and max, aligned by step 13268 _value: function() { 13269 var val = this.options.value; 13270 val = this._trimAlignValue( val ); 13271 13272 return val; 13273 }, 13274 13275 //internal values getter 13276 // _values() returns array of values trimmed by min and max, aligned by step 13277 // _values( index ) returns single value trimmed by min and max, aligned by step 13278 _values: function( index ) { 13279 var val, 13280 vals, 13281 i; 13282 13283 if ( arguments.length ) { 13284 val = this.options.values[ index ]; 13285 val = this._trimAlignValue( val ); 13286 13287 return val; 13288 } else if ( this.options.values && this.options.values.length ) { 13289 // .slice() creates a copy of the array 13290 // this copy gets trimmed by min and max and then returned 13291 vals = this.options.values.slice(); 13292 for ( i = 0; i < vals.length; i += 1) { 13293 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13294 } 13295 13296 return vals; 13297 } else { 13298 return []; 13299 } 13300 }, 13301 13302 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13303 _trimAlignValue: function( val ) { 13304 if ( val <= this._valueMin() ) { 13305 return this._valueMin(); 13306 } 13307 if ( val >= this._valueMax() ) { 13308 return this._valueMax(); 13309 } 13310 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13311 valModStep = (val - this._valueMin()) % step, 13312 alignValue = val - valModStep; 13313 13314 if ( Math.abs(valModStep) * 2 >= step ) { 13315 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13316 } 13317 13318 // Since JavaScript has problems with large floats, round 13319 // the final value to 5 digits after the decimal point (see #4124) 13320 return parseFloat( alignValue.toFixed(5) ); 13321 }, 13322 13323 _calculateNewMax: function() { 13324 var max = this.options.max, 13325 min = this._valueMin(), 13326 step = this.options.step, 13327 aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step; 13328 max = aboveMin + min; 13329 this.max = parseFloat( max.toFixed( this._precision() ) ); 13330 }, 13331 13332 _precision: function() { 13333 var precision = this._precisionOf( this.options.step ); 13334 if ( this.options.min !== null ) { 13335 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13336 } 13337 return precision; 13338 }, 13339 13340 _precisionOf: function( num ) { 13341 var str = num.toString(), 13342 decimal = str.indexOf( "." ); 13343 return decimal === -1 ? 0 : str.length - decimal - 1; 13344 }, 13345 13346 _valueMin: function() { 13347 return this.options.min; 13348 }, 13349 13350 _valueMax: function() { 13351 return this.max; 13352 }, 13353 13354 _refreshValue: function() { 13355 var lastValPercent, valPercent, value, valueMin, valueMax, 13356 oRange = this.options.range, 13357 o = this.options, 13358 that = this, 13359 animate = ( !this._animateOff ) ? o.animate : false, 13360 _set = {}; 13361 13362 if ( this.options.values && this.options.values.length ) { 13363 this.handles.each(function( i ) { 13364 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13365 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13366 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13367 if ( that.options.range === true ) { 13368 if ( that.orientation === "horizontal" ) { 13369 if ( i === 0 ) { 13370 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13371 } 13372 if ( i === 1 ) { 13373 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13374 } 13375 } else { 13376 if ( i === 0 ) { 13377 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13378 } 13379 if ( i === 1 ) { 13380 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13381 } 13382 } 13383 } 13384 lastValPercent = valPercent; 13385 }); 13386 } else { 13387 value = this.value(); 13388 valueMin = this._valueMin(); 13389 valueMax = this._valueMax(); 13390 valPercent = ( valueMax !== valueMin ) ? 13391 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13392 0; 13393 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13394 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13395 13396 if ( oRange === "min" && this.orientation === "horizontal" ) { 13397 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13398 } 13399 if ( oRange === "max" && this.orientation === "horizontal" ) { 13400 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13401 } 13402 if ( oRange === "min" && this.orientation === "vertical" ) { 13403 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13404 } 13405 if ( oRange === "max" && this.orientation === "vertical" ) { 13406 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13407 } 13408 } 13409 }, 13410 13411 _handleEvents: { 13412 keydown: function( event ) { 13413 var allowed, curVal, newVal, step, 13414 index = $( event.target ).data( "ui-slider-handle-index" ); 13415 13416 switch ( event.keyCode ) { 13417 case $.ui.keyCode.HOME: 13418 case $.ui.keyCode.END: 13419 case $.ui.keyCode.PAGE_UP: 13420 case $.ui.keyCode.PAGE_DOWN: 13421 case $.ui.keyCode.UP: 13422 case $.ui.keyCode.RIGHT: 13423 case $.ui.keyCode.DOWN: 13424 case $.ui.keyCode.LEFT: 13425 event.preventDefault(); 13426 if ( !this._keySliding ) { 13427 this._keySliding = true; 13428 $( event.target ).addClass( "ui-state-active" ); 13429 allowed = this._start( event, index ); 13430 if ( allowed === false ) { 13431 return; 13432 } 13433 } 13434 break; 13435 } 13436 13437 step = this.options.step; 13438 if ( this.options.values && this.options.values.length ) { 13439 curVal = newVal = this.values( index ); 13440 } else { 13441 curVal = newVal = this.value(); 13442 } 13443 13444 switch ( event.keyCode ) { 13445 case $.ui.keyCode.HOME: 13446 newVal = this._valueMin(); 13447 break; 13448 case $.ui.keyCode.END: 13449 newVal = this._valueMax(); 13450 break; 13451 case $.ui.keyCode.PAGE_UP: 13452 newVal = this._trimAlignValue( 13453 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 13454 ); 13455 break; 13456 case $.ui.keyCode.PAGE_DOWN: 13457 newVal = this._trimAlignValue( 13458 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); 13459 break; 13460 case $.ui.keyCode.UP: 13461 case $.ui.keyCode.RIGHT: 13462 if ( curVal === this._valueMax() ) { 13463 return; 13464 } 13465 newVal = this._trimAlignValue( curVal + step ); 13466 break; 13467 case $.ui.keyCode.DOWN: 13468 case $.ui.keyCode.LEFT: 13469 if ( curVal === this._valueMin() ) { 13470 return; 13471 } 13472 newVal = this._trimAlignValue( curVal - step ); 13473 break; 13474 } 13475 13476 this._slide( event, index, newVal ); 13477 }, 13478 keyup: function( event ) { 13479 var index = $( event.target ).data( "ui-slider-handle-index" ); 13480 13481 if ( this._keySliding ) { 13482 this._keySliding = false; 13483 this._stop( event, index ); 13484 this._change( event, index ); 13485 $( event.target ).removeClass( "ui-state-active" ); 13486 } 13487 } 13488 } 13489}); 13490 13491 13492/*! 13493 * jQuery UI Sortable 1.11.4 13494 * http://jqueryui.com 13495 * 13496 * Copyright jQuery Foundation and other contributors 13497 * Released under the MIT license. 13498 * http://jquery.org/license 13499 * 13500 * http://api.jqueryui.com/sortable/ 13501 */ 13502 13503 13504var sortable = $.widget("ui.sortable", $.ui.mouse, { 13505 version: "1.11.4", 13506 widgetEventPrefix: "sort", 13507 ready: false, 13508 options: { 13509 appendTo: "parent", 13510 axis: false, 13511 connectWith: false, 13512 containment: false, 13513 cursor: "auto", 13514 cursorAt: false, 13515 dropOnEmpty: true, 13516 forcePlaceholderSize: false, 13517 forceHelperSize: false, 13518 grid: false, 13519 handle: false, 13520 helper: "original", 13521 items: "> *", 13522 opacity: false, 13523 placeholder: false, 13524 revert: false, 13525 scroll: true, 13526 scrollSensitivity: 20, 13527 scrollSpeed: 20, 13528 scope: "default", 13529 tolerance: "intersect", 13530 zIndex: 1000, 13531 13532 // callbacks 13533 activate: null, 13534 beforeStop: null, 13535 change: null, 13536 deactivate: null, 13537 out: null, 13538 over: null, 13539 receive: null, 13540 remove: null, 13541 sort: null, 13542 start: null, 13543 stop: null, 13544 update: null 13545 }, 13546 13547 _isOverAxis: function( x, reference, size ) { 13548 return ( x >= reference ) && ( x < ( reference + size ) ); 13549 }, 13550 13551 _isFloating: function( item ) { 13552 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 13553 }, 13554 13555 _create: function() { 13556 this.containerCache = {}; 13557 this.element.addClass("ui-sortable"); 13558 13559 //Get the items 13560 this.refresh(); 13561 13562 //Let's determine the parent's offset 13563 this.offset = this.element.offset(); 13564 13565 //Initialize mouse events for interaction 13566 this._mouseInit(); 13567 13568 this._setHandleClassName(); 13569 13570 //We're ready to go 13571 this.ready = true; 13572 13573 }, 13574 13575 _setOption: function( key, value ) { 13576 this._super( key, value ); 13577 13578 if ( key === "handle" ) { 13579 this._setHandleClassName(); 13580 } 13581 }, 13582 13583 _setHandleClassName: function() { 13584 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); 13585 $.each( this.items, function() { 13586 ( this.instance.options.handle ? 13587 this.item.find( this.instance.options.handle ) : this.item ) 13588 .addClass( "ui-sortable-handle" ); 13589 }); 13590 }, 13591 13592 _destroy: function() { 13593 this.element 13594 .removeClass( "ui-sortable ui-sortable-disabled" ) 13595 .find( ".ui-sortable-handle" ) 13596 .removeClass( "ui-sortable-handle" ); 13597 this._mouseDestroy(); 13598 13599 for ( var i = this.items.length - 1; i >= 0; i-- ) { 13600 this.items[i].item.removeData(this.widgetName + "-item"); 13601 } 13602 13603 return this; 13604 }, 13605 13606 _mouseCapture: function(event, overrideHandle) { 13607 var currentItem = null, 13608 validHandle = false, 13609 that = this; 13610 13611 if (this.reverting) { 13612 return false; 13613 } 13614 13615 if(this.options.disabled || this.options.type === "static") { 13616 return false; 13617 } 13618 13619 //We have to refresh the items data once first 13620 this._refreshItems(event); 13621 13622 //Find out if the clicked node (or one of its parents) is a actual item in this.items 13623 $(event.target).parents().each(function() { 13624 if($.data(this, that.widgetName + "-item") === that) { 13625 currentItem = $(this); 13626 return false; 13627 } 13628 }); 13629 if($.data(event.target, that.widgetName + "-item") === that) { 13630 currentItem = $(event.target); 13631 } 13632 13633 if(!currentItem) { 13634 return false; 13635 } 13636 if(this.options.handle && !overrideHandle) { 13637 $(this.options.handle, currentItem).find("*").addBack().each(function() { 13638 if(this === event.target) { 13639 validHandle = true; 13640 } 13641 }); 13642 if(!validHandle) { 13643 return false; 13644 } 13645 } 13646 13647 this.currentItem = currentItem; 13648 this._removeCurrentsFromItems(); 13649 return true; 13650 13651 }, 13652 13653 _mouseStart: function(event, overrideHandle, noActivation) { 13654 13655 var i, body, 13656 o = this.options; 13657 13658 this.currentContainer = this; 13659 13660 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 13661 this.refreshPositions(); 13662 13663 //Create and append the visible helper 13664 this.helper = this._createHelper(event); 13665 13666 //Cache the helper size 13667 this._cacheHelperProportions(); 13668 13669 /* 13670 * - Position generation - 13671 * This block generates everything position related - it's the core of draggables. 13672 */ 13673 13674 //Cache the margins of the original element 13675 this._cacheMargins(); 13676 13677 //Get the next scrolling parent 13678 this.scrollParent = this.helper.scrollParent(); 13679 13680 //The element's absolute position on the page minus margins 13681 this.offset = this.currentItem.offset(); 13682 this.offset = { 13683 top: this.offset.top - this.margins.top, 13684 left: this.offset.left - this.margins.left 13685 }; 13686 13687 $.extend(this.offset, { 13688 click: { //Where the click happened, relative to the element 13689 left: event.pageX - this.offset.left, 13690 top: event.pageY - this.offset.top 13691 }, 13692 parent: this._getParentOffset(), 13693 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 13694 }); 13695 13696 // Only after we got the offset, we can change the helper's position to absolute 13697 // TODO: Still need to figure out a way to make relative sorting possible 13698 this.helper.css("position", "absolute"); 13699 this.cssPosition = this.helper.css("position"); 13700 13701 //Generate the original position 13702 this.originalPosition = this._generatePosition(event); 13703 this.originalPageX = event.pageX; 13704 this.originalPageY = event.pageY; 13705 13706 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 13707 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 13708 13709 //Cache the former DOM position 13710 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 13711 13712 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way 13713 if(this.helper[0] !== this.currentItem[0]) { 13714 this.currentItem.hide(); 13715 } 13716 13717 //Create the placeholder 13718 this._createPlaceholder(); 13719 13720 //Set a containment if given in the options 13721 if(o.containment) { 13722 this._setContainment(); 13723 } 13724 13725 if( o.cursor && o.cursor !== "auto" ) { // cursor option 13726 body = this.document.find( "body" ); 13727 13728 // support: IE 13729 this.storedCursor = body.css( "cursor" ); 13730 body.css( "cursor", o.cursor ); 13731 13732 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 13733 } 13734 13735 if(o.opacity) { // opacity option 13736 if (this.helper.css("opacity")) { 13737 this._storedOpacity = this.helper.css("opacity"); 13738 } 13739 this.helper.css("opacity", o.opacity); 13740 } 13741 13742 if(o.zIndex) { // zIndex option 13743 if (this.helper.css("zIndex")) { 13744 this._storedZIndex = this.helper.css("zIndex"); 13745 } 13746 this.helper.css("zIndex", o.zIndex); 13747 } 13748 13749 //Prepare scrolling 13750 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { 13751 this.overflowOffset = this.scrollParent.offset(); 13752 } 13753 13754 //Call callbacks 13755 this._trigger("start", event, this._uiHash()); 13756 13757 //Recache the helper size 13758 if(!this._preserveHelperProportions) { 13759 this._cacheHelperProportions(); 13760 } 13761 13762 13763 //Post "activate" events to possible containers 13764 if( !noActivation ) { 13765 for ( i = this.containers.length - 1; i >= 0; i-- ) { 13766 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 13767 } 13768 } 13769 13770 //Prepare possible droppables 13771 if($.ui.ddmanager) { 13772 $.ui.ddmanager.current = this; 13773 } 13774 13775 if ($.ui.ddmanager && !o.dropBehaviour) { 13776 $.ui.ddmanager.prepareOffsets(this, event); 13777 } 13778 13779 this.dragging = true; 13780 13781 this.helper.addClass("ui-sortable-helper"); 13782 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 13783 return true; 13784 13785 }, 13786 13787 _mouseDrag: function(event) { 13788 var i, item, itemElement, intersection, 13789 o = this.options, 13790 scrolled = false; 13791 13792 //Compute the helpers position 13793 this.position = this._generatePosition(event); 13794 this.positionAbs = this._convertPositionTo("absolute"); 13795 13796 if (!this.lastPositionAbs) { 13797 this.lastPositionAbs = this.positionAbs; 13798 } 13799 13800 //Do scrolling 13801 if(this.options.scroll) { 13802 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { 13803 13804 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 13805 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 13806 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 13807 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 13808 } 13809 13810 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 13811 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 13812 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 13813 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 13814 } 13815 13816 } else { 13817 13818 if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) { 13819 scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); 13820 } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) { 13821 scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); 13822 } 13823 13824 if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { 13825 scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed); 13826 } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) { 13827 scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed); 13828 } 13829 13830 } 13831 13832 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 13833 $.ui.ddmanager.prepareOffsets(this, event); 13834 } 13835 } 13836 13837 //Regenerate the absolute position used for position checks 13838 this.positionAbs = this._convertPositionTo("absolute"); 13839 13840 //Set the helper position 13841 if(!this.options.axis || this.options.axis !== "y") { 13842 this.helper[0].style.left = this.position.left+"px"; 13843 } 13844 if(!this.options.axis || this.options.axis !== "x") { 13845 this.helper[0].style.top = this.position.top+"px"; 13846 } 13847 13848 //Rearrange 13849 for (i = this.items.length - 1; i >= 0; i--) { 13850 13851 //Cache variables and intersection, continue if no intersection 13852 item = this.items[i]; 13853 itemElement = item.item[0]; 13854 intersection = this._intersectsWithPointer(item); 13855 if (!intersection) { 13856 continue; 13857 } 13858 13859 // Only put the placeholder inside the current Container, skip all 13860 // items from other containers. This works because when moving 13861 // an item from one container to another the 13862 // currentContainer is switched before the placeholder is moved. 13863 // 13864 // Without this, moving items in "sub-sortables" can cause 13865 // the placeholder to jitter between the outer and inner container. 13866 if (item.instance !== this.currentContainer) { 13867 continue; 13868 } 13869 13870 // cannot intersect with itself 13871 // no useless actions that have been done before 13872 // no action if the item moved is the parent of the item checked 13873 if (itemElement !== this.currentItem[0] && 13874 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 13875 !$.contains(this.placeholder[0], itemElement) && 13876 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 13877 ) { 13878 13879 this.direction = intersection === 1 ? "down" : "up"; 13880 13881 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 13882 this._rearrange(event, item); 13883 } else { 13884 break; 13885 } 13886 13887 this._trigger("change", event, this._uiHash()); 13888 break; 13889 } 13890 } 13891 13892 //Post events to containers 13893 this._contactContainers(event); 13894 13895 //Interconnect with droppables 13896 if($.ui.ddmanager) { 13897 $.ui.ddmanager.drag(this, event); 13898 } 13899 13900 //Call callbacks 13901 this._trigger("sort", event, this._uiHash()); 13902 13903 this.lastPositionAbs = this.positionAbs; 13904 return false; 13905 13906 }, 13907 13908 _mouseStop: function(event, noPropagation) { 13909 13910 if(!event) { 13911 return; 13912 } 13913 13914 //If we are using droppables, inform the manager about the drop 13915 if ($.ui.ddmanager && !this.options.dropBehaviour) { 13916 $.ui.ddmanager.drop(this, event); 13917 } 13918 13919 if(this.options.revert) { 13920 var that = this, 13921 cur = this.placeholder.offset(), 13922 axis = this.options.axis, 13923 animation = {}; 13924 13925 if ( !axis || axis === "x" ) { 13926 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft); 13927 } 13928 if ( !axis || axis === "y" ) { 13929 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop); 13930 } 13931 this.reverting = true; 13932 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 13933 that._clear(event); 13934 }); 13935 } else { 13936 this._clear(event, noPropagation); 13937 } 13938 13939 return false; 13940 13941 }, 13942 13943 cancel: function() { 13944 13945 if(this.dragging) { 13946 13947 this._mouseUp({ target: null });
vendor: 5,388 bytes, lines 13948-14110
13948 13949 if(this.options.helper === "original") { 13950 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 13951 } else { 13952 this.currentItem.show(); 13953 } 13954 13955 //Post deactivating events to containers 13956 for (var i = this.containers.length - 1; i >= 0; i--){ 13957 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 13958 if(this.containers[i].containerCache.over) { 13959 this.containers[i]._trigger("out", null, this._uiHash(this)); 13960 this.containers[i].containerCache.over = 0; 13961 } 13962 } 13963 13964 } 13965 13966 if (this.placeholder) { 13967 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 13968 if(this.placeholder[0].parentNode) { 13969 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 13970 } 13971 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 13972 this.helper.remove(); 13973 } 13974 13975 $.extend(this, { 13976 helper: null, 13977 dragging: false, 13978 reverting: false, 13979 _noFinalSort: null 13980 }); 13981 13982 if(this.domPosition.prev) { 13983 $(this.domPosition.prev).after(this.currentItem); 13984 } else { 13985 $(this.domPosition.parent).prepend(this.currentItem); 13986 } 13987 } 13988 13989 return this; 13990 13991 }, 13992 13993 serialize: function(o) { 13994 13995 var items = this._getItemsAsjQuery(o && o.connected), 13996 str = []; 13997 o = o || {}; 13998 13999 $(items).each(function() { 14000 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 14001 if (res) { 14002 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 14003 } 14004 }); 14005 14006 if(!str.length && o.key) { 14007 str.push(o.key + "="); 14008 } 14009 14010 return str.join("&"); 14011 14012 }, 14013 14014 toArray: function(o) { 14015 14016 var items = this._getItemsAsjQuery(o && o.connected), 14017 ret = []; 14018 14019 o = o || {}; 14020 14021 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 14022 return ret; 14023 14024 }, 14025 14026 /* Be careful with the following core functions */ 14027 _intersectsWith: function(item) { 14028 14029 var x1 = this.positionAbs.left, 14030 x2 = x1 + this.helperProportions.width, 14031 y1 = this.positionAbs.top, 14032 y2 = y1 + this.helperProportions.height, 14033 l = item.left, 14034 r = l + item.width, 14035 t = item.top, 14036 b = t + item.height, 14037 dyClick = this.offset.click.top, 14038 dxClick = this.offset.click.left, 14039 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 14040 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 14041 isOverElement = isOverElementHeight && isOverElementWidth; 14042 14043 if ( this.options.tolerance === "pointer" || 14044 this.options.forcePointerForContainers || 14045 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 14046 ) { 14047 return isOverElement; 14048 } else { 14049 14050 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 14051 x2 - (this.helperProportions.width / 2) < r && // Left Half 14052 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 14053 y2 - (this.helperProportions.height / 2) < b ); // Top Half 14054 14055 } 14056 }, 14057 14058 _intersectsWithPointer: function(item) { 14059 14060 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 14061 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 14062 isOverElement = isOverElementHeight && isOverElementWidth, 14063 verticalDirection = this._getDragVerticalDirection(), 14064 horizontalDirection = this._getDragHorizontalDirection(); 14065 14066 if (!isOverElement) { 14067 return false; 14068 } 14069 14070 return this.floating ? 14071 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 14072 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 14073 14074 }, 14075 14076 _intersectsWithSides: function(item) { 14077 14078 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 14079 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 14080 verticalDirection = this._getDragVerticalDirection(), 14081 horizontalDirection = this._getDragHorizontalDirection(); 14082 14083 if (this.floating && horizontalDirection) { 14084 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 14085 } else { 14086 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 14087 } 14088 14089 }, 14090 14091 _getDragVerticalDirection: function() { 14092 var delta = this.positionAbs.top - this.lastPositionAbs.top; 14093 return delta !== 0 && (delta > 0 ? "down" : "up"); 14094 }, 14095 14096 _getDragHorizontalDirection: function() { 14097 var delta = this.positionAbs.left - this.lastPositionAbs.left; 14098 return delta !== 0 && (delta > 0 ? "right" : "left"); 14099 }, 14100 14101 refresh: function(event) { 14102 this._refreshItems(event); 14103 this._setHandleClassName(); 14104 this.refreshPositions(); 14105 return this; 14106 }, 14107 14108 _connectWith: function() { 14109 var options = this.options; 14110 return options.connectWith.constructor === String ? [options.connectWith
vendor: 21,496 bytes, lines 14110-14663
14110] : options.connectWith; 14111 }, 14112 14113 _getItemsAsjQuery: function(connected) { 14114 14115 var i, j, cur, inst, 14116 items = [], 14117 queries = [], 14118 connectWith = this._connectWith(); 14119 14120 if(connectWith && connected) { 14121 for (i = connectWith.length - 1; i >= 0; i--){ 14122 cur = $(connectWith[i], this.document[0]); 14123 for ( j = cur.length - 1; j >= 0; j--){ 14124 inst = $.data(cur[j], this.widgetFullName); 14125 if(inst && inst !== this && !inst.options.disabled) { 14126 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); 14127 } 14128 } 14129 } 14130 } 14131 14132 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); 14133 14134 function addItems() { 14135 items.push( this ); 14136 } 14137 for (i = queries.length - 1; i >= 0; i--){ 14138 queries[i][0].each( addItems ); 14139 } 14140 14141 return $(items); 14142 14143 }, 14144 14145 _removeCurrentsFromItems: function() { 14146 14147 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 14148 14149 this.items = $.grep(this.items, function (item) { 14150 for (var j=0; j < list.length; j++) { 14151 if(list[j] === item.item[0]) { 14152 return false; 14153 } 14154 } 14155 return true; 14156 }); 14157 14158 }, 14159 14160 _refreshItems: function(event) { 14161 14162 this.items = []; 14163 this.containers = [this]; 14164 14165 var i, j, cur, inst, targetData, _queries, item, queriesLength, 14166 items = this.items, 14167 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 14168 connectWith = this._connectWith(); 14169 14170 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 14171 for (i = connectWith.length - 1; i >= 0; i--){ 14172 cur = $(connectWith[i], this.document[0]); 14173 for (j = cur.length - 1; j >= 0; j--){ 14174 inst = $.data(cur[j], this.widgetFullName); 14175 if(inst && inst !== this && !inst.options.disabled) { 14176 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 14177 this.containers.push(inst); 14178 } 14179 } 14180 } 14181 } 14182 14183 for (i = queries.length - 1; i >= 0; i--) { 14184 targetData = queries[i][1]; 14185 _queries = queries[i][0]; 14186 14187 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 14188 item = $(_queries[j]); 14189 14190 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 14191 14192 items.push({ 14193 item: item, 14194 instance: targetData, 14195 width: 0, height: 0, 14196 left: 0, top: 0 14197 }); 14198 } 14199 } 14200 14201 }, 14202 14203 refreshPositions: function(fast) { 14204 14205 // Determine whether items are being displayed horizontally 14206 this.floating = this.items.length ? 14207 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 14208 false; 14209 14210 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 14211 if(this.offsetParent && this.helper) { 14212 this.offset.parent = this._getParentOffset(); 14213 } 14214 14215 var i, item, t, p; 14216 14217 for (i = this.items.length - 1; i >= 0; i--){ 14218 item = this.items[i]; 14219 14220 //We ignore calculating positions of all connected containers when we're not over them 14221 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 14222 continue; 14223 } 14224 14225 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 14226 14227 if (!fast) { 14228 item.width = t.outerWidth(); 14229 item.height = t.outerHeight(); 14230 } 14231 14232 p = t.offset(); 14233 item.left = p.left; 14234 item.top = p.top; 14235 } 14236 14237 if(this.options.custom && this.options.custom.refreshContainers) { 14238 this.options.custom.refreshContainers.call(this); 14239 } else { 14240 for (i = this.containers.length - 1; i >= 0; i--){ 14241 p = this.containers[i].element.offset(); 14242 this.containers[i].containerCache.left = p.left; 14243 this.containers[i].containerCache.top = p.top; 14244 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 14245 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 14246 } 14247 } 14248 14249 return this; 14250 }, 14251 14252 _createPlaceholder: function(that) { 14253 that = that || this; 14254 var className, 14255 o = that.options; 14256 14257 if(!o.placeholder || o.placeholder.constructor === String) { 14258 className = o.placeholder; 14259 o.placeholder = { 14260 element: function() { 14261 14262 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 14263 element = $( "<" + nodeName + ">", that.document[0] ) 14264 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 14265 .removeClass("ui-sortable-helper"); 14266 14267 if ( nodeName === "tbody" ) { 14268 that._createTrPlaceholder( 14269 that.currentItem.find( "tr" ).eq( 0 ), 14270 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 14271 ); 14272 } else if ( nodeName === "tr" ) { 14273 that._createTrPlaceholder( that.currentItem, element ); 14274 } else if ( nodeName === "img" ) { 14275 element.attr( "src", that.currentItem.attr( "src" ) ); 14276 } 14277 14278 if ( !className ) { 14279 element.css( "visibility", "hidden" ); 14280 } 14281 14282 return element; 14283 }, 14284 update: function(container, p) { 14285 14286 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 14287 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 14288 if(className && !o.forcePlaceholderSize) { 14289 return; 14290 } 14291 14292 //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item 14293 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 14294 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 14295 } 14296 }; 14297 } 14298 14299 //Create the placeholder 14300 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 14301 14302 //Append it after the actual current item 14303 that.currentItem.after(that.placeholder); 14304 14305 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 14306 o.placeholder.update(that, that.placeholder); 14307 14308 }, 14309 14310 _createTrPlaceholder: function( sourceTr, targetTr ) { 14311 var that = this; 14312 14313 sourceTr.children().each(function() { 14314 $( "<td> </td>", that.document[ 0 ] ) 14315 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 14316 .appendTo( targetTr ); 14317 }); 14318 }, 14319 14320 _contactContainers: function(event) { 14321 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, 14322 innermostContainer = null, 14323 innermostIndex = null; 14324 14325 // get innermost container that intersects with item 14326 for (i = this.containers.length - 1; i >= 0; i--) { 14327 14328 // never consider a container that's located within the item itself 14329 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 14330 continue; 14331 } 14332 14333 if(this._intersectsWith(this.containers[i].containerCache)) { 14334 14335 // if we've already found a container and it's more "inner" than this, then continue 14336 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 14337 continue; 14338 } 14339 14340 innermostContainer = this.containers[i]; 14341 innermostIndex = i; 14342 14343 } else { 14344 // container doesn't intersect. trigger "out" event if necessary 14345 if(this.containers[i].containerCache.over) { 14346 this.containers[i]._trigger("out", event, this._uiHash(this)); 14347 this.containers[i].containerCache.over = 0; 14348 } 14349 } 14350 14351 } 14352 14353 // if no intersecting containers found, return 14354 if(!innermostContainer) { 14355 return; 14356 } 14357 14358 // move the item into the container if it's not there already 14359 if(this.containers.length === 1) { 14360 if (!this.containers[innermostIndex].containerCache.over) { 14361 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14362 this.containers[innermostIndex].containerCache.over = 1; 14363 } 14364 } else { 14365 14366 //When entering a new container, we will find the item with the least distance and append our item near it 14367 dist = 10000; 14368 itemWithLeastDistance = null; 14369 floating = innermostContainer.floating || this._isFloating(this.currentItem); 14370 posProperty = floating ? "left" : "top"; 14371 sizeProperty = floating ? "width" : "height"; 14372 axis = floating ? "clientX" : "clientY"; 14373 14374 for (j = this.items.length - 1; j >= 0; j--) { 14375 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 14376 continue; 14377 } 14378 if(this.items[j].item[0] === this.currentItem[0]) { 14379 continue; 14380 } 14381 14382 cur = this.items[j].item.offset()[posProperty]; 14383 nearBottom = false; 14384 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 14385 nearBottom = true; 14386 } 14387 14388 if ( Math.abs( event[ axis ] - cur ) < dist ) { 14389 dist = Math.abs( event[ axis ] - cur ); 14390 itemWithLeastDistance = this.items[ j ]; 14391 this.direction = nearBottom ? "up": "down"; 14392 } 14393 } 14394 14395 //Check if dropOnEmpty is enabled 14396 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 14397 return; 14398 } 14399 14400 if(this.currentContainer === this.containers[innermostIndex]) { 14401 if ( !this.currentContainer.containerCache.over ) { 14402 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 14403 this.currentContainer.containerCache.over = 1; 14404 } 14405 return; 14406 } 14407 14408 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 14409 this._trigger("change", event, this._uiHash()); 14410 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 14411 this.currentContainer = this.containers[innermostIndex]; 14412 14413 //Update the placeholder 14414 this.options.placeholder.update(this.currentContainer, this.placeholder); 14415 14416 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14417 this.containers[innermostIndex].containerCache.over = 1; 14418 } 14419 14420 14421 }, 14422 14423 _createHelper: function(event) { 14424 14425 var o = this.options, 14426 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 14427 14428 //Add the helper to the DOM if that didn't happen already 14429 if(!helper.parents("body").length) { 14430 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 14431 } 14432 14433 if(helper[0] === this.currentItem[0]) { 14434 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; 14435 } 14436 14437 if(!helper[0].style.width || o.forceHelperSize) { 14438 helper.width(this.currentItem.width()); 14439 } 14440 if(!helper[0].style.height || o.forceHelperSize) { 14441 helper.height(this.currentItem.height()); 14442 } 14443 14444 return helper; 14445 14446 }, 14447 14448 _adjustOffsetFromHelper: function(obj) { 14449 if (typeof obj === "string") { 14450 obj = obj.split(" "); 14451 } 14452 if ($.isArray(obj)) { 14453 obj = {left: +obj[0], top: +obj[1] || 0}; 14454 } 14455 if ("left" in obj) { 14456 this.offset.click.left = obj.left + this.margins.left; 14457 } 14458 if ("right" in obj) { 14459 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 14460 } 14461 if ("top" in obj) { 14462 this.offset.click.top = obj.top + this.margins.top; 14463 } 14464 if ("bottom" in obj) { 14465 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 14466 } 14467 }, 14468 14469 _getParentOffset: function() { 14470 14471 14472 //Get the offsetParent and cache its position 14473 this.offsetParent = this.helper.offsetParent(); 14474 var po = this.offsetParent.offset(); 14475 14476 // This is a special case where we need to modify a offset calculated on start, since the following happened: 14477 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 14478 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 14479 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 14480 if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) { 14481 po.left += this.scrollParent.scrollLeft(); 14482 po.top += this.scrollParent.scrollTop(); 14483 } 14484 14485 // This needs to be actually done for all browsers, since pageX/pageY includes this information 14486 // with an ugly IE fix 14487 if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 14488 po = { top: 0, left: 0 }; 14489 } 14490 14491 return { 14492 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 14493 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 14494 }; 14495 14496 }, 14497 14498 _getRelativeOffset: function() { 14499 14500 if(this.cssPosition === "relative") { 14501 var p = this.currentItem.position(); 14502 return { 14503 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 14504 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 14505 }; 14506 } else { 14507 return { top: 0, left: 0 }; 14508 } 14509 14510 }, 14511 14512 _cacheMargins: function() { 14513 this.margins = { 14514 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 14515 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 14516 }; 14517 }, 14518 14519 _cacheHelperProportions: function() { 14520 this.helperProportions = { 14521 width: this.helper.outerWidth(), 14522 height: this.helper.outerHeight() 14523 }; 14524 }, 14525 14526 _setContainment: function() { 14527 14528 var ce, co, over, 14529 o = this.options; 14530 if(o.containment === "parent") { 14531 o.containment = this.helper[0].parentNode; 14532 } 14533 if(o.containment === "document" || o.containment === "window") { 14534 this.containment = [ 14535 0 - this.offset.relative.left - this.offset.parent.left, 14536 0 - this.offset.relative.top - this.offset.parent.top, 14537 o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, 14538 (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 14539 ]; 14540 } 14541 14542 if(!(/^(document|window|parent)$/).test(o.containment)) { 14543 ce = $(o.containment)[0]; 14544 co = $(o.containment).offset(); 14545 over = ($(ce).css("overflow") !== "hidden"); 14546 14547 this.containment = [ 14548 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 14549 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 14550 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, 14551 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 14552 ]; 14553 } 14554 14555 }, 14556 14557 _convertPositionTo: function(d, pos) { 14558 14559 if(!pos) { 14560 pos = this.position; 14561 } 14562 var mod = d === "absolute" ? 1 : -1, 14563 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 14564 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 14565 14566 return { 14567 top: ( 14568 pos.top + // The absolute mouse position 14569 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14570 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 14571 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 14572 ), 14573 left: ( 14574 pos.left + // The absolute mouse position 14575 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14576 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 14577 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 14578 ) 14579 }; 14580 14581 }, 14582 14583 _generatePosition: function(event) { 14584 14585 var top, left, 14586 o = this.options, 14587 pageX = event.pageX, 14588 pageY = event.pageY, 14589 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 14590 14591 // This is another very weird special case that only happens for relative elements: 14592 // 1. If the css position is relative 14593 // 2. and the scroll parent is the document or similar to the offset parent 14594 // we have to refresh the relative offset during the scroll so there are no jumps 14595 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) { 14596 this.offset.relative = this._getRelativeOffset(); 14597 } 14598 14599 /* 14600 * - Position constraining - 14601 * Constrain the position to a mix of grid, containment. 14602 */ 14603 14604 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 14605 14606 if(this.containment) { 14607 if(event.pageX - this.offset.click.left < this.containment[0]) { 14608 pageX = this.containment[0] + this.offset.click.left; 14609 } 14610 if(event.pageY - this.offset.click.top < this.containment[1]) { 14611 pageY = this.containment[1] + this.offset.click.top; 14612 } 14613 if(event.pageX - this.offset.click.left > this.containment[2]) { 14614 pageX = this.containment[2] + this.offset.click.left; 14615 } 14616 if(event.pageY - this.offset.click.top > this.containment[3]) { 14617 pageY = this.containment[3] + this.offset.click.top; 14618 } 14619 } 14620 14621 if(o.grid) { 14622 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 14623 pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 14624 14625 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 14626 pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 14627 } 14628 14629 } 14630 14631 return { 14632 top: ( 14633 pageY - // The absolute mouse position 14634 this.offset.click.top - // Click offset (relative to the element) 14635 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 14636 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 14637 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 14638 ), 14639 left: ( 14640 pageX - // The absolute mouse position 14641 this.offset.click.left - // Click offset (relative to the element) 14642 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 14643 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 14644 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 14645 ) 14646 }; 14647 14648 }, 14649 14650 _rearrange: function(event, i, a, hardRefresh) { 14651 14652 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); 14653 14654 //Various things done here to improve the performance: 14655 // 1. we create a setTimeout, that calls refreshPositions 14656 // 2. on the instance, we have a counter variable, that get's higher after every append 14657 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 14658 // 4. this lets only the last addition to the timeout stack through 14659 this.counter = this.counter ? ++this.counter : 1; 14660 var counter = this.counter; 14661 14662 this._delay(function() { 14663 if(counter === this.counter) {
vendor: 4,297 bytes, lines 14664-14792
14664 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 14665 } 14666 }); 14667 14668 }, 14669 14670 _clear: function(event, noPropagation) { 14671 14672 this.reverting = false; 14673 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 14674 // everything else normalized again 14675 var i, 14676 delayedTriggers = []; 14677 14678 // We first have to update the dom position of the actual currentItem 14679 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 14680 if(!this._noFinalSort && this.currentItem.parent().length) { 14681 this.placeholder.before(this.currentItem); 14682 } 14683 this._noFinalSort = null; 14684 14685 if(this.helper[0] === this.currentItem[0]) { 14686 for(i in this._storedCSS) { 14687 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 14688 this._storedCSS[i] = ""; 14689 } 14690 } 14691 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 14692 } else { 14693 this.currentItem.show(); 14694 } 14695 14696 if(this.fromOutside && !noPropagation) { 14697 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 14698 } 14699 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 14700 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 14701 } 14702 14703 // Check if the items Container has Changed and trigger appropriate 14704 // events. 14705 if (this !== this.currentContainer) { 14706 if(!noPropagation) { 14707 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 14708 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14709 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14710 } 14711 } 14712 14713 14714 //Post events to containers 14715 function delayEvent( type, instance, container ) { 14716 return function( event ) { 14717 container._trigger( type, event, instance._uiHash( instance ) ); 14718 }; 14719 } 14720 for (i = this.containers.length - 1; i >= 0; i--){ 14721 if (!noPropagation) { 14722 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 14723 } 14724 if(this.containers[i].containerCache.over) { 14725 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 14726 this.containers[i].containerCache.over = 0; 14727 } 14728 } 14729 14730 //Do what was originally in plugins 14731 if ( this.storedCursor ) { 14732 this.document.find( "body" ).css( "cursor", this.storedCursor ); 14733 this.storedStylesheet.remove(); 14734 } 14735 if(this._storedOpacity) { 14736 this.helper.css("opacity", this._storedOpacity); 14737 } 14738 if(this._storedZIndex) { 14739 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 14740 } 14741 14742 this.dragging = false; 14743 14744 if(!noPropagation) { 14745 this._trigger("beforeStop", event, this._uiHash()); 14746 } 14747 14748 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 14749 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 14750 14751 if ( !this.cancelHelperRemoval ) { 14752 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 14753 this.helper.remove(); 14754 } 14755 this.helper = null; 14756 } 14757 14758 if(!noPropagation) { 14759 for (i=0; i < delayedTriggers.length; i++) { 14760 delayedTriggers[i].call(this, event); 14761 } //Trigger all delayed events 14762 this._trigger("stop", event, this._uiHash()); 14763 } 14764 14765 this.fromOutside = false; 14766 return !this.cancelHelperRemoval; 14767 14768 }, 14769 14770 _trigger: function() { 14771 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 14772 this.cancel(); 14773 } 14774 }, 14775 14776 _uiHash: function(_inst) { 14777 var inst = _inst || this; 14778 return { 14779 helper: inst.helper, 14780 placeholder: inst.placeholder || $([]), 14781 position: inst.position, 14782 originalPosition: inst.originalPosition, 14783 offset: inst.positionAbs, 14784 item: inst.currentItem, 14785 sender: _inst ? _inst.element : null 14786 }; 14787 } 14788 14789}); 14790 14791 14792/*!
vendor: 13,186 bytes, lines 14793-15293
14793 * jQuery UI Spinner 1.11.4 14794 * http://jqueryui.com 14795 * 14796 * Copyright jQuery Foundation and other contributors 14797 * Released under the MIT license. 14798 * http://jquery.org/license 14799 * 14800 * http://api.jqueryui.com/spinner/ 14801 */ 14802 14803 14804function spinner_modifier( fn ) { 14805 return function() { 14806 var previous = this.element.val(); 14807 fn.apply( this, arguments ); 14808 this._refresh(); 14809 if ( previous !== this.element.val() ) { 14810 this._trigger( "change" ); 14811 } 14812 }; 14813} 14814 14815var spinner = $.widget( "ui.spinner", { 14816 version: "1.11.4", 14817 defaultElement: "<input>", 14818 widgetEventPrefix: "spin", 14819 options: { 14820 culture: null, 14821 icons: { 14822 down: "ui-icon-triangle-1-s", 14823 up: "ui-icon-triangle-1-n" 14824 }, 14825 incremental: true, 14826 max: null, 14827 min: null, 14828 numberFormat: null, 14829 page: 10, 14830 step: 1, 14831 14832 change: null, 14833 spin: null, 14834 start: null, 14835 stop: null 14836 }, 14837 14838 _create: function() { 14839 // handle string values that need to be parsed 14840 this._setOption( "max", this.options.max ); 14841 this._setOption( "min", this.options.min ); 14842 this._setOption( "step", this.options.step ); 14843 14844 // Only format if there is a value, prevents the field from being marked 14845 // as invalid in Firefox, see #9573. 14846 if ( this.value() !== "" ) { 14847 // Format the value, but don't constrain. 14848 this._value( this.element.val(), true ); 14849 } 14850 14851 this._draw(); 14852 this._on( this._events ); 14853 this._refresh(); 14854 14855 // turning off autocomplete prevents the browser from remembering the 14856 // value when navigating through history, so we re-enable autocomplete 14857 // if the page is unloaded before the widget is destroyed. #7790 14858 this._on( this.window, { 14859 beforeunload: function() { 14860 this.element.removeAttr( "autocomplete" ); 14861 } 14862 }); 14863 }, 14864 14865 _getCreateOptions: function() { 14866 var options = {}, 14867 element = this.element; 14868 14869 $.each( [ "min", "max", "step" ], function( i, option ) { 14870 var value = element.attr( option ); 14871 if ( value !== undefined && value.length ) { 14872 options[ option ] = value; 14873 } 14874 }); 14875 14876 return options; 14877 }, 14878 14879 _events: { 14880 keydown: function( event ) { 14881 if ( this._start( event ) && this._keydown( event ) ) { 14882 event.preventDefault(); 14883 } 14884 }, 14885 keyup: "_stop", 14886 focus: function() { 14887 this.previous = this.element.val(); 14888 }, 14889 blur: function( event ) { 14890 if ( this.cancelBlur ) { 14891 delete this.cancelBlur; 14892 return; 14893 } 14894 14895 this._stop(); 14896 this._refresh(); 14897 if ( this.previous !== this.element.val() ) { 14898 this._trigger( "change", event ); 14899 } 14900 }, 14901 mousewheel: function( event, delta ) { 14902 if ( !delta ) { 14903 return; 14904 } 14905 if ( !this.spinning && !this._start( event ) ) { 14906 return false; 14907 } 14908 14909 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 14910 clearTimeout( this.mousewheelTimer ); 14911 this.mousewheelTimer = this._delay(function() { 14912 if ( this.spinning ) { 14913 this._stop( event ); 14914 } 14915 }, 100 ); 14916 event.preventDefault(); 14917 }, 14918 "mousedown .ui-spinner-button": function( event ) { 14919 var previous; 14920 14921 // We never want the buttons to have focus; whenever the user is 14922 // interacting with the spinner, the focus should be on the input. 14923 // If the input is focused then this.previous is properly set from 14924 // when the input first received focus. If the input is not focused 14925 // then we need to set this.previous based on the value before spinning. 14926 previous = this.element[0] === this.document[0].activeElement ? 14927 this.previous : this.element.val(); 14928 function checkFocus() { 14929 var isActive = this.element[0] === this.document[0].activeElement; 14930 if ( !isActive ) { 14931 this.element.focus(); 14932 this.previous = previous; 14933 // support: IE 14934 // IE sets focus asynchronously, so we need to check if focus 14935 // moved off of the input because the user clicked on the button. 14936 this._delay(function() { 14937 this.previous = previous; 14938 }); 14939 } 14940 } 14941 14942 // ensure focus is on (or stays on) the text field 14943 event.preventDefault(); 14944 checkFocus.call( this ); 14945 14946 // support: IE 14947 // IE doesn't prevent moving focus even with event.preventDefault() 14948 // so we set a flag to know when we should ignore the blur event 14949 // and check (again) if focus moved off of the input. 14950 this.cancelBlur = true; 14951 this._delay(function() { 14952 delete this.cancelBlur; 14953 checkFocus.call( this ); 14954 }); 14955 14956 if ( this._start( event ) === false ) { 14957 return; 14958 } 14959 14960 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14961 }, 14962 "mouseup .ui-spinner-button": "_stop", 14963 "mouseenter .ui-spinner-button": function( event ) { 14964 // button will add ui-state-active if mouse was down while mouseleave and kept down 14965 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14966 return; 14967 } 14968 14969 if ( this._start( event ) === false ) { 14970 return false; 14971 } 14972 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14973 }, 14974 // TODO: do we really want to consider this a stop? 14975 // shouldn't we just stop the repeater and wait until mouseup before 14976 // we trigger the stop event? 14977 "mouseleave .ui-spinner-button": "_stop" 14978 }, 14979 14980 _draw: function() { 14981 var uiSpinner = this.uiSpinner = this.element 14982 .addClass( "ui-spinner-input" ) 14983 .attr( "autocomplete", "off" ) 14984 .wrap( this._uiSpinnerHtml() ) 14985 .parent() 14986 // add buttons 14987 .append( this._buttonHtml() ); 14988 14989 this.element.attr( "role", "spinbutton" ); 14990 14991 // button bindings 14992 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 14993 .attr( "tabIndex", -1 ) 14994 .button() 14995 .removeClass( "ui-corner-all" ); 14996 14997 // IE 6 doesn't understand height: 50% for the buttons 14998 // unless the wrapper has an explicit height 14999 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 15000 uiSpinner.height() > 0 ) { 15001 uiSpinner.height( uiSpinner.height() ); 15002 } 15003 15004 // disable spinner if element was already disabled 15005 if ( this.options.disabled ) { 15006 this.disable(); 15007 } 15008 }, 15009 15010 _keydown: function( event ) { 15011 var options = this.options, 15012 keyCode = $.ui.keyCode; 15013 15014 switch ( event.keyCode ) { 15015 case keyCode.UP: 15016 this._repeat( null, 1, event ); 15017 return true; 15018 case keyCode.DOWN: 15019 this._repeat( null, -1, event ); 15020 return true; 15021 case keyCode.PAGE_UP: 15022 this._repeat( null, options.page, event ); 15023 return true; 15024 case keyCode.PAGE_DOWN: 15025 this._repeat( null, -options.page, event ); 15026 return true; 15027 } 15028 15029 return false; 15030 }, 15031 15032 _uiSpinnerHtml: function() { 15033 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 15034 }, 15035 15036 _buttonHtml: function() { 15037 return "" + 15038 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 15039 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 15040 "</a>" + 15041 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 15042 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 15043 "</a>"; 15044 }, 15045 15046 _start: function( event ) { 15047 if ( !this.spinning && this._trigger( "start", event ) === false ) { 15048 return false; 15049 } 15050 15051 if ( !this.counter ) { 15052 this.counter = 1; 15053 } 15054 this.spinning = true; 15055 return true; 15056 }, 15057 15058 _repeat: function( i, steps, event ) { 15059 i = i || 500; 15060 15061 clearTimeout( this.timer ); 15062 this.timer = this._delay(function() { 15063 this._repeat( 40, steps, event ); 15064 }, i ); 15065 15066 this._spin( steps * this.options.step, event ); 15067 }, 15068 15069 _spin: function( step, event ) { 15070 var value = this.value() || 0; 15071 15072 if ( !this.counter ) { 15073 this.counter = 1; 15074 } 15075 15076 value = this._adjustValue( value + step * this._increment( this.counter ) ); 15077 15078 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 15079 this._value( value ); 15080 this.counter++; 15081 } 15082 }, 15083 15084 _increment: function( i ) { 15085 var incremental = this.options.incremental; 15086 15087 if ( incremental ) { 15088 return $.isFunction( incremental ) ? 15089 incremental( i ) : 15090 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 15091 } 15092 15093 return 1; 15094 }, 15095 15096 _precision: function() { 15097 var precision = this._precisionOf( this.options.step ); 15098 if ( this.options.min !== null ) { 15099 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15100 } 15101 return precision; 15102 }, 15103 15104 _precisionOf: function( num ) { 15105 var str = num.toString(), 15106 decimal = str.indexOf( "." ); 15107 return decimal === -1 ? 0 : str.length - decimal - 1; 15108 }, 15109 15110 _adjustValue: function( value ) { 15111 var base, aboveMin, 15112 options = this.options; 15113 15114 // make sure we're at a valid step 15115 // - find out where we are relative to the base (min or 0) 15116 base = options.min !== null ? options.min : 0; 15117 aboveMin = value - base; 15118 // - round to the nearest step 15119 aboveMin = Math.round(aboveMin / options.step) * options.step; 15120 // - rounding is based on 0, so adjust back to our base 15121 value = base + aboveMin; 15122 15123 // fix precision from bad JS floating point math 15124 value = parseFloat( value.toFixed( this._precision() ) ); 15125 15126 // clamp the value 15127 if ( options.max !== null && value > options.max) { 15128 return options.max; 15129 } 15130 if ( options.min !== null && value < options.min ) { 15131 return options.min; 15132 } 15133 15134 return value; 15135 }, 15136 15137 _stop: function( event ) { 15138 if ( !this.spinning ) { 15139 return; 15140 } 15141 15142 clearTimeout( this.timer ); 15143 clearTimeout( this.mousewheelTimer ); 15144 this.counter = 0; 15145 this.spinning = false; 15146 this._trigger( "stop", event ); 15147 }, 15148 15149 _setOption: function( key, value ) { 15150 if ( key === "culture" || key === "numberFormat" ) { 15151 var prevValue = this._parse( this.element.val() ); 15152 this.options[ key ] = value; 15153 this.element.val( this._format( prevValue ) ); 15154 return; 15155 } 15156 15157 if ( key === "max" || key === "min" || key === "step" ) { 15158 if ( typeof value === "string" ) { 15159 value = this._parse( value ); 15160 } 15161 } 15162 if ( key === "icons" ) { 15163 this.buttons.first().find( ".ui-icon" ) 15164 .removeClass( this.options.icons.up ) 15165 .addClass( value.up ); 15166 this.buttons.last().find( ".ui-icon" ) 15167 .removeClass( this.options.icons.down ) 15168 .addClass( value.down ); 15169 } 15170 15171 this._super( key, value ); 15172 15173 if ( key === "disabled" ) { 15174 this.widget().toggleClass( "ui-state-disabled", !!value ); 15175 this.element.prop( "disabled", !!value ); 15176 this.buttons.button( value ? "disable" : "enable" ); 15177 } 15178 }, 15179 15180 _setOptions: spinner_modifier(function( options ) { 15181 this._super( options ); 15182 }), 15183 15184 _parse: function( val ) { 15185 if ( typeof val === "string" && val !== "" ) { 15186 val = window.Globalize && this.options.numberFormat ? 15187 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 15188 } 15189 return val === "" || isNaN( val ) ? null : val; 15190 }, 15191 15192 _format: function( value ) { 15193 if ( value === "" ) { 15194 return ""; 15195 } 15196 return window.Globalize && this.options.numberFormat ? 15197 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 15198 value; 15199 }, 15200 15201 _refresh: function() { 15202 this.element.attr({ 15203 "aria-valuemin": this.options.min, 15204 "aria-valuemax": this.options.max, 15205 // TODO: what should we do with values that can't be parsed? 15206 "aria-valuenow": this._parse( this.element.val() ) 15207 }); 15208 }, 15209 15210 isValid: function() { 15211 var value = this.value(); 15212 15213 // null is invalid 15214 if ( value === null ) { 15215 return false; 15216 } 15217 15218 // if value gets adjusted, it's invalid 15219 return value === this._adjustValue( value ); 15220 }, 15221 15222 // update the value without triggering change 15223 _value: function( value, allowAny ) { 15224 var parsed; 15225 if ( value !== "" ) { 15226 parsed = this._parse( value ); 15227 if ( parsed !== null ) { 15228 if ( !allowAny ) { 15229 parsed = this._adjustValue( parsed ); 15230 } 15231 value = this._format( parsed ); 15232 } 15233 } 15234 this.element.val( value ); 15235 this._refresh(); 15236 }, 15237 15238 _destroy: function() { 15239 this.element 15240 .removeClass( "ui-spinner-input" ) 15241 .prop( "disabled", false ) 15242 .removeAttr( "autocomplete" ) 15243 .removeAttr( "role" ) 15244 .removeAttr( "aria-valuemin" ) 15245 .removeAttr( "aria-valuemax" ) 15246 .removeAttr( "aria-valuenow" ); 15247 this.uiSpinner.replaceWith( this.element ); 15248 }, 15249 15250 stepUp: spinner_modifier(function( steps ) { 15251 this._stepUp( steps ); 15252 }), 15253 _stepUp: function( steps ) { 15254 if ( this._start() ) { 15255 this._spin( (steps || 1) * this.options.step ); 15256 this._stop(); 15257 } 15258 }, 15259 15260 stepDown: spinner_modifier(function( steps ) { 15261 this._stepDown( steps ); 15262 }), 15263 _stepDown: function( steps ) { 15264 if ( this._start() ) { 15265 this._spin( (steps || 1) * -this.options.step ); 15266 this._stop(); 15267 } 15268 }, 15269 15270 pageUp: spinner_modifier(function( pages ) { 15271 this._stepUp( (pages || 1) * this.options.page ); 15272 }), 15273 15274 pageDown: spinner_modifier(function( pages ) { 15275 this._stepDown( (pages || 1) * this.options.page ); 15276 }), 15277 15278 value: function( newVal ) { 15279 if ( !arguments.length ) { 15280 return this._parse( this.element.val() ); 15281 } 15282 spinner_modifier( this._value ).call( this, newVal ); 15283 }, 15284 15285 widget: function() { 15286 return this.uiSpinner; 15287 } 15288}); 15289 15290 15291/*! 15292 * jQuery UI Tabs 1.11.4 15293 * http://jqueryui.com
vendor: 36,920 bytes, lines 15294-16622
15294 * 15295 * Copyright jQuery Foundation and other contributors 15296 * Released under the MIT license. 15297 * http://jquery.org/license 15298 * 15299 * http://api.jqueryui.com/tabs/ 15300 */ 15301 15302 15303var tabs = $.widget( "ui.tabs", { 15304 version: "1.11.4", 15305 delay: 300, 15306 options: { 15307 active: null, 15308 collapsible: false, 15309 event: "click", 15310 heightStyle: "content", 15311 hide: null, 15312 show: null, 15313 15314 // callbacks 15315 activate: null, 15316 beforeActivate: null, 15317 beforeLoad: null, 15318 load: null 15319 }, 15320 15321 _isLocal: (function() { 15322 var rhash = /#.*$/; 15323 15324 return function( anchor ) { 15325 var anchorUrl, locationUrl; 15326 15327 // support: IE7 15328 // IE7 doesn't normalize the href property when set via script (#9317) 15329 anchor = anchor.cloneNode( false ); 15330 15331 anchorUrl = anchor.href.replace( rhash, "" ); 15332 locationUrl = location.href.replace( rhash, "" ); 15333 15334 // decoding may throw an error if the URL isn't UTF-8 (#9518) 15335 try { 15336 anchorUrl = decodeURIComponent( anchorUrl ); 15337 } catch ( error ) {} 15338 try { 15339 locationUrl = decodeURIComponent( locationUrl ); 15340 } catch ( error ) {} 15341 15342 return anchor.hash.length > 1 && anchorUrl === locationUrl; 15343 }; 15344 })(), 15345 15346 _create: function() { 15347 var that = this, 15348 options = this.options; 15349 15350 this.running = false; 15351 15352 this.element 15353 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 15354 .toggleClass( "ui-tabs-collapsible", options.collapsible ); 15355 15356 this._processTabs(); 15357 options.active = this._initialActive(); 15358 15359 // Take disabling tabs via class attribute from HTML 15360 // into account and update option properly. 15361 if ( $.isArray( options.disabled ) ) { 15362 options.disabled = $.unique( options.disabled.concat( 15363 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 15364 return that.tabs.index( li ); 15365 }) 15366 ) ).sort(); 15367 } 15368 15369 // check for length avoids error when initializing empty list 15370 if ( this.options.active !== false && this.anchors.length ) { 15371 this.active = this._findActive( options.active ); 15372 } else { 15373 this.active = $(); 15374 } 15375 15376 this._refresh(); 15377 15378 if ( this.active.length ) { 15379 this.load( options.active ); 15380 } 15381 }, 15382 15383 _initialActive: function() { 15384 var active = this.options.active, 15385 collapsible = this.options.collapsible, 15386 locationHash = location.hash.substring( 1 ); 15387 15388 if ( active === null ) { 15389 // check the fragment identifier in the URL 15390 if ( locationHash ) { 15391 this.tabs.each(function( i, tab ) { 15392 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 15393 active = i; 15394 return false; 15395 } 15396 }); 15397 } 15398 15399 // check for a tab marked active via a class 15400 if ( active === null ) { 15401 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 15402 } 15403 15404 // no active tab, set to false 15405 if ( active === null || active === -1 ) { 15406 active = this.tabs.length ? 0 : false; 15407 } 15408 } 15409 15410 // handle numbers: negative, out of range 15411 if ( active !== false ) { 15412 active = this.tabs.index( this.tabs.eq( active ) ); 15413 if ( active === -1 ) { 15414 active = collapsible ? false : 0; 15415 } 15416 } 15417 15418 // don't allow collapsible: false and active: false 15419 if ( !collapsible && active === false && this.anchors.length ) { 15420 active = 0; 15421 } 15422 15423 return active; 15424 }, 15425 15426 _getCreateEventData: function() { 15427 return { 15428 tab: this.active, 15429 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 15430 }; 15431 }, 15432 15433 _tabKeydown: function( event ) { 15434 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 15435 selectedIndex = this.tabs.index( focusedTab ), 15436 goingForward = true; 15437 15438 if ( this._handlePageNav( event ) ) { 15439 return; 15440 } 15441 15442 switch ( event.keyCode ) { 15443 case $.ui.keyCode.RIGHT: 15444 case $.ui.keyCode.DOWN: 15445 selectedIndex++; 15446 break; 15447 case $.ui.keyCode.UP: 15448 case $.ui.keyCode.LEFT: 15449 goingForward = false; 15450 selectedIndex--; 15451 break; 15452 case $.ui.keyCode.END: 15453 selectedIndex = this.anchors.length - 1; 15454 break; 15455 case $.ui.keyCode.HOME: 15456 selectedIndex = 0; 15457 break; 15458 case $.ui.keyCode.SPACE: 15459 // Activate only, no collapsing 15460 event.preventDefault(); 15461 clearTimeout( this.activating ); 15462 this._activate( selectedIndex ); 15463 return; 15464 case $.ui.keyCode.ENTER: 15465 // Toggle (cancel delayed activation, allow collapsing) 15466 event.preventDefault(); 15467 clearTimeout( this.activating ); 15468 // Determine if we should collapse or activate 15469 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 15470 return; 15471 default: 15472 return; 15473 } 15474 15475 // Focus the appropriate tab, based on which key was pressed 15476 event.preventDefault(); 15477 clearTimeout( this.activating ); 15478 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 15479 15480 // Navigating with control/command key will prevent automatic activation 15481 if ( !event.ctrlKey && !event.metaKey ) { 15482 15483 // Update aria-selected immediately so that AT think the tab is already selected. 15484 // Otherwise AT may confuse the user by stating that they need to activate the tab, 15485 // but the tab will already be activated by the time the announcement finishes. 15486 focusedTab.attr( "aria-selected", "false" ); 15487 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 15488 15489 this.activating = this._delay(function() { 15490 this.option( "active", selectedIndex ); 15491 }, this.delay ); 15492 } 15493 }, 15494 15495 _panelKeydown: function( event ) { 15496 if ( this._handlePageNav( event ) ) { 15497 return; 15498 } 15499 15500 // Ctrl+up moves focus to the current tab 15501 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 15502 event.preventDefault(); 15503 this.active.focus(); 15504 } 15505 }, 15506 15507 // Alt+page up/down moves focus to the previous/next tab (and activates) 15508 _handlePageNav: function( event ) { 15509 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 15510 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 15511 return true; 15512 } 15513 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 15514 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 15515 return true; 15516 } 15517 }, 15518 15519 _findNextTab: function( index, goingForward ) { 15520 var lastTabIndex = this.tabs.length - 1; 15521 15522 function constrain() { 15523 if ( index > lastTabIndex ) { 15524 index = 0; 15525 } 15526 if ( index < 0 ) { 15527 index = lastTabIndex; 15528 } 15529 return index; 15530 } 15531 15532 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 15533 index = goingForward ? index + 1 : index - 1; 15534 } 15535 15536 return index; 15537 }, 15538 15539 _focusNextTab: function( index, goingForward ) { 15540 index = this._findNextTab( index, goingForward ); 15541 this.tabs.eq( index ).focus(); 15542 return index; 15543 }, 15544 15545 _setOption: function( key, value ) { 15546 if ( key === "active" ) { 15547 // _activate() will handle invalid values and update this.options 15548 this._activate( value ); 15549 return; 15550 } 15551 15552 if ( key === "disabled" ) { 15553 // don't use the widget factory's disabled handling 15554 this._setupDisabled( value ); 15555 return; 15556 } 15557 15558 this._super( key, value); 15559 15560 if ( key === "collapsible" ) { 15561 this.element.toggleClass( "ui-tabs-collapsible", value ); 15562 // Setting collapsible: false while collapsed; open first panel 15563 if ( !value && this.options.active === false ) { 15564 this._activate( 0 ); 15565 } 15566 } 15567 15568 if ( key === "event" ) { 15569 this._setupEvents( value ); 15570 } 15571 15572 if ( key === "heightStyle" ) { 15573 this._setupHeightStyle( value ); 15574 } 15575 }, 15576 15577 _sanitizeSelector: function( hash ) { 15578 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 15579 }, 15580 15581 refresh: function() { 15582 var options = this.options, 15583 lis = this.tablist.children( ":has(a[href])" ); 15584 15585 // get disabled tabs from class attribute from HTML 15586 // this will get converted to a boolean if needed in _refresh() 15587 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15588 return lis.index( tab ); 15589 }); 15590 15591 this._processTabs(); 15592 15593 // was collapsed or no tabs 15594 if ( options.active === false || !this.anchors.length ) { 15595 options.active = false; 15596 this.active = $(); 15597 // was active, but active tab is gone 15598 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15599 // all remaining tabs are disabled 15600 if ( this.tabs.length === options.disabled.length ) { 15601 options.active = false; 15602 this.active = $(); 15603 // activate previous tab 15604 } else { 15605 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15606 } 15607 // was active, active tab still exists 15608 } else { 15609 // make sure active index is correct 15610 options.active = this.tabs.index( this.active ); 15611 } 15612 15613 this._refresh(); 15614 }, 15615 15616 _refresh: function() { 15617 this._setupDisabled( this.options.disabled ); 15618 this._setupEvents( this.options.event ); 15619 this._setupHeightStyle( this.options.heightStyle ); 15620 15621 this.tabs.not( this.active ).attr({ 15622 "aria-selected": "false", 15623 "aria-expanded": "false", 15624 tabIndex: -1 15625 }); 15626 this.panels.not( this._getPanelForTab( this.active ) ) 15627 .hide() 15628 .attr({ 15629 "aria-hidden": "true" 15630 }); 15631 15632 // Make sure one tab is in the tab order 15633 if ( !this.active.length ) { 15634 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15635 } else { 15636 this.active 15637 .addClass( "ui-tabs-active ui-state-active" ) 15638 .attr({ 15639 "aria-selected": "true", 15640 "aria-expanded": "true", 15641 tabIndex: 0 15642 }); 15643 this._getPanelForTab( this.active ) 15644 .show() 15645 .attr({ 15646 "aria-hidden": "false" 15647 }); 15648 } 15649 }, 15650 15651 _processTabs: function() { 15652 var that = this, 15653 prevTabs = this.tabs, 15654 prevAnchors = this.anchors, 15655 prevPanels = this.panels; 15656 15657 this.tablist = this._getList() 15658 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 15659 .attr( "role", "tablist" ) 15660 15661 // Prevent users from focusing disabled tabs via click 15662 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { 15663 if ( $( this ).is( ".ui-state-disabled" ) ) { 15664 event.preventDefault(); 15665 } 15666 }) 15667 15668 // support: IE <9 15669 // Preventing the default action in mousedown doesn't prevent IE 15670 // from focusing the element, so if the anchor gets focused, blur. 15671 // We don't have to worry about focusing the previously focused 15672 // element since clicking on a non-focusable element should focus 15673 // the body anyway. 15674 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 15675 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 15676 this.blur(); 15677 } 15678 }); 15679 15680 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15681 .addClass( "ui-state-default ui-corner-top" ) 15682 .attr({ 15683 role: "tab", 15684 tabIndex: -1 15685 }); 15686 15687 this.anchors = this.tabs.map(function() { 15688 return $( "a", this )[ 0 ]; 15689 }) 15690 .addClass( "ui-tabs-anchor" ) 15691 .attr({ 15692 role: "presentation", 15693 tabIndex: -1 15694 }); 15695 15696 this.panels = $(); 15697 15698 this.anchors.each(function( i, anchor ) { 15699 var selector, panel, panelId, 15700 anchorId = $( anchor ).uniqueId().attr( "id" ), 15701 tab = $( anchor ).closest( "li" ), 15702 originalAriaControls = tab.attr( "aria-controls" ); 15703 15704 // inline tab 15705 if ( that._isLocal( anchor ) ) { 15706 selector = anchor.hash; 15707 panelId = selector.substring( 1 ); 15708 panel = that.element.find( that._sanitizeSelector( selector ) ); 15709 // remote tab 15710 } else { 15711 // If the tab doesn't already have aria-controls, 15712 // generate an id by using a throw-away element 15713 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15714 selector = "#" + panelId; 15715 panel = that.element.find( selector ); 15716 if ( !panel.length ) { 15717 panel = that._createPanel( panelId ); 15718 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15719 } 15720 panel.attr( "aria-live", "polite" ); 15721 } 15722 15723 if ( panel.length) { 15724 that.panels = that.panels.add( panel ); 15725 } 15726 if ( originalAriaControls ) { 15727 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15728 } 15729 tab.attr({ 15730 "aria-controls": panelId, 15731 "aria-labelledby": anchorId 15732 }); 15733 panel.attr( "aria-labelledby", anchorId ); 15734 }); 15735 15736 this.panels 15737 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15738 .attr( "role", "tabpanel" ); 15739 15740 // Avoid memory leaks (#10056) 15741 if ( prevTabs ) { 15742 this._off( prevTabs.not( this.tabs ) ); 15743 this._off( prevAnchors.not( this.anchors ) ); 15744 this._off( prevPanels.not( this.panels ) ); 15745 } 15746 }, 15747 15748 // allow overriding how to find the list for rare usage scenarios (#7715) 15749 _getList: function() { 15750 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 15751 }, 15752 15753 _createPanel: function( id ) { 15754 return $( "<div>" ) 15755 .attr( "id", id ) 15756 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15757 .data( "ui-tabs-destroy", true ); 15758 }, 15759 15760 _setupDisabled: function( disabled ) { 15761 if ( $.isArray( disabled ) ) { 15762 if ( !disabled.length ) { 15763 disabled = false; 15764 } else if ( disabled.length === this.anchors.length ) { 15765 disabled = true; 15766 } 15767 } 15768 15769 // disable tabs 15770 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 15771 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15772 $( li ) 15773 .addClass( "ui-state-disabled" ) 15774 .attr( "aria-disabled", "true" ); 15775 } else { 15776 $( li ) 15777 .removeClass( "ui-state-disabled" ) 15778 .removeAttr( "aria-disabled" ); 15779 } 15780 } 15781 15782 this.options.disabled = disabled; 15783 }, 15784 15785 _setupEvents: function( event ) { 15786 var events = {}; 15787 if ( event ) { 15788 $.each( event.split(" "), function( index, eventName ) { 15789 events[ eventName ] = "_eventHandler"; 15790 }); 15791 } 15792 15793 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15794 // Always prevent the default action, even when disabled 15795 this._on( true, this.anchors, { 15796 click: function( event ) { 15797 event.preventDefault(); 15798 } 15799 }); 15800 this._on( this.anchors, events ); 15801 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15802 this._on( this.panels, { keydown: "_panelKeydown" } ); 15803 15804 this._focusable( this.tabs ); 15805 this._hoverable( this.tabs ); 15806 }, 15807 15808 _setupHeightStyle: function( heightStyle ) { 15809 var maxHeight, 15810 parent = this.element.parent(); 15811 15812 if ( heightStyle === "fill" ) { 15813 maxHeight = parent.height(); 15814 maxHeight -= this.element.outerHeight() - this.element.height(); 15815 15816 this.element.siblings( ":visible" ).each(function() { 15817 var elem = $( this ), 15818 position = elem.css( "position" ); 15819 15820 if ( position === "absolute" || position === "fixed" ) { 15821 return; 15822 } 15823 maxHeight -= elem.outerHeight( true ); 15824 }); 15825 15826 this.element.children().not( this.panels ).each(function() { 15827 maxHeight -= $( this ).outerHeight( true ); 15828 }); 15829 15830 this.panels.each(function() { 15831 $( this ).height( Math.max( 0, maxHeight - 15832 $( this ).innerHeight() + $( this ).height() ) ); 15833 }) 15834 .css( "overflow", "auto" ); 15835 } else if ( heightStyle === "auto" ) { 15836 maxHeight = 0; 15837 this.panels.each(function() { 15838 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15839 }).height( maxHeight ); 15840 } 15841 }, 15842 15843 _eventHandler: function( event ) { 15844 var options = this.options, 15845 active = this.active, 15846 anchor = $( event.currentTarget ), 15847 tab = anchor.closest( "li" ), 15848 clickedIsActive = tab[ 0 ] === active[ 0 ], 15849 collapsing = clickedIsActive && options.collapsible, 15850 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15851 toHide = !active.length ? $() : this._getPanelForTab( active ), 15852 eventData = { 15853 oldTab: active, 15854 oldPanel: toHide, 15855 newTab: collapsing ? $() : tab, 15856 newPanel: toShow 15857 }; 15858 15859 event.preventDefault(); 15860 15861 if ( tab.hasClass( "ui-state-disabled" ) || 15862 // tab is already loading 15863 tab.hasClass( "ui-tabs-loading" ) || 15864 // can't switch durning an animation 15865 this.running || 15866 // click on active header, but not collapsible 15867 ( clickedIsActive && !options.collapsible ) || 15868 // allow canceling activation 15869 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15870 return; 15871 } 15872 15873 options.active = collapsing ? false : this.tabs.index( tab ); 15874 15875 this.active = clickedIsActive ? $() : tab; 15876 if ( this.xhr ) { 15877 this.xhr.abort(); 15878 } 15879 15880 if ( !toHide.length && !toShow.length ) { 15881 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15882 } 15883 15884 if ( toShow.length ) { 15885 this.load( this.tabs.index( tab ), event ); 15886 } 15887 this._toggle( event, eventData ); 15888 }, 15889 15890 // handles show/hide for selecting tabs 15891 _toggle: function( event, eventData ) { 15892 var that = this, 15893 toShow = eventData.newPanel, 15894 toHide = eventData.oldPanel; 15895 15896 this.running = true; 15897 15898 function complete() { 15899 that.running = false; 15900 that._trigger( "activate", event, eventData ); 15901 } 15902 15903 function show() { 15904 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 15905 15906 if ( toShow.length && that.options.show ) { 15907 that._show( toShow, that.options.show, complete ); 15908 } else { 15909 toShow.show(); 15910 complete(); 15911 } 15912 } 15913 15914 // start out by hiding, then showing, then completing 15915 if ( toHide.length && this.options.hide ) { 15916 this._hide( toHide, this.options.hide, function() { 15917 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 15918 show(); 15919 }); 15920 } else { 15921 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 15922 toHide.hide(); 15923 show(); 15924 } 15925 15926 toHide.attr( "aria-hidden", "true" ); 15927 eventData.oldTab.attr({ 15928 "aria-selected": "false", 15929 "aria-expanded": "false" 15930 }); 15931 // If we're switching tabs, remove the old tab from the tab order. 15932 // If we're opening from collapsed state, remove the previous tab from the tab order. 15933 // If we're collapsing, then keep the collapsing tab in the tab order. 15934 if ( toShow.length && toHide.length ) { 15935 eventData.oldTab.attr( "tabIndex", -1 ); 15936 } else if ( toShow.length ) { 15937 this.tabs.filter(function() { 15938 return $( this ).attr( "tabIndex" ) === 0; 15939 }) 15940 .attr( "tabIndex", -1 ); 15941 } 15942 15943 toShow.attr( "aria-hidden", "false" ); 15944 eventData.newTab.attr({ 15945 "aria-selected": "true", 15946 "aria-expanded": "true", 15947 tabIndex: 0 15948 }); 15949 }, 15950 15951 _activate: function( index ) { 15952 var anchor, 15953 active = this._findActive( index ); 15954 15955 // trying to activate the already active panel 15956 if ( active[ 0 ] === this.active[ 0 ] ) { 15957 return; 15958 } 15959 15960 // trying to collapse, simulate a click on the current active header 15961 if ( !active.length ) { 15962 active = this.active; 15963 } 15964 15965 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15966 this._eventHandler({ 15967 target: anchor, 15968 currentTarget: anchor, 15969 preventDefault: $.noop 15970 }); 15971 }, 15972 15973 _findActive: function( index ) { 15974 return index === false ? $() : this.tabs.eq( index ); 15975 }, 15976 15977 _getIndex: function( index ) { 15978 // meta-function to give users option to provide a href string instead of a numerical index. 15979 if ( typeof index === "string" ) { 15980 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 15981 } 15982 15983 return index; 15984 }, 15985 15986 _destroy: function() { 15987 if ( this.xhr ) { 15988 this.xhr.abort(); 15989 } 15990 15991 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 15992 15993 this.tablist 15994 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 15995 .removeAttr( "role" ); 15996 15997 this.anchors 15998 .removeClass( "ui-tabs-anchor" ) 15999 .removeAttr( "role" ) 16000 .removeAttr( "tabIndex" ) 16001 .removeUniqueId(); 16002 16003 this.tablist.unbind( this.eventNamespace ); 16004 16005 this.tabs.add( this.panels ).each(function() { 16006 if ( $.data( this, "ui-tabs-destroy" ) ) { 16007 $( this ).remove(); 16008 } else { 16009 $( this ) 16010 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 16011 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 16012 .removeAttr( "tabIndex" ) 16013 .removeAttr( "aria-live" ) 16014 .removeAttr( "aria-busy" ) 16015 .removeAttr( "aria-selected" ) 16016 .removeAttr( "aria-labelledby" ) 16017 .removeAttr( "aria-hidden" ) 16018 .removeAttr( "aria-expanded" ) 16019 .removeAttr( "role" ); 16020 } 16021 }); 16022 16023 this.tabs.each(function() { 16024 var li = $( this ), 16025 prev = li.data( "ui-tabs-aria-controls" ); 16026 if ( prev ) { 16027 li 16028 .attr( "aria-controls", prev ) 16029 .removeData( "ui-tabs-aria-controls" ); 16030 } else { 16031 li.removeAttr( "aria-controls" ); 16032 } 16033 }); 16034 16035 this.panels.show(); 16036 16037 if ( this.options.heightStyle !== "content" ) { 16038 this.panels.css( "height", "" ); 16039 } 16040 }, 16041 16042 enable: function( index ) { 16043 var disabled = this.options.disabled; 16044 if ( disabled === false ) { 16045 return; 16046 } 16047 16048 if ( index === undefined ) { 16049 disabled = false; 16050 } else { 16051 index = this._getIndex( index ); 16052 if ( $.isArray( disabled ) ) { 16053 disabled = $.map( disabled, function( num ) { 16054 return num !== index ? num : null; 16055 }); 16056 } else { 16057 disabled = $.map( this.tabs, function( li, num ) { 16058 return num !== index ? num : null; 16059 }); 16060 } 16061 } 16062 this._setupDisabled( disabled ); 16063 }, 16064 16065 disable: function( index ) { 16066 var disabled = this.options.disabled; 16067 if ( disabled === true ) { 16068 return; 16069 } 16070 16071 if ( index === undefined ) { 16072 disabled = true; 16073 } else { 16074 index = this._getIndex( index ); 16075 if ( $.inArray( index, disabled ) !== -1 ) { 16076 return; 16077 } 16078 if ( $.isArray( disabled ) ) { 16079 disabled = $.merge( [ index ], disabled ).sort(); 16080 } else { 16081 disabled = [ index ]; 16082 } 16083 } 16084 this._setupDisabled( disabled ); 16085 }, 16086 16087 load: function( index, event ) { 16088 index = this._getIndex( index ); 16089 var that = this, 16090 tab = this.tabs.eq( index ), 16091 anchor = tab.find( ".ui-tabs-anchor" ), 16092 panel = this._getPanelForTab( tab ), 16093 eventData = { 16094 tab: tab, 16095 panel: panel 16096 }, 16097 complete = function( jqXHR, status ) { 16098 if ( status === "abort" ) { 16099 that.panels.stop( false, true ); 16100 } 16101 16102 tab.removeClass( "ui-tabs-loading" ); 16103 panel.removeAttr( "aria-busy" ); 16104 16105 if ( jqXHR === that.xhr ) { 16106 delete that.xhr; 16107 } 16108 }; 16109 16110 // not remote 16111 if ( this._isLocal( anchor[ 0 ] ) ) { 16112 return; 16113 } 16114 16115 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 16116 16117 // support: jQuery <1.8 16118 // jQuery <1.8 returns false if the request is canceled in beforeSend, 16119 // but as of 1.8, $.ajax() always returns a jqXHR object. 16120 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 16121 tab.addClass( "ui-tabs-loading" ); 16122 panel.attr( "aria-busy", "true" ); 16123 16124 this.xhr 16125 .done(function( response, status, jqXHR ) { 16126 // support: jQuery <1.8 16127 // http://bugs.jquery.com/ticket/11778 16128 setTimeout(function() { 16129 panel.html( response ); 16130 that._trigger( "load", event, eventData ); 16131 16132 complete( jqXHR, status ); 16133 }, 1 ); 16134 }) 16135 .fail(function( jqXHR, status ) { 16136 // support: jQuery <1.8 16137 // http://bugs.jquery.com/ticket/11778 16138 setTimeout(function() { 16139 complete( jqXHR, status ); 16140 }, 1 ); 16141 }); 16142 } 16143 }, 16144 16145 _ajaxSettings: function( anchor, event, eventData ) { 16146 var that = this; 16147 return { 16148 url: anchor.attr( "href" ), 16149 beforeSend: function( jqXHR, settings ) { 16150 return that._trigger( "beforeLoad", event, 16151 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 16152 } 16153 }; 16154 }, 16155 16156 _getPanelForTab: function( tab ) { 16157 var id = $( tab ).attr( "aria-controls" ); 16158 return this.element.find( this._sanitizeSelector( "#" + id ) ); 16159 } 16160}); 16161 16162 16163/*! 16164 * jQuery UI Tooltip 1.11.4 16165 * http://jqueryui.com 16166 * 16167 * Copyright jQuery Foundation and other contributors 16168 * Released under the MIT license. 16169 * http://jquery.org/license 16170 * 16171 * http://api.jqueryui.com/tooltip/ 16172 */ 16173 16174 16175var tooltip = $.widget( "ui.tooltip", { 16176 version: "1.11.4", 16177 options: { 16178 content: function() { 16179 // support: IE<9, Opera in jQuery <1.7 16180 // .text() can't accept undefined, so coerce to a string 16181 var title = $( this ).attr( "title" ) || ""; 16182 // Escape title, since we're going from an attribute to raw HTML 16183 return $( "<a>" ).text( title ).html(); 16184 }, 16185 hide: true, 16186 // Disabled elements have inconsistent behavior across browsers (#8661) 16187 items: "[title]:not([disabled])", 16188 position: { 16189 my: "left top+15", 16190 at: "left bottom", 16191 collision: "flipfit flip" 16192 }, 16193 show: true, 16194 tooltipClass: null, 16195 track: false, 16196 16197 // callbacks 16198 close: null, 16199 open: null 16200 }, 16201 16202 _addDescribedBy: function( elem, id ) { 16203 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 16204 describedby.push( id ); 16205 elem 16206 .data( "ui-tooltip-id", id ) 16207 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 16208 }, 16209 16210 _removeDescribedBy: function( elem ) { 16211 var id = elem.data( "ui-tooltip-id" ), 16212 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 16213 index = $.inArray( id, describedby ); 16214 16215 if ( index !== -1 ) { 16216 describedby.splice( index, 1 ); 16217 } 16218 16219 elem.removeData( "ui-tooltip-id" ); 16220 describedby = $.trim( describedby.join( " " ) ); 16221 if ( describedby ) { 16222 elem.attr( "aria-describedby", describedby ); 16223 } else { 16224 elem.removeAttr( "aria-describedby" ); 16225 } 16226 }, 16227 16228 _create: function() { 16229 this._on({ 16230 mouseover: "open", 16231 focusin: "open" 16232 }); 16233 16234 // IDs of generated tooltips, needed for destroy 16235 this.tooltips = {}; 16236 16237 // IDs of parent tooltips where we removed the title attribute 16238 this.parents = {}; 16239 16240 if ( this.options.disabled ) { 16241 this._disable(); 16242 } 16243 16244 // Append the aria-live region so tooltips announce correctly 16245 this.liveRegion = $( "<div>" ) 16246 .attr({ 16247 role: "log", 16248 "aria-live": "assertive", 16249 "aria-relevant": "additions" 16250 }) 16251 .addClass( "ui-helper-hidden-accessible" ) 16252 .appendTo( this.document[ 0 ].body ); 16253 }, 16254 16255 _setOption: function( key, value ) { 16256 var that = this; 16257 16258 if ( key === "disabled" ) { 16259 this[ value ? "_disable" : "_enable" ](); 16260 this.options[ key ] = value; 16261 // disable element style changes 16262 return; 16263 } 16264 16265 this._super( key, value ); 16266 16267 if ( key === "content" ) { 16268 $.each( this.tooltips, function( id, tooltipData ) { 16269 that._updateContent( tooltipData.element ); 16270 }); 16271 } 16272 }, 16273 16274 _disable: function() { 16275 var that = this; 16276 16277 // close open tooltips 16278 $.each( this.tooltips, function( id, tooltipData ) { 16279 var event = $.Event( "blur" ); 16280 event.target = event.currentTarget = tooltipData.element[ 0 ]; 16281 that.close( event, true ); 16282 }); 16283 16284 // remove title attributes to prevent native tooltips 16285 this.element.find( this.options.items ).addBack().each(function() { 16286 var element = $( this ); 16287 if ( element.is( "[title]" ) ) { 16288 element 16289 .data( "ui-tooltip-title", element.attr( "title" ) ) 16290 .removeAttr( "title" ); 16291 } 16292 }); 16293 }, 16294 16295 _enable: function() { 16296 // restore title attributes 16297 this.element.find( this.options.items ).addBack().each(function() { 16298 var element = $( this ); 16299 if ( element.data( "ui-tooltip-title" ) ) { 16300 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16301 } 16302 }); 16303 }, 16304 16305 open: function( event ) { 16306 var that = this, 16307 target = $( event ? event.target : this.element ) 16308 // we need closest here due to mouseover bubbling, 16309 // but always pointing at the same event target 16310 .closest( this.options.items ); 16311 16312 // No element to show a tooltip for or the tooltip is already open 16313 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 16314 return; 16315 } 16316 16317 if ( target.attr( "title" ) ) { 16318 target.data( "ui-tooltip-title", target.attr( "title" ) ); 16319 } 16320 16321 target.data( "ui-tooltip-open", true ); 16322 16323 // kill parent tooltips, custom or native, for hover 16324 if ( event && event.type === "mouseover" ) { 16325 target.parents().each(function() { 16326 var parent = $( this ), 16327 blurEvent; 16328 if ( parent.data( "ui-tooltip-open" ) ) { 16329 blurEvent = $.Event( "blur" ); 16330 blurEvent.target = blurEvent.currentTarget = this; 16331 that.close( blurEvent, true ); 16332 } 16333 if ( parent.attr( "title" ) ) { 16334 parent.uniqueId(); 16335 that.parents[ this.id ] = { 16336 element: this, 16337 title: parent.attr( "title" ) 16338 }; 16339 parent.attr( "title", "" ); 16340 } 16341 }); 16342 } 16343 16344 this._registerCloseHandlers( event, target ); 16345 this._updateContent( target, event ); 16346 }, 16347 16348 _updateContent: function( target, event ) { 16349 var content, 16350 contentOption = this.options.content, 16351 that = this, 16352 eventType = event ? event.type : null; 16353 16354 if ( typeof contentOption === "string" ) { 16355 return this._open( event, target, contentOption ); 16356 } 16357 16358 content = contentOption.call( target[0], function( response ) { 16359 16360 // IE may instantly serve a cached response for ajax requests 16361 // delay this call to _open so the other call to _open runs first 16362 that._delay(function() { 16363 16364 // Ignore async response if tooltip was closed already 16365 if ( !target.data( "ui-tooltip-open" ) ) { 16366 return; 16367 } 16368 16369 // jQuery creates a special event for focusin when it doesn't 16370 // exist natively. To improve performance, the native event 16371 // object is reused and the type is changed. Therefore, we can't 16372 // rely on the type being correct after the event finished 16373 // bubbling, so we set it back to the previous value. (#8740) 16374 if ( event ) { 16375 event.type = eventType; 16376 } 16377 this._open( event, target, response ); 16378 }); 16379 }); 16380 if ( content ) { 16381 this._open( event, target, content ); 16382 } 16383 }, 16384 16385 _open: function( event, target, content ) { 16386 var tooltipData, tooltip, delayedShow, a11yContent, 16387 positionOption = $.extend( {}, this.options.position ); 16388 16389 if ( !content ) { 16390 return; 16391 } 16392 16393 // Content can be updated multiple times. If the tooltip already 16394 // exists, then just update the content and bail. 16395 tooltipData = this._find( target ); 16396 if ( tooltipData ) { 16397 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 16398 return; 16399 } 16400 16401 // if we have a title, clear it to prevent the native tooltip 16402 // we have to check first to avoid defining a title if none exists 16403 // (we don't want to cause an element to start matching [title]) 16404 // 16405 // We use removeAttr only for key events, to allow IE to export the correct 16406 // accessible attributes. For mouse events, set to empty string to avoid 16407 // native tooltip showing up (happens only when removing inside mouseover). 16408 if ( target.is( "[title]" ) ) { 16409 if ( event && event.type === "mouseover" ) { 16410 target.attr( "title", "" ); 16411 } else { 16412 target.removeAttr( "title" ); 16413 } 16414 } 16415 16416 tooltipData = this._tooltip( target ); 16417 tooltip = tooltipData.tooltip; 16418 this._addDescribedBy( target, tooltip.attr( "id" ) ); 16419 tooltip.find( ".ui-tooltip-content" ).html( content ); 16420 16421 // Support: Voiceover on OS X, JAWS on IE <= 9 16422 // JAWS announces deletions even when aria-relevant="additions" 16423 // Voiceover will sometimes re-read the entire log region's contents from the beginning 16424 this.liveRegion.children().hide(); 16425 if ( content.clone ) { 16426 a11yContent = content.clone(); 16427 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 16428 } else { 16429 a11yContent = content; 16430 } 16431 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion ); 16432 16433 function position( event ) { 16434 positionOption.of = event; 16435 if ( tooltip.is( ":hidden" ) ) { 16436 return; 16437 } 16438 tooltip.position( positionOption ); 16439 } 16440 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 16441 this._on( this.document, { 16442 mousemove: position 16443 }); 16444 // trigger once to override element-relative positioning 16445 position( event ); 16446 } else { 16447 tooltip.position( $.extend({ 16448 of: target 16449 }, this.options.position ) ); 16450 } 16451 16452 tooltip.hide(); 16453 16454 this._show( tooltip, this.options.show ); 16455 // Handle tracking tooltips that are shown with a delay (#8644). As soon 16456 // as the tooltip is visible, position the tooltip using the most recent 16457 // event. 16458 if ( this.options.show && this.options.show.delay ) { 16459 delayedShow = this.delayedShow = setInterval(function() { 16460 if ( tooltip.is( ":visible" ) ) { 16461 position( positionOption.of ); 16462 clearInterval( delayedShow ); 16463 } 16464 }, $.fx.interval ); 16465 } 16466 16467 this._trigger( "open", event, { tooltip: tooltip } ); 16468 }, 16469 16470 _registerCloseHandlers: function( event, target ) { 16471 var events = { 16472 keyup: function( event ) { 16473 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 16474 var fakeEvent = $.Event(event); 16475 fakeEvent.currentTarget = target[0]; 16476 this.close( fakeEvent, true ); 16477 } 16478 } 16479 }; 16480 16481 // Only bind remove handler for delegated targets. Non-delegated 16482 // tooltips will handle this in destroy. 16483 if ( target[ 0 ] !== this.element[ 0 ] ) { 16484 events.remove = function() { 16485 this._removeTooltip( this._find( target ).tooltip ); 16486 }; 16487 } 16488 16489 if ( !event || event.type === "mouseover" ) { 16490 events.mouseleave = "close"; 16491 } 16492 if ( !event || event.type === "focusin" ) { 16493 events.focusout = "close"; 16494 } 16495 this._on( true, target, events ); 16496 }, 16497 16498 close: function( event ) { 16499 var tooltip, 16500 that = this, 16501 target = $( event ? event.currentTarget : this.element ), 16502 tooltipData = this._find( target ); 16503 16504 // The tooltip may already be closed 16505 if ( !tooltipData ) { 16506 16507 // We set ui-tooltip-open immediately upon open (in open()), but only set the 16508 // additional data once there's actually content to show (in _open()). So even if the 16509 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 16510 // the period between open() and _open(). 16511 target.removeData( "ui-tooltip-open" ); 16512 return; 16513 } 16514 16515 tooltip = tooltipData.tooltip; 16516 16517 // disabling closes the tooltip, so we need to track when we're closing 16518 // to avoid an infinite loop in case the tooltip becomes disabled on close 16519 if ( tooltipData.closing ) { 16520 return; 16521 } 16522 16523 // Clear the interval for delayed tracking tooltips 16524 clearInterval( this.delayedShow ); 16525 16526 // only set title if we had one before (see comment in _open()) 16527 // If the title attribute has changed since open(), don't restore 16528 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16529 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16530 } 16531 16532 this._removeDescribedBy( target ); 16533 16534 tooltipData.hiding = true; 16535 tooltip.stop( true ); 16536 this._hide( tooltip, this.options.hide, function() { 16537 that._removeTooltip( $( this ) ); 16538 }); 16539 16540 target.removeData( "ui-tooltip-open" ); 16541 this._off( target, "mouseleave focusout keyup" ); 16542 16543 // Remove 'remove' binding only on delegated targets 16544 if ( target[ 0 ] !== this.element[ 0 ] ) { 16545 this._off( target, "remove" ); 16546 } 16547 this._off( this.document, "mousemove" ); 16548 16549 if ( event && event.type === "mouseleave" ) { 16550 $.each( this.parents, function( id, parent ) { 16551 $( parent.element ).attr( "title", parent.title ); 16552 delete that.parents[ id ]; 16553 }); 16554 } 16555 16556 tooltipData.closing = true; 16557 this._trigger( "close", event, { tooltip: tooltip } ); 16558 if ( !tooltipData.hiding ) { 16559 tooltipData.closing = false; 16560 } 16561 }, 16562 16563 _tooltip: function( element ) { 16564 var tooltip = $( "<div>" ) 16565 .attr( "role", "tooltip" ) 16566 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 16567 ( this.options.tooltipClass || "" ) ), 16568 id = tooltip.uniqueId().attr( "id" ); 16569 16570 $( "<div>" ) 16571 .addClass( "ui-tooltip-content" ) 16572 .appendTo( tooltip ); 16573 16574 tooltip.appendTo( this.document[0].body ); 16575 16576 return this.tooltips[ id ] = { 16577 element: element, 16578 tooltip: tooltip 16579 }; 16580 }, 16581 16582 _find: function( target ) { 16583 var id = target.data( "ui-tooltip-id" ); 16584 return id ? this.tooltips[ id ] : null; 16585 }, 16586 16587 _removeTooltip: function( tooltip ) { 16588 tooltip.remove(); 16589 delete this.tooltips[ tooltip.attr( "id" ) ]; 16590 }, 16591 16592 _destroy: function() { 16593 var that = this; 16594 16595 // close open tooltips 16596 $.each( this.tooltips, function( id, tooltipData ) { 16597 // Delegate to close method to handle common cleanup 16598 var event = $.Event( "blur" ), 16599 element = tooltipData.element; 16600 event.target = event.currentTarget = element[ 0 ]; 16601 that.close( event, true ); 16602 16603 // Remove immediately; destroying an open tooltip doesn't use the 16604 // hide animation 16605 $( "#" + id ).remove(); 16606 16607 // Restore the title 16608 if ( element.data( "ui-tooltip-title" ) ) { 16609 // If the title attribute has changed since open(), don't restore 16610 if ( !element.attr( "title" ) ) { 16611 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16612 } 16613 element.removeData( "ui-tooltip-title" ); 16614 } 16615 }); 16616 this.liveRegion.remove(); 16617 } 16618}); 16619 16620 16621 16622}));
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.