vendor: 33,555 bytes, lines 1-1203
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 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, 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 ] ) ?
vendor: 4,791 bytes, lines 1204-1359
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
vendor: 7,320 bytes, lines 1360-1592
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",
vendor: 4,428 bytes, lines 1593-1769
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, 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
vendor: 17,411 bytes, lines 1770-2422
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: 4,109 bytes, lines 2423-2574
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() {
vendor: 11,138 bytes, lines 2575-2991
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 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 }, 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;
vendor: 4,086 bytes, lines 2992-3142
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)
vendor: 8,850 bytes, lines 3143-3491
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;
vendor: 5,528 bytes, lines 3492-3676
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,
vendor: 6,515 bytes, lines 3677-3847
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: "Done", // 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: ["January","February","March","April","May","June", 3833 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 3834 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 3835 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 3836 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 3837 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 3838 weekHeader: "Wk", // Column header for week of the year 3839 dateFormat: "mm/dd/yy", // See format options on parseDate 3840 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 3841 isRTL: false, // True if right-to-left language, false if left-to-right 3842 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 3843 yearSuffix: "" // Additional text to append to the year in the month headers 3844 }; 3845 this._defaults = { // Global defaults for all the date picker instances 3846 showOn: "focus", // "focus" for popup on focus, 3847 // "button" for trigger button, or "both" for either
vendor: 73,430 bytes, lines 3848-5832
3848 showAnim: "fadeIn", // Name of jQuery animation for popup 3849 showOptions: {}, // Options for enhanced animations 3850 defaultDate: null, // Used when field is blank: actual date, 3851 // +/-number for offset from today, null for today 3852 appendText: "", // Display text following the input box, e.g. showing the format 3853 buttonText: "...", // Text for trigger button 3854 buttonImage: "", // URL for trigger button image 3855 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 3856 hideIfNoPrevNext: false, // True to hide next/previous month links 3857 // if not applicable, false to just disable them 3858 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 3859 gotoCurrent: false, // True if today link goes back to current selection instead 3860 changeMonth: false, // True if month can be selected directly, false if only prev/next 3861 changeYear: false, // True if year can be selected directly, false if only prev/next 3862 yearRange: "c-10:c+10", // Range of years to display in drop-down, 3863 // either relative to today's year (-nn:+nn), relative to currently displayed year 3864 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 3865 showOtherMonths: false, // True to show dates in other months, false to leave blank 3866 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 3867 showWeek: false, // True to show week of the year, false to not show it 3868 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 3869 // takes a Date and returns the number of the week for it 3870 shortYearCutoff: "+10", // Short year values < this are in the current century, 3871 // > this are in the previous century, 3872 // string value starting with "+" for current year + value 3873 minDate: null, // The earliest selectable date, or null for no limit 3874 maxDate: null, // The latest selectable date, or null for no limit 3875 duration: "fast", // Duration of display/closure 3876 beforeShowDay: null, // Function that takes a date and returns an array with 3877 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 3878 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 3879 beforeShow: null, // Function that takes an input field and 3880 // returns a set of custom settings for the date picker 3881 onSelect: null, // Define a callback function when a date is selected 3882 onChangeMonthYear: null, // Define a callback function when the month or year is changed 3883 onClose: null, // Define a callback function when the datepicker is closed 3884 numberOfMonths: 1, // Number of months to show at a time 3885 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 3886 stepMonths: 1, // Number of months to step back/forward 3887 stepBigMonths: 12, // Number of months to step back/forward for the big links 3888 altField: "", // Selector for an alternate field to store selected dates into 3889 altFormat: "", // The date format to use for the alternate field 3890 constrainInput: true, // The input is constrained by the current date format 3891 showButtonPanel: false, // True to show button panel, false to not show it 3892 autoSize: false, // True to size the input for the date format, false to leave as is 3893 disabled: false // The initial disabled state 3894 }; 3895 $.extend(this._defaults, this.regional[""]); 3896 this.regional.en = $.extend( true, {}, this.regional[ "" ]); 3897 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 3898 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 3899} 3900 3901$.extend(Datepicker.prototype, { 3902 /* Class name added to elements to indicate already configured with a date picker. */ 3903 markerClassName: "hasDatepicker", 3904 3905 //Keep track of the maximum number of rows displayed (see #7043) 3906 maxRows: 4, 3907 3908 // TODO rename to "widget" when switching to widget factory 3909 _widgetDatepicker: function() { 3910 return this.dpDiv; 3911 }, 3912 3913 /* Override the default settings for all instances of the date picker. 3914 * @param settings object - the new settings to use as defaults (anonymous object) 3915 * @return the manager object 3916 */ 3917 setDefaults: function(settings) { 3918 datepicker_extendRemove(this._defaults, settings || {}); 3919 return this; 3920 }, 3921 3922 /* Attach the date picker to a jQuery selection. 3923 * @param target element - the target input field or division or span 3924 * @param settings object - the new settings to use for this date picker instance (anonymous) 3925 */ 3926 _attachDatepicker: function(target, settings) { 3927 var nodeName, inline, inst; 3928 nodeName = target.nodeName.toLowerCase(); 3929 inline = (nodeName === "div" || nodeName === "span"); 3930 if (!target.id) { 3931 this.uuid += 1; 3932 target.id = "dp" + this.uuid; 3933 } 3934 inst = this._newInst($(target), inline); 3935 inst.settings = $.extend({}, settings || {}); 3936 if (nodeName === "input") { 3937 this._connectDatepicker(target, inst); 3938 } else if (inline) { 3939 this._inlineDatepicker(target, inst); 3940 } 3941 }, 3942 3943 /* Create a new instance object. */ 3944 _newInst: function(target, inline) { 3945 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 3946 return {id: id, input: target, // associated target 3947 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 3948 drawMonth: 0, drawYear: 0, // month being drawn 3949 inline: inline, // is datepicker inline or not 3950 dpDiv: (!inline ? this.dpDiv : // presentation div 3951 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 3952 }, 3953 3954 /* Attach the date picker to an input field. */ 3955 _connectDatepicker: function(target, inst) { 3956 var input = $(target); 3957 inst.append = $([]); 3958 inst.trigger = $([]); 3959 if (input.hasClass(this.markerClassName)) { 3960 return; 3961 } 3962 this._attachments(input, inst); 3963 input.addClass(this.markerClassName).keydown(this._doKeyDown). 3964 keypress(this._doKeyPress).keyup(this._doKeyUp); 3965 this._autoSize(inst); 3966 $.data(target, "datepicker", inst); 3967 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 3968 if( inst.settings.disabled ) { 3969 this._disableDatepicker( target ); 3970 } 3971 }, 3972 3973 /* Make attachments based on settings. */ 3974 _attachments: function(input, inst) { 3975 var showOn, buttonText, buttonImage, 3976 appendText = this._get(inst, "appendText"), 3977 isRTL = this._get(inst, "isRTL"); 3978 3979 if (inst.append) { 3980 inst.append.remove(); 3981 } 3982 if (appendText) { 3983 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 3984 input[isRTL ? "before" : "after"](inst.append); 3985 } 3986 3987 input.unbind("focus", this._showDatepicker); 3988 3989 if (inst.trigger) { 3990 inst.trigger.remove(); 3991 } 3992 3993 showOn = this._get(inst, "showOn"); 3994 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 3995 input.focus(this._showDatepicker); 3996 } 3997 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 3998 buttonText = this._get(inst, "buttonText"); 3999 buttonImage = this._get(inst, "buttonImage"); 4000 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 4001 $("<img/>").addClass(this._triggerClass). 4002 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 4003 $("<button type='button'></button>").addClass(this._triggerClass). 4004 html(!buttonImage ? buttonText : $("<img/>").attr( 4005 { src:buttonImage, alt:buttonText, title:buttonText }))); 4006 input[isRTL ? "before" : "after"](inst.trigger); 4007 inst.trigger.click(function() { 4008 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 4009 $.datepicker._hideDatepicker(); 4010 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 4011 $.datepicker._hideDatepicker(); 4012 $.datepicker._showDatepicker(input[0]); 4013 } else { 4014 $.datepicker._showDatepicker(input[0]); 4015 } 4016 return false; 4017 }); 4018 } 4019 }, 4020 4021 /* Apply the maximum length for the date format. */ 4022 _autoSize: function(inst) { 4023 if (this._get(inst, "autoSize") && !inst.inline) { 4024 var findMax, max, maxI, i, 4025 date = new Date(2009, 12 - 1, 20), // Ensure double digits 4026 dateFormat = this._get(inst, "dateFormat"); 4027 4028 if (dateFormat.match(/[DM]/)) { 4029 findMax = function(names) { 4030 max = 0; 4031 maxI = 0; 4032 for (i = 0; i < names.length; i++) { 4033 if (names[i].length > max) { 4034 max = names[i].length; 4035 maxI = i; 4036 } 4037 } 4038 return maxI; 4039 }; 4040 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 4041 "monthNames" : "monthNamesShort")))); 4042 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 4043 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 4044 } 4045 inst.input.attr("size", this._formatDate(inst, date).length); 4046 } 4047 }, 4048 4049 /* Attach an inline date picker to a div. */ 4050 _inlineDatepicker: function(target, inst) { 4051 var divSpan = $(target); 4052 if (divSpan.hasClass(this.markerClassName)) { 4053 return; 4054 } 4055 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 4056 $.data(target, "datepicker", inst); 4057 this._setDate(inst, this._getDefaultDate(inst), true); 4058 this._updateDatepicker(inst); 4059 this._updateAlternate(inst); 4060 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 4061 if( inst.settings.disabled ) { 4062 this._disableDatepicker( target ); 4063 } 4064 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 4065 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 4066 inst.dpDiv.css( "display", "block" ); 4067 }, 4068 4069 /* Pop-up the date picker in a "dialog" box. 4070 * @param input element - ignored 4071 * @param date string or Date - the initial date to display 4072 * @param onSelect function - the function to call when a date is selected 4073 * @param settings object - update the dialog date picker instance's settings (anonymous object) 4074 * @param pos int[2] - coordinates for the dialog's position within the screen or 4075 * event - with x/y coordinates or 4076 * leave empty for default (screen centre) 4077 * @return the manager object 4078 */ 4079 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 4080 var id, browserWidth, browserHeight, scrollX, scrollY, 4081 inst = this._dialogInst; // internal instance 4082 4083 if (!inst) { 4084 this.uuid += 1; 4085 id = "dp" + this.uuid; 4086 this._dialogInput = $("<input type='text' id='" + id + 4087 "' style='position: absolute; top: -100px; width: 0px;'/>"); 4088 this._dialogInput.keydown(this._doKeyDown); 4089 $("body").append(this._dialogInput); 4090 inst = this._dialogInst = this._newInst(this._dialogInput, false); 4091 inst.settings = {}; 4092 $.data(this._dialogInput[0], "datepicker", inst); 4093 } 4094 datepicker_extendRemove(inst.settings, settings || {}); 4095 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 4096 this._dialogInput.val(date); 4097 4098 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 4099 if (!this._pos) { 4100 browserWidth = document.documentElement.clientWidth; 4101 browserHeight = document.documentElement.clientHeight; 4102 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 4103 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 4104 this._pos = // should use actual width/height below 4105 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 4106 } 4107 4108 // move input on screen for focus, but hidden behind dialog 4109 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 4110 inst.settings.onSelect = onSelect; 4111 this._inDialog = true; 4112 this.dpDiv.addClass(this._dialogClass); 4113 this._showDatepicker(this._dialogInput[0]); 4114 if ($.blockUI) { 4115 $.blockUI(this.dpDiv); 4116 } 4117 $.data(this._dialogInput[0], "datepicker", inst); 4118 return this; 4119 }, 4120 4121 /* Detach a datepicker from its control. 4122 * @param target element - the target input field or division or span 4123 */ 4124 _destroyDatepicker: function(target) { 4125 var nodeName, 4126 $target = $(target), 4127 inst = $.data(target, "datepicker"); 4128 4129 if (!$target.hasClass(this.markerClassName)) { 4130 return; 4131 } 4132 4133 nodeName = target.nodeName.toLowerCase(); 4134 $.removeData(target, "datepicker"); 4135 if (nodeName === "input") { 4136 inst.append.remove(); 4137 inst.trigger.remove(); 4138 $target.removeClass(this.markerClassName). 4139 unbind("focus", this._showDatepicker). 4140 unbind("keydown", this._doKeyDown). 4141 unbind("keypress", this._doKeyPress). 4142 unbind("keyup", this._doKeyUp); 4143 } else if (nodeName === "div" || nodeName === "span") { 4144 $target.removeClass(this.markerClassName).empty(); 4145 } 4146 4147 if ( datepicker_instActive === inst ) { 4148 datepicker_instActive = null; 4149 } 4150 }, 4151 4152 /* Enable the date picker to a jQuery selection. 4153 * @param target element - the target input field or division or span 4154 */ 4155 _enableDatepicker: function(target) { 4156 var nodeName, inline, 4157 $target = $(target), 4158 inst = $.data(target, "datepicker"); 4159 4160 if (!$target.hasClass(this.markerClassName)) { 4161 return; 4162 } 4163 4164 nodeName = target.nodeName.toLowerCase(); 4165 if (nodeName === "input") { 4166 target.disabled = false; 4167 inst.trigger.filter("button"). 4168 each(function() { this.disabled = false; }).end(). 4169 filter("img").css({opacity: "1.0", cursor: ""}); 4170 } else if (nodeName === "div" || nodeName === "span") { 4171 inline = $target.children("." + this._inlineClass); 4172 inline.children().removeClass("ui-state-disabled"); 4173 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4174 prop("disabled", false); 4175 } 4176 this._disabledInputs = $.map(this._disabledInputs, 4177 function(value) { return (value === target ? null : value); }); // delete entry 4178 }, 4179 4180 /* Disable the date picker to a jQuery selection. 4181 * @param target element - the target input field or division or span 4182 */ 4183 _disableDatepicker: function(target) { 4184 var nodeName, inline, 4185 $target = $(target), 4186 inst = $.data(target, "datepicker"); 4187 4188 if (!$target.hasClass(this.markerClassName)) { 4189 return; 4190 } 4191 4192 nodeName = target.nodeName.toLowerCase(); 4193 if (nodeName === "input") { 4194 target.disabled = true; 4195 inst.trigger.filter("button"). 4196 each(function() { this.disabled = true; }).end(). 4197 filter("img").css({opacity: "0.5", cursor: "default"}); 4198 } else if (nodeName === "div" || nodeName === "span") { 4199 inline = $target.children("." + this._inlineClass); 4200 inline.children().addClass("ui-state-disabled"); 4201 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4202 prop("disabled", true); 4203 } 4204 this._disabledInputs = $.map(this._disabledInputs, 4205 function(value) { return (value === target ? null : value); }); // delete entry 4206 this._disabledInputs[this._disabledInputs.length] = target; 4207 }, 4208 4209 /* Is the first field in a jQuery collection disabled as a datepicker? 4210 * @param target element - the target input field or division or span 4211 * @return boolean - true if disabled, false if enabled 4212 */ 4213 _isDisabledDatepicker: function(target) { 4214 if (!target) { 4215 return false; 4216 } 4217 for (var i = 0; i < this._disabledInputs.length; i++) { 4218 if (this._disabledInputs[i] === target) { 4219 return true; 4220 } 4221 } 4222 return false; 4223 }, 4224 4225 /* Retrieve the instance data for the target control. 4226 * @param target element - the target input field or division or span 4227 * @return object - the associated instance data 4228 * @throws error if a jQuery problem getting data 4229 */ 4230 _getInst: function(target) { 4231 try { 4232 return $.data(target, "datepicker"); 4233 } 4234 catch (err) { 4235 throw "Missing instance data for this datepicker"; 4236 } 4237 }, 4238 4239 /* Update or retrieve the settings for a date picker attached to an input field or division. 4240 * @param target element - the target input field or division or span 4241 * @param name object - the new settings to update or 4242 * string - the name of the setting to change or retrieve, 4243 * when retrieving also "all" for all instance settings or 4244 * "defaults" for all global defaults 4245 * @param value any - the new value for the setting 4246 * (omit if above is an object or to retrieve a value) 4247 */ 4248 _optionDatepicker: function(target, name, value) { 4249 var settings, date, minDate, maxDate, 4250 inst = this._getInst(target); 4251 4252 if (arguments.length === 2 && typeof name === "string") { 4253 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 4254 (inst ? (name === "all" ? $.extend({}, inst.settings) : 4255 this._get(inst, name)) : null)); 4256 } 4257 4258 settings = name || {}; 4259 if (typeof name === "string") { 4260 settings = {}; 4261 settings[name] = value; 4262 } 4263 4264 if (inst) { 4265 if (this._curInst === inst) { 4266 this._hideDatepicker(); 4267 } 4268 4269 date = this._getDateDatepicker(target, true); 4270 minDate = this._getMinMaxDate(inst, "min"); 4271 maxDate = this._getMinMaxDate(inst, "max"); 4272 datepicker_extendRemove(inst.settings, settings); 4273 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 4274 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 4275 inst.settings.minDate = this._formatDate(inst, minDate); 4276 } 4277 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 4278 inst.settings.maxDate = this._formatDate(inst, maxDate); 4279 } 4280 if ( "disabled" in settings ) { 4281 if ( settings.disabled ) { 4282 this._disableDatepicker(target); 4283 } else { 4284 this._enableDatepicker(target); 4285 } 4286 } 4287 this._attachments($(target), inst); 4288 this._autoSize(inst); 4289 this._setDate(inst, date); 4290 this._updateAlternate(inst); 4291 this._updateDatepicker(inst); 4292 } 4293 }, 4294 4295 // change method deprecated 4296 _changeDatepicker: function(target, name, value) { 4297 this._optionDatepicker(target, name, value); 4298 }, 4299 4300 /* Redraw the date picker attached to an input field or division. 4301 * @param target element - the target input field or division or span 4302 */ 4303 _refreshDatepicker: function(target) { 4304 var inst = this._getInst(target); 4305 if (inst) { 4306 this._updateDatepicker(inst); 4307 } 4308 }, 4309 4310 /* Set the dates for a jQuery selection. 4311 * @param target element - the target input field or division or span 4312 * @param date Date - the new date 4313 */ 4314 _setDateDatepicker: function(target, date) { 4315 var inst = this._getInst(target); 4316 if (inst) { 4317 this._setDate(inst, date); 4318 this._updateDatepicker(inst); 4319 this._updateAlternate(inst); 4320 } 4321 }, 4322 4323 /* Get the date(s) for the first entry in a jQuery selection. 4324 * @param target element - the target input field or division or span 4325 * @param noDefault boolean - true if no default date is to be used 4326 * @return Date - the current date 4327 */ 4328 _getDateDatepicker: function(target, noDefault) { 4329 var inst = this._getInst(target); 4330 if (inst && !inst.inline) { 4331 this._setDateFromField(inst, noDefault); 4332 } 4333 return (inst ? this._getDate(inst) : null); 4334 }, 4335 4336 /* Handle keystrokes. */ 4337 _doKeyDown: function(event) { 4338 var onSelect, dateStr, sel, 4339 inst = $.datepicker._getInst(event.target), 4340 handled = true, 4341 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 4342 4343 inst._keyEvent = true; 4344 if ($.datepicker._datepickerShowing) { 4345 switch (event.keyCode) { 4346 case 9: $.datepicker._hideDatepicker(); 4347 handled = false; 4348 break; // hide on tab out 4349 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 4350 $.datepicker._currentClass + ")", inst.dpDiv); 4351 if (sel[0]) { 4352 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 4353 } 4354 4355 onSelect = $.datepicker._get(inst, "onSelect"); 4356 if (onSelect) { 4357 dateStr = $.datepicker._formatDate(inst); 4358 4359 // trigger custom callback 4360 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 4361 } else { 4362 $.datepicker._hideDatepicker(); 4363 } 4364 4365 return false; // don't submit the form 4366 case 27: $.datepicker._hideDatepicker(); 4367 break; // hide on escape 4368 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4369 -$.datepicker._get(inst, "stepBigMonths") : 4370 -$.datepicker._get(inst, "stepMonths")), "M"); 4371 break; // previous month/year on page up/+ ctrl 4372 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4373 +$.datepicker._get(inst, "stepBigMonths") : 4374 +$.datepicker._get(inst, "stepMonths")), "M"); 4375 break; // next month/year on page down/+ ctrl 4376 case 35: if (event.ctrlKey || event.metaKey) { 4377 $.datepicker._clearDate(event.target); 4378 } 4379 handled = event.ctrlKey || event.metaKey; 4380 break; // clear on ctrl or command +end 4381 case 36: if (event.ctrlKey || event.metaKey) { 4382 $.datepicker._gotoToday(event.target); 4383 } 4384 handled = event.ctrlKey || event.metaKey; 4385 break; // current on ctrl or command +home 4386 case 37: if (event.ctrlKey || event.metaKey) { 4387 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 4388 } 4389 handled = event.ctrlKey || event.metaKey; 4390 // -1 day on ctrl or command +left 4391 if (event.originalEvent.altKey) { 4392 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4393 -$.datepicker._get(inst, "stepBigMonths") : 4394 -$.datepicker._get(inst, "stepMonths")), "M"); 4395 } 4396 // next month/year on alt +left on Mac 4397 break; 4398 case 38: if (event.ctrlKey || event.metaKey) { 4399 $.datepicker._adjustDate(event.target, -7, "D"); 4400 } 4401 handled = event.ctrlKey || event.metaKey; 4402 break; // -1 week on ctrl or command +up 4403 case 39: if (event.ctrlKey || event.metaKey) { 4404 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 4405 } 4406 handled = event.ctrlKey || event.metaKey; 4407 // +1 day on ctrl or command +right 4408 if (event.originalEvent.altKey) { 4409 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4410 +$.datepicker._get(inst, "stepBigMonths") : 4411 +$.datepicker._get(inst, "stepMonths")), "M"); 4412 } 4413 // next month/year on alt +right 4414 break; 4415 case 40: if (event.ctrlKey || event.metaKey) { 4416 $.datepicker._adjustDate(event.target, +7, "D"); 4417 } 4418 handled = event.ctrlKey || event.metaKey; 4419 break; // +1 week on ctrl or command +down 4420 default: handled = false; 4421 } 4422 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 4423 $.datepicker._showDatepicker(this); 4424 } else { 4425 handled = false; 4426 } 4427 4428 if (handled) { 4429 event.preventDefault(); 4430 event.stopPropagation(); 4431 } 4432 }, 4433 4434 /* Filter entered characters - based on date format. */ 4435 _doKeyPress: function(event) { 4436 var chars, chr, 4437 inst = $.datepicker._getInst(event.target); 4438 4439 if ($.datepicker._get(inst, "constrainInput")) { 4440 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 4441 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 4442 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 4443 } 4444 }, 4445 4446 /* Synchronise manual entry and field/alternate field. */ 4447 _doKeyUp: function(event) { 4448 var date, 4449 inst = $.datepicker._getInst(event.target); 4450 4451 if (inst.input.val() !== inst.lastVal) { 4452 try { 4453 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 4454 (inst.input ? inst.input.val() : null), 4455 $.datepicker._getFormatConfig(inst)); 4456 4457 if (date) { // only if valid 4458 $.datepicker._setDateFromField(inst); 4459 $.datepicker._updateAlternate(inst); 4460 $.datepicker._updateDatepicker(inst); 4461 } 4462 } 4463 catch (err) { 4464 } 4465 } 4466 return true; 4467 }, 4468 4469 /* Pop-up the date picker for a given input field. 4470 * If false returned from beforeShow event handler do not show. 4471 * @param input element - the input field attached to the date picker or 4472 * event - if triggered by focus 4473 */ 4474 _showDatepicker: function(input) { 4475 input = input.target || input; 4476 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 4477 input = $("input", input.parentNode)[0]; 4478 } 4479 4480 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 4481 return; 4482 } 4483 4484 var inst, beforeShow, beforeShowSettings, isFixed, 4485 offset, showAnim, duration; 4486 4487 inst = $.datepicker._getInst(input); 4488 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 4489 $.datepicker._curInst.dpDiv.stop(true, true); 4490 if ( inst && $.datepicker._datepickerShowing ) { 4491 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 4492 } 4493 } 4494 4495 beforeShow = $.datepicker._get(inst, "beforeShow"); 4496 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 4497 if(beforeShowSettings === false){ 4498 return; 4499 } 4500 datepicker_extendRemove(inst.settings, beforeShowSettings); 4501 4502 inst.lastVal = null; 4503 $.datepicker._lastInput = input; 4504 $.datepicker._setDateFromField(inst); 4505 4506 if ($.datepicker._inDialog) { // hide cursor 4507 input.value = ""; 4508 } 4509 if (!$.datepicker._pos) { // position below input 4510 $.datepicker._pos = $.datepicker._findPos(input); 4511 $.datepicker._pos[1] += input.offsetHeight; // add the height 4512 } 4513 4514 isFixed = false; 4515 $(input).parents().each(function() { 4516 isFixed |= $(this).css("position") === "fixed"; 4517 return !isFixed; 4518 }); 4519 4520 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 4521 $.datepicker._pos = null; 4522 //to avoid flashes on Firefox 4523 inst.dpDiv.empty(); 4524 // determine sizing offscreen 4525 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 4526 $.datepicker._updateDatepicker(inst); 4527 // fix width for dynamic number of date pickers 4528 // and adjust position before showing 4529 offset = $.datepicker._checkOffset(inst, offset, isFixed); 4530 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 4531 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 4532 left: offset.left + "px", top: offset.top + "px"}); 4533 4534 if (!inst.inline) { 4535 showAnim = $.datepicker._get(inst, "showAnim"); 4536 duration = $.datepicker._get(inst, "duration"); 4537 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 4538 $.datepicker._datepickerShowing = true; 4539 4540 if ( $.effects && $.effects.effect[ showAnim ] ) { 4541 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 4542 } else { 4543 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 4544 } 4545 4546 if ( $.datepicker._shouldFocusInput( inst ) ) { 4547 inst.input.focus(); 4548 } 4549 4550 $.datepicker._curInst = inst; 4551 } 4552 }, 4553 4554 /* Generate the date picker content. */ 4555 _updateDatepicker: function(inst) { 4556 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 4557 datepicker_instActive = inst; // for delegate hover events 4558 inst.dpDiv.empty().append(this._generateHTML(inst)); 4559 this._attachHandlers(inst); 4560 4561 var origyearshtml, 4562 numMonths = this._getNumberOfMonths(inst), 4563 cols = numMonths[1], 4564 width = 17, 4565 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 4566 4567 if ( activeCell.length > 0 ) { 4568 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 4569 } 4570 4571 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 4572 if (cols > 1) { 4573 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 4574 } 4575 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 4576 "Class"]("ui-datepicker-multi"); 4577 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 4578 "Class"]("ui-datepicker-rtl"); 4579 4580 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 4581 inst.input.focus(); 4582 } 4583 4584 // deffered render of the years select (to avoid flashes on Firefox) 4585 if( inst.yearshtml ){ 4586 origyearshtml = inst.yearshtml; 4587 setTimeout(function(){ 4588 //assure that inst.yearshtml didn't change. 4589 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 4590 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 4591 } 4592 origyearshtml = inst.yearshtml = null; 4593 }, 0); 4594 } 4595 }, 4596 4597 // #6694 - don't focus the input if it's already focused 4598 // this breaks the change event in IE 4599 // Support: IE and jQuery <1.9 4600 _shouldFocusInput: function( inst ) { 4601 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 4602 }, 4603 4604 /* Check positioning to remain on screen. */ 4605 _checkOffset: function(inst, offset, isFixed) { 4606 var dpWidth = inst.dpDiv.outerWidth(), 4607 dpHeight = inst.dpDiv.outerHeight(), 4608 inputWidth = inst.input ? inst.input.outerWidth() : 0, 4609 inputHeight = inst.input ? inst.input.outerHeight() : 0, 4610 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 4611 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 4612 4613 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 4614 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 4615 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 4616 4617 // now check if datepicker is showing outside window viewport - move to a better place if so. 4618 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 4619 Math.abs(offset.left + dpWidth - viewWidth) : 0); 4620 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 4621 Math.abs(dpHeight + inputHeight) : 0); 4622 4623 return offset; 4624 }, 4625 4626 /* Find an object's position on the screen. */ 4627 _findPos: function(obj) { 4628 var position, 4629 inst = this._getInst(obj), 4630 isRTL = this._get(inst, "isRTL"); 4631 4632 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 4633 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 4634 } 4635 4636 position = $(obj).offset(); 4637 return [position.left, position.top]; 4638 }, 4639 4640 /* Hide the date picker from view. 4641 * @param input element - the input field attached to the date picker 4642 */ 4643 _hideDatepicker: function(input) { 4644 var showAnim, duration, postProcess, onClose, 4645 inst = this._curInst; 4646 4647 if (!inst || (input && inst !== $.data(input, "datepicker"))) { 4648 return; 4649 } 4650 4651 if (this._datepickerShowing) { 4652 showAnim = this._get(inst, "showAnim"); 4653 duration = this._get(inst, "duration"); 4654 postProcess = function() { 4655 $.datepicker._tidyDialog(inst); 4656 }; 4657 4658 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 4659 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 4660 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 4661 } else { 4662 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 4663 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 4664 } 4665 4666 if (!showAnim) { 4667 postProcess(); 4668 } 4669 this._datepickerShowing = false; 4670 4671 onClose = this._get(inst, "onClose"); 4672 if (onClose) { 4673 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 4674 } 4675 4676 this._lastInput = null; 4677 if (this._inDialog) { 4678 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 4679 if ($.blockUI) { 4680 $.unblockUI(); 4681 $("body").append(this.dpDiv); 4682 } 4683 } 4684 this._inDialog = false; 4685 } 4686 }, 4687 4688 /* Tidy up after a dialog display. */ 4689 _tidyDialog: function(inst) { 4690 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 4691 }, 4692 4693 /* Close date picker if clicked elsewhere. */ 4694 _checkExternalClick: function(event) { 4695 if (!$.datepicker._curInst) { 4696 return; 4697 } 4698 4699 var $target = $(event.target), 4700 inst = $.datepicker._getInst($target[0]); 4701 4702 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 4703 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 4704 !$target.hasClass($.datepicker.markerClassName) && 4705 !$target.closest("." + $.datepicker._triggerClass).length && 4706 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 4707 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 4708 $.datepicker._hideDatepicker(); 4709 } 4710 }, 4711 4712 /* Adjust one of the date sub-fields. */ 4713 _adjustDate: function(id, offset, period) { 4714 var target = $(id), 4715 inst = this._getInst(target[0]); 4716 4717 if (this._isDisabledDatepicker(target[0])) { 4718 return; 4719 } 4720 this._adjustInstDate(inst, offset + 4721 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 4722 period); 4723 this._updateDatepicker(inst); 4724 }, 4725 4726 /* Action for current link. */ 4727 _gotoToday: function(id) { 4728 var date, 4729 target = $(id), 4730 inst = this._getInst(target[0]); 4731 4732 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 4733 inst.selectedDay = inst.currentDay; 4734 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 4735 inst.drawYear = inst.selectedYear = inst.currentYear; 4736 } else { 4737 date = new Date(); 4738 inst.selectedDay = date.getDate(); 4739 inst.drawMonth = inst.selectedMonth = date.getMonth(); 4740 inst.drawYear = inst.selectedYear = date.getFullYear(); 4741 } 4742 this._notifyChange(inst); 4743 this._adjustDate(target); 4744 }, 4745 4746 /* Action for selecting a new month/year. */ 4747 _selectMonthYear: function(id, select, period) { 4748 var target = $(id), 4749 inst = this._getInst(target[0]); 4750 4751 inst["selected" + (period === "M" ? "Month" : "Year")] = 4752 inst["draw" + (period === "M" ? "Month" : "Year")] = 4753 parseInt(select.options[select.selectedIndex].value,10); 4754 4755 this._notifyChange(inst); 4756 this._adjustDate(target); 4757 }, 4758 4759 /* Action for selecting a day. */ 4760 _selectDay: function(id, month, year, td) { 4761 var inst, 4762 target = $(id); 4763 4764 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 4765 return; 4766 } 4767 4768 inst = this._getInst(target[0]); 4769 inst.selectedDay = inst.currentDay = $("a", td).html(); 4770 inst.selectedMonth = inst.currentMonth = month; 4771 inst.selectedYear = inst.currentYear = year; 4772 this._selectDate(id, this._formatDate(inst, 4773 inst.currentDay, inst.currentMonth, inst.currentYear)); 4774 }, 4775 4776 /* Erase the input field and hide the date picker. */ 4777 _clearDate: function(id) { 4778 var target = $(id); 4779 this._selectDate(target, ""); 4780 }, 4781 4782 /* Update the input field with the selected date. */ 4783 _selectDate: function(id, dateStr) { 4784 var onSelect, 4785 target = $(id), 4786 inst = this._getInst(target[0]); 4787 4788 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 4789 if (inst.input) { 4790 inst.input.val(dateStr); 4791 } 4792 this._updateAlternate(inst); 4793 4794 onSelect = this._get(inst, "onSelect"); 4795 if (onSelect) { 4796 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 4797 } else if (inst.input) { 4798 inst.input.trigger("change"); // fire the change event 4799 } 4800 4801 if (inst.inline){ 4802 this._updateDatepicker(inst); 4803 } else { 4804 this._hideDatepicker(); 4805 this._lastInput = inst.input[0]; 4806 if (typeof(inst.input[0]) !== "object") { 4807 inst.input.focus(); // restore focus 4808 } 4809 this._lastInput = null; 4810 } 4811 }, 4812 4813 /* Update any alternate field to synchronise with the main field. */ 4814 _updateAlternate: function(inst) { 4815 var altFormat, date, dateStr, 4816 altField = this._get(inst, "altField"); 4817 4818 if (altField) { // update alternate field too 4819 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 4820 date = this._getDate(inst); 4821 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 4822 $(altField).each(function() { $(this).val(dateStr); }); 4823 } 4824 }, 4825 4826 /* Set as beforeShowDay function to prevent selection of weekends. 4827 * @param date Date - the date to customise 4828 * @return [boolean, string] - is this date selectable?, what is its CSS class? 4829 */ 4830 noWeekends: function(date) { 4831 var day = date.getDay(); 4832 return [(day > 0 && day < 6), ""]; 4833 }, 4834 4835 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 4836 * @param date Date - the date to get the week for 4837 * @return number - the number of the week within the year that contains this date 4838 */ 4839 iso8601Week: function(date) { 4840 var time, 4841 checkDate = new Date(date.getTime()); 4842 4843 // Find Thursday of this week starting on Monday 4844 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 4845 4846 time = checkDate.getTime(); 4847 checkDate.setMonth(0); // Compare with Jan 1 4848 checkDate.setDate(1); 4849 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 4850 }, 4851 4852 /* Parse a string value into a date object. 4853 * See formatDate below for the possible formats. 4854 * 4855 * @param format string - the expected format of the date 4856 * @param value string - the date in the above format 4857 * @param settings Object - attributes include: 4858 * shortYearCutoff number - the cutoff year for determining the century (optional) 4859 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 4860 * dayNames string[7] - names of the days from Sunday (optional) 4861 * monthNamesShort string[12] - abbreviated names of the months (optional) 4862 * monthNames string[12] - names of the months (optional) 4863 * @return Date - the extracted date value or null if value is blank 4864 */ 4865 parseDate: function (format, value, settings) { 4866 if (format == null || value == null) { 4867 throw "Invalid arguments"; 4868 } 4869 4870 value = (typeof value === "object" ? value.toString() : value + ""); 4871 if (value === "") { 4872 return null; 4873 } 4874 4875 var iFormat, dim, extra, 4876 iValue = 0, 4877 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 4878 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 4879 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 4880 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 4881 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 4882 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 4883 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 4884 year = -1, 4885 month = -1, 4886 day = -1, 4887 doy = -1, 4888 literal = false, 4889 date, 4890 // Check whether a format character is doubled 4891 lookAhead = function(match) { 4892 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 4893 if (matches) { 4894 iFormat++; 4895 } 4896 return matches; 4897 }, 4898 // Extract a number from the string value 4899 getNumber = function(match) { 4900 var isDoubled = lookAhead(match), 4901 size = (match === "@" ? 14 : (match === "!" ? 20 : 4902 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 4903 minSize = (match === "y" ? size : 1), 4904 digits = new RegExp("^\\d{" + minSize + "," + size + "}"), 4905 num = value.substring(iValue).match(digits); 4906 if (!num) { 4907 throw "Missing number at position " + iValue; 4908 } 4909 iValue += num[0].length; 4910 return parseInt(num[0], 10); 4911 }, 4912 // Extract a name from the string value and convert to an index 4913 getName = function(match, shortNames, longNames) { 4914 var index = -1, 4915 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 4916 return [ [k, v] ]; 4917 }).sort(function (a, b) { 4918 return -(a[1].length - b[1].length); 4919 }); 4920 4921 $.each(names, function (i, pair) { 4922 var name = pair[1]; 4923 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 4924 index = pair[0]; 4925 iValue += name.length; 4926 return false; 4927 } 4928 }); 4929 if (index !== -1) { 4930 return index + 1; 4931 } else { 4932 throw "Unknown name at position " + iValue; 4933 } 4934 }, 4935 // Confirm that a literal character matches the string value 4936 checkLiteral = function() { 4937 if (value.charAt(iValue) !== format.charAt(iFormat)) { 4938 throw "Unexpected literal at position " + iValue; 4939 } 4940 iValue++; 4941 }; 4942 4943 for (iFormat = 0; iFormat < format.length; iFormat++) { 4944 if (literal) { 4945 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 4946 literal = false; 4947 } else { 4948 checkLiteral(); 4949 } 4950 } else { 4951 switch (format.charAt(iFormat)) { 4952 case "d": 4953 day = getNumber("d"); 4954 break; 4955 case "D": 4956 getName("D", dayNamesShort, dayNames); 4957 break; 4958 case "o": 4959 doy = getNumber("o"); 4960 break; 4961 case "m": 4962 month = getNumber("m"); 4963 break; 4964 case "M": 4965 month = getName("M", monthNamesShort, monthNames); 4966 break; 4967 case "y": 4968 year = getNumber("y"); 4969 break; 4970 case "@": 4971 date = new Date(getNumber("@")); 4972 year = date.getFullYear(); 4973 month = date.getMonth() + 1; 4974 day = date.getDate(); 4975 break; 4976 case "!": 4977 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 4978 year = date.getFullYear(); 4979 month = date.getMonth() + 1; 4980 day = date.getDate(); 4981 break; 4982 case "'": 4983 if (lookAhead("'")){ 4984 checkLiteral(); 4985 } else { 4986 literal = true; 4987 } 4988 break; 4989 default: 4990 checkLiteral(); 4991 } 4992 } 4993 } 4994 4995 if (iValue < value.length){ 4996 extra = value.substr(iValue); 4997 if (!/^\s+/.test(extra)) { 4998 throw "Extra/unparsed characters found in date: " + extra; 4999 } 5000 } 5001 5002 if (year === -1) { 5003 year = new Date().getFullYear(); 5004 } else if (year < 100) { 5005 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 5006 (year <= shortYearCutoff ? 0 : -100); 5007 } 5008 5009 if (doy > -1) { 5010 month = 1; 5011 day = doy; 5012 do { 5013 dim = this._getDaysInMonth(year, month - 1); 5014 if (day <= dim) { 5015 break; 5016 } 5017 month++; 5018 day -= dim; 5019 } while (true); 5020 } 5021 5022 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 5023 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 5024 throw "Invalid date"; // E.g. 31/02/00 5025 } 5026 return date; 5027 }, 5028 5029 /* Standard date formats. */ 5030 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 5031 COOKIE: "D, dd M yy", 5032 ISO_8601: "yy-mm-dd", 5033 RFC_822: "D, d M y", 5034 RFC_850: "DD, dd-M-y", 5035 RFC_1036: "D, d M y", 5036 RFC_1123: "D, d M yy", 5037 RFC_2822: "D, d M yy", 5038 RSS: "D, d M y", // RFC 822 5039 TICKS: "!", 5040 TIMESTAMP: "@", 5041 W3C: "yy-mm-dd", // ISO 8601 5042 5043 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 5044 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 5045 5046 /* Format a date object into a string value. 5047 * The format can be combinations of the following: 5048 * d - day of month (no leading zero) 5049 * dd - day of month (two digit) 5050 * o - day of year (no leading zeros) 5051 * oo - day of year (three digit) 5052 * D - day name short 5053 * DD - day name long 5054 * m - month of year (no leading zero) 5055 * mm - month of year (two digit) 5056 * M - month name short 5057 * MM - month name long 5058 * y - year (two digit) 5059 * yy - year (four digit) 5060 * @ - Unix timestamp (ms since 01/01/1970) 5061 * ! - Windows ticks (100ns since 01/01/0001) 5062 * "..." - literal text 5063 * '' - single quote 5064 * 5065 * @param format string - the desired format of the date 5066 * @param date Date - the date value to format 5067 * @param settings Object - attributes include: 5068 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5069 * dayNames string[7] - names of the days from Sunday (optional) 5070 * monthNamesShort string[12] - abbreviated names of the months (optional) 5071 * monthNames string[12] - names of the months (optional) 5072 * @return string - the date in the above format 5073 */ 5074 formatDate: function (format, date, settings) { 5075 if (!date) { 5076 return ""; 5077 } 5078 5079 var iFormat, 5080 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 5081 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 5082 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 5083 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 5084 // Check whether a format character is doubled 5085 lookAhead = function(match) { 5086 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5087 if (matches) { 5088 iFormat++; 5089 } 5090 return matches; 5091 }, 5092 // Format a number, with leading zero if necessary 5093 formatNumber = function(match, value, len) { 5094 var num = "" + value; 5095 if (lookAhead(match)) { 5096 while (num.length < len) { 5097 num = "0" + num; 5098 } 5099 } 5100 return num; 5101 }, 5102 // Format a name, short or long as requested 5103 formatName = function(match, value, shortNames, longNames) { 5104 return (lookAhead(match) ? longNames[value] : shortNames[value]); 5105 }, 5106 output = "", 5107 literal = false; 5108 5109 if (date) { 5110 for (iFormat = 0; iFormat < format.length; iFormat++) { 5111 if (literal) { 5112 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5113 literal = false; 5114 } else { 5115 output += format.charAt(iFormat); 5116 } 5117 } else { 5118 switch (format.charAt(iFormat)) { 5119 case "d": 5120 output += formatNumber("d", date.getDate(), 2); 5121 break; 5122 case "D": 5123 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 5124 break; 5125 case "o": 5126 output += formatNumber("o", 5127 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 5128 break; 5129 case "m": 5130 output += formatNumber("m", date.getMonth() + 1, 2); 5131 break; 5132 case "M": 5133 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 5134 break; 5135 case "y": 5136 output += (lookAhead("y") ? date.getFullYear() : 5137 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 5138 break; 5139 case "@": 5140 output += date.getTime(); 5141 break; 5142 case "!": 5143 output += date.getTime() * 10000 + this._ticksTo1970; 5144 break; 5145 case "'": 5146 if (lookAhead("'")) { 5147 output += "'"; 5148 } else { 5149 literal = true; 5150 } 5151 break; 5152 default: 5153 output += format.charAt(iFormat); 5154 } 5155 } 5156 } 5157 } 5158 return output; 5159 }, 5160 5161 /* Extract all possible characters from the date format. */ 5162 _possibleChars: function (format) { 5163 var iFormat, 5164 chars = "", 5165 literal = false, 5166 // Check whether a format character is doubled 5167 lookAhead = function(match) { 5168 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5169 if (matches) { 5170 iFormat++; 5171 } 5172 return matches; 5173 }; 5174 5175 for (iFormat = 0; iFormat < format.length; iFormat++) { 5176 if (literal) { 5177 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5178 literal = false; 5179 } else { 5180 chars += format.charAt(iFormat); 5181 } 5182 } else { 5183 switch (format.charAt(iFormat)) { 5184 case "d": case "m": case "y": case "@": 5185 chars += "0123456789"; 5186 break; 5187 case "D": case "M": 5188 return null; // Accept anything 5189 case "'": 5190 if (lookAhead("'")) { 5191 chars += "'"; 5192 } else { 5193 literal = true; 5194 } 5195 break; 5196 default: 5197 chars += format.charAt(iFormat); 5198 } 5199 } 5200 } 5201 return chars; 5202 }, 5203 5204 /* Get a setting value, defaulting if necessary. */ 5205 _get: function(inst, name) { 5206 return inst.settings[name] !== undefined ? 5207 inst.settings[name] : this._defaults[name]; 5208 }, 5209 5210 /* Parse existing date and initialise date picker. */ 5211 _setDateFromField: function(inst, noDefault) { 5212 if (inst.input.val() === inst.lastVal) { 5213 return; 5214 } 5215 5216 var dateFormat = this._get(inst, "dateFormat"), 5217 dates = inst.lastVal = inst.input ? inst.input.val() : null, 5218 defaultDate = this._getDefaultDate(inst), 5219 date = defaultDate, 5220 settings = this._getFormatConfig(inst); 5221 5222 try { 5223 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 5224 } catch (event) { 5225 dates = (noDefault ? "" : dates); 5226 } 5227 inst.selectedDay = date.getDate(); 5228 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5229 inst.drawYear = inst.selectedYear = date.getFullYear(); 5230 inst.currentDay = (dates ? date.getDate() : 0); 5231 inst.currentMonth = (dates ? date.getMonth() : 0); 5232 inst.currentYear = (dates ? date.getFullYear() : 0); 5233 this._adjustInstDate(inst); 5234 }, 5235 5236 /* Retrieve the default date shown on opening. */ 5237 _getDefaultDate: function(inst) { 5238 return this._restrictMinMax(inst, 5239 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 5240 }, 5241 5242 /* A date may be specified as an exact value or a relative one. */ 5243 _determineDate: function(inst, date, defaultDate) { 5244 var offsetNumeric = function(offset) { 5245 var date = new Date(); 5246 date.setDate(date.getDate() + offset); 5247 return date; 5248 }, 5249 offsetString = function(offset) { 5250 try { 5251 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 5252 offset, $.datepicker._getFormatConfig(inst)); 5253 } 5254 catch (e) { 5255 // Ignore 5256 } 5257 5258 var date = (offset.toLowerCase().match(/^c/) ? 5259 $.datepicker._getDate(inst) : null) || new Date(), 5260 year = date.getFullYear(), 5261 month = date.getMonth(), 5262 day = date.getDate(), 5263 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 5264 matches = pattern.exec(offset); 5265 5266 while (matches) { 5267 switch (matches[2] || "d") { 5268 case "d" : case "D" : 5269 day += parseInt(matches[1],10); break; 5270 case "w" : case "W" : 5271 day += parseInt(matches[1],10) * 7; break; 5272 case "m" : case "M" : 5273 month += parseInt(matches[1],10); 5274 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5275 break; 5276 case "y": case "Y" : 5277 year += parseInt(matches[1],10); 5278 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5279 break; 5280 } 5281 matches = pattern.exec(offset); 5282 } 5283 return new Date(year, month, day); 5284 }, 5285 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 5286 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 5287 5288 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 5289 if (newDate) { 5290 newDate.setHours(0); 5291 newDate.setMinutes(0); 5292 newDate.setSeconds(0); 5293 newDate.setMilliseconds(0); 5294 } 5295 return this._daylightSavingAdjust(newDate); 5296 }, 5297 5298 /* Handle switch to/from daylight saving. 5299 * Hours may be non-zero on daylight saving cut-over: 5300 * > 12 when midnight changeover, but then cannot generate 5301 * midnight datetime, so jump to 1AM, otherwise reset. 5302 * @param date (Date) the date to check 5303 * @return (Date) the corrected date 5304 */ 5305 _daylightSavingAdjust: function(date) { 5306 if (!date) { 5307 return null; 5308 } 5309 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 5310 return date; 5311 }, 5312 5313 /* Set the date(s) directly. */ 5314 _setDate: function(inst, date, noChange) { 5315 var clear = !date, 5316 origMonth = inst.selectedMonth, 5317 origYear = inst.selectedYear, 5318 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 5319 5320 inst.selectedDay = inst.currentDay = newDate.getDate(); 5321 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 5322 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 5323 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 5324 this._notifyChange(inst); 5325 } 5326 this._adjustInstDate(inst); 5327 if (inst.input) { 5328 inst.input.val(clear ? "" : this._formatDate(inst)); 5329 } 5330 }, 5331 5332 /* Retrieve the date(s) directly. */ 5333 _getDate: function(inst) { 5334 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 5335 this._daylightSavingAdjust(new Date( 5336 inst.currentYear, inst.currentMonth, inst.currentDay))); 5337 return startDate; 5338 }, 5339 5340 /* Attach the onxxx handlers. These are declared statically so 5341 * they work with static code transformers like Caja. 5342 */ 5343 _attachHandlers: function(inst) { 5344 var stepMonths = this._get(inst, "stepMonths"), 5345 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 5346 inst.dpDiv.find("[data-handler]").map(function () { 5347 var handler = { 5348 prev: function () { 5349 $.datepicker._adjustDate(id, -stepMonths, "M"); 5350 }, 5351 next: function () { 5352 $.datepicker._adjustDate(id, +stepMonths, "M"); 5353 }, 5354 hide: function () { 5355 $.datepicker._hideDatepicker(); 5356 }, 5357 today: function () { 5358 $.datepicker._gotoToday(id); 5359 }, 5360 selectDay: function () { 5361 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 5362 return false; 5363 }, 5364 selectMonth: function () { 5365 $.datepicker._selectMonthYear(id, this, "M"); 5366 return false; 5367 }, 5368 selectYear: function () { 5369 $.datepicker._selectMonthYear(id, this, "Y"); 5370 return false; 5371 } 5372 }; 5373 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 5374 }); 5375 }, 5376 5377 /* Generate the HTML for the current state of the date picker. */ 5378 _generateHTML: function(inst) { 5379 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 5380 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 5381 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 5382 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 5383 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 5384 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 5385 tempDate = new Date(), 5386 today = this._daylightSavingAdjust( 5387 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 5388 isRTL = this._get(inst, "isRTL"), 5389 showButtonPanel = this._get(inst, "showButtonPanel"), 5390 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 5391 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 5392 numMonths = this._getNumberOfMonths(inst), 5393 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 5394 stepMonths = this._get(inst, "stepMonths"), 5395 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 5396 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 5397 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 5398 minDate = this._getMinMaxDate(inst, "min"), 5399 maxDate = this._getMinMaxDate(inst, "max"), 5400 drawMonth = inst.drawMonth - showCurrentAtPos, 5401 drawYear = inst.drawYear; 5402 5403 if (drawMonth < 0) { 5404 drawMonth += 12; 5405 drawYear--; 5406 } 5407 if (maxDate) { 5408 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 5409 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 5410 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 5411 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 5412 drawMonth--; 5413 if (drawMonth < 0) { 5414 drawMonth = 11; 5415 drawYear--; 5416 } 5417 } 5418 } 5419 inst.drawMonth = drawMonth; 5420 inst.drawYear = drawYear; 5421 5422 prevText = this._get(inst, "prevText"); 5423 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 5424 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 5425 this._getFormatConfig(inst))); 5426 5427 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 5428 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 5429 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 5430 (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>")); 5431 5432 nextText = this._get(inst, "nextText"); 5433 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 5434 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 5435 this._getFormatConfig(inst))); 5436 5437 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 5438 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 5439 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 5440 (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>")); 5441 5442 currentText = this._get(inst, "currentText"); 5443 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 5444 currentText = (!navigationAsDateFormat ? currentText : 5445 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 5446 5447 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'>" + 5448 this._get(inst, "closeText") + "</button>" : ""); 5449 5450 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 5451 (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'" + 5452 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 5453 5454 firstDay = parseInt(this._get(inst, "firstDay"),10); 5455 firstDay = (isNaN(firstDay) ? 0 : firstDay); 5456 5457 showWeek = this._get(inst, "showWeek"); 5458 dayNames = this._get(inst, "dayNames"); 5459 dayNamesMin = this._get(inst, "dayNamesMin"); 5460 monthNames = this._get(inst, "monthNames"); 5461 monthNamesShort = this._get(inst, "monthNamesShort"); 5462 beforeShowDay = this._get(inst, "beforeShowDay"); 5463 showOtherMonths = this._get(inst, "showOtherMonths"); 5464 selectOtherMonths = this._get(inst, "selectOtherMonths"); 5465 defaultDate = this._getDefaultDate(inst); 5466 html = ""; 5467 dow; 5468 for (row = 0; row < numMonths[0]; row++) { 5469 group = ""; 5470 this.maxRows = 4; 5471 for (col = 0; col < numMonths[1]; col++) { 5472 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 5473 cornerClass = " ui-corner-all"; 5474 calender = ""; 5475 if (isMultiMonth) { 5476 calender += "<div class='ui-datepicker-group"; 5477 if (numMonths[1] > 1) { 5478 switch (col) { 5479 case 0: calender += " ui-datepicker-group-first"; 5480 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 5481 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 5482 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 5483 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 5484 } 5485 } 5486 calender += "'>"; 5487 } 5488 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 5489 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 5490 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 5491 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 5492 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 5493 "</div><table class='ui-datepicker-calendar'><thead>" + 5494 "<tr>"; 5495 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 5496 for (dow = 0; dow < 7; dow++) { // days of the week 5497 day = (dow + firstDay) % 7; 5498 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 5499 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 5500 } 5501 calender += thead + "</tr></thead><tbody>"; 5502 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 5503 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 5504 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 5505 } 5506 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 5507 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 5508 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 5509 this.maxRows = numRows; 5510 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 5511 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 5512 calender += "<tr>"; 5513 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 5514 this._get(inst, "calculateWeek")(printDate) + "</td>"); 5515 for (dow = 0; dow < 7; dow++) { // create date picker days 5516 daySettings = (beforeShowDay ? 5517 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 5518 otherMonth = (printDate.getMonth() !== drawMonth); 5519 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 5520 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 5521 tbody += "<td class='" + 5522 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 5523 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 5524 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 5525 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 5526 // or defaultDate is current printedDate and defaultDate is selectedDate 5527 " " + this._dayOverClass : "") + // highlight selected day 5528 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 5529 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 5530 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 5531 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 5532 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 5533 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 5534 (otherMonth && !showOtherMonths ? " " : // display for other months 5535 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 5536 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 5537 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 5538 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 5539 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 5540 printDate.setDate(printDate.getDate() + 1); 5541 printDate = this._daylightSavingAdjust(printDate); 5542 } 5543 calender += tbody + "</tr>"; 5544 } 5545 drawMonth++; 5546 if (drawMonth > 11) { 5547 drawMonth = 0; 5548 drawYear++; 5549 } 5550 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 5551 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 5552 group += calender; 5553 } 5554 html += group; 5555 } 5556 html += buttonPanel; 5557 inst._keyEvent = false; 5558 return html; 5559 }, 5560 5561 /* Generate the month and year header. */ 5562 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 5563 secondary, monthNames, monthNamesShort) { 5564 5565 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 5566 changeMonth = this._get(inst, "changeMonth"), 5567 changeYear = this._get(inst, "changeYear"), 5568 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 5569 html = "<div class='ui-datepicker-title'>", 5570 monthHtml = ""; 5571 5572 // month selection 5573 if (secondary || !changeMonth) { 5574 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 5575 } else { 5576 inMinYear = (minDate && minDate.getFullYear() === drawYear); 5577 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 5578 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 5579 for ( month = 0; month < 12; month++) { 5580 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 5581 monthHtml += "<option value='" + month + "'" + 5582 (month === drawMonth ? " selected='selected'" : "") + 5583 ">" + monthNamesShort[month] + "</option>"; 5584 } 5585 } 5586 monthHtml += "</select>"; 5587 } 5588 5589 if (!showMonthAfterYear) { 5590 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 5591 } 5592 5593 // year selection 5594 if ( !inst.yearshtml ) { 5595 inst.yearshtml = ""; 5596 if (secondary || !changeYear) { 5597 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 5598 } else { 5599 // determine range of years to display 5600 years = this._get(inst, "yearRange").split(":"); 5601 thisYear = new Date().getFullYear(); 5602 determineYear = function(value) { 5603 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 5604 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 5605 parseInt(value, 10))); 5606 return (isNaN(year) ? thisYear : year); 5607 }; 5608 year = determineYear(years[0]); 5609 endYear = Math.max(year, determineYear(years[1] || "")); 5610 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 5611 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 5612 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 5613 for (; year <= endYear; year++) { 5614 inst.yearshtml += "<option value='" + year + "'" + 5615 (year === drawYear ? " selected='selected'" : "") + 5616 ">" + year + "</option>"; 5617 } 5618 inst.yearshtml += "</select>"; 5619 5620 html += inst.yearshtml; 5621 inst.yearshtml = null; 5622 } 5623 } 5624 5625 html += this._get(inst, "yearSuffix"); 5626 if (showMonthAfterYear) { 5627 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 5628 } 5629 html += "</div>"; // Close datepicker_header 5630 return html; 5631 }, 5632 5633 /* Adjust one of the date sub-fields. */ 5634 _adjustInstDate: function(inst, offset, period) { 5635 var year = inst.drawYear + (period === "Y" ? offset : 0), 5636 month = inst.drawMonth + (period === "M" ? offset : 0), 5637 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 5638 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 5639 5640 inst.selectedDay = date.getDate(); 5641 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5642 inst.drawYear = inst.selectedYear = date.getFullYear(); 5643 if (period === "M" || period === "Y") { 5644 this._notifyChange(inst); 5645 } 5646 }, 5647 5648 /* Ensure a date is within any min/max bounds. */ 5649 _restrictMinMax: function(inst, date) { 5650 var minDate = this._getMinMaxDate(inst, "min"), 5651 maxDate = this._getMinMaxDate(inst, "max"), 5652 newDate = (minDate && date < minDate ? minDate : date); 5653 return (maxDate && newDate > maxDate ? maxDate : newDate); 5654 }, 5655 5656 /* Notify change of month/year. */ 5657 _notifyChange: function(inst) { 5658 var onChange = this._get(inst, "onChangeMonthYear"); 5659 if (onChange) { 5660 onChange.apply((inst.input ? inst.input[0] : null), 5661 [inst.selectedYear, inst.selectedMonth + 1, inst]); 5662 } 5663 }, 5664 5665 /* Determine the number of months to show. */ 5666 _getNumberOfMonths: function(inst) { 5667 var numMonths = this._get(inst, "numberOfMonths"); 5668 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 5669 }, 5670 5671 /* Determine the current maximum date - ensure no time components are set. */ 5672 _getMinMaxDate: function(inst, minMax) { 5673 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 5674 }, 5675 5676 /* Find the number of days in a given month. */ 5677 _getDaysInMonth: function(year, month) { 5678 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 5679 }, 5680 5681 /* Find the day of the week of the first of a month. */ 5682 _getFirstDayOfMonth: function(year, month) { 5683 return new Date(year, month, 1).getDay(); 5684 }, 5685 5686 /* Determines if we should allow a "next/prev" month display change. */ 5687 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 5688 var numMonths = this._getNumberOfMonths(inst), 5689 date = this._daylightSavingAdjust(new Date(curYear, 5690 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 5691 5692 if (offset < 0) { 5693 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 5694 } 5695 return this._isInRange(inst, date); 5696 }, 5697 5698 /* Is the given date in the accepted range? */ 5699 _isInRange: function(inst, date) { 5700 var yearSplit, currentYear, 5701 minDate = this._getMinMaxDate(inst, "min"), 5702 maxDate = this._getMinMaxDate(inst, "max"), 5703 minYear = null, 5704 maxYear = null, 5705 years = this._get(inst, "yearRange"); 5706 if (years){ 5707 yearSplit = years.split(":"); 5708 currentYear = new Date().getFullYear(); 5709 minYear = parseInt(yearSplit[0], 10); 5710 maxYear = parseInt(yearSplit[1], 10); 5711 if ( yearSplit[0].match(/[+\-].*/) ) { 5712 minYear += currentYear; 5713 } 5714 if ( yearSplit[1].match(/[+\-].*/) ) { 5715 maxYear += currentYear; 5716 } 5717 } 5718 5719 return ((!minDate || date.getTime() >= minDate.getTime()) && 5720 (!maxDate || date.getTime() <= maxDate.getTime()) && 5721 (!minYear || date.getFullYear() >= minYear) && 5722 (!maxYear || date.getFullYear() <= maxYear)); 5723 }, 5724 5725 /* Provide the configuration settings for formatting/parsing. */ 5726 _getFormatConfig: function(inst) { 5727 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 5728 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 5729 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 5730 return {shortYearCutoff: shortYearCutoff, 5731 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 5732 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 5733 }, 5734 5735 /* Format the given date for display. */ 5736 _formatDate: function(inst, day, month, year) { 5737 if (!day) { 5738 inst.currentDay = inst.selectedDay; 5739 inst.currentMonth = inst.selectedMonth; 5740 inst.currentYear = inst.selectedYear; 5741 } 5742 var date = (day ? (typeof day === "object" ? day : 5743 this._daylightSavingAdjust(new Date(year, month, day))) : 5744 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 5745 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 5746 } 5747}); 5748 5749/* 5750 * Bind hover events for datepicker elements. 5751 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 5752 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 5753 */ 5754function datepicker_bindHover(dpDiv) { 5755 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 5756 return dpDiv.delegate(selector, "mouseout", function() { 5757 $(this).removeClass("ui-state-hover"); 5758 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 5759 $(this).removeClass("ui-datepicker-prev-hover"); 5760 } 5761 if (this.className.indexOf("ui-datepicker-next") !== -1) { 5762 $(this).removeClass("ui-datepicker-next-hover"); 5763 } 5764 }) 5765 .delegate( selector, "mouseover", datepicker_handleMouseover ); 5766} 5767 5768function datepicker_handleMouseover() { 5769 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { 5770 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 5771 $(this).addClass("ui-state-hover"); 5772 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 5773 $(this).addClass("ui-datepicker-prev-hover"); 5774 } 5775 if (this.className.indexOf("ui-datepicker-next") !== -1) { 5776 $(this).addClass("ui-datepicker-next-hover"); 5777 } 5778 } 5779} 5780 5781/* jQuery extend now ignores nulls! */ 5782function datepicker_extendRemove(target, props) { 5783 $.extend(target, props); 5784 for (var name in props) { 5785 if (props[name] == null) { 5786 target[name] = props[name]; 5787 } 5788 } 5789 return target; 5790} 5791 5792/* Invoke the datepicker functionality. 5793 @param options string - a command, optionally followed by additional parameters or 5794 Object - settings for attaching new datepicker functionality 5795 @return jQuery object */ 5796$.fn.datepicker = function(options){ 5797 5798 /* Verify an empty collection wasn't passed - Fixes #6976 */ 5799 if ( !this.length ) { 5800 return this; 5801 } 5802 5803 /* Initialise the date picker. */ 5804 if (!$.datepicker.initialized) { 5805 $(document).mousedown($.datepicker._checkExternalClick); 5806 $.datepicker.initialized = true; 5807 } 5808 5809 /* Append datepicker main container to body if not exist. */ 5810 if ($("#"+$.datepicker._mainDivId).length === 0) { 5811 $("body").append($.datepicker.dpDiv); 5812 } 5813 5814 var otherArgs = Array.prototype.slice.call(arguments, 1); 5815 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 5816 return $.datepicker["_" + options + "Datepicker"]. 5817 apply($.datepicker, [this[0]].concat(otherArgs)); 5818 } 5819 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 5820 return $.datepicker["_" + options + "Datepicker"]. 5821 apply($.datepicker, [this[0]].concat(otherArgs)); 5822 } 5823 return this.each(function() { 5824 typeof options === "string" ? 5825 $.datepicker["_" + options + "Datepicker"]. 5826 apply($.datepicker, [this].concat(otherArgs)) : 5827 $.datepicker._attachDatepicker(this, options); 5828 }); 5829}; 5830 5831$.datepicker = new Datepicker(); // singleton instance 5832$.datepicker.initialized = false;
vendor: 44,343 bytes, lines 5833-7353
5833$.datepicker.uuid = new Date().getTime(); 5834$.datepicker.version = "1.11.4"; 5835 5836var datepicker = $.datepicker; 5837 5838 5839/*! 5840 * jQuery UI Draggable 1.11.4 5841 * http://jqueryui.com 5842 * 5843 * Copyright jQuery Foundation and other contributors 5844 * Released under the MIT license. 5845 * http://jquery.org/license 5846 * 5847 * http://api.jqueryui.com/draggable/ 5848 */ 5849 5850 5851$.widget("ui.draggable", $.ui.mouse, { 5852 version: "1.11.4", 5853 widgetEventPrefix: "drag", 5854 options: { 5855 addClasses: true, 5856 appendTo: "parent", 5857 axis: false, 5858 connectToSortable: false, 5859 containment: false, 5860 cursor: "auto", 5861 cursorAt: false, 5862 grid: false, 5863 handle: false, 5864 helper: "original", 5865 iframeFix: false, 5866 opacity: false, 5867 refreshPositions: false, 5868 revert: false, 5869 revertDuration: 500, 5870 scope: "default", 5871 scroll: true, 5872 scrollSensitivity: 20, 5873 scrollSpeed: 20, 5874 snap: false, 5875 snapMode: "both", 5876 snapTolerance: 20, 5877 stack: false, 5878 zIndex: false, 5879 5880 // callbacks 5881 drag: null, 5882 start: null, 5883 stop: null 5884 }, 5885 _create: function() { 5886 5887 if ( this.options.helper === "original" ) { 5888 this._setPositionRelative(); 5889 } 5890 if (this.options.addClasses){ 5891 this.element.addClass("ui-draggable"); 5892 } 5893 if (this.options.disabled){ 5894 this.element.addClass("ui-draggable-disabled"); 5895 } 5896 this._setHandleClassName(); 5897 5898 this._mouseInit(); 5899 }, 5900 5901 _setOption: function( key, value ) { 5902 this._super( key, value ); 5903 if ( key === "handle" ) { 5904 this._removeHandleClassName(); 5905 this._setHandleClassName(); 5906 } 5907 }, 5908 5909 _destroy: function() { 5910 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 5911 this.destroyOnClear = true; 5912 return; 5913 } 5914 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 5915 this._removeHandleClassName(); 5916 this._mouseDestroy(); 5917 }, 5918 5919 _mouseCapture: function(event) { 5920 var o = this.options; 5921 5922 this._blurActiveElement( event ); 5923 5924 // among others, prevent a drag on a resizable-handle 5925 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 5926 return false; 5927 } 5928 5929 //Quit if we're not on a valid handle 5930 this.handle = this._getHandle(event); 5931 if (!this.handle) { 5932 return false; 5933 } 5934 5935 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 5936 5937 return true; 5938 5939 }, 5940 5941 _blockFrames: function( selector ) { 5942 this.iframeBlocks = this.document.find( selector ).map(function() { 5943 var iframe = $( this ); 5944 5945 return $( "<div>" ) 5946 .css( "position", "absolute" ) 5947 .appendTo( iframe.parent() ) 5948 .outerWidth( iframe.outerWidth() ) 5949 .outerHeight( iframe.outerHeight() ) 5950 .offset( iframe.offset() )[ 0 ]; 5951 }); 5952 }, 5953 5954 _unblockFrames: function() { 5955 if ( this.iframeBlocks ) { 5956 this.iframeBlocks.remove(); 5957 delete this.iframeBlocks; 5958 } 5959 }, 5960 5961 _blurActiveElement: function( event ) { 5962 var document = this.document[ 0 ]; 5963 5964 // Only need to blur if the event occurred on the draggable itself, see #10527 5965 if ( !this.handleElement.is( event.target ) ) { 5966 return; 5967 } 5968 5969 // support: IE9 5970 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 5971 try { 5972 5973 // Support: IE9, IE10 5974 // If the <body> is blurred, IE will switch windows, see #9520 5975 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { 5976 5977 // Blur any element that currently has focus, see #4261 5978 $( document.activeElement ).blur(); 5979 } 5980 } catch ( error ) {} 5981 }, 5982 5983 _mouseStart: function(event) { 5984 5985 var o = this.options; 5986 5987 //Create and append the visible helper 5988 this.helper = this._createHelper(event); 5989 5990 this.helper.addClass("ui-draggable-dragging"); 5991 5992 //Cache the helper size 5993 this._cacheHelperProportions(); 5994 5995 //If ddmanager is used for droppables, set the global draggable 5996 if ($.ui.ddmanager) { 5997 $.ui.ddmanager.current = this; 5998 } 5999 6000 /* 6001 * - Position generation - 6002 * This block generates everything position related - it's the core of draggables. 6003 */ 6004 6005 //Cache the margins of the original element 6006 this._cacheMargins(); 6007 6008 //Store the helper's css position 6009 this.cssPosition = this.helper.css( "position" ); 6010 this.scrollParent = this.helper.scrollParent( true ); 6011 this.offsetParent = this.helper.offsetParent(); 6012 this.hasFixedAncestor = this.helper.parents().filter(function() { 6013 return $( this ).css( "position" ) === "fixed"; 6014 }).length > 0; 6015 6016 //The element's absolute position on the page minus margins 6017 this.positionAbs = this.element.offset(); 6018 this._refreshOffsets( event ); 6019 6020 //Generate the original position 6021 this.originalPosition = this.position = this._generatePosition( event, false ); 6022 this.originalPageX = event.pageX; 6023 this.originalPageY = event.pageY; 6024 6025 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 6026 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 6027 6028 //Set a containment if given in the options 6029 this._setContainment(); 6030 6031 //Trigger event + callbacks 6032 if (this._trigger("start", event) === false) { 6033 this._clear(); 6034 return false; 6035 } 6036 6037 //Recache the helper size 6038 this._cacheHelperProportions(); 6039 6040 //Prepare the droppable offsets 6041 if ($.ui.ddmanager && !o.dropBehaviour) { 6042 $.ui.ddmanager.prepareOffsets(this, event); 6043 } 6044 6045 // Reset helper's right/bottom css if they're set and set explicit width/height instead 6046 // as this prevents resizing of elements with right/bottom set (see #7772) 6047 this._normalizeRightBottom(); 6048 6049 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 6050 6051 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 6052 if ( $.ui.ddmanager ) { 6053 $.ui.ddmanager.dragStart(this, event); 6054 } 6055 6056 return true; 6057 }, 6058 6059 _refreshOffsets: function( event ) { 6060 this.offset = { 6061 top: this.positionAbs.top - this.margins.top, 6062 left: this.positionAbs.left - this.margins.left, 6063 scroll: false, 6064 parent: this._getParentOffset(), 6065 relative: this._getRelativeOffset() 6066 }; 6067 6068 this.offset.click = { 6069 left: event.pageX - this.offset.left, 6070 top: event.pageY - this.offset.top 6071 }; 6072 }, 6073 6074 _mouseDrag: function(event, noPropagation) { 6075 // reset any necessary cached properties (see #5009) 6076 if ( this.hasFixedAncestor ) { 6077 this.offset.parent = this._getParentOffset(); 6078 } 6079 6080 //Compute the helpers position 6081 this.position = this._generatePosition( event, true ); 6082 this.positionAbs = this._convertPositionTo("absolute"); 6083 6084 //Call plugins and callbacks and use the resulting position if something is returned 6085 if (!noPropagation) { 6086 var ui = this._uiHash(); 6087 if (this._trigger("drag", event, ui) === false) { 6088 this._mouseUp({}); 6089 return false; 6090 } 6091 this.position = ui.position; 6092 } 6093 6094 this.helper[ 0 ].style.left = this.position.left + "px"; 6095 this.helper[ 0 ].style.top = this.position.top + "px"; 6096 6097 if ($.ui.ddmanager) { 6098 $.ui.ddmanager.drag(this, event); 6099 } 6100 6101 return false; 6102 }, 6103 6104 _mouseStop: function(event) { 6105 6106 //If we are using droppables, inform the manager about the drop 6107 var that = this, 6108 dropped = false; 6109 if ($.ui.ddmanager && !this.options.dropBehaviour) { 6110 dropped = $.ui.ddmanager.drop(this, event); 6111 } 6112 6113 //if a drop comes from outside (a sortable) 6114 if (this.dropped) { 6115 dropped = this.dropped; 6116 this.dropped = false; 6117 } 6118 6119 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))) { 6120 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 6121 if (that._trigger("stop", event) !== false) { 6122 that._clear(); 6123 } 6124 }); 6125 } else { 6126 if (this._trigger("stop", event) !== false) { 6127 this._clear(); 6128 } 6129 } 6130 6131 return false; 6132 }, 6133 6134 _mouseUp: function( event ) { 6135 this._unblockFrames(); 6136 6137 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 6138 if ( $.ui.ddmanager ) { 6139 $.ui.ddmanager.dragStop(this, event); 6140 } 6141 6142 // Only need to focus if the event occurred on the draggable itself, see #10527 6143 if ( this.handleElement.is( event.target ) ) { 6144 // The interaction is over; whether or not the click resulted in a drag, focus the element 6145 this.element.focus(); 6146 } 6147 6148 return $.ui.mouse.prototype._mouseUp.call(this, event); 6149 }, 6150 6151 cancel: function() { 6152 6153 if (this.helper.is(".ui-draggable-dragging")) { 6154 this._mouseUp({}); 6155 } else { 6156 this._clear(); 6157 } 6158 6159 return this; 6160 6161 }, 6162 6163 _getHandle: function(event) { 6164 return this.options.handle ? 6165 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 6166 true; 6167 }, 6168 6169 _setHandleClassName: function() { 6170 this.handleElement = this.options.handle ? 6171 this.element.find( this.options.handle ) : this.element; 6172 this.handleElement.addClass( "ui-draggable-handle" ); 6173 }, 6174 6175 _removeHandleClassName: function() { 6176 this.handleElement.removeClass( "ui-draggable-handle" ); 6177 }, 6178 6179 _createHelper: function(event) { 6180 6181 var o = this.options, 6182 helperIsFunction = $.isFunction( o.helper ), 6183 helper = helperIsFunction ? 6184 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 6185 ( o.helper === "clone" ? 6186 this.element.clone().removeAttr( "id" ) : 6187 this.element ); 6188 6189 if (!helper.parents("body").length) { 6190 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 6191 } 6192 6193 // http://bugs.jqueryui.com/ticket/9446 6194 // a helper function can return the original element 6195 // which wouldn't have been set to relative in _create 6196 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 6197 this._setPositionRelative(); 6198 } 6199 6200 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 6201 helper.css("position", "absolute"); 6202 } 6203 6204 return helper; 6205 6206 }, 6207 6208 _setPositionRelative: function() { 6209 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 6210 this.element[ 0 ].style.position = "relative"; 6211 } 6212 }, 6213 6214 _adjustOffsetFromHelper: function(obj) { 6215 if (typeof obj === "string") { 6216 obj = obj.split(" "); 6217 } 6218 if ($.isArray(obj)) { 6219 obj = { left: +obj[0], top: +obj[1] || 0 }; 6220 } 6221 if ("left" in obj) { 6222 this.offset.click.left = obj.left + this.margins.left; 6223 } 6224 if ("right" in obj) { 6225 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6226 } 6227 if ("top" in obj) { 6228 this.offset.click.top = obj.top + this.margins.top; 6229 } 6230 if ("bottom" in obj) { 6231 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6232 } 6233 }, 6234 6235 _isRootNode: function( element ) { 6236 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 6237 }, 6238 6239 _getParentOffset: function() { 6240 6241 //Get the offsetParent and cache its position 6242 var po = this.offsetParent.offset(), 6243 document = this.document[ 0 ]; 6244 6245 // This is a special case where we need to modify a offset calculated on start, since the following happened: 6246 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 6247 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 6248 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 6249 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 6250 po.left += this.scrollParent.scrollLeft(); 6251 po.top += this.scrollParent.scrollTop(); 6252 } 6253 6254 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 6255 po = { top: 0, left: 0 }; 6256 } 6257 6258 return { 6259 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 6260 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 6261 }; 6262 6263 }, 6264 6265 _getRelativeOffset: function() { 6266 if ( this.cssPosition !== "relative" ) { 6267 return { top: 0, left: 0 }; 6268 } 6269 6270 var p = this.element.position(), 6271 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6272 6273 return { 6274 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 6275 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 6276 }; 6277 6278 }, 6279 6280 _cacheMargins: function() { 6281 this.margins = { 6282 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 6283 top: (parseInt(this.element.css("marginTop"), 10) || 0), 6284 right: (parseInt(this.element.css("marginRight"), 10) || 0), 6285 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 6286 }; 6287 }, 6288 6289 _cacheHelperProportions: function() { 6290 this.helperProportions = { 6291 width: this.helper.outerWidth(), 6292 height: this.helper.outerHeight() 6293 }; 6294 }, 6295 6296 _setContainment: function() { 6297 6298 var isUserScrollable, c, ce, 6299 o = this.options, 6300 document = this.document[ 0 ]; 6301 6302 this.relativeContainer = null; 6303 6304 if ( !o.containment ) { 6305 this.containment = null; 6306 return; 6307 } 6308 6309 if ( o.containment === "window" ) { 6310 this.containment = [ 6311 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 6312 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 6313 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 6314 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6315 ]; 6316 return; 6317 } 6318 6319 if ( o.containment === "document") { 6320 this.containment = [ 6321 0, 6322 0, 6323 $( document ).width() - this.helperProportions.width - this.margins.left, 6324 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6325 ]; 6326 return; 6327 } 6328 6329 if ( o.containment.constructor === Array ) { 6330 this.containment = o.containment; 6331 return; 6332 } 6333 6334 if ( o.containment === "parent" ) { 6335 o.containment = this.helper[ 0 ].parentNode; 6336 } 6337 6338 c = $( o.containment ); 6339 ce = c[ 0 ]; 6340 6341 if ( !ce ) { 6342 return; 6343 } 6344 6345 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 6346 6347 this.containment = [ 6348 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 6349 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 6350 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 6351 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 6352 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 6353 this.helperProportions.width - 6354 this.margins.left - 6355 this.margins.right, 6356 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 6357 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 6358 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 6359 this.helperProportions.height - 6360 this.margins.top - 6361 this.margins.bottom 6362 ]; 6363 this.relativeContainer = c; 6364 }, 6365 6366 _convertPositionTo: function(d, pos) { 6367 6368 if (!pos) { 6369 pos = this.position; 6370 } 6371 6372 var mod = d === "absolute" ? 1 : -1, 6373 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6374 6375 return { 6376 top: ( 6377 pos.top + // The absolute mouse position 6378 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6379 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 6380 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) 6381 ), 6382 left: ( 6383 pos.left + // The absolute mouse position 6384 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6385 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 6386 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) 6387 ) 6388 }; 6389 6390 }, 6391 6392 _generatePosition: function( event, constrainPosition ) { 6393 6394 var containment, co, top, left, 6395 o = this.options, 6396 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 6397 pageX = event.pageX, 6398 pageY = event.pageY; 6399 6400 // Cache the scroll 6401 if ( !scrollIsRootNode || !this.offset.scroll ) { 6402 this.offset.scroll = { 6403 top: this.scrollParent.scrollTop(), 6404 left: this.scrollParent.scrollLeft() 6405 }; 6406 } 6407 6408 /* 6409 * - Position constraining - 6410 * Constrain the position to a mix of grid, containment. 6411 */ 6412 6413 // If we are not dragging yet, we won't check for options 6414 if ( constrainPosition ) { 6415 if ( this.containment ) { 6416 if ( this.relativeContainer ){ 6417 co = this.relativeContainer.offset(); 6418 containment = [ 6419 this.containment[ 0 ] + co.left, 6420 this.containment[ 1 ] + co.top, 6421 this.containment[ 2 ] + co.left, 6422 this.containment[ 3 ] + co.top 6423 ]; 6424 } else { 6425 containment = this.containment; 6426 } 6427 6428 if (event.pageX - this.offset.click.left < containment[0]) { 6429 pageX = containment[0] + this.offset.click.left; 6430 } 6431 if (event.pageY - this.offset.click.top < containment[1]) { 6432 pageY = containment[1] + this.offset.click.top; 6433 } 6434 if (event.pageX - this.offset.click.left > containment[2]) { 6435 pageX = containment[2] + this.offset.click.left; 6436 } 6437 if (event.pageY - this.offset.click.top > containment[3]) { 6438 pageY = containment[3] + this.offset.click.top; 6439 } 6440 } 6441 6442 if (o.grid) { 6443 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 6444 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 6445 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; 6446 6447 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 6448 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; 6449 } 6450 6451 if ( o.axis === "y" ) { 6452 pageX = this.originalPageX; 6453 } 6454 6455 if ( o.axis === "x" ) { 6456 pageY = this.originalPageY; 6457 } 6458 } 6459 6460 return { 6461 top: ( 6462 pageY - // The absolute mouse position 6463 this.offset.click.top - // Click offset (relative to the element) 6464 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 6465 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 6466 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 6467 ), 6468 left: ( 6469 pageX - // The absolute mouse position 6470 this.offset.click.left - // Click offset (relative to the element) 6471 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 6472 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 6473 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 6474 ) 6475 }; 6476 6477 }, 6478 6479 _clear: function() { 6480 this.helper.removeClass("ui-draggable-dragging"); 6481 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 6482 this.helper.remove(); 6483 } 6484 this.helper = null; 6485 this.cancelHelperRemoval = false; 6486 if ( this.destroyOnClear ) { 6487 this.destroy(); 6488 } 6489 }, 6490 6491 _normalizeRightBottom: function() { 6492 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { 6493 this.helper.width( this.helper.width() ); 6494 this.helper.css( "right", "auto" ); 6495 } 6496 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { 6497 this.helper.height( this.helper.height() ); 6498 this.helper.css( "bottom", "auto" ); 6499 } 6500 }, 6501 6502 // From now on bulk stuff - mainly helpers 6503 6504 _trigger: function( type, event, ui ) { 6505 ui = ui || this._uiHash(); 6506 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 6507 6508 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 6509 if ( /^(drag|start|stop)/.test( type ) ) { 6510 this.positionAbs = this._convertPositionTo( "absolute" ); 6511 ui.offset = this.positionAbs; 6512 } 6513 return $.Widget.prototype._trigger.call( this, type, event, ui ); 6514 }, 6515 6516 plugins: {}, 6517 6518 _uiHash: function() { 6519 return { 6520 helper: this.helper, 6521 position: this.position, 6522 originalPosition: this.originalPosition, 6523 offset: this.positionAbs 6524 }; 6525 } 6526 6527}); 6528 6529$.ui.plugin.add( "draggable", "connectToSortable", { 6530 start: function( event, ui, draggable ) { 6531 var uiSortable = $.extend( {}, ui, { 6532 item: draggable.element 6533 }); 6534 6535 draggable.sortables = []; 6536 $( draggable.options.connectToSortable ).each(function() { 6537 var sortable = $( this ).sortable( "instance" ); 6538 6539 if ( sortable && !sortable.options.disabled ) { 6540 draggable.sortables.push( sortable ); 6541 6542 // refreshPositions is called at drag start to refresh the containerCache 6543 // which is used in drag. This ensures it's initialized and synchronized 6544 // with any changes that might have happened on the page since initialization. 6545 sortable.refreshPositions(); 6546 sortable._trigger("activate", event, uiSortable); 6547 } 6548 }); 6549 }, 6550 stop: function( event, ui, draggable ) { 6551 var uiSortable = $.extend( {}, ui, { 6552 item: draggable.element 6553 }); 6554 6555 draggable.cancelHelperRemoval = false; 6556 6557 $.each( draggable.sortables, function() { 6558 var sortable = this; 6559 6560 if ( sortable.isOver ) { 6561 sortable.isOver = 0; 6562 6563 // Allow this sortable to handle removing the helper 6564 draggable.cancelHelperRemoval = true; 6565 sortable.cancelHelperRemoval = false; 6566 6567 // Use _storedCSS To restore properties in the sortable, 6568 // as this also handles revert (#9675) since the draggable 6569 // may have modified them in unexpected ways (#8809) 6570 sortable._storedCSS = { 6571 position: sortable.placeholder.css( "position" ), 6572 top: sortable.placeholder.css( "top" ), 6573 left: sortable.placeholder.css( "left" ) 6574 }; 6575 6576 sortable._mouseStop(event); 6577 6578 // Once drag has ended, the sortable should return to using 6579 // its original helper, not the shared helper from draggable 6580 sortable.options.helper = sortable.options._helper; 6581 } else { 6582 // Prevent this Sortable from removing the helper. 6583 // However, don't set the draggable to remove the helper 6584 // either as another connected Sortable may yet handle the removal. 6585 sortable.cancelHelperRemoval = true; 6586 6587 sortable._trigger( "deactivate", event, uiSortable ); 6588 } 6589 }); 6590 }, 6591 drag: function( event, ui, draggable ) { 6592 $.each( draggable.sortables, function() { 6593 var innermostIntersecting = false, 6594 sortable = this; 6595 6596 // Copy over variables that sortable's _intersectsWith uses 6597 sortable.positionAbs = draggable.positionAbs; 6598 sortable.helperProportions = draggable.helperProportions; 6599 sortable.offset.click = draggable.offset.click; 6600 6601 if ( sortable._intersectsWith( sortable.containerCache ) ) { 6602 innermostIntersecting = true; 6603 6604 $.each( draggable.sortables, function() { 6605 // Copy over variables that sortable's _intersectsWith uses 6606 this.positionAbs = draggable.positionAbs; 6607 this.helperProportions = draggable.helperProportions; 6608 this.offset.click = draggable.offset.click; 6609 6610 if ( this !== sortable && 6611 this._intersectsWith( this.containerCache ) && 6612 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 6613 innermostIntersecting = false; 6614 } 6615 6616 return innermostIntersecting; 6617 }); 6618 } 6619 6620 if ( innermostIntersecting ) { 6621 // If it intersects, we use a little isOver variable and set it once, 6622 // so that the move-in stuff gets fired only once. 6623 if ( !sortable.isOver ) { 6624 sortable.isOver = 1; 6625 6626 // Store draggable's parent in case we need to reappend to it later. 6627 draggable._parent = ui.helper.parent(); 6628 6629 sortable.currentItem = ui.helper 6630 .appendTo( sortable.element ) 6631 .data( "ui-sortable-item", true ); 6632 6633 // Store helper option to later restore it 6634 sortable.options._helper = sortable.options.helper; 6635 6636 sortable.options.helper = function() { 6637 return ui.helper[ 0 ]; 6638 }; 6639 6640 // Fire the start events of the sortable with our passed browser event, 6641 // and our own helper (so it doesn't create a new one) 6642 event.target = sortable.currentItem[ 0 ]; 6643 sortable._mouseCapture( event, true ); 6644 sortable._mouseStart( event, true, true ); 6645 6646 // Because the browser event is way off the new appended portlet, 6647 // modify necessary variables to reflect the changes 6648 sortable.offset.click.top = draggable.offset.click.top; 6649 sortable.offset.click.left = draggable.offset.click.left; 6650 sortable.offset.parent.left -= draggable.offset.parent.left - 6651 sortable.offset.parent.left; 6652 sortable.offset.parent.top -= draggable.offset.parent.top - 6653 sortable.offset.parent.top; 6654 6655 draggable._trigger( "toSortable", event ); 6656 6657 // Inform draggable that the helper is in a valid drop zone, 6658 // used solely in the revert option to handle "valid/invalid". 6659 draggable.dropped = sortable.element; 6660 6661 // Need to refreshPositions of all sortables in the case that 6662 // adding to one sortable changes the location of the other sortables (#9675) 6663 $.each( draggable.sortables, function() { 6664 this.refreshPositions(); 6665 }); 6666 6667 // hack so receive/update callbacks work (mostly) 6668 draggable.currentItem = draggable.element; 6669 sortable.fromOutside = draggable; 6670 } 6671 6672 if ( sortable.currentItem ) { 6673 sortable._mouseDrag( event ); 6674 // Copy the sortable's position because the draggable's can potentially reflect 6675 // a relative position, while sortable is always absolute, which the dragged 6676 // element has now become. (#8809) 6677 ui.position = sortable.position; 6678 } 6679 } else { 6680 // If it doesn't intersect with the sortable, and it intersected before, 6681 // we fake the drag stop of the sortable, but make sure it doesn't remove 6682 // the helper by using cancelHelperRemoval. 6683 if ( sortable.isOver ) { 6684 6685 sortable.isOver = 0; 6686 sortable.cancelHelperRemoval = true; 6687 6688 // Calling sortable's mouseStop would trigger a revert, 6689 // so revert must be temporarily false until after mouseStop is called. 6690 sortable.options._revert = sortable.options.revert; 6691 sortable.options.revert = false; 6692 6693 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 6694 sortable._mouseStop( event, true ); 6695 6696 // restore sortable behaviors that were modfied 6697 // when the draggable entered the sortable area (#9481) 6698 sortable.options.revert = sortable.options._revert; 6699 sortable.options.helper = sortable.options._helper; 6700 6701 if ( sortable.placeholder ) { 6702 sortable.placeholder.remove(); 6703 } 6704 6705 // Restore and recalculate the draggable's offset considering the sortable 6706 // may have modified them in unexpected ways. (#8809, #10669) 6707 ui.helper.appendTo( draggable._parent ); 6708 draggable._refreshOffsets( event ); 6709 ui.position = draggable._generatePosition( event, true ); 6710 6711 draggable._trigger( "fromSortable", event ); 6712 6713 // Inform draggable that the helper is no longer in a valid drop zone 6714 draggable.dropped = false; 6715 6716 // Need to refreshPositions of all sortables just in case removing 6717 // from one sortable changes the location of other sortables (#9675) 6718 $.each( draggable.sortables, function() { 6719 this.refreshPositions(); 6720 }); 6721 } 6722 } 6723 }); 6724 } 6725}); 6726 6727$.ui.plugin.add("draggable", "cursor", { 6728 start: function( event, ui, instance ) { 6729 var t = $( "body" ), 6730 o = instance.options; 6731 6732 if (t.css("cursor")) { 6733 o._cursor = t.css("cursor"); 6734 } 6735 t.css("cursor", o.cursor); 6736 }, 6737 stop: function( event, ui, instance ) { 6738 var o = instance.options; 6739 if (o._cursor) { 6740 $("body").css("cursor", o._cursor); 6741 } 6742 } 6743}); 6744 6745$.ui.plugin.add("draggable", "opacity", { 6746 start: function( event, ui, instance ) { 6747 var t = $( ui.helper ), 6748 o = instance.options; 6749 if (t.css("opacity")) { 6750 o._opacity = t.css("opacity"); 6751 } 6752 t.css("opacity", o.opacity); 6753 }, 6754 stop: function( event, ui, instance ) { 6755 var o = instance.options; 6756 if (o._opacity) { 6757 $(ui.helper).css("opacity", o._opacity); 6758 } 6759 } 6760}); 6761 6762$.ui.plugin.add("draggable", "scroll", { 6763 start: function( event, ui, i ) { 6764 if ( !i.scrollParentNotHidden ) { 6765 i.scrollParentNotHidden = i.helper.scrollParent( false ); 6766 } 6767 6768 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 6769 i.overflowOffset = i.scrollParentNotHidden.offset(); 6770 } 6771 }, 6772 drag: function( event, ui, i ) { 6773 6774 var o = i.options, 6775 scrolled = false, 6776 scrollParent = i.scrollParentNotHidden[ 0 ], 6777 document = i.document[ 0 ]; 6778 6779 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 6780 if ( !o.axis || o.axis !== "x" ) { 6781 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { 6782 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 6783 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 6784 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 6785 } 6786 } 6787 6788 if ( !o.axis || o.axis !== "y" ) { 6789 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { 6790 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 6791 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 6792 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 6793 } 6794 } 6795 6796 } else { 6797 6798 if (!o.axis || o.axis !== "x") { 6799 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 6800 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 6801 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 6802 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 6803 } 6804 } 6805 6806 if (!o.axis || o.axis !== "y") { 6807 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 6808 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 6809 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 6810 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 6811 } 6812 } 6813 6814 } 6815 6816 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 6817 $.ui.ddmanager.prepareOffsets(i, event); 6818 } 6819 6820 } 6821}); 6822 6823$.ui.plugin.add("draggable", "snap", { 6824 start: function( event, ui, i ) { 6825 6826 var o = i.options; 6827 6828 i.snapElements = []; 6829 6830 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 6831 var $t = $(this), 6832 $o = $t.offset(); 6833 if (this !== i.element[0]) { 6834 i.snapElements.push({ 6835 item: this, 6836 width: $t.outerWidth(), height: $t.outerHeight(), 6837 top: $o.top, left: $o.left 6838 }); 6839 } 6840 }); 6841 6842 }, 6843 drag: function( event, ui, inst ) { 6844 6845 var ts, bs, ls, rs, l, r, t, b, i, first, 6846 o = inst.options, 6847 d = o.snapTolerance, 6848 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 6849 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 6850 6851 for (i = inst.snapElements.length - 1; i >= 0; i--){ 6852 6853 l = inst.snapElements[i].left - inst.margins.left; 6854 r = l + inst.snapElements[i].width; 6855 t = inst.snapElements[i].top - inst.margins.top; 6856 b = t + inst.snapElements[i].height; 6857 6858 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 6859 if (inst.snapElements[i].snapping) { 6860 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6861 } 6862 inst.snapElements[i].snapping = false; 6863 continue; 6864 } 6865 6866 if (o.snapMode !== "inner") { 6867 ts = Math.abs(t - y2) <= d; 6868 bs = Math.abs(b - y1) <= d; 6869 ls = Math.abs(l - x2) <= d; 6870 rs = Math.abs(r - x1) <= d; 6871 if (ts) { 6872 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; 6873 } 6874 if (bs) { 6875 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; 6876 } 6877 if (ls) { 6878 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; 6879 } 6880 if (rs) { 6881 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; 6882 } 6883 } 6884 6885 first = (ts || bs || ls || rs); 6886 6887 if (o.snapMode !== "outer") { 6888 ts = Math.abs(t - y1) <= d; 6889 bs = Math.abs(b - y2) <= d; 6890 ls = Math.abs(l - x1) <= d; 6891 rs = Math.abs(r - x2) <= d; 6892 if (ts) { 6893 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; 6894 } 6895 if (bs) { 6896 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; 6897 } 6898 if (ls) { 6899 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; 6900 } 6901 if (rs) { 6902 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; 6903 } 6904 } 6905 6906 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 6907 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 6908 } 6909 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 6910 6911 } 6912 6913 } 6914}); 6915 6916$.ui.plugin.add("draggable", "stack", { 6917 start: function( event, ui, instance ) { 6918 var min, 6919 o = instance.options, 6920 group = $.makeArray($(o.stack)).sort(function(a, b) { 6921 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 6922 }); 6923 6924 if (!group.length) { return; } 6925 6926 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 6927 $(group).each(function(i) { 6928 $(this).css("zIndex", min + i); 6929 }); 6930 this.css("zIndex", (min + group.length)); 6931 } 6932}); 6933 6934$.ui.plugin.add("draggable", "zIndex", { 6935 start: function( event, ui, instance ) { 6936 var t = $( ui.helper ), 6937 o = instance.options; 6938 6939 if (t.css("zIndex")) { 6940 o._zIndex = t.css("zIndex"); 6941 } 6942 t.css("zIndex", o.zIndex); 6943 }, 6944 stop: function( event, ui, instance ) { 6945 var o = instance.options; 6946 6947 if (o._zIndex) { 6948 $(ui.helper).css("zIndex", o._zIndex); 6949 } 6950 } 6951}); 6952 6953var draggable = $.ui.draggable; 6954 6955 6956/*! 6957 * jQuery UI Resizable 1.11.4 6958 * http://jqueryui.com 6959 * 6960 * Copyright jQuery Foundation and other contributors 6961 * Released under the MIT license. 6962 * http://jquery.org/license 6963 * 6964 * http://api.jqueryui.com/resizable/ 6965 */ 6966 6967 6968$.widget("ui.resizable", $.ui.mouse, { 6969 version: "1.11.4", 6970 widgetEventPrefix: "resize", 6971 options: { 6972 alsoResize: false, 6973 animate: false, 6974 animateDuration: "slow", 6975 animateEasing: "swing", 6976 aspectRatio: false, 6977 autoHide: false, 6978 containment: false, 6979 ghost: false, 6980 grid: false, 6981 handles: "e,s,se", 6982 helper: false, 6983 maxHeight: null, 6984 maxWidth: null, 6985 minHeight: 10, 6986 minWidth: 10, 6987 // See #7960 6988 zIndex: 90, 6989 6990 // callbacks 6991 resize: null, 6992 start: null, 6993 stop: null 6994 }, 6995 6996 _num: function( value ) { 6997 return parseInt( value, 10 ) || 0; 6998 }, 6999 7000 _isNumber: function( value ) { 7001 return !isNaN( parseInt( value, 10 ) ); 7002 }, 7003 7004 _hasScroll: function( el, a ) { 7005 7006 if ( $( el ).css( "overflow" ) === "hidden") { 7007 return false; 7008 } 7009 7010 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 7011 has = false; 7012 7013 if ( el[ scroll ] > 0 ) { 7014 return true; 7015 } 7016 7017 // TODO: determine which cases actually cause this to happen 7018 // if the element doesn't have the scroll set, see if it's possible to 7019 // set the scroll 7020 el[ scroll ] = 1; 7021 has = ( el[ scroll ] > 0 ); 7022 el[ scroll ] = 0; 7023 return has; 7024 }, 7025 7026 _create: function() { 7027 7028 var n, i, handle, axis, hname, 7029 that = this, 7030 o = this.options; 7031 this.element.addClass("ui-resizable"); 7032 7033 $.extend(this, { 7034 _aspectRatio: !!(o.aspectRatio), 7035 aspectRatio: o.aspectRatio, 7036 originalElement: this.element, 7037 _proportionallyResizeElements: [], 7038 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 7039 }); 7040 7041 // Wrap the element if it cannot hold child nodes 7042 if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) { 7043 7044 this.element.wrap( 7045 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 7046 position: this.element.css("position"), 7047 width: this.element.outerWidth(), 7048 height: this.element.outerHeight(), 7049 top: this.element.css("top"), 7050 left: this.element.css("left") 7051 }) 7052 ); 7053 7054 this.element = this.element.parent().data( 7055 "ui-resizable", this.element.resizable( "instance" ) 7056 ); 7057 7058 this.elementIsWrapper = true; 7059 7060 this.element.css({ 7061 marginLeft: this.originalElement.css("marginLeft"), 7062 marginTop: this.originalElement.css("marginTop"), 7063 marginRight: this.originalElement.css("marginRight"), 7064 marginBottom: this.originalElement.css("marginBottom") 7065 }); 7066 this.originalElement.css({ 7067 marginLeft: 0, 7068 marginTop: 0, 7069 marginRight: 0, 7070 marginBottom: 0 7071 }); 7072 // support: Safari 7073 // Prevent Safari textarea resize 7074 this.originalResizeStyle = this.originalElement.css("resize"); 7075 this.originalElement.css("resize", "none"); 7076 7077 this._proportionallyResizeElements.push( this.originalElement.css({ 7078 position: "static", 7079 zoom: 1, 7080 display: "block" 7081 }) ); 7082 7083 // support: IE9 7084 // avoid IE jump (hard set the margin) 7085 this.originalElement.css({ margin: this.originalElement.css("margin") }); 7086 7087 this._proportionallyResize(); 7088 } 7089 7090 this.handles = o.handles || 7091 ( !$(".ui-resizable-handle", this.element).length ? 7092 "e,s,se" : { 7093 n: ".ui-resizable-n", 7094 e: ".ui-resizable-e", 7095 s: ".ui-resizable-s", 7096 w: ".ui-resizable-w", 7097 se: ".ui-resizable-se", 7098 sw: ".ui-resizable-sw", 7099 ne: ".ui-resizable-ne", 7100 nw: ".ui-resizable-nw" 7101 } ); 7102 7103 this._handles = $(); 7104 if ( this.handles.constructor === String ) { 7105 7106 if ( this.handles === "all") { 7107 this.handles = "n,e,s,w,se,sw,ne,nw"; 7108 } 7109 7110 n = this.handles.split(","); 7111 this.handles = {}; 7112 7113 for (i = 0; i < n.length; i++) { 7114 7115 handle = $.trim(n[i]); 7116 hname = "ui-resizable-" + handle; 7117 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 7118 7119 axis.css({ zIndex: o.zIndex }); 7120 7121 // TODO : What's going on here? 7122 if ("se" === handle) { 7123 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 7124 } 7125 7126 this.handles[handle] = ".ui-resizable-" + handle; 7127 this.element.append(axis); 7128 } 7129 7130 } 7131 7132 this._renderAxis = function(target) { 7133 7134 var i, axis, padPos, padWrapper; 7135 7136 target = target || this.element; 7137 7138 for (i in this.handles) { 7139 7140 if (this.handles[i].constructor === String) { 7141 this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); 7142 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 7143 this.handles[ i ] = $( this.handles[ i ] ); 7144 this._on( this.handles[ i ], { "mousedown": that._mouseDown }); 7145 } 7146 7147 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) { 7148 7149 axis = $(this.handles[i], this.element); 7150 7151 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 7152 7153 padPos = [ "padding", 7154 /ne|nw|n/.test(i) ? "Top" : 7155 /se|sw|s/.test(i) ? "Bottom" : 7156 /^e$/.test(i) ? "Right" : "Left" ].join(""); 7157 7158 target.css(padPos, padWrapper); 7159 7160 this._proportionallyResize(); 7161 } 7162 7163 this._handles = this._handles.add( this.handles[ i ] ); 7164 } 7165 }; 7166 7167 // TODO: make renderAxis a prototype function 7168 this._renderAxis(this.element); 7169 7170 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 7171 this._handles.disableSelection(); 7172 7173 this._handles.mouseover(function() { 7174 if (!that.resizing) { 7175 if (this.className) { 7176 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 7177 } 7178 that.axis = axis && axis[1] ? axis[1] : "se"; 7179 } 7180 }); 7181 7182 if (o.autoHide) { 7183 this._handles.hide(); 7184 $(this.element) 7185 .addClass("ui-resizable-autohide") 7186 .mouseenter(function() { 7187 if (o.disabled) { 7188 return; 7189 } 7190 $(this).removeClass("ui-resizable-autohide"); 7191 that._handles.show(); 7192 }) 7193 .mouseleave(function() { 7194 if (o.disabled) { 7195 return; 7196 } 7197 if (!that.resizing) { 7198 $(this).addClass("ui-resizable-autohide"); 7199 that._handles.hide(); 7200 } 7201 }); 7202 } 7203 7204 this._mouseInit(); 7205 }, 7206 7207 _destroy: function() { 7208 7209 this._mouseDestroy(); 7210 7211 var wrapper, 7212 _destroy = function(exp) { 7213 $(exp) 7214 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 7215 .removeData("resizable") 7216 .removeData("ui-resizable") 7217 .unbind(".resizable") 7218 .find(".ui-resizable-handle") 7219 .remove(); 7220 }; 7221 7222 // TODO: Unwrap at same DOM position 7223 if (this.elementIsWrapper) { 7224 _destroy(this.element); 7225 wrapper = this.element; 7226 this.originalElement.css({ 7227 position: wrapper.css("position"), 7228 width: wrapper.outerWidth(), 7229 height: wrapper.outerHeight(), 7230 top: wrapper.css("top"), 7231 left: wrapper.css("left") 7232 }).insertAfter( wrapper ); 7233 wrapper.remove(); 7234 } 7235 7236 this.originalElement.css("resize", this.originalResizeStyle); 7237 _destroy(this.originalElement); 7238 7239 return this; 7240 }, 7241 7242 _mouseCapture: function(event) { 7243 var i, handle, 7244 capture = false; 7245 7246 for (i in this.handles) { 7247 handle = $(this.handles[i])[0]; 7248 if (handle === event.target || $.contains(handle, event.target)) { 7249 capture = true; 7250 } 7251 } 7252 7253 return !this.options.disabled && capture; 7254 }, 7255 7256 _mouseStart: function(event) { 7257 7258 var curleft, curtop, cursor, 7259 o = this.options, 7260 el = this.element; 7261 7262 this.resizing = true; 7263 7264 this._renderProxy(); 7265 7266 curleft = this._num(this.helper.css("left")); 7267 curtop = this._num(this.helper.css("top")); 7268 7269 if (o.containment) { 7270 curleft += $(o.containment).scrollLeft() || 0; 7271 curtop += $(o.containment).scrollTop() || 0; 7272 } 7273 7274 this.offset = this.helper.offset(); 7275 this.position = { left: curleft, top: curtop }; 7276 7277 this.size = this._helper ? { 7278 width: this.helper.width(), 7279 height: this.helper.height() 7280 } : { 7281 width: el.width(), 7282 height: el.height() 7283 }; 7284 7285 this.originalSize = this._helper ? { 7286 width: el.outerWidth(), 7287 height: el.outerHeight() 7288 } : { 7289 width: el.width(), 7290 height: el.height() 7291 }; 7292 7293 this.sizeDiff = { 7294 width: el.outerWidth() - el.width(), 7295 height: el.outerHeight() - el.height() 7296 }; 7297 7298 this.originalPosition = { left: curleft, top: curtop }; 7299 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 7300 7301 this.aspectRatio = (typeof o.aspectRatio === "number") ? 7302 o.aspectRatio : 7303 ((this.originalSize.width / this.originalSize.height) || 1); 7304 7305 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 7306 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 7307 7308 el.addClass("ui-resizable-resizing"); 7309 this._propagate("start", event); 7310 return true; 7311 }, 7312 7313 _mouseDrag: function(event) { 7314 7315 var data, props, 7316 smp = this.originalMousePosition, 7317 a = this.axis, 7318 dx = (event.pageX - smp.left) || 0, 7319 dy = (event.pageY - smp.top) || 0, 7320 trigger = this._change[a]; 7321 7322 this._updatePrevProperties(); 7323 7324 if (!trigger) { 7325 return false; 7326 } 7327 7328 data = trigger.apply(this, [ event, dx, dy ]); 7329 7330 this._updateVirtualBoundaries(event.shiftKey); 7331 if (this._aspectRatio || event.shiftKey) { 7332 data = this._updateRatio(data, event); 7333 } 7334 7335 data = this._respectSize(data, event); 7336 7337 this._updateCache(data); 7338 7339 this._propagate("resize", event); 7340 7341 props = this._applyChanges(); 7342 7343 if ( !this._helper && this._proportionallyResizeElements.length ) { 7344 this._proportionallyResize(); 7345 } 7346 7347 if ( !$.isEmptyObject( props ) ) { 7348 this._updatePrevProperties(); 7349 this._trigger( "resize", event, this.ui() ); 7350 this._applyChanges(); 7351 } 7352 7353 return false;
vendor: 10,889 bytes, lines 7354-7783
7354 }, 7355 7356 _mouseStop: function(event) { 7357 7358 this.resizing = false; 7359 var pr, ista, soffseth, soffsetw, s, left, top, 7360 o = this.options, that = this; 7361 7362 if (this._helper) { 7363 7364 pr = this._proportionallyResizeElements; 7365 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 7366 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; 7367 soffsetw = ista ? 0 : that.sizeDiff.width; 7368 7369 s = { 7370 width: (that.helper.width() - soffsetw), 7371 height: (that.helper.height() - soffseth) 7372 }; 7373 left = (parseInt(that.element.css("left"), 10) + 7374 (that.position.left - that.originalPosition.left)) || null; 7375 top = (parseInt(that.element.css("top"), 10) + 7376 (that.position.top - that.originalPosition.top)) || null; 7377 7378 if (!o.animate) { 7379 this.element.css($.extend(s, { top: top, left: left })); 7380 } 7381 7382 that.helper.height(that.size.height); 7383 that.helper.width(that.size.width); 7384 7385 if (this._helper && !o.animate) { 7386 this._proportionallyResize(); 7387 } 7388 } 7389 7390 $("body").css("cursor", "auto"); 7391 7392 this.element.removeClass("ui-resizable-resizing"); 7393 7394 this._propagate("stop", event); 7395 7396 if (this._helper) { 7397 this.helper.remove(); 7398 } 7399 7400 return false; 7401 7402 }, 7403 7404 _updatePrevProperties: function() { 7405 this.prevPosition = { 7406 top: this.position.top, 7407 left: this.position.left 7408 }; 7409 this.prevSize = { 7410 width: this.size.width, 7411 height: this.size.height 7412 }; 7413 }, 7414 7415 _applyChanges: function() { 7416 var props = {}; 7417 7418 if ( this.position.top !== this.prevPosition.top ) { 7419 props.top = this.position.top + "px"; 7420 } 7421 if ( this.position.left !== this.prevPosition.left ) { 7422 props.left = this.position.left + "px"; 7423 } 7424 if ( this.size.width !== this.prevSize.width ) { 7425 props.width = this.size.width + "px"; 7426 } 7427 if ( this.size.height !== this.prevSize.height ) { 7428 props.height = this.size.height + "px"; 7429 } 7430 7431 this.helper.css( props ); 7432 7433 return props; 7434 }, 7435 7436 _updateVirtualBoundaries: function(forceAspectRatio) { 7437 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 7438 o = this.options; 7439 7440 b = { 7441 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, 7442 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, 7443 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, 7444 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity 7445 }; 7446 7447 if (this._aspectRatio || forceAspectRatio) { 7448 pMinWidth = b.minHeight * this.aspectRatio; 7449 pMinHeight = b.minWidth / this.aspectRatio; 7450 pMaxWidth = b.maxHeight * this.aspectRatio; 7451 pMaxHeight = b.maxWidth / this.aspectRatio; 7452 7453 if (pMinWidth > b.minWidth) { 7454 b.minWidth = pMinWidth; 7455 } 7456 if (pMinHeight > b.minHeight) { 7457 b.minHeight = pMinHeight; 7458 } 7459 if (pMaxWidth < b.maxWidth) { 7460 b.maxWidth = pMaxWidth; 7461 } 7462 if (pMaxHeight < b.maxHeight) { 7463 b.maxHeight = pMaxHeight; 7464 } 7465 } 7466 this._vBoundaries = b; 7467 }, 7468 7469 _updateCache: function(data) { 7470 this.offset = this.helper.offset(); 7471 if (this._isNumber(data.left)) { 7472 this.position.left = data.left; 7473 } 7474 if (this._isNumber(data.top)) { 7475 this.position.top = data.top; 7476 } 7477 if (this._isNumber(data.height)) { 7478 this.size.height = data.height; 7479 } 7480 if (this._isNumber(data.width)) { 7481 this.size.width = data.width; 7482 } 7483 }, 7484 7485 _updateRatio: function( data ) { 7486 7487 var cpos = this.position, 7488 csize = this.size, 7489 a = this.axis; 7490 7491 if (this._isNumber(data.height)) { 7492 data.width = (data.height * this.aspectRatio); 7493 } else if (this._isNumber(data.width)) { 7494 data.height = (data.width / this.aspectRatio); 7495 } 7496 7497 if (a === "sw") { 7498 data.left = cpos.left + (csize.width - data.width); 7499 data.top = null; 7500 } 7501 if (a === "nw") { 7502 data.top = cpos.top + (csize.height - data.height); 7503 data.left = cpos.left + (csize.width - data.width); 7504 } 7505 7506 return data; 7507 }, 7508 7509 _respectSize: function( data ) { 7510 7511 var o = this._vBoundaries, 7512 a = this.axis, 7513 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), 7514 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 7515 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), 7516 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 7517 dw = this.originalPosition.left + this.originalSize.width, 7518 dh = this.position.top + this.size.height, 7519 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 7520 if (isminw) { 7521 data.width = o.minWidth; 7522 } 7523 if (isminh) { 7524 data.height = o.minHeight; 7525 } 7526 if (ismaxw) { 7527 data.width = o.maxWidth; 7528 } 7529 if (ismaxh) { 7530 data.height = o.maxHeight; 7531 } 7532 7533 if (isminw && cw) { 7534 data.left = dw - o.minWidth; 7535 } 7536 if (ismaxw && cw) { 7537 data.left = dw - o.maxWidth; 7538 } 7539 if (isminh && ch) { 7540 data.top = dh - o.minHeight; 7541 } 7542 if (ismaxh && ch) { 7543 data.top = dh - o.maxHeight; 7544 } 7545 7546 // Fixing jump error on top/left - bug #2330 7547 if (!data.width && !data.height && !data.left && data.top) { 7548 data.top = null; 7549 } else if (!data.width && !data.height && !data.top && data.left) { 7550 data.left = null; 7551 } 7552 7553 return data; 7554 }, 7555 7556 _getPaddingPlusBorderDimensions: function( element ) { 7557 var i = 0, 7558 widths = [], 7559 borders = [ 7560 element.css( "borderTopWidth" ), 7561 element.css( "borderRightWidth" ), 7562 element.css( "borderBottomWidth" ), 7563 element.css( "borderLeftWidth" ) 7564 ], 7565 paddings = [ 7566 element.css( "paddingTop" ), 7567 element.css( "paddingRight" ), 7568 element.css( "paddingBottom" ), 7569 element.css( "paddingLeft" ) 7570 ]; 7571 7572 for ( ; i < 4; i++ ) { 7573 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); 7574 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); 7575 } 7576 7577 return { 7578 height: widths[ 0 ] + widths[ 2 ], 7579 width: widths[ 1 ] + widths[ 3 ] 7580 }; 7581 }, 7582 7583 _proportionallyResize: function() { 7584 7585 if (!this._proportionallyResizeElements.length) { 7586 return; 7587 } 7588 7589 var prel, 7590 i = 0, 7591 element = this.helper || this.element; 7592 7593 for ( ; i < this._proportionallyResizeElements.length; i++) { 7594 7595 prel = this._proportionallyResizeElements[i]; 7596 7597 // TODO: Seems like a bug to cache this.outerDimensions 7598 // considering that we are in a loop. 7599 if (!this.outerDimensions) { 7600 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 7601 } 7602 7603 prel.css({ 7604 height: (element.height() - this.outerDimensions.height) || 0, 7605 width: (element.width() - this.outerDimensions.width) || 0 7606 }); 7607 7608 } 7609 7610 }, 7611 7612 _renderProxy: function() { 7613 7614 var el = this.element, o = this.options; 7615 this.elementOffset = el.offset(); 7616 7617 if (this._helper) { 7618 7619 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 7620 7621 this.helper.addClass(this._helper).css({ 7622 width: this.element.outerWidth() - 1, 7623 height: this.element.outerHeight() - 1, 7624 position: "absolute", 7625 left: this.elementOffset.left + "px", 7626 top: this.elementOffset.top + "px", 7627 zIndex: ++o.zIndex //TODO: Don't modify option 7628 }); 7629 7630 this.helper 7631 .appendTo("body") 7632 .disableSelection(); 7633 7634 } else { 7635 this.helper = this.element; 7636 } 7637 7638 }, 7639 7640 _change: { 7641 e: function(event, dx) { 7642 return { width: this.originalSize.width + dx }; 7643 }, 7644 w: function(event, dx) { 7645 var cs = this.originalSize, sp = this.originalPosition; 7646 return { left: sp.left + dx, width: cs.width - dx }; 7647 }, 7648 n: function(event, dx, dy) { 7649 var cs = this.originalSize, sp = this.originalPosition; 7650 return { top: sp.top + dy, height: cs.height - dy }; 7651 }, 7652 s: function(event, dx, dy) { 7653 return { height: this.originalSize.height + dy }; 7654 }, 7655 se: function(event, dx, dy) { 7656 return $.extend(this._change.s.apply(this, arguments), 7657 this._change.e.apply(this, [ event, dx, dy ])); 7658 }, 7659 sw: function(event, dx, dy) { 7660 return $.extend(this._change.s.apply(this, arguments), 7661 this._change.w.apply(this, [ event, dx, dy ])); 7662 }, 7663 ne: function(event, dx, dy) { 7664 return $.extend(this._change.n.apply(this, arguments), 7665 this._change.e.apply(this, [ event, dx, dy ])); 7666 }, 7667 nw: function(event, dx, dy) { 7668 return $.extend(this._change.n.apply(this, arguments), 7669 this._change.w.apply(this, [ event, dx, dy ])); 7670 } 7671 }, 7672 7673 _propagate: function(n, event) { 7674 $.ui.plugin.call(this, n, [ event, this.ui() ]); 7675 (n !== "resize" && this._trigger(n, event, this.ui())); 7676 }, 7677 7678 plugins: {}, 7679 7680 ui: function() { 7681 return { 7682 originalElement: this.originalElement, 7683 element: this.element, 7684 helper: this.helper, 7685 position: this.position, 7686 size: this.size, 7687 originalSize: this.originalSize, 7688 originalPosition: this.originalPosition 7689 }; 7690 } 7691 7692}); 7693 7694/* 7695 * Resizable Extensions 7696 */ 7697 7698$.ui.plugin.add("resizable", "animate", { 7699 7700 stop: function( event ) { 7701 var that = $(this).resizable( "instance" ), 7702 o = that.options, 7703 pr = that._proportionallyResizeElements, 7704 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 7705 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, 7706 soffsetw = ista ? 0 : that.sizeDiff.width, 7707 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 7708 left = (parseInt(that.element.css("left"), 10) + 7709 (that.position.left - that.originalPosition.left)) || null, 7710 top = (parseInt(that.element.css("top"), 10) + 7711 (that.position.top - that.originalPosition.top)) || null; 7712 7713 that.element.animate( 7714 $.extend(style, top && left ? { top: top, left: left } : {}), { 7715 duration: o.animateDuration, 7716 easing: o.animateEasing, 7717 step: function() { 7718 7719 var data = { 7720 width: parseInt(that.element.css("width"), 10), 7721 height: parseInt(that.element.css("height"), 10), 7722 top: parseInt(that.element.css("top"), 10), 7723 left: parseInt(that.element.css("left"), 10) 7724 }; 7725 7726 if (pr && pr.length) { 7727 $(pr[0]).css({ width: data.width, height: data.height }); 7728 } 7729 7730 // propagating resize, and updating values for each animation step 7731 that._updateCache(data); 7732 that._propagate("resize", event); 7733 7734 } 7735 } 7736 ); 7737 } 7738 7739}); 7740 7741$.ui.plugin.add( "resizable", "containment", { 7742 7743 start: function() { 7744 var element, p, co, ch, cw, width, height, 7745 that = $( this ).resizable( "instance" ), 7746 o = that.options, 7747 el = that.element, 7748 oc = o.containment, 7749 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 7750 7751 if ( !ce ) { 7752 return; 7753 } 7754 7755 that.containerElement = $( ce ); 7756 7757 if ( /document/.test( oc ) || oc === document ) { 7758 that.containerOffset = { 7759 left: 0, 7760 top: 0 7761 }; 7762 that.containerPosition = { 7763 left: 0, 7764 top: 0 7765 }; 7766 7767 that.parentData = { 7768 element: $( document ), 7769 left: 0, 7770 top: 0, 7771 width: $( document ).width(), 7772 height: $( document ).height() || document.body.parentNode.scrollHeight 7773 }; 7774 } else { 7775 element = $( ce ); 7776 p = []; 7777 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { 7778 p[ i ] = that._num( element.css( "padding" + name ) ); 7779 }); 7780 7781 that.containerOffset = element.offset(); 7782 that.containerPosition = element.position(); 7783 that.containerSize = {
vendor: 8,405 bytes, lines 7784-8118
7784 height: ( element.innerHeight() - p[ 3 ] ), 7785 width: ( element.innerWidth() - p[ 1 ] ) 7786 }; 7787 7788 co = that.containerOffset; 7789 ch = that.containerSize.height; 7790 cw = that.containerSize.width; 7791 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 7792 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 7793 7794 that.parentData = { 7795 element: ce, 7796 left: co.left, 7797 top: co.top, 7798 width: width, 7799 height: height 7800 }; 7801 } 7802 }, 7803 7804 resize: function( event ) { 7805 var woset, hoset, isParent, isOffsetRelative, 7806 that = $( this ).resizable( "instance" ), 7807 o = that.options, 7808 co = that.containerOffset, 7809 cp = that.position, 7810 pRatio = that._aspectRatio || event.shiftKey, 7811 cop = { 7812 top: 0, 7813 left: 0 7814 }, 7815 ce = that.containerElement, 7816 continueResize = true; 7817 7818 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 7819 cop = co; 7820 } 7821 7822 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 7823 that.size.width = that.size.width + 7824 ( that._helper ? 7825 ( that.position.left - co.left ) : 7826 ( that.position.left - cop.left ) ); 7827 7828 if ( pRatio ) { 7829 that.size.height = that.size.width / that.aspectRatio; 7830 continueResize = false; 7831 } 7832 that.position.left = o.helper ? co.left : 0; 7833 } 7834 7835 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 7836 that.size.height = that.size.height + 7837 ( that._helper ? 7838 ( that.position.top - co.top ) : 7839 that.position.top ); 7840 7841 if ( pRatio ) { 7842 that.size.width = that.size.height * that.aspectRatio; 7843 continueResize = false; 7844 } 7845 that.position.top = that._helper ? co.top : 0; 7846 } 7847 7848 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 7849 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 7850 7851 if ( isParent && isOffsetRelative ) { 7852 that.offset.left = that.parentData.left + that.position.left; 7853 that.offset.top = that.parentData.top + that.position.top; 7854 } else { 7855 that.offset.left = that.element.offset().left; 7856 that.offset.top = that.element.offset().top; 7857 } 7858 7859 woset = Math.abs( that.sizeDiff.width + 7860 (that._helper ? 7861 that.offset.left - cop.left : 7862 (that.offset.left - co.left)) ); 7863 7864 hoset = Math.abs( that.sizeDiff.height + 7865 (that._helper ? 7866 that.offset.top - cop.top : 7867 (that.offset.top - co.top)) ); 7868 7869 if ( woset + that.size.width >= that.parentData.width ) { 7870 that.size.width = that.parentData.width - woset; 7871 if ( pRatio ) { 7872 that.size.height = that.size.width / that.aspectRatio; 7873 continueResize = false; 7874 } 7875 } 7876 7877 if ( hoset + that.size.height >= that.parentData.height ) { 7878 that.size.height = that.parentData.height - hoset; 7879 if ( pRatio ) { 7880 that.size.width = that.size.height * that.aspectRatio; 7881 continueResize = false; 7882 } 7883 } 7884 7885 if ( !continueResize ) { 7886 that.position.left = that.prevPosition.left; 7887 that.position.top = that.prevPosition.top; 7888 that.size.width = that.prevSize.width; 7889 that.size.height = that.prevSize.height; 7890 } 7891 }, 7892 7893 stop: function() { 7894 var that = $( this ).resizable( "instance" ), 7895 o = that.options, 7896 co = that.containerOffset, 7897 cop = that.containerPosition, 7898 ce = that.containerElement, 7899 helper = $( that.helper ), 7900 ho = helper.offset(), 7901 w = helper.outerWidth() - that.sizeDiff.width, 7902 h = helper.outerHeight() - that.sizeDiff.height; 7903 7904 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 7905 $( this ).css({ 7906 left: ho.left - cop.left - co.left, 7907 width: w, 7908 height: h 7909 }); 7910 } 7911 7912 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 7913 $( this ).css({ 7914 left: ho.left - cop.left - co.left, 7915 width: w, 7916 height: h 7917 }); 7918 } 7919 } 7920}); 7921 7922$.ui.plugin.add("resizable", "alsoResize", { 7923 7924 start: function() { 7925 var that = $(this).resizable( "instance" ), 7926 o = that.options; 7927 7928 $(o.alsoResize).each(function() { 7929 var el = $(this); 7930 el.data("ui-resizable-alsoresize", { 7931 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 7932 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 7933 }); 7934 }); 7935 }, 7936 7937 resize: function(event, ui) { 7938 var that = $(this).resizable( "instance" ), 7939 o = that.options, 7940 os = that.originalSize, 7941 op = that.originalPosition, 7942 delta = { 7943 height: (that.size.height - os.height) || 0, 7944 width: (that.size.width - os.width) || 0, 7945 top: (that.position.top - op.top) || 0, 7946 left: (that.position.left - op.left) || 0 7947 }; 7948 7949 $(o.alsoResize).each(function() { 7950 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 7951 css = el.parents(ui.originalElement[0]).length ? 7952 [ "width", "height" ] : 7953 [ "width", "height", "top", "left" ]; 7954 7955 $.each(css, function(i, prop) { 7956 var sum = (start[prop] || 0) + (delta[prop] || 0); 7957 if (sum && sum >= 0) { 7958 style[prop] = sum || null; 7959 } 7960 }); 7961 7962 el.css(style); 7963 }); 7964 }, 7965 7966 stop: function() { 7967 $(this).removeData("resizable-alsoresize"); 7968 } 7969}); 7970 7971$.ui.plugin.add("resizable", "ghost", { 7972 7973 start: function() { 7974 7975 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; 7976 7977 that.ghost = that.originalElement.clone(); 7978 that.ghost 7979 .css({ 7980 opacity: 0.25, 7981 display: "block", 7982 position: "relative", 7983 height: cs.height, 7984 width: cs.width, 7985 margin: 0, 7986 left: 0, 7987 top: 0 7988 }) 7989 .addClass("ui-resizable-ghost") 7990 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 7991 7992 that.ghost.appendTo(that.helper); 7993 7994 }, 7995 7996 resize: function() { 7997 var that = $(this).resizable( "instance" ); 7998 if (that.ghost) { 7999 that.ghost.css({ 8000 position: "relative", 8001 height: that.size.height, 8002 width: that.size.width 8003 }); 8004 } 8005 }, 8006 8007 stop: function() { 8008 var that = $(this).resizable( "instance" ); 8009 if (that.ghost && that.helper) { 8010 that.helper.get(0).removeChild(that.ghost.get(0)); 8011 } 8012 } 8013 8014}); 8015 8016$.ui.plugin.add("resizable", "grid", { 8017 8018 resize: function() { 8019 var outerDimensions, 8020 that = $(this).resizable( "instance" ), 8021 o = that.options, 8022 cs = that.size, 8023 os = that.originalSize, 8024 op = that.originalPosition, 8025 a = that.axis, 8026 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 8027 gridX = (grid[0] || 1), 8028 gridY = (grid[1] || 1), 8029 ox = Math.round((cs.width - os.width) / gridX) * gridX, 8030 oy = Math.round((cs.height - os.height) / gridY) * gridY, 8031 newWidth = os.width + ox, 8032 newHeight = os.height + oy, 8033 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 8034 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 8035 isMinWidth = o.minWidth && (o.minWidth > newWidth), 8036 isMinHeight = o.minHeight && (o.minHeight > newHeight); 8037 8038 o.grid = grid; 8039 8040 if (isMinWidth) { 8041 newWidth += gridX; 8042 } 8043 if (isMinHeight) { 8044 newHeight += gridY; 8045 } 8046 if (isMaxWidth) { 8047 newWidth -= gridX; 8048 } 8049 if (isMaxHeight) { 8050 newHeight -= gridY; 8051 } 8052 8053 if (/^(se|s|e)$/.test(a)) { 8054 that.size.width = newWidth; 8055 that.size.height = newHeight; 8056 } else if (/^(ne)$/.test(a)) { 8057 that.size.width = newWidth; 8058 that.size.height = newHeight; 8059 that.position.top = op.top - oy; 8060 } else if (/^(sw)$/.test(a)) { 8061 that.size.width = newWidth; 8062 that.size.height = newHeight; 8063 that.position.left = op.left - ox; 8064 } else { 8065 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { 8066 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 8067 } 8068 8069 if ( newHeight - gridY > 0 ) { 8070 that.size.height = newHeight; 8071 that.position.top = op.top - oy; 8072 } else { 8073 newHeight = gridY - outerDimensions.height; 8074 that.size.height = newHeight; 8075 that.position.top = op.top + os.height - newHeight; 8076 } 8077 if ( newWidth - gridX > 0 ) { 8078 that.size.width = newWidth; 8079 that.position.left = op.left - ox; 8080 } else { 8081 newWidth = gridX - outerDimensions.width; 8082 that.size.width = newWidth; 8083 that.position.left = op.left + os.width - newWidth; 8084 } 8085 } 8086 } 8087 8088}); 8089 8090var resizable = $.ui.resizable; 8091 8092 8093/*! 8094 * jQuery UI Dialog 1.11.4 8095 * http://jqueryui.com 8096 * 8097 * Copyright jQuery Foundation and other contributors 8098 * Released under the MIT license. 8099 * http://jquery.org/license 8100 * 8101 * http://api.jqueryui.com/dialog/ 8102 */ 8103 8104 8105var dialog = $.widget( "ui.dialog", { 8106 version: "1.11.4", 8107 options: { 8108 appendTo: "body", 8109 autoOpen: true, 8110 buttons: [], 8111 closeOnEscape: true, 8112 closeText: "Close", 8113 dialogClass: "", 8114 draggable: true, 8115 hide: null, 8116 height: "auto", 8117 maxHeight: null, 8118 maxWidth:
8118function() { 8119 $( this ).css( "max-width", "400" ); 8120 }, 8121 minHeight: 150, 8122 minWidth: 150, 8123 modal: false, 8124 position: { 8125 my: "center", 8126 at: "center", 8127 of: window, 8128 collision: "fit", 8129 // Ensure the titlebar is always visible 8130 using: function( pos ) { 8131 var topOffset = $( this ).css( pos ).offset().top; 8132 if ( topOffset < 0 ) { 8133 $( this ).css( "top", pos.top - topOffset ); 8134 } 8135 } 8136 }, 8137 resizable: false, 8138 show: null, 8139 title: false
vendor: 35,087 bytes, lines 8139-9479
8139, 8140 width: 300, 8141 8142 // callbacks 8143 beforeClose: null, 8144 close: null, 8145 drag: null, 8146 dragStart: null, 8147 dragStop: null, 8148 focus: null, 8149 open: null, 8150 resize: null, 8151 resizeStart: null, 8152 resizeStop: null 8153 }, 8154 8155 sizeRelatedOptions: { 8156 buttons: true, 8157 height: true, 8158 maxHeight: true, 8159 maxWidth: true, 8160 minHeight: true, 8161 minWidth: true, 8162 width: true 8163 }, 8164 8165 resizableRelatedOptions: { 8166 maxHeight: true, 8167 maxWidth: true, 8168 minHeight: true, 8169 minWidth: true 8170 }, 8171 8172 _create: function() { 8173 this.originalCss = { 8174 display: this.element[ 0 ].style.display, 8175 width: this.element[ 0 ].style.width, 8176 minHeight: this.element[ 0 ].style.minHeight, 8177 maxHeight: this.element[ 0 ].style.maxHeight, 8178 height: this.element[ 0 ].style.height 8179 }; 8180 this.originalPosition = { 8181 parent: this.element.parent(), 8182 index: this.element.parent().children().index( this.element ) 8183 }; 8184 this.originalTitle = this.element.attr( "title" ); 8185 this.options.title = this.options.title || this.originalTitle; 8186 8187 this._createWrapper(); 8188 8189 this.element 8190 .show() 8191 .removeAttr( "title" ) 8192 .addClass( "ui-dialog-content ui-widget-content" ) 8193 .appendTo( this.uiDialog ); 8194 8195 this._createTitlebar(); 8196 this._createButtonPane(); 8197 8198 if ( this.options.draggable && $.fn.draggable ) { 8199 this._makeDraggable(); 8200 } 8201 if ( this.options.resizable && $.fn.resizable ) { 8202 this._makeResizable(); 8203 } 8204 8205 this._isOpen = false; 8206 8207 this._trackFocus(); 8208 }, 8209 8210 _init: function() { 8211 if ( this.options.autoOpen ) { 8212 this.open(); 8213 } 8214 }, 8215 8216 _appendTo: function() { 8217 var element = this.options.appendTo; 8218 if ( element && (element.jquery || element.nodeType) ) { 8219 return $( element ); 8220 } 8221 return this.document.find( element || "body" ).eq( 0 ); 8222 }, 8223 8224 _destroy: function() { 8225 var next, 8226 originalPosition = this.originalPosition; 8227 8228 this._untrackInstance(); 8229 this._destroyOverlay(); 8230 8231 this.element 8232 .removeUniqueId() 8233 .removeClass( "ui-dialog-content ui-widget-content" ) 8234 .css( this.originalCss ) 8235 // Without detaching first, the following becomes really slow 8236 .detach(); 8237 8238 this.uiDialog.stop( true, true ).remove(); 8239 8240 if ( this.originalTitle ) { 8241 this.element.attr( "title", this.originalTitle ); 8242 } 8243 8244 next = originalPosition.parent.children().eq( originalPosition.index ); 8245 // Don't try to place the dialog next to itself (#8613) 8246 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 8247 next.before( this.element ); 8248 } else { 8249 originalPosition.parent.append( this.element ); 8250 } 8251 }, 8252 8253 widget: function() { 8254 return this.uiDialog; 8255 }, 8256 8257 disable: $.noop, 8258 enable: $.noop, 8259 8260 close: function( event ) { 8261 var activeElement, 8262 that = this; 8263 8264 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 8265 return; 8266 } 8267 8268 this._isOpen = false; 8269 this._focusedElement = null; 8270 this._destroyOverlay(); 8271 this._untrackInstance(); 8272 8273 if ( !this.opener.filter( ":focusable" ).focus().length ) { 8274 8275 // support: IE9 8276 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 8277 try { 8278 activeElement = this.document[ 0 ].activeElement; 8279 8280 // Support: IE9, IE10 8281 // If the <body> is blurred, IE will switch windows, see #4520 8282 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 8283 8284 // Hiding a focused element doesn't trigger blur in WebKit 8285 // so in case we have nothing to focus on, explicitly blur the active element 8286 // https://bugs.webkit.org/show_bug.cgi?id=47182 8287 $( activeElement ).blur(); 8288 } 8289 } catch ( error ) {} 8290 } 8291 8292 this._hide( this.uiDialog, this.options.hide, function() { 8293 that._trigger( "close", event ); 8294 }); 8295 }, 8296 8297 isOpen: function() { 8298 return this._isOpen; 8299 }, 8300 8301 moveToTop: function() { 8302 this._moveToTop(); 8303 }, 8304 8305 _moveToTop: function( event, silent ) { 8306 var moved = false, 8307 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { 8308 return +$( this ).css( "z-index" ); 8309 }).get(), 8310 zIndexMax = Math.max.apply( null, zIndices ); 8311 8312 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 8313 this.uiDialog.css( "z-index", zIndexMax + 1 ); 8314 moved = true; 8315 } 8316 8317 if ( moved && !silent ) { 8318 this._trigger( "focus", event ); 8319 } 8320 return moved; 8321 }, 8322 8323 open: function() { 8324 var that = this; 8325 if ( this._isOpen ) { 8326 if ( this._moveToTop() ) { 8327 this._focusTabbable(); 8328 } 8329 return; 8330 } 8331 8332 this._isOpen = true; 8333 this.opener = $( this.document[ 0 ].activeElement ); 8334 8335 this._size(); 8336 this._position(); 8337 this._createOverlay(); 8338 this._moveToTop( null, true ); 8339 8340 // Ensure the overlay is moved to the top with the dialog, but only when 8341 // opening. The overlay shouldn't move after the dialog is open so that 8342 // modeless dialogs opened after the modal dialog stack properly. 8343 if ( this.overlay ) { 8344 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 8345 } 8346 8347 this._show( this.uiDialog, this.options.show, function() { 8348 that._focusTabbable(); 8349 that._trigger( "focus" ); 8350 }); 8351 8352 // Track the dialog immediately upon openening in case a focus event 8353 // somehow occurs outside of the dialog before an element inside the 8354 // dialog is focused (#10152) 8355 this._makeFocusTarget(); 8356 8357 this._trigger( "open" ); 8358 }, 8359 8360 _focusTabbable: function() { 8361 // Set focus to the first match: 8362 // 1. An element that was focused previously 8363 // 2. First element inside the dialog matching [autofocus] 8364 // 3. Tabbable element inside the content element 8365 // 4. Tabbable element inside the buttonpane 8366 // 5. The close button 8367 // 6. The dialog itself 8368 var hasFocus = this._focusedElement; 8369 if ( !hasFocus ) { 8370 hasFocus = this.element.find( "[autofocus]" ); 8371 } 8372 if ( !hasFocus.length ) { 8373 hasFocus = this.element.find( ":tabbable" ); 8374 } 8375 if ( !hasFocus.length ) { 8376 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 8377 } 8378 if ( !hasFocus.length ) { 8379 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 8380 } 8381 if ( !hasFocus.length ) { 8382 hasFocus = this.uiDialog; 8383 } 8384 hasFocus.eq( 0 ).focus(); 8385 }, 8386 8387 _keepFocus: function( event ) { 8388 function checkFocus() { 8389 var activeElement = this.document[0].activeElement, 8390 isActive = this.uiDialog[0] === activeElement || 8391 $.contains( this.uiDialog[0], activeElement ); 8392 if ( !isActive ) { 8393 this._focusTabbable(); 8394 } 8395 } 8396 event.preventDefault(); 8397 checkFocus.call( this ); 8398 // support: IE 8399 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 8400 // so we check again later 8401 this._delay( checkFocus ); 8402 }, 8403 8404 _createWrapper: function() { 8405 this.uiDialog = $("<div>") 8406 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 8407 this.options.dialogClass ) 8408 .hide() 8409 .attr({ 8410 // Setting tabIndex makes the div focusable 8411 tabIndex: -1, 8412 role: "dialog" 8413 }) 8414 .appendTo( this._appendTo() ); 8415 8416 this._on( this.uiDialog, { 8417 keydown: function( event ) { 8418 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 8419 event.keyCode === $.ui.keyCode.ESCAPE ) { 8420 event.preventDefault(); 8421 this.close( event ); 8422 return; 8423 } 8424 8425 // prevent tabbing out of dialogs 8426 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 8427 return; 8428 } 8429 var tabbables = this.uiDialog.find( ":tabbable" ), 8430 first = tabbables.filter( ":first" ), 8431 last = tabbables.filter( ":last" ); 8432 8433 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 8434 this._delay(function() { 8435 first.focus(); 8436 }); 8437 event.preventDefault(); 8438 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 8439 this._delay(function() { 8440 last.focus(); 8441 }); 8442 event.preventDefault(); 8443 } 8444 }, 8445 mousedown: function( event ) { 8446 if ( this._moveToTop( event ) ) { 8447 this._focusTabbable(); 8448 } 8449 } 8450 }); 8451 8452 // We assume that any existing aria-describedby attribute means 8453 // that the dialog content is marked up properly 8454 // otherwise we brute force the content as the description 8455 if ( !this.element.find( "[aria-describedby]" ).length ) { 8456 this.uiDialog.attr({ 8457 "aria-describedby": this.element.uniqueId().attr( "id" ) 8458 }); 8459 } 8460 }, 8461 8462 _createTitlebar: function() { 8463 var uiDialogTitle; 8464 8465 this.uiDialogTitlebar = $( "<div>" ) 8466 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) 8467 .prependTo( this.uiDialog ); 8468 this._on( this.uiDialogTitlebar, { 8469 mousedown: function( event ) { 8470 // Don't prevent click on close button (#8838) 8471 // Focusing a dialog that is partially scrolled out of view 8472 // causes the browser to scroll it into view, preventing the click event 8473 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 8474 // Dialog isn't getting focus when dragging (#8063) 8475 this.uiDialog.focus(); 8476 } 8477 } 8478 }); 8479 8480 // support: IE 8481 // Use type="button" to prevent enter keypresses in textboxes from closing the 8482 // dialog in IE (#9312) 8483 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 8484 .button({ 8485 label: this.options.closeText, 8486 icons: { 8487 primary: "ui-icon-closethick" 8488 }, 8489 text: false 8490 }) 8491 .addClass( "ui-dialog-titlebar-close" ) 8492 .appendTo( this.uiDialogTitlebar ); 8493 this._on( this.uiDialogTitlebarClose, { 8494 click: function( event ) { 8495 event.preventDefault(); 8496 this.close( event ); 8497 } 8498 }); 8499 8500 uiDialogTitle = $( "<span>" ) 8501 .uniqueId() 8502 .addClass( "ui-dialog-title" ) 8503 .prependTo( this.uiDialogTitlebar ); 8504 this._title( uiDialogTitle ); 8505 8506 this.uiDialog.attr({ 8507 "aria-labelledby": uiDialogTitle.attr( "id" ) 8508 }); 8509 }, 8510 8511 _title: function( title ) { 8512 if ( !this.options.title ) { 8513 title.html( " " ); 8514 } 8515 title.text( this.options.title ); 8516 }, 8517 8518 _createButtonPane: function() { 8519 this.uiDialogButtonPane = $( "<div>" ) 8520 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 8521 8522 this.uiButtonSet = $( "<div>" ) 8523 .addClass( "ui-dialog-buttonset" ) 8524 .appendTo( this.uiDialogButtonPane ); 8525 8526 this._createButtons(); 8527 }, 8528 8529 _createButtons: function() { 8530 var that = this, 8531 buttons = this.options.buttons; 8532 8533 // if we already have a button pane, remove it 8534 this.uiDialogButtonPane.remove(); 8535 this.uiButtonSet.empty(); 8536 8537 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 8538 this.uiDialog.removeClass( "ui-dialog-buttons" ); 8539 return; 8540 } 8541 8542 $.each( buttons, function( name, props ) { 8543 var click, buttonOptions; 8544 props = $.isFunction( props ) ? 8545 { click: props, text: name } : 8546 props; 8547 // Default to a non-submitting button 8548 props = $.extend( { type: "button" }, props ); 8549 // Change the context for the click callback to be the main element 8550 click = props.click; 8551 props.click = function() { 8552 click.apply( that.element[ 0 ], arguments ); 8553 }; 8554 buttonOptions = { 8555 icons: props.icons, 8556 text: props.showText 8557 }; 8558 delete props.icons; 8559 delete props.showText; 8560 $( "<button></button>", props ) 8561 .button( buttonOptions ) 8562 .appendTo( that.uiButtonSet ); 8563 }); 8564 this.uiDialog.addClass( "ui-dialog-buttons" ); 8565 this.uiDialogButtonPane.appendTo( this.uiDialog ); 8566 }, 8567 8568 _makeDraggable: function() { 8569 var that = this, 8570 options = this.options; 8571 8572 function filteredUi( ui ) { 8573 return { 8574 position: ui.position, 8575 offset: ui.offset 8576 }; 8577 } 8578 8579 this.uiDialog.draggable({ 8580 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 8581 handle: ".ui-dialog-titlebar", 8582 containment: "document", 8583 start: function( event, ui ) { 8584 $( this ).addClass( "ui-dialog-dragging" ); 8585 that._blockFrames(); 8586 that._trigger( "dragStart", event, filteredUi( ui ) ); 8587 }, 8588 drag: function( event, ui ) { 8589 that._trigger( "drag", event, filteredUi( ui ) ); 8590 }, 8591 stop: function( event, ui ) { 8592 var left = ui.offset.left - that.document.scrollLeft(), 8593 top = ui.offset.top - that.document.scrollTop(); 8594 8595 options.position = { 8596 my: "left top", 8597 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8598 "top" + (top >= 0 ? "+" : "") + top, 8599 of: that.window 8600 }; 8601 $( this ).removeClass( "ui-dialog-dragging" ); 8602 that._unblockFrames(); 8603 that._trigger( "dragStop", event, filteredUi( ui ) ); 8604 } 8605 }); 8606 }, 8607 8608 _makeResizable: function() { 8609 var that = this, 8610 options = this.options, 8611 handles = options.resizable, 8612 // .ui-resizable has position: relative defined in the stylesheet 8613 // but dialogs have to use absolute or fixed positioning 8614 position = this.uiDialog.css("position"), 8615 resizeHandles = typeof handles === "string" ? 8616 handles : 8617 "n,e,s,w,se,sw,ne,nw"; 8618 8619 function filteredUi( ui ) { 8620 return { 8621 originalPosition: ui.originalPosition, 8622 originalSize: ui.originalSize, 8623 position: ui.position, 8624 size: ui.size 8625 }; 8626 } 8627 8628 this.uiDialog.resizable({ 8629 cancel: ".ui-dialog-content", 8630 containment: "document", 8631 alsoResize: this.element, 8632 maxWidth: options.maxWidth, 8633 maxHeight: options.maxHeight, 8634 minWidth: options.minWidth, 8635 minHeight: this._minHeight(), 8636 handles: resizeHandles, 8637 start: function( event, ui ) { 8638 $( this ).addClass( "ui-dialog-resizing" ); 8639 that._blockFrames(); 8640 that._trigger( "resizeStart", event, filteredUi( ui ) ); 8641 }, 8642 resize: function( event, ui ) { 8643 that._trigger( "resize", event, filteredUi( ui ) ); 8644 }, 8645 stop: function( event, ui ) { 8646 var offset = that.uiDialog.offset(), 8647 left = offset.left - that.document.scrollLeft(), 8648 top = offset.top - that.document.scrollTop(); 8649 8650 options.height = that.uiDialog.height(); 8651 options.width = that.uiDialog.width(); 8652 options.position = { 8653 my: "left top", 8654 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8655 "top" + (top >= 0 ? "+" : "") + top, 8656 of: that.window 8657 }; 8658 $( this ).removeClass( "ui-dialog-resizing" ); 8659 that._unblockFrames(); 8660 that._trigger( "resizeStop", event, filteredUi( ui ) ); 8661 } 8662 }) 8663 .css( "position", position ); 8664 }, 8665 8666 _trackFocus: function() { 8667 this._on( this.widget(), { 8668 focusin: function( event ) { 8669 this._makeFocusTarget(); 8670 this._focusedElement = $( event.target ); 8671 } 8672 }); 8673 }, 8674 8675 _makeFocusTarget: function() { 8676 this._untrackInstance(); 8677 this._trackingInstances().unshift( this ); 8678 }, 8679 8680 _untrackInstance: function() { 8681 var instances = this._trackingInstances(), 8682 exists = $.inArray( this, instances ); 8683 if ( exists !== -1 ) { 8684 instances.splice( exists, 1 ); 8685 } 8686 }, 8687 8688 _trackingInstances: function() { 8689 var instances = this.document.data( "ui-dialog-instances" ); 8690 if ( !instances ) { 8691 instances = []; 8692 this.document.data( "ui-dialog-instances", instances ); 8693 } 8694 return instances; 8695 }, 8696 8697 _minHeight: function() { 8698 var options = this.options; 8699 8700 return options.height === "auto" ? 8701 options.minHeight : 8702 Math.min( options.minHeight, options.height ); 8703 }, 8704 8705 _position: function() { 8706 // Need to show the dialog to get the actual offset in the position plugin 8707 var isVisible = this.uiDialog.is( ":visible" ); 8708 if ( !isVisible ) { 8709 this.uiDialog.show(); 8710 } 8711 this.uiDialog.position( this.options.position ); 8712 if ( !isVisible ) { 8713 this.uiDialog.hide(); 8714 } 8715 }, 8716 8717 _setOptions: function( options ) { 8718 var that = this, 8719 resize = false, 8720 resizableOptions = {}; 8721 8722 $.each( options, function( key, value ) { 8723 that._setOption( key, value ); 8724 8725 if ( key in that.sizeRelatedOptions ) { 8726 resize = true; 8727 } 8728 if ( key in that.resizableRelatedOptions ) { 8729 resizableOptions[ key ] = value; 8730 } 8731 }); 8732 8733 if ( resize ) { 8734 this._size(); 8735 this._position(); 8736 } 8737 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 8738 this.uiDialog.resizable( "option", resizableOptions ); 8739 } 8740 }, 8741 8742 _setOption: function( key, value ) { 8743 var isDraggable, isResizable, 8744 uiDialog = this.uiDialog; 8745 8746 if ( key === "dialogClass" ) { 8747 uiDialog 8748 .removeClass( this.options.dialogClass ) 8749 .addClass( value ); 8750 } 8751 8752 if ( key === "disabled" ) { 8753 return; 8754 } 8755 8756 this._super( key, value ); 8757 8758 if ( key === "appendTo" ) { 8759 this.uiDialog.appendTo( this._appendTo() ); 8760 } 8761 8762 if ( key === "buttons" ) { 8763 this._createButtons(); 8764 } 8765 8766 if ( key === "closeText" ) { 8767 this.uiDialogTitlebarClose.button({ 8768 // Ensure that we always pass a string 8769 label: "" + value 8770 }); 8771 } 8772 8773 if ( key === "draggable" ) { 8774 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 8775 if ( isDraggable && !value ) { 8776 uiDialog.draggable( "destroy" ); 8777 } 8778 8779 if ( !isDraggable && value ) { 8780 this._makeDraggable(); 8781 } 8782 } 8783 8784 if ( key === "position" ) { 8785 this._position(); 8786 } 8787 8788 if ( key === "resizable" ) { 8789 // currently resizable, becoming non-resizable 8790 isResizable = uiDialog.is( ":data(ui-resizable)" ); 8791 if ( isResizable && !value ) { 8792 uiDialog.resizable( "destroy" ); 8793 } 8794 8795 // currently resizable, changing handles 8796 if ( isResizable && typeof value === "string" ) { 8797 uiDialog.resizable( "option", "handles", value ); 8798 } 8799 8800 // currently non-resizable, becoming resizable 8801 if ( !isResizable && value !== false ) { 8802 this._makeResizable(); 8803 } 8804 } 8805 8806 if ( key === "title" ) { 8807 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 8808 } 8809 }, 8810 8811 _size: function() { 8812 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 8813 // divs will both have width and height set, so we need to reset them 8814 var nonContentHeight, minContentHeight, maxContentHeight, 8815 options = this.options; 8816 8817 // Reset content sizing 8818 this.element.show().css({ 8819 width: "auto", 8820 minHeight: 0, 8821 maxHeight: "none", 8822 height: 0 8823 }); 8824 8825 if ( options.minWidth > options.width ) { 8826 options.width = options.minWidth; 8827 } 8828 8829 // reset wrapper sizing 8830 // determine the height of all the non-content elements 8831 nonContentHeight = this.uiDialog.css({ 8832 height: "auto", 8833 width: options.width 8834 }) 8835 .outerHeight(); 8836 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 8837 maxContentHeight = typeof options.maxHeight === "number" ? 8838 Math.max( 0, options.maxHeight - nonContentHeight ) : 8839 "none"; 8840 8841 if ( options.height === "auto" ) { 8842 this.element.css({ 8843 minHeight: minContentHeight, 8844 maxHeight: maxContentHeight, 8845 height: "auto" 8846 }); 8847 } else { 8848 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 8849 } 8850 8851 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 8852 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 8853 } 8854 }, 8855 8856 _blockFrames: function() { 8857 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 8858 var iframe = $( this ); 8859 8860 return $( "<div>" ) 8861 .css({ 8862 position: "absolute", 8863 width: iframe.outerWidth(), 8864 height: iframe.outerHeight() 8865 }) 8866 .appendTo( iframe.parent() ) 8867 .offset( iframe.offset() )[0]; 8868 }); 8869 }, 8870 8871 _unblockFrames: function() { 8872 if ( this.iframeBlocks ) { 8873 this.iframeBlocks.remove(); 8874 delete this.iframeBlocks; 8875 } 8876 }, 8877 8878 _allowInteraction: function( event ) { 8879 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 8880 return true; 8881 } 8882 8883 // TODO: Remove hack when datepicker implements 8884 // the .ui-front logic (#8989) 8885 return !!$( event.target ).closest( ".ui-datepicker" ).length; 8886 }, 8887 8888 _createOverlay: function() { 8889 if ( !this.options.modal ) { 8890 return; 8891 } 8892 8893 // We use a delay in case the overlay is created from an 8894 // event that we're going to be cancelling (#2804) 8895 var isOpening = true; 8896 this._delay(function() { 8897 isOpening = false; 8898 }); 8899 8900 if ( !this.document.data( "ui-dialog-overlays" ) ) { 8901 8902 // Prevent use of anchors and inputs 8903 // Using _on() for an event handler shared across many instances is 8904 // safe because the dialogs stack and must be closed in reverse order 8905 this._on( this.document, { 8906 focusin: function( event ) { 8907 if ( isOpening ) { 8908 return; 8909 } 8910 8911 if ( !this._allowInteraction( event ) ) { 8912 event.preventDefault(); 8913 this._trackingInstances()[ 0 ]._focusTabbable(); 8914 } 8915 } 8916 }); 8917 } 8918 8919 this.overlay = $( "<div>" ) 8920 .addClass( "ui-widget-overlay ui-front" ) 8921 .appendTo( this._appendTo() ); 8922 this._on( this.overlay, { 8923 mousedown: "_keepFocus" 8924 }); 8925 this.document.data( "ui-dialog-overlays", 8926 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); 8927 }, 8928 8929 _destroyOverlay: function() { 8930 if ( !this.options.modal ) { 8931 return; 8932 } 8933 8934 if ( this.overlay ) { 8935 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 8936 8937 if ( !overlays ) { 8938 this.document 8939 .unbind( "focusin" ) 8940 .removeData( "ui-dialog-overlays" ); 8941 } else { 8942 this.document.data( "ui-dialog-overlays", overlays ); 8943 } 8944 8945 this.overlay.remove(); 8946 this.overlay = null; 8947 } 8948 } 8949}); 8950 8951 8952/*! 8953 * jQuery UI Droppable 1.11.4 8954 * http://jqueryui.com 8955 * 8956 * Copyright jQuery Foundation and other contributors 8957 * Released under the MIT license. 8958 * http://jquery.org/license 8959 * 8960 * http://api.jqueryui.com/droppable/ 8961 */ 8962 8963 8964$.widget( "ui.droppable", { 8965 version: "1.11.4", 8966 widgetEventPrefix: "drop", 8967 options: { 8968 accept: "*", 8969 activeClass: false, 8970 addClasses: true, 8971 greedy: false, 8972 hoverClass: false, 8973 scope: "default", 8974 tolerance: "intersect", 8975 8976 // callbacks 8977 activate: null, 8978 deactivate: null, 8979 drop: null, 8980 out: null, 8981 over: null 8982 }, 8983 _create: function() { 8984 8985 var proportions, 8986 o = this.options, 8987 accept = o.accept; 8988 8989 this.isover = false; 8990 this.isout = true; 8991 8992 this.accept = $.isFunction( accept ) ? accept : function( d ) { 8993 return d.is( accept ); 8994 }; 8995 8996 this.proportions = function( /* valueToWrite */ ) { 8997 if ( arguments.length ) { 8998 // Store the droppable's proportions 8999 proportions = arguments[ 0 ]; 9000 } else { 9001 // Retrieve or derive the droppable's proportions 9002 return proportions ? 9003 proportions : 9004 proportions = { 9005 width: this.element[ 0 ].offsetWidth, 9006 height: this.element[ 0 ].offsetHeight 9007 }; 9008 } 9009 }; 9010 9011 this._addToManager( o.scope ); 9012 9013 o.addClasses && this.element.addClass( "ui-droppable" ); 9014 9015 }, 9016 9017 _addToManager: function( scope ) { 9018 // Add the reference and positions to the manager 9019 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 9020 $.ui.ddmanager.droppables[ scope ].push( this ); 9021 }, 9022 9023 _splice: function( drop ) { 9024 var i = 0; 9025 for ( ; i < drop.length; i++ ) { 9026 if ( drop[ i ] === this ) { 9027 drop.splice( i, 1 ); 9028 } 9029 } 9030 }, 9031 9032 _destroy: function() { 9033 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9034 9035 this._splice( drop ); 9036 9037 this.element.removeClass( "ui-droppable ui-droppable-disabled" ); 9038 }, 9039 9040 _setOption: function( key, value ) { 9041 9042 if ( key === "accept" ) { 9043 this.accept = $.isFunction( value ) ? value : function( d ) { 9044 return d.is( value ); 9045 }; 9046 } else if ( key === "scope" ) { 9047 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9048 9049 this._splice( drop ); 9050 this._addToManager( value ); 9051 } 9052 9053 this._super( key, value ); 9054 }, 9055 9056 _activate: function( event ) { 9057 var draggable = $.ui.ddmanager.current; 9058 if ( this.options.activeClass ) { 9059 this.element.addClass( this.options.activeClass ); 9060 } 9061 if ( draggable ){ 9062 this._trigger( "activate", event, this.ui( draggable ) ); 9063 } 9064 }, 9065 9066 _deactivate: function( event ) { 9067 var draggable = $.ui.ddmanager.current; 9068 if ( this.options.activeClass ) { 9069 this.element.removeClass( this.options.activeClass ); 9070 } 9071 if ( draggable ){ 9072 this._trigger( "deactivate", event, this.ui( draggable ) ); 9073 } 9074 }, 9075 9076 _over: function( event ) { 9077 9078 var draggable = $.ui.ddmanager.current; 9079 9080 // Bail if draggable and droppable are same element 9081 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9082 return; 9083 } 9084 9085 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9086 if ( this.options.hoverClass ) { 9087 this.element.addClass( this.options.hoverClass ); 9088 } 9089 this._trigger( "over", event, this.ui( draggable ) ); 9090 } 9091 9092 }, 9093 9094 _out: function( event ) { 9095 9096 var draggable = $.ui.ddmanager.current; 9097 9098 // Bail if draggable and droppable are same element 9099 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9100 return; 9101 } 9102 9103 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9104 if ( this.options.hoverClass ) { 9105 this.element.removeClass( this.options.hoverClass ); 9106 } 9107 this._trigger( "out", event, this.ui( draggable ) ); 9108 } 9109 9110 }, 9111 9112 _drop: function( event, custom ) { 9113 9114 var draggable = custom || $.ui.ddmanager.current, 9115 childrenIntersection = false; 9116 9117 // Bail if draggable and droppable are same element 9118 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9119 return false; 9120 } 9121 9122 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { 9123 var inst = $( this ).droppable( "instance" ); 9124 if ( 9125 inst.options.greedy && 9126 !inst.options.disabled && 9127 inst.options.scope === draggable.options.scope && 9128 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && 9129 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) 9130 ) { childrenIntersection = true; return false; } 9131 }); 9132 if ( childrenIntersection ) { 9133 return false; 9134 } 9135 9136 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9137 if ( this.options.activeClass ) { 9138 this.element.removeClass( this.options.activeClass ); 9139 } 9140 if ( this.options.hoverClass ) { 9141 this.element.removeClass( this.options.hoverClass ); 9142 } 9143 this._trigger( "drop", event, this.ui( draggable ) ); 9144 return this.element; 9145 } 9146 9147 return false; 9148 9149 }, 9150 9151 ui: function( c ) { 9152 return { 9153 draggable: ( c.currentItem || c.element ), 9154 helper: c.helper, 9155 position: c.position, 9156 offset: c.positionAbs 9157 }; 9158 } 9159 9160}); 9161 9162$.ui.intersect = (function() { 9163 function isOverAxis( x, reference, size ) { 9164 return ( x >= reference ) && ( x < ( reference + size ) ); 9165 } 9166 9167 return function( draggable, droppable, toleranceMode, event ) { 9168 9169 if ( !droppable.offset ) { 9170 return false; 9171 } 9172 9173 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, 9174 y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, 9175 x2 = x1 + draggable.helperProportions.width, 9176 y2 = y1 + draggable.helperProportions.height, 9177 l = droppable.offset.left, 9178 t = droppable.offset.top, 9179 r = l + droppable.proportions().width, 9180 b = t + droppable.proportions().height; 9181 9182 switch ( toleranceMode ) { 9183 case "fit": 9184 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 9185 case "intersect": 9186 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 9187 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 9188 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 9189 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 9190 case "pointer": 9191 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); 9192 case "touch": 9193 return ( 9194 ( y1 >= t && y1 <= b ) || // Top edge touching 9195 ( y2 >= t && y2 <= b ) || // Bottom edge touching 9196 ( y1 < t && y2 > b ) // Surrounded vertically 9197 ) && ( 9198 ( x1 >= l && x1 <= r ) || // Left edge touching 9199 ( x2 >= l && x2 <= r ) || // Right edge touching 9200 ( x1 < l && x2 > r ) // Surrounded horizontally 9201 ); 9202 default: 9203 return false; 9204 } 9205 }; 9206})(); 9207 9208/* 9209 This manager tracks offsets of draggables and droppables 9210*/ 9211$.ui.ddmanager = { 9212 current: null, 9213 droppables: { "default": [] }, 9214 prepareOffsets: function( t, event ) { 9215 9216 var i, j, 9217 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 9218 type = event ? event.type : null, // workaround for #2317 9219 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 9220 9221 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 9222 9223 // No disabled and non-accepted 9224 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { 9225 continue; 9226 } 9227 9228 // Filter out elements in the current dragged item 9229 for ( j = 0; j < list.length; j++ ) { 9230 if ( list[ j ] === m[ i ].element[ 0 ] ) { 9231 m[ i ].proportions().height = 0; 9232 continue droppablesLoop; 9233 } 9234 } 9235 9236 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 9237 if ( !m[ i ].visible ) { 9238 continue; 9239 } 9240 9241 // Activate the droppable if used directly from draggables 9242 if ( type === "mousedown" ) { 9243 m[ i ]._activate.call( m[ i ], event ); 9244 } 9245 9246 m[ i ].offset = m[ i ].element.offset(); 9247 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 9248 9249 } 9250 9251 }, 9252 drop: function( draggable, event ) { 9253 9254 var dropped = false; 9255 // Create a copy of the droppables in case the list changes during the drop (#9116) 9256 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 9257 9258 if ( !this.options ) { 9259 return; 9260 } 9261 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 9262 dropped = this._drop.call( this, event ) || dropped; 9263 } 9264 9265 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9266 this.isout = true; 9267 this.isover = false; 9268 this._deactivate.call( this, event ); 9269 } 9270 9271 }); 9272 return dropped; 9273 9274 }, 9275 dragStart: function( draggable, event ) { 9276 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 9277 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 9278 if ( !draggable.options.refreshPositions ) { 9279 $.ui.ddmanager.prepareOffsets( draggable, event ); 9280 } 9281 }); 9282 }, 9283 drag: function( draggable, event ) { 9284 9285 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 9286 if ( draggable.options.refreshPositions ) { 9287 $.ui.ddmanager.prepareOffsets( draggable, event ); 9288 } 9289 9290 // Run through all droppables and check their positions based on specific tolerance options 9291 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 9292 9293 if ( this.options.disabled || this.greedyChild || !this.visible ) { 9294 return; 9295 } 9296 9297 var parentInstance, scope, parent, 9298 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 9299 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); 9300 if ( !c ) { 9301 return; 9302 } 9303 9304 if ( this.options.greedy ) { 9305 // find droppable parents with same scope 9306 scope = this.options.scope; 9307 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { 9308 return $( this ).droppable( "instance" ).options.scope === scope; 9309 }); 9310 9311 if ( parent.length ) { 9312 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 9313 parentInstance.greedyChild = ( c === "isover" ); 9314 } 9315 } 9316 9317 // we just moved into a greedy child 9318 if ( parentInstance && c === "isover" ) { 9319 parentInstance.isover = false; 9320 parentInstance.isout = true; 9321 parentInstance._out.call( parentInstance, event ); 9322 } 9323 9324 this[ c ] = true; 9325 this[c === "isout" ? "isover" : "isout"] = false; 9326 this[c === "isover" ? "_over" : "_out"].call( this, event ); 9327 9328 // we just moved out of a greedy child 9329 if ( parentInstance && c === "isout" ) { 9330 parentInstance.isout = false; 9331 parentInstance.isover = true; 9332 parentInstance._over.call( parentInstance, event ); 9333 } 9334 }); 9335 9336 }, 9337 dragStop: function( draggable, event ) { 9338 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 9339 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 9340 if ( !draggable.options.refreshPositions ) { 9341 $.ui.ddmanager.prepareOffsets( draggable, event ); 9342 } 9343 } 9344}; 9345 9346var droppable = $.ui.droppable; 9347 9348 9349/*! 9350 * jQuery UI Effects 1.11.4 9351 * http://jqueryui.com 9352 * 9353 * Copyright jQuery Foundation and other contributors 9354 * Released under the MIT license. 9355 * http://jquery.org/license 9356 * 9357 * http://api.jqueryui.com/category/effects-core/ 9358 */ 9359 9360 9361var dataSpace = "ui-effects-", 9362 9363 // Create a local jQuery because jQuery Color relies on it and the 9364 // global may not exist with AMD and a custom build (#10199) 9365 jQuery = $; 9366 9367$.effects = { 9368 effect: {} 9369}; 9370 9371/*! 9372 * jQuery Color Animations v2.1.2 9373 * https://github.com/jquery/jquery-color 9374 * 9375 * Copyright 2014 jQuery Foundation and other contributors 9376 * Released under the MIT license. 9377 * http://jquery.org/license 9378 * 9379 * Date: Wed Jan 16 08:47:09 2013 -0600 9380 */ 9381(function( jQuery, undefined ) { 9382 9383 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 9384 9385 // plusequals test for += 100 -= 100 9386 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 9387 // a set of RE's that can match strings and generate color tuples. 9388 stringParsers = [ { 9389 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9390 parse: function( execResult ) { 9391 return [ 9392 execResult[ 1 ], 9393 execResult[ 2 ], 9394 execResult[ 3 ], 9395 execResult[ 4 ] 9396 ]; 9397 } 9398 }, { 9399 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9400 parse: function( execResult ) { 9401 return [ 9402 execResult[ 1 ] * 2.55, 9403 execResult[ 2 ] * 2.55, 9404 execResult[ 3 ] * 2.55, 9405 execResult[ 4 ] 9406 ]; 9407 } 9408 }, { 9409 // this regex ignores A-F because it's compared against an already lowercased string 9410 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 9411 parse: function( execResult ) { 9412 return [ 9413 parseInt( execResult[ 1 ], 16 ), 9414 parseInt( execResult[ 2 ], 16 ), 9415 parseInt( execResult[ 3 ], 16 ) 9416 ]; 9417 } 9418 }, { 9419 // this regex ignores A-F because it's compared against an already lowercased string 9420 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 9421 parse: function( execResult ) { 9422 return [ 9423 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 9424 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 9425 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 9426 ]; 9427 } 9428 }, { 9429 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9430 space: "hsla", 9431 parse: function( execResult ) { 9432 return [ 9433 execResult[ 1 ], 9434 execResult[ 2 ] / 100, 9435 execResult[ 3 ] / 100, 9436 execResult[ 4 ] 9437 ]; 9438 } 9439 } ], 9440 9441 // jQuery.Color( ) 9442 color = jQuery.Color = function( color, green, blue, alpha ) { 9443 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 9444 }, 9445 spaces = { 9446 rgba: { 9447 props: { 9448 red: { 9449 idx: 0, 9450 type: "byte" 9451 }, 9452 green: { 9453 idx: 1, 9454 type: "byte" 9455 }, 9456 blue: { 9457 idx: 2, 9458 type: "byte" 9459 } 9460 } 9461 }, 9462 9463 hsla: { 9464 props: { 9465 hue: { 9466 idx: 0, 9467 type: "degrees" 9468 }, 9469 saturation: { 9470 idx: 1, 9471 type: "percent" 9472 }, 9473 lightness: { 9474 idx: 2, 9475 type: "percent" 9476 } 9477 } 9478 } 9479 },
vendor: 9,998 bytes, lines 9480-9887
9480 propTypes = { 9481 "byte": { 9482 floor: true, 9483 max: 255 9484 }, 9485 "percent": { 9486 max: 1 9487 }, 9488 "degrees": { 9489 mod: 360, 9490 floor: true 9491 } 9492 }, 9493 support = color.support = {}, 9494 9495 // element for support tests 9496 supportElem = jQuery( "<p>" )[ 0 ], 9497 9498 // colors = jQuery.Color.names 9499 colors, 9500 9501 // local aliases of functions called often 9502 each = jQuery.each; 9503 9504// determine rgba support immediately 9505supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 9506support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 9507 9508// define cache name and alpha properties 9509// for rgba and hsla spaces 9510each( spaces, function( spaceName, space ) { 9511 space.cache = "_" + spaceName; 9512 space.props.alpha = { 9513 idx: 3, 9514 type: "percent", 9515 def: 1 9516 }; 9517}); 9518 9519function clamp( value, prop, allowEmpty ) { 9520 var type = propTypes[ prop.type ] || {}; 9521 9522 if ( value == null ) { 9523 return (allowEmpty || !prop.def) ? null : prop.def; 9524 } 9525 9526 // ~~ is an short way of doing floor for positive numbers 9527 value = type.floor ? ~~value : parseFloat( value ); 9528 9529 // IE will pass in empty strings as value for alpha, 9530 // which will hit this case 9531 if ( isNaN( value ) ) { 9532 return prop.def; 9533 } 9534 9535 if ( type.mod ) { 9536 // we add mod before modding to make sure that negatives values 9537 // get converted properly: -10 -> 350 9538 return (value + type.mod) % type.mod; 9539 } 9540 9541 // for now all property types without mod have min and max 9542 return 0 > value ? 0 : type.max < value ? type.max : value; 9543} 9544 9545function stringParse( string ) { 9546 var inst = color(), 9547 rgba = inst._rgba = []; 9548 9549 string = string.toLowerCase(); 9550 9551 each( stringParsers, function( i, parser ) { 9552 var parsed, 9553 match = parser.re.exec( string ), 9554 values = match && parser.parse( match ), 9555 spaceName = parser.space || "rgba"; 9556 9557 if ( values ) { 9558 parsed = inst[ spaceName ]( values ); 9559 9560 // if this was an rgba parse the assignment might happen twice 9561 // oh well.... 9562 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 9563 rgba = inst._rgba = parsed._rgba; 9564 9565 // exit each( stringParsers ) here because we matched 9566 return false; 9567 } 9568 }); 9569 9570 // Found a stringParser that handled it 9571 if ( rgba.length ) { 9572 9573 // if this came from a parsed string, force "transparent" when alpha is 0 9574 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 9575 if ( rgba.join() === "0,0,0,0" ) { 9576 jQuery.extend( rgba, colors.transparent ); 9577 } 9578 return inst; 9579 } 9580 9581 // named colors 9582 return colors[ string ]; 9583} 9584 9585color.fn = jQuery.extend( color.prototype, { 9586 parse: function( red, green, blue, alpha ) { 9587 if ( red === undefined ) { 9588 this._rgba = [ null, null, null, null ]; 9589 return this; 9590 } 9591 if ( red.jquery || red.nodeType ) { 9592 red = jQuery( red ).css( green ); 9593 green = undefined; 9594 } 9595 9596 var inst = this, 9597 type = jQuery.type( red ), 9598 rgba = this._rgba = []; 9599 9600 // more than 1 argument specified - assume ( red, green, blue, alpha ) 9601 if ( green !== undefined ) { 9602 red = [ red, green, blue, alpha ]; 9603 type = "array"; 9604 } 9605 9606 if ( type === "string" ) { 9607 return this.parse( stringParse( red ) || colors._default ); 9608 } 9609 9610 if ( type === "array" ) { 9611 each( spaces.rgba.props, function( key, prop ) { 9612 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 9613 }); 9614 return this; 9615 } 9616 9617 if ( type === "object" ) { 9618 if ( red instanceof color ) { 9619 each( spaces, function( spaceName, space ) { 9620 if ( red[ space.cache ] ) { 9621 inst[ space.cache ] = red[ space.cache ].slice(); 9622 } 9623 }); 9624 } else { 9625 each( spaces, function( spaceName, space ) { 9626 var cache = space.cache; 9627 each( space.props, function( key, prop ) { 9628 9629 // if the cache doesn't exist, and we know how to convert 9630 if ( !inst[ cache ] && space.to ) { 9631 9632 // if the value was null, we don't need to copy it 9633 // if the key was alpha, we don't need to copy it either 9634 if ( key === "alpha" || red[ key ] == null ) { 9635 return; 9636 } 9637 inst[ cache ] = space.to( inst._rgba ); 9638 } 9639 9640 // this is the only case where we allow nulls for ALL properties. 9641 // call clamp with alwaysAllowEmpty 9642 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 9643 }); 9644 9645 // everything defined but alpha? 9646 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 9647 // use the default of 1 9648 inst[ cache ][ 3 ] = 1; 9649 if ( space.from ) { 9650 inst._rgba = space.from( inst[ cache ] ); 9651 } 9652 } 9653 }); 9654 } 9655 return this; 9656 } 9657 }, 9658 is: function( compare ) { 9659 var is = color( compare ), 9660 same = true, 9661 inst = this; 9662 9663 each( spaces, function( _, space ) { 9664 var localCache, 9665 isCache = is[ space.cache ]; 9666 if (isCache) { 9667 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 9668 each( space.props, function( _, prop ) { 9669 if ( isCache[ prop.idx ] != null ) { 9670 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 9671 return same; 9672 } 9673 }); 9674 } 9675 return same; 9676 }); 9677 return same; 9678 }, 9679 _space: function() { 9680 var used = [], 9681 inst = this; 9682 each( spaces, function( spaceName, space ) { 9683 if ( inst[ space.cache ] ) { 9684 used.push( spaceName ); 9685 } 9686 }); 9687 return used.pop(); 9688 }, 9689 transition: function( other, distance ) { 9690 var end = color( other ), 9691 spaceName = end._space(), 9692 space = spaces[ spaceName ], 9693 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 9694 start = startColor[ space.cache ] || space.to( startColor._rgba ), 9695 result = start.slice(); 9696 9697 end = end[ space.cache ]; 9698 each( space.props, function( key, prop ) { 9699 var index = prop.idx, 9700 startValue = start[ index ], 9701 endValue = end[ index ], 9702 type = propTypes[ prop.type ] || {}; 9703 9704 // if null, don't override start value 9705 if ( endValue === null ) { 9706 return; 9707 } 9708 // if null - use end 9709 if ( startValue === null ) { 9710 result[ index ] = endValue; 9711 } else { 9712 if ( type.mod ) { 9713 if ( endValue - startValue > type.mod / 2 ) { 9714 startValue += type.mod; 9715 } else if ( startValue - endValue > type.mod / 2 ) { 9716 startValue -= type.mod; 9717 } 9718 } 9719 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 9720 } 9721 }); 9722 return this[ spaceName ]( result ); 9723 }, 9724 blend: function( opaque ) { 9725 // if we are already opaque - return ourself 9726 if ( this._rgba[ 3 ] === 1 ) { 9727 return this; 9728 } 9729 9730 var rgb = this._rgba.slice(), 9731 a = rgb.pop(), 9732 blend = color( opaque )._rgba; 9733 9734 return color( jQuery.map( rgb, function( v, i ) { 9735 return ( 1 - a ) * blend[ i ] + a * v; 9736 })); 9737 }, 9738 toRgbaString: function() { 9739 var prefix = "rgba(", 9740 rgba = jQuery.map( this._rgba, function( v, i ) { 9741 return v == null ? ( i > 2 ? 1 : 0 ) : v; 9742 }); 9743 9744 if ( rgba[ 3 ] === 1 ) { 9745 rgba.pop(); 9746 prefix = "rgb("; 9747 } 9748 9749 return prefix + rgba.join() + ")"; 9750 }, 9751 toHslaString: function() { 9752 var prefix = "hsla(", 9753 hsla = jQuery.map( this.hsla(), function( v, i ) { 9754 if ( v == null ) { 9755 v = i > 2 ? 1 : 0; 9756 } 9757 9758 // catch 1 and 2 9759 if ( i && i < 3 ) { 9760 v = Math.round( v * 100 ) + "%"; 9761 } 9762 return v; 9763 }); 9764 9765 if ( hsla[ 3 ] === 1 ) { 9766 hsla.pop(); 9767 prefix = "hsl("; 9768 } 9769 return prefix + hsla.join() + ")"; 9770 }, 9771 toHexString: function( includeAlpha ) { 9772 var rgba = this._rgba.slice(), 9773 alpha = rgba.pop(); 9774 9775 if ( includeAlpha ) { 9776 rgba.push( ~~( alpha * 255 ) ); 9777 } 9778 9779 return "#" + jQuery.map( rgba, function( v ) { 9780 9781 // default to 0 when nulls exist 9782 v = ( v || 0 ).toString( 16 ); 9783 return v.length === 1 ? "0" + v : v; 9784 }).join(""); 9785 }, 9786 toString: function() { 9787 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 9788 } 9789}); 9790color.fn.parse.prototype = color.fn; 9791 9792// hsla conversions adapted from: 9793// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 9794 9795function hue2rgb( p, q, h ) { 9796 h = ( h + 1 ) % 1; 9797 if ( h * 6 < 1 ) { 9798 return p + ( q - p ) * h * 6; 9799 } 9800 if ( h * 2 < 1) { 9801 return q; 9802 } 9803 if ( h * 3 < 2 ) { 9804 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 9805 } 9806 return p; 9807} 9808 9809spaces.hsla.to = function( rgba ) { 9810 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 9811 return [ null, null, null, rgba[ 3 ] ]; 9812 } 9813 var r = rgba[ 0 ] / 255, 9814 g = rgba[ 1 ] / 255, 9815 b = rgba[ 2 ] / 255, 9816 a = rgba[ 3 ], 9817 max = Math.max( r, g, b ), 9818 min = Math.min( r, g, b ), 9819 diff = max - min, 9820 add = max + min, 9821 l = add * 0.5, 9822 h, s; 9823 9824 if ( min === max ) { 9825 h = 0; 9826 } else if ( r === max ) { 9827 h = ( 60 * ( g - b ) / diff ) + 360; 9828 } else if ( g === max ) { 9829 h = ( 60 * ( b - r ) / diff ) + 120; 9830 } else { 9831 h = ( 60 * ( r - g ) / diff ) + 240; 9832 } 9833 9834 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 9835 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 9836 if ( diff === 0 ) { 9837 s = 0; 9838 } else if ( l <= 0.5 ) { 9839 s = diff / add; 9840 } else { 9841 s = diff / ( 2 - add ); 9842 } 9843 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 9844}; 9845 9846spaces.hsla.from = function( hsla ) { 9847 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 9848 return [ null, null, null, hsla[ 3 ] ]; 9849 } 9850 var h = hsla[ 0 ] / 360, 9851 s = hsla[ 1 ], 9852 l = hsla[ 2 ], 9853 a = hsla[ 3 ], 9854 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 9855 p = 2 * l - q; 9856 9857 return [ 9858 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 9859 Math.round( hue2rgb( p, q, h ) * 255 ), 9860 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 9861 a 9862 ]; 9863}; 9864 9865each( spaces, function( spaceName, space ) { 9866 var props = space.props, 9867 cache = space.cache, 9868 to = space.to, 9869 from = space.from; 9870 9871 // makes rgba() and hsla() 9872 color.fn[ spaceName ] = function( value ) { 9873 9874 // generate a cache for this space if it doesn't exist 9875 if ( to && !this[ cache ] ) { 9876 this[ cache ] = to( this._rgba ); 9877 } 9878 if ( value === undefined ) { 9879 return this[ cache ].slice(); 9880 } 9881 9882 var ret, 9883 type = jQuery.type( value ), 9884 arr = ( type === "array" || type === "object" ) ? value : arguments, 9885 local = this[ cache ].slice(); 9886 9887 each( props, function( key, prop ) {
vendor: 50,293 bytes, lines 9888-11951
9888 var val = arr[ type === "object" ? key : prop.idx ]; 9889 if ( val == null ) { 9890 val = local[ prop.idx ]; 9891 } 9892 local[ prop.idx ] = clamp( val, prop ); 9893 }); 9894 9895 if ( from ) { 9896 ret = color( from( local ) ); 9897 ret[ cache ] = local; 9898 return ret; 9899 } else { 9900 return color( local ); 9901 } 9902 }; 9903 9904 // makes red() green() blue() alpha() hue() saturation() lightness() 9905 each( props, function( key, prop ) { 9906 // alpha is included in more than one space 9907 if ( color.fn[ key ] ) { 9908 return; 9909 } 9910 color.fn[ key ] = function( value ) { 9911 var vtype = jQuery.type( value ), 9912 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 9913 local = this[ fn ](), 9914 cur = local[ prop.idx ], 9915 match; 9916 9917 if ( vtype === "undefined" ) { 9918 return cur; 9919 } 9920 9921 if ( vtype === "function" ) { 9922 value = value.call( this, cur ); 9923 vtype = jQuery.type( value ); 9924 } 9925 if ( value == null && prop.empty ) { 9926 return this; 9927 } 9928 if ( vtype === "string" ) { 9929 match = rplusequals.exec( value ); 9930 if ( match ) { 9931 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 9932 } 9933 } 9934 local[ prop.idx ] = value; 9935 return this[ fn ]( local ); 9936 }; 9937 }); 9938}); 9939 9940// add cssHook and .fx.step function for each named hook. 9941// accept a space separated string of properties 9942color.hook = function( hook ) { 9943 var hooks = hook.split( " " ); 9944 each( hooks, function( i, hook ) { 9945 jQuery.cssHooks[ hook ] = { 9946 set: function( elem, value ) { 9947 var parsed, curElem, 9948 backgroundColor = ""; 9949 9950 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 9951 value = color( parsed || value ); 9952 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 9953 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 9954 while ( 9955 (backgroundColor === "" || backgroundColor === "transparent") && 9956 curElem && curElem.style 9957 ) { 9958 try { 9959 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 9960 curElem = curElem.parentNode; 9961 } catch ( e ) { 9962 } 9963 } 9964 9965 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 9966 backgroundColor : 9967 "_default" ); 9968 } 9969 9970 value = value.toRgbaString(); 9971 } 9972 try { 9973 elem.style[ hook ] = value; 9974 } catch ( e ) { 9975 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 9976 } 9977 } 9978 }; 9979 jQuery.fx.step[ hook ] = function( fx ) { 9980 if ( !fx.colorInit ) { 9981 fx.start = color( fx.elem, hook ); 9982 fx.end = color( fx.end ); 9983 fx.colorInit = true; 9984 } 9985 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 9986 }; 9987 }); 9988 9989}; 9990 9991color.hook( stepHooks ); 9992 9993jQuery.cssHooks.borderColor = { 9994 expand: function( value ) { 9995 var expanded = {}; 9996 9997 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 9998 expanded[ "border" + part + "Color" ] = value; 9999 }); 10000 return expanded; 10001 } 10002}; 10003 10004// Basic color names only. 10005// Usage of any of the other color names requires adding yourself or including 10006// jquery.color.svg-names.js. 10007colors = jQuery.Color.names = { 10008 // 4.1. Basic color keywords 10009 aqua: "#00ffff", 10010 black: "#000000", 10011 blue: "#0000ff", 10012 fuchsia: "#ff00ff", 10013 gray: "#808080", 10014 green: "#008000", 10015 lime: "#00ff00", 10016 maroon: "#800000", 10017 navy: "#000080", 10018 olive: "#808000", 10019 purple: "#800080", 10020 red: "#ff0000", 10021 silver: "#c0c0c0", 10022 teal: "#008080", 10023 white: "#ffffff", 10024 yellow: "#ffff00", 10025 10026 // 4.2.3. "transparent" color keyword 10027 transparent: [ null, null, null, 0 ], 10028 10029 _default: "#ffffff" 10030}; 10031 10032})( jQuery ); 10033 10034/******************************************************************************/ 10035/****************************** CLASS ANIMATIONS ******************************/ 10036/******************************************************************************/ 10037(function() { 10038 10039var classAnimationActions = [ "add", "remove", "toggle" ], 10040 shorthandStyles = { 10041 border: 1, 10042 borderBottom: 1, 10043 borderColor: 1, 10044 borderLeft: 1, 10045 borderRight: 1, 10046 borderTop: 1, 10047 borderWidth: 1, 10048 margin: 1, 10049 padding: 1 10050 }; 10051 10052$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 10053 $.fx.step[ prop ] = function( fx ) { 10054 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 10055 jQuery.style( fx.elem, prop, fx.end ); 10056 fx.setAttr = true; 10057 } 10058 }; 10059}); 10060 10061function getElementStyles( elem ) { 10062 var key, len, 10063 style = elem.ownerDocument.defaultView ? 10064 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 10065 elem.currentStyle, 10066 styles = {}; 10067 10068 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 10069 len = style.length; 10070 while ( len-- ) { 10071 key = style[ len ]; 10072 if ( typeof style[ key ] === "string" ) { 10073 styles[ $.camelCase( key ) ] = style[ key ]; 10074 } 10075 } 10076 // support: Opera, IE <9 10077 } else { 10078 for ( key in style ) { 10079 if ( typeof style[ key ] === "string" ) { 10080 styles[ key ] = style[ key ]; 10081 } 10082 } 10083 } 10084 10085 return styles; 10086} 10087 10088function styleDifference( oldStyle, newStyle ) { 10089 var diff = {}, 10090 name, value; 10091 10092 for ( name in newStyle ) { 10093 value = newStyle[ name ]; 10094 if ( oldStyle[ name ] !== value ) { 10095 if ( !shorthandStyles[ name ] ) { 10096 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 10097 diff[ name ] = value; 10098 } 10099 } 10100 } 10101 } 10102 10103 return diff; 10104} 10105 10106// support: jQuery <1.8 10107if ( !$.fn.addBack ) { 10108 $.fn.addBack = function( selector ) { 10109 return this.add( selector == null ? 10110 this.prevObject : this.prevObject.filter( selector ) 10111 ); 10112 }; 10113} 10114 10115$.effects.animateClass = function( value, duration, easing, callback ) { 10116 var o = $.speed( duration, easing, callback ); 10117 10118 return this.queue( function() { 10119 var animated = $( this ), 10120 baseClass = animated.attr( "class" ) || "", 10121 applyClassChange, 10122 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 10123 10124 // map the animated objects to store the original styles. 10125 allAnimations = allAnimations.map(function() { 10126 var el = $( this ); 10127 return { 10128 el: el, 10129 start: getElementStyles( this ) 10130 }; 10131 }); 10132 10133 // apply class change 10134 applyClassChange = function() { 10135 $.each( classAnimationActions, function(i, action) { 10136 if ( value[ action ] ) { 10137 animated[ action + "Class" ]( value[ action ] ); 10138 } 10139 }); 10140 }; 10141 applyClassChange(); 10142 10143 // map all animated objects again - calculate new styles and diff 10144 allAnimations = allAnimations.map(function() { 10145 this.end = getElementStyles( this.el[ 0 ] ); 10146 this.diff = styleDifference( this.start, this.end ); 10147 return this; 10148 }); 10149 10150 // apply original class 10151 animated.attr( "class", baseClass ); 10152 10153 // map all animated objects again - this time collecting a promise 10154 allAnimations = allAnimations.map(function() { 10155 var styleInfo = this, 10156 dfd = $.Deferred(), 10157 opts = $.extend({}, o, { 10158 queue: false, 10159 complete: function() { 10160 dfd.resolve( styleInfo ); 10161 } 10162 }); 10163 10164 this.el.animate( this.diff, opts ); 10165 return dfd.promise(); 10166 }); 10167 10168 // once all animations have completed: 10169 $.when.apply( $, allAnimations.get() ).done(function() { 10170 10171 // set the final class 10172 applyClassChange(); 10173 10174 // for each animated element, 10175 // clear all css properties that were animated 10176 $.each( arguments, function() { 10177 var el = this.el; 10178 $.each( this.diff, function(key) { 10179 el.css( key, "" ); 10180 }); 10181 }); 10182 10183 // this is guarnteed to be there if you use jQuery.speed() 10184 // it also handles dequeuing the next anim... 10185 o.complete.call( animated[ 0 ] ); 10186 }); 10187 }); 10188}; 10189 10190$.fn.extend({ 10191 addClass: (function( orig ) { 10192 return function( classNames, speed, easing, callback ) { 10193 return speed ? 10194 $.effects.animateClass.call( this, 10195 { add: classNames }, speed, easing, callback ) : 10196 orig.apply( this, arguments ); 10197 }; 10198 })( $.fn.addClass ), 10199 10200 removeClass: (function( orig ) { 10201 return function( classNames, speed, easing, callback ) { 10202 return arguments.length > 1 ? 10203 $.effects.animateClass.call( this, 10204 { remove: classNames }, speed, easing, callback ) : 10205 orig.apply( this, arguments ); 10206 }; 10207 })( $.fn.removeClass ), 10208 10209 toggleClass: (function( orig ) { 10210 return function( classNames, force, speed, easing, callback ) { 10211 if ( typeof force === "boolean" || force === undefined ) { 10212 if ( !speed ) { 10213 // without speed parameter 10214 return orig.apply( this, arguments ); 10215 } else { 10216 return $.effects.animateClass.call( this, 10217 (force ? { add: classNames } : { remove: classNames }), 10218 speed, easing, callback ); 10219 } 10220 } else { 10221 // without force parameter 10222 return $.effects.animateClass.call( this, 10223 { toggle: classNames }, force, speed, easing ); 10224 } 10225 }; 10226 })( $.fn.toggleClass ), 10227 10228 switchClass: function( remove, add, speed, easing, callback) { 10229 return $.effects.animateClass.call( this, { 10230 add: add, 10231 remove: remove 10232 }, speed, easing, callback ); 10233 } 10234}); 10235 10236})(); 10237 10238/******************************************************************************/ 10239/*********************************** EFFECTS **********************************/ 10240/******************************************************************************/ 10241 10242(function() { 10243 10244$.extend( $.effects, { 10245 version: "1.11.4", 10246 10247 // Saves a set of properties in a data storage 10248 save: function( element, set ) { 10249 for ( var i = 0; i < set.length; i++ ) { 10250 if ( set[ i ] !== null ) { 10251 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 10252 } 10253 } 10254 }, 10255 10256 // Restores a set of previously saved properties from a data storage 10257 restore: function( element, set ) { 10258 var val, i; 10259 for ( i = 0; i < set.length; i++ ) { 10260 if ( set[ i ] !== null ) { 10261 val = element.data( dataSpace + set[ i ] ); 10262 // support: jQuery 1.6.2 10263 // http://bugs.jquery.com/ticket/9917 10264 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 10265 // We can't differentiate between "" and 0 here, so we just assume 10266 // empty string since it's likely to be a more common value... 10267 if ( val === undefined ) { 10268 val = ""; 10269 } 10270 element.css( set[ i ], val ); 10271 } 10272 } 10273 }, 10274 10275 setMode: function( el, mode ) { 10276 if (mode === "toggle") { 10277 mode = el.is( ":hidden" ) ? "show" : "hide"; 10278 } 10279 return mode; 10280 }, 10281 10282 // Translates a [top,left] array into a baseline value 10283 // this should be a little more flexible in the future to handle a string & hash 10284 getBaseline: function( origin, original ) { 10285 var y, x; 10286 switch ( origin[ 0 ] ) { 10287 case "top": y = 0; break; 10288 case "middle": y = 0.5; break; 10289 case "bottom": y = 1; break; 10290 default: y = origin[ 0 ] / original.height; 10291 } 10292 switch ( origin[ 1 ] ) { 10293 case "left": x = 0; break; 10294 case "center": x = 0.5; break; 10295 case "right": x = 1; break; 10296 default: x = origin[ 1 ] / original.width; 10297 } 10298 return { 10299 x: x, 10300 y: y 10301 }; 10302 }, 10303 10304 // Wraps the element around a wrapper that copies position properties 10305 createWrapper: function( element ) { 10306 10307 // if the element is already wrapped, return it 10308 if ( element.parent().is( ".ui-effects-wrapper" )) { 10309 return element.parent(); 10310 } 10311 10312 // wrap the element 10313 var props = { 10314 width: element.outerWidth(true), 10315 height: element.outerHeight(true), 10316 "float": element.css( "float" ) 10317 }, 10318 wrapper = $( "<div></div>" ) 10319 .addClass( "ui-effects-wrapper" ) 10320 .css({ 10321 fontSize: "100%", 10322 background: "transparent", 10323 border: "none", 10324 margin: 0, 10325 padding: 0 10326 }), 10327 // Store the size in case width/height are defined in % - Fixes #5245 10328 size = { 10329 width: element.width(), 10330 height: element.height() 10331 }, 10332 active = document.activeElement; 10333 10334 // support: Firefox 10335 // Firefox incorrectly exposes anonymous content 10336 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 10337 try { 10338 active.id; 10339 } catch ( e ) { 10340 active = document.body; 10341 } 10342 10343 element.wrap( wrapper ); 10344 10345 // Fixes #7595 - Elements lose focus when wrapped. 10346 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10347 $( active ).focus(); 10348 } 10349 10350 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 10351 10352 // transfer positioning properties to the wrapper 10353 if ( element.css( "position" ) === "static" ) { 10354 wrapper.css({ position: "relative" }); 10355 element.css({ position: "relative" }); 10356 } else { 10357 $.extend( props, { 10358 position: element.css( "position" ), 10359 zIndex: element.css( "z-index" ) 10360 }); 10361 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 10362 props[ pos ] = element.css( pos ); 10363 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 10364 props[ pos ] = "auto"; 10365 } 10366 }); 10367 element.css({ 10368 position: "relative", 10369 top: 0, 10370 left: 0, 10371 right: "auto", 10372 bottom: "auto" 10373 }); 10374 } 10375 element.css(size); 10376 10377 return wrapper.css( props ).show(); 10378 }, 10379 10380 removeWrapper: function( element ) { 10381 var active = document.activeElement; 10382 10383 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 10384 element.parent().replaceWith( element ); 10385 10386 // Fixes #7595 - Elements lose focus when wrapped. 10387 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10388 $( active ).focus(); 10389 } 10390 } 10391 10392 return element; 10393 }, 10394 10395 setTransition: function( element, list, factor, value ) { 10396 value = value || {}; 10397 $.each( list, function( i, x ) { 10398 var unit = element.cssUnit( x ); 10399 if ( unit[ 0 ] > 0 ) { 10400 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 10401 } 10402 }); 10403 return value; 10404 } 10405}); 10406 10407// return an effect options object for the given parameters: 10408function _normalizeArguments( effect, options, speed, callback ) { 10409 10410 // allow passing all options as the first parameter 10411 if ( $.isPlainObject( effect ) ) { 10412 options = effect; 10413 effect = effect.effect; 10414 } 10415 10416 // convert to an object 10417 effect = { effect: effect }; 10418 10419 // catch (effect, null, ...) 10420 if ( options == null ) { 10421 options = {}; 10422 } 10423 10424 // catch (effect, callback) 10425 if ( $.isFunction( options ) ) { 10426 callback = options; 10427 speed = null; 10428 options = {}; 10429 } 10430 10431 // catch (effect, speed, ?) 10432 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 10433 callback = speed; 10434 speed = options; 10435 options = {}; 10436 } 10437 10438 // catch (effect, options, callback) 10439 if ( $.isFunction( speed ) ) { 10440 callback = speed; 10441 speed = null; 10442 } 10443 10444 // add options to effect 10445 if ( options ) { 10446 $.extend( effect, options ); 10447 } 10448 10449 speed = speed || options.duration; 10450 effect.duration = $.fx.off ? 0 : 10451 typeof speed === "number" ? speed : 10452 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 10453 $.fx.speeds._default; 10454 10455 effect.complete = callback || options.complete; 10456 10457 return effect; 10458} 10459 10460function standardAnimationOption( option ) { 10461 // Valid standard speeds (nothing, number, named speed) 10462 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 10463 return true; 10464 } 10465 10466 // Invalid strings - treat as "normal" speed 10467 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 10468 return true; 10469 } 10470 10471 // Complete callback 10472 if ( $.isFunction( option ) ) { 10473 return true; 10474 } 10475 10476 // Options hash (but not naming an effect) 10477 if ( typeof option === "object" && !option.effect ) { 10478 return true; 10479 } 10480 10481 // Didn't match any standard API 10482 return false; 10483} 10484 10485$.fn.extend({ 10486 effect: function( /* effect, options, speed, callback */ ) { 10487 var args = _normalizeArguments.apply( this, arguments ), 10488 mode = args.mode, 10489 queue = args.queue, 10490 effectMethod = $.effects.effect[ args.effect ]; 10491 10492 if ( $.fx.off || !effectMethod ) { 10493 // delegate to the original method (e.g., .show()) if possible 10494 if ( mode ) { 10495 return this[ mode ]( args.duration, args.complete ); 10496 } else { 10497 return this.each( function() { 10498 if ( args.complete ) { 10499 args.complete.call( this ); 10500 } 10501 }); 10502 } 10503 } 10504 10505 function run( next ) { 10506 var elem = $( this ), 10507 complete = args.complete, 10508 mode = args.mode; 10509 10510 function done() { 10511 if ( $.isFunction( complete ) ) { 10512 complete.call( elem[0] ); 10513 } 10514 if ( $.isFunction( next ) ) { 10515 next(); 10516 } 10517 } 10518 10519 // If the element already has the correct final state, delegate to 10520 // the core methods so the internal tracking of "olddisplay" works. 10521 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 10522 elem[ mode ](); 10523 done(); 10524 } else { 10525 effectMethod.call( elem[0], args, done ); 10526 } 10527 } 10528 10529 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 10530 }, 10531 10532 show: (function( orig ) { 10533 return function( option ) { 10534 if ( standardAnimationOption( option ) ) { 10535 return orig.apply( this, arguments ); 10536 } else { 10537 var args = _normalizeArguments.apply( this, arguments ); 10538 args.mode = "show"; 10539 return this.effect.call( this, args ); 10540 } 10541 }; 10542 })( $.fn.show ), 10543 10544 hide: (function( orig ) { 10545 return function( option ) { 10546 if ( standardAnimationOption( option ) ) { 10547 return orig.apply( this, arguments ); 10548 } else { 10549 var args = _normalizeArguments.apply( this, arguments ); 10550 args.mode = "hide"; 10551 return this.effect.call( this, args ); 10552 } 10553 }; 10554 })( $.fn.hide ), 10555 10556 toggle: (function( orig ) { 10557 return function( option ) { 10558 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 10559 return orig.apply( this, arguments ); 10560 } else { 10561 var args = _normalizeArguments.apply( this, arguments ); 10562 args.mode = "toggle"; 10563 return this.effect.call( this, args ); 10564 } 10565 }; 10566 })( $.fn.toggle ), 10567 10568 // helper functions 10569 cssUnit: function(key) { 10570 var style = this.css( key ), 10571 val = []; 10572 10573 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 10574 if ( style.indexOf( unit ) > 0 ) { 10575 val = [ parseFloat( style ), unit ]; 10576 } 10577 }); 10578 return val; 10579 } 10580}); 10581 10582})(); 10583 10584/******************************************************************************/ 10585/*********************************** EASING ***********************************/ 10586/******************************************************************************/ 10587 10588(function() { 10589 10590// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 10591 10592var baseEasings = {}; 10593 10594$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 10595 baseEasings[ name ] = function( p ) { 10596 return Math.pow( p, i + 2 ); 10597 }; 10598}); 10599 10600$.extend( baseEasings, { 10601 Sine: function( p ) { 10602 return 1 - Math.cos( p * Math.PI / 2 ); 10603 }, 10604 Circ: function( p ) { 10605 return 1 - Math.sqrt( 1 - p * p ); 10606 }, 10607 Elastic: function( p ) { 10608 return p === 0 || p === 1 ? p : 10609 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 10610 }, 10611 Back: function( p ) { 10612 return p * p * ( 3 * p - 2 ); 10613 }, 10614 Bounce: function( p ) { 10615 var pow2, 10616 bounce = 4; 10617 10618 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 10619 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 10620 } 10621}); 10622 10623$.each( baseEasings, function( name, easeIn ) { 10624 $.easing[ "easeIn" + name ] = easeIn; 10625 $.easing[ "easeOut" + name ] = function( p ) { 10626 return 1 - easeIn( 1 - p ); 10627 }; 10628 $.easing[ "easeInOut" + name ] = function( p ) { 10629 return p < 0.5 ? 10630 easeIn( p * 2 ) / 2 : 10631 1 - easeIn( p * -2 + 2 ) / 2; 10632 }; 10633}); 10634 10635})(); 10636 10637var effect = $.effects; 10638 10639 10640/*! 10641 * jQuery UI Effects Blind 1.11.4 10642 * http://jqueryui.com 10643 * 10644 * Copyright jQuery Foundation and other contributors 10645 * Released under the MIT license. 10646 * http://jquery.org/license 10647 * 10648 * http://api.jqueryui.com/blind-effect/ 10649 */ 10650 10651 10652var effectBlind = $.effects.effect.blind = function( o, done ) { 10653 // Create element 10654 var el = $( this ), 10655 rvertical = /up|down|vertical/, 10656 rpositivemotion = /up|left|vertical|horizontal/, 10657 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10658 mode = $.effects.setMode( el, o.mode || "hide" ), 10659 direction = o.direction || "up", 10660 vertical = rvertical.test( direction ), 10661 ref = vertical ? "height" : "width", 10662 ref2 = vertical ? "top" : "left", 10663 motion = rpositivemotion.test( direction ), 10664 animation = {}, 10665 show = mode === "show", 10666 wrapper, distance, margin; 10667 10668 // if already wrapped, the wrapper's properties are my property. #6245 10669 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10670 $.effects.save( el.parent(), props ); 10671 } else { 10672 $.effects.save( el, props ); 10673 } 10674 el.show(); 10675 wrapper = $.effects.createWrapper( el ).css({ 10676 overflow: "hidden" 10677 }); 10678 10679 distance = wrapper[ ref ](); 10680 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10681 10682 animation[ ref ] = show ? distance : 0; 10683 if ( !motion ) { 10684 el 10685 .css( vertical ? "bottom" : "right", 0 ) 10686 .css( vertical ? "top" : "left", "auto" ) 10687 .css({ position: "absolute" }); 10688 10689 animation[ ref2 ] = show ? margin : distance + margin; 10690 } 10691 10692 // start at 0 if we are showing 10693 if ( show ) { 10694 wrapper.css( ref, 0 ); 10695 if ( !motion ) { 10696 wrapper.css( ref2, margin + distance ); 10697 } 10698 } 10699 10700 // Animate 10701 wrapper.animate( animation, { 10702 duration: o.duration, 10703 easing: o.easing, 10704 queue: false, 10705 complete: function() { 10706 if ( mode === "hide" ) { 10707 el.hide(); 10708 } 10709 $.effects.restore( el, props ); 10710 $.effects.removeWrapper( el ); 10711 done(); 10712 } 10713 }); 10714}; 10715 10716 10717/*! 10718 * jQuery UI Effects Bounce 1.11.4 10719 * http://jqueryui.com 10720 * 10721 * Copyright jQuery Foundation and other contributors 10722 * Released under the MIT license. 10723 * http://jquery.org/license 10724 * 10725 * http://api.jqueryui.com/bounce-effect/ 10726 */ 10727 10728 10729var effectBounce = $.effects.effect.bounce = function( o, done ) { 10730 var el = $( this ), 10731 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10732 10733 // defaults: 10734 mode = $.effects.setMode( el, o.mode || "effect" ), 10735 hide = mode === "hide", 10736 show = mode === "show", 10737 direction = o.direction || "up", 10738 distance = o.distance, 10739 times = o.times || 5, 10740 10741 // number of internal animations 10742 anims = times * 2 + ( show || hide ? 1 : 0 ), 10743 speed = o.duration / anims, 10744 easing = o.easing, 10745 10746 // utility: 10747 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10748 motion = ( direction === "up" || direction === "left" ), 10749 i, 10750 upAnim, 10751 downAnim, 10752 10753 // we will need to re-assemble the queue to stack our animations in place 10754 queue = el.queue(), 10755 queuelen = queue.length; 10756 10757 // Avoid touching opacity to prevent clearType and PNG issues in IE 10758 if ( show || hide ) { 10759 props.push( "opacity" ); 10760 } 10761 10762 $.effects.save( el, props ); 10763 el.show(); 10764 $.effects.createWrapper( el ); // Create Wrapper 10765 10766 // default distance for the BIGGEST bounce is the outer Distance / 3 10767 if ( !distance ) { 10768 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10769 } 10770 10771 if ( show ) { 10772 downAnim = { opacity: 1 }; 10773 downAnim[ ref ] = 0; 10774 10775 // if we are showing, force opacity 0 and set the initial position 10776 // then do the "first" animation 10777 el.css( "opacity", 0 ) 10778 .css( ref, motion ? -distance * 2 : distance * 2 ) 10779 .animate( downAnim, speed, easing ); 10780 } 10781 10782 // start at the smallest distance if we are hiding 10783 if ( hide ) { 10784 distance = distance / Math.pow( 2, times - 1 ); 10785 } 10786 10787 downAnim = {}; 10788 downAnim[ ref ] = 0; 10789 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10790 for ( i = 0; i < times; i++ ) { 10791 upAnim = {}; 10792 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10793 10794 el.animate( upAnim, speed, easing ) 10795 .animate( downAnim, speed, easing ); 10796 10797 distance = hide ? distance * 2 : distance / 2; 10798 } 10799 10800 // Last Bounce when Hiding 10801 if ( hide ) { 10802 upAnim = { opacity: 0 }; 10803 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10804 10805 el.animate( upAnim, speed, easing ); 10806 } 10807 10808 el.queue(function() { 10809 if ( hide ) { 10810 el.hide(); 10811 } 10812 $.effects.restore( el, props ); 10813 $.effects.removeWrapper( el ); 10814 done(); 10815 }); 10816 10817 // inject all the animations we just queued to be first in line (after "inprogress") 10818 if ( queuelen > 1) { 10819 queue.splice.apply( queue, 10820 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10821 } 10822 el.dequeue(); 10823 10824}; 10825 10826 10827/*! 10828 * jQuery UI Effects Clip 1.11.4 10829 * http://jqueryui.com 10830 * 10831 * Copyright jQuery Foundation and other contributors 10832 * Released under the MIT license. 10833 * http://jquery.org/license 10834 * 10835 * http://api.jqueryui.com/clip-effect/ 10836 */ 10837 10838 10839var effectClip = $.effects.effect.clip = function( o, done ) { 10840 // Create element 10841 var el = $( this ), 10842 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10843 mode = $.effects.setMode( el, o.mode || "hide" ), 10844 show = mode === "show", 10845 direction = o.direction || "vertical", 10846 vert = direction === "vertical", 10847 size = vert ? "height" : "width", 10848 position = vert ? "top" : "left", 10849 animation = {}, 10850 wrapper, animate, distance; 10851 10852 // Save & Show 10853 $.effects.save( el, props ); 10854 el.show(); 10855 10856 // Create Wrapper 10857 wrapper = $.effects.createWrapper( el ).css({ 10858 overflow: "hidden" 10859 }); 10860 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10861 distance = animate[ size ](); 10862 10863 // Shift 10864 if ( show ) { 10865 animate.css( size, 0 ); 10866 animate.css( position, distance / 2 ); 10867 } 10868 10869 // Create Animation Object: 10870 animation[ size ] = show ? distance : 0; 10871 animation[ position ] = show ? 0 : distance / 2; 10872 10873 // Animate 10874 animate.animate( animation, { 10875 queue: false, 10876 duration: o.duration, 10877 easing: o.easing, 10878 complete: function() { 10879 if ( !show ) { 10880 el.hide(); 10881 } 10882 $.effects.restore( el, props ); 10883 $.effects.removeWrapper( el ); 10884 done(); 10885 } 10886 }); 10887 10888}; 10889 10890 10891/*! 10892 * jQuery UI Effects Drop 1.11.4 10893 * http://jqueryui.com 10894 * 10895 * Copyright jQuery Foundation and other contributors 10896 * Released under the MIT license. 10897 * http://jquery.org/license 10898 * 10899 * http://api.jqueryui.com/drop-effect/ 10900 */ 10901 10902 10903var effectDrop = $.effects.effect.drop = function( o, done ) { 10904 10905 var el = $( this ), 10906 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10907 mode = $.effects.setMode( el, o.mode || "hide" ), 10908 show = mode === "show", 10909 direction = o.direction || "left", 10910 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10911 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10912 animation = { 10913 opacity: show ? 1 : 0 10914 }, 10915 distance; 10916 10917 // Adjust 10918 $.effects.save( el, props ); 10919 el.show(); 10920 $.effects.createWrapper( el ); 10921 10922 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 10923 10924 if ( show ) { 10925 el 10926 .css( "opacity", 0 ) 10927 .css( ref, motion === "pos" ? -distance : distance ); 10928 } 10929 10930 // Animation 10931 animation[ ref ] = ( show ? 10932 ( motion === "pos" ? "+=" : "-=" ) : 10933 ( motion === "pos" ? "-=" : "+=" ) ) + 10934 distance; 10935 10936 // Animate 10937 el.animate( animation, { 10938 queue: false, 10939 duration: o.duration, 10940 easing: o.easing, 10941 complete: function() { 10942 if ( mode === "hide" ) { 10943 el.hide(); 10944 } 10945 $.effects.restore( el, props ); 10946 $.effects.removeWrapper( el ); 10947 done(); 10948 } 10949 }); 10950}; 10951 10952 10953/*! 10954 * jQuery UI Effects Explode 1.11.4 10955 * http://jqueryui.com 10956 * 10957 * Copyright jQuery Foundation and other contributors 10958 * Released under the MIT license. 10959 * http://jquery.org/license 10960 * 10961 * http://api.jqueryui.com/explode-effect/ 10962 */ 10963 10964 10965var effectExplode = $.effects.effect.explode = function( o, done ) { 10966 10967 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10968 cells = rows, 10969 el = $( this ), 10970 mode = $.effects.setMode( el, o.mode || "hide" ), 10971 show = mode === "show", 10972 10973 // show and then visibility:hidden the element before calculating offset 10974 offset = el.show().css( "visibility", "hidden" ).offset(), 10975 10976 // width and height of a piece 10977 width = Math.ceil( el.outerWidth() / cells ), 10978 height = Math.ceil( el.outerHeight() / rows ), 10979 pieces = [], 10980 10981 // loop 10982 i, j, left, top, mx, my; 10983 10984 // children animate complete: 10985 function childComplete() { 10986 pieces.push( this ); 10987 if ( pieces.length === rows * cells ) { 10988 animComplete(); 10989 } 10990 } 10991 10992 // clone the element for each row and cell. 10993 for ( i = 0; i < rows ; i++ ) { // ===> 10994 top = offset.top + i * height; 10995 my = i - ( rows - 1 ) / 2 ; 10996 10997 for ( j = 0; j < cells ; j++ ) { // ||| 10998 left = offset.left + j * width; 10999 mx = j - ( cells - 1 ) / 2 ; 11000 11001 // Create a clone of the now hidden main element that will be absolute positioned 11002 // within a wrapper div off the -left and -top equal to size of our pieces 11003 el 11004 .clone() 11005 .appendTo( "body" ) 11006 .wrap( "<div></div>" ) 11007 .css({ 11008 position: "absolute", 11009 visibility: "visible", 11010 left: -j * width, 11011 top: -i * height 11012 }) 11013 11014 // select the wrapper - make it overflow: hidden and absolute positioned based on 11015 // where the original was located +left and +top equal to the size of pieces 11016 .parent() 11017 .addClass( "ui-effects-explode" ) 11018 .css({ 11019 position: "absolute", 11020 overflow: "hidden", 11021 width: width, 11022 height: height, 11023 left: left + ( show ? mx * width : 0 ), 11024 top: top + ( show ? my * height : 0 ), 11025 opacity: show ? 0 : 1 11026 }).animate({ 11027 left: left + ( show ? 0 : mx * width ), 11028 top: top + ( show ? 0 : my * height ), 11029 opacity: show ? 1 : 0 11030 }, o.duration || 500, o.easing, childComplete ); 11031 } 11032 } 11033 11034 function animComplete() { 11035 el.css({ 11036 visibility: "visible" 11037 }); 11038 $( pieces ).remove(); 11039 if ( !show ) { 11040 el.hide(); 11041 } 11042 done(); 11043 } 11044}; 11045 11046 11047/*! 11048 * jQuery UI Effects Fade 1.11.4 11049 * http://jqueryui.com 11050 * 11051 * Copyright jQuery Foundation and other contributors 11052 * Released under the MIT license. 11053 * http://jquery.org/license 11054 * 11055 * http://api.jqueryui.com/fade-effect/ 11056 */ 11057 11058 11059var effectFade = $.effects.effect.fade = function( o, done ) { 11060 var el = $( this ), 11061 mode = $.effects.setMode( el, o.mode || "toggle" ); 11062 11063 el.animate({ 11064 opacity: mode 11065 }, { 11066 queue: false, 11067 duration: o.duration, 11068 easing: o.easing, 11069 complete: done 11070 }); 11071}; 11072 11073 11074/*! 11075 * jQuery UI Effects Fold 1.11.4 11076 * http://jqueryui.com 11077 * 11078 * Copyright jQuery Foundation and other contributors 11079 * Released under the MIT license. 11080 * http://jquery.org/license 11081 * 11082 * http://api.jqueryui.com/fold-effect/ 11083 */ 11084 11085 11086var effectFold = $.effects.effect.fold = function( o, done ) { 11087 11088 // Create element 11089 var el = $( this ), 11090 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11091 mode = $.effects.setMode( el, o.mode || "hide" ), 11092 show = mode === "show", 11093 hide = mode === "hide", 11094 size = o.size || 15, 11095 percent = /([0-9]+)%/.exec( size ), 11096 horizFirst = !!o.horizFirst, 11097 widthFirst = show !== horizFirst, 11098 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 11099 duration = o.duration / 2, 11100 wrapper, distance, 11101 animation1 = {}, 11102 animation2 = {}; 11103 11104 $.effects.save( el, props ); 11105 el.show(); 11106 11107 // Create Wrapper 11108 wrapper = $.effects.createWrapper( el ).css({ 11109 overflow: "hidden" 11110 }); 11111 distance = widthFirst ? 11112 [ wrapper.width(), wrapper.height() ] : 11113 [ wrapper.height(), wrapper.width() ]; 11114 11115 if ( percent ) { 11116 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 11117 } 11118 if ( show ) { 11119 wrapper.css( horizFirst ? { 11120 height: 0, 11121 width: size 11122 } : { 11123 height: size, 11124 width: 0 11125 }); 11126 } 11127 11128 // Animation 11129 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 11130 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 11131 11132 // Animate 11133 wrapper 11134 .animate( animation1, duration, o.easing ) 11135 .animate( animation2, duration, o.easing, function() { 11136 if ( hide ) { 11137 el.hide(); 11138 } 11139 $.effects.restore( el, props ); 11140 $.effects.removeWrapper( el ); 11141 done(); 11142 }); 11143 11144}; 11145 11146 11147/*! 11148 * jQuery UI Effects Highlight 1.11.4 11149 * http://jqueryui.com 11150 * 11151 * Copyright jQuery Foundation and other contributors 11152 * Released under the MIT license. 11153 * http://jquery.org/license 11154 * 11155 * http://api.jqueryui.com/highlight-effect/ 11156 */ 11157 11158 11159var effectHighlight = $.effects.effect.highlight = function( o, done ) { 11160 var elem = $( this ), 11161 props = [ "backgroundImage", "backgroundColor", "opacity" ], 11162 mode = $.effects.setMode( elem, o.mode || "show" ), 11163 animation = { 11164 backgroundColor: elem.css( "backgroundColor" ) 11165 }; 11166 11167 if (mode === "hide") { 11168 animation.opacity = 0; 11169 } 11170 11171 $.effects.save( elem, props ); 11172 11173 elem 11174 .show() 11175 .css({ 11176 backgroundImage: "none", 11177 backgroundColor: o.color || "#ffff99" 11178 }) 11179 .animate( animation, { 11180 queue: false, 11181 duration: o.duration, 11182 easing: o.easing, 11183 complete: function() { 11184 if ( mode === "hide" ) { 11185 elem.hide(); 11186 } 11187 $.effects.restore( elem, props ); 11188 done(); 11189 } 11190 }); 11191}; 11192 11193 11194/*! 11195 * jQuery UI Effects Size 1.11.4 11196 * http://jqueryui.com 11197 * 11198 * Copyright jQuery Foundation and other contributors 11199 * Released under the MIT license. 11200 * http://jquery.org/license 11201 * 11202 * http://api.jqueryui.com/size-effect/ 11203 */ 11204 11205 11206var effectSize = $.effects.effect.size = function( o, done ) { 11207 11208 // Create element 11209 var original, baseline, factor, 11210 el = $( this ), 11211 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11212 11213 // Always restore 11214 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11215 11216 // Copy for children 11217 props2 = [ "width", "height", "overflow" ], 11218 cProps = [ "fontSize" ], 11219 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11220 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11221 11222 // Set options 11223 mode = $.effects.setMode( el, o.mode || "effect" ), 11224 restore = o.restore || mode !== "effect", 11225 scale = o.scale || "both", 11226 origin = o.origin || [ "middle", "center" ], 11227 position = el.css( "position" ), 11228 props = restore ? props0 : props1, 11229 zero = { 11230 height: 0, 11231 width: 0, 11232 outerHeight: 0, 11233 outerWidth: 0 11234 }; 11235 11236 if ( mode === "show" ) { 11237 el.show(); 11238 } 11239 original = { 11240 height: el.height(), 11241 width: el.width(), 11242 outerHeight: el.outerHeight(), 11243 outerWidth: el.outerWidth() 11244 }; 11245 11246 if ( o.mode === "toggle" && mode === "show" ) { 11247 el.from = o.to || zero; 11248 el.to = o.from || original; 11249 } else { 11250 el.from = o.from || ( mode === "show" ? zero : original ); 11251 el.to = o.to || ( mode === "hide" ? zero : original ); 11252 } 11253 11254 // Set scaling factor 11255 factor = { 11256 from: { 11257 y: el.from.height / original.height, 11258 x: el.from.width / original.width 11259 }, 11260 to: { 11261 y: el.to.height / original.height, 11262 x: el.to.width / original.width 11263 } 11264 }; 11265 11266 // Scale the css box 11267 if ( scale === "box" || scale === "both" ) { 11268 11269 // Vertical props scaling 11270 if ( factor.from.y !== factor.to.y ) { 11271 props = props.concat( vProps ); 11272 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11273 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11274 } 11275 11276 // Horizontal props scaling 11277 if ( factor.from.x !== factor.to.x ) { 11278 props = props.concat( hProps ); 11279 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11280 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11281 } 11282 } 11283 11284 // Scale the content 11285 if ( scale === "content" || scale === "both" ) { 11286 11287 // Vertical props scaling 11288 if ( factor.from.y !== factor.to.y ) { 11289 props = props.concat( cProps ).concat( props2 ); 11290 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11291 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11292 } 11293 } 11294 11295 $.effects.save( el, props ); 11296 el.show(); 11297 $.effects.createWrapper( el ); 11298 el.css( "overflow", "hidden" ).css( el.from ); 11299 11300 // Adjust 11301 if (origin) { // Calculate baseline shifts 11302 baseline = $.effects.getBaseline( origin, original ); 11303 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11304 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11305 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11306 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11307 } 11308 el.css( el.from ); // set top & left 11309 11310 // Animate 11311 if ( scale === "content" || scale === "both" ) { // Scale the children 11312 11313 // Add margins/font-size 11314 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11315 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11316 props2 = props0.concat(vProps).concat(hProps); 11317 11318 el.find( "*[width]" ).each( function() { 11319 var child = $( this ), 11320 c_original = { 11321 height: child.height(), 11322 width: child.width(), 11323 outerHeight: child.outerHeight(), 11324 outerWidth: child.outerWidth() 11325 }; 11326 if (restore) { 11327 $.effects.save(child, props2); 11328 } 11329 11330 child.from = { 11331 height: c_original.height * factor.from.y, 11332 width: c_original.width * factor.from.x, 11333 outerHeight: c_original.outerHeight * factor.from.y, 11334 outerWidth: c_original.outerWidth * factor.from.x 11335 }; 11336 child.to = { 11337 height: c_original.height * factor.to.y, 11338 width: c_original.width * factor.to.x, 11339 outerHeight: c_original.height * factor.to.y, 11340 outerWidth: c_original.width * factor.to.x 11341 }; 11342 11343 // Vertical props scaling 11344 if ( factor.from.y !== factor.to.y ) { 11345 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11346 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11347 } 11348 11349 // Horizontal props scaling 11350 if ( factor.from.x !== factor.to.x ) { 11351 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11352 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11353 } 11354 11355 // Animate children 11356 child.css( child.from ); 11357 child.animate( child.to, o.duration, o.easing, function() { 11358 11359 // Restore children 11360 if ( restore ) { 11361 $.effects.restore( child, props2 ); 11362 } 11363 }); 11364 }); 11365 } 11366 11367 // Animate 11368 el.animate( el.to, { 11369 queue: false, 11370 duration: o.duration, 11371 easing: o.easing, 11372 complete: function() { 11373 if ( el.to.opacity === 0 ) { 11374 el.css( "opacity", el.from.opacity ); 11375 } 11376 if ( mode === "hide" ) { 11377 el.hide(); 11378 } 11379 $.effects.restore( el, props ); 11380 if ( !restore ) { 11381 11382 // we need to calculate our new positioning based on the scaling 11383 if ( position === "static" ) { 11384 el.css({ 11385 position: "relative", 11386 top: el.to.top, 11387 left: el.to.left 11388 }); 11389 } else { 11390 $.each([ "top", "left" ], function( idx, pos ) { 11391 el.css( pos, function( _, str ) { 11392 var val = parseInt( str, 10 ), 11393 toRef = idx ? el.to.left : el.to.top; 11394 11395 // if original was "auto", recalculate the new value from wrapper 11396 if ( str === "auto" ) { 11397 return toRef + "px"; 11398 } 11399 11400 return val + toRef + "px"; 11401 }); 11402 }); 11403 } 11404 } 11405 11406 $.effects.removeWrapper( el ); 11407 done(); 11408 } 11409 }); 11410 11411}; 11412 11413 11414/*! 11415 * jQuery UI Effects Scale 1.11.4 11416 * http://jqueryui.com 11417 * 11418 * Copyright jQuery Foundation and other contributors 11419 * Released under the MIT license. 11420 * http://jquery.org/license 11421 * 11422 * http://api.jqueryui.com/scale-effect/ 11423 */ 11424 11425 11426var effectScale = $.effects.effect.scale = function( o, done ) { 11427 11428 // Create element 11429 var el = $( this ), 11430 options = $.extend( true, {}, o ), 11431 mode = $.effects.setMode( el, o.mode || "effect" ), 11432 percent = parseInt( o.percent, 10 ) || 11433 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 11434 direction = o.direction || "both", 11435 origin = o.origin, 11436 original = { 11437 height: el.height(), 11438 width: el.width(), 11439 outerHeight: el.outerHeight(), 11440 outerWidth: el.outerWidth() 11441 }, 11442 factor = { 11443 y: direction !== "horizontal" ? (percent / 100) : 1, 11444 x: direction !== "vertical" ? (percent / 100) : 1 11445 }; 11446 11447 // We are going to pass this effect to the size effect: 11448 options.effect = "size"; 11449 options.queue = false; 11450 options.complete = done; 11451 11452 // Set default origin and restore for show/hide 11453 if ( mode !== "effect" ) { 11454 options.origin = origin || [ "middle", "center" ]; 11455 options.restore = true; 11456 } 11457 11458 options.from = o.from || ( mode === "show" ? { 11459 height: 0, 11460 width: 0, 11461 outerHeight: 0, 11462 outerWidth: 0 11463 } : original ); 11464 options.to = { 11465 height: original.height * factor.y, 11466 width: original.width * factor.x, 11467 outerHeight: original.outerHeight * factor.y, 11468 outerWidth: original.outerWidth * factor.x 11469 }; 11470 11471 // Fade option to support puff 11472 if ( options.fade ) { 11473 if ( mode === "show" ) { 11474 options.from.opacity = 0; 11475 options.to.opacity = 1; 11476 } 11477 if ( mode === "hide" ) { 11478 options.from.opacity = 1; 11479 options.to.opacity = 0; 11480 } 11481 } 11482 11483 // Animate 11484 el.effect( options ); 11485 11486}; 11487 11488 11489/*! 11490 * jQuery UI Effects Puff 1.11.4 11491 * http://jqueryui.com 11492 * 11493 * Copyright jQuery Foundation and other contributors 11494 * Released under the MIT license. 11495 * http://jquery.org/license 11496 * 11497 * http://api.jqueryui.com/puff-effect/ 11498 */ 11499 11500 11501var effectPuff = $.effects.effect.puff = function( o, done ) { 11502 var elem = $( this ), 11503 mode = $.effects.setMode( elem, o.mode || "hide" ), 11504 hide = mode === "hide", 11505 percent = parseInt( o.percent, 10 ) || 150, 11506 factor = percent / 100, 11507 original = { 11508 height: elem.height(), 11509 width: elem.width(), 11510 outerHeight: elem.outerHeight(), 11511 outerWidth: elem.outerWidth() 11512 }; 11513 11514 $.extend( o, { 11515 effect: "scale", 11516 queue: false, 11517 fade: true, 11518 mode: mode, 11519 complete: done, 11520 percent: hide ? percent : 100, 11521 from: hide ? 11522 original : 11523 { 11524 height: original.height * factor, 11525 width: original.width * factor, 11526 outerHeight: original.outerHeight * factor, 11527 outerWidth: original.outerWidth * factor 11528 } 11529 }); 11530 11531 elem.effect( o ); 11532}; 11533 11534 11535/*! 11536 * jQuery UI Effects Pulsate 1.11.4 11537 * http://jqueryui.com 11538 * 11539 * Copyright jQuery Foundation and other contributors 11540 * Released under the MIT license. 11541 * http://jquery.org/license 11542 * 11543 * http://api.jqueryui.com/pulsate-effect/ 11544 */ 11545 11546 11547var effectPulsate = $.effects.effect.pulsate = function( o, done ) { 11548 var elem = $( this ), 11549 mode = $.effects.setMode( elem, o.mode || "show" ), 11550 show = mode === "show", 11551 hide = mode === "hide", 11552 showhide = ( show || mode === "hide" ), 11553 11554 // showing or hiding leaves of the "last" animation 11555 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 11556 duration = o.duration / anims, 11557 animateTo = 0, 11558 queue = elem.queue(), 11559 queuelen = queue.length, 11560 i; 11561 11562 if ( show || !elem.is(":visible")) { 11563 elem.css( "opacity", 0 ).show(); 11564 animateTo = 1; 11565 } 11566 11567 // anims - 1 opacity "toggles" 11568 for ( i = 1; i < anims; i++ ) { 11569 elem.animate({ 11570 opacity: animateTo 11571 }, duration, o.easing ); 11572 animateTo = 1 - animateTo; 11573 } 11574 11575 elem.animate({ 11576 opacity: animateTo 11577 }, duration, o.easing); 11578 11579 elem.queue(function() { 11580 if ( hide ) { 11581 elem.hide(); 11582 } 11583 done(); 11584 }); 11585 11586 // We just queued up "anims" animations, we need to put them next in the queue 11587 if ( queuelen > 1 ) { 11588 queue.splice.apply( queue, 11589 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11590 } 11591 elem.dequeue(); 11592}; 11593 11594 11595/*! 11596 * jQuery UI Effects Shake 1.11.4 11597 * http://jqueryui.com 11598 * 11599 * Copyright jQuery Foundation and other contributors 11600 * Released under the MIT license. 11601 * http://jquery.org/license 11602 * 11603 * http://api.jqueryui.com/shake-effect/ 11604 */ 11605 11606 11607var effectShake = $.effects.effect.shake = function( o, done ) { 11608 11609 var el = $( this ), 11610 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11611 mode = $.effects.setMode( el, o.mode || "effect" ), 11612 direction = o.direction || "left", 11613 distance = o.distance || 20, 11614 times = o.times || 3, 11615 anims = times * 2 + 1, 11616 speed = Math.round( o.duration / anims ), 11617 ref = (direction === "up" || direction === "down") ? "top" : "left", 11618 positiveMotion = (direction === "up" || direction === "left"), 11619 animation = {}, 11620 animation1 = {}, 11621 animation2 = {}, 11622 i, 11623 11624 // we will need to re-assemble the queue to stack our animations in place 11625 queue = el.queue(), 11626 queuelen = queue.length; 11627 11628 $.effects.save( el, props ); 11629 el.show(); 11630 $.effects.createWrapper( el ); 11631 11632 // Animation 11633 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11634 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11635 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11636 11637 // Animate 11638 el.animate( animation, speed, o.easing ); 11639 11640 // Shakes 11641 for ( i = 1; i < times; i++ ) { 11642 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11643 } 11644 el 11645 .animate( animation1, speed, o.easing ) 11646 .animate( animation, speed / 2, o.easing ) 11647 .queue(function() { 11648 if ( mode === "hide" ) { 11649 el.hide(); 11650 } 11651 $.effects.restore( el, props ); 11652 $.effects.removeWrapper( el ); 11653 done(); 11654 }); 11655 11656 // inject all the animations we just queued to be first in line (after "inprogress") 11657 if ( queuelen > 1) { 11658 queue.splice.apply( queue, 11659 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11660 } 11661 el.dequeue(); 11662 11663}; 11664 11665 11666/*! 11667 * jQuery UI Effects Slide 1.11.4 11668 * http://jqueryui.com 11669 * 11670 * Copyright jQuery Foundation and other contributors 11671 * Released under the MIT license. 11672 * http://jquery.org/license 11673 * 11674 * http://api.jqueryui.com/slide-effect/ 11675 */ 11676 11677 11678var effectSlide = $.effects.effect.slide = function( o, done ) { 11679 11680 // Create element 11681 var el = $( this ), 11682 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11683 mode = $.effects.setMode( el, o.mode || "show" ), 11684 show = mode === "show", 11685 direction = o.direction || "left", 11686 ref = (direction === "up" || direction === "down") ? "top" : "left", 11687 positiveMotion = (direction === "up" || direction === "left"), 11688 distance, 11689 animation = {}; 11690 11691 // Adjust 11692 $.effects.save( el, props ); 11693 el.show(); 11694 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11695 11696 $.effects.createWrapper( el ).css({ 11697 overflow: "hidden" 11698 }); 11699 11700 if ( show ) { 11701 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11702 } 11703 11704 // Animation 11705 animation[ ref ] = ( show ? 11706 ( positiveMotion ? "+=" : "-=") : 11707 ( positiveMotion ? "-=" : "+=")) + 11708 distance; 11709 11710 // Animate 11711 el.animate( animation, { 11712 queue: false, 11713 duration: o.duration, 11714 easing: o.easing, 11715 complete: function() { 11716 if ( mode === "hide" ) { 11717 el.hide(); 11718 } 11719 $.effects.restore( el, props ); 11720 $.effects.removeWrapper( el ); 11721 done(); 11722 } 11723 }); 11724}; 11725 11726 11727/*! 11728 * jQuery UI Effects Transfer 1.11.4 11729 * http://jqueryui.com 11730 * 11731 * Copyright jQuery Foundation and other contributors 11732 * Released under the MIT license. 11733 * http://jquery.org/license 11734 * 11735 * http://api.jqueryui.com/transfer-effect/ 11736 */ 11737 11738 11739var effectTransfer = $.effects.effect.transfer = function( o, done ) { 11740 var elem = $( this ), 11741 target = $( o.to ), 11742 targetFixed = target.css( "position" ) === "fixed", 11743 body = $("body"), 11744 fixTop = targetFixed ? body.scrollTop() : 0, 11745 fixLeft = targetFixed ? body.scrollLeft() : 0, 11746 endPosition = target.offset(), 11747 animation = { 11748 top: endPosition.top - fixTop, 11749 left: endPosition.left - fixLeft, 11750 height: target.innerHeight(), 11751 width: target.innerWidth() 11752 }, 11753 startPosition = elem.offset(), 11754 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11755 .appendTo( document.body ) 11756 .addClass( o.className ) 11757 .css({ 11758 top: startPosition.top - fixTop, 11759 left: startPosition.left - fixLeft, 11760 height: elem.innerHeight(), 11761 width: elem.innerWidth(), 11762 position: targetFixed ? "fixed" : "absolute" 11763 }) 11764 .animate( animation, o.duration, o.easing, function() { 11765 transfer.remove(); 11766 done(); 11767 }); 11768}; 11769 11770 11771/*! 11772 * jQuery UI Progressbar 1.11.4 11773 * http://jqueryui.com 11774 * 11775 * Copyright jQuery Foundation and other contributors 11776 * Released under the MIT license. 11777 * http://jquery.org/license 11778 * 11779 * http://api.jqueryui.com/progressbar/ 11780 */ 11781 11782 11783var progressbar = $.widget( "ui.progressbar", { 11784 version: "1.11.4", 11785 options: { 11786 max: 100, 11787 value: 0, 11788 11789 change: null, 11790 complete: null 11791 }, 11792 11793 min: 0, 11794 11795 _create: function() { 11796 // Constrain initial value 11797 this.oldValue = this.options.value = this._constrainedValue(); 11798 11799 this.element 11800 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 11801 .attr({ 11802 // Only set static values, aria-valuenow and aria-valuemax are 11803 // set inside _refreshValue() 11804 role: "progressbar", 11805 "aria-valuemin": this.min 11806 }); 11807 11808 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 11809 .appendTo( this.element ); 11810 11811 this._refreshValue(); 11812 }, 11813 11814 _destroy: function() { 11815 this.element 11816 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 11817 .removeAttr( "role" ) 11818 .removeAttr( "aria-valuemin" ) 11819 .removeAttr( "aria-valuemax" ) 11820 .removeAttr( "aria-valuenow" ); 11821 11822 this.valueDiv.remove(); 11823 }, 11824 11825 value: function( newValue ) { 11826 if ( newValue === undefined ) { 11827 return this.options.value; 11828 } 11829 11830 this.options.value = this._constrainedValue( newValue ); 11831 this._refreshValue(); 11832 }, 11833 11834 _constrainedValue: function( newValue ) { 11835 if ( newValue === undefined ) { 11836 newValue = this.options.value; 11837 } 11838 11839 this.indeterminate = newValue === false; 11840 11841 // sanitize value 11842 if ( typeof newValue !== "number" ) { 11843 newValue = 0; 11844 } 11845 11846 return this.indeterminate ? false : 11847 Math.min( this.options.max, Math.max( this.min, newValue ) ); 11848 }, 11849 11850 _setOptions: function( options ) { 11851 // Ensure "value" option is set after other values (like max) 11852 var value = options.value; 11853 delete options.value; 11854 11855 this._super( options ); 11856 11857 this.options.value = this._constrainedValue( value ); 11858 this._refreshValue(); 11859 }, 11860 11861 _setOption: function( key, value ) { 11862 if ( key === "max" ) { 11863 // Don't allow a max less than min 11864 value = Math.max( this.min, value ); 11865 } 11866 if ( key === "disabled" ) { 11867 this.element 11868 .toggleClass( "ui-state-disabled", !!value ) 11869 .attr( "aria-disabled", value ); 11870 } 11871 this._super( key, value ); 11872 }, 11873 11874 _percentage: function() { 11875 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 11876 }, 11877 11878 _refreshValue: function() { 11879 var value = this.options.value, 11880 percentage = this._percentage(); 11881 11882 this.valueDiv 11883 .toggle( this.indeterminate || value > this.min ) 11884 .toggleClass( "ui-corner-right", value === this.options.max ) 11885 .width( percentage.toFixed(0) + "%" ); 11886 11887 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 11888 11889 if ( this.indeterminate ) { 11890 this.element.removeAttr( "aria-valuenow" ); 11891 if ( !this.overlayDiv ) { 11892 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 11893 } 11894 } else { 11895 this.element.attr({ 11896 "aria-valuemax": this.options.max, 11897 "aria-valuenow": value 11898 }); 11899 if ( this.overlayDiv ) { 11900 this.overlayDiv.remove(); 11901 this.overlayDiv = null; 11902 } 11903 } 11904 11905 if ( this.oldValue !== value ) { 11906 this.oldValue = value; 11907 this._trigger( "change" ); 11908 } 11909 if ( value === this.options.max ) { 11910 this._trigger( "complete" ); 11911 } 11912 } 11913}); 11914 11915 11916/*! 11917 * jQuery UI Selectable 1.11.4 11918 * http://jqueryui.com 11919 * 11920 * Copyright jQuery Foundation and other contributors 11921 * Released under the MIT license. 11922 * http://jquery.org/license 11923 * 11924 * http://api.jqueryui.com/selectable/ 11925 */ 11926 11927 11928var selectable = $.widget("ui.selectable", $.ui.mouse, { 11929 version: "1.11.4", 11930 options: { 11931 appendTo: "body", 11932 autoRefresh: true, 11933 distance: 0, 11934 filter: "*", 11935 tolerance: "touch", 11936 11937 // callbacks 11938 selected: null, 11939 selecting: null, 11940 start: null, 11941 stop: null, 11942 unselected: null, 11943 unselecting: null 11944 }, 11945 _create: function() { 11946 var selectees, 11947 that = this; 11948 11949 this.element.addClass("ui-selectable"); 11950 11951 this.dragged = false;
vendor: 4,465 bytes, lines 11952-12119
11952 11953 // cache selectee children based on filter 11954 this.refresh = function() { 11955 selectees = $(that.options.filter, that.element[0]); 11956 selectees.addClass("ui-selectee"); 11957 selectees.each(function() { 11958 var $this = $(this), 11959 pos = $this.offset(); 11960 $.data(this, "selectable-item", { 11961 element: this, 11962 $element: $this, 11963 left: pos.left, 11964 top: pos.top, 11965 right: pos.left + $this.outerWidth(), 11966 bottom: pos.top + $this.outerHeight(), 11967 startselected: false, 11968 selected: $this.hasClass("ui-selected"), 11969 selecting: $this.hasClass("ui-selecting"), 11970 unselecting: $this.hasClass("ui-unselecting") 11971 }); 11972 }); 11973 }; 11974 this.refresh(); 11975 11976 this.selectees = selectees.addClass("ui-selectee"); 11977 11978 this._mouseInit(); 11979 11980 this.helper = $("<div class='ui-selectable-helper'></div>"); 11981 }, 11982 11983 _destroy: function() { 11984 this.selectees 11985 .removeClass("ui-selectee") 11986 .removeData("selectable-item"); 11987 this.element 11988 .removeClass("ui-selectable ui-selectable-disabled"); 11989 this._mouseDestroy(); 11990 }, 11991 11992 _mouseStart: function(event) { 11993 var that = this, 11994 options = this.options; 11995 11996 this.opos = [ event.pageX, event.pageY ]; 11997 11998 if (this.options.disabled) { 11999 return; 12000 } 12001 12002 this.selectees = $(options.filter, this.element[0]); 12003 12004 this._trigger("start", event); 12005 12006 $(options.appendTo).append(this.helper); 12007 // position helper (lasso) 12008 this.helper.css({ 12009 "left": event.pageX, 12010 "top": event.pageY, 12011 "width": 0, 12012 "height": 0 12013 }); 12014 12015 if (options.autoRefresh) { 12016 this.refresh(); 12017 } 12018 12019 this.selectees.filter(".ui-selected").each(function() { 12020 var selectee = $.data(this, "selectable-item"); 12021 selectee.startselected = true; 12022 if (!event.metaKey && !event.ctrlKey) { 12023 selectee.$element.removeClass("ui-selected"); 12024 selectee.selected = false; 12025 selectee.$element.addClass("ui-unselecting"); 12026 selectee.unselecting = true; 12027 // selectable UNSELECTING callback 12028 that._trigger("unselecting", event, { 12029 unselecting: selectee.element 12030 }); 12031 } 12032 }); 12033 12034 $(event.target).parents().addBack().each(function() { 12035 var doSelect, 12036 selectee = $.data(this, "selectable-item"); 12037 if (selectee) { 12038 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 12039 selectee.$element 12040 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 12041 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 12042 selectee.unselecting = !doSelect; 12043 selectee.selecting = doSelect; 12044 selectee.selected = doSelect; 12045 // selectable (UN)SELECTING callback 12046 if (doSelect) { 12047 that._trigger("selecting", event, { 12048 selecting: selectee.element 12049 }); 12050 } else { 12051 that._trigger("unselecting", event, { 12052 unselecting: selectee.element 12053 }); 12054 } 12055 return false; 12056 } 12057 }); 12058 12059 }, 12060 12061 _mouseDrag: function(event) { 12062 12063 this.dragged = true; 12064 12065 if (this.options.disabled) { 12066 return; 12067 } 12068 12069 var tmp, 12070 that = this, 12071 options = this.options, 12072 x1 = this.opos[0], 12073 y1 = this.opos[1], 12074 x2 = event.pageX, 12075 y2 = event.pageY; 12076 12077 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 12078 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 12079 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 12080 12081 this.selectees.each(function() { 12082 var selectee = $.data(this, "selectable-item"), 12083 hit = false; 12084 12085 //prevent helper from being selected if appendTo: selectable 12086 if (!selectee || selectee.element === that.element[0]) { 12087 return; 12088 } 12089 12090 if (options.tolerance === "touch") { 12091 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 12092 } else if (options.tolerance === "fit") { 12093 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 12094 } 12095 12096 if (hit) { 12097 // SELECT 12098 if (selectee.selected) { 12099 selectee.$element.removeClass("ui-selected"); 12100 selectee.selected = false; 12101 } 12102 if (selectee.unselecting) { 12103 selectee.$element.removeClass("ui-unselecting"); 12104 selectee.unselecting = false; 12105 } 12106 if (!selectee.selecting) { 12107 selectee.$element.addClass("ui-selecting"); 12108 selectee.selecting = true; 12109 // selectable SELECTING callback 12110 that._trigger("selecting", event, { 12111 selecting: selectee.element 12112 }); 12113 } 12114 } else { 12115 // UNSELECT 12116 if (selectee.selecting) { 12117 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 12118 selectee.$element.removeClass("ui-selecting"); 12119 selectee.selecting = false;
vendor: 20,164 bytes, lines 12120-12988
12120 selectee.$element.addClass("ui-selected"); 12121 selectee.selected = true; 12122 } else { 12123 selectee.$element.removeClass("ui-selecting"); 12124 selectee.selecting = false; 12125 if (selectee.startselected) { 12126 selectee.$element.addClass("ui-unselecting"); 12127 selectee.unselecting = true; 12128 } 12129 // selectable UNSELECTING callback 12130 that._trigger("unselecting", event, { 12131 unselecting: selectee.element 12132 }); 12133 } 12134 } 12135 if (selectee.selected) { 12136 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 12137 selectee.$element.removeClass("ui-selected"); 12138 selectee.selected = false; 12139 12140 selectee.$element.addClass("ui-unselecting"); 12141 selectee.unselecting = true; 12142 // selectable UNSELECTING callback 12143 that._trigger("unselecting", event, { 12144 unselecting: selectee.element 12145 }); 12146 } 12147 } 12148 } 12149 }); 12150 12151 return false; 12152 }, 12153 12154 _mouseStop: function(event) { 12155 var that = this; 12156 12157 this.dragged = false; 12158 12159 $(".ui-unselecting", this.element[0]).each(function() { 12160 var selectee = $.data(this, "selectable-item"); 12161 selectee.$element.removeClass("ui-unselecting"); 12162 selectee.unselecting = false; 12163 selectee.startselected = false; 12164 that._trigger("unselected", event, { 12165 unselected: selectee.element 12166 }); 12167 }); 12168 $(".ui-selecting", this.element[0]).each(function() { 12169 var selectee = $.data(this, "selectable-item"); 12170 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 12171 selectee.selecting = false; 12172 selectee.selected = true; 12173 selectee.startselected = true; 12174 that._trigger("selected", event, { 12175 selected: selectee.element 12176 }); 12177 }); 12178 this._trigger("stop", event); 12179 12180 this.helper.remove(); 12181 12182 return false; 12183 } 12184 12185}); 12186 12187 12188/*! 12189 * jQuery UI Selectmenu 1.11.4 12190 * http://jqueryui.com 12191 * 12192 * Copyright jQuery Foundation and other contributors 12193 * Released under the MIT license. 12194 * http://jquery.org/license 12195 * 12196 * http://api.jqueryui.com/selectmenu 12197 */ 12198 12199 12200var selectmenu = $.widget( "ui.selectmenu", { 12201 version: "1.11.4", 12202 defaultElement: "<select>", 12203 options: { 12204 appendTo: null, 12205 disabled: null, 12206 icons: { 12207 button: "ui-icon-triangle-1-s" 12208 }, 12209 position: { 12210 my: "left top", 12211 at: "left bottom", 12212 collision: "none" 12213 }, 12214 width: null, 12215 12216 // callbacks 12217 change: null, 12218 close: null, 12219 focus: null, 12220 open: null, 12221 select: null 12222 }, 12223 12224 _create: function() { 12225 var selectmenuId = this.element.uniqueId().attr( "id" ); 12226 this.ids = { 12227 element: selectmenuId, 12228 button: selectmenuId + "-button", 12229 menu: selectmenuId + "-menu" 12230 }; 12231 12232 this._drawButton(); 12233 this._drawMenu(); 12234 12235 if ( this.options.disabled ) { 12236 this.disable(); 12237 } 12238 }, 12239 12240 _drawButton: function() { 12241 var that = this; 12242 12243 // Associate existing label with the new button 12244 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); 12245 this._on( this.label, { 12246 click: function( event ) { 12247 this.button.focus(); 12248 event.preventDefault(); 12249 } 12250 }); 12251 12252 // Hide original select element 12253 this.element.hide(); 12254 12255 // Create button 12256 this.button = $( "<span>", { 12257 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", 12258 tabindex: this.options.disabled ? -1 : 0, 12259 id: this.ids.button, 12260 role: "combobox", 12261 "aria-expanded": "false", 12262 "aria-autocomplete": "list", 12263 "aria-owns": this.ids.menu, 12264 "aria-haspopup": "true" 12265 }) 12266 .insertAfter( this.element ); 12267 12268 $( "<span>", { 12269 "class": "ui-icon " + this.options.icons.button 12270 }) 12271 .prependTo( this.button ); 12272 12273 this.buttonText = $( "<span>", { 12274 "class": "ui-selectmenu-text" 12275 }) 12276 .appendTo( this.button ); 12277 12278 this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); 12279 this._resizeButton(); 12280 12281 this._on( this.button, this._buttonEvents ); 12282 this.button.one( "focusin", function() { 12283 12284 // Delay rendering the menu items until the button receives focus. 12285 // The menu may have already been rendered via a programmatic open. 12286 if ( !that.menuItems ) { 12287 that._refreshMenu(); 12288 } 12289 }); 12290 this._hoverable( this.button ); 12291 this._focusable( this.button ); 12292 }, 12293 12294 _drawMenu: function() { 12295 var that = this; 12296 12297 // Create menu 12298 this.menu = $( "<ul>", { 12299 "aria-hidden": "true", 12300 "aria-labelledby": this.ids.button, 12301 id: this.ids.menu 12302 }); 12303 12304 // Wrap menu 12305 this.menuWrap = $( "<div>", { 12306 "class": "ui-selectmenu-menu ui-front" 12307 }) 12308 .append( this.menu ) 12309 .appendTo( this._appendTo() ); 12310 12311 // Initialize menu widget 12312 this.menuInstance = this.menu 12313 .menu({ 12314 role: "listbox", 12315 select: function( event, ui ) { 12316 event.preventDefault(); 12317 12318 // support: IE8 12319 // If the item was selected via a click, the text selection 12320 // will be destroyed in IE 12321 that._setSelection(); 12322 12323 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 12324 }, 12325 focus: function( event, ui ) { 12326 var item = ui.item.data( "ui-selectmenu-item" ); 12327 12328 // Prevent inital focus from firing and check if its a newly focused item 12329 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 12330 that._trigger( "focus", event, { item: item } ); 12331 if ( !that.isOpen ) { 12332 that._select( item, event ); 12333 } 12334 } 12335 that.focusIndex = item.index; 12336 12337 that.button.attr( "aria-activedescendant", 12338 that.menuItems.eq( item.index ).attr( "id" ) ); 12339 } 12340 }) 12341 .menu( "instance" ); 12342 12343 // Adjust menu styles to dropdown 12344 this.menu 12345 .addClass( "ui-corner-bottom" ) 12346 .removeClass( "ui-corner-all" ); 12347 12348 // Don't close the menu on mouseleave 12349 this.menuInstance._off( this.menu, "mouseleave" ); 12350 12351 // Cancel the menu's collapseAll on document click 12352 this.menuInstance._closeOnDocumentClick = function() { 12353 return false; 12354 }; 12355 12356 // Selects often contain empty items, but never contain dividers 12357 this.menuInstance._isDivider = function() { 12358 return false; 12359 }; 12360 }, 12361 12362 refresh: function() { 12363 this._refreshMenu(); 12364 this._setText( this.buttonText, this._getSelectedItem().text() ); 12365 if ( !this.options.width ) { 12366 this._resizeButton(); 12367 } 12368 }, 12369 12370 _refreshMenu: function() { 12371 this.menu.empty(); 12372 12373 var item, 12374 options = this.element.find( "option" ); 12375 12376 if ( !options.length ) { 12377 return; 12378 } 12379 12380 this._parseOptions( options ); 12381 this._renderMenu( this.menu, this.items ); 12382 12383 this.menuInstance.refresh(); 12384 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); 12385 12386 item = this._getSelectedItem(); 12387 12388 // Update the menu to have the correct item focused 12389 this.menuInstance.focus( null, item ); 12390 this._setAria( item.data( "ui-selectmenu-item" ) ); 12391 12392 // Set disabled state 12393 this._setOption( "disabled", this.element.prop( "disabled" ) ); 12394 }, 12395 12396 open: function( event ) { 12397 if ( this.options.disabled ) { 12398 return; 12399 } 12400 12401 // If this is the first time the menu is being opened, render the items 12402 if ( !this.menuItems ) { 12403 this._refreshMenu(); 12404 } else { 12405 12406 // Menu clears focus on close, reset focus to selected item 12407 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); 12408 this.menuInstance.focus( null, this._getSelectedItem() ); 12409 } 12410 12411 this.isOpen = true; 12412 this._toggleAttr(); 12413 this._resizeMenu(); 12414 this._position(); 12415 12416 this._on( this.document, this._documentClick ); 12417 12418 this._trigger( "open", event ); 12419 }, 12420 12421 _position: function() { 12422 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 12423 }, 12424 12425 close: function( event ) { 12426 if ( !this.isOpen ) { 12427 return; 12428 } 12429 12430 this.isOpen = false; 12431 this._toggleAttr(); 12432 12433 this.range = null; 12434 this._off( this.document ); 12435 12436 this._trigger( "close", event ); 12437 }, 12438 12439 widget: function() { 12440 return this.button; 12441 }, 12442 12443 menuWidget: function() { 12444 return this.menu; 12445 }, 12446 12447 _renderMenu: function( ul, items ) { 12448 var that = this, 12449 currentOptgroup = ""; 12450 12451 $.each( items, function( index, item ) { 12452 if ( item.optgroup !== currentOptgroup ) { 12453 $( "<li>", { 12454 "class": "ui-selectmenu-optgroup ui-menu-divider" + 12455 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 12456 " ui-state-disabled" : 12457 "" ), 12458 text: item.optgroup 12459 }) 12460 .appendTo( ul ); 12461 12462 currentOptgroup = item.optgroup; 12463 } 12464 12465 that._renderItemData( ul, item ); 12466 }); 12467 }, 12468 12469 _renderItemData: function( ul, item ) { 12470 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 12471 }, 12472 12473 _renderItem: function( ul, item ) { 12474 var li = $( "<li>" ); 12475 12476 if ( item.disabled ) { 12477 li.addClass( "ui-state-disabled" ); 12478 } 12479 this._setText( li, item.label ); 12480 12481 return li.appendTo( ul ); 12482 }, 12483 12484 _setText: function( element, value ) { 12485 if ( value ) { 12486 element.text( value ); 12487 } else { 12488 element.html( " " ); 12489 } 12490 }, 12491 12492 _move: function( direction, event ) { 12493 var item, next, 12494 filter = ".ui-menu-item"; 12495 12496 if ( this.isOpen ) { 12497 item = this.menuItems.eq( this.focusIndex ); 12498 } else { 12499 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12500 filter += ":not(.ui-state-disabled)"; 12501 } 12502 12503 if ( direction === "first" || direction === "last" ) { 12504 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 12505 } else { 12506 next = item[ direction + "All" ]( filter ).eq( 0 ); 12507 } 12508 12509 if ( next.length ) { 12510 this.menuInstance.focus( event, next ); 12511 } 12512 }, 12513 12514 _getSelectedItem: function() { 12515 return this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12516 }, 12517 12518 _toggle: function( event ) { 12519 this[ this.isOpen ? "close" : "open" ]( event ); 12520 }, 12521 12522 _setSelection: function() { 12523 var selection; 12524 12525 if ( !this.range ) { 12526 return; 12527 } 12528 12529 if ( window.getSelection ) { 12530 selection = window.getSelection(); 12531 selection.removeAllRanges(); 12532 selection.addRange( this.range ); 12533 12534 // support: IE8 12535 } else { 12536 this.range.select(); 12537 } 12538 12539 // support: IE 12540 // Setting the text selection kills the button focus in IE, but 12541 // restoring the focus doesn't kill the selection. 12542 this.button.focus(); 12543 }, 12544 12545 _documentClick: { 12546 mousedown: function( event ) { 12547 if ( !this.isOpen ) { 12548 return; 12549 } 12550 12551 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { 12552 this.close( event ); 12553 } 12554 } 12555 }, 12556 12557 _buttonEvents: { 12558 12559 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 12560 mousedown: function() { 12561 var selection; 12562 12563 if ( window.getSelection ) { 12564 selection = window.getSelection(); 12565 if ( selection.rangeCount ) { 12566 this.range = selection.getRangeAt( 0 ); 12567 } 12568 12569 // support: IE8 12570 } else { 12571 this.range = document.selection.createRange(); 12572 } 12573 }, 12574 12575 click: function( event ) { 12576 this._setSelection(); 12577 this._toggle( event ); 12578 }, 12579 12580 keydown: function( event ) { 12581 var preventDefault = true; 12582 switch ( event.keyCode ) { 12583 case $.ui.keyCode.TAB: 12584 case $.ui.keyCode.ESCAPE: 12585 this.close( event ); 12586 preventDefault = false; 12587 break; 12588 case $.ui.keyCode.ENTER: 12589 if ( this.isOpen ) { 12590 this._selectFocusedItem( event ); 12591 } 12592 break; 12593 case $.ui.keyCode.UP: 12594 if ( event.altKey ) { 12595 this._toggle( event ); 12596 } else { 12597 this._move( "prev", event ); 12598 } 12599 break; 12600 case $.ui.keyCode.DOWN: 12601 if ( event.altKey ) { 12602 this._toggle( event ); 12603 } else { 12604 this._move( "next", event ); 12605 } 12606 break; 12607 case $.ui.keyCode.SPACE: 12608 if ( this.isOpen ) { 12609 this._selectFocusedItem( event ); 12610 } else { 12611 this._toggle( event ); 12612 } 12613 break; 12614 case $.ui.keyCode.LEFT: 12615 this._move( "prev", event ); 12616 break; 12617 case $.ui.keyCode.RIGHT: 12618 this._move( "next", event ); 12619 break; 12620 case $.ui.keyCode.HOME: 12621 case $.ui.keyCode.PAGE_UP: 12622 this._move( "first", event ); 12623 break; 12624 case $.ui.keyCode.END: 12625 case $.ui.keyCode.PAGE_DOWN: 12626 this._move( "last", event ); 12627 break; 12628 default: 12629 this.menu.trigger( event ); 12630 preventDefault = false; 12631 } 12632 12633 if ( preventDefault ) { 12634 event.preventDefault(); 12635 } 12636 } 12637 }, 12638 12639 _selectFocusedItem: function( event ) { 12640 var item = this.menuItems.eq( this.focusIndex ); 12641 if ( !item.hasClass( "ui-state-disabled" ) ) { 12642 this._select( item.data( "ui-selectmenu-item" ), event ); 12643 } 12644 }, 12645 12646 _select: function( item, event ) { 12647 var oldIndex = this.element[ 0 ].selectedIndex; 12648 12649 // Change native select element 12650 this.element[ 0 ].selectedIndex = item.index; 12651 this._setText( this.buttonText, item.label ); 12652 this._setAria( item ); 12653 this._trigger( "select", event, { item: item } ); 12654 12655 if ( item.index !== oldIndex ) { 12656 this._trigger( "change", event, { item: item } ); 12657 } 12658 12659 this.close( event ); 12660 }, 12661 12662 _setAria: function( item ) { 12663 var id = this.menuItems.eq( item.index ).attr( "id" ); 12664 12665 this.button.attr({ 12666 "aria-labelledby": id, 12667 "aria-activedescendant": id 12668 }); 12669 this.menu.attr( "aria-activedescendant", id ); 12670 }, 12671 12672 _setOption: function( key, value ) { 12673 if ( key === "icons" ) { 12674 this.button.find( "span.ui-icon" ) 12675 .removeClass( this.options.icons.button ) 12676 .addClass( value.button ); 12677 } 12678 12679 this._super( key, value ); 12680 12681 if ( key === "appendTo" ) { 12682 this.menuWrap.appendTo( this._appendTo() ); 12683 } 12684 12685 if ( key === "disabled" ) { 12686 this.menuInstance.option( "disabled", value ); 12687 this.button 12688 .toggleClass( "ui-state-disabled", value ) 12689 .attr( "aria-disabled", value ); 12690 12691 this.element.prop( "disabled", value ); 12692 if ( value ) { 12693 this.button.attr( "tabindex", -1 ); 12694 this.close(); 12695 } else { 12696 this.button.attr( "tabindex", 0 ); 12697 } 12698 } 12699 12700 if ( key === "width" ) { 12701 this._resizeButton(); 12702 } 12703 }, 12704 12705 _appendTo: function() { 12706 var element = this.options.appendTo; 12707 12708 if ( element ) { 12709 element = element.jquery || element.nodeType ? 12710 $( element ) : 12711 this.document.find( element ).eq( 0 ); 12712 } 12713 12714 if ( !element || !element[ 0 ] ) { 12715 element = this.element.closest( ".ui-front" ); 12716 } 12717 12718 if ( !element.length ) { 12719 element = this.document[ 0 ].body; 12720 } 12721 12722 return element; 12723 }, 12724 12725 _toggleAttr: function() { 12726 this.button 12727 .toggleClass( "ui-corner-top", this.isOpen ) 12728 .toggleClass( "ui-corner-all", !this.isOpen ) 12729 .attr( "aria-expanded", this.isOpen ); 12730 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); 12731 this.menu.attr( "aria-hidden", !this.isOpen ); 12732 }, 12733 12734 _resizeButton: function() { 12735 var width = this.options.width; 12736 12737 if ( !width ) { 12738 width = this.element.show().outerWidth(); 12739 this.element.hide(); 12740 } 12741 12742 this.button.outerWidth( width ); 12743 }, 12744 12745 _resizeMenu: function() { 12746 this.menu.outerWidth( Math.max( 12747 this.button.outerWidth(), 12748 12749 // support: IE10 12750 // IE10 wraps long text (possibly a rounding bug) 12751 // so we add 1px to avoid the wrapping 12752 this.menu.width( "" ).outerWidth() + 1 12753 ) ); 12754 }, 12755 12756 _getCreateOptions: function() { 12757 return { disabled: this.element.prop( "disabled" ) }; 12758 }, 12759 12760 _parseOptions: function( options ) { 12761 var data = []; 12762 options.each(function( index, item ) { 12763 var option = $( item ), 12764 optgroup = option.parent( "optgroup" ); 12765 data.push({ 12766 element: option, 12767 index: index, 12768 value: option.val(), 12769 label: option.text(), 12770 optgroup: optgroup.attr( "label" ) || "", 12771 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 12772 }); 12773 }); 12774 this.items = data; 12775 }, 12776 12777 _destroy: function() { 12778 this.menuWrap.remove(); 12779 this.button.remove(); 12780 this.element.show(); 12781 this.element.removeUniqueId(); 12782 this.label.attr( "for", this.ids.element ); 12783 } 12784}); 12785 12786 12787/*! 12788 * jQuery UI Slider 1.11.4 12789 * http://jqueryui.com 12790 * 12791 * Copyright jQuery Foundation and other contributors 12792 * Released under the MIT license. 12793 * http://jquery.org/license 12794 * 12795 * http://api.jqueryui.com/slider/ 12796 */ 12797 12798 12799var slider = $.widget( "ui.slider", $.ui.mouse, { 12800 version: "1.11.4", 12801 widgetEventPrefix: "slide", 12802 12803 options: { 12804 animate: false, 12805 distance: 0, 12806 max: 100, 12807 min: 0, 12808 orientation: "horizontal", 12809 range: false, 12810 step: 1, 12811 value: 0, 12812 values: null, 12813 12814 // callbacks 12815 change: null, 12816 slide: null, 12817 start: null, 12818 stop: null 12819 }, 12820 12821 // number of pages in a slider 12822 // (how many times can you page up/down to go through the whole range) 12823 numPages: 5, 12824 12825 _create: function() { 12826 this._keySliding = false; 12827 this._mouseSliding = false; 12828 this._animateOff = true; 12829 this._handleIndex = null; 12830 this._detectOrientation(); 12831 this._mouseInit(); 12832 this._calculateNewMax(); 12833 12834 this.element 12835 .addClass( "ui-slider" + 12836 " ui-slider-" + this.orientation + 12837 " ui-widget" + 12838 " ui-widget-content" + 12839 " ui-corner-all"); 12840 12841 this._refresh(); 12842 this._setOption( "disabled", this.options.disabled ); 12843 12844 this._animateOff = false; 12845 }, 12846 12847 _refresh: function() { 12848 this._createRange(); 12849 this._createHandles(); 12850 this._setupEvents(); 12851 this._refreshValue(); 12852 }, 12853 12854 _createHandles: function() { 12855 var i, handleCount, 12856 options = this.options, 12857 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12858 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", 12859 handles = []; 12860 12861 handleCount = ( options.values && options.values.length ) || 1; 12862 12863 if ( existingHandles.length > handleCount ) { 12864 existingHandles.slice( handleCount ).remove(); 12865 existingHandles = existingHandles.slice( 0, handleCount ); 12866 } 12867 12868 for ( i = existingHandles.length; i < handleCount; i++ ) { 12869 handles.push( handle ); 12870 } 12871 12872 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12873 12874 this.handle = this.handles.eq( 0 ); 12875 12876 this.handles.each(function( i ) { 12877 $( this ).data( "ui-slider-handle-index", i ); 12878 }); 12879 }, 12880 12881 _createRange: function() { 12882 var options = this.options, 12883 classes = ""; 12884 12885 if ( options.range ) { 12886 if ( options.range === true ) { 12887 if ( !options.values ) { 12888 options.values = [ this._valueMin(), this._valueMin() ]; 12889 } else if ( options.values.length && options.values.length !== 2 ) { 12890 options.values = [ options.values[0], options.values[0] ]; 12891 } else if ( $.isArray( options.values ) ) { 12892 options.values = options.values.slice(0); 12893 } 12894 } 12895 12896 if ( !this.range || !this.range.length ) { 12897 this.range = $( "<div></div>" ) 12898 .appendTo( this.element ); 12899 12900 classes = "ui-slider-range" + 12901 // note: this isn't the most fittingly semantic framework class for this element, 12902 // but worked best visually with a variety of themes 12903 " ui-widget-header ui-corner-all"; 12904 } else { 12905 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12906 // Handle range switching from true to min/max 12907 .css({ 12908 "left": "", 12909 "bottom": "" 12910 }); 12911 } 12912 12913 this.range.addClass( classes + 12914 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12915 } else { 12916 if ( this.range ) { 12917 this.range.remove(); 12918 } 12919 this.range = null; 12920 } 12921 }, 12922 12923 _setupEvents: function() { 12924 this._off( this.handles ); 12925 this._on( this.handles, this._handleEvents ); 12926 this._hoverable( this.handles ); 12927 this._focusable( this.handles ); 12928 }, 12929 12930 _destroy: function() { 12931 this.handles.remove(); 12932 if ( this.range ) { 12933 this.range.remove(); 12934 } 12935 12936 this.element 12937 .removeClass( "ui-slider" + 12938 " ui-slider-horizontal" + 12939 " ui-slider-vertical" + 12940 " ui-widget" + 12941 " ui-widget-content" + 12942 " ui-corner-all" ); 12943 12944 this._mouseDestroy(); 12945 }, 12946 12947 _mouseCapture: function( event ) { 12948 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12949 that = this, 12950 o = this.options; 12951 12952 if ( o.disabled ) { 12953 return false; 12954 } 12955 12956 this.elementSize = { 12957 width: this.element.outerWidth(), 12958 height: this.element.outerHeight() 12959 }; 12960 this.elementOffset = this.element.offset(); 12961 12962 position = { x: event.pageX, y: event.pageY }; 12963 normValue = this._normValueFromMouse( position ); 12964 distance = this._valueMax() - this._valueMin() + 1; 12965 this.handles.each(function( i ) { 12966 var thisDistance = Math.abs( normValue - that.values(i) ); 12967 if (( distance > thisDistance ) || 12968 ( distance === thisDistance && 12969 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12970 distance = thisDistance; 12971 closestHandle = $( this ); 12972 index = i; 12973 } 12974 }); 12975 12976 allowed = this._start( event, index ); 12977 if ( allowed === false ) { 12978 return false; 12979 } 12980 this._mouseSliding = true; 12981 12982 this._handleIndex = index; 12983 12984 closestHandle 12985 .addClass( "ui-state-active" ) 12986 .focus(); 12987 12988 offset = closestHandle.offset();
vendor: 4,641 bytes, lines 12989-13161
12989 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12990 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12991 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12992 top: event.pageY - offset.top - 12993 ( closestHandle.height() / 2 ) - 12994 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12995 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12996 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12997 }; 12998 12999 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13000 this._slide( event, index, normValue ); 13001 } 13002 this._animateOff = true; 13003 return true; 13004 }, 13005 13006 _mouseStart: function() { 13007 return true; 13008 }, 13009 13010 _mouseDrag: function( event ) { 13011 var position = { x: event.pageX, y: event.pageY }, 13012 normValue = this._normValueFromMouse( position ); 13013 13014 this._slide( event, this._handleIndex, normValue ); 13015 13016 return false; 13017 }, 13018 13019 _mouseStop: function( event ) { 13020 this.handles.removeClass( "ui-state-active" ); 13021 this._mouseSliding = false; 13022 13023 this._stop( event, this._handleIndex ); 13024 this._change( event, this._handleIndex ); 13025 13026 this._handleIndex = null; 13027 this._clickOffset = null; 13028 this._animateOff = false; 13029 13030 return false; 13031 }, 13032 13033 _detectOrientation: function() { 13034 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13035 }, 13036 13037 _normValueFromMouse: function( position ) { 13038 var pixelTotal, 13039 pixelMouse, 13040 percentMouse, 13041 valueTotal, 13042 valueMouse; 13043 13044 if ( this.orientation === "horizontal" ) { 13045 pixelTotal = this.elementSize.width; 13046 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 13047 } else { 13048 pixelTotal = this.elementSize.height; 13049 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 13050 } 13051 13052 percentMouse = ( pixelMouse / pixelTotal ); 13053 if ( percentMouse > 1 ) { 13054 percentMouse = 1; 13055 } 13056 if ( percentMouse < 0 ) { 13057 percentMouse = 0; 13058 } 13059 if ( this.orientation === "vertical" ) { 13060 percentMouse = 1 - percentMouse; 13061 } 13062 13063 valueTotal = this._valueMax() - this._valueMin(); 13064 valueMouse = this._valueMin() + percentMouse * valueTotal; 13065 13066 return this._trimAlignValue( valueMouse ); 13067 }, 13068 13069 _start: function( event, index ) { 13070 var uiHash = { 13071 handle: this.handles[ index ], 13072 value: this.value() 13073 }; 13074 if ( this.options.values && this.options.values.length ) { 13075 uiHash.value = this.values( index ); 13076 uiHash.values = this.values(); 13077 } 13078 return this._trigger( "start", event, uiHash ); 13079 }, 13080 13081 _slide: function( event, index, newVal ) { 13082 var otherVal, 13083 newValues, 13084 allowed; 13085 13086 if ( this.options.values && this.options.values.length ) { 13087 otherVal = this.values( index ? 0 : 1 ); 13088 13089 if ( ( this.options.values.length === 2 && this.options.range === true ) && 13090 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 13091 ) { 13092 newVal = otherVal; 13093 } 13094 13095 if ( newVal !== this.values( index ) ) { 13096 newValues = this.values(); 13097 newValues[ index ] = newVal; 13098 // A slide can be canceled by returning false from the slide callback 13099 allowed = this._trigger( "slide", event, { 13100 handle: this.handles[ index ], 13101 value: newVal, 13102 values: newValues 13103 } ); 13104 otherVal = this.values( index ? 0 : 1 ); 13105 if ( allowed !== false ) { 13106 this.values( index, newVal ); 13107 } 13108 } 13109 } else { 13110 if ( newVal !== this.value() ) { 13111 // A slide can be canceled by returning false from the slide callback 13112 allowed = this._trigger( "slide", event, { 13113 handle: this.handles[ index ], 13114 value: newVal 13115 } ); 13116 if ( allowed !== false ) { 13117 this.value( newVal ); 13118 } 13119 } 13120 } 13121 }, 13122 13123 _stop: function( event, index ) { 13124 var uiHash = { 13125 handle: this.handles[ index ], 13126 value: this.value() 13127 }; 13128 if ( this.options.values && this.options.values.length ) { 13129 uiHash.value = this.values( index ); 13130 uiHash.values = this.values(); 13131 } 13132 13133 this._trigger( "stop", event, uiHash ); 13134 }, 13135 13136 _change: function( event, index ) { 13137 if ( !this._keySliding && !this._mouseSliding ) { 13138 var uiHash = { 13139 handle: this.handles[ index ], 13140 value: this.value() 13141 }; 13142 if ( this.options.values && this.options.values.length ) { 13143 uiHash.value = this.values( index ); 13144 uiHash.values = this.values(); 13145 } 13146 13147 //store the last changed value index for reference when handles overlap 13148 this._lastChangedValue = index; 13149 13150 this._trigger( "change", event, uiHash ); 13151 } 13152 }, 13153 13154 value: function( newValue ) { 13155 if ( arguments.length ) { 13156 this.options.value = this._trimAlignValue( newValue ); 13157 this._refreshValue(); 13158 this._change( null, 0 ); 13159 return; 13160 } 13161
vendor: 56,341 bytes, lines 13162-14940
13162 return this._value(); 13163 }, 13164 13165 values: function( index, newValue ) { 13166 var vals, 13167 newValues, 13168 i; 13169 13170 if ( arguments.length > 1 ) { 13171 this.options.values[ index ] = this._trimAlignValue( newValue ); 13172 this._refreshValue(); 13173 this._change( null, index ); 13174 return; 13175 } 13176 13177 if ( arguments.length ) { 13178 if ( $.isArray( arguments[ 0 ] ) ) { 13179 vals = this.options.values; 13180 newValues = arguments[ 0 ]; 13181 for ( i = 0; i < vals.length; i += 1 ) { 13182 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13183 this._change( null, i ); 13184 } 13185 this._refreshValue(); 13186 } else { 13187 if ( this.options.values && this.options.values.length ) { 13188 return this._values( index ); 13189 } else { 13190 return this.value(); 13191 } 13192 } 13193 } else { 13194 return this._values(); 13195 } 13196 }, 13197 13198 _setOption: function( key, value ) { 13199 var i, 13200 valsLength = 0; 13201 13202 if ( key === "range" && this.options.range === true ) { 13203 if ( value === "min" ) { 13204 this.options.value = this._values( 0 ); 13205 this.options.values = null; 13206 } else if ( value === "max" ) { 13207 this.options.value = this._values( this.options.values.length - 1 ); 13208 this.options.values = null; 13209 } 13210 } 13211 13212 if ( $.isArray( this.options.values ) ) { 13213 valsLength = this.options.values.length; 13214 } 13215 13216 if ( key === "disabled" ) { 13217 this.element.toggleClass( "ui-state-disabled", !!value ); 13218 } 13219 13220 this._super( key, value ); 13221 13222 switch ( key ) { 13223 case "orientation": 13224 this._detectOrientation(); 13225 this.element 13226 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13227 .addClass( "ui-slider-" + this.orientation ); 13228 this._refreshValue(); 13229 13230 // Reset positioning from previous orientation 13231 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 13232 break; 13233 case "value": 13234 this._animateOff = true; 13235 this._refreshValue(); 13236 this._change( null, 0 ); 13237 this._animateOff = false; 13238 break; 13239 case "values": 13240 this._animateOff = true; 13241 this._refreshValue(); 13242 for ( i = 0; i < valsLength; i += 1 ) { 13243 this._change( null, i ); 13244 } 13245 this._animateOff = false; 13246 break; 13247 case "step": 13248 case "min": 13249 case "max": 13250 this._animateOff = true; 13251 this._calculateNewMax(); 13252 this._refreshValue(); 13253 this._animateOff = false; 13254 break; 13255 case "range": 13256 this._animateOff = true; 13257 this._refresh(); 13258 this._animateOff = false; 13259 break; 13260 } 13261 }, 13262 13263 //internal value getter 13264 // _value() returns value trimmed by min and max, aligned by step 13265 _value: function() { 13266 var val = this.options.value; 13267 val = this._trimAlignValue( val ); 13268 13269 return val; 13270 }, 13271 13272 //internal values getter 13273 // _values() returns array of values trimmed by min and max, aligned by step 13274 // _values( index ) returns single value trimmed by min and max, aligned by step 13275 _values: function( index ) { 13276 var val, 13277 vals, 13278 i; 13279 13280 if ( arguments.length ) { 13281 val = this.options.values[ index ]; 13282 val = this._trimAlignValue( val ); 13283 13284 return val; 13285 } else if ( this.options.values && this.options.values.length ) { 13286 // .slice() creates a copy of the array 13287 // this copy gets trimmed by min and max and then returned 13288 vals = this.options.values.slice(); 13289 for ( i = 0; i < vals.length; i += 1) { 13290 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13291 } 13292 13293 return vals; 13294 } else { 13295 return []; 13296 } 13297 }, 13298 13299 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13300 _trimAlignValue: function( val ) { 13301 if ( val <= this._valueMin() ) { 13302 return this._valueMin(); 13303 } 13304 if ( val >= this._valueMax() ) { 13305 return this._valueMax(); 13306 } 13307 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13308 valModStep = (val - this._valueMin()) % step, 13309 alignValue = val - valModStep; 13310 13311 if ( Math.abs(valModStep) * 2 >= step ) { 13312 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13313 } 13314 13315 // Since JavaScript has problems with large floats, round 13316 // the final value to 5 digits after the decimal point (see #4124) 13317 return parseFloat( alignValue.toFixed(5) ); 13318 }, 13319 13320 _calculateNewMax: function() { 13321 var max = this.options.max, 13322 min = this._valueMin(), 13323 step = this.options.step, 13324 aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step; 13325 max = aboveMin + min; 13326 this.max = parseFloat( max.toFixed( this._precision() ) ); 13327 }, 13328 13329 _precision: function() { 13330 var precision = this._precisionOf( this.options.step ); 13331 if ( this.options.min !== null ) { 13332 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13333 } 13334 return precision; 13335 }, 13336 13337 _precisionOf: function( num ) { 13338 var str = num.toString(), 13339 decimal = str.indexOf( "." ); 13340 return decimal === -1 ? 0 : str.length - decimal - 1; 13341 }, 13342 13343 _valueMin: function() { 13344 return this.options.min; 13345 }, 13346 13347 _valueMax: function() { 13348 return this.max; 13349 }, 13350 13351 _refreshValue: function() { 13352 var lastValPercent, valPercent, value, valueMin, valueMax, 13353 oRange = this.options.range, 13354 o = this.options, 13355 that = this, 13356 animate = ( !this._animateOff ) ? o.animate : false, 13357 _set = {}; 13358 13359 if ( this.options.values && this.options.values.length ) { 13360 this.handles.each(function( i ) { 13361 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13362 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13363 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13364 if ( that.options.range === true ) { 13365 if ( that.orientation === "horizontal" ) { 13366 if ( i === 0 ) { 13367 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13368 } 13369 if ( i === 1 ) { 13370 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13371 } 13372 } else { 13373 if ( i === 0 ) { 13374 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13375 } 13376 if ( i === 1 ) { 13377 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13378 } 13379 } 13380 } 13381 lastValPercent = valPercent; 13382 }); 13383 } else { 13384 value = this.value(); 13385 valueMin = this._valueMin(); 13386 valueMax = this._valueMax(); 13387 valPercent = ( valueMax !== valueMin ) ? 13388 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13389 0; 13390 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13391 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13392 13393 if ( oRange === "min" && this.orientation === "horizontal" ) { 13394 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13395 } 13396 if ( oRange === "max" && this.orientation === "horizontal" ) { 13397 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13398 } 13399 if ( oRange === "min" && this.orientation === "vertical" ) { 13400 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13401 } 13402 if ( oRange === "max" && this.orientation === "vertical" ) { 13403 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13404 } 13405 } 13406 }, 13407 13408 _handleEvents: { 13409 keydown: function( event ) { 13410 var allowed, curVal, newVal, step, 13411 index = $( event.target ).data( "ui-slider-handle-index" ); 13412 13413 switch ( event.keyCode ) { 13414 case $.ui.keyCode.HOME: 13415 case $.ui.keyCode.END: 13416 case $.ui.keyCode.PAGE_UP: 13417 case $.ui.keyCode.PAGE_DOWN: 13418 case $.ui.keyCode.UP: 13419 case $.ui.keyCode.RIGHT: 13420 case $.ui.keyCode.DOWN: 13421 case $.ui.keyCode.LEFT: 13422 event.preventDefault(); 13423 if ( !this._keySliding ) { 13424 this._keySliding = true; 13425 $( event.target ).addClass( "ui-state-active" ); 13426 allowed = this._start( event, index ); 13427 if ( allowed === false ) { 13428 return; 13429 } 13430 } 13431 break; 13432 } 13433 13434 step = this.options.step; 13435 if ( this.options.values && this.options.values.length ) { 13436 curVal = newVal = this.values( index ); 13437 } else { 13438 curVal = newVal = this.value(); 13439 } 13440 13441 switch ( event.keyCode ) { 13442 case $.ui.keyCode.HOME: 13443 newVal = this._valueMin(); 13444 break; 13445 case $.ui.keyCode.END: 13446 newVal = this._valueMax(); 13447 break; 13448 case $.ui.keyCode.PAGE_UP: 13449 newVal = this._trimAlignValue( 13450 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 13451 ); 13452 break; 13453 case $.ui.keyCode.PAGE_DOWN: 13454 newVal = this._trimAlignValue( 13455 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); 13456 break; 13457 case $.ui.keyCode.UP: 13458 case $.ui.keyCode.RIGHT: 13459 if ( curVal === this._valueMax() ) { 13460 return; 13461 } 13462 newVal = this._trimAlignValue( curVal + step ); 13463 break; 13464 case $.ui.keyCode.DOWN: 13465 case $.ui.keyCode.LEFT: 13466 if ( curVal === this._valueMin() ) { 13467 return; 13468 } 13469 newVal = this._trimAlignValue( curVal - step ); 13470 break; 13471 } 13472 13473 this._slide( event, index, newVal ); 13474 }, 13475 keyup: function( event ) { 13476 var index = $( event.target ).data( "ui-slider-handle-index" ); 13477 13478 if ( this._keySliding ) { 13479 this._keySliding = false; 13480 this._stop( event, index ); 13481 this._change( event, index ); 13482 $( event.target ).removeClass( "ui-state-active" ); 13483 } 13484 } 13485 } 13486}); 13487 13488 13489/*! 13490 * jQuery UI Sortable 1.11.4 13491 * http://jqueryui.com 13492 * 13493 * Copyright jQuery Foundation and other contributors 13494 * Released under the MIT license. 13495 * http://jquery.org/license 13496 * 13497 * http://api.jqueryui.com/sortable/ 13498 */ 13499 13500 13501var sortable = $.widget("ui.sortable", $.ui.mouse, { 13502 version: "1.11.4", 13503 widgetEventPrefix: "sort", 13504 ready: false, 13505 options: { 13506 appendTo: "parent", 13507 axis: false, 13508 connectWith: false, 13509 containment: false, 13510 cursor: "auto", 13511 cursorAt: false, 13512 dropOnEmpty: true, 13513 forcePlaceholderSize: false, 13514 forceHelperSize: false, 13515 grid: false, 13516 handle: false, 13517 helper: "original", 13518 items: "> *", 13519 opacity: false, 13520 placeholder: false, 13521 revert: false, 13522 scroll: true, 13523 scrollSensitivity: 20, 13524 scrollSpeed: 20, 13525 scope: "default", 13526 tolerance: "intersect", 13527 zIndex: 1000, 13528 13529 // callbacks 13530 activate: null, 13531 beforeStop: null, 13532 change: null, 13533 deactivate: null, 13534 out: null, 13535 over: null, 13536 receive: null, 13537 remove: null, 13538 sort: null, 13539 start: null, 13540 stop: null, 13541 update: null 13542 }, 13543 13544 _isOverAxis: function( x, reference, size ) { 13545 return ( x >= reference ) && ( x < ( reference + size ) ); 13546 }, 13547 13548 _isFloating: function( item ) { 13549 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 13550 }, 13551 13552 _create: function() { 13553 this.containerCache = {}; 13554 this.element.addClass("ui-sortable"); 13555 13556 //Get the items 13557 this.refresh(); 13558 13559 //Let's determine the parent's offset 13560 this.offset = this.element.offset(); 13561 13562 //Initialize mouse events for interaction 13563 this._mouseInit(); 13564 13565 this._setHandleClassName(); 13566 13567 //We're ready to go 13568 this.ready = true; 13569 13570 }, 13571 13572 _setOption: function( key, value ) { 13573 this._super( key, value ); 13574 13575 if ( key === "handle" ) { 13576 this._setHandleClassName(); 13577 } 13578 }, 13579 13580 _setHandleClassName: function() { 13581 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); 13582 $.each( this.items, function() { 13583 ( this.instance.options.handle ? 13584 this.item.find( this.instance.options.handle ) : this.item ) 13585 .addClass( "ui-sortable-handle" ); 13586 }); 13587 }, 13588 13589 _destroy: function() { 13590 this.element 13591 .removeClass( "ui-sortable ui-sortable-disabled" ) 13592 .find( ".ui-sortable-handle" ) 13593 .removeClass( "ui-sortable-handle" ); 13594 this._mouseDestroy(); 13595 13596 for ( var i = this.items.length - 1; i >= 0; i-- ) { 13597 this.items[i].item.removeData(this.widgetName + "-item"); 13598 } 13599 13600 return this; 13601 }, 13602 13603 _mouseCapture: function(event, overrideHandle) { 13604 var currentItem = null, 13605 validHandle = false, 13606 that = this; 13607 13608 if (this.reverting) { 13609 return false; 13610 } 13611 13612 if(this.options.disabled || this.options.type === "static") { 13613 return false; 13614 } 13615 13616 //We have to refresh the items data once first 13617 this._refreshItems(event); 13618 13619 //Find out if the clicked node (or one of its parents) is a actual item in this.items 13620 $(event.target).parents().each(function() { 13621 if($.data(this, that.widgetName + "-item") === that) { 13622 currentItem = $(this); 13623 return false; 13624 } 13625 }); 13626 if($.data(event.target, that.widgetName + "-item") === that) { 13627 currentItem = $(event.target); 13628 } 13629 13630 if(!currentItem) { 13631 return false; 13632 } 13633 if(this.options.handle && !overrideHandle) { 13634 $(this.options.handle, currentItem).find("*").addBack().each(function() { 13635 if(this === event.target) { 13636 validHandle = true; 13637 } 13638 }); 13639 if(!validHandle) { 13640 return false; 13641 } 13642 } 13643 13644 this.currentItem = currentItem; 13645 this._removeCurrentsFromItems(); 13646 return true; 13647 13648 }, 13649 13650 _mouseStart: function(event, overrideHandle, noActivation) { 13651 13652 var i, body, 13653 o = this.options; 13654 13655 this.currentContainer = this; 13656 13657 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 13658 this.refreshPositions(); 13659 13660 //Create and append the visible helper 13661 this.helper = this._createHelper(event); 13662 13663 //Cache the helper size 13664 this._cacheHelperProportions(); 13665 13666 /* 13667 * - Position generation - 13668 * This block generates everything position related - it's the core of draggables. 13669 */ 13670 13671 //Cache the margins of the original element 13672 this._cacheMargins(); 13673 13674 //Get the next scrolling parent 13675 this.scrollParent = this.helper.scrollParent(); 13676 13677 //The element's absolute position on the page minus margins 13678 this.offset = this.currentItem.offset(); 13679 this.offset = { 13680 top: this.offset.top - this.margins.top, 13681 left: this.offset.left - this.margins.left 13682 }; 13683 13684 $.extend(this.offset, { 13685 click: { //Where the click happened, relative to the element 13686 left: event.pageX - this.offset.left, 13687 top: event.pageY - this.offset.top 13688 }, 13689 parent: this._getParentOffset(), 13690 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 13691 }); 13692 13693 // Only after we got the offset, we can change the helper's position to absolute 13694 // TODO: Still need to figure out a way to make relative sorting possible 13695 this.helper.css("position", "absolute"); 13696 this.cssPosition = this.helper.css("position"); 13697 13698 //Generate the original position 13699 this.originalPosition = this._generatePosition(event); 13700 this.originalPageX = event.pageX; 13701 this.originalPageY = event.pageY; 13702 13703 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 13704 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 13705 13706 //Cache the former DOM position 13707 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 13708 13709 //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 13710 if(this.helper[0] !== this.currentItem[0]) { 13711 this.currentItem.hide(); 13712 } 13713 13714 //Create the placeholder 13715 this._createPlaceholder(); 13716 13717 //Set a containment if given in the options 13718 if(o.containment) { 13719 this._setContainment(); 13720 } 13721 13722 if( o.cursor && o.cursor !== "auto" ) { // cursor option 13723 body = this.document.find( "body" ); 13724 13725 // support: IE 13726 this.storedCursor = body.css( "cursor" ); 13727 body.css( "cursor", o.cursor ); 13728 13729 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 13730 } 13731 13732 if(o.opacity) { // opacity option 13733 if (this.helper.css("opacity")) { 13734 this._storedOpacity = this.helper.css("opacity"); 13735 } 13736 this.helper.css("opacity", o.opacity); 13737 } 13738 13739 if(o.zIndex) { // zIndex option 13740 if (this.helper.css("zIndex")) { 13741 this._storedZIndex = this.helper.css("zIndex"); 13742 } 13743 this.helper.css("zIndex", o.zIndex); 13744 } 13745 13746 //Prepare scrolling 13747 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { 13748 this.overflowOffset = this.scrollParent.offset(); 13749 } 13750 13751 //Call callbacks 13752 this._trigger("start", event, this._uiHash()); 13753 13754 //Recache the helper size 13755 if(!this._preserveHelperProportions) { 13756 this._cacheHelperProportions(); 13757 } 13758 13759 13760 //Post "activate" events to possible containers 13761 if( !noActivation ) { 13762 for ( i = this.containers.length - 1; i >= 0; i-- ) { 13763 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 13764 } 13765 } 13766 13767 //Prepare possible droppables 13768 if($.ui.ddmanager) { 13769 $.ui.ddmanager.current = this; 13770 } 13771 13772 if ($.ui.ddmanager && !o.dropBehaviour) { 13773 $.ui.ddmanager.prepareOffsets(this, event); 13774 } 13775 13776 this.dragging = true; 13777 13778 this.helper.addClass("ui-sortable-helper"); 13779 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 13780 return true; 13781 13782 }, 13783 13784 _mouseDrag: function(event) { 13785 var i, item, itemElement, intersection, 13786 o = this.options, 13787 scrolled = false; 13788 13789 //Compute the helpers position 13790 this.position = this._generatePosition(event); 13791 this.positionAbs = this._convertPositionTo("absolute"); 13792 13793 if (!this.lastPositionAbs) { 13794 this.lastPositionAbs = this.positionAbs; 13795 } 13796 13797 //Do scrolling 13798 if(this.options.scroll) { 13799 if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { 13800 13801 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 13802 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 13803 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 13804 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 13805 } 13806 13807 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 13808 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 13809 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 13810 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 13811 } 13812 13813 } else { 13814 13815 if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) { 13816 scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); 13817 } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) { 13818 scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); 13819 } 13820 13821 if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { 13822 scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed); 13823 } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) { 13824 scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed); 13825 } 13826 13827 } 13828 13829 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 13830 $.ui.ddmanager.prepareOffsets(this, event); 13831 } 13832 } 13833 13834 //Regenerate the absolute position used for position checks 13835 this.positionAbs = this._convertPositionTo("absolute"); 13836 13837 //Set the helper position 13838 if(!this.options.axis || this.options.axis !== "y") { 13839 this.helper[0].style.left = this.position.left+"px"; 13840 } 13841 if(!this.options.axis || this.options.axis !== "x") { 13842 this.helper[0].style.top = this.position.top+"px"; 13843 } 13844 13845 //Rearrange 13846 for (i = this.items.length - 1; i >= 0; i--) { 13847 13848 //Cache variables and intersection, continue if no intersection 13849 item = this.items[i]; 13850 itemElement = item.item[0]; 13851 intersection = this._intersectsWithPointer(item); 13852 if (!intersection) { 13853 continue; 13854 } 13855 13856 // Only put the placeholder inside the current Container, skip all 13857 // items from other containers. This works because when moving 13858 // an item from one container to another the 13859 // currentContainer is switched before the placeholder is moved. 13860 // 13861 // Without this, moving items in "sub-sortables" can cause 13862 // the placeholder to jitter between the outer and inner container. 13863 if (item.instance !== this.currentContainer) { 13864 continue; 13865 } 13866 13867 // cannot intersect with itself 13868 // no useless actions that have been done before 13869 // no action if the item moved is the parent of the item checked 13870 if (itemElement !== this.currentItem[0] && 13871 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 13872 !$.contains(this.placeholder[0], itemElement) && 13873 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 13874 ) { 13875 13876 this.direction = intersection === 1 ? "down" : "up"; 13877 13878 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 13879 this._rearrange(event, item); 13880 } else { 13881 break; 13882 } 13883 13884 this._trigger("change", event, this._uiHash()); 13885 break; 13886 } 13887 } 13888 13889 //Post events to containers 13890 this._contactContainers(event); 13891 13892 //Interconnect with droppables 13893 if($.ui.ddmanager) { 13894 $.ui.ddmanager.drag(this, event); 13895 } 13896 13897 //Call callbacks 13898 this._trigger("sort", event, this._uiHash()); 13899 13900 this.lastPositionAbs = this.positionAbs; 13901 return false; 13902 13903 }, 13904 13905 _mouseStop: function(event, noPropagation) { 13906 13907 if(!event) { 13908 return; 13909 } 13910 13911 //If we are using droppables, inform the manager about the drop 13912 if ($.ui.ddmanager && !this.options.dropBehaviour) { 13913 $.ui.ddmanager.drop(this, event); 13914 } 13915 13916 if(this.options.revert) { 13917 var that = this, 13918 cur = this.placeholder.offset(), 13919 axis = this.options.axis, 13920 animation = {}; 13921 13922 if ( !axis || axis === "x" ) { 13923 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft); 13924 } 13925 if ( !axis || axis === "y" ) { 13926 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop); 13927 } 13928 this.reverting = true; 13929 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 13930 that._clear(event); 13931 }); 13932 } else { 13933 this._clear(event, noPropagation); 13934 } 13935 13936 return false; 13937 13938 }, 13939 13940 cancel: function() { 13941 13942 if(this.dragging) { 13943 13944 this._mouseUp({ target: null }); 13945 13946 if(this.options.helper === "original") { 13947 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 13948 } else { 13949 this.currentItem.show(); 13950 } 13951 13952 //Post deactivating events to containers 13953 for (var i = this.containers.length - 1; i >= 0; i--){ 13954 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 13955 if(this.containers[i].containerCache.over) { 13956 this.containers[i]._trigger("out", null, this._uiHash(this)); 13957 this.containers[i].containerCache.over = 0; 13958 } 13959 } 13960 13961 } 13962 13963 if (this.placeholder) { 13964 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 13965 if(this.placeholder[0].parentNode) { 13966 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 13967 } 13968 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 13969 this.helper.remove(); 13970 } 13971 13972 $.extend(this, { 13973 helper: null, 13974 dragging: false, 13975 reverting: false, 13976 _noFinalSort: null 13977 }); 13978 13979 if(this.domPosition.prev) { 13980 $(this.domPosition.prev).after(this.currentItem); 13981 } else { 13982 $(this.domPosition.parent).prepend(this.currentItem); 13983 } 13984 } 13985 13986 return this; 13987 13988 }, 13989 13990 serialize: function(o) { 13991 13992 var items = this._getItemsAsjQuery(o && o.connected), 13993 str = []; 13994 o = o || {}; 13995 13996 $(items).each(function() { 13997 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 13998 if (res) { 13999 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 14000 } 14001 }); 14002 14003 if(!str.length && o.key) { 14004 str.push(o.key + "="); 14005 } 14006 14007 return str.join("&"); 14008 14009 }, 14010 14011 toArray: function(o) { 14012 14013 var items = this._getItemsAsjQuery(o && o.connected), 14014 ret = []; 14015 14016 o = o || {}; 14017 14018 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 14019 return ret; 14020 14021 }, 14022 14023 /* Be careful with the following core functions */ 14024 _intersectsWith: function(item) { 14025 14026 var x1 = this.positionAbs.left, 14027 x2 = x1 + this.helperProportions.width, 14028 y1 = this.positionAbs.top, 14029 y2 = y1 + this.helperProportions.height, 14030 l = item.left, 14031 r = l + item.width, 14032 t = item.top, 14033 b = t + item.height, 14034 dyClick = this.offset.click.top, 14035 dxClick = this.offset.click.left, 14036 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 14037 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 14038 isOverElement = isOverElementHeight && isOverElementWidth; 14039 14040 if ( this.options.tolerance === "pointer" || 14041 this.options.forcePointerForContainers || 14042 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 14043 ) { 14044 return isOverElement; 14045 } else { 14046 14047 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 14048 x2 - (this.helperProportions.width / 2) < r && // Left Half 14049 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 14050 y2 - (this.helperProportions.height / 2) < b ); // Top Half 14051 14052 } 14053 }, 14054 14055 _intersectsWithPointer: function(item) { 14056 14057 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 14058 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 14059 isOverElement = isOverElementHeight && isOverElementWidth, 14060 verticalDirection = this._getDragVerticalDirection(), 14061 horizontalDirection = this._getDragHorizontalDirection(); 14062 14063 if (!isOverElement) { 14064 return false; 14065 } 14066 14067 return this.floating ? 14068 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 14069 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 14070 14071 }, 14072 14073 _intersectsWithSides: function(item) { 14074 14075 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 14076 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 14077 verticalDirection = this._getDragVerticalDirection(), 14078 horizontalDirection = this._getDragHorizontalDirection(); 14079 14080 if (this.floating && horizontalDirection) { 14081 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 14082 } else { 14083 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 14084 } 14085 14086 }, 14087 14088 _getDragVerticalDirection: function() { 14089 var delta = this.positionAbs.top - this.lastPositionAbs.top; 14090 return delta !== 0 && (delta > 0 ? "down" : "up"); 14091 }, 14092 14093 _getDragHorizontalDirection: function() { 14094 var delta = this.positionAbs.left - this.lastPositionAbs.left; 14095 return delta !== 0 && (delta > 0 ? "right" : "left"); 14096 }, 14097 14098 refresh: function(event) { 14099 this._refreshItems(event); 14100 this._setHandleClassName(); 14101 this.refreshPositions(); 14102 return this; 14103 }, 14104 14105 _connectWith: function() { 14106 var options = this.options; 14107 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 14108 }, 14109 14110 _getItemsAsjQuery: function(connected) { 14111 14112 var i, j, cur, inst, 14113 items = [], 14114 queries = [], 14115 connectWith = this._connectWith(); 14116 14117 if(connectWith && connected) { 14118 for (i = connectWith.length - 1; i >= 0; i--){ 14119 cur = $(connectWith[i], this.document[0]); 14120 for ( j = cur.length - 1; j >= 0; j--){ 14121 inst = $.data(cur[j], this.widgetFullName); 14122 if(inst && inst !== this && !inst.options.disabled) { 14123 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]); 14124 } 14125 } 14126 } 14127 } 14128 14129 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]); 14130 14131 function addItems() { 14132 items.push( this ); 14133 } 14134 for (i = queries.length - 1; i >= 0; i--){ 14135 queries[i][0].each( addItems ); 14136 } 14137 14138 return $(items); 14139 14140 }, 14141 14142 _removeCurrentsFromItems: function() { 14143 14144 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 14145 14146 this.items = $.grep(this.items, function (item) { 14147 for (var j=0; j < list.length; j++) { 14148 if(list[j] === item.item[0]) { 14149 return false; 14150 } 14151 } 14152 return true; 14153 }); 14154 14155 }, 14156 14157 _refreshItems: function(event) { 14158 14159 this.items = []; 14160 this.containers = [this]; 14161 14162 var i, j, cur, inst, targetData, _queries, item, queriesLength, 14163 items = this.items, 14164 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 14165 connectWith = this._connectWith(); 14166 14167 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 14168 for (i = connectWith.length - 1; i >= 0; i--){ 14169 cur = $(connectWith[i], this.document[0]); 14170 for (j = cur.length - 1; j >= 0; j--){ 14171 inst = $.data(cur[j], this.widgetFullName); 14172 if(inst && inst !== this && !inst.options.disabled) { 14173 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 14174 this.containers.push(inst); 14175 } 14176 } 14177 } 14178 } 14179 14180 for (i = queries.length - 1; i >= 0; i--) { 14181 targetData = queries[i][1]; 14182 _queries = queries[i][0]; 14183 14184 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 14185 item = $(_queries[j]); 14186 14187 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 14188 14189 items.push({ 14190 item: item, 14191 instance: targetData, 14192 width: 0, height: 0, 14193 left: 0, top: 0 14194 }); 14195 } 14196 } 14197 14198 }, 14199 14200 refreshPositions: function(fast) { 14201 14202 // Determine whether items are being displayed horizontally 14203 this.floating = this.items.length ? 14204 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 14205 false; 14206 14207 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 14208 if(this.offsetParent && this.helper) { 14209 this.offset.parent = this._getParentOffset(); 14210 } 14211 14212 var i, item, t, p; 14213 14214 for (i = this.items.length - 1; i >= 0; i--){ 14215 item = this.items[i]; 14216 14217 //We ignore calculating positions of all connected containers when we're not over them 14218 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 14219 continue; 14220 } 14221 14222 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 14223 14224 if (!fast) { 14225 item.width = t.outerWidth(); 14226 item.height = t.outerHeight(); 14227 } 14228 14229 p = t.offset(); 14230 item.left = p.left; 14231 item.top = p.top; 14232 } 14233 14234 if(this.options.custom && this.options.custom.refreshContainers) { 14235 this.options.custom.refreshContainers.call(this); 14236 } else { 14237 for (i = this.containers.length - 1; i >= 0; i--){ 14238 p = this.containers[i].element.offset(); 14239 this.containers[i].containerCache.left = p.left; 14240 this.containers[i].containerCache.top = p.top; 14241 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 14242 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 14243 } 14244 } 14245 14246 return this; 14247 }, 14248 14249 _createPlaceholder: function(that) { 14250 that = that || this; 14251 var className, 14252 o = that.options; 14253 14254 if(!o.placeholder || o.placeholder.constructor === String) { 14255 className = o.placeholder; 14256 o.placeholder = { 14257 element: function() { 14258 14259 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 14260 element = $( "<" + nodeName + ">", that.document[0] ) 14261 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 14262 .removeClass("ui-sortable-helper"); 14263 14264 if ( nodeName === "tbody" ) { 14265 that._createTrPlaceholder( 14266 that.currentItem.find( "tr" ).eq( 0 ), 14267 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 14268 ); 14269 } else if ( nodeName === "tr" ) { 14270 that._createTrPlaceholder( that.currentItem, element ); 14271 } else if ( nodeName === "img" ) { 14272 element.attr( "src", that.currentItem.attr( "src" ) ); 14273 } 14274 14275 if ( !className ) { 14276 element.css( "visibility", "hidden" ); 14277 } 14278 14279 return element; 14280 }, 14281 update: function(container, p) { 14282 14283 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 14284 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 14285 if(className && !o.forcePlaceholderSize) { 14286 return; 14287 } 14288 14289 //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 14290 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 14291 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 14292 } 14293 }; 14294 } 14295 14296 //Create the placeholder 14297 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 14298 14299 //Append it after the actual current item 14300 that.currentItem.after(that.placeholder); 14301 14302 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 14303 o.placeholder.update(that, that.placeholder); 14304 14305 }, 14306 14307 _createTrPlaceholder: function( sourceTr, targetTr ) { 14308 var that = this; 14309 14310 sourceTr.children().each(function() { 14311 $( "<td> </td>", that.document[ 0 ] ) 14312 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 14313 .appendTo( targetTr ); 14314 }); 14315 }, 14316 14317 _contactContainers: function(event) { 14318 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, 14319 innermostContainer = null, 14320 innermostIndex = null; 14321 14322 // get innermost container that intersects with item 14323 for (i = this.containers.length - 1; i >= 0; i--) { 14324 14325 // never consider a container that's located within the item itself 14326 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 14327 continue; 14328 } 14329 14330 if(this._intersectsWith(this.containers[i].containerCache)) { 14331 14332 // if we've already found a container and it's more "inner" than this, then continue 14333 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 14334 continue; 14335 } 14336 14337 innermostContainer = this.containers[i]; 14338 innermostIndex = i; 14339 14340 } else { 14341 // container doesn't intersect. trigger "out" event if necessary 14342 if(this.containers[i].containerCache.over) { 14343 this.containers[i]._trigger("out", event, this._uiHash(this)); 14344 this.containers[i].containerCache.over = 0; 14345 } 14346 } 14347 14348 } 14349 14350 // if no intersecting containers found, return 14351 if(!innermostContainer) { 14352 return; 14353 } 14354 14355 // move the item into the container if it's not there already 14356 if(this.containers.length === 1) { 14357 if (!this.containers[innermostIndex].containerCache.over) { 14358 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14359 this.containers[innermostIndex].containerCache.over = 1; 14360 } 14361 } else { 14362 14363 //When entering a new container, we will find the item with the least distance and append our item near it 14364 dist = 10000; 14365 itemWithLeastDistance = null; 14366 floating = innermostContainer.floating || this._isFloating(this.currentItem); 14367 posProperty = floating ? "left" : "top"; 14368 sizeProperty = floating ? "width" : "height"; 14369 axis = floating ? "clientX" : "clientY"; 14370 14371 for (j = this.items.length - 1; j >= 0; j--) { 14372 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 14373 continue; 14374 } 14375 if(this.items[j].item[0] === this.currentItem[0]) { 14376 continue; 14377 } 14378 14379 cur = this.items[j].item.offset()[posProperty]; 14380 nearBottom = false; 14381 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 14382 nearBottom = true; 14383 } 14384 14385 if ( Math.abs( event[ axis ] - cur ) < dist ) { 14386 dist = Math.abs( event[ axis ] - cur ); 14387 itemWithLeastDistance = this.items[ j ]; 14388 this.direction = nearBottom ? "up": "down"; 14389 } 14390 } 14391 14392 //Check if dropOnEmpty is enabled 14393 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 14394 return; 14395 } 14396 14397 if(this.currentContainer === this.containers[innermostIndex]) { 14398 if ( !this.currentContainer.containerCache.over ) { 14399 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 14400 this.currentContainer.containerCache.over = 1; 14401 } 14402 return; 14403 } 14404 14405 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 14406 this._trigger("change", event, this._uiHash()); 14407 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 14408 this.currentContainer = this.containers[innermostIndex]; 14409 14410 //Update the placeholder 14411 this.options.placeholder.update(this.currentContainer, this.placeholder); 14412 14413 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14414 this.containers[innermostIndex].containerCache.over = 1; 14415 } 14416 14417 14418 }, 14419 14420 _createHelper: function(event) { 14421 14422 var o = this.options, 14423 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 14424 14425 //Add the helper to the DOM if that didn't happen already 14426 if(!helper.parents("body").length) { 14427 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 14428 } 14429 14430 if(helper[0] === this.currentItem[0]) { 14431 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") }; 14432 } 14433 14434 if(!helper[0].style.width || o.forceHelperSize) { 14435 helper.width(this.currentItem.width()); 14436 } 14437 if(!helper[0].style.height || o.forceHelperSize) { 14438 helper.height(this.currentItem.height()); 14439 } 14440 14441 return helper; 14442 14443 }, 14444 14445 _adjustOffsetFromHelper: function(obj) { 14446 if (typeof obj === "string") { 14447 obj = obj.split(" "); 14448 } 14449 if ($.isArray(obj)) { 14450 obj = {left: +obj[0], top: +obj[1] || 0}; 14451 } 14452 if ("left" in obj) { 14453 this.offset.click.left = obj.left + this.margins.left; 14454 } 14455 if ("right" in obj) { 14456 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 14457 } 14458 if ("top" in obj) { 14459 this.offset.click.top = obj.top + this.margins.top; 14460 } 14461 if ("bottom" in obj) { 14462 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 14463 } 14464 }, 14465 14466 _getParentOffset: function() { 14467 14468 14469 //Get the offsetParent and cache its position 14470 this.offsetParent = this.helper.offsetParent(); 14471 var po = this.offsetParent.offset(); 14472 14473 // This is a special case where we need to modify a offset calculated on start, since the following happened: 14474 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 14475 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 14476 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 14477 if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) { 14478 po.left += this.scrollParent.scrollLeft(); 14479 po.top += this.scrollParent.scrollTop(); 14480 } 14481 14482 // This needs to be actually done for all browsers, since pageX/pageY includes this information 14483 // with an ugly IE fix 14484 if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 14485 po = { top: 0, left: 0 }; 14486 } 14487 14488 return { 14489 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 14490 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 14491 }; 14492 14493 }, 14494 14495 _getRelativeOffset: function() { 14496 14497 if(this.cssPosition === "relative") { 14498 var p = this.currentItem.position(); 14499 return { 14500 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 14501 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 14502 }; 14503 } else { 14504 return { top: 0, left: 0 }; 14505 } 14506 14507 }, 14508 14509 _cacheMargins: function() { 14510 this.margins = { 14511 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 14512 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 14513 }; 14514 }, 14515 14516 _cacheHelperProportions: function() { 14517 this.helperProportions = { 14518 width: this.helper.outerWidth(), 14519 height: this.helper.outerHeight() 14520 }; 14521 }, 14522 14523 _setContainment: function() { 14524 14525 var ce, co, over, 14526 o = this.options; 14527 if(o.containment === "parent") { 14528 o.containment = this.helper[0].parentNode; 14529 } 14530 if(o.containment === "document" || o.containment === "window") { 14531 this.containment = [ 14532 0 - this.offset.relative.left - this.offset.parent.left, 14533 0 - this.offset.relative.top - this.offset.parent.top, 14534 o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, 14535 (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 14536 ]; 14537 } 14538 14539 if(!(/^(document|window|parent)$/).test(o.containment)) { 14540 ce = $(o.containment)[0]; 14541 co = $(o.containment).offset(); 14542 over = ($(ce).css("overflow") !== "hidden"); 14543 14544 this.containment = [ 14545 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 14546 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 14547 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, 14548 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 14549 ]; 14550 } 14551 14552 }, 14553 14554 _convertPositionTo: function(d, pos) { 14555 14556 if(!pos) { 14557 pos = this.position; 14558 } 14559 var mod = d === "absolute" ? 1 : -1, 14560 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 14561 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 14562 14563 return { 14564 top: ( 14565 pos.top + // The absolute mouse position 14566 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14567 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 14568 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 14569 ), 14570 left: ( 14571 pos.left + // The absolute mouse position 14572 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14573 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 14574 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 14575 ) 14576 }; 14577 14578 }, 14579 14580 _generatePosition: function(event) { 14581 14582 var top, left, 14583 o = this.options, 14584 pageX = event.pageX, 14585 pageY = event.pageY, 14586 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); 14587 14588 // This is another very weird special case that only happens for relative elements: 14589 // 1. If the css position is relative 14590 // 2. and the scroll parent is the document or similar to the offset parent 14591 // we have to refresh the relative offset during the scroll so there are no jumps 14592 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) { 14593 this.offset.relative = this._getRelativeOffset(); 14594 } 14595 14596 /* 14597 * - Position constraining - 14598 * Constrain the position to a mix of grid, containment. 14599 */ 14600 14601 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 14602 14603 if(this.containment) { 14604 if(event.pageX - this.offset.click.left < this.containment[0]) { 14605 pageX = this.containment[0] + this.offset.click.left; 14606 } 14607 if(event.pageY - this.offset.click.top < this.containment[1]) { 14608 pageY = this.containment[1] + this.offset.click.top; 14609 } 14610 if(event.pageX - this.offset.click.left > this.containment[2]) { 14611 pageX = this.containment[2] + this.offset.click.left; 14612 } 14613 if(event.pageY - this.offset.click.top > this.containment[3]) { 14614 pageY = this.containment[3] + this.offset.click.top; 14615 } 14616 } 14617 14618 if(o.grid) { 14619 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 14620 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; 14621 14622 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 14623 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; 14624 } 14625 14626 } 14627 14628 return { 14629 top: ( 14630 pageY - // The absolute mouse position 14631 this.offset.click.top - // Click offset (relative to the element) 14632 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 14633 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 14634 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 14635 ), 14636 left: ( 14637 pageX - // The absolute mouse position 14638 this.offset.click.left - // Click offset (relative to the element) 14639 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 14640 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 14641 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 14642 ) 14643 }; 14644 14645 }, 14646 14647 _rearrange: function(event, i, a, hardRefresh) { 14648 14649 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)); 14650 14651 //Various things done here to improve the performance: 14652 // 1. we create a setTimeout, that calls refreshPositions 14653 // 2. on the instance, we have a counter variable, that get's higher after every append 14654 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 14655 // 4. this lets only the last addition to the timeout stack through 14656 this.counter = this.counter ? ++this.counter : 1; 14657 var counter = this.counter; 14658 14659 this._delay(function() { 14660 if(counter === this.counter) { 14661 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 14662 } 14663 }); 14664 14665 }, 14666 14667 _clear: function(event, noPropagation) { 14668 14669 this.reverting = false; 14670 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 14671 // everything else normalized again 14672 var i, 14673 delayedTriggers = []; 14674 14675 // We first have to update the dom position of the actual currentItem 14676 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 14677 if(!this._noFinalSort && this.currentItem.parent().length) { 14678 this.placeholder.before(this.currentItem); 14679 } 14680 this._noFinalSort = null; 14681 14682 if(this.helper[0] === this.currentItem[0]) { 14683 for(i in this._storedCSS) { 14684 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 14685 this._storedCSS[i] = ""; 14686 } 14687 } 14688 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 14689 } else { 14690 this.currentItem.show(); 14691 } 14692 14693 if(this.fromOutside && !noPropagation) { 14694 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 14695 } 14696 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 14697 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 14698 } 14699 14700 // Check if the items Container has Changed and trigger appropriate 14701 // events. 14702 if (this !== this.currentContainer) { 14703 if(!noPropagation) { 14704 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 14705 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14706 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14707 } 14708 } 14709 14710 14711 //Post events to containers 14712 function delayEvent( type, instance, container ) { 14713 return function( event ) { 14714 container._trigger( type, event, instance._uiHash( instance ) ); 14715 }; 14716 } 14717 for (i = this.containers.length - 1; i >= 0; i--){ 14718 if (!noPropagation) { 14719 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 14720 } 14721 if(this.containers[i].containerCache.over) { 14722 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 14723 this.containers[i].containerCache.over = 0; 14724 } 14725 } 14726 14727 //Do what was originally in plugins 14728 if ( this.storedCursor ) { 14729 this.document.find( "body" ).css( "cursor", this.storedCursor ); 14730 this.storedStylesheet.remove(); 14731 } 14732 if(this._storedOpacity) { 14733 this.helper.css("opacity", this._storedOpacity); 14734 } 14735 if(this._storedZIndex) { 14736 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 14737 } 14738 14739 this.dragging = false; 14740 14741 if(!noPropagation) { 14742 this._trigger("beforeStop", event, this._uiHash()); 14743 } 14744 14745 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 14746 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 14747 14748 if ( !this.cancelHelperRemoval ) { 14749 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 14750 this.helper.remove(); 14751 } 14752 this.helper = null; 14753 } 14754 14755 if(!noPropagation) { 14756 for (i=0; i < delayedTriggers.length; i++) { 14757 delayedTriggers[i].call(this, event); 14758 } //Trigger all delayed events 14759 this._trigger("stop", event, this._uiHash()); 14760 } 14761 14762 this.fromOutside = false; 14763 return !this.cancelHelperRemoval; 14764 14765 }, 14766 14767 _trigger: function() { 14768 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 14769 this.cancel(); 14770 } 14771 }, 14772 14773 _uiHash: function(_inst) { 14774 var inst = _inst || this; 14775 return { 14776 helper: inst.helper, 14777 placeholder: inst.placeholder || $([]), 14778 position: inst.position, 14779 originalPosition: inst.originalPosition, 14780 offset: inst.positionAbs, 14781 item: inst.currentItem, 14782 sender: _inst ? _inst.element : null 14783 }; 14784 } 14785 14786}); 14787 14788 14789/*! 14790 * jQuery UI Spinner 1.11.4 14791 * http://jqueryui.com 14792 * 14793 * Copyright jQuery Foundation and other contributors 14794 * Released under the MIT license. 14795 * http://jquery.org/license 14796 * 14797 * http://api.jqueryui.com/spinner/ 14798 */ 14799 14800 14801function spinner_modifier( fn ) { 14802 return function() { 14803 var previous = this.element.val(); 14804 fn.apply( this, arguments ); 14805 this._refresh(); 14806 if ( previous !== this.element.val() ) { 14807 this._trigger( "change" ); 14808 } 14809 }; 14810} 14811 14812var spinner = $.widget( "ui.spinner", { 14813 version: "1.11.4", 14814 defaultElement: "<input>", 14815 widgetEventPrefix: "spin", 14816 options: { 14817 culture: null, 14818 icons: { 14819 down: "ui-icon-triangle-1-s", 14820 up: "ui-icon-triangle-1-n" 14821 }, 14822 incremental: true, 14823 max: null, 14824 min: null, 14825 numberFormat: null, 14826 page: 10, 14827 step: 1, 14828 14829 change: null, 14830 spin: null, 14831 start: null, 14832 stop: null 14833 }, 14834 14835 _create: function() { 14836 // handle string values that need to be parsed 14837 this._setOption( "max", this.options.max ); 14838 this._setOption( "min", this.options.min ); 14839 this._setOption( "step", this.options.step ); 14840 14841 // Only format if there is a value, prevents the field from being marked 14842 // as invalid in Firefox, see #9573. 14843 if ( this.value() !== "" ) { 14844 // Format the value, but don't constrain. 14845 this._value( this.element.val(), true ); 14846 } 14847 14848 this._draw(); 14849 this._on( this._events ); 14850 this._refresh(); 14851 14852 // turning off autocomplete prevents the browser from remembering the 14853 // value when navigating through history, so we re-enable autocomplete 14854 // if the page is unloaded before the widget is destroyed. #7790 14855 this._on( this.window, { 14856 beforeunload: function() { 14857 this.element.removeAttr( "autocomplete" ); 14858 } 14859 }); 14860 }, 14861 14862 _getCreateOptions: function() { 14863 var options = {}, 14864 element = this.element; 14865 14866 $.each( [ "min", "max", "step" ], function( i, option ) { 14867 var value = element.attr( option ); 14868 if ( value !== undefined && value.length ) { 14869 options[ option ] = value; 14870 } 14871 }); 14872 14873 return options; 14874 }, 14875 14876 _events: { 14877 keydown: function( event ) { 14878 if ( this._start( event ) && this._keydown( event ) ) { 14879 event.preventDefault(); 14880 } 14881 }, 14882 keyup: "_stop", 14883 focus: function() { 14884 this.previous = this.element.val(); 14885 }, 14886 blur: function( event ) { 14887 if ( this.cancelBlur ) { 14888 delete this.cancelBlur; 14889 return; 14890 } 14891 14892 this._stop(); 14893 this._refresh(); 14894 if ( this.previous !== this.element.val() ) { 14895 this._trigger( "change", event ); 14896 } 14897 }, 14898 mousewheel: function( event, delta ) { 14899 if ( !delta ) { 14900 return; 14901 } 14902 if ( !this.spinning && !this._start( event ) ) { 14903 return false; 14904 } 14905 14906 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 14907 clearTimeout( this.mousewheelTimer ); 14908 this.mousewheelTimer = this._delay(function() { 14909 if ( this.spinning ) { 14910 this._stop( event ); 14911 } 14912 }, 100 ); 14913 event.preventDefault(); 14914 }, 14915 "mousedown .ui-spinner-button": function( event ) { 14916 var previous; 14917 14918 // We never want the buttons to have focus; whenever the user is 14919 // interacting with the spinner, the focus should be on the input. 14920 // If the input is focused then this.previous is properly set from 14921 // when the input first received focus. If the input is not focused 14922 // then we need to set this.previous based on the value before spinning. 14923 previous = this.element[0] === this.document[0].activeElement ? 14924 this.previous : this.element.val(); 14925 function checkFocus() { 14926 var isActive = this.element[0] === this.document[0].activeElement; 14927 if ( !isActive ) { 14928 this.element.focus(); 14929 this.previous = previous; 14930 // support: IE 14931 // IE sets focus asynchronously, so we need to check if focus 14932 // moved off of the input because the user clicked on the button. 14933 this._delay(function() { 14934 this.previous = previous; 14935 }); 14936 } 14937 } 14938 14939 // ensure focus is on (or stays on) the text field 14940 event.preventDefault();
vendor: 5,275 bytes, lines 14941-15142
14941 checkFocus.call( this ); 14942 14943 // support: IE 14944 // IE doesn't prevent moving focus even with event.preventDefault() 14945 // so we set a flag to know when we should ignore the blur event 14946 // and check (again) if focus moved off of the input. 14947 this.cancelBlur = true; 14948 this._delay(function() { 14949 delete this.cancelBlur; 14950 checkFocus.call( this ); 14951 }); 14952 14953 if ( this._start( event ) === false ) { 14954 return; 14955 } 14956 14957 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14958 }, 14959 "mouseup .ui-spinner-button": "_stop", 14960 "mouseenter .ui-spinner-button": function( event ) { 14961 // button will add ui-state-active if mouse was down while mouseleave and kept down 14962 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 14963 return; 14964 } 14965 14966 if ( this._start( event ) === false ) { 14967 return false; 14968 } 14969 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 14970 }, 14971 // TODO: do we really want to consider this a stop? 14972 // shouldn't we just stop the repeater and wait until mouseup before 14973 // we trigger the stop event? 14974 "mouseleave .ui-spinner-button": "_stop" 14975 }, 14976 14977 _draw: function() { 14978 var uiSpinner = this.uiSpinner = this.element 14979 .addClass( "ui-spinner-input" ) 14980 .attr( "autocomplete", "off" ) 14981 .wrap( this._uiSpinnerHtml() ) 14982 .parent() 14983 // add buttons 14984 .append( this._buttonHtml() ); 14985 14986 this.element.attr( "role", "spinbutton" ); 14987 14988 // button bindings 14989 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 14990 .attr( "tabIndex", -1 ) 14991 .button() 14992 .removeClass( "ui-corner-all" ); 14993 14994 // IE 6 doesn't understand height: 50% for the buttons 14995 // unless the wrapper has an explicit height 14996 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 14997 uiSpinner.height() > 0 ) { 14998 uiSpinner.height( uiSpinner.height() ); 14999 } 15000 15001 // disable spinner if element was already disabled 15002 if ( this.options.disabled ) { 15003 this.disable(); 15004 } 15005 }, 15006 15007 _keydown: function( event ) { 15008 var options = this.options, 15009 keyCode = $.ui.keyCode; 15010 15011 switch ( event.keyCode ) { 15012 case keyCode.UP: 15013 this._repeat( null, 1, event ); 15014 return true; 15015 case keyCode.DOWN: 15016 this._repeat( null, -1, event ); 15017 return true; 15018 case keyCode.PAGE_UP: 15019 this._repeat( null, options.page, event ); 15020 return true; 15021 case keyCode.PAGE_DOWN: 15022 this._repeat( null, -options.page, event ); 15023 return true; 15024 } 15025 15026 return false; 15027 }, 15028 15029 _uiSpinnerHtml: function() { 15030 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 15031 }, 15032 15033 _buttonHtml: function() { 15034 return "" + 15035 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 15036 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 15037 "</a>" + 15038 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 15039 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 15040 "</a>"; 15041 }, 15042 15043 _start: function( event ) { 15044 if ( !this.spinning && this._trigger( "start", event ) === false ) { 15045 return false; 15046 } 15047 15048 if ( !this.counter ) { 15049 this.counter = 1; 15050 } 15051 this.spinning = true; 15052 return true; 15053 }, 15054 15055 _repeat: function( i, steps, event ) { 15056 i = i || 500; 15057 15058 clearTimeout( this.timer ); 15059 this.timer = this._delay(function() { 15060 this._repeat( 40, steps, event ); 15061 }, i ); 15062 15063 this._spin( steps * this.options.step, event ); 15064 }, 15065 15066 _spin: function( step, event ) { 15067 var value = this.value() || 0; 15068 15069 if ( !this.counter ) { 15070 this.counter = 1; 15071 } 15072 15073 value = this._adjustValue( value + step * this._increment( this.counter ) ); 15074 15075 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 15076 this._value( value ); 15077 this.counter++; 15078 } 15079 }, 15080 15081 _increment: function( i ) { 15082 var incremental = this.options.incremental; 15083 15084 if ( incremental ) { 15085 return $.isFunction( incremental ) ? 15086 incremental( i ) : 15087 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 15088 } 15089 15090 return 1; 15091 }, 15092 15093 _precision: function() { 15094 var precision = this._precisionOf( this.options.step ); 15095 if ( this.options.min !== null ) { 15096 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15097 } 15098 return precision; 15099 }, 15100 15101 _precisionOf: function( num ) { 15102 var str = num.toString(), 15103 decimal = str.indexOf( "." ); 15104 return decimal === -1 ? 0 : str.length - decimal - 1; 15105 }, 15106 15107 _adjustValue: function( value ) { 15108 var base, aboveMin, 15109 options = this.options; 15110 15111 // make sure we're at a valid step 15112 // - find out where we are relative to the base (min or 0) 15113 base = options.min !== null ? options.min : 0; 15114 aboveMin = value - base; 15115 // - round to the nearest step 15116 aboveMin = Math.round(aboveMin / options.step) * options.step; 15117 // - rounding is based on 0, so adjust back to our base 15118 value = base + aboveMin; 15119 15120 // fix precision from bad JS floating point math 15121 value = parseFloat( value.toFixed( this._precision() ) ); 15122 15123 // clamp the value 15124 if ( options.max !== null && value > options.max) { 15125 return options.max; 15126 } 15127 if ( options.min !== null && value < options.min ) { 15128 return options.min; 15129 } 15130 15131 return value; 15132 }, 15133 15134 _stop: function( event ) { 15135 if ( !this.spinning ) { 15136 return; 15137 } 15138 15139 clearTimeout( this.timer ); 15140 clearTimeout( this.mousewheelTimer ); 15141 this.counter = 0; 15142 this.spinning = false;
vendor: 16,063 bytes, lines 15143-15760
15143 this._trigger( "stop", event ); 15144 }, 15145 15146 _setOption: function( key, value ) { 15147 if ( key === "culture" || key === "numberFormat" ) { 15148 var prevValue = this._parse( this.element.val() ); 15149 this.options[ key ] = value; 15150 this.element.val( this._format( prevValue ) ); 15151 return; 15152 } 15153 15154 if ( key === "max" || key === "min" || key === "step" ) { 15155 if ( typeof value === "string" ) { 15156 value = this._parse( value ); 15157 } 15158 } 15159 if ( key === "icons" ) { 15160 this.buttons.first().find( ".ui-icon" ) 15161 .removeClass( this.options.icons.up ) 15162 .addClass( value.up ); 15163 this.buttons.last().find( ".ui-icon" ) 15164 .removeClass( this.options.icons.down ) 15165 .addClass( value.down ); 15166 } 15167 15168 this._super( key, value ); 15169 15170 if ( key === "disabled" ) { 15171 this.widget().toggleClass( "ui-state-disabled", !!value ); 15172 this.element.prop( "disabled", !!value ); 15173 this.buttons.button( value ? "disable" : "enable" ); 15174 } 15175 }, 15176 15177 _setOptions: spinner_modifier(function( options ) { 15178 this._super( options ); 15179 }), 15180 15181 _parse: function( val ) { 15182 if ( typeof val === "string" && val !== "" ) { 15183 val = window.Globalize && this.options.numberFormat ? 15184 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 15185 } 15186 return val === "" || isNaN( val ) ? null : val; 15187 }, 15188 15189 _format: function( value ) { 15190 if ( value === "" ) { 15191 return ""; 15192 } 15193 return window.Globalize && this.options.numberFormat ? 15194 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 15195 value; 15196 }, 15197 15198 _refresh: function() { 15199 this.element.attr({ 15200 "aria-valuemin": this.options.min, 15201 "aria-valuemax": this.options.max, 15202 // TODO: what should we do with values that can't be parsed? 15203 "aria-valuenow": this._parse( this.element.val() ) 15204 }); 15205 }, 15206 15207 isValid: function() { 15208 var value = this.value(); 15209 15210 // null is invalid 15211 if ( value === null ) { 15212 return false; 15213 } 15214 15215 // if value gets adjusted, it's invalid 15216 return value === this._adjustValue( value ); 15217 }, 15218 15219 // update the value without triggering change 15220 _value: function( value, allowAny ) { 15221 var parsed; 15222 if ( value !== "" ) { 15223 parsed = this._parse( value ); 15224 if ( parsed !== null ) { 15225 if ( !allowAny ) { 15226 parsed = this._adjustValue( parsed ); 15227 } 15228 value = this._format( parsed ); 15229 } 15230 } 15231 this.element.val( value ); 15232 this._refresh(); 15233 }, 15234 15235 _destroy: function() { 15236 this.element 15237 .removeClass( "ui-spinner-input" ) 15238 .prop( "disabled", false ) 15239 .removeAttr( "autocomplete" ) 15240 .removeAttr( "role" ) 15241 .removeAttr( "aria-valuemin" ) 15242 .removeAttr( "aria-valuemax" ) 15243 .removeAttr( "aria-valuenow" ); 15244 this.uiSpinner.replaceWith( this.element ); 15245 }, 15246 15247 stepUp: spinner_modifier(function( steps ) { 15248 this._stepUp( steps ); 15249 }), 15250 _stepUp: function( steps ) { 15251 if ( this._start() ) { 15252 this._spin( (steps || 1) * this.options.step ); 15253 this._stop(); 15254 } 15255 }, 15256 15257 stepDown: spinner_modifier(function( steps ) { 15258 this._stepDown( steps ); 15259 }), 15260 _stepDown: function( steps ) { 15261 if ( this._start() ) { 15262 this._spin( (steps || 1) * -this.options.step ); 15263 this._stop(); 15264 } 15265 }, 15266 15267 pageUp: spinner_modifier(function( pages ) { 15268 this._stepUp( (pages || 1) * this.options.page ); 15269 }), 15270 15271 pageDown: spinner_modifier(function( pages ) { 15272 this._stepDown( (pages || 1) * this.options.page ); 15273 }), 15274 15275 value: function( newVal ) { 15276 if ( !arguments.length ) { 15277 return this._parse( this.element.val() ); 15278 } 15279 spinner_modifier( this._value ).call( this, newVal ); 15280 }, 15281 15282 widget: function() { 15283 return this.uiSpinner; 15284 } 15285}); 15286 15287 15288/*! 15289 * jQuery UI Tabs 1.11.4 15290 * http://jqueryui.com 15291 * 15292 * Copyright jQuery Foundation and other contributors 15293 * Released under the MIT license. 15294 * http://jquery.org/license 15295 * 15296 * http://api.jqueryui.com/tabs/ 15297 */ 15298 15299 15300var tabs = $.widget( "ui.tabs", { 15301 version: "1.11.4", 15302 delay: 300, 15303 options: { 15304 active: null, 15305 collapsible: false, 15306 event: "click", 15307 heightStyle: "content", 15308 hide: null, 15309 show: null, 15310 15311 // callbacks 15312 activate: null, 15313 beforeActivate: null, 15314 beforeLoad: null, 15315 load: null 15316 }, 15317 15318 _isLocal: (function() { 15319 var rhash = /#.*$/; 15320 15321 return function( anchor ) { 15322 var anchorUrl, locationUrl; 15323 15324 // support: IE7 15325 // IE7 doesn't normalize the href property when set via script (#9317) 15326 anchor = anchor.cloneNode( false ); 15327 15328 anchorUrl = anchor.href.replace( rhash, "" ); 15329 locationUrl = location.href.replace( rhash, "" ); 15330 15331 // decoding may throw an error if the URL isn't UTF-8 (#9518) 15332 try { 15333 anchorUrl = decodeURIComponent( anchorUrl ); 15334 } catch ( error ) {} 15335 try { 15336 locationUrl = decodeURIComponent( locationUrl ); 15337 } catch ( error ) {} 15338 15339 return anchor.hash.length > 1 && anchorUrl === locationUrl; 15340 }; 15341 })(), 15342 15343 _create: function() { 15344 var that = this, 15345 options = this.options; 15346 15347 this.running = false; 15348 15349 this.element 15350 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 15351 .toggleClass( "ui-tabs-collapsible", options.collapsible ); 15352 15353 this._processTabs(); 15354 options.active = this._initialActive(); 15355 15356 // Take disabling tabs via class attribute from HTML 15357 // into account and update option properly. 15358 if ( $.isArray( options.disabled ) ) { 15359 options.disabled = $.unique( options.disabled.concat( 15360 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 15361 return that.tabs.index( li ); 15362 }) 15363 ) ).sort(); 15364 } 15365 15366 // check for length avoids error when initializing empty list 15367 if ( this.options.active !== false && this.anchors.length ) { 15368 this.active = this._findActive( options.active ); 15369 } else { 15370 this.active = $(); 15371 } 15372 15373 this._refresh(); 15374 15375 if ( this.active.length ) { 15376 this.load( options.active ); 15377 } 15378 }, 15379 15380 _initialActive: function() { 15381 var active = this.options.active, 15382 collapsible = this.options.collapsible, 15383 locationHash = location.hash.substring( 1 ); 15384 15385 if ( active === null ) { 15386 // check the fragment identifier in the URL 15387 if ( locationHash ) { 15388 this.tabs.each(function( i, tab ) { 15389 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 15390 active = i; 15391 return false; 15392 } 15393 }); 15394 } 15395 15396 // check for a tab marked active via a class 15397 if ( active === null ) { 15398 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 15399 } 15400 15401 // no active tab, set to false 15402 if ( active === null || active === -1 ) { 15403 active = this.tabs.length ? 0 : false; 15404 } 15405 } 15406 15407 // handle numbers: negative, out of range 15408 if ( active !== false ) { 15409 active = this.tabs.index( this.tabs.eq( active ) ); 15410 if ( active === -1 ) { 15411 active = collapsible ? false : 0; 15412 } 15413 } 15414 15415 // don't allow collapsible: false and active: false 15416 if ( !collapsible && active === false && this.anchors.length ) { 15417 active = 0; 15418 } 15419 15420 return active; 15421 }, 15422 15423 _getCreateEventData: function() { 15424 return { 15425 tab: this.active, 15426 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 15427 }; 15428 }, 15429 15430 _tabKeydown: function( event ) { 15431 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 15432 selectedIndex = this.tabs.index( focusedTab ), 15433 goingForward = true; 15434 15435 if ( this._handlePageNav( event ) ) { 15436 return; 15437 } 15438 15439 switch ( event.keyCode ) { 15440 case $.ui.keyCode.RIGHT: 15441 case $.ui.keyCode.DOWN: 15442 selectedIndex++; 15443 break; 15444 case $.ui.keyCode.UP: 15445 case $.ui.keyCode.LEFT: 15446 goingForward = false; 15447 selectedIndex--; 15448 break; 15449 case $.ui.keyCode.END: 15450 selectedIndex = this.anchors.length - 1; 15451 break; 15452 case $.ui.keyCode.HOME: 15453 selectedIndex = 0; 15454 break; 15455 case $.ui.keyCode.SPACE: 15456 // Activate only, no collapsing 15457 event.preventDefault(); 15458 clearTimeout( this.activating ); 15459 this._activate( selectedIndex ); 15460 return; 15461 case $.ui.keyCode.ENTER: 15462 // Toggle (cancel delayed activation, allow collapsing) 15463 event.preventDefault(); 15464 clearTimeout( this.activating ); 15465 // Determine if we should collapse or activate 15466 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 15467 return; 15468 default: 15469 return; 15470 } 15471 15472 // Focus the appropriate tab, based on which key was pressed 15473 event.preventDefault(); 15474 clearTimeout( this.activating ); 15475 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 15476 15477 // Navigating with control/command key will prevent automatic activation 15478 if ( !event.ctrlKey && !event.metaKey ) { 15479 15480 // Update aria-selected immediately so that AT think the tab is already selected. 15481 // Otherwise AT may confuse the user by stating that they need to activate the tab, 15482 // but the tab will already be activated by the time the announcement finishes. 15483 focusedTab.attr( "aria-selected", "false" ); 15484 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 15485 15486 this.activating = this._delay(function() { 15487 this.option( "active", selectedIndex ); 15488 }, this.delay ); 15489 } 15490 }, 15491 15492 _panelKeydown: function( event ) { 15493 if ( this._handlePageNav( event ) ) { 15494 return; 15495 } 15496 15497 // Ctrl+up moves focus to the current tab 15498 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 15499 event.preventDefault(); 15500 this.active.focus(); 15501 } 15502 }, 15503 15504 // Alt+page up/down moves focus to the previous/next tab (and activates) 15505 _handlePageNav: function( event ) { 15506 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 15507 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 15508 return true; 15509 } 15510 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 15511 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 15512 return true; 15513 } 15514 }, 15515 15516 _findNextTab: function( index, goingForward ) { 15517 var lastTabIndex = this.tabs.length - 1; 15518 15519 function constrain() { 15520 if ( index > lastTabIndex ) { 15521 index = 0; 15522 } 15523 if ( index < 0 ) { 15524 index = lastTabIndex; 15525 } 15526 return index; 15527 } 15528 15529 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 15530 index = goingForward ? index + 1 : index - 1; 15531 } 15532 15533 return index; 15534 }, 15535 15536 _focusNextTab: function( index, goingForward ) { 15537 index = this._findNextTab( index, goingForward ); 15538 this.tabs.eq( index ).focus(); 15539 return index; 15540 }, 15541 15542 _setOption: function( key, value ) { 15543 if ( key === "active" ) { 15544 // _activate() will handle invalid values and update this.options 15545 this._activate( value ); 15546 return; 15547 } 15548 15549 if ( key === "disabled" ) { 15550 // don't use the widget factory's disabled handling 15551 this._setupDisabled( value ); 15552 return; 15553 } 15554 15555 this._super( key, value); 15556 15557 if ( key === "collapsible" ) { 15558 this.element.toggleClass( "ui-tabs-collapsible", value ); 15559 // Setting collapsible: false while collapsed; open first panel 15560 if ( !value && this.options.active === false ) { 15561 this._activate( 0 ); 15562 } 15563 } 15564 15565 if ( key === "event" ) { 15566 this._setupEvents( value ); 15567 } 15568 15569 if ( key === "heightStyle" ) { 15570 this._setupHeightStyle( value ); 15571 } 15572 }, 15573 15574 _sanitizeSelector: function( hash ) { 15575 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 15576 }, 15577 15578 refresh: function() { 15579 var options = this.options, 15580 lis = this.tablist.children( ":has(a[href])" ); 15581 15582 // get disabled tabs from class attribute from HTML 15583 // this will get converted to a boolean if needed in _refresh() 15584 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15585 return lis.index( tab ); 15586 }); 15587 15588 this._processTabs(); 15589 15590 // was collapsed or no tabs 15591 if ( options.active === false || !this.anchors.length ) { 15592 options.active = false; 15593 this.active = $(); 15594 // was active, but active tab is gone 15595 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15596 // all remaining tabs are disabled 15597 if ( this.tabs.length === options.disabled.length ) { 15598 options.active = false; 15599 this.active = $(); 15600 // activate previous tab 15601 } else { 15602 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15603 } 15604 // was active, active tab still exists 15605 } else { 15606 // make sure active index is correct 15607 options.active = this.tabs.index( this.active ); 15608 } 15609 15610 this._refresh(); 15611 }, 15612 15613 _refresh: function() { 15614 this._setupDisabled( this.options.disabled ); 15615 this._setupEvents( this.options.event ); 15616 this._setupHeightStyle( this.options.heightStyle ); 15617 15618 this.tabs.not( this.active ).attr({ 15619 "aria-selected": "false", 15620 "aria-expanded": "false", 15621 tabIndex: -1 15622 }); 15623 this.panels.not( this._getPanelForTab( this.active ) ) 15624 .hide() 15625 .attr({ 15626 "aria-hidden": "true" 15627 }); 15628 15629 // Make sure one tab is in the tab order 15630 if ( !this.active.length ) { 15631 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15632 } else { 15633 this.active 15634 .addClass( "ui-tabs-active ui-state-active" ) 15635 .attr({ 15636 "aria-selected": "true", 15637 "aria-expanded": "true", 15638 tabIndex: 0 15639 }); 15640 this._getPanelForTab( this.active ) 15641 .show() 15642 .attr({ 15643 "aria-hidden": "false" 15644 }); 15645 } 15646 }, 15647 15648 _processTabs: function() { 15649 var that = this, 15650 prevTabs = this.tabs, 15651 prevAnchors = this.anchors, 15652 prevPanels = this.panels; 15653 15654 this.tablist = this._getList() 15655 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 15656 .attr( "role", "tablist" ) 15657 15658 // Prevent users from focusing disabled tabs via click 15659 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { 15660 if ( $( this ).is( ".ui-state-disabled" ) ) { 15661 event.preventDefault(); 15662 } 15663 }) 15664 15665 // support: IE <9 15666 // Preventing the default action in mousedown doesn't prevent IE 15667 // from focusing the element, so if the anchor gets focused, blur. 15668 // We don't have to worry about focusing the previously focused 15669 // element since clicking on a non-focusable element should focus 15670 // the body anyway. 15671 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 15672 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 15673 this.blur(); 15674 } 15675 }); 15676 15677 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15678 .addClass( "ui-state-default ui-corner-top" ) 15679 .attr({ 15680 role: "tab", 15681 tabIndex: -1 15682 }); 15683 15684 this.anchors = this.tabs.map(function() { 15685 return $( "a", this )[ 0 ]; 15686 }) 15687 .addClass( "ui-tabs-anchor" ) 15688 .attr({ 15689 role: "presentation", 15690 tabIndex: -1 15691 }); 15692 15693 this.panels = $(); 15694 15695 this.anchors.each(function( i, anchor ) { 15696 var selector, panel, panelId, 15697 anchorId = $( anchor ).uniqueId().attr( "id" ), 15698 tab = $( anchor ).closest( "li" ), 15699 originalAriaControls = tab.attr( "aria-controls" ); 15700 15701 // inline tab 15702 if ( that._isLocal( anchor ) ) { 15703 selector = anchor.hash; 15704 panelId = selector.substring( 1 ); 15705 panel = that.element.find( that._sanitizeSelector( selector ) ); 15706 // remote tab 15707 } else { 15708 // If the tab doesn't already have aria-controls, 15709 // generate an id by using a throw-away element 15710 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15711 selector = "#" + panelId; 15712 panel = that.element.find( selector ); 15713 if ( !panel.length ) { 15714 panel = that._createPanel( panelId ); 15715 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15716 } 15717 panel.attr( "aria-live", "polite" ); 15718 } 15719 15720 if ( panel.length) { 15721 that.panels = that.panels.add( panel ); 15722 } 15723 if ( originalAriaControls ) { 15724 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15725 } 15726 tab.attr({ 15727 "aria-controls": panelId, 15728 "aria-labelledby": anchorId 15729 }); 15730 panel.attr( "aria-labelledby", anchorId ); 15731 }); 15732 15733 this.panels 15734 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15735 .attr( "role", "tabpanel" ); 15736 15737 // Avoid memory leaks (#10056) 15738 if ( prevTabs ) { 15739 this._off( prevTabs.not( this.tabs ) ); 15740 this._off( prevAnchors.not( this.anchors ) ); 15741 this._off( prevPanels.not( this.panels ) ); 15742 } 15743 }, 15744 15745 // allow overriding how to find the list for rare usage scenarios (#7715) 15746 _getList: function() { 15747 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 15748 }, 15749 15750 _createPanel: function( id ) { 15751 return $( "<div>" ) 15752 .attr( "id", id ) 15753 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15754 .data( "ui-tabs-destroy", true ); 15755 }, 15756 15757 _setupDisabled: function( disabled ) { 15758 if ( $.isArray( disabled ) ) { 15759 if ( !disabled.length ) { 15760 disabled = false;
vendor: 4,561 bytes, lines 15761-15928
15761 } else if ( disabled.length === this.anchors.length ) { 15762 disabled = true; 15763 } 15764 } 15765 15766 // disable tabs 15767 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 15768 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15769 $( li ) 15770 .addClass( "ui-state-disabled" ) 15771 .attr( "aria-disabled", "true" ); 15772 } else { 15773 $( li ) 15774 .removeClass( "ui-state-disabled" ) 15775 .removeAttr( "aria-disabled" ); 15776 } 15777 } 15778 15779 this.options.disabled = disabled; 15780 }, 15781 15782 _setupEvents: function( event ) { 15783 var events = {}; 15784 if ( event ) { 15785 $.each( event.split(" "), function( index, eventName ) { 15786 events[ eventName ] = "_eventHandler"; 15787 }); 15788 } 15789 15790 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15791 // Always prevent the default action, even when disabled 15792 this._on( true, this.anchors, { 15793 click: function( event ) { 15794 event.preventDefault(); 15795 } 15796 }); 15797 this._on( this.anchors, events ); 15798 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15799 this._on( this.panels, { keydown: "_panelKeydown" } ); 15800 15801 this._focusable( this.tabs ); 15802 this._hoverable( this.tabs ); 15803 }, 15804 15805 _setupHeightStyle: function( heightStyle ) { 15806 var maxHeight, 15807 parent = this.element.parent(); 15808 15809 if ( heightStyle === "fill" ) { 15810 maxHeight = parent.height(); 15811 maxHeight -= this.element.outerHeight() - this.element.height(); 15812 15813 this.element.siblings( ":visible" ).each(function() { 15814 var elem = $( this ), 15815 position = elem.css( "position" ); 15816 15817 if ( position === "absolute" || position === "fixed" ) { 15818 return; 15819 } 15820 maxHeight -= elem.outerHeight( true ); 15821 }); 15822 15823 this.element.children().not( this.panels ).each(function() { 15824 maxHeight -= $( this ).outerHeight( true ); 15825 }); 15826 15827 this.panels.each(function() { 15828 $( this ).height( Math.max( 0, maxHeight - 15829 $( this ).innerHeight() + $( this ).height() ) ); 15830 }) 15831 .css( "overflow", "auto" ); 15832 } else if ( heightStyle === "auto" ) { 15833 maxHeight = 0; 15834 this.panels.each(function() { 15835 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15836 }).height( maxHeight ); 15837 } 15838 }, 15839 15840 _eventHandler: function( event ) { 15841 var options = this.options, 15842 active = this.active, 15843 anchor = $( event.currentTarget ), 15844 tab = anchor.closest( "li" ), 15845 clickedIsActive = tab[ 0 ] === active[ 0 ], 15846 collapsing = clickedIsActive && options.collapsible, 15847 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15848 toHide = !active.length ? $() : this._getPanelForTab( active ), 15849 eventData = { 15850 oldTab: active, 15851 oldPanel: toHide, 15852 newTab: collapsing ? $() : tab, 15853 newPanel: toShow 15854 }; 15855 15856 event.preventDefault(); 15857 15858 if ( tab.hasClass( "ui-state-disabled" ) || 15859 // tab is already loading 15860 tab.hasClass( "ui-tabs-loading" ) || 15861 // can't switch durning an animation 15862 this.running || 15863 // click on active header, but not collapsible 15864 ( clickedIsActive && !options.collapsible ) || 15865 // allow canceling activation 15866 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15867 return; 15868 } 15869 15870 options.active = collapsing ? false : this.tabs.index( tab ); 15871 15872 this.active = clickedIsActive ? $() : tab; 15873 if ( this.xhr ) { 15874 this.xhr.abort(); 15875 } 15876 15877 if ( !toHide.length && !toShow.length ) { 15878 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 15879 } 15880 15881 if ( toShow.length ) { 15882 this.load( this.tabs.index( tab ), event ); 15883 } 15884 this._toggle( event, eventData ); 15885 }, 15886 15887 // handles show/hide for selecting tabs 15888 _toggle: function( event, eventData ) { 15889 var that = this, 15890 toShow = eventData.newPanel, 15891 toHide = eventData.oldPanel; 15892 15893 this.running = true; 15894 15895 function complete() { 15896 that.running = false; 15897 that._trigger( "activate", event, eventData ); 15898 } 15899 15900 function show() { 15901 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 15902 15903 if ( toShow.length && that.options.show ) { 15904 that._show( toShow, that.options.show, complete ); 15905 } else { 15906 toShow.show(); 15907 complete(); 15908 } 15909 } 15910 15911 // start out by hiding, then showing, then completing 15912 if ( toHide.length && this.options.hide ) { 15913 this._hide( toHide, this.options.hide, function() { 15914 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 15915 show(); 15916 }); 15917 } else { 15918 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 15919 toHide.hide(); 15920 show(); 15921 } 15922 15923 toHide.attr( "aria-hidden", "true" ); 15924 eventData.oldTab.attr({ 15925 "aria-selected": "false", 15926 "aria-expanded": "false" 15927 }); 15928 // If we're switching tabs, remove the old tab from the tab order.
vendor: 18,503 bytes, lines 15929-16619
15929 // If we're opening from collapsed state, remove the previous tab from the tab order. 15930 // If we're collapsing, then keep the collapsing tab in the tab order. 15931 if ( toShow.length && toHide.length ) { 15932 eventData.oldTab.attr( "tabIndex", -1 ); 15933 } else if ( toShow.length ) { 15934 this.tabs.filter(function() { 15935 return $( this ).attr( "tabIndex" ) === 0; 15936 }) 15937 .attr( "tabIndex", -1 ); 15938 } 15939 15940 toShow.attr( "aria-hidden", "false" ); 15941 eventData.newTab.attr({ 15942 "aria-selected": "true", 15943 "aria-expanded": "true", 15944 tabIndex: 0 15945 }); 15946 }, 15947 15948 _activate: function( index ) { 15949 var anchor, 15950 active = this._findActive( index ); 15951 15952 // trying to activate the already active panel 15953 if ( active[ 0 ] === this.active[ 0 ] ) { 15954 return; 15955 } 15956 15957 // trying to collapse, simulate a click on the current active header 15958 if ( !active.length ) { 15959 active = this.active; 15960 } 15961 15962 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 15963 this._eventHandler({ 15964 target: anchor, 15965 currentTarget: anchor, 15966 preventDefault: $.noop 15967 }); 15968 }, 15969 15970 _findActive: function( index ) { 15971 return index === false ? $() : this.tabs.eq( index ); 15972 }, 15973 15974 _getIndex: function( index ) { 15975 // meta-function to give users option to provide a href string instead of a numerical index. 15976 if ( typeof index === "string" ) { 15977 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 15978 } 15979 15980 return index; 15981 }, 15982 15983 _destroy: function() { 15984 if ( this.xhr ) { 15985 this.xhr.abort(); 15986 } 15987 15988 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 15989 15990 this.tablist 15991 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 15992 .removeAttr( "role" ); 15993 15994 this.anchors 15995 .removeClass( "ui-tabs-anchor" ) 15996 .removeAttr( "role" ) 15997 .removeAttr( "tabIndex" ) 15998 .removeUniqueId(); 15999 16000 this.tablist.unbind( this.eventNamespace ); 16001 16002 this.tabs.add( this.panels ).each(function() { 16003 if ( $.data( this, "ui-tabs-destroy" ) ) { 16004 $( this ).remove(); 16005 } else { 16006 $( this ) 16007 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 16008 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 16009 .removeAttr( "tabIndex" ) 16010 .removeAttr( "aria-live" ) 16011 .removeAttr( "aria-busy" ) 16012 .removeAttr( "aria-selected" ) 16013 .removeAttr( "aria-labelledby" ) 16014 .removeAttr( "aria-hidden" ) 16015 .removeAttr( "aria-expanded" ) 16016 .removeAttr( "role" ); 16017 } 16018 }); 16019 16020 this.tabs.each(function() { 16021 var li = $( this ), 16022 prev = li.data( "ui-tabs-aria-controls" ); 16023 if ( prev ) { 16024 li 16025 .attr( "aria-controls", prev ) 16026 .removeData( "ui-tabs-aria-controls" ); 16027 } else { 16028 li.removeAttr( "aria-controls" ); 16029 } 16030 }); 16031 16032 this.panels.show(); 16033 16034 if ( this.options.heightStyle !== "content" ) { 16035 this.panels.css( "height", "" ); 16036 } 16037 }, 16038 16039 enable: function( index ) { 16040 var disabled = this.options.disabled; 16041 if ( disabled === false ) { 16042 return; 16043 } 16044 16045 if ( index === undefined ) { 16046 disabled = false; 16047 } else { 16048 index = this._getIndex( index ); 16049 if ( $.isArray( disabled ) ) { 16050 disabled = $.map( disabled, function( num ) { 16051 return num !== index ? num : null; 16052 }); 16053 } else { 16054 disabled = $.map( this.tabs, function( li, num ) { 16055 return num !== index ? num : null; 16056 }); 16057 } 16058 } 16059 this._setupDisabled( disabled ); 16060 }, 16061 16062 disable: function( index ) { 16063 var disabled = this.options.disabled; 16064 if ( disabled === true ) { 16065 return; 16066 } 16067 16068 if ( index === undefined ) { 16069 disabled = true; 16070 } else { 16071 index = this._getIndex( index ); 16072 if ( $.inArray( index, disabled ) !== -1 ) { 16073 return; 16074 } 16075 if ( $.isArray( disabled ) ) { 16076 disabled = $.merge( [ index ], disabled ).sort(); 16077 } else { 16078 disabled = [ index ]; 16079 } 16080 } 16081 this._setupDisabled( disabled ); 16082 }, 16083 16084 load: function( index, event ) { 16085 index = this._getIndex( index ); 16086 var that = this, 16087 tab = this.tabs.eq( index ), 16088 anchor = tab.find( ".ui-tabs-anchor" ), 16089 panel = this._getPanelForTab( tab ), 16090 eventData = { 16091 tab: tab, 16092 panel: panel 16093 }, 16094 complete = function( jqXHR, status ) { 16095 if ( status === "abort" ) { 16096 that.panels.stop( false, true ); 16097 } 16098 16099 tab.removeClass( "ui-tabs-loading" ); 16100 panel.removeAttr( "aria-busy" ); 16101 16102 if ( jqXHR === that.xhr ) { 16103 delete that.xhr; 16104 } 16105 }; 16106 16107 // not remote 16108 if ( this._isLocal( anchor[ 0 ] ) ) { 16109 return; 16110 } 16111 16112 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 16113 16114 // support: jQuery <1.8 16115 // jQuery <1.8 returns false if the request is canceled in beforeSend, 16116 // but as of 1.8, $.ajax() always returns a jqXHR object. 16117 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 16118 tab.addClass( "ui-tabs-loading" ); 16119 panel.attr( "aria-busy", "true" ); 16120 16121 this.xhr 16122 .done(function( response, status, jqXHR ) { 16123 // support: jQuery <1.8 16124 // http://bugs.jquery.com/ticket/11778 16125 setTimeout(function() { 16126 panel.html( response ); 16127 that._trigger( "load", event, eventData ); 16128 16129 complete( jqXHR, status ); 16130 }, 1 ); 16131 }) 16132 .fail(function( jqXHR, status ) { 16133 // support: jQuery <1.8 16134 // http://bugs.jquery.com/ticket/11778 16135 setTimeout(function() { 16136 complete( jqXHR, status ); 16137 }, 1 ); 16138 }); 16139 } 16140 }, 16141 16142 _ajaxSettings: function( anchor, event, eventData ) { 16143 var that = this; 16144 return { 16145 url: anchor.attr( "href" ), 16146 beforeSend: function( jqXHR, settings ) { 16147 return that._trigger( "beforeLoad", event, 16148 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 16149 } 16150 }; 16151 }, 16152 16153 _getPanelForTab: function( tab ) { 16154 var id = $( tab ).attr( "aria-controls" ); 16155 return this.element.find( this._sanitizeSelector( "#" + id ) ); 16156 } 16157}); 16158 16159 16160/*! 16161 * jQuery UI Tooltip 1.11.4 16162 * http://jqueryui.com 16163 * 16164 * Copyright jQuery Foundation and other contributors 16165 * Released under the MIT license. 16166 * http://jquery.org/license 16167 * 16168 * http://api.jqueryui.com/tooltip/ 16169 */ 16170 16171 16172var tooltip = $.widget( "ui.tooltip", { 16173 version: "1.11.4", 16174 options: { 16175 content: function() { 16176 // support: IE<9, Opera in jQuery <1.7 16177 // .text() can't accept undefined, so coerce to a string 16178 var title = $( this ).attr( "title" ) || ""; 16179 // Escape title, since we're going from an attribute to raw HTML 16180 return $( "<a>" ).text( title ).html(); 16181 }, 16182 hide: true, 16183 // Disabled elements have inconsistent behavior across browsers (#8661) 16184 items: "[title]:not([disabled])", 16185 position: { 16186 my: "left top+15", 16187 at: "left bottom", 16188 collision: "flipfit flip" 16189 }, 16190 show: true, 16191 tooltipClass: null, 16192 track: false, 16193 16194 // callbacks 16195 close: null, 16196 open: null 16197 }, 16198 16199 _addDescribedBy: function( elem, id ) { 16200 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 16201 describedby.push( id ); 16202 elem 16203 .data( "ui-tooltip-id", id ) 16204 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 16205 }, 16206 16207 _removeDescribedBy: function( elem ) { 16208 var id = elem.data( "ui-tooltip-id" ), 16209 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 16210 index = $.inArray( id, describedby ); 16211 16212 if ( index !== -1 ) { 16213 describedby.splice( index, 1 ); 16214 } 16215 16216 elem.removeData( "ui-tooltip-id" ); 16217 describedby = $.trim( describedby.join( " " ) ); 16218 if ( describedby ) { 16219 elem.attr( "aria-describedby", describedby ); 16220 } else { 16221 elem.removeAttr( "aria-describedby" ); 16222 } 16223 }, 16224 16225 _create: function() { 16226 this._on({ 16227 mouseover: "open", 16228 focusin: "open" 16229 }); 16230 16231 // IDs of generated tooltips, needed for destroy 16232 this.tooltips = {}; 16233 16234 // IDs of parent tooltips where we removed the title attribute 16235 this.parents = {}; 16236 16237 if ( this.options.disabled ) { 16238 this._disable(); 16239 } 16240 16241 // Append the aria-live region so tooltips announce correctly 16242 this.liveRegion = $( "<div>" ) 16243 .attr({ 16244 role: "log", 16245 "aria-live": "assertive", 16246 "aria-relevant": "additions" 16247 }) 16248 .addClass( "ui-helper-hidden-accessible" ) 16249 .appendTo( this.document[ 0 ].body ); 16250 }, 16251 16252 _setOption: function( key, value ) { 16253 var that = this; 16254 16255 if ( key === "disabled" ) { 16256 this[ value ? "_disable" : "_enable" ](); 16257 this.options[ key ] = value; 16258 // disable element style changes 16259 return; 16260 } 16261 16262 this._super( key, value ); 16263 16264 if ( key === "content" ) { 16265 $.each( this.tooltips, function( id, tooltipData ) { 16266 that._updateContent( tooltipData.element ); 16267 }); 16268 } 16269 }, 16270 16271 _disable: function() { 16272 var that = this; 16273 16274 // close open tooltips 16275 $.each( this.tooltips, function( id, tooltipData ) { 16276 var event = $.Event( "blur" ); 16277 event.target = event.currentTarget = tooltipData.element[ 0 ]; 16278 that.close( event, true ); 16279 }); 16280 16281 // remove title attributes to prevent native tooltips 16282 this.element.find( this.options.items ).addBack().each(function() { 16283 var element = $( this ); 16284 if ( element.is( "[title]" ) ) { 16285 element 16286 .data( "ui-tooltip-title", element.attr( "title" ) ) 16287 .removeAttr( "title" ); 16288 } 16289 }); 16290 }, 16291 16292 _enable: function() { 16293 // restore title attributes 16294 this.element.find( this.options.items ).addBack().each(function() { 16295 var element = $( this ); 16296 if ( element.data( "ui-tooltip-title" ) ) { 16297 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16298 } 16299 }); 16300 }, 16301 16302 open: function( event ) { 16303 var that = this, 16304 target = $( event ? event.target : this.element ) 16305 // we need closest here due to mouseover bubbling, 16306 // but always pointing at the same event target 16307 .closest( this.options.items ); 16308 16309 // No element to show a tooltip for or the tooltip is already open 16310 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 16311 return; 16312 } 16313 16314 if ( target.attr( "title" ) ) { 16315 target.data( "ui-tooltip-title", target.attr( "title" ) ); 16316 } 16317 16318 target.data( "ui-tooltip-open", true ); 16319 16320 // kill parent tooltips, custom or native, for hover 16321 if ( event && event.type === "mouseover" ) { 16322 target.parents().each(function() { 16323 var parent = $( this ), 16324 blurEvent; 16325 if ( parent.data( "ui-tooltip-open" ) ) { 16326 blurEvent = $.Event( "blur" ); 16327 blurEvent.target = blurEvent.currentTarget = this; 16328 that.close( blurEvent, true ); 16329 } 16330 if ( parent.attr( "title" ) ) { 16331 parent.uniqueId(); 16332 that.parents[ this.id ] = { 16333 element: this, 16334 title: parent.attr( "title" ) 16335 }; 16336 parent.attr( "title", "" ); 16337 } 16338 }); 16339 } 16340 16341 this._registerCloseHandlers( event, target ); 16342 this._updateContent( target, event ); 16343 }, 16344 16345 _updateContent: function( target, event ) { 16346 var content, 16347 contentOption = this.options.content, 16348 that = this, 16349 eventType = event ? event.type : null; 16350 16351 if ( typeof contentOption === "string" ) { 16352 return this._open( event, target, contentOption ); 16353 } 16354 16355 content = contentOption.call( target[0], function( response ) { 16356 16357 // IE may instantly serve a cached response for ajax requests 16358 // delay this call to _open so the other call to _open runs first 16359 that._delay(function() { 16360 16361 // Ignore async response if tooltip was closed already 16362 if ( !target.data( "ui-tooltip-open" ) ) { 16363 return; 16364 } 16365 16366 // jQuery creates a special event for focusin when it doesn't 16367 // exist natively. To improve performance, the native event 16368 // object is reused and the type is changed. Therefore, we can't 16369 // rely on the type being correct after the event finished 16370 // bubbling, so we set it back to the previous value. (#8740) 16371 if ( event ) { 16372 event.type = eventType; 16373 } 16374 this._open( event, target, response ); 16375 }); 16376 }); 16377 if ( content ) { 16378 this._open( event, target, content ); 16379 } 16380 }, 16381 16382 _open: function( event, target, content ) { 16383 var tooltipData, tooltip, delayedShow, a11yContent, 16384 positionOption = $.extend( {}, this.options.position ); 16385 16386 if ( !content ) { 16387 return; 16388 } 16389 16390 // Content can be updated multiple times. If the tooltip already 16391 // exists, then just update the content and bail. 16392 tooltipData = this._find( target ); 16393 if ( tooltipData ) { 16394 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 16395 return; 16396 } 16397 16398 // if we have a title, clear it to prevent the native tooltip 16399 // we have to check first to avoid defining a title if none exists 16400 // (we don't want to cause an element to start matching [title]) 16401 // 16402 // We use removeAttr only for key events, to allow IE to export the correct 16403 // accessible attributes. For mouse events, set to empty string to avoid 16404 // native tooltip showing up (happens only when removing inside mouseover). 16405 if ( target.is( "[title]" ) ) { 16406 if ( event && event.type === "mouseover" ) { 16407 target.attr( "title", "" ); 16408 } else { 16409 target.removeAttr( "title" ); 16410 } 16411 } 16412 16413 tooltipData = this._tooltip( target ); 16414 tooltip = tooltipData.tooltip; 16415 this._addDescribedBy( target, tooltip.attr( "id" ) ); 16416 tooltip.find( ".ui-tooltip-content" ).html( content ); 16417 16418 // Support: Voiceover on OS X, JAWS on IE <= 9 16419 // JAWS announces deletions even when aria-relevant="additions" 16420 // Voiceover will sometimes re-read the entire log region's contents from the beginning 16421 this.liveRegion.children().hide(); 16422 if ( content.clone ) { 16423 a11yContent = content.clone(); 16424 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 16425 } else { 16426 a11yContent = content; 16427 } 16428 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion ); 16429 16430 function position( event ) { 16431 positionOption.of = event; 16432 if ( tooltip.is( ":hidden" ) ) { 16433 return; 16434 } 16435 tooltip.position( positionOption ); 16436 } 16437 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 16438 this._on( this.document, { 16439 mousemove: position 16440 }); 16441 // trigger once to override element-relative positioning 16442 position( event ); 16443 } else { 16444 tooltip.position( $.extend({ 16445 of: target 16446 }, this.options.position ) ); 16447 } 16448 16449 tooltip.hide(); 16450 16451 this._show( tooltip, this.options.show ); 16452 // Handle tracking tooltips that are shown with a delay (#8644). As soon 16453 // as the tooltip is visible, position the tooltip using the most recent 16454 // event. 16455 if ( this.options.show && this.options.show.delay ) { 16456 delayedShow = this.delayedShow = setInterval(function() { 16457 if ( tooltip.is( ":visible" ) ) { 16458 position( positionOption.of ); 16459 clearInterval( delayedShow ); 16460 } 16461 }, $.fx.interval ); 16462 } 16463 16464 this._trigger( "open", event, { tooltip: tooltip } ); 16465 }, 16466 16467 _registerCloseHandlers: function( event, target ) { 16468 var events = { 16469 keyup: function( event ) { 16470 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 16471 var fakeEvent = $.Event(event); 16472 fakeEvent.currentTarget = target[0]; 16473 this.close( fakeEvent, true ); 16474 } 16475 } 16476 }; 16477 16478 // Only bind remove handler for delegated targets. Non-delegated 16479 // tooltips will handle this in destroy. 16480 if ( target[ 0 ] !== this.element[ 0 ] ) { 16481 events.remove = function() { 16482 this._removeTooltip( this._find( target ).tooltip ); 16483 }; 16484 } 16485 16486 if ( !event || event.type === "mouseover" ) { 16487 events.mouseleave = "close"; 16488 } 16489 if ( !event || event.type === "focusin" ) { 16490 events.focusout = "close"; 16491 } 16492 this._on( true, target, events ); 16493 }, 16494 16495 close: function( event ) { 16496 var tooltip, 16497 that = this, 16498 target = $( event ? event.currentTarget : this.element ), 16499 tooltipData = this._find( target ); 16500 16501 // The tooltip may already be closed 16502 if ( !tooltipData ) { 16503 16504 // We set ui-tooltip-open immediately upon open (in open()), but only set the 16505 // additional data once there's actually content to show (in _open()). So even if the 16506 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 16507 // the period between open() and _open(). 16508 target.removeData( "ui-tooltip-open" ); 16509 return; 16510 } 16511 16512 tooltip = tooltipData.tooltip; 16513 16514 // disabling closes the tooltip, so we need to track when we're closing 16515 // to avoid an infinite loop in case the tooltip becomes disabled on close 16516 if ( tooltipData.closing ) { 16517 return; 16518 } 16519 16520 // Clear the interval for delayed tracking tooltips 16521 clearInterval( this.delayedShow ); 16522 16523 // only set title if we had one before (see comment in _open()) 16524 // If the title attribute has changed since open(), don't restore 16525 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16526 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16527 } 16528 16529 this._removeDescribedBy( target ); 16530 16531 tooltipData.hiding = true; 16532 tooltip.stop( true ); 16533 this._hide( tooltip, this.options.hide, function() { 16534 that._removeTooltip( $( this ) ); 16535 }); 16536 16537 target.removeData( "ui-tooltip-open" ); 16538 this._off( target, "mouseleave focusout keyup" ); 16539 16540 // Remove 'remove' binding only on delegated targets 16541 if ( target[ 0 ] !== this.element[ 0 ] ) { 16542 this._off( target, "remove" ); 16543 } 16544 this._off( this.document, "mousemove" ); 16545 16546 if ( event && event.type === "mouseleave" ) { 16547 $.each( this.parents, function( id, parent ) { 16548 $( parent.element ).attr( "title", parent.title ); 16549 delete that.parents[ id ]; 16550 }); 16551 } 16552 16553 tooltipData.closing = true; 16554 this._trigger( "close", event, { tooltip: tooltip } ); 16555 if ( !tooltipData.hiding ) { 16556 tooltipData.closing = false; 16557 } 16558 }, 16559 16560 _tooltip: function( element ) { 16561 var tooltip = $( "<div>" ) 16562 .attr( "role", "tooltip" ) 16563 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 16564 ( this.options.tooltipClass || "" ) ), 16565 id = tooltip.uniqueId().attr( "id" ); 16566 16567 $( "<div>" ) 16568 .addClass( "ui-tooltip-content" ) 16569 .appendTo( tooltip ); 16570 16571 tooltip.appendTo( this.document[0].body ); 16572 16573 return this.tooltips[ id ] = { 16574 element: element, 16575 tooltip: tooltip 16576 }; 16577 }, 16578 16579 _find: function( target ) { 16580 var id = target.data( "ui-tooltip-id" ); 16581 return id ? this.tooltips[ id ] : null; 16582 }, 16583 16584 _removeTooltip: function( tooltip ) { 16585 tooltip.remove(); 16586 delete this.tooltips[ tooltip.attr( "id" ) ]; 16587 }, 16588 16589 _destroy: function() { 16590 var that = this; 16591 16592 // close open tooltips 16593 $.each( this.tooltips, function( id, tooltipData ) { 16594 // Delegate to close method to handle common cleanup 16595 var event = $.Event( "blur" ), 16596 element = tooltipData.element; 16597 event.target = event.currentTarget = element[ 0 ]; 16598 that.close( event, true ); 16599 16600 // Remove immediately; destroying an open tooltip doesn't use the 16601 // hide animation 16602 $( "#" + id ).remove(); 16603 16604 // Restore the title 16605 if ( element.data( "ui-tooltip-title" ) ) { 16606 // If the title attribute has changed since open(), don't restore 16607 if ( !element.attr( "title" ) ) { 16608 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16609 } 16610 element.removeData( "ui-tooltip-title" ); 16611 } 16612 }); 16613 this.liveRegion.remove(); 16614 } 16615}); 16616 16617 16618 16619}));
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.