vendor: 56,298 bytes, lines 1-1906
1/*! jQuery UI - v1.11.2 - 2014-11-05 2* http://jqueryui.com 3* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.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 4* Copyright 2014 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.2 19 * http://jqueryui.com 20 * 21 * Copyright 2014 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.2", 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.2 313 * http://jqueryui.com 314 * 315 * Copyright 2014 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 // allow multiple hashes to be passed on init 494 options = !isMethodCall && args.length ? 495 $.widget.extend.apply( null, [ options ].concat(args) ) : 496 options; 497 498 if ( isMethodCall ) { 499 this.each(function() { 500 var methodValue, 501 instance = $.data( this, fullName ); 502 if ( options === "instance" ) { 503 returnValue = instance; 504 return false; 505 } 506 if ( !instance ) { 507 return $.error( "cannot call methods on " + name + " prior to initialization; " + 508 "attempted to call method '" + options + "'" ); 509 } 510 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 511 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 512 } 513 methodValue = instance[ options ].apply( instance, args ); 514 if ( methodValue !== instance && methodValue !== undefined ) { 515 returnValue = methodValue && methodValue.jquery ? 516 returnValue.pushStack( methodValue.get() ) : 517 methodValue; 518 return false; 519 } 520 }); 521 } else { 522 this.each(function() { 523 var instance = $.data( this, fullName ); 524 if ( instance ) { 525 instance.option( options || {} ); 526 if ( instance._init ) { 527 instance._init(); 528 } 529 } else { 530 $.data( this, fullName, new object( options, this ) ); 531 } 532 }); 533 } 534 535 return returnValue; 536 }; 537}; 538 539$.Widget = function( /* options, element */ ) {}; 540$.Widget._childConstructors = []; 541 542$.Widget.prototype = { 543 widgetName: "widget", 544 widgetEventPrefix: "", 545 defaultElement: "<div>", 546 options: { 547 disabled: false, 548 549 // callbacks 550 create: null 551 }, 552 _createWidget: function( options, element ) { 553 element = $( element || this.defaultElement || this )[ 0 ]; 554 this.element = $( element ); 555 this.uuid = widget_uuid++; 556 this.eventNamespace = "." + this.widgetName + this.uuid; 557 558 this.bindings = $(); 559 this.hoverable = $(); 560 this.focusable = $(); 561 562 if ( element !== this ) { 563 $.data( element, this.widgetFullName, this ); 564 this._on( true, this.element, { 565 remove: function( event ) { 566 if ( event.target === element ) { 567 this.destroy(); 568 } 569 } 570 }); 571 this.document = $( element.style ? 572 // element within the document 573 element.ownerDocument : 574 // element is window or document 575 element.document || element ); 576 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 577 } 578 579 this.options = $.widget.extend( {}, 580 this.options, 581 this._getCreateOptions(), 582 options ); 583 584 this._create(); 585 this._trigger( "create", null, this._getCreateEventData() ); 586 this._init(); 587 }, 588 _getCreateOptions: $.noop, 589 _getCreateEventData: $.noop, 590 _create: $.noop, 591 _init: $.noop, 592 593 destroy: function() { 594 this._destroy(); 595 // we can probably remove the unbind calls in 2.0 596 // all event bindings should go through this._on() 597 this.element 598 .unbind( this.eventNamespace ) 599 .removeData( this.widgetFullName ) 600 // support: jquery <1.6.3 601 // http://bugs.jquery.com/ticket/9413 602 .removeData( $.camelCase( this.widgetFullName ) ); 603 this.widget() 604 .unbind( this.eventNamespace ) 605 .removeAttr( "aria-disabled" ) 606 .removeClass( 607 this.widgetFullName + "-disabled " + 608 "ui-state-disabled" ); 609 610 // clean up events and states 611 this.bindings.unbind( this.eventNamespace ); 612 this.hoverable.removeClass( "ui-state-hover" ); 613 this.focusable.removeClass( "ui-state-focus" ); 614 }, 615 _destroy: $.noop, 616 617 widget: function() { 618 return this.element; 619 }, 620 621 option: function( key, value ) { 622 var options = key, 623 parts, 624 curOption, 625 i; 626 627 if ( arguments.length === 0 ) { 628 // don't return a reference to the internal hash 629 return $.widget.extend( {}, this.options ); 630 } 631 632 if ( typeof key === "string" ) { 633 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 634 options = {}; 635 parts = key.split( "." ); 636 key = parts.shift(); 637 if ( parts.length ) { 638 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 639 for ( i = 0; i < parts.length - 1; i++ ) { 640 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 641 curOption = curOption[ parts[ i ] ]; 642 } 643 key = parts.pop(); 644 if ( arguments.length === 1 ) { 645 return curOption[ key ] === undefined ? null : curOption[ key ]; 646 } 647 curOption[ key ] = value; 648 } else { 649 if ( arguments.length === 1 ) { 650 return this.options[ key ] === undefined ? null : this.options[ key ]; 651 } 652 options[ key ] = value; 653 } 654 } 655 656 this._setOptions( options ); 657 658 return this; 659 }, 660 _setOptions: function( options ) { 661 var key; 662 663 for ( key in options ) { 664 this._setOption( key, options[ key ] ); 665 } 666 667 return this; 668 }, 669 _setOption: function( key, value ) { 670 this.options[ key ] = value; 671 672 if ( key === "disabled" ) { 673 this.widget() 674 .toggleClass( this.widgetFullName + "-disabled", !!value ); 675 676 // If the widget is becoming disabled, then nothing is interactive 677 if ( value ) { 678 this.hoverable.removeClass( "ui-state-hover" ); 679 this.focusable.removeClass( "ui-state-focus" ); 680 } 681 } 682 683 return this; 684 }, 685 686 enable: function() { 687 return this._setOptions({ disabled: false }); 688 }, 689 disable: function() { 690 return this._setOptions({ disabled: true }); 691 }, 692 693 _on: function( suppressDisabledCheck, element, handlers ) { 694 var delegateElement, 695 instance = this; 696 697 // no suppressDisabledCheck flag, shuffle arguments 698 if ( typeof suppressDisabledCheck !== "boolean" ) { 699 handlers = element; 700 element = suppressDisabledCheck; 701 suppressDisabledCheck = false; 702 } 703 704 // no element argument, shuffle and use this.element 705 if ( !handlers ) { 706 handlers = element; 707 element = this.element; 708 delegateElement = this.widget(); 709 } else { 710 element = delegateElement = $( element ); 711 this.bindings = this.bindings.add( element ); 712 } 713 714 $.each( handlers, function( event, handler ) { 715 function handlerProxy() { 716 // allow widgets to customize the disabled handling 717 // - disabled as an array instead of boolean 718 // - disabled class as method for disabling individual parts 719 if ( !suppressDisabledCheck && 720 ( instance.options.disabled === true || 721 $( this ).hasClass( "ui-state-disabled" ) ) ) { 722 return; 723 } 724 return ( typeof handler === "string" ? instance[ handler ] : handler ) 725 .apply( instance, arguments ); 726 } 727 728 // copy the guid so direct unbinding works 729 if ( typeof handler !== "string" ) { 730 handlerProxy.guid = handler.guid = 731 handler.guid || handlerProxy.guid || $.guid++; 732 } 733 734 var match = event.match( /^([\w:-]*)\s*(.*)$/ ), 735 eventName = match[1] + instance.eventNamespace, 736 selector = match[2]; 737 if ( selector ) { 738 delegateElement.delegate( selector, eventName, handlerProxy ); 739 } else { 740 element.bind( eventName, handlerProxy ); 741 } 742 }); 743 }, 744 745 _off: function( element, eventName ) { 746 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + 747 this.eventNamespace; 748 element.unbind( eventName ).undelegate( eventName ); 749 750 // Clear the stack to avoid memory leaks (#10056) 751 this.bindings = $( this.bindings.not( element ).get() ); 752 this.focusable = $( this.focusable.not( element ).get() ); 753 this.hoverable = $( this.hoverable.not( element ).get() ); 754 }, 755 756 _delay: function( handler, delay ) { 757 function handlerProxy() { 758 return ( typeof handler === "string" ? instance[ handler ] : handler ) 759 .apply( instance, arguments ); 760 } 761 var instance = this; 762 return setTimeout( handlerProxy, delay || 0 ); 763 }, 764 765 _hoverable: function( element ) { 766 this.hoverable = this.hoverable.add( element ); 767 this._on( element, { 768 mouseenter: function( event ) { 769 $( event.currentTarget ).addClass( "ui-state-hover" ); 770 }, 771 mouseleave: function( event ) { 772 $( event.currentTarget ).removeClass( "ui-state-hover" ); 773 } 774 }); 775 }, 776 777 _focusable: function( element ) { 778 this.focusable = this.focusable.add( element ); 779 this._on( element, { 780 focusin: function( event ) { 781 $( event.currentTarget ).addClass( "ui-state-focus" ); 782 }, 783 focusout: function( event ) { 784 $( event.currentTarget ).removeClass( "ui-state-focus" ); 785 } 786 }); 787 }, 788 789 _trigger: function( type, event, data ) { 790 var prop, orig, 791 callback = this.options[ type ]; 792 793 data = data || {}; 794 event = $.Event( event ); 795 event.type = ( type === this.widgetEventPrefix ? 796 type : 797 this.widgetEventPrefix + type ).toLowerCase(); 798 // the original event may come from any element 799 // so we need to reset the target on the new event 800 event.target = this.element[ 0 ]; 801 802 // copy original event properties over to the new event 803 orig = event.originalEvent; 804 if ( orig ) { 805 for ( prop in orig ) { 806 if ( !( prop in event ) ) { 807 event[ prop ] = orig[ prop ]; 808 } 809 } 810 } 811 812 this.element.trigger( event, data ); 813 return !( $.isFunction( callback ) && 814 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 815 event.isDefaultPrevented() ); 816 } 817}; 818 819$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 820 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 821 if ( typeof options === "string" ) { 822 options = { effect: options }; 823 } 824 var hasOptions, 825 effectName = !options ? 826 method : 827 options === true || typeof options === "number" ? 828 defaultEffect : 829 options.effect || defaultEffect; 830 options = options || {}; 831 if ( typeof options === "number" ) { 832 options = { duration: options }; 833 } 834 hasOptions = !$.isEmptyObject( options ); 835 options.complete = callback; 836 if ( options.delay ) { 837 element.delay( options.delay ); 838 } 839 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 840 element[ method ]( options ); 841 } else if ( effectName !== method && element[ effectName ] ) { 842 element[ effectName ]( options.duration, options.easing, callback ); 843 } else { 844 element.queue(function( next ) { 845 $( this )[ method ](); 846 if ( callback ) { 847 callback.call( element[ 0 ] ); 848 } 849 next(); 850 }); 851 } 852 }; 853}); 854 855var widget = $.widget; 856 857 858/*! 859 * jQuery UI Mouse 1.11.2 860 * http://jqueryui.com 861 * 862 * Copyright 2014 jQuery Foundation and other contributors 863 * Released under the MIT license. 864 * http://jquery.org/license 865 * 866 * http://api.jqueryui.com/mouse/ 867 */ 868 869 870var mouseHandled = false; 871$( document ).mouseup( function() { 872 mouseHandled = false; 873}); 874 875var mouse = $.widget("ui.mouse", { 876 version: "1.11.2", 877 options: { 878 cancel: "input,textarea,button,select,option", 879 distance: 1, 880 delay: 0 881 }, 882 _mouseInit: function() { 883 var that = this; 884 885 this.element 886 .bind("mousedown." + this.widgetName, function(event) { 887 return that._mouseDown(event); 888 }) 889 .bind("click." + this.widgetName, function(event) { 890 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 891 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 892 event.stopImmediatePropagation(); 893 return false; 894 } 895 }); 896 897 this.started = false; 898 }, 899 900 // TODO: make sure destroying one instance of mouse doesn't mess with 901 // other instances of mouse 902 _mouseDestroy: function() { 903 this.element.unbind("." + this.widgetName); 904 if ( this._mouseMoveDelegate ) { 905 this.document 906 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) 907 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); 908 } 909 }, 910 911 _mouseDown: function(event) { 912 // don't let more than one widget handle mouseStart 913 if ( mouseHandled ) { 914 return; 915 } 916 917 this._mouseMoved = false; 918 919 // we may have missed mouseup (out of window) 920 (this._mouseStarted && this._mouseUp(event)); 921 922 this._mouseDownEvent = event; 923 924 var that = this, 925 btnIsLeft = (event.which === 1), 926 // event.target.nodeName works around a bug in IE 8 with 927 // disabled inputs (#7620) 928 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 929 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 930 return true; 931 } 932 933 this.mouseDelayMet = !this.options.delay; 934 if (!this.mouseDelayMet) { 935 this._mouseDelayTimer = setTimeout(function() { 936 that.mouseDelayMet = true; 937 }, this.options.delay); 938 } 939 940 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 941 this._mouseStarted = (this._mouseStart(event) !== false); 942 if (!this._mouseStarted) { 943 event.preventDefault(); 944 return true; 945 } 946 } 947 948 // Click event may never have fired (Gecko & Opera) 949 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 950 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 951 } 952 953 // these delegates are required to keep context 954 this._mouseMoveDelegate = function(event) { 955 return that._mouseMove(event); 956 }; 957 this._mouseUpDelegate = function(event) { 958 return that._mouseUp(event); 959 }; 960 961 this.document 962 .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 963 .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 964 965 event.preventDefault(); 966 967 mouseHandled = true; 968 return true; 969 }, 970 971 _mouseMove: function(event) { 972 // Only check for mouseups outside the document if you've moved inside the document 973 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 974 // fire a mousemove event if content is placed under the cursor. See #7778 975 // Support: IE <9 976 if ( this._mouseMoved ) { 977 // IE mouseup check - mouseup happened when mouse was out of window 978 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 979 return this._mouseUp(event); 980 981 // Iframe mouseup check - mouseup occurred in another document 982 } else if ( !event.which ) { 983 return this._mouseUp( event ); 984 } 985 } 986 987 if ( event.which || event.button ) { 988 this._mouseMoved = true; 989 } 990 991 if (this._mouseStarted) { 992 this._mouseDrag(event); 993 return event.preventDefault(); 994 } 995 996 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 997 this._mouseStarted = 998 (this._mouseStart(this._mouseDownEvent, event) !== false); 999 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 1000 } 1001 1002 return !this._mouseStarted; 1003 }, 1004 1005 _mouseUp: function(event) { 1006 this.document 1007 .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1008 .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1009 1010 if (this._mouseStarted) { 1011 this._mouseStarted = false; 1012 1013 if (event.target === this._mouseDownEvent.target) { 1014 $.data(event.target, this.widgetName + ".preventClickEvent", true); 1015 } 1016 1017 this._mouseStop(event); 1018 } 1019 1020 mouseHandled = false; 1021 return false; 1022 }, 1023 1024 _mouseDistanceMet: function(event) { 1025 return (Math.max( 1026 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1027 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1028 ) >= this.options.distance 1029 ); 1030 }, 1031 1032 _mouseDelayMet: function(/* event */) { 1033 return this.mouseDelayMet; 1034 }, 1035 1036 // These are placeholder methods, to be overriden by extending plugin 1037 _mouseStart: function(/* event */) {}, 1038 _mouseDrag: function(/* event */) {}, 1039 _mouseStop: function(/* event */) {}, 1040 _mouseCapture: function(/* event */) { return true; } 1041}); 1042 1043 1044/*! 1045 * jQuery UI Position 1.11.2 1046 * http://jqueryui.com 1047 * 1048 * Copyright 2014 jQuery Foundation and other contributors 1049 * Released under the MIT license. 1050 * http://jquery.org/license 1051 * 1052 * http://api.jqueryui.com/position/ 1053 */ 1054 1055(function() { 1056 1057$.ui = $.ui || {}; 1058 1059var cachedScrollbarWidth, supportsOffsetFractions, 1060 max = Math.max, 1061 abs = Math.abs, 1062 round = Math.round, 1063 rhorizontal = /left|center|right/, 1064 rvertical = /top|center|bottom/, 1065 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 1066 rposition = /^\w+/, 1067 rpercent = /%$/, 1068 _position = $.fn.position; 1069 1070function getOffsets( offsets, width, height ) { 1071 return [ 1072 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1073 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1074 ]; 1075} 1076 1077function parseCss( element, property ) { 1078 return parseInt( $.css( element, property ), 10 ) || 0; 1079} 1080 1081function getDimensions( elem ) { 1082 var raw = elem[0]; 1083 if ( raw.nodeType === 9 ) { 1084 return { 1085 width: elem.width(), 1086 height: elem.height(), 1087 offset: { top: 0, left: 0 } 1088 }; 1089 } 1090 if ( $.isWindow( raw ) ) { 1091 return { 1092 width: elem.width(), 1093 height: elem.height(), 1094 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1095 }; 1096 } 1097 if ( raw.preventDefault ) { 1098 return { 1099 width: 0, 1100 height: 0, 1101 offset: { top: raw.pageY, left: raw.pageX } 1102 }; 1103 } 1104 return { 1105 width: elem.outerWidth(), 1106 height: elem.outerHeight(), 1107 offset: elem.offset() 1108 }; 1109} 1110 1111$.position = { 1112 scrollbarWidth: function() { 1113 if ( cachedScrollbarWidth !== undefined ) { 1114 return cachedScrollbarWidth; 1115 } 1116 var w1, w2, 1117 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1118 innerDiv = div.children()[0]; 1119 1120 $( "body" ).append( div ); 1121 w1 = innerDiv.offsetWidth; 1122 div.css( "overflow", "scroll" ); 1123 1124 w2 = innerDiv.offsetWidth; 1125 1126 if ( w1 === w2 ) { 1127 w2 = div[0].clientWidth; 1128 } 1129 1130 div.remove(); 1131 1132 return (cachedScrollbarWidth = w1 - w2); 1133 }, 1134 getScrollInfo: function( within ) { 1135 var overflowX = within.isWindow || within.isDocument ? "" : 1136 within.element.css( "overflow-x" ), 1137 overflowY = within.isWindow || within.isDocument ? "" : 1138 within.element.css( "overflow-y" ), 1139 hasOverflowX = overflowX === "scroll" || 1140 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1141 hasOverflowY = overflowY === "scroll" || 1142 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1143 return { 1144 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1145 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1146 }; 1147 }, 1148 getWithinInfo: function( element ) { 1149 var withinElement = $( element || window ), 1150 isWindow = $.isWindow( withinElement[0] ), 1151 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1152 return { 1153 element: withinElement, 1154 isWindow: isWindow, 1155 isDocument: isDocument, 1156 offset: withinElement.offset() || { left: 0, top: 0 }, 1157 scrollLeft: withinElement.scrollLeft(), 1158 scrollTop: withinElement.scrollTop(), 1159 1160 // support: jQuery 1.6.x 1161 // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows 1162 width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), 1163 height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() 1164 }; 1165 } 1166}; 1167 1168$.fn.position = function( options ) { 1169 if ( !options || !options.of ) { 1170 return _position.apply( this, arguments ); 1171 } 1172 1173 // make a copy, we don't want to modify arguments 1174 options = $.extend( {}, options ); 1175 1176 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1177 target = $( options.of ), 1178 within = $.position.getWithinInfo( options.within ), 1179 scrollInfo = $.position.getScrollInfo( within ), 1180 collision = ( options.collision || "flip" ).split( " " ), 1181 offsets = {}; 1182 1183 dimensions = getDimensions( target ); 1184 if ( target[0].preventDefault ) { 1185 // force left top to allow flipping 1186 options.at = "left top"; 1187 } 1188 targetWidth = dimensions.width; 1189 targetHeight = dimensions.height; 1190 targetOffset = dimensions.offset; 1191 // clone to reuse original targetOffset later 1192 basePosition = $.extend( {}, targetOffset ); 1193 1194 // force my and at to have valid horizontal and vertical positions 1195 // if a value is missing or invalid, it will be converted to center 1196 $.each( [ "my", "at" ], function() { 1197 var pos = ( options[ this ] || "" ).split( " " ), 1198 horizontalOffset, 1199 verticalOffset; 1200 1201 if ( pos.length === 1) { 1202 pos = rhorizontal.test( pos[ 0 ] ) ? 1203 pos.concat( [ "center" ] ) : 1204 rvertical.test( pos[ 0 ] ) ? 1205 [ "center" ].concat( pos ) : 1206 [ "center", "center" ]; 1207 } 1208 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1209 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1210 1211 // calculate offsets 1212 horizontalOffset = roffset.exec( pos[ 0 ] ); 1213 verticalOffset = roffset.exec( pos[ 1 ] ); 1214 offsets[ this ] = [ 1215 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1216 verticalOffset ? verticalOffset[ 0 ] : 0 1217 ]; 1218 1219 // reduce to just the positions without the offsets 1220 options[ this ] = [ 1221 rposition.exec( pos[ 0 ] )[ 0 ], 1222 rposition.exec( pos[ 1 ] )[ 0 ] 1223 ]; 1224 }); 1225 1226 // normalize collision option 1227 if ( collision.length === 1 ) { 1228 collision[ 1 ] = collision[ 0 ]; 1229 } 1230 1231 if ( options.at[ 0 ] === "right" ) { 1232 basePosition.left += targetWidth; 1233 } else if ( options.at[ 0 ] === "center" ) { 1234 basePosition.left += targetWidth / 2; 1235 } 1236 1237 if ( options.at[ 1 ] === "bottom" ) { 1238 basePosition.top += targetHeight; 1239 } else if ( options.at[ 1 ] === "center" ) { 1240 basePosition.top += targetHeight / 2; 1241 } 1242 1243 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1244 basePosition.left += atOffset[ 0 ]; 1245 basePosition.top += atOffset[ 1 ]; 1246 1247 return this.each(function() { 1248 var collisionPosition, using, 1249 elem = $( this ), 1250 elemWidth = elem.outerWidth(), 1251 elemHeight = elem.outerHeight(), 1252 marginLeft = parseCss( this, "marginLeft" ), 1253 marginTop = parseCss( this, "marginTop" ), 1254 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1255 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1256 position = $.extend( {}, basePosition ), 1257 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1258 1259 if ( options.my[ 0 ] === "right" ) { 1260 position.left -= elemWidth; 1261 } else if ( options.my[ 0 ] === "center" ) { 1262 position.left -= elemWidth / 2; 1263 } 1264 1265 if ( options.my[ 1 ] === "bottom" ) { 1266 position.top -= elemHeight; 1267 } else if ( options.my[ 1 ] === "center" ) { 1268 position.top -= elemHeight / 2; 1269 } 1270 1271 position.left += myOffset[ 0 ]; 1272 position.top += myOffset[ 1 ]; 1273 1274 // if the browser doesn't support fractions, then round for consistent results 1275 if ( !supportsOffsetFractions ) { 1276 position.left = round( position.left ); 1277 position.top = round( position.top ); 1278 } 1279 1280 collisionPosition = { 1281 marginLeft: marginLeft, 1282 marginTop: marginTop 1283 }; 1284 1285 $.each( [ "left", "top" ], function( i, dir ) { 1286 if ( $.ui.position[ collision[ i ] ] ) { 1287 $.ui.position[ collision[ i ] ][ dir ]( position, { 1288 targetWidth: targetWidth, 1289 targetHeight: targetHeight, 1290 elemWidth: elemWidth, 1291 elemHeight: elemHeight, 1292 collisionPosition: collisionPosition, 1293 collisionWidth: collisionWidth, 1294 collisionHeight: collisionHeight, 1295 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1296 my: options.my, 1297 at: options.at, 1298 within: within, 1299 elem: elem 1300 }); 1301 } 1302 }); 1303 1304 if ( options.using ) { 1305 // adds feedback as second argument to using callback, if present 1306 using = function( props ) { 1307 var left = targetOffset.left - position.left, 1308 right = left + targetWidth - elemWidth, 1309 top = targetOffset.top - position.top, 1310 bottom = top + targetHeight - elemHeight, 1311 feedback = { 1312 target: { 1313 element: target, 1314 left: targetOffset.left, 1315 top: targetOffset.top, 1316 width: targetWidth, 1317 height: targetHeight 1318 }, 1319 element: { 1320 element: elem, 1321 left: position.left, 1322 top: position.top, 1323 width: elemWidth, 1324 height: elemHeight 1325 }, 1326 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1327 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1328 }; 1329 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1330 feedback.horizontal = "center"; 1331 } 1332 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1333 feedback.vertical = "middle"; 1334 } 1335 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1336 feedback.important = "horizontal"; 1337 } else { 1338 feedback.important = "vertical"; 1339 } 1340 options.using.call( this, props, feedback ); 1341 }; 1342 } 1343 1344 elem.offset( $.extend( position, { using: using } ) ); 1345 }); 1346}; 1347 1348$.ui.position = { 1349 fit: { 1350 left: function( position, data ) { 1351 var within = data.within, 1352 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1353 outerWidth = within.width, 1354 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1355 overLeft = withinOffset - collisionPosLeft, 1356 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1357 newOverRight; 1358 1359 // element is wider than within 1360 if ( data.collisionWidth > outerWidth ) { 1361 // element is initially over the left side of within 1362 if ( overLeft > 0 && overRight <= 0 ) { 1363 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1364 position.left += overLeft - newOverRight; 1365 // element is initially over right side of within 1366 } else if ( overRight > 0 && overLeft <= 0 ) { 1367 position.left = withinOffset; 1368 // element is initially over both left and right sides of within 1369 } else { 1370 if ( overLeft > overRight ) { 1371 position.left = withinOffset + outerWidth - data.collisionWidth; 1372 } else { 1373 position.left = withinOffset; 1374 } 1375 } 1376 // too far left -> align with left edge 1377 } else if ( overLeft > 0 ) { 1378 position.left += overLeft; 1379 // too far right -> align with right edge 1380 } else if ( overRight > 0 ) { 1381 position.left -= overRight; 1382 // adjust based on position and margin 1383 } else { 1384 position.left = max( position.left - collisionPosLeft, position.left ); 1385 } 1386 }, 1387 top: function( position, data ) { 1388 var within = data.within, 1389 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1390 outerHeight = data.within.height, 1391 collisionPosTop = position.top - data.collisionPosition.marginTop, 1392 overTop = withinOffset - collisionPosTop, 1393 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1394 newOverBottom; 1395 1396 // element is taller than within 1397 if ( data.collisionHeight > outerHeight ) { 1398 // element is initially over the top of within 1399 if ( overTop > 0 && overBottom <= 0 ) { 1400 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1401 position.top += overTop - newOverBottom; 1402 // element is initially over bottom of within 1403 } else if ( overBottom > 0 && overTop <= 0 ) { 1404 position.top = withinOffset; 1405 // element is initially over both top and bottom of within 1406 } else { 1407 if ( overTop > overBottom ) { 1408 position.top = withinOffset + outerHeight - data.collisionHeight; 1409 } else { 1410 position.top = withinOffset; 1411 } 1412 } 1413 // too far up -> align with top 1414 } else if ( overTop > 0 ) { 1415 position.top += overTop; 1416 // too far down -> align with bottom edge 1417 } else if ( overBottom > 0 ) { 1418 position.top -= overBottom; 1419 // adjust based on position and margin 1420 } else { 1421 position.top = max( position.top - collisionPosTop, position.top ); 1422 } 1423 } 1424 }, 1425 flip: { 1426 left: function( position, data ) { 1427 var within = data.within, 1428 withinOffset = within.offset.left + within.scrollLeft, 1429 outerWidth = within.width, 1430 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1431 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1432 overLeft = collisionPosLeft - offsetLeft, 1433 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1434 myOffset = data.my[ 0 ] === "left" ? 1435 -data.elemWidth : 1436 data.my[ 0 ] === "right" ? 1437 data.elemWidth : 1438 0, 1439 atOffset = data.at[ 0 ] === "left" ? 1440 data.targetWidth : 1441 data.at[ 0 ] === "right" ? 1442 -data.targetWidth : 1443 0, 1444 offset = -2 * data.offset[ 0 ], 1445 newOverRight, 1446 newOverLeft; 1447 1448 if ( overLeft < 0 ) { 1449 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1450 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1451 position.left += myOffset + atOffset + offset; 1452 } 1453 } else if ( overRight > 0 ) { 1454 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1455 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1456 position.left += myOffset + atOffset + offset; 1457 } 1458 } 1459 }, 1460 top: function( position, data ) { 1461 var within = data.within, 1462 withinOffset = within.offset.top + within.scrollTop, 1463 outerHeight = within.height, 1464 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1465 collisionPosTop = position.top - data.collisionPosition.marginTop, 1466 overTop = collisionPosTop - offsetTop, 1467 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1468 top = data.my[ 1 ] === "top", 1469 myOffset = top ? 1470 -data.elemHeight : 1471 data.my[ 1 ] === "bottom" ? 1472 data.elemHeight : 1473 0, 1474 atOffset = data.at[ 1 ] === "top" ? 1475 data.targetHeight : 1476 data.at[ 1 ] === "bottom" ? 1477 -data.targetHeight : 1478 0, 1479 offset = -2 * data.offset[ 1 ], 1480 newOverTop, 1481 newOverBottom; 1482 if ( overTop < 0 ) { 1483 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1484 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1485 position.top += myOffset + atOffset + offset; 1486 } 1487 } else if ( overBottom > 0 ) { 1488 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1489 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1490 position.top += myOffset + atOffset + offset; 1491 } 1492 } 1493 } 1494 }, 1495 flipfit: { 1496 left: function() { 1497 $.ui.position.flip.left.apply( this, arguments ); 1498 $.ui.position.fit.left.apply( this, arguments ); 1499 }, 1500 top: function() { 1501 $.ui.position.flip.top.apply( this, arguments ); 1502 $.ui.position.fit.top.apply( this, arguments ); 1503 } 1504 } 1505}; 1506 1507// fraction support test 1508(function() { 1509 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1510 body = document.getElementsByTagName( "body" )[ 0 ], 1511 div = document.createElement( "div" ); 1512 1513 //Create a "fake body" for testing based on method used in jQuery.support 1514 testElement = document.createElement( body ? "div" : "body" ); 1515 testElementStyle = { 1516 visibility: "hidden", 1517 width: 0, 1518 height: 0, 1519 border: 0, 1520 margin: 0, 1521 background: "none" 1522 }; 1523 if ( body ) { 1524 $.extend( testElementStyle, { 1525 position: "absolute", 1526 left: "-1000px", 1527 top: "-1000px" 1528 }); 1529 } 1530 for ( i in testElementStyle ) { 1531 testElement.style[ i ] = testElementStyle[ i ]; 1532 } 1533 testElement.appendChild( div ); 1534 testElementParent = body || document.documentElement; 1535 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1536 1537 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1538 1539 offsetLeft = $( div ).offset().left; 1540 supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; 1541 1542 testElement.innerHTML = ""; 1543 testElementParent.removeChild( testElement ); 1544})(); 1545 1546})(); 1547 1548var position = $.ui.position; 1549 1550 1551/*! 1552 * jQuery UI Draggable 1.11.2 1553 * http://jqueryui.com 1554 * 1555 * Copyright 2014 jQuery Foundation and other contributors 1556 * Released under the MIT license. 1557 * http://jquery.org/license 1558 * 1559 * http://api.jqueryui.com/draggable/ 1560 */ 1561 1562 1563$.widget("ui.draggable", $.ui.mouse, { 1564 version: "1.11.2", 1565 widgetEventPrefix: "drag", 1566 options: { 1567 addClasses: true, 1568 appendTo: "parent", 1569 axis: false, 1570 connectToSortable: false, 1571 containment: false, 1572 cursor: "auto", 1573 cursorAt: false, 1574 grid: false, 1575 handle: false, 1576 helper: "original", 1577 iframeFix: false, 1578 opacity: false, 1579 refreshPositions: false, 1580 revert: false, 1581 revertDuration: 500, 1582 scope: "default", 1583 scroll: true, 1584 scrollSensitivity: 20, 1585 scrollSpeed: 20, 1586 snap: false, 1587 snapMode: "both", 1588 snapTolerance: 20, 1589 stack: false, 1590 zIndex: false, 1591 1592 // callbacks 1593 drag: null, 1594 start: null, 1595 stop: null 1596 }, 1597 _create: function() { 1598 1599 if ( this.options.helper === "original" ) { 1600 this._setPositionRelative(); 1601 } 1602 if (this.options.addClasses){ 1603 this.element.addClass("ui-draggable"); 1604 } 1605 if (this.options.disabled){ 1606 this.element.addClass("ui-draggable-disabled"); 1607 } 1608 this._setHandleClassName(); 1609 1610 this._mouseInit(); 1611 }, 1612 1613 _setOption: function( key, value ) { 1614 this._super( key, value ); 1615 if ( key === "handle" ) { 1616 this._removeHandleClassName(); 1617 this._setHandleClassName(); 1618 } 1619 }, 1620 1621 _destroy: function() { 1622 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 1623 this.destroyOnClear = true; 1624 return; 1625 } 1626 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1627 this._removeHandleClassName(); 1628 this._mouseDestroy(); 1629 }, 1630 1631 _mouseCapture: function(event) { 1632 var o = this.options; 1633 1634 this._blurActiveElement( event ); 1635 1636 // among others, prevent a drag on a resizable-handle 1637 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1638 return false; 1639 } 1640 1641 //Quit if we're not on a valid handle 1642 this.handle = this._getHandle(event); 1643 if (!this.handle) { 1644 return false; 1645 } 1646 1647 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 1648 1649 return true; 1650 1651 }, 1652 1653 _blockFrames: function( selector ) { 1654 this.iframeBlocks = this.document.find( selector ).map(function() { 1655 var iframe = $( this ); 1656 1657 return $( "<div>" ) 1658 .css( "position", "absolute" ) 1659 .appendTo( iframe.parent() ) 1660 .outerWidth( iframe.outerWidth() ) 1661 .outerHeight( iframe.outerHeight() ) 1662 .offset( iframe.offset() )[ 0 ]; 1663 }); 1664 }, 1665 1666 _unblockFrames: function() { 1667 if ( this.iframeBlocks ) { 1668 this.iframeBlocks.remove(); 1669 delete this.iframeBlocks; 1670 } 1671 }, 1672 1673 _blurActiveElement: function( event ) { 1674 var document = this.document[ 0 ]; 1675 1676 // Only need to blur if the event occurred on the draggable itself, see #10527 1677 if ( !this.handleElement.is( event.target ) ) { 1678 return; 1679 } 1680 1681 // support: IE9 1682 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1683 try { 1684 1685 // Support: IE9, IE10 1686 // If the <body> is blurred, IE will switch windows, see #9520 1687 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { 1688 1689 // Blur any element that currently has focus, see #4261 1690 $( document.activeElement ).blur(); 1691 } 1692 } catch ( error ) {} 1693 }, 1694 1695 _mouseStart: function(event) { 1696 1697 var o = this.options; 1698 1699 //Create and append the visible helper 1700 this.helper = this._createHelper(event); 1701 1702 this.helper.addClass("ui-draggable-dragging"); 1703 1704 //Cache the helper size 1705 this._cacheHelperProportions(); 1706 1707 //If ddmanager is used for droppables, set the global draggable 1708 if ($.ui.ddmanager) { 1709 $.ui.ddmanager.current = this; 1710 } 1711 1712 /* 1713 * - Position generation - 1714 * This block generates everything position related - it's the core of draggables. 1715 */ 1716 1717 //Cache the margins of the original element 1718 this._cacheMargins(); 1719 1720 //Store the helper's css position 1721 this.cssPosition = this.helper.css( "position" ); 1722 this.scrollParent = this.helper.scrollParent( true ); 1723 this.offsetParent = this.helper.offsetParent(); 1724 this.hasFixedAncestor = this.helper.parents().filter(function() { 1725 return $( this ).css( "position" ) === "fixed"; 1726 }).length > 0; 1727 1728 //The element's absolute position on the page minus margins 1729 this.positionAbs = this.element.offset(); 1730 this._refreshOffsets( event ); 1731 1732 //Generate the original position 1733 this.originalPosition = this.position = this._generatePosition( event, false ); 1734 this.originalPageX = event.pageX; 1735 this.originalPageY = event.pageY; 1736 1737 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1738 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1739 1740 //Set a containment if given in the options 1741 this._setContainment(); 1742 1743 //Trigger event + callbacks 1744 if (this._trigger("start", event) === false) { 1745 this._clear(); 1746 return false; 1747 } 1748 1749 //Recache the helper size 1750 this._cacheHelperProportions(); 1751 1752 //Prepare the droppable offsets 1753 if ($.ui.ddmanager && !o.dropBehaviour) { 1754 $.ui.ddmanager.prepareOffsets(this, event); 1755 } 1756 1757 // Reset helper's right/bottom css if they're set and set explicit width/height instead 1758 // as this prevents resizing of elements with right/bottom set (see #7772) 1759 this._normalizeRightBottom(); 1760 1761 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1762 1763 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1764 if ( $.ui.ddmanager ) { 1765 $.ui.ddmanager.dragStart(this, event); 1766 } 1767 1768 return true; 1769 }, 1770 1771 _refreshOffsets: function( event ) { 1772 this.offset = { 1773 top: this.positionAbs.top - this.margins.top, 1774 left: this.positionAbs.left - this.margins.left, 1775 scroll: false, 1776 parent: this._getParentOffset(), 1777 relative: this._getRelativeOffset() 1778 }; 1779 1780 this.offset.click = { 1781 left: event.pageX - this.offset.left, 1782 top: event.pageY - this.offset.top 1783 }; 1784 }, 1785 1786 _mouseDrag: function(event, noPropagation) { 1787 // reset any necessary cached properties (see #5009) 1788 if ( this.hasFixedAncestor ) { 1789 this.offset.parent = this._getParentOffset(); 1790 } 1791 1792 //Compute the helpers position 1793 this.position = this._generatePosition( event, true ); 1794 this.positionAbs = this._convertPositionTo("absolute"); 1795 1796 //Call plugins and callbacks and use the resulting position if something is returned 1797 if (!noPropagation) { 1798 var ui = this._uiHash(); 1799 if (this._trigger("drag", event, ui) === false) { 1800 this._mouseUp({}); 1801 return false; 1802 } 1803 this.position = ui.position; 1804 } 1805 1806 this.helper[ 0 ].style.left = this.position.left + "px"; 1807 this.helper[ 0 ].style.top = this.position.top + "px"; 1808 1809 if ($.ui.ddmanager) { 1810 $.ui.ddmanager.drag(this, event); 1811 } 1812 1813 return false; 1814 }, 1815 1816 _mouseStop: function(event) { 1817 1818 //If we are using droppables, inform the manager about the drop 1819 var that = this, 1820 dropped = false; 1821 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1822 dropped = $.ui.ddmanager.drop(this, event); 1823 } 1824 1825 //if a drop comes from outside (a sortable) 1826 if (this.dropped) { 1827 dropped = this.dropped; 1828 this.dropped = false; 1829 } 1830 1831 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))) { 1832 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1833 if (that._trigger("stop", event) !== false) { 1834 that._clear(); 1835 } 1836 }); 1837 } else { 1838 if (this._trigger("stop", event) !== false) { 1839 this._clear(); 1840 } 1841 } 1842 1843 return false; 1844 }, 1845 1846 _mouseUp: function( event ) { 1847 this._unblockFrames(); 1848 1849 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1850 if ( $.ui.ddmanager ) { 1851 $.ui.ddmanager.dragStop(this, event); 1852 } 1853 1854 // Only need to focus if the event occurred on the draggable itself, see #10527 1855 if ( this.handleElement.is( event.target ) ) { 1856 // The interaction is over; whether or not the click resulted in a drag, focus the element 1857 this.element.focus(); 1858 } 1859 1860 return $.ui.mouse.prototype._mouseUp.call(this, event); 1861 }, 1862 1863 cancel: function() { 1864 1865 if (this.helper.is(".ui-draggable-dragging")) { 1866 this._mouseUp({}); 1867 } else { 1868 this._clear(); 1869 } 1870 1871 return this; 1872 1873 }, 1874 1875 _getHandle: function(event) { 1876 return this.options.handle ? 1877 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1878 true; 1879 }, 1880 1881 _setHandleClassName: function() { 1882 this.handleElement = this.options.handle ? 1883 this.element.find( this.options.handle ) : this.element; 1884 this.handleElement.addClass( "ui-draggable-handle" ); 1885 }, 1886 1887 _removeHandleClassName: function() { 1888 this.handleElement.removeClass( "ui-draggable-handle" ); 1889 }, 1890 1891 _createHelper: function(event) { 1892 1893 var o = this.options, 1894 helperIsFunction = $.isFunction( o.helper ), 1895 helper = helperIsFunction ? 1896 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 1897 ( o.helper === "clone" ? 1898 this.element.clone().removeAttr( "id" ) : 1899 this.element ); 1900 1901 if (!helper.parents("body").length) { 1902 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1903 } 1904 1905 // http://bugs.jqueryui.com/ticket/9446 1906 // a helper function can return the original element
vendor: 4,479 bytes, lines 1907-2041
1907 // which wouldn't have been set to relative in _create 1908 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 1909 this._setPositionRelative(); 1910 } 1911 1912 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1913 helper.css("position", "absolute"); 1914 } 1915 1916 return helper; 1917 1918 }, 1919 1920 _setPositionRelative: function() { 1921 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 1922 this.element[ 0 ].style.position = "relative"; 1923 } 1924 }, 1925 1926 _adjustOffsetFromHelper: function(obj) { 1927 if (typeof obj === "string") { 1928 obj = obj.split(" "); 1929 } 1930 if ($.isArray(obj)) { 1931 obj = { left: +obj[0], top: +obj[1] || 0 }; 1932 } 1933 if ("left" in obj) { 1934 this.offset.click.left = obj.left + this.margins.left; 1935 } 1936 if ("right" in obj) { 1937 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1938 } 1939 if ("top" in obj) { 1940 this.offset.click.top = obj.top + this.margins.top; 1941 } 1942 if ("bottom" in obj) { 1943 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1944 } 1945 }, 1946 1947 _isRootNode: function( element ) { 1948 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 1949 }, 1950 1951 _getParentOffset: function() { 1952 1953 //Get the offsetParent and cache its position 1954 var po = this.offsetParent.offset(), 1955 document = this.document[ 0 ]; 1956 1957 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1958 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1959 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1960 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1961 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1962 po.left += this.scrollParent.scrollLeft(); 1963 po.top += this.scrollParent.scrollTop(); 1964 } 1965 1966 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 1967 po = { top: 0, left: 0 }; 1968 } 1969 1970 return { 1971 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 1972 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 1973 }; 1974 1975 }, 1976 1977 _getRelativeOffset: function() { 1978 if ( this.cssPosition !== "relative" ) { 1979 return { top: 0, left: 0 }; 1980 } 1981 1982 var p = this.element.position(), 1983 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 1984 1985 return { 1986 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 1987 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 1988 }; 1989 1990 }, 1991 1992 _cacheMargins: function() { 1993 this.margins = { 1994 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 1995 top: (parseInt(this.element.css("marginTop"), 10) || 0), 1996 right: (parseInt(this.element.css("marginRight"), 10) || 0), 1997 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 1998 }; 1999 }, 2000 2001 _cacheHelperProportions: function() { 2002 this.helperProportions = { 2003 width: this.helper.outerWidth(), 2004 height: this.helper.outerHeight() 2005 }; 2006 }, 2007 2008 _setContainment: function() { 2009 2010 var isUserScrollable, c, ce, 2011 o = this.options, 2012 document = this.document[ 0 ]; 2013 2014 this.relativeContainer = null; 2015 2016 if ( !o.containment ) { 2017 this.containment = null; 2018 return; 2019 } 2020 2021 if ( o.containment === "window" ) { 2022 this.containment = [ 2023 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 2024 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 2025 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 2026 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 2027 ]; 2028 return; 2029 } 2030 2031 if ( o.containment === "document") { 2032 this.containment = [ 2033 0, 2034 0, 2035 $( document ).width() - this.helperProportions.width - this.margins.left, 2036 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 2037 ]; 2038 return; 2039 } 2040 2041 if ( o.containment.constructor === Array ) {
vendor: 6,831 bytes, lines 2042-2220
2042 this.containment = o.containment; 2043 return; 2044 } 2045 2046 if ( o.containment === "parent" ) { 2047 o.containment = this.helper[ 0 ].parentNode; 2048 } 2049 2050 c = $( o.containment ); 2051 ce = c[ 0 ]; 2052 2053 if ( !ce ) { 2054 return; 2055 } 2056 2057 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 2058 2059 this.containment = [ 2060 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 2061 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 2062 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 2063 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 2064 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 2065 this.helperProportions.width - 2066 this.margins.left - 2067 this.margins.right, 2068 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 2069 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 2070 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 2071 this.helperProportions.height - 2072 this.margins.top - 2073 this.margins.bottom 2074 ]; 2075 this.relativeContainer = c; 2076 }, 2077 2078 _convertPositionTo: function(d, pos) { 2079 2080 if (!pos) { 2081 pos = this.position; 2082 } 2083 2084 var mod = d === "absolute" ? 1 : -1, 2085 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2086 2087 return { 2088 top: ( 2089 pos.top + // The absolute mouse position 2090 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 2091 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 2092 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) 2093 ), 2094 left: ( 2095 pos.left + // The absolute mouse position 2096 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 2097 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 2098 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) 2099 ) 2100 }; 2101 2102 }, 2103 2104 _generatePosition: function( event, constrainPosition ) { 2105 2106 var containment, co, top, left, 2107 o = this.options, 2108 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2109 pageX = event.pageX, 2110 pageY = event.pageY; 2111 2112 // Cache the scroll 2113 if ( !scrollIsRootNode || !this.offset.scroll ) { 2114 this.offset.scroll = { 2115 top: this.scrollParent.scrollTop(), 2116 left: this.scrollParent.scrollLeft() 2117 }; 2118 } 2119 2120 /* 2121 * - Position constraining - 2122 * Constrain the position to a mix of grid, containment. 2123 */ 2124 2125 // If we are not dragging yet, we won't check for options 2126 if ( constrainPosition ) { 2127 if ( this.containment ) { 2128 if ( this.relativeContainer ){ 2129 co = this.relativeContainer.offset(); 2130 containment = [ 2131 this.containment[ 0 ] + co.left, 2132 this.containment[ 1 ] + co.top, 2133 this.containment[ 2 ] + co.left, 2134 this.containment[ 3 ] + co.top 2135 ]; 2136 } else { 2137 containment = this.containment; 2138 } 2139 2140 if (event.pageX - this.offset.click.left < containment[0]) { 2141 pageX = containment[0] + this.offset.click.left; 2142 } 2143 if (event.pageY - this.offset.click.top < containment[1]) { 2144 pageY = containment[1] + this.offset.click.top; 2145 } 2146 if (event.pageX - this.offset.click.left > containment[2]) { 2147 pageX = containment[2] + this.offset.click.left; 2148 } 2149 if (event.pageY - this.offset.click.top > containment[3]) { 2150 pageY = containment[3] + this.offset.click.top; 2151 } 2152 } 2153 2154 if (o.grid) { 2155 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 2156 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 2157 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; 2158 2159 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 2160 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; 2161 } 2162 2163 if ( o.axis === "y" ) { 2164 pageX = this.originalPageX; 2165 } 2166 2167 if ( o.axis === "x" ) { 2168 pageY = this.originalPageY; 2169 } 2170 } 2171 2172 return { 2173 top: ( 2174 pageY - // The absolute mouse position 2175 this.offset.click.top - // Click offset (relative to the element) 2176 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 2177 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 2178 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2179 ), 2180 left: ( 2181 pageX - // The absolute mouse position 2182 this.offset.click.left - // Click offset (relative to the element) 2183 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 2184 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 2185 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2186 ) 2187 }; 2188 2189 }, 2190 2191 _clear: function() { 2192 this.helper.removeClass("ui-draggable-dragging"); 2193 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 2194 this.helper.remove(); 2195 } 2196 this.helper = null; 2197 this.cancelHelperRemoval = false; 2198 if ( this.destroyOnClear ) { 2199 this.destroy(); 2200 } 2201 }, 2202 2203 _normalizeRightBottom: function() { 2204 if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { 2205 this.helper.width( this.helper.width() ); 2206 this.helper.css( "right", "auto" ); 2207 } 2208 if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { 2209 this.helper.height( this.helper.height() ); 2210 this.helper.css( "bottom", "auto" ); 2211 } 2212 }, 2213 2214 // From now on bulk stuff - mainly helpers 2215 2216 _trigger: function( type, event, ui ) { 2217 ui = ui || this._uiHash(); 2218 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2219 2220 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
vendor: 4,383 bytes, lines 2221-2354
2221 if ( /^(drag|start|stop)/.test( type ) ) { 2222 this.positionAbs = this._convertPositionTo( "absolute" ); 2223 ui.offset = this.positionAbs; 2224 } 2225 return $.Widget.prototype._trigger.call( this, type, event, ui ); 2226 }, 2227 2228 plugins: {}, 2229 2230 _uiHash: function() { 2231 return { 2232 helper: this.helper, 2233 position: this.position, 2234 originalPosition: this.originalPosition, 2235 offset: this.positionAbs 2236 }; 2237 } 2238 2239}); 2240 2241$.ui.plugin.add( "draggable", "connectToSortable", { 2242 start: function( event, ui, draggable ) { 2243 var uiSortable = $.extend( {}, ui, { 2244 item: draggable.element 2245 }); 2246 2247 draggable.sortables = []; 2248 $( draggable.options.connectToSortable ).each(function() { 2249 var sortable = $( this ).sortable( "instance" ); 2250 2251 if ( sortable && !sortable.options.disabled ) { 2252 draggable.sortables.push( sortable ); 2253 2254 // refreshPositions is called at drag start to refresh the containerCache 2255 // which is used in drag. This ensures it's initialized and synchronized 2256 // with any changes that might have happened on the page since initialization. 2257 sortable.refreshPositions(); 2258 sortable._trigger("activate", event, uiSortable); 2259 } 2260 }); 2261 }, 2262 stop: function( event, ui, draggable ) { 2263 var uiSortable = $.extend( {}, ui, { 2264 item: draggable.element 2265 }); 2266 2267 draggable.cancelHelperRemoval = false; 2268 2269 $.each( draggable.sortables, function() { 2270 var sortable = this; 2271 2272 if ( sortable.isOver ) { 2273 sortable.isOver = 0; 2274 2275 // Allow this sortable to handle removing the helper 2276 draggable.cancelHelperRemoval = true; 2277 sortable.cancelHelperRemoval = false; 2278 2279 // Use _storedCSS To restore properties in the sortable, 2280 // as this also handles revert (#9675) since the draggable 2281 // may have modified them in unexpected ways (#8809) 2282 sortable._storedCSS = { 2283 position: sortable.placeholder.css( "position" ), 2284 top: sortable.placeholder.css( "top" ), 2285 left: sortable.placeholder.css( "left" ) 2286 }; 2287 2288 sortable._mouseStop(event); 2289 2290 // Once drag has ended, the sortable should return to using 2291 // its original helper, not the shared helper from draggable 2292 sortable.options.helper = sortable.options._helper; 2293 } else { 2294 // Prevent this Sortable from removing the helper. 2295 // However, don't set the draggable to remove the helper 2296 // either as another connected Sortable may yet handle the removal. 2297 sortable.cancelHelperRemoval = true; 2298 2299 sortable._trigger( "deactivate", event, uiSortable ); 2300 } 2301 }); 2302 }, 2303 drag: function( event, ui, draggable ) { 2304 $.each( draggable.sortables, function() { 2305 var innermostIntersecting = false, 2306 sortable = this; 2307 2308 // Copy over variables that sortable's _intersectsWith uses 2309 sortable.positionAbs = draggable.positionAbs; 2310 sortable.helperProportions = draggable.helperProportions; 2311 sortable.offset.click = draggable.offset.click; 2312 2313 if ( sortable._intersectsWith( sortable.containerCache ) ) { 2314 innermostIntersecting = true; 2315 2316 $.each( draggable.sortables, function() { 2317 // Copy over variables that sortable's _intersectsWith uses 2318 this.positionAbs = draggable.positionAbs; 2319 this.helperProportions = draggable.helperProportions; 2320 this.offset.click = draggable.offset.click; 2321 2322 if ( this !== sortable && 2323 this._intersectsWith( this.containerCache ) && 2324 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 2325 innermostIntersecting = false; 2326 } 2327 2328 return innermostIntersecting; 2329 }); 2330 } 2331 2332 if ( innermostIntersecting ) { 2333 // If it intersects, we use a little isOver variable and set it once, 2334 // so that the move-in stuff gets fired only once. 2335 if ( !sortable.isOver ) { 2336 sortable.isOver = 1; 2337 2338 sortable.currentItem = ui.helper 2339 .appendTo( sortable.element ) 2340 .data( "ui-sortable-item", true ); 2341 2342 // Store helper option to later restore it 2343 sortable.options._helper = sortable.options.helper; 2344 2345 sortable.options.helper = function() { 2346 return ui.helper[ 0 ]; 2347 }; 2348 2349 // Fire the start events of the sortable with our passed browser event, 2350 // and our own helper (so it doesn't create a new one) 2351 event.target = sortable.currentItem[ 0 ]; 2352 sortable._mouseCapture( event, true ); 2353 sortable._mouseStart( event, true, true ); 2354
vendor: 38,707 bytes, lines 2355-3730
2355 // Because the browser event is way off the new appended portlet, 2356 // modify necessary variables to reflect the changes 2357 sortable.offset.click.top = draggable.offset.click.top; 2358 sortable.offset.click.left = draggable.offset.click.left; 2359 sortable.offset.parent.left -= draggable.offset.parent.left - 2360 sortable.offset.parent.left; 2361 sortable.offset.parent.top -= draggable.offset.parent.top - 2362 sortable.offset.parent.top; 2363 2364 draggable._trigger( "toSortable", event ); 2365 2366 // Inform draggable that the helper is in a valid drop zone, 2367 // used solely in the revert option to handle "valid/invalid". 2368 draggable.dropped = sortable.element; 2369 2370 // Need to refreshPositions of all sortables in the case that 2371 // adding to one sortable changes the location of the other sortables (#9675) 2372 $.each( draggable.sortables, function() { 2373 this.refreshPositions(); 2374 }); 2375 2376 // hack so receive/update callbacks work (mostly) 2377 draggable.currentItem = draggable.element; 2378 sortable.fromOutside = draggable; 2379 } 2380 2381 if ( sortable.currentItem ) { 2382 sortable._mouseDrag( event ); 2383 // Copy the sortable's position because the draggable's can potentially reflect 2384 // a relative position, while sortable is always absolute, which the dragged 2385 // element has now become. (#8809) 2386 ui.position = sortable.position; 2387 } 2388 } else { 2389 // If it doesn't intersect with the sortable, and it intersected before, 2390 // we fake the drag stop of the sortable, but make sure it doesn't remove 2391 // the helper by using cancelHelperRemoval. 2392 if ( sortable.isOver ) { 2393 2394 sortable.isOver = 0; 2395 sortable.cancelHelperRemoval = true; 2396 2397 // Calling sortable's mouseStop would trigger a revert, 2398 // so revert must be temporarily false until after mouseStop is called. 2399 sortable.options._revert = sortable.options.revert; 2400 sortable.options.revert = false; 2401 2402 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 2403 sortable._mouseStop( event, true ); 2404 2405 // restore sortable behaviors that were modfied 2406 // when the draggable entered the sortable area (#9481) 2407 sortable.options.revert = sortable.options._revert; 2408 sortable.options.helper = sortable.options._helper; 2409 2410 if ( sortable.placeholder ) { 2411 sortable.placeholder.remove(); 2412 } 2413 2414 // Recalculate the draggable's offset considering the sortable 2415 // may have modified them in unexpected ways (#8809) 2416 draggable._refreshOffsets( event ); 2417 ui.position = draggable._generatePosition( event, true ); 2418 2419 draggable._trigger( "fromSortable", event ); 2420 2421 // Inform draggable that the helper is no longer in a valid drop zone 2422 draggable.dropped = false; 2423 2424 // Need to refreshPositions of all sortables just in case removing 2425 // from one sortable changes the location of other sortables (#9675) 2426 $.each( draggable.sortables, function() { 2427 this.refreshPositions(); 2428 }); 2429 } 2430 } 2431 }); 2432 } 2433}); 2434 2435$.ui.plugin.add("draggable", "cursor", { 2436 start: function( event, ui, instance ) { 2437 var t = $( "body" ), 2438 o = instance.options; 2439 2440 if (t.css("cursor")) { 2441 o._cursor = t.css("cursor"); 2442 } 2443 t.css("cursor", o.cursor); 2444 }, 2445 stop: function( event, ui, instance ) { 2446 var o = instance.options; 2447 if (o._cursor) { 2448 $("body").css("cursor", o._cursor); 2449 } 2450 } 2451}); 2452 2453$.ui.plugin.add("draggable", "opacity", { 2454 start: function( event, ui, instance ) { 2455 var t = $( ui.helper ), 2456 o = instance.options; 2457 if (t.css("opacity")) { 2458 o._opacity = t.css("opacity"); 2459 } 2460 t.css("opacity", o.opacity); 2461 }, 2462 stop: function( event, ui, instance ) { 2463 var o = instance.options; 2464 if (o._opacity) { 2465 $(ui.helper).css("opacity", o._opacity); 2466 } 2467 } 2468}); 2469 2470$.ui.plugin.add("draggable", "scroll", { 2471 start: function( event, ui, i ) { 2472 if ( !i.scrollParentNotHidden ) { 2473 i.scrollParentNotHidden = i.helper.scrollParent( false ); 2474 } 2475 2476 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 2477 i.overflowOffset = i.scrollParentNotHidden.offset(); 2478 } 2479 }, 2480 drag: function( event, ui, i ) { 2481 2482 var o = i.options, 2483 scrolled = false, 2484 scrollParent = i.scrollParentNotHidden[ 0 ], 2485 document = i.document[ 0 ]; 2486 2487 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 2488 if ( !o.axis || o.axis !== "x" ) { 2489 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { 2490 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 2491 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 2492 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 2493 } 2494 } 2495 2496 if ( !o.axis || o.axis !== "y" ) { 2497 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { 2498 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 2499 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 2500 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 2501 } 2502 } 2503 2504 } else { 2505 2506 if (!o.axis || o.axis !== "x") { 2507 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 2508 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2509 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 2510 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2511 } 2512 } 2513 2514 if (!o.axis || o.axis !== "y") { 2515 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 2516 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2517 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 2518 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2519 } 2520 } 2521 2522 } 2523 2524 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 2525 $.ui.ddmanager.prepareOffsets(i, event); 2526 } 2527 2528 } 2529}); 2530 2531$.ui.plugin.add("draggable", "snap", { 2532 start: function( event, ui, i ) { 2533 2534 var o = i.options; 2535 2536 i.snapElements = []; 2537 2538 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 2539 var $t = $(this), 2540 $o = $t.offset(); 2541 if (this !== i.element[0]) { 2542 i.snapElements.push({ 2543 item: this, 2544 width: $t.outerWidth(), height: $t.outerHeight(), 2545 top: $o.top, left: $o.left 2546 }); 2547 } 2548 }); 2549 2550 }, 2551 drag: function( event, ui, inst ) { 2552 2553 var ts, bs, ls, rs, l, r, t, b, i, first, 2554 o = inst.options, 2555 d = o.snapTolerance, 2556 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2557 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2558 2559 for (i = inst.snapElements.length - 1; i >= 0; i--){ 2560 2561 l = inst.snapElements[i].left - inst.margins.left; 2562 r = l + inst.snapElements[i].width; 2563 t = inst.snapElements[i].top - inst.margins.top; 2564 b = t + inst.snapElements[i].height; 2565 2566 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 2567 if (inst.snapElements[i].snapping) { 2568 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2569 } 2570 inst.snapElements[i].snapping = false; 2571 continue; 2572 } 2573 2574 if (o.snapMode !== "inner") { 2575 ts = Math.abs(t - y2) <= d; 2576 bs = Math.abs(b - y1) <= d; 2577 ls = Math.abs(l - x2) <= d; 2578 rs = Math.abs(r - x1) <= d; 2579 if (ts) { 2580 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; 2581 } 2582 if (bs) { 2583 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; 2584 } 2585 if (ls) { 2586 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; 2587 } 2588 if (rs) { 2589 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; 2590 } 2591 } 2592 2593 first = (ts || bs || ls || rs); 2594 2595 if (o.snapMode !== "outer") { 2596 ts = Math.abs(t - y1) <= d; 2597 bs = Math.abs(b - y2) <= d; 2598 ls = Math.abs(l - x1) <= d; 2599 rs = Math.abs(r - x2) <= d; 2600 if (ts) { 2601 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; 2602 } 2603 if (bs) { 2604 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; 2605 } 2606 if (ls) { 2607 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; 2608 } 2609 if (rs) { 2610 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; 2611 } 2612 } 2613 2614 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 2615 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2616 } 2617 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2618 2619 } 2620 2621 } 2622}); 2623 2624$.ui.plugin.add("draggable", "stack", { 2625 start: function( event, ui, instance ) { 2626 var min, 2627 o = instance.options, 2628 group = $.makeArray($(o.stack)).sort(function(a, b) { 2629 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 2630 }); 2631 2632 if (!group.length) { return; } 2633 2634 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 2635 $(group).each(function(i) { 2636 $(this).css("zIndex", min + i); 2637 }); 2638 this.css("zIndex", (min + group.length)); 2639 } 2640}); 2641 2642$.ui.plugin.add("draggable", "zIndex", { 2643 start: function( event, ui, instance ) { 2644 var t = $( ui.helper ), 2645 o = instance.options; 2646 2647 if (t.css("zIndex")) { 2648 o._zIndex = t.css("zIndex"); 2649 } 2650 t.css("zIndex", o.zIndex); 2651 }, 2652 stop: function( event, ui, instance ) { 2653 var o = instance.options; 2654 2655 if (o._zIndex) { 2656 $(ui.helper).css("zIndex", o._zIndex); 2657 } 2658 } 2659}); 2660 2661var draggable = $.ui.draggable; 2662 2663 2664/*! 2665 * jQuery UI Droppable 1.11.2 2666 * http://jqueryui.com 2667 * 2668 * Copyright 2014 jQuery Foundation and other contributors 2669 * Released under the MIT license. 2670 * http://jquery.org/license 2671 * 2672 * http://api.jqueryui.com/droppable/ 2673 */ 2674 2675 2676$.widget( "ui.droppable", { 2677 version: "1.11.2", 2678 widgetEventPrefix: "drop", 2679 options: { 2680 accept: "*", 2681 activeClass: false, 2682 addClasses: true, 2683 greedy: false, 2684 hoverClass: false, 2685 scope: "default", 2686 tolerance: "intersect", 2687 2688 // callbacks 2689 activate: null, 2690 deactivate: null, 2691 drop: null, 2692 out: null, 2693 over: null 2694 }, 2695 _create: function() { 2696 2697 var proportions, 2698 o = this.options, 2699 accept = o.accept; 2700 2701 this.isover = false; 2702 this.isout = true; 2703 2704 this.accept = $.isFunction( accept ) ? accept : function( d ) { 2705 return d.is( accept ); 2706 }; 2707 2708 this.proportions = function( /* valueToWrite */ ) { 2709 if ( arguments.length ) { 2710 // Store the droppable's proportions 2711 proportions = arguments[ 0 ]; 2712 } else { 2713 // Retrieve or derive the droppable's proportions 2714 return proportions ? 2715 proportions : 2716 proportions = { 2717 width: this.element[ 0 ].offsetWidth, 2718 height: this.element[ 0 ].offsetHeight 2719 }; 2720 } 2721 }; 2722 2723 this._addToManager( o.scope ); 2724 2725 o.addClasses && this.element.addClass( "ui-droppable" ); 2726 2727 }, 2728 2729 _addToManager: function( scope ) { 2730 // Add the reference and positions to the manager 2731 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 2732 $.ui.ddmanager.droppables[ scope ].push( this ); 2733 }, 2734 2735 _splice: function( drop ) { 2736 var i = 0; 2737 for ( ; i < drop.length; i++ ) { 2738 if ( drop[ i ] === this ) { 2739 drop.splice( i, 1 ); 2740 } 2741 } 2742 }, 2743 2744 _destroy: function() { 2745 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 2746 2747 this._splice( drop ); 2748 2749 this.element.removeClass( "ui-droppable ui-droppable-disabled" ); 2750 }, 2751 2752 _setOption: function( key, value ) { 2753 2754 if ( key === "accept" ) { 2755 this.accept = $.isFunction( value ) ? value : function( d ) { 2756 return d.is( value ); 2757 }; 2758 } else if ( key === "scope" ) { 2759 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 2760 2761 this._splice( drop ); 2762 this._addToManager( value ); 2763 } 2764 2765 this._super( key, value ); 2766 }, 2767 2768 _activate: function( event ) { 2769 var draggable = $.ui.ddmanager.current; 2770 if ( this.options.activeClass ) { 2771 this.element.addClass( this.options.activeClass ); 2772 } 2773 if ( draggable ){ 2774 this._trigger( "activate", event, this.ui( draggable ) ); 2775 } 2776 }, 2777 2778 _deactivate: function( event ) { 2779 var draggable = $.ui.ddmanager.current; 2780 if ( this.options.activeClass ) { 2781 this.element.removeClass( this.options.activeClass ); 2782 } 2783 if ( draggable ){ 2784 this._trigger( "deactivate", event, this.ui( draggable ) ); 2785 } 2786 }, 2787 2788 _over: function( event ) { 2789 2790 var draggable = $.ui.ddmanager.current; 2791 2792 // Bail if draggable and droppable are same element 2793 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2794 return; 2795 } 2796 2797 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2798 if ( this.options.hoverClass ) { 2799 this.element.addClass( this.options.hoverClass ); 2800 } 2801 this._trigger( "over", event, this.ui( draggable ) ); 2802 } 2803 2804 }, 2805 2806 _out: function( event ) { 2807 2808 var draggable = $.ui.ddmanager.current; 2809 2810 // Bail if draggable and droppable are same element 2811 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2812 return; 2813 } 2814 2815 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2816 if ( this.options.hoverClass ) { 2817 this.element.removeClass( this.options.hoverClass ); 2818 } 2819 this._trigger( "out", event, this.ui( draggable ) ); 2820 } 2821 2822 }, 2823 2824 _drop: function( event, custom ) { 2825 2826 var draggable = custom || $.ui.ddmanager.current, 2827 childrenIntersection = false; 2828 2829 // Bail if draggable and droppable are same element 2830 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2831 return false; 2832 } 2833 2834 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { 2835 var inst = $( this ).droppable( "instance" ); 2836 if ( 2837 inst.options.greedy && 2838 !inst.options.disabled && 2839 inst.options.scope === draggable.options.scope && 2840 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && 2841 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) 2842 ) { childrenIntersection = true; return false; } 2843 }); 2844 if ( childrenIntersection ) { 2845 return false; 2846 } 2847 2848 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2849 if ( this.options.activeClass ) { 2850 this.element.removeClass( this.options.activeClass ); 2851 } 2852 if ( this.options.hoverClass ) { 2853 this.element.removeClass( this.options.hoverClass ); 2854 } 2855 this._trigger( "drop", event, this.ui( draggable ) ); 2856 return this.element; 2857 } 2858 2859 return false; 2860 2861 }, 2862 2863 ui: function( c ) { 2864 return { 2865 draggable: ( c.currentItem || c.element ), 2866 helper: c.helper, 2867 position: c.position, 2868 offset: c.positionAbs 2869 }; 2870 } 2871 2872}); 2873 2874$.ui.intersect = (function() { 2875 function isOverAxis( x, reference, size ) { 2876 return ( x >= reference ) && ( x < ( reference + size ) ); 2877 } 2878 2879 return function( draggable, droppable, toleranceMode, event ) { 2880 2881 if ( !droppable.offset ) { 2882 return false; 2883 } 2884 2885 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, 2886 y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, 2887 x2 = x1 + draggable.helperProportions.width, 2888 y2 = y1 + draggable.helperProportions.height, 2889 l = droppable.offset.left, 2890 t = droppable.offset.top, 2891 r = l + droppable.proportions().width, 2892 b = t + droppable.proportions().height; 2893 2894 switch ( toleranceMode ) { 2895 case "fit": 2896 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 2897 case "intersect": 2898 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 2899 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 2900 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 2901 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 2902 case "pointer": 2903 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); 2904 case "touch": 2905 return ( 2906 ( y1 >= t && y1 <= b ) || // Top edge touching 2907 ( y2 >= t && y2 <= b ) || // Bottom edge touching 2908 ( y1 < t && y2 > b ) // Surrounded vertically 2909 ) && ( 2910 ( x1 >= l && x1 <= r ) || // Left edge touching 2911 ( x2 >= l && x2 <= r ) || // Right edge touching 2912 ( x1 < l && x2 > r ) // Surrounded horizontally 2913 ); 2914 default: 2915 return false; 2916 } 2917 }; 2918})(); 2919 2920/* 2921 This manager tracks offsets of draggables and droppables 2922*/ 2923$.ui.ddmanager = { 2924 current: null, 2925 droppables: { "default": [] }, 2926 prepareOffsets: function( t, event ) { 2927 2928 var i, j, 2929 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 2930 type = event ? event.type : null, // workaround for #2317 2931 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 2932 2933 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 2934 2935 // No disabled and non-accepted 2936 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { 2937 continue; 2938 } 2939 2940 // Filter out elements in the current dragged item 2941 for ( j = 0; j < list.length; j++ ) { 2942 if ( list[ j ] === m[ i ].element[ 0 ] ) { 2943 m[ i ].proportions().height = 0; 2944 continue droppablesLoop; 2945 } 2946 } 2947 2948 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 2949 if ( !m[ i ].visible ) { 2950 continue; 2951 } 2952 2953 // Activate the droppable if used directly from draggables 2954 if ( type === "mousedown" ) { 2955 m[ i ]._activate.call( m[ i ], event ); 2956 } 2957 2958 m[ i ].offset = m[ i ].element.offset(); 2959 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 2960 2961 } 2962 2963 }, 2964 drop: function( draggable, event ) { 2965 2966 var dropped = false; 2967 // Create a copy of the droppables in case the list changes during the drop (#9116) 2968 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 2969 2970 if ( !this.options ) { 2971 return; 2972 } 2973 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 2974 dropped = this._drop.call( this, event ) || dropped; 2975 } 2976 2977 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2978 this.isout = true; 2979 this.isover = false; 2980 this._deactivate.call( this, event ); 2981 } 2982 2983 }); 2984 return dropped; 2985 2986 }, 2987 dragStart: function( draggable, event ) { 2988 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2989 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2990 if ( !draggable.options.refreshPositions ) { 2991 $.ui.ddmanager.prepareOffsets( draggable, event ); 2992 } 2993 }); 2994 }, 2995 drag: function( draggable, event ) { 2996 2997 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2998 if ( draggable.options.refreshPositions ) { 2999 $.ui.ddmanager.prepareOffsets( draggable, event ); 3000 } 3001 3002 // Run through all droppables and check their positions based on specific tolerance options 3003 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 3004 3005 if ( this.options.disabled || this.greedyChild || !this.visible ) { 3006 return; 3007 } 3008 3009 var parentInstance, scope, parent, 3010 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 3011 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); 3012 if ( !c ) { 3013 return; 3014 } 3015 3016 if ( this.options.greedy ) { 3017 // find droppable parents with same scope 3018 scope = this.options.scope; 3019 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { 3020 return $( this ).droppable( "instance" ).options.scope === scope; 3021 }); 3022 3023 if ( parent.length ) { 3024 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 3025 parentInstance.greedyChild = ( c === "isover" ); 3026 } 3027 } 3028 3029 // we just moved into a greedy child 3030 if ( parentInstance && c === "isover" ) { 3031 parentInstance.isover = false; 3032 parentInstance.isout = true; 3033 parentInstance._out.call( parentInstance, event ); 3034 } 3035 3036 this[ c ] = true; 3037 this[c === "isout" ? "isover" : "isout"] = false; 3038 this[c === "isover" ? "_over" : "_out"].call( this, event ); 3039 3040 // we just moved out of a greedy child 3041 if ( parentInstance && c === "isout" ) { 3042 parentInstance.isout = false; 3043 parentInstance.isover = true; 3044 parentInstance._over.call( parentInstance, event ); 3045 } 3046 }); 3047 3048 }, 3049 dragStop: function( draggable, event ) { 3050 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 3051 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 3052 if ( !draggable.options.refreshPositions ) { 3053 $.ui.ddmanager.prepareOffsets( draggable, event ); 3054 } 3055 } 3056}; 3057 3058var droppable = $.ui.droppable; 3059 3060 3061/*! 3062 * jQuery UI Resizable 1.11.2 3063 * http://jqueryui.com 3064 * 3065 * Copyright 2014 jQuery Foundation and other contributors 3066 * Released under the MIT license. 3067 * http://jquery.org/license 3068 * 3069 * http://api.jqueryui.com/resizable/ 3070 */ 3071 3072 3073$.widget("ui.resizable", $.ui.mouse, { 3074 version: "1.11.2", 3075 widgetEventPrefix: "resize", 3076 options: { 3077 alsoResize: false, 3078 animate: false, 3079 animateDuration: "slow", 3080 animateEasing: "swing", 3081 aspectRatio: false, 3082 autoHide: false, 3083 containment: false, 3084 ghost: false, 3085 grid: false, 3086 handles: "e,s,se", 3087 helper: false, 3088 maxHeight: null, 3089 maxWidth: null, 3090 minHeight: 10, 3091 minWidth: 10, 3092 // See #7960 3093 zIndex: 90, 3094 3095 // callbacks 3096 resize: null, 3097 start: null, 3098 stop: null 3099 }, 3100 3101 _num: function( value ) { 3102 return parseInt( value, 10 ) || 0; 3103 }, 3104 3105 _isNumber: function( value ) { 3106 return !isNaN( parseInt( value, 10 ) ); 3107 }, 3108 3109 _hasScroll: function( el, a ) { 3110 3111 if ( $( el ).css( "overflow" ) === "hidden") { 3112 return false; 3113 } 3114 3115 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3116 has = false; 3117 3118 if ( el[ scroll ] > 0 ) { 3119 return true; 3120 } 3121 3122 // TODO: determine which cases actually cause this to happen 3123 // if the element doesn't have the scroll set, see if it's possible to 3124 // set the scroll 3125 el[ scroll ] = 1; 3126 has = ( el[ scroll ] > 0 ); 3127 el[ scroll ] = 0; 3128 return has; 3129 }, 3130 3131 _create: function() { 3132 3133 var n, i, handle, axis, hname, 3134 that = this, 3135 o = this.options; 3136 this.element.addClass("ui-resizable"); 3137 3138 $.extend(this, { 3139 _aspectRatio: !!(o.aspectRatio), 3140 aspectRatio: o.aspectRatio, 3141 originalElement: this.element, 3142 _proportionallyResizeElements: [], 3143 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 3144 }); 3145 3146 // Wrap the element if it cannot hold child nodes 3147 if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 3148 3149 this.element.wrap( 3150 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 3151 position: this.element.css("position"), 3152 width: this.element.outerWidth(), 3153 height: this.element.outerHeight(), 3154 top: this.element.css("top"), 3155 left: this.element.css("left") 3156 }) 3157 ); 3158 3159 this.element = this.element.parent().data( 3160 "ui-resizable", this.element.resizable( "instance" ) 3161 ); 3162 3163 this.elementIsWrapper = true; 3164 3165 this.element.css({ 3166 marginLeft: this.originalElement.css("marginLeft"), 3167 marginTop: this.originalElement.css("marginTop"), 3168 marginRight: this.originalElement.css("marginRight"), 3169 marginBottom: this.originalElement.css("marginBottom") 3170 }); 3171 this.originalElement.css({ 3172 marginLeft: 0, 3173 marginTop: 0, 3174 marginRight: 0, 3175 marginBottom: 0 3176 }); 3177 // support: Safari 3178 // Prevent Safari textarea resize 3179 this.originalResizeStyle = this.originalElement.css("resize"); 3180 this.originalElement.css("resize", "none"); 3181 3182 this._proportionallyResizeElements.push( this.originalElement.css({ 3183 position: "static", 3184 zoom: 1, 3185 display: "block" 3186 }) ); 3187 3188 // support: IE9 3189 // avoid IE jump (hard set the margin) 3190 this.originalElement.css({ margin: this.originalElement.css("margin") }); 3191 3192 this._proportionallyResize(); 3193 } 3194 3195 this.handles = o.handles || 3196 ( !$(".ui-resizable-handle", this.element).length ? 3197 "e,s,se" : { 3198 n: ".ui-resizable-n", 3199 e: ".ui-resizable-e", 3200 s: ".ui-resizable-s", 3201 w: ".ui-resizable-w", 3202 se: ".ui-resizable-se", 3203 sw: ".ui-resizable-sw", 3204 ne: ".ui-resizable-ne", 3205 nw: ".ui-resizable-nw" 3206 } ); 3207 3208 if (this.handles.constructor === String) { 3209 3210 if ( this.handles === "all") { 3211 this.handles = "n,e,s,w,se,sw,ne,nw"; 3212 } 3213 3214 n = this.handles.split(","); 3215 this.handles = {}; 3216 3217 for (i = 0; i < n.length; i++) { 3218 3219 handle = $.trim(n[i]); 3220 hname = "ui-resizable-" + handle; 3221 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 3222 3223 axis.css({ zIndex: o.zIndex }); 3224 3225 // TODO : What's going on here? 3226 if ("se" === handle) { 3227 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 3228 } 3229 3230 this.handles[handle] = ".ui-resizable-" + handle; 3231 this.element.append(axis); 3232 } 3233 3234 } 3235 3236 this._renderAxis = function(target) { 3237 3238 var i, axis, padPos, padWrapper; 3239 3240 target = target || this.element; 3241 3242 for (i in this.handles) { 3243 3244 if (this.handles[i].constructor === String) { 3245 this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); 3246 } 3247 3248 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 3249 3250 axis = $(this.handles[i], this.element); 3251 3252 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 3253 3254 padPos = [ "padding", 3255 /ne|nw|n/.test(i) ? "Top" : 3256 /se|sw|s/.test(i) ? "Bottom" : 3257 /^e$/.test(i) ? "Right" : "Left" ].join(""); 3258 3259 target.css(padPos, padWrapper); 3260 3261 this._proportionallyResize(); 3262 3263 } 3264 3265 // TODO: What's that good for? There's not anything to be executed left 3266 if (!$(this.handles[i]).length) { 3267 continue; 3268 } 3269 } 3270 }; 3271 3272 // TODO: make renderAxis a prototype function 3273 this._renderAxis(this.element); 3274 3275 this._handles = $(".ui-resizable-handle", this.element) 3276 .disableSelection(); 3277 3278 this._handles.mouseover(function() { 3279 if (!that.resizing) { 3280 if (this.className) { 3281 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 3282 } 3283 that.axis = axis && axis[1] ? axis[1] : "se"; 3284 } 3285 }); 3286 3287 if (o.autoHide) { 3288 this._handles.hide(); 3289 $(this.element) 3290 .addClass("ui-resizable-autohide") 3291 .mouseenter(function() { 3292 if (o.disabled) { 3293 return; 3294 } 3295 $(this).removeClass("ui-resizable-autohide"); 3296 that._handles.show(); 3297 }) 3298 .mouseleave(function() { 3299 if (o.disabled) { 3300 return; 3301 } 3302 if (!that.resizing) { 3303 $(this).addClass("ui-resizable-autohide"); 3304 that._handles.hide(); 3305 } 3306 }); 3307 } 3308 3309 this._mouseInit(); 3310 3311 }, 3312 3313 _destroy: function() { 3314 3315 this._mouseDestroy(); 3316 3317 var wrapper, 3318 _destroy = function(exp) { 3319 $(exp) 3320 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 3321 .removeData("resizable") 3322 .removeData("ui-resizable") 3323 .unbind(".resizable") 3324 .find(".ui-resizable-handle") 3325 .remove(); 3326 }; 3327 3328 // TODO: Unwrap at same DOM position 3329 if (this.elementIsWrapper) { 3330 _destroy(this.element); 3331 wrapper = this.element; 3332 this.originalElement.css({ 3333 position: wrapper.css("position"), 3334 width: wrapper.outerWidth(), 3335 height: wrapper.outerHeight(), 3336 top: wrapper.css("top"), 3337 left: wrapper.css("left") 3338 }).insertAfter( wrapper ); 3339 wrapper.remove(); 3340 } 3341 3342 this.originalElement.css("resize", this.originalResizeStyle); 3343 _destroy(this.originalElement); 3344 3345 return this; 3346 }, 3347 3348 _mouseCapture: function(event) { 3349 var i, handle, 3350 capture = false; 3351 3352 for (i in this.handles) { 3353 handle = $(this.handles[i])[0]; 3354 if (handle === event.target || $.contains(handle, event.target)) { 3355 capture = true; 3356 } 3357 } 3358 3359 return !this.options.disabled && capture; 3360 }, 3361 3362 _mouseStart: function(event) { 3363 3364 var curleft, curtop, cursor, 3365 o = this.options, 3366 el = this.element; 3367 3368 this.resizing = true; 3369 3370 this._renderProxy(); 3371 3372 curleft = this._num(this.helper.css("left")); 3373 curtop = this._num(this.helper.css("top")); 3374 3375 if (o.containment) { 3376 curleft += $(o.containment).scrollLeft() || 0; 3377 curtop += $(o.containment).scrollTop() || 0; 3378 } 3379 3380 this.offset = this.helper.offset(); 3381 this.position = { left: curleft, top: curtop }; 3382 3383 this.size = this._helper ? { 3384 width: this.helper.width(), 3385 height: this.helper.height() 3386 } : { 3387 width: el.width(), 3388 height: el.height() 3389 }; 3390 3391 this.originalSize = this._helper ? { 3392 width: el.outerWidth(), 3393 height: el.outerHeight() 3394 } : { 3395 width: el.width(), 3396 height: el.height() 3397 }; 3398 3399 this.sizeDiff = { 3400 width: el.outerWidth() - el.width(), 3401 height: el.outerHeight() - el.height() 3402 }; 3403 3404 this.originalPosition = { left: curleft, top: curtop }; 3405 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 3406 3407 this.aspectRatio = (typeof o.aspectRatio === "number") ? 3408 o.aspectRatio : 3409 ((this.originalSize.width / this.originalSize.height) || 1); 3410 3411 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 3412 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 3413 3414 el.addClass("ui-resizable-resizing"); 3415 this._propagate("start", event); 3416 return true; 3417 }, 3418 3419 _mouseDrag: function(event) { 3420 3421 var data, props, 3422 smp = this.originalMousePosition, 3423 a = this.axis, 3424 dx = (event.pageX - smp.left) || 0, 3425 dy = (event.pageY - smp.top) || 0, 3426 trigger = this._change[a]; 3427 3428 this._updatePrevProperties(); 3429 3430 if (!trigger) { 3431 return false; 3432 } 3433 3434 data = trigger.apply(this, [ event, dx, dy ]); 3435 3436 this._updateVirtualBoundaries(event.shiftKey); 3437 if (this._aspectRatio || event.shiftKey) { 3438 data = this._updateRatio(data, event); 3439 } 3440 3441 data = this._respectSize(data, event); 3442 3443 this._updateCache(data); 3444 3445 this._propagate("resize", event); 3446 3447 props = this._applyChanges(); 3448 3449 if ( !this._helper && this._proportionallyResizeElements.length ) { 3450 this._proportionallyResize(); 3451 } 3452 3453 if ( !$.isEmptyObject( props ) ) { 3454 this._updatePrevProperties(); 3455 this._trigger( "resize", event, this.ui() ); 3456 this._applyChanges(); 3457 } 3458 3459 return false; 3460 }, 3461 3462 _mouseStop: function(event) { 3463 3464 this.resizing = false; 3465 var pr, ista, soffseth, soffsetw, s, left, top, 3466 o = this.options, that = this; 3467 3468 if (this._helper) { 3469 3470 pr = this._proportionallyResizeElements; 3471 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 3472 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; 3473 soffsetw = ista ? 0 : that.sizeDiff.width; 3474 3475 s = { 3476 width: (that.helper.width() - soffsetw), 3477 height: (that.helper.height() - soffseth) 3478 }; 3479 left = (parseInt(that.element.css("left"), 10) + 3480 (that.position.left - that.originalPosition.left)) || null; 3481 top = (parseInt(that.element.css("top"), 10) + 3482 (that.position.top - that.originalPosition.top)) || null; 3483 3484 if (!o.animate) { 3485 this.element.css($.extend(s, { top: top, left: left })); 3486 } 3487 3488 that.helper.height(that.size.height); 3489 that.helper.width(that.size.width); 3490 3491 if (this._helper && !o.animate) { 3492 this._proportionallyResize(); 3493 } 3494 } 3495 3496 $("body").css("cursor", "auto"); 3497 3498 this.element.removeClass("ui-resizable-resizing"); 3499 3500 this._propagate("stop", event); 3501 3502 if (this._helper) { 3503 this.helper.remove(); 3504 } 3505 3506 return false; 3507 3508 }, 3509 3510 _updatePrevProperties: function() { 3511 this.prevPosition = { 3512 top: this.position.top, 3513 left: this.position.left 3514 }; 3515 this.prevSize = { 3516 width: this.size.width, 3517 height: this.size.height 3518 }; 3519 }, 3520 3521 _applyChanges: function() { 3522 var props = {}; 3523 3524 if ( this.position.top !== this.prevPosition.top ) { 3525 props.top = this.position.top + "px"; 3526 } 3527 if ( this.position.left !== this.prevPosition.left ) { 3528 props.left = this.position.left + "px"; 3529 } 3530 if ( this.size.width !== this.prevSize.width ) { 3531 props.width = this.size.width + "px"; 3532 } 3533 if ( this.size.height !== this.prevSize.height ) { 3534 props.height = this.size.height + "px"; 3535 } 3536 3537 this.helper.css( props ); 3538 3539 return props; 3540 }, 3541 3542 _updateVirtualBoundaries: function(forceAspectRatio) { 3543 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 3544 o = this.options; 3545 3546 b = { 3547 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, 3548 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, 3549 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, 3550 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity 3551 }; 3552 3553 if (this._aspectRatio || forceAspectRatio) { 3554 pMinWidth = b.minHeight * this.aspectRatio; 3555 pMinHeight = b.minWidth / this.aspectRatio; 3556 pMaxWidth = b.maxHeight * this.aspectRatio; 3557 pMaxHeight = b.maxWidth / this.aspectRatio; 3558 3559 if (pMinWidth > b.minWidth) { 3560 b.minWidth = pMinWidth; 3561 } 3562 if (pMinHeight > b.minHeight) { 3563 b.minHeight = pMinHeight; 3564 } 3565 if (pMaxWidth < b.maxWidth) { 3566 b.maxWidth = pMaxWidth; 3567 } 3568 if (pMaxHeight < b.maxHeight) { 3569 b.maxHeight = pMaxHeight; 3570 } 3571 } 3572 this._vBoundaries = b; 3573 }, 3574 3575 _updateCache: function(data) { 3576 this.offset = this.helper.offset(); 3577 if (this._isNumber(data.left)) { 3578 this.position.left = data.left; 3579 } 3580 if (this._isNumber(data.top)) { 3581 this.position.top = data.top; 3582 } 3583 if (this._isNumber(data.height)) { 3584 this.size.height = data.height; 3585 } 3586 if (this._isNumber(data.width)) { 3587 this.size.width = data.width; 3588 } 3589 }, 3590 3591 _updateRatio: function( data ) { 3592 3593 var cpos = this.position, 3594 csize = this.size, 3595 a = this.axis; 3596 3597 if (this._isNumber(data.height)) { 3598 data.width = (data.height * this.aspectRatio); 3599 } else if (this._isNumber(data.width)) { 3600 data.height = (data.width / this.aspectRatio); 3601 } 3602 3603 if (a === "sw") { 3604 data.left = cpos.left + (csize.width - data.width); 3605 data.top = null; 3606 } 3607 if (a === "nw") { 3608 data.top = cpos.top + (csize.height - data.height); 3609 data.left = cpos.left + (csize.width - data.width); 3610 } 3611 3612 return data; 3613 }, 3614 3615 _respectSize: function( data ) { 3616 3617 var o = this._vBoundaries, 3618 a = this.axis, 3619 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), 3620 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3621 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), 3622 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 3623 dw = this.originalPosition.left + this.originalSize.width, 3624 dh = this.position.top + this.size.height, 3625 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3626 if (isminw) { 3627 data.width = o.minWidth; 3628 } 3629 if (isminh) { 3630 data.height = o.minHeight; 3631 } 3632 if (ismaxw) { 3633 data.width = o.maxWidth; 3634 } 3635 if (ismaxh) { 3636 data.height = o.maxHeight; 3637 } 3638 3639 if (isminw && cw) { 3640 data.left = dw - o.minWidth; 3641 } 3642 if (ismaxw && cw) { 3643 data.left = dw - o.maxWidth; 3644 } 3645 if (isminh && ch) { 3646 data.top = dh - o.minHeight; 3647 } 3648 if (ismaxh && ch) { 3649 data.top = dh - o.maxHeight; 3650 } 3651 3652 // Fixing jump error on top/left - bug #2330 3653 if (!data.width && !data.height && !data.left && data.top) { 3654 data.top = null; 3655 } else if (!data.width && !data.height && !data.top && data.left) { 3656 data.left = null; 3657 } 3658 3659 return data; 3660 }, 3661 3662 _getPaddingPlusBorderDimensions: function( element ) { 3663 var i = 0, 3664 widths = [], 3665 borders = [ 3666 element.css( "borderTopWidth" ), 3667 element.css( "borderRightWidth" ), 3668 element.css( "borderBottomWidth" ), 3669 element.css( "borderLeftWidth" ) 3670 ], 3671 paddings = [ 3672 element.css( "paddingTop" ), 3673 element.css( "paddingRight" ), 3674 element.css( "paddingBottom" ), 3675 element.css( "paddingLeft" ) 3676 ]; 3677 3678 for ( ; i < 4; i++ ) { 3679 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); 3680 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); 3681 } 3682 3683 return { 3684 height: widths[ 0 ] + widths[ 2 ], 3685 width: widths[ 1 ] + widths[ 3 ] 3686 }; 3687 }, 3688 3689 _proportionallyResize: function() { 3690 3691 if (!this._proportionallyResizeElements.length) { 3692 return; 3693 } 3694 3695 var prel, 3696 i = 0, 3697 element = this.helper || this.element; 3698 3699 for ( ; i < this._proportionallyResizeElements.length; i++) { 3700 3701 prel = this._proportionallyResizeElements[i]; 3702 3703 // TODO: Seems like a bug to cache this.outerDimensions 3704 // considering that we are in a loop. 3705 if (!this.outerDimensions) { 3706 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 3707 } 3708 3709 prel.css({ 3710 height: (element.height() - this.outerDimensions.height) || 0, 3711 width: (element.width() - this.outerDimensions.width) || 0 3712 }); 3713 3714 } 3715 3716 }, 3717 3718 _renderProxy: function() { 3719 3720 var el = this.element, o = this.options; 3721 this.elementOffset = el.offset(); 3722 3723 if (this._helper) { 3724 3725 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 3726 3727 this.helper.addClass(this._helper).css({ 3728 width: this.element.outerWidth() - 1, 3729 height: this.element.outerHeight() - 1, 3730 position: "absolute",
vendor: 1,378 bytes, lines 3731-3778
3731 left: this.elementOffset.left + "px", 3732 top: this.elementOffset.top + "px", 3733 zIndex: ++o.zIndex //TODO: Don't modify option 3734 }); 3735 3736 this.helper 3737 .appendTo("body") 3738 .disableSelection(); 3739 3740 } else { 3741 this.helper = this.element; 3742 } 3743 3744 }, 3745 3746 _change: { 3747 e: function(event, dx) { 3748 return { width: this.originalSize.width + dx }; 3749 }, 3750 w: function(event, dx) { 3751 var cs = this.originalSize, sp = this.originalPosition; 3752 return { left: sp.left + dx, width: cs.width - dx }; 3753 }, 3754 n: function(event, dx, dy) { 3755 var cs = this.originalSize, sp = this.originalPosition; 3756 return { top: sp.top + dy, height: cs.height - dy }; 3757 }, 3758 s: function(event, dx, dy) { 3759 return { height: this.originalSize.height + dy }; 3760 }, 3761 se: function(event, dx, dy) { 3762 return $.extend(this._change.s.apply(this, arguments), 3763 this._change.e.apply(this, [ event, dx, dy ])); 3764 }, 3765 sw: function(event, dx, dy) { 3766 return $.extend(this._change.s.apply(this, arguments), 3767 this._change.w.apply(this, [ event, dx, dy ])); 3768 }, 3769 ne: function(event, dx, dy) { 3770 return $.extend(this._change.n.apply(this, arguments), 3771 this._change.e.apply(this, [ event, dx, dy ])); 3772 }, 3773 nw: function(event, dx, dy) { 3774 return $.extend(this._change.n.apply(this, arguments), 3775 this._change.w.apply(this, [ event, dx, dy ])); 3776 } 3777 }, 3778
vendor: 48,504 bytes, lines 3779-5428
3779 _propagate: function(n, event) { 3780 $.ui.plugin.call(this, n, [ event, this.ui() ]); 3781 (n !== "resize" && this._trigger(n, event, this.ui())); 3782 }, 3783 3784 plugins: {}, 3785 3786 ui: function() { 3787 return { 3788 originalElement: this.originalElement, 3789 element: this.element, 3790 helper: this.helper, 3791 position: this.position, 3792 size: this.size, 3793 originalSize: this.originalSize, 3794 originalPosition: this.originalPosition 3795 }; 3796 } 3797 3798}); 3799 3800/* 3801 * Resizable Extensions 3802 */ 3803 3804$.ui.plugin.add("resizable", "animate", { 3805 3806 stop: function( event ) { 3807 var that = $(this).resizable( "instance" ), 3808 o = that.options, 3809 pr = that._proportionallyResizeElements, 3810 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3811 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, 3812 soffsetw = ista ? 0 : that.sizeDiff.width, 3813 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3814 left = (parseInt(that.element.css("left"), 10) + 3815 (that.position.left - that.originalPosition.left)) || null, 3816 top = (parseInt(that.element.css("top"), 10) + 3817 (that.position.top - that.originalPosition.top)) || null; 3818 3819 that.element.animate( 3820 $.extend(style, top && left ? { top: top, left: left } : {}), { 3821 duration: o.animateDuration, 3822 easing: o.animateEasing, 3823 step: function() { 3824 3825 var data = { 3826 width: parseInt(that.element.css("width"), 10), 3827 height: parseInt(that.element.css("height"), 10), 3828 top: parseInt(that.element.css("top"), 10), 3829 left: parseInt(that.element.css("left"), 10) 3830 }; 3831 3832 if (pr && pr.length) { 3833 $(pr[0]).css({ width: data.width, height: data.height }); 3834 } 3835 3836 // propagating resize, and updating values for each animation step 3837 that._updateCache(data); 3838 that._propagate("resize", event); 3839 3840 } 3841 } 3842 ); 3843 } 3844 3845}); 3846 3847$.ui.plugin.add( "resizable", "containment", { 3848 3849 start: function() { 3850 var element, p, co, ch, cw, width, height, 3851 that = $( this ).resizable( "instance" ), 3852 o = that.options, 3853 el = that.element, 3854 oc = o.containment, 3855 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 3856 3857 if ( !ce ) { 3858 return; 3859 } 3860 3861 that.containerElement = $( ce ); 3862 3863 if ( /document/.test( oc ) || oc === document ) { 3864 that.containerOffset = { 3865 left: 0, 3866 top: 0 3867 }; 3868 that.containerPosition = { 3869 left: 0, 3870 top: 0 3871 }; 3872 3873 that.parentData = { 3874 element: $( document ), 3875 left: 0, 3876 top: 0, 3877 width: $( document ).width(), 3878 height: $( document ).height() || document.body.parentNode.scrollHeight 3879 }; 3880 } else { 3881 element = $( ce ); 3882 p = []; 3883 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { 3884 p[ i ] = that._num( element.css( "padding" + name ) ); 3885 }); 3886 3887 that.containerOffset = element.offset(); 3888 that.containerPosition = element.position(); 3889 that.containerSize = { 3890 height: ( element.innerHeight() - p[ 3 ] ), 3891 width: ( element.innerWidth() - p[ 1 ] ) 3892 }; 3893 3894 co = that.containerOffset; 3895 ch = that.containerSize.height; 3896 cw = that.containerSize.width; 3897 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 3898 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 3899 3900 that.parentData = { 3901 element: ce, 3902 left: co.left, 3903 top: co.top, 3904 width: width, 3905 height: height 3906 }; 3907 } 3908 }, 3909 3910 resize: function( event ) { 3911 var woset, hoset, isParent, isOffsetRelative, 3912 that = $( this ).resizable( "instance" ), 3913 o = that.options, 3914 co = that.containerOffset, 3915 cp = that.position, 3916 pRatio = that._aspectRatio || event.shiftKey, 3917 cop = { 3918 top: 0, 3919 left: 0 3920 }, 3921 ce = that.containerElement, 3922 continueResize = true; 3923 3924 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 3925 cop = co; 3926 } 3927 3928 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 3929 that.size.width = that.size.width + 3930 ( that._helper ? 3931 ( that.position.left - co.left ) : 3932 ( that.position.left - cop.left ) ); 3933 3934 if ( pRatio ) { 3935 that.size.height = that.size.width / that.aspectRatio; 3936 continueResize = false; 3937 } 3938 that.position.left = o.helper ? co.left : 0; 3939 } 3940 3941 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 3942 that.size.height = that.size.height + 3943 ( that._helper ? 3944 ( that.position.top - co.top ) : 3945 that.position.top ); 3946 3947 if ( pRatio ) { 3948 that.size.width = that.size.height * that.aspectRatio; 3949 continueResize = false; 3950 } 3951 that.position.top = that._helper ? co.top : 0; 3952 } 3953 3954 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 3955 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 3956 3957 if ( isParent && isOffsetRelative ) { 3958 that.offset.left = that.parentData.left + that.position.left; 3959 that.offset.top = that.parentData.top + that.position.top; 3960 } else { 3961 that.offset.left = that.element.offset().left; 3962 that.offset.top = that.element.offset().top; 3963 } 3964 3965 woset = Math.abs( that.sizeDiff.width + 3966 (that._helper ? 3967 that.offset.left - cop.left : 3968 (that.offset.left - co.left)) ); 3969 3970 hoset = Math.abs( that.sizeDiff.height + 3971 (that._helper ? 3972 that.offset.top - cop.top : 3973 (that.offset.top - co.top)) ); 3974 3975 if ( woset + that.size.width >= that.parentData.width ) { 3976 that.size.width = that.parentData.width - woset; 3977 if ( pRatio ) { 3978 that.size.height = that.size.width / that.aspectRatio; 3979 continueResize = false; 3980 } 3981 } 3982 3983 if ( hoset + that.size.height >= that.parentData.height ) { 3984 that.size.height = that.parentData.height - hoset; 3985 if ( pRatio ) { 3986 that.size.width = that.size.height * that.aspectRatio; 3987 continueResize = false; 3988 } 3989 } 3990 3991 if ( !continueResize ){ 3992 that.position.left = that.prevPosition.left; 3993 that.position.top = that.prevPosition.top; 3994 that.size.width = that.prevSize.width; 3995 that.size.height = that.prevSize.height; 3996 } 3997 }, 3998 3999 stop: function() { 4000 var that = $( this ).resizable( "instance" ), 4001 o = that.options, 4002 co = that.containerOffset, 4003 cop = that.containerPosition, 4004 ce = that.containerElement, 4005 helper = $( that.helper ), 4006 ho = helper.offset(), 4007 w = helper.outerWidth() - that.sizeDiff.width, 4008 h = helper.outerHeight() - that.sizeDiff.height; 4009 4010 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 4011 $( this ).css({ 4012 left: ho.left - cop.left - co.left, 4013 width: w, 4014 height: h 4015 }); 4016 } 4017 4018 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 4019 $( this ).css({ 4020 left: ho.left - cop.left - co.left, 4021 width: w, 4022 height: h 4023 }); 4024 } 4025 } 4026}); 4027 4028$.ui.plugin.add("resizable", "alsoResize", { 4029 4030 start: function() { 4031 var that = $(this).resizable( "instance" ), 4032 o = that.options, 4033 _store = function(exp) { 4034 $(exp).each(function() { 4035 var el = $(this); 4036 el.data("ui-resizable-alsoresize", { 4037 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 4038 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 4039 }); 4040 }); 4041 }; 4042 4043 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 4044 if (o.alsoResize.length) { 4045 o.alsoResize = o.alsoResize[0]; 4046 _store(o.alsoResize); 4047 } else { 4048 $.each(o.alsoResize, function(exp) { 4049 _store(exp); 4050 }); 4051 } 4052 } else { 4053 _store(o.alsoResize); 4054 } 4055 }, 4056 4057 resize: function(event, ui) { 4058 var that = $(this).resizable( "instance" ), 4059 o = that.options, 4060 os = that.originalSize, 4061 op = that.originalPosition, 4062 delta = { 4063 height: (that.size.height - os.height) || 0, 4064 width: (that.size.width - os.width) || 0, 4065 top: (that.position.top - op.top) || 0, 4066 left: (that.position.left - op.left) || 0 4067 }, 4068 4069 _alsoResize = function(exp, c) { 4070 $(exp).each(function() { 4071 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 4072 css = c && c.length ? 4073 c : 4074 el.parents(ui.originalElement[0]).length ? 4075 [ "width", "height" ] : 4076 [ "width", "height", "top", "left" ]; 4077 4078 $.each(css, function(i, prop) { 4079 var sum = (start[prop] || 0) + (delta[prop] || 0); 4080 if (sum && sum >= 0) { 4081 style[prop] = sum || null; 4082 } 4083 }); 4084 4085 el.css(style); 4086 }); 4087 }; 4088 4089 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 4090 $.each(o.alsoResize, function(exp, c) { 4091 _alsoResize(exp, c); 4092 }); 4093 } else { 4094 _alsoResize(o.alsoResize); 4095 } 4096 }, 4097 4098 stop: function() { 4099 $(this).removeData("resizable-alsoresize"); 4100 } 4101}); 4102 4103$.ui.plugin.add("resizable", "ghost", { 4104 4105 start: function() { 4106 4107 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; 4108 4109 that.ghost = that.originalElement.clone(); 4110 that.ghost 4111 .css({ 4112 opacity: 0.25, 4113 display: "block", 4114 position: "relative", 4115 height: cs.height, 4116 width: cs.width, 4117 margin: 0, 4118 left: 0, 4119 top: 0 4120 }) 4121 .addClass("ui-resizable-ghost") 4122 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 4123 4124 that.ghost.appendTo(that.helper); 4125 4126 }, 4127 4128 resize: function() { 4129 var that = $(this).resizable( "instance" ); 4130 if (that.ghost) { 4131 that.ghost.css({ 4132 position: "relative", 4133 height: that.size.height, 4134 width: that.size.width 4135 }); 4136 } 4137 }, 4138 4139 stop: function() { 4140 var that = $(this).resizable( "instance" ); 4141 if (that.ghost && that.helper) { 4142 that.helper.get(0).removeChild(that.ghost.get(0)); 4143 } 4144 } 4145 4146}); 4147 4148$.ui.plugin.add("resizable", "grid", { 4149 4150 resize: function() { 4151 var outerDimensions, 4152 that = $(this).resizable( "instance" ), 4153 o = that.options, 4154 cs = that.size, 4155 os = that.originalSize, 4156 op = that.originalPosition, 4157 a = that.axis, 4158 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4159 gridX = (grid[0] || 1), 4160 gridY = (grid[1] || 1), 4161 ox = Math.round((cs.width - os.width) / gridX) * gridX, 4162 oy = Math.round((cs.height - os.height) / gridY) * gridY, 4163 newWidth = os.width + ox, 4164 newHeight = os.height + oy, 4165 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 4166 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 4167 isMinWidth = o.minWidth && (o.minWidth > newWidth), 4168 isMinHeight = o.minHeight && (o.minHeight > newHeight); 4169 4170 o.grid = grid; 4171 4172 if (isMinWidth) { 4173 newWidth += gridX; 4174 } 4175 if (isMinHeight) { 4176 newHeight += gridY; 4177 } 4178 if (isMaxWidth) { 4179 newWidth -= gridX; 4180 } 4181 if (isMaxHeight) { 4182 newHeight -= gridY; 4183 } 4184 4185 if (/^(se|s|e)$/.test(a)) { 4186 that.size.width = newWidth; 4187 that.size.height = newHeight; 4188 } else if (/^(ne)$/.test(a)) { 4189 that.size.width = newWidth; 4190 that.size.height = newHeight; 4191 that.position.top = op.top - oy; 4192 } else if (/^(sw)$/.test(a)) { 4193 that.size.width = newWidth; 4194 that.size.height = newHeight; 4195 that.position.left = op.left - ox; 4196 } else { 4197 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { 4198 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4199 } 4200 4201 if ( newHeight - gridY > 0 ) { 4202 that.size.height = newHeight; 4203 that.position.top = op.top - oy; 4204 } else { 4205 newHeight = gridY - outerDimensions.height; 4206 that.size.height = newHeight; 4207 that.position.top = op.top + os.height - newHeight; 4208 } 4209 if ( newWidth - gridX > 0 ) { 4210 that.size.width = newWidth; 4211 that.position.left = op.left - ox; 4212 } else { 4213 newWidth = gridY - outerDimensions.height; 4214 that.size.width = newWidth; 4215 that.position.left = op.left + os.width - newWidth; 4216 } 4217 } 4218 } 4219 4220}); 4221 4222var resizable = $.ui.resizable; 4223 4224 4225/*! 4226 * jQuery UI Selectable 1.11.2 4227 * http://jqueryui.com 4228 * 4229 * Copyright 2014 jQuery Foundation and other contributors 4230 * Released under the MIT license. 4231 * http://jquery.org/license 4232 * 4233 * http://api.jqueryui.com/selectable/ 4234 */ 4235 4236 4237var selectable = $.widget("ui.selectable", $.ui.mouse, { 4238 version: "1.11.2", 4239 options: { 4240 appendTo: "body", 4241 autoRefresh: true, 4242 distance: 0, 4243 filter: "*", 4244 tolerance: "touch", 4245 4246 // callbacks 4247 selected: null, 4248 selecting: null, 4249 start: null, 4250 stop: null, 4251 unselected: null, 4252 unselecting: null 4253 }, 4254 _create: function() { 4255 var selectees, 4256 that = this; 4257 4258 this.element.addClass("ui-selectable"); 4259 4260 this.dragged = false; 4261 4262 // cache selectee children based on filter 4263 this.refresh = function() { 4264 selectees = $(that.options.filter, that.element[0]); 4265 selectees.addClass("ui-selectee"); 4266 selectees.each(function() { 4267 var $this = $(this), 4268 pos = $this.offset(); 4269 $.data(this, "selectable-item", { 4270 element: this, 4271 $element: $this, 4272 left: pos.left, 4273 top: pos.top, 4274 right: pos.left + $this.outerWidth(), 4275 bottom: pos.top + $this.outerHeight(), 4276 startselected: false, 4277 selected: $this.hasClass("ui-selected"), 4278 selecting: $this.hasClass("ui-selecting"), 4279 unselecting: $this.hasClass("ui-unselecting") 4280 }); 4281 }); 4282 }; 4283 this.refresh(); 4284 4285 this.selectees = selectees.addClass("ui-selectee"); 4286 4287 this._mouseInit(); 4288 4289 this.helper = $("<div class='ui-selectable-helper'></div>"); 4290 }, 4291 4292 _destroy: function() { 4293 this.selectees 4294 .removeClass("ui-selectee") 4295 .removeData("selectable-item"); 4296 this.element 4297 .removeClass("ui-selectable ui-selectable-disabled"); 4298 this._mouseDestroy(); 4299 }, 4300 4301 _mouseStart: function(event) { 4302 var that = this, 4303 options = this.options; 4304 4305 this.opos = [ event.pageX, event.pageY ]; 4306 4307 if (this.options.disabled) { 4308 return; 4309 } 4310 4311 this.selectees = $(options.filter, this.element[0]); 4312 4313 this._trigger("start", event); 4314 4315 $(options.appendTo).append(this.helper); 4316 // position helper (lasso) 4317 this.helper.css({ 4318 "left": event.pageX, 4319 "top": event.pageY, 4320 "width": 0, 4321 "height": 0 4322 }); 4323 4324 if (options.autoRefresh) { 4325 this.refresh(); 4326 } 4327 4328 this.selectees.filter(".ui-selected").each(function() { 4329 var selectee = $.data(this, "selectable-item"); 4330 selectee.startselected = true; 4331 if (!event.metaKey && !event.ctrlKey) { 4332 selectee.$element.removeClass("ui-selected"); 4333 selectee.selected = false; 4334 selectee.$element.addClass("ui-unselecting"); 4335 selectee.unselecting = true; 4336 // selectable UNSELECTING callback 4337 that._trigger("unselecting", event, { 4338 unselecting: selectee.element 4339 }); 4340 } 4341 }); 4342 4343 $(event.target).parents().addBack().each(function() { 4344 var doSelect, 4345 selectee = $.data(this, "selectable-item"); 4346 if (selectee) { 4347 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 4348 selectee.$element 4349 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 4350 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 4351 selectee.unselecting = !doSelect; 4352 selectee.selecting = doSelect; 4353 selectee.selected = doSelect; 4354 // selectable (UN)SELECTING callback 4355 if (doSelect) { 4356 that._trigger("selecting", event, { 4357 selecting: selectee.element 4358 }); 4359 } else { 4360 that._trigger("unselecting", event, { 4361 unselecting: selectee.element 4362 }); 4363 } 4364 return false; 4365 } 4366 }); 4367 4368 }, 4369 4370 _mouseDrag: function(event) { 4371 4372 this.dragged = true; 4373 4374 if (this.options.disabled) { 4375 return; 4376 } 4377 4378 var tmp, 4379 that = this, 4380 options = this.options, 4381 x1 = this.opos[0], 4382 y1 = this.opos[1], 4383 x2 = event.pageX, 4384 y2 = event.pageY; 4385 4386 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 4387 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 4388 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 4389 4390 this.selectees.each(function() { 4391 var selectee = $.data(this, "selectable-item"), 4392 hit = false; 4393 4394 //prevent helper from being selected if appendTo: selectable 4395 if (!selectee || selectee.element === that.element[0]) { 4396 return; 4397 } 4398 4399 if (options.tolerance === "touch") { 4400 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 4401 } else if (options.tolerance === "fit") { 4402 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 4403 } 4404 4405 if (hit) { 4406 // SELECT 4407 if (selectee.selected) { 4408 selectee.$element.removeClass("ui-selected"); 4409 selectee.selected = false; 4410 } 4411 if (selectee.unselecting) { 4412 selectee.$element.removeClass("ui-unselecting"); 4413 selectee.unselecting = false; 4414 } 4415 if (!selectee.selecting) { 4416 selectee.$element.addClass("ui-selecting"); 4417 selectee.selecting = true; 4418 // selectable SELECTING callback 4419 that._trigger("selecting", event, { 4420 selecting: selectee.element 4421 }); 4422 } 4423 } else { 4424 // UNSELECT 4425 if (selectee.selecting) { 4426 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 4427 selectee.$element.removeClass("ui-selecting"); 4428 selectee.selecting = false; 4429 selectee.$element.addClass("ui-selected"); 4430 selectee.selected = true; 4431 } else { 4432 selectee.$element.removeClass("ui-selecting"); 4433 selectee.selecting = false; 4434 if (selectee.startselected) { 4435 selectee.$element.addClass("ui-unselecting"); 4436 selectee.unselecting = true; 4437 } 4438 // selectable UNSELECTING callback 4439 that._trigger("unselecting", event, { 4440 unselecting: selectee.element 4441 }); 4442 } 4443 } 4444 if (selectee.selected) { 4445 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 4446 selectee.$element.removeClass("ui-selected"); 4447 selectee.selected = false; 4448 4449 selectee.$element.addClass("ui-unselecting"); 4450 selectee.unselecting = true; 4451 // selectable UNSELECTING callback 4452 that._trigger("unselecting", event, { 4453 unselecting: selectee.element 4454 }); 4455 } 4456 } 4457 } 4458 }); 4459 4460 return false; 4461 }, 4462 4463 _mouseStop: function(event) { 4464 var that = this; 4465 4466 this.dragged = false; 4467 4468 $(".ui-unselecting", this.element[0]).each(function() { 4469 var selectee = $.data(this, "selectable-item"); 4470 selectee.$element.removeClass("ui-unselecting"); 4471 selectee.unselecting = false; 4472 selectee.startselected = false; 4473 that._trigger("unselected", event, { 4474 unselected: selectee.element 4475 }); 4476 }); 4477 $(".ui-selecting", this.element[0]).each(function() { 4478 var selectee = $.data(this, "selectable-item"); 4479 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 4480 selectee.selecting = false; 4481 selectee.selected = true; 4482 selectee.startselected = true; 4483 that._trigger("selected", event, { 4484 selected: selectee.element 4485 }); 4486 }); 4487 this._trigger("stop", event); 4488 4489 this.helper.remove(); 4490 4491 return false; 4492 } 4493 4494}); 4495 4496 4497/*! 4498 * jQuery UI Sortable 1.11.2 4499 * http://jqueryui.com 4500 * 4501 * Copyright 2014 jQuery Foundation and other contributors 4502 * Released under the MIT license. 4503 * http://jquery.org/license 4504 * 4505 * http://api.jqueryui.com/sortable/ 4506 */ 4507 4508 4509var sortable = $.widget("ui.sortable", $.ui.mouse, { 4510 version: "1.11.2", 4511 widgetEventPrefix: "sort", 4512 ready: false, 4513 options: { 4514 appendTo: "parent", 4515 axis: false, 4516 connectWith: false, 4517 containment: false, 4518 cursor: "auto", 4519 cursorAt: false, 4520 dropOnEmpty: true, 4521 forcePlaceholderSize: false, 4522 forceHelperSize: false, 4523 grid: false, 4524 handle: false, 4525 helper: "original", 4526 items: "> *", 4527 opacity: false, 4528 placeholder: false, 4529 revert: false, 4530 scroll: true, 4531 scrollSensitivity: 20, 4532 scrollSpeed: 20, 4533 scope: "default", 4534 tolerance: "intersect", 4535 zIndex: 1000, 4536 4537 // callbacks 4538 activate: null, 4539 beforeStop: null, 4540 change: null, 4541 deactivate: null, 4542 out: null, 4543 over: null, 4544 receive: null, 4545 remove: null, 4546 sort: null, 4547 start: null, 4548 stop: null, 4549 update: null 4550 }, 4551 4552 _isOverAxis: function( x, reference, size ) { 4553 return ( x >= reference ) && ( x < ( reference + size ) ); 4554 }, 4555 4556 _isFloating: function( item ) { 4557 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 4558 }, 4559 4560 _create: function() { 4561 4562 var o = this.options; 4563 this.containerCache = {}; 4564 this.element.addClass("ui-sortable"); 4565 4566 //Get the items 4567 this.refresh(); 4568 4569 //Let's determine if the items are being displayed horizontally 4570 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false; 4571 4572 //Let's determine the parent's offset 4573 this.offset = this.element.offset(); 4574 4575 //Initialize mouse events for interaction 4576 this._mouseInit(); 4577 4578 this._setHandleClassName(); 4579 4580 //We're ready to go 4581 this.ready = true; 4582 4583 }, 4584 4585 _setOption: function( key, value ) { 4586 this._super( key, value ); 4587 4588 if ( key === "handle" ) { 4589 this._setHandleClassName(); 4590 } 4591 }, 4592 4593 _setHandleClassName: function() { 4594 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); 4595 $.each( this.items, function() { 4596 ( this.instance.options.handle ? 4597 this.item.find( this.instance.options.handle ) : this.item ) 4598 .addClass( "ui-sortable-handle" ); 4599 }); 4600 }, 4601 4602 _destroy: function() { 4603 this.element 4604 .removeClass( "ui-sortable ui-sortable-disabled" ) 4605 .find( ".ui-sortable-handle" ) 4606 .removeClass( "ui-sortable-handle" ); 4607 this._mouseDestroy(); 4608 4609 for ( var i = this.items.length - 1; i >= 0; i-- ) { 4610 this.items[i].item.removeData(this.widgetName + "-item"); 4611 } 4612 4613 return this; 4614 }, 4615 4616 _mouseCapture: function(event, overrideHandle) { 4617 var currentItem = null, 4618 validHandle = false, 4619 that = this; 4620 4621 if (this.reverting) { 4622 return false; 4623 } 4624 4625 if(this.options.disabled || this.options.type === "static") { 4626 return false; 4627 } 4628 4629 //We have to refresh the items data once first 4630 this._refreshItems(event); 4631 4632 //Find out if the clicked node (or one of its parents) is a actual item in this.items 4633 $(event.target).parents().each(function() { 4634 if($.data(this, that.widgetName + "-item") === that) { 4635 currentItem = $(this); 4636 return false; 4637 } 4638 }); 4639 if($.data(event.target, that.widgetName + "-item") === that) { 4640 currentItem = $(event.target); 4641 } 4642 4643 if(!currentItem) { 4644 return false; 4645 } 4646 if(this.options.handle && !overrideHandle) { 4647 $(this.options.handle, currentItem).find("*").addBack().each(function() { 4648 if(this === event.target) { 4649 validHandle = true; 4650 } 4651 }); 4652 if(!validHandle) { 4653 return false; 4654 } 4655 } 4656 4657 this.currentItem = currentItem; 4658 this._removeCurrentsFromItems(); 4659 return true; 4660 4661 }, 4662 4663 _mouseStart: function(event, overrideHandle, noActivation) { 4664 4665 var i, body, 4666 o = this.options; 4667 4668 this.currentContainer = this; 4669 4670 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 4671 this.refreshPositions(); 4672 4673 //Create and append the visible helper 4674 this.helper = this._createHelper(event); 4675 4676 //Cache the helper size 4677 this._cacheHelperProportions(); 4678 4679 /* 4680 * - Position generation - 4681 * This block generates everything position related - it's the core of draggables. 4682 */ 4683 4684 //Cache the margins of the original element 4685 this._cacheMargins(); 4686 4687 //Get the next scrolling parent 4688 this.scrollParent = this.helper.scrollParent(); 4689 4690 //The element's absolute position on the page minus margins 4691 this.offset = this.currentItem.offset(); 4692 this.offset = { 4693 top: this.offset.top - this.margins.top, 4694 left: this.offset.left - this.margins.left 4695 }; 4696 4697 $.extend(this.offset, { 4698 click: { //Where the click happened, relative to the element 4699 left: event.pageX - this.offset.left, 4700 top: event.pageY - this.offset.top 4701 }, 4702 parent: this._getParentOffset(), 4703 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 4704 }); 4705 4706 // Only after we got the offset, we can change the helper's position to absolute 4707 // TODO: Still need to figure out a way to make relative sorting possible 4708 this.helper.css("position", "absolute"); 4709 this.cssPosition = this.helper.css("position"); 4710 4711 //Generate the original position 4712 this.originalPosition = this._generatePosition(event); 4713 this.originalPageX = event.pageX; 4714 this.originalPageY = event.pageY; 4715 4716 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 4717 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 4718 4719 //Cache the former DOM position 4720 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 4721 4722 //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 4723 if(this.helper[0] !== this.currentItem[0]) { 4724 this.currentItem.hide(); 4725 } 4726 4727 //Create the placeholder 4728 this._createPlaceholder(); 4729 4730 //Set a containment if given in the options 4731 if(o.containment) { 4732 this._setContainment(); 4733 } 4734 4735 if( o.cursor && o.cursor !== "auto" ) { // cursor option 4736 body = this.document.find( "body" ); 4737 4738 // support: IE 4739 this.storedCursor = body.css( "cursor" ); 4740 body.css( "cursor", o.cursor ); 4741 4742 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 4743 } 4744 4745 if(o.opacity) { // opacity option 4746 if (this.helper.css("opacity")) { 4747 this._storedOpacity = this.helper.css("opacity"); 4748 } 4749 this.helper.css("opacity", o.opacity); 4750 } 4751 4752 if(o.zIndex) { // zIndex option 4753 if (this.helper.css("zIndex")) { 4754 this._storedZIndex = this.helper.css("zIndex"); 4755 } 4756 this.helper.css("zIndex", o.zIndex); 4757 } 4758 4759 //Prepare scrolling 4760 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4761 this.overflowOffset = this.scrollParent.offset(); 4762 } 4763 4764 //Call callbacks 4765 this._trigger("start", event, this._uiHash()); 4766 4767 //Recache the helper size 4768 if(!this._preserveHelperProportions) { 4769 this._cacheHelperProportions(); 4770 } 4771 4772 4773 //Post "activate" events to possible containers 4774 if( !noActivation ) { 4775 for ( i = this.containers.length - 1; i >= 0; i-- ) { 4776 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 4777 } 4778 } 4779 4780 //Prepare possible droppables 4781 if($.ui.ddmanager) { 4782 $.ui.ddmanager.current = this; 4783 } 4784 4785 if ($.ui.ddmanager && !o.dropBehaviour) { 4786 $.ui.ddmanager.prepareOffsets(this, event); 4787 } 4788 4789 this.dragging = true; 4790 4791 this.helper.addClass("ui-sortable-helper"); 4792 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 4793 return true; 4794 4795 }, 4796 4797 _mouseDrag: function(event) { 4798 var i, item, itemElement, intersection, 4799 o = this.options, 4800 scrolled = false; 4801 4802 //Compute the helpers position 4803 this.position = this._generatePosition(event); 4804 this.positionAbs = this._convertPositionTo("absolute"); 4805 4806 if (!this.lastPositionAbs) { 4807 this.lastPositionAbs = this.positionAbs; 4808 } 4809 4810 //Do scrolling 4811 if(this.options.scroll) { 4812 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4813 4814 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 4815 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 4816 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 4817 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 4818 } 4819 4820 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 4821 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 4822 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 4823 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 4824 } 4825 4826 } else { 4827 4828 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 4829 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4830 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 4831 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4832 } 4833 4834 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 4835 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4836 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 4837 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4838 } 4839 4840 } 4841 4842 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 4843 $.ui.ddmanager.prepareOffsets(this, event); 4844 } 4845 } 4846 4847 //Regenerate the absolute position used for position checks 4848 this.positionAbs = this._convertPositionTo("absolute"); 4849 4850 //Set the helper position 4851 if(!this.options.axis || this.options.axis !== "y") { 4852 this.helper[0].style.left = this.position.left+"px"; 4853 } 4854 if(!this.options.axis || this.options.axis !== "x") { 4855 this.helper[0].style.top = this.position.top+"px"; 4856 } 4857 4858 //Rearrange 4859 for (i = this.items.length - 1; i >= 0; i--) { 4860 4861 //Cache variables and intersection, continue if no intersection 4862 item = this.items[i]; 4863 itemElement = item.item[0]; 4864 intersection = this._intersectsWithPointer(item); 4865 if (!intersection) { 4866 continue; 4867 } 4868 4869 // Only put the placeholder inside the current Container, skip all 4870 // items from other containers. This works because when moving 4871 // an item from one container to another the 4872 // currentContainer is switched before the placeholder is moved. 4873 // 4874 // Without this, moving items in "sub-sortables" can cause 4875 // the placeholder to jitter between the outer and inner container. 4876 if (item.instance !== this.currentContainer) { 4877 continue; 4878 } 4879 4880 // cannot intersect with itself 4881 // no useless actions that have been done before 4882 // no action if the item moved is the parent of the item checked 4883 if (itemElement !== this.currentItem[0] && 4884 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 4885 !$.contains(this.placeholder[0], itemElement) && 4886 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 4887 ) { 4888 4889 this.direction = intersection === 1 ? "down" : "up"; 4890 4891 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 4892 this._rearrange(event, item); 4893 } else { 4894 break; 4895 } 4896 4897 this._trigger("change", event, this._uiHash()); 4898 break; 4899 } 4900 } 4901 4902 //Post events to containers 4903 this._contactContainers(event); 4904 4905 //Interconnect with droppables 4906 if($.ui.ddmanager) { 4907 $.ui.ddmanager.drag(this, event); 4908 } 4909 4910 //Call callbacks 4911 this._trigger("sort", event, this._uiHash()); 4912 4913 this.lastPositionAbs = this.positionAbs; 4914 return false; 4915 4916 }, 4917 4918 _mouseStop: function(event, noPropagation) { 4919 4920 if(!event) { 4921 return; 4922 } 4923 4924 //If we are using droppables, inform the manager about the drop 4925 if ($.ui.ddmanager && !this.options.dropBehaviour) { 4926 $.ui.ddmanager.drop(this, event); 4927 } 4928 4929 if(this.options.revert) { 4930 var that = this, 4931 cur = this.placeholder.offset(), 4932 axis = this.options.axis, 4933 animation = {}; 4934 4935 if ( !axis || axis === "x" ) { 4936 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 4937 } 4938 if ( !axis || axis === "y" ) { 4939 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 4940 } 4941 this.reverting = true; 4942 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 4943 that._clear(event); 4944 }); 4945 } else { 4946 this._clear(event, noPropagation); 4947 } 4948 4949 return false; 4950 4951 }, 4952 4953 cancel: function() { 4954 4955 if(this.dragging) { 4956 4957 this._mouseUp({ target: null }); 4958 4959 if(this.options.helper === "original") { 4960 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4961 } else { 4962 this.currentItem.show(); 4963 } 4964 4965 //Post deactivating events to containers 4966 for (var i = this.containers.length - 1; i >= 0; i--){ 4967 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4968 if(this.containers[i].containerCache.over) { 4969 this.containers[i]._trigger("out", null, this._uiHash(this)); 4970 this.containers[i].containerCache.over = 0; 4971 } 4972 } 4973 4974 } 4975 4976 if (this.placeholder) { 4977 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4978 if(this.placeholder[0].parentNode) { 4979 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4980 } 4981 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 4982 this.helper.remove(); 4983 } 4984 4985 $.extend(this, { 4986 helper: null, 4987 dragging: false, 4988 reverting: false, 4989 _noFinalSort: null 4990 }); 4991 4992 if(this.domPosition.prev) { 4993 $(this.domPosition.prev).after(this.currentItem); 4994 } else { 4995 $(this.domPosition.parent).prepend(this.currentItem); 4996 } 4997 } 4998 4999 return this; 5000 5001 }, 5002 5003 serialize: function(o) { 5004 5005 var items = this._getItemsAsjQuery(o && o.connected), 5006 str = []; 5007 o = o || {}; 5008 5009 $(items).each(function() { 5010 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 5011 if (res) { 5012 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 5013 } 5014 }); 5015 5016 if(!str.length && o.key) { 5017 str.push(o.key + "="); 5018 } 5019 5020 return str.join("&"); 5021 5022 }, 5023 5024 toArray: function(o) { 5025 5026 var items = this._getItemsAsjQuery(o && o.connected), 5027 ret = []; 5028 5029 o = o || {}; 5030 5031 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 5032 return ret; 5033 5034 }, 5035 5036 /* Be careful with the following core functions */ 5037 _intersectsWith: function(item) { 5038 5039 var x1 = this.positionAbs.left, 5040 x2 = x1 + this.helperProportions.width, 5041 y1 = this.positionAbs.top, 5042 y2 = y1 + this.helperProportions.height, 5043 l = item.left, 5044 r = l + item.width, 5045 t = item.top, 5046 b = t + item.height, 5047 dyClick = this.offset.click.top, 5048 dxClick = this.offset.click.left, 5049 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 5050 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 5051 isOverElement = isOverElementHeight && isOverElementWidth; 5052 5053 if ( this.options.tolerance === "pointer" || 5054 this.options.forcePointerForContainers || 5055 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 5056 ) { 5057 return isOverElement; 5058 } else { 5059 5060 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 5061 x2 - (this.helperProportions.width / 2) < r && // Left Half 5062 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 5063 y2 - (this.helperProportions.height / 2) < b ); // Top Half 5064 5065 } 5066 }, 5067 5068 _intersectsWithPointer: function(item) { 5069 5070 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 5071 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 5072 isOverElement = isOverElementHeight && isOverElementWidth, 5073 verticalDirection = this._getDragVerticalDirection(), 5074 horizontalDirection = this._getDragHorizontalDirection(); 5075 5076 if (!isOverElement) { 5077 return false; 5078 } 5079 5080 return this.floating ? 5081 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 5082 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 5083 5084 }, 5085 5086 _intersectsWithSides: function(item) { 5087 5088 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 5089 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 5090 verticalDirection = this._getDragVerticalDirection(), 5091 horizontalDirection = this._getDragHorizontalDirection(); 5092 5093 if (this.floating && horizontalDirection) { 5094 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 5095 } else { 5096 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 5097 } 5098 5099 }, 5100 5101 _getDragVerticalDirection: function() { 5102 var delta = this.positionAbs.top - this.lastPositionAbs.top; 5103 return delta !== 0 && (delta > 0 ? "down" : "up"); 5104 }, 5105 5106 _getDragHorizontalDirection: function() { 5107 var delta = this.positionAbs.left - this.lastPositionAbs.left; 5108 return delta !== 0 && (delta > 0 ? "right" : "left"); 5109 }, 5110 5111 refresh: function(event) { 5112 this._refreshItems(event); 5113 this._setHandleClassName(); 5114 this.refreshPositions(); 5115 return this; 5116 }, 5117 5118 _connectWith: function() { 5119 var options = this.options; 5120 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 5121 }, 5122 5123 _getItemsAsjQuery: function(connected) { 5124 5125 var i, j, cur, inst, 5126 items = [], 5127 queries = [], 5128 connectWith = this._connectWith(); 5129 5130 if(connectWith && connected) { 5131 for (i = connectWith.length - 1; i >= 0; i--){ 5132 cur = $(connectWith[i]); 5133 for ( j = cur.length - 1; j >= 0; j--){ 5134 inst = $.data(cur[j], this.widgetFullName); 5135 if(inst && inst !== this && !inst.options.disabled) { 5136 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]); 5137 } 5138 } 5139 } 5140 } 5141 5142 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]); 5143 5144 function addItems() { 5145 items.push( this ); 5146 } 5147 for (i = queries.length - 1; i >= 0; i--){ 5148 queries[i][0].each( addItems ); 5149 } 5150 5151 return $(items); 5152 5153 }, 5154 5155 _removeCurrentsFromItems: function() { 5156 5157 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 5158 5159 this.items = $.grep(this.items, function (item) { 5160 for (var j=0; j < list.length; j++) { 5161 if(list[j] === item.item[0]) { 5162 return false; 5163 } 5164 } 5165 return true; 5166 }); 5167 5168 }, 5169 5170 _refreshItems: function(event) { 5171 5172 this.items = []; 5173 this.containers = [this]; 5174 5175 var i, j, cur, inst, targetData, _queries, item, queriesLength, 5176 items = this.items, 5177 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 5178 connectWith = this._connectWith(); 5179 5180 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 5181 for (i = connectWith.length - 1; i >= 0; i--){ 5182 cur = $(connectWith[i]); 5183 for (j = cur.length - 1; j >= 0; j--){ 5184 inst = $.data(cur[j], this.widgetFullName); 5185 if(inst && inst !== this && !inst.options.disabled) { 5186 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 5187 this.containers.push(inst); 5188 } 5189 } 5190 } 5191 } 5192 5193 for (i = queries.length - 1; i >= 0; i--) { 5194 targetData = queries[i][1]; 5195 _queries = queries[i][0]; 5196 5197 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 5198 item = $(_queries[j]); 5199 5200 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 5201 5202 items.push({ 5203 item: item, 5204 instance: targetData, 5205 width: 0, height: 0, 5206 left: 0, top: 0 5207 }); 5208 } 5209 } 5210 5211 }, 5212 5213 refreshPositions: function(fast) { 5214 5215 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 5216 if(this.offsetParent && this.helper) { 5217 this.offset.parent = this._getParentOffset(); 5218 } 5219 5220 var i, item, t, p; 5221 5222 for (i = this.items.length - 1; i >= 0; i--){ 5223 item = this.items[i]; 5224 5225 //We ignore calculating positions of all connected containers when we're not over them 5226 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 5227 continue; 5228 } 5229 5230 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 5231 5232 if (!fast) { 5233 item.width = t.outerWidth(); 5234 item.height = t.outerHeight(); 5235 } 5236 5237 p = t.offset(); 5238 item.left = p.left; 5239 item.top = p.top; 5240 } 5241 5242 if(this.options.custom && this.options.custom.refreshContainers) { 5243 this.options.custom.refreshContainers.call(this); 5244 } else { 5245 for (i = this.containers.length - 1; i >= 0; i--){ 5246 p = this.containers[i].element.offset(); 5247 this.containers[i].containerCache.left = p.left; 5248 this.containers[i].containerCache.top = p.top; 5249 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 5250 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 5251 } 5252 } 5253 5254 return this; 5255 }, 5256 5257 _createPlaceholder: function(that) { 5258 that = that || this; 5259 var className, 5260 o = that.options; 5261 5262 if(!o.placeholder || o.placeholder.constructor === String) { 5263 className = o.placeholder; 5264 o.placeholder = { 5265 element: function() { 5266 5267 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 5268 element = $( "<" + nodeName + ">", that.document[0] ) 5269 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 5270 .removeClass("ui-sortable-helper"); 5271 5272 if ( nodeName === "tr" ) { 5273 that.currentItem.children().each(function() { 5274 $( "<td> </td>", that.document[0] ) 5275 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 5276 .appendTo( element ); 5277 }); 5278 } else if ( nodeName === "img" ) { 5279 element.attr( "src", that.currentItem.attr( "src" ) ); 5280 } 5281 5282 if ( !className ) { 5283 element.css( "visibility", "hidden" ); 5284 } 5285 5286 return element; 5287 }, 5288 update: function(container, p) { 5289 5290 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 5291 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 5292 if(className && !o.forcePlaceholderSize) { 5293 return; 5294 } 5295 5296 //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 5297 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 5298 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 5299 } 5300 }; 5301 } 5302 5303 //Create the placeholder 5304 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 5305 5306 //Append it after the actual current item 5307 that.currentItem.after(that.placeholder); 5308 5309 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 5310 o.placeholder.update(that, that.placeholder); 5311 5312 }, 5313 5314 _contactContainers: function(event) { 5315 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, 5316 innermostContainer = null, 5317 innermostIndex = null; 5318 5319 // get innermost container that intersects with item 5320 for (i = this.containers.length - 1; i >= 0; i--) { 5321 5322 // never consider a container that's located within the item itself 5323 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 5324 continue; 5325 } 5326 5327 if(this._intersectsWith(this.containers[i].containerCache)) { 5328 5329 // if we've already found a container and it's more "inner" than this, then continue 5330 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 5331 continue; 5332 } 5333 5334 innermostContainer = this.containers[i]; 5335 innermostIndex = i; 5336 5337 } else { 5338 // container doesn't intersect. trigger "out" event if necessary 5339 if(this.containers[i].containerCache.over) { 5340 this.containers[i]._trigger("out", event, this._uiHash(this)); 5341 this.containers[i].containerCache.over = 0; 5342 } 5343 } 5344 5345 } 5346 5347 // if no intersecting containers found, return 5348 if(!innermostContainer) { 5349 return; 5350 } 5351 5352 // move the item into the container if it's not there already 5353 if(this.containers.length === 1) { 5354 if (!this.containers[innermostIndex].containerCache.over) { 5355 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5356 this.containers[innermostIndex].containerCache.over = 1; 5357 } 5358 } else { 5359 5360 //When entering a new container, we will find the item with the least distance and append our item near it 5361 dist = 10000; 5362 itemWithLeastDistance = null; 5363 floating = innermostContainer.floating || this._isFloating(this.currentItem); 5364 posProperty = floating ? "left" : "top"; 5365 sizeProperty = floating ? "width" : "height"; 5366 axis = floating ? "clientX" : "clientY"; 5367 5368 for (j = this.items.length - 1; j >= 0; j--) { 5369 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 5370 continue; 5371 } 5372 if(this.items[j].item[0] === this.currentItem[0]) { 5373 continue; 5374 } 5375 5376 cur = this.items[j].item.offset()[posProperty]; 5377 nearBottom = false; 5378 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 5379 nearBottom = true; 5380 } 5381 5382 if ( Math.abs( event[ axis ] - cur ) < dist ) { 5383 dist = Math.abs( event[ axis ] - cur ); 5384 itemWithLeastDistance = this.items[ j ]; 5385 this.direction = nearBottom ? "up": "down"; 5386 } 5387 } 5388 5389 //Check if dropOnEmpty is enabled 5390 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 5391 return; 5392 } 5393 5394 if(this.currentContainer === this.containers[innermostIndex]) { 5395 if ( !this.currentContainer.containerCache.over ) { 5396 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 5397 this.currentContainer.containerCache.over = 1; 5398 } 5399 return; 5400 } 5401 5402 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 5403 this._trigger("change", event, this._uiHash()); 5404 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 5405 this.currentContainer = this.containers[innermostIndex]; 5406 5407 //Update the placeholder 5408 this.options.placeholder.update(this.currentContainer, this.placeholder); 5409 5410 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5411 this.containers[innermostIndex].containerCache.over = 1; 5412 } 5413 5414 5415 }, 5416 5417 _createHelper: function(event) { 5418 5419 var o = this.options, 5420 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 5421 5422 //Add the helper to the DOM if that didn't happen already 5423 if(!helper.parents("body").length) { 5424 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 5425 } 5426 5427 if(helper[0] === this.currentItem[0]) { 5428 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
vendor: 4,496 bytes, lines 5428-5545
5428: this.currentItem.css("left") }; 5429 } 5430 5431 if(!helper[0].style.width || o.forceHelperSize) { 5432 helper.width(this.currentItem.width()); 5433 } 5434 if(!helper[0].style.height || o.forceHelperSize) { 5435 helper.height(this.currentItem.height()); 5436 } 5437 5438 return helper; 5439 5440 }, 5441 5442 _adjustOffsetFromHelper: function(obj) { 5443 if (typeof obj === "string") { 5444 obj = obj.split(" "); 5445 } 5446 if ($.isArray(obj)) { 5447 obj = {left: +obj[0], top: +obj[1] || 0}; 5448 } 5449 if ("left" in obj) { 5450 this.offset.click.left = obj.left + this.margins.left; 5451 } 5452 if ("right" in obj) { 5453 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 5454 } 5455 if ("top" in obj) { 5456 this.offset.click.top = obj.top + this.margins.top; 5457 } 5458 if ("bottom" in obj) { 5459 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 5460 } 5461 }, 5462 5463 _getParentOffset: function() { 5464 5465 5466 //Get the offsetParent and cache its position 5467 this.offsetParent = this.helper.offsetParent(); 5468 var po = this.offsetParent.offset(); 5469 5470 // This is a special case where we need to modify a offset calculated on start, since the following happened: 5471 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 5472 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 5473 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 5474 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 5475 po.left += this.scrollParent.scrollLeft(); 5476 po.top += this.scrollParent.scrollTop(); 5477 } 5478 5479 // This needs to be actually done for all browsers, since pageX/pageY includes this information 5480 // with an ugly IE fix 5481 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 5482 po = { top: 0, left: 0 }; 5483 } 5484 5485 return { 5486 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 5487 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 5488 }; 5489 5490 }, 5491 5492 _getRelativeOffset: function() { 5493 5494 if(this.cssPosition === "relative") { 5495 var p = this.currentItem.position(); 5496 return { 5497 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 5498 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 5499 }; 5500 } else { 5501 return { top: 0, left: 0 }; 5502 } 5503 5504 }, 5505 5506 _cacheMargins: function() { 5507 this.margins = { 5508 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 5509 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 5510 }; 5511 }, 5512 5513 _cacheHelperProportions: function() { 5514 this.helperProportions = { 5515 width: this.helper.outerWidth(), 5516 height: this.helper.outerHeight() 5517 }; 5518 }, 5519 5520 _setContainment: function() { 5521 5522 var ce, co, over, 5523 o = this.options; 5524 if(o.containment === "parent") { 5525 o.containment = this.helper[0].parentNode; 5526 } 5527 if(o.containment === "document" || o.containment === "window") { 5528 this.containment = [ 5529 0 - this.offset.relative.left - this.offset.parent.left, 5530 0 - this.offset.relative.top - this.offset.parent.top, 5531 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 5532 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 5533 ]; 5534 } 5535 5536 if(!(/^(document|window|parent)$/).test(o.containment)) { 5537 ce = $(o.containment)[0]; 5538 co = $(o.containment).offset(); 5539 over = ($(ce).css("overflow") !== "hidden"); 5540 5541 this.containment = [ 5542 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 5543 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 5544 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, 5545 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 5,621 bytes, lines 5545-5657
554510) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 5546 ]; 5547 } 5548 5549 }, 5550 5551 _convertPositionTo: function(d, pos) { 5552 5553 if(!pos) { 5554 pos = this.position; 5555 } 5556 var mod = d === "absolute" ? 1 : -1, 5557 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 5558 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 5559 5560 return { 5561 top: ( 5562 pos.top + // The absolute mouse position 5563 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5564 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 5565 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 5566 ), 5567 left: ( 5568 pos.left + // The absolute mouse position 5569 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5570 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 5571 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 5572 ) 5573 }; 5574 5575 }, 5576 5577 _generatePosition: function(event) { 5578 5579 var top, left, 5580 o = this.options, 5581 pageX = event.pageX, 5582 pageY = event.pageY, 5583 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 5584 5585 // This is another very weird special case that only happens for relative elements: 5586 // 1. If the css position is relative 5587 // 2. and the scroll parent is the document or similar to the offset parent 5588 // we have to refresh the relative offset during the scroll so there are no jumps 5589 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 5590 this.offset.relative = this._getRelativeOffset(); 5591 } 5592 5593 /* 5594 * - Position constraining - 5595 * Constrain the position to a mix of grid, containment. 5596 */ 5597 5598 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 5599 5600 if(this.containment) { 5601 if(event.pageX - this.offset.click.left < this.containment[0]) { 5602 pageX = this.containment[0] + this.offset.click.left; 5603 } 5604 if(event.pageY - this.offset.click.top < this.containment[1]) { 5605 pageY = this.containment[1] + this.offset.click.top; 5606 } 5607 if(event.pageX - this.offset.click.left > this.containment[2]) { 5608 pageX = this.containment[2] + this.offset.click.left; 5609 } 5610 if(event.pageY - this.offset.click.top > this.containment[3]) { 5611 pageY = this.containment[3] + this.offset.click.top; 5612 } 5613 } 5614 5615 if(o.grid) { 5616 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 5617 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; 5618 5619 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 5620 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; 5621 } 5622 5623 } 5624 5625 return { 5626 top: ( 5627 pageY - // The absolute mouse position 5628 this.offset.click.top - // Click offset (relative to the element) 5629 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 5630 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 5631 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 5632 ), 5633 left: ( 5634 pageX - // The absolute mouse position 5635 this.offset.click.left - // Click offset (relative to the element) 5636 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 5637 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 5638 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 5639 ) 5640 }; 5641 5642 }, 5643 5644 _rearrange: function(event, i, a, hardRefresh) { 5645 5646 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)); 5647 5648 //Various things done here to improve the performance: 5649 // 1. we create a setTimeout, that calls refreshPositions 5650 // 2. on the instance, we have a counter variable, that get's higher after every append 5651 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 5652 // 4. this lets only the last addition to the timeout stack through 5653 this.counter = this.counter ? ++this.counter : 1; 5654 var counter = this.counter; 5655 5656 this._delay(function() { 5657 if(counter === this.counter) {
vendor: 4,352 bytes, lines 5658-5788
5658 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 5659 } 5660 }); 5661 5662 }, 5663 5664 _clear: function(event, noPropagation) { 5665 5666 this.reverting = false; 5667 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 5668 // everything else normalized again 5669 var i, 5670 delayedTriggers = []; 5671 5672 // We first have to update the dom position of the actual currentItem 5673 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 5674 if(!this._noFinalSort && this.currentItem.parent().length) { 5675 this.placeholder.before(this.currentItem); 5676 } 5677 this._noFinalSort = null; 5678 5679 if(this.helper[0] === this.currentItem[0]) { 5680 for(i in this._storedCSS) { 5681 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 5682 this._storedCSS[i] = ""; 5683 } 5684 } 5685 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 5686 } else { 5687 this.currentItem.show(); 5688 } 5689 5690 if(this.fromOutside && !noPropagation) { 5691 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 5692 } 5693 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 5694 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 5695 } 5696 5697 // Check if the items Container has Changed and trigger appropriate 5698 // events. 5699 if (this !== this.currentContainer) { 5700 if(!noPropagation) { 5701 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 5702 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5703 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5704 } 5705 } 5706 5707 5708 //Post events to containers 5709 function delayEvent( type, instance, container ) { 5710 return function( event ) { 5711 container._trigger( type, event, instance._uiHash( instance ) ); 5712 }; 5713 } 5714 for (i = this.containers.length - 1; i >= 0; i--){ 5715 if (!noPropagation) { 5716 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 5717 } 5718 if(this.containers[i].containerCache.over) { 5719 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 5720 this.containers[i].containerCache.over = 0; 5721 } 5722 } 5723 5724 //Do what was originally in plugins 5725 if ( this.storedCursor ) { 5726 this.document.find( "body" ).css( "cursor", this.storedCursor ); 5727 this.storedStylesheet.remove(); 5728 } 5729 if(this._storedOpacity) { 5730 this.helper.css("opacity", this._storedOpacity); 5731 } 5732 if(this._storedZIndex) { 5733 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 5734 } 5735 5736 this.dragging = false; 5737 5738 if(!noPropagation) { 5739 this._trigger("beforeStop", event, this._uiHash()); 5740 } 5741 5742 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 5743 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 5744 5745 if ( !this.cancelHelperRemoval ) { 5746 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 5747 this.helper.remove(); 5748 } 5749 this.helper = null; 5750 } 5751 5752 if(!noPropagation) { 5753 for (i=0; i < delayedTriggers.length; i++) { 5754 delayedTriggers[i].call(this, event); 5755 } //Trigger all delayed events 5756 this._trigger("stop", event, this._uiHash()); 5757 } 5758 5759 this.fromOutside = false; 5760 return !this.cancelHelperRemoval; 5761 5762 }, 5763 5764 _trigger: function() { 5765 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 5766 this.cancel(); 5767 } 5768 }, 5769 5770 _uiHash: function(_inst) { 5771 var inst = _inst || this; 5772 return { 5773 helper: inst.helper, 5774 placeholder: inst.placeholder || $([]), 5775 position: inst.position, 5776 originalPosition: inst.originalPosition, 5777 offset: inst.positionAbs, 5778 item: inst.currentItem, 5779 sender: _inst ? _inst.element : null 5780 }; 5781 } 5782 5783}); 5784 5785 5786/*! 5787 * jQuery UI Accordion 1.11.2 5788 * http://jqueryui.com
vendor: 64,945 bytes, lines 5789-8075
5789 * 5790 * Copyright 2014 jQuery Foundation and other contributors 5791 * Released under the MIT license. 5792 * http://jquery.org/license 5793 * 5794 * http://api.jqueryui.com/accordion/ 5795 */ 5796 5797 5798var accordion = $.widget( "ui.accordion", { 5799 version: "1.11.2", 5800 options: { 5801 active: 0, 5802 animate: {}, 5803 collapsible: false, 5804 event: "click", 5805 header: "> li > :first-child,> :not(li):even", 5806 heightStyle: "auto", 5807 icons: { 5808 activeHeader: "ui-icon-triangle-1-s", 5809 header: "ui-icon-triangle-1-e" 5810 }, 5811 5812 // callbacks 5813 activate: null, 5814 beforeActivate: null 5815 }, 5816 5817 hideProps: { 5818 borderTopWidth: "hide", 5819 borderBottomWidth: "hide", 5820 paddingTop: "hide", 5821 paddingBottom: "hide", 5822 height: "hide" 5823 }, 5824 5825 showProps: { 5826 borderTopWidth: "show", 5827 borderBottomWidth: "show", 5828 paddingTop: "show", 5829 paddingBottom: "show", 5830 height: "show" 5831 }, 5832 5833 _create: function() { 5834 var options = this.options; 5835 this.prevShow = this.prevHide = $(); 5836 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 5837 // ARIA 5838 .attr( "role", "tablist" ); 5839 5840 // don't allow collapsible: false and active: false / null 5841 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5842 options.active = 0; 5843 } 5844 5845 this._processPanels(); 5846 // handle negative values 5847 if ( options.active < 0 ) { 5848 options.active += this.headers.length; 5849 } 5850 this._refresh(); 5851 }, 5852 5853 _getCreateEventData: function() { 5854 return { 5855 header: this.active, 5856 panel: !this.active.length ? $() : this.active.next() 5857 }; 5858 }, 5859 5860 _createIcons: function() { 5861 var icons = this.options.icons; 5862 if ( icons ) { 5863 $( "<span>" ) 5864 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5865 .prependTo( this.headers ); 5866 this.active.children( ".ui-accordion-header-icon" ) 5867 .removeClass( icons.header ) 5868 .addClass( icons.activeHeader ); 5869 this.headers.addClass( "ui-accordion-icons" ); 5870 } 5871 }, 5872 5873 _destroyIcons: function() { 5874 this.headers 5875 .removeClass( "ui-accordion-icons" ) 5876 .children( ".ui-accordion-header-icon" ) 5877 .remove(); 5878 }, 5879 5880 _destroy: function() { 5881 var contents; 5882 5883 // clean up main element 5884 this.element 5885 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5886 .removeAttr( "role" ); 5887 5888 // clean up headers 5889 this.headers 5890 .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + 5891 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 5892 .removeAttr( "role" ) 5893 .removeAttr( "aria-expanded" ) 5894 .removeAttr( "aria-selected" ) 5895 .removeAttr( "aria-controls" ) 5896 .removeAttr( "tabIndex" ) 5897 .removeUniqueId(); 5898 5899 this._destroyIcons(); 5900 5901 // clean up content panels 5902 contents = this.headers.next() 5903 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + 5904 "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5905 .css( "display", "" ) 5906 .removeAttr( "role" ) 5907 .removeAttr( "aria-hidden" ) 5908 .removeAttr( "aria-labelledby" ) 5909 .removeUniqueId(); 5910 5911 if ( this.options.heightStyle !== "content" ) { 5912 contents.css( "height", "" ); 5913 } 5914 }, 5915 5916 _setOption: function( key, value ) { 5917 if ( key === "active" ) { 5918 // _activate() will handle invalid values and update this.options 5919 this._activate( value ); 5920 return; 5921 } 5922 5923 if ( key === "event" ) { 5924 if ( this.options.event ) { 5925 this._off( this.headers, this.options.event ); 5926 } 5927 this._setupEvents( value ); 5928 } 5929 5930 this._super( key, value ); 5931 5932 // setting collapsible: false while collapsed; open first panel 5933 if ( key === "collapsible" && !value && this.options.active === false ) { 5934 this._activate( 0 ); 5935 } 5936 5937 if ( key === "icons" ) { 5938 this._destroyIcons(); 5939 if ( value ) { 5940 this._createIcons(); 5941 } 5942 } 5943 5944 // #5332 - opacity doesn't cascade to positioned elements in IE 5945 // so we need to add the disabled class to the headers and panels 5946 if ( key === "disabled" ) { 5947 this.element 5948 .toggleClass( "ui-state-disabled", !!value ) 5949 .attr( "aria-disabled", value ); 5950 this.headers.add( this.headers.next() ) 5951 .toggleClass( "ui-state-disabled", !!value ); 5952 } 5953 }, 5954 5955 _keydown: function( event ) { 5956 if ( event.altKey || event.ctrlKey ) { 5957 return; 5958 } 5959 5960 var keyCode = $.ui.keyCode, 5961 length = this.headers.length, 5962 currentIndex = this.headers.index( event.target ), 5963 toFocus = false; 5964 5965 switch ( event.keyCode ) { 5966 case keyCode.RIGHT: 5967 case keyCode.DOWN: 5968 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5969 break; 5970 case keyCode.LEFT: 5971 case keyCode.UP: 5972 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5973 break; 5974 case keyCode.SPACE: 5975 case keyCode.ENTER: 5976 this._eventHandler( event ); 5977 break; 5978 case keyCode.HOME: 5979 toFocus = this.headers[ 0 ]; 5980 break; 5981 case keyCode.END: 5982 toFocus = this.headers[ length - 1 ]; 5983 break; 5984 } 5985 5986 if ( toFocus ) { 5987 $( event.target ).attr( "tabIndex", -1 ); 5988 $( toFocus ).attr( "tabIndex", 0 ); 5989 toFocus.focus(); 5990 event.preventDefault(); 5991 } 5992 }, 5993 5994 _panelKeyDown: function( event ) { 5995 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5996 $( event.currentTarget ).prev().focus(); 5997 } 5998 }, 5999 6000 refresh: function() { 6001 var options = this.options; 6002 this._processPanels(); 6003 6004 // was collapsed or no panel 6005 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6006 options.active = false; 6007 this.active = $(); 6008 // active false only when collapsible is true 6009 } else if ( options.active === false ) { 6010 this._activate( 0 ); 6011 // was active, but active panel is gone 6012 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6013 // all remaining panel are disabled 6014 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6015 options.active = false; 6016 this.active = $(); 6017 // activate previous panel 6018 } else { 6019 this._activate( Math.max( 0, options.active - 1 ) ); 6020 } 6021 // was active, active panel still exists 6022 } else { 6023 // make sure active index is correct 6024 options.active = this.headers.index( this.active ); 6025 } 6026 6027 this._destroyIcons(); 6028 6029 this._refresh(); 6030 }, 6031 6032 _processPanels: function() { 6033 var prevHeaders = this.headers, 6034 prevPanels = this.panels; 6035 6036 this.headers = this.element.find( this.options.header ) 6037 .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); 6038 6039 this.panels = this.headers.next() 6040 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6041 .filter( ":not(.ui-accordion-content-active)" ) 6042 .hide(); 6043 6044 // Avoid memory leaks (#10056) 6045 if ( prevPanels ) { 6046 this._off( prevHeaders.not( this.headers ) ); 6047 this._off( prevPanels.not( this.panels ) ); 6048 } 6049 }, 6050 6051 _refresh: function() { 6052 var maxHeight, 6053 options = this.options, 6054 heightStyle = options.heightStyle, 6055 parent = this.element.parent(); 6056 6057 this.active = this._findActive( options.active ) 6058 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6059 .removeClass( "ui-corner-all" ); 6060 this.active.next() 6061 .addClass( "ui-accordion-content-active" ) 6062 .show(); 6063 6064 this.headers 6065 .attr( "role", "tab" ) 6066 .each(function() { 6067 var header = $( this ), 6068 headerId = header.uniqueId().attr( "id" ), 6069 panel = header.next(), 6070 panelId = panel.uniqueId().attr( "id" ); 6071 header.attr( "aria-controls", panelId ); 6072 panel.attr( "aria-labelledby", headerId ); 6073 }) 6074 .next() 6075 .attr( "role", "tabpanel" ); 6076 6077 this.headers 6078 .not( this.active ) 6079 .attr({ 6080 "aria-selected": "false", 6081 "aria-expanded": "false", 6082 tabIndex: -1 6083 }) 6084 .next() 6085 .attr({ 6086 "aria-hidden": "true" 6087 }) 6088 .hide(); 6089 6090 // make sure at least one header is in the tab order 6091 if ( !this.active.length ) { 6092 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6093 } else { 6094 this.active.attr({ 6095 "aria-selected": "true", 6096 "aria-expanded": "true", 6097 tabIndex: 0 6098 }) 6099 .next() 6100 .attr({ 6101 "aria-hidden": "false" 6102 }); 6103 } 6104 6105 this._createIcons(); 6106 6107 this._setupEvents( options.event ); 6108 6109 if ( heightStyle === "fill" ) { 6110 maxHeight = parent.height(); 6111 this.element.siblings( ":visible" ).each(function() { 6112 var elem = $( this ), 6113 position = elem.css( "position" ); 6114 6115 if ( position === "absolute" || position === "fixed" ) { 6116 return; 6117 } 6118 maxHeight -= elem.outerHeight( true ); 6119 }); 6120 6121 this.headers.each(function() { 6122 maxHeight -= $( this ).outerHeight( true ); 6123 }); 6124 6125 this.headers.next() 6126 .each(function() { 6127 $( this ).height( Math.max( 0, maxHeight - 6128 $( this ).innerHeight() + $( this ).height() ) ); 6129 }) 6130 .css( "overflow", "auto" ); 6131 } else if ( heightStyle === "auto" ) { 6132 maxHeight = 0; 6133 this.headers.next() 6134 .each(function() { 6135 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6136 }) 6137 .height( maxHeight ); 6138 } 6139 }, 6140 6141 _activate: function( index ) { 6142 var active = this._findActive( index )[ 0 ]; 6143 6144 // trying to activate the already active panel 6145 if ( active === this.active[ 0 ] ) { 6146 return; 6147 } 6148 6149 // trying to collapse, simulate a click on the currently active header 6150 active = active || this.active[ 0 ]; 6151 6152 this._eventHandler({ 6153 target: active, 6154 currentTarget: active, 6155 preventDefault: $.noop 6156 }); 6157 }, 6158 6159 _findActive: function( selector ) { 6160 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6161 }, 6162 6163 _setupEvents: function( event ) { 6164 var events = { 6165 keydown: "_keydown" 6166 }; 6167 if ( event ) { 6168 $.each( event.split( " " ), function( index, eventName ) { 6169 events[ eventName ] = "_eventHandler"; 6170 }); 6171 } 6172 6173 this._off( this.headers.add( this.headers.next() ) ); 6174 this._on( this.headers, events ); 6175 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6176 this._hoverable( this.headers ); 6177 this._focusable( this.headers ); 6178 }, 6179 6180 _eventHandler: function( event ) { 6181 var options = this.options, 6182 active = this.active, 6183 clicked = $( event.currentTarget ), 6184 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6185 collapsing = clickedIsActive && options.collapsible, 6186 toShow = collapsing ? $() : clicked.next(), 6187 toHide = active.next(), 6188 eventData = { 6189 oldHeader: active, 6190 oldPanel: toHide, 6191 newHeader: collapsing ? $() : clicked, 6192 newPanel: toShow 6193 }; 6194 6195 event.preventDefault(); 6196 6197 if ( 6198 // click on active header, but not collapsible 6199 ( clickedIsActive && !options.collapsible ) || 6200 // allow canceling activation 6201 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6202 return; 6203 } 6204 6205 options.active = collapsing ? false : this.headers.index( clicked ); 6206 6207 // when the call to ._toggle() comes after the class changes 6208 // it causes a very odd bug in IE 8 (see #6720) 6209 this.active = clickedIsActive ? $() : clicked; 6210 this._toggle( eventData ); 6211 6212 // switch classes 6213 // corner classes on the previously active header stay after the animation 6214 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6215 if ( options.icons ) { 6216 active.children( ".ui-accordion-header-icon" ) 6217 .removeClass( options.icons.activeHeader ) 6218 .addClass( options.icons.header ); 6219 } 6220 6221 if ( !clickedIsActive ) { 6222 clicked 6223 .removeClass( "ui-corner-all" ) 6224 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6225 if ( options.icons ) { 6226 clicked.children( ".ui-accordion-header-icon" ) 6227 .removeClass( options.icons.header ) 6228 .addClass( options.icons.activeHeader ); 6229 } 6230 6231 clicked 6232 .next() 6233 .addClass( "ui-accordion-content-active" ); 6234 } 6235 }, 6236 6237 _toggle: function( data ) { 6238 var toShow = data.newPanel, 6239 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6240 6241 // handle activating a panel during the animation for another activation 6242 this.prevShow.add( this.prevHide ).stop( true, true ); 6243 this.prevShow = toShow; 6244 this.prevHide = toHide; 6245 6246 if ( this.options.animate ) { 6247 this._animate( toShow, toHide, data ); 6248 } else { 6249 toHide.hide(); 6250 toShow.show(); 6251 this._toggleComplete( data ); 6252 } 6253 6254 toHide.attr({ 6255 "aria-hidden": "true" 6256 }); 6257 toHide.prev().attr( "aria-selected", "false" ); 6258 // if we're switching panels, remove the old header from the tab order 6259 // if we're opening from collapsed state, remove the previous header from the tab order 6260 // if we're collapsing, then keep the collapsing header in the tab order 6261 if ( toShow.length && toHide.length ) { 6262 toHide.prev().attr({ 6263 "tabIndex": -1, 6264 "aria-expanded": "false" 6265 }); 6266 } else if ( toShow.length ) { 6267 this.headers.filter(function() { 6268 return $( this ).attr( "tabIndex" ) === 0; 6269 }) 6270 .attr( "tabIndex", -1 ); 6271 } 6272 6273 toShow 6274 .attr( "aria-hidden", "false" ) 6275 .prev() 6276 .attr({ 6277 "aria-selected": "true", 6278 tabIndex: 0, 6279 "aria-expanded": "true" 6280 }); 6281 }, 6282 6283 _animate: function( toShow, toHide, data ) { 6284 var total, easing, duration, 6285 that = this, 6286 adjust = 0, 6287 down = toShow.length && 6288 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6289 animate = this.options.animate || {}, 6290 options = down && animate.down || animate, 6291 complete = function() { 6292 that._toggleComplete( data ); 6293 }; 6294 6295 if ( typeof options === "number" ) { 6296 duration = options; 6297 } 6298 if ( typeof options === "string" ) { 6299 easing = options; 6300 } 6301 // fall back from options to animation in case of partial down settings 6302 easing = easing || options.easing || animate.easing; 6303 duration = duration || options.duration || animate.duration; 6304 6305 if ( !toHide.length ) { 6306 return toShow.animate( this.showProps, duration, easing, complete ); 6307 } 6308 if ( !toShow.length ) { 6309 return toHide.animate( this.hideProps, duration, easing, complete ); 6310 } 6311 6312 total = toShow.show().outerHeight(); 6313 toHide.animate( this.hideProps, { 6314 duration: duration, 6315 easing: easing, 6316 step: function( now, fx ) { 6317 fx.now = Math.round( now ); 6318 } 6319 }); 6320 toShow 6321 .hide() 6322 .animate( this.showProps, { 6323 duration: duration, 6324 easing: easing, 6325 complete: complete, 6326 step: function( now, fx ) { 6327 fx.now = Math.round( now ); 6328 if ( fx.prop !== "height" ) { 6329 adjust += fx.now; 6330 } else if ( that.options.heightStyle !== "content" ) { 6331 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6332 adjust = 0; 6333 } 6334 } 6335 }); 6336 }, 6337 6338 _toggleComplete: function( data ) { 6339 var toHide = data.oldPanel; 6340 6341 toHide 6342 .removeClass( "ui-accordion-content-active" ) 6343 .prev() 6344 .removeClass( "ui-corner-top" ) 6345 .addClass( "ui-corner-all" ); 6346 6347 // Work around for rendering bug in IE (#5421) 6348 if ( toHide.length ) { 6349 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 6350 } 6351 this._trigger( "activate", null, data ); 6352 } 6353}); 6354 6355 6356/*! 6357 * jQuery UI Menu 1.11.2 6358 * http://jqueryui.com 6359 * 6360 * Copyright 2014 jQuery Foundation and other contributors 6361 * Released under the MIT license. 6362 * http://jquery.org/license 6363 * 6364 * http://api.jqueryui.com/menu/ 6365 */ 6366 6367 6368var menu = $.widget( "ui.menu", { 6369 version: "1.11.2", 6370 defaultElement: "<ul>", 6371 delay: 300, 6372 options: { 6373 icons: { 6374 submenu: "ui-icon-carat-1-e" 6375 }, 6376 items: "> *", 6377 menus: "ul", 6378 position: { 6379 my: "left-1 top", 6380 at: "right top" 6381 }, 6382 role: "menu", 6383 6384 // callbacks 6385 blur: null, 6386 focus: null, 6387 select: null 6388 }, 6389 6390 _create: function() { 6391 this.activeMenu = this.element; 6392 6393 // Flag used to prevent firing of the click handler 6394 // as the event bubbles up through nested menus 6395 this.mouseHandled = false; 6396 this.element 6397 .uniqueId() 6398 .addClass( "ui-menu ui-widget ui-widget-content" ) 6399 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 6400 .attr({ 6401 role: this.options.role, 6402 tabIndex: 0 6403 }); 6404 6405 if ( this.options.disabled ) { 6406 this.element 6407 .addClass( "ui-state-disabled" ) 6408 .attr( "aria-disabled", "true" ); 6409 } 6410 6411 this._on({ 6412 // Prevent focus from sticking to links inside menu after clicking 6413 // them (focus should always stay on UL during navigation). 6414 "mousedown .ui-menu-item": function( event ) { 6415 event.preventDefault(); 6416 }, 6417 "click .ui-menu-item": function( event ) { 6418 var target = $( event.target ); 6419 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 6420 this.select( event ); 6421 6422 // Only set the mouseHandled flag if the event will bubble, see #9469. 6423 if ( !event.isPropagationStopped() ) { 6424 this.mouseHandled = true; 6425 } 6426 6427 // Open submenu on click 6428 if ( target.has( ".ui-menu" ).length ) { 6429 this.expand( event ); 6430 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 6431 6432 // Redirect focus to the menu 6433 this.element.trigger( "focus", [ true ] ); 6434 6435 // If the active item is on the top level, let it stay active. 6436 // Otherwise, blur the active item since it is no longer visible. 6437 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 6438 clearTimeout( this.timer ); 6439 } 6440 } 6441 } 6442 }, 6443 "mouseenter .ui-menu-item": function( event ) { 6444 // Ignore mouse events while typeahead is active, see #10458. 6445 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 6446 // is over an item in the menu 6447 if ( this.previousFilter ) { 6448 return; 6449 } 6450 var target = $( event.currentTarget ); 6451 // Remove ui-state-active class from siblings of the newly focused menu item 6452 // to avoid a jump caused by adjacent elements both having a class with a border 6453 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); 6454 this.focus( event, target ); 6455 }, 6456 mouseleave: "collapseAll", 6457 "mouseleave .ui-menu": "collapseAll", 6458 focus: function( event, keepActiveItem ) { 6459 // If there's already an active item, keep it active 6460 // If not, activate the first item 6461 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 6462 6463 if ( !keepActiveItem ) { 6464 this.focus( event, item ); 6465 } 6466 }, 6467 blur: function( event ) { 6468 this._delay(function() { 6469 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 6470 this.collapseAll( event ); 6471 } 6472 }); 6473 }, 6474 keydown: "_keydown" 6475 }); 6476 6477 this.refresh(); 6478 6479 // Clicks outside of a menu collapse any open menus 6480 this._on( this.document, { 6481 click: function( event ) { 6482 if ( this._closeOnDocumentClick( event ) ) { 6483 this.collapseAll( event ); 6484 } 6485 6486 // Reset the mouseHandled flag 6487 this.mouseHandled = false; 6488 } 6489 }); 6490 }, 6491 6492 _destroy: function() { 6493 // Destroy (sub)menus 6494 this.element 6495 .removeAttr( "aria-activedescendant" ) 6496 .find( ".ui-menu" ).addBack() 6497 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) 6498 .removeAttr( "role" ) 6499 .removeAttr( "tabIndex" ) 6500 .removeAttr( "aria-labelledby" ) 6501 .removeAttr( "aria-expanded" ) 6502 .removeAttr( "aria-hidden" ) 6503 .removeAttr( "aria-disabled" ) 6504 .removeUniqueId() 6505 .show(); 6506 6507 // Destroy menu items 6508 this.element.find( ".ui-menu-item" ) 6509 .removeClass( "ui-menu-item" ) 6510 .removeAttr( "role" ) 6511 .removeAttr( "aria-disabled" ) 6512 .removeUniqueId() 6513 .removeClass( "ui-state-hover" ) 6514 .removeAttr( "tabIndex" ) 6515 .removeAttr( "role" ) 6516 .removeAttr( "aria-haspopup" ) 6517 .children().each( function() { 6518 var elem = $( this ); 6519 if ( elem.data( "ui-menu-submenu-carat" ) ) { 6520 elem.remove(); 6521 } 6522 }); 6523 6524 // Destroy menu dividers 6525 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 6526 }, 6527 6528 _keydown: function( event ) { 6529 var match, prev, character, skip, 6530 preventDefault = true; 6531 6532 switch ( event.keyCode ) { 6533 case $.ui.keyCode.PAGE_UP: 6534 this.previousPage( event ); 6535 break; 6536 case $.ui.keyCode.PAGE_DOWN: 6537 this.nextPage( event ); 6538 break; 6539 case $.ui.keyCode.HOME: 6540 this._move( "first", "first", event ); 6541 break; 6542 case $.ui.keyCode.END: 6543 this._move( "last", "last", event ); 6544 break; 6545 case $.ui.keyCode.UP: 6546 this.previous( event ); 6547 break; 6548 case $.ui.keyCode.DOWN: 6549 this.next( event ); 6550 break; 6551 case $.ui.keyCode.LEFT: 6552 this.collapse( event ); 6553 break; 6554 case $.ui.keyCode.RIGHT: 6555 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 6556 this.expand( event ); 6557 } 6558 break; 6559 case $.ui.keyCode.ENTER: 6560 case $.ui.keyCode.SPACE: 6561 this._activate( event ); 6562 break; 6563 case $.ui.keyCode.ESCAPE: 6564 this.collapse( event ); 6565 break; 6566 default: 6567 preventDefault = false; 6568 prev = this.previousFilter || ""; 6569 character = String.fromCharCode( event.keyCode ); 6570 skip = false; 6571 6572 clearTimeout( this.filterTimer ); 6573 6574 if ( character === prev ) { 6575 skip = true; 6576 } else { 6577 character = prev + character; 6578 } 6579 6580 match = this._filterMenuItems( character ); 6581 match = skip && match.index( this.active.next() ) !== -1 ? 6582 this.active.nextAll( ".ui-menu-item" ) : 6583 match; 6584 6585 // If no matches on the current filter, reset to the last character pressed 6586 // to move down the menu to the first item that starts with that character 6587 if ( !match.length ) { 6588 character = String.fromCharCode( event.keyCode ); 6589 match = this._filterMenuItems( character ); 6590 } 6591 6592 if ( match.length ) { 6593 this.focus( event, match ); 6594 this.previousFilter = character; 6595 this.filterTimer = this._delay(function() { 6596 delete this.previousFilter; 6597 }, 1000 ); 6598 } else { 6599 delete this.previousFilter; 6600 } 6601 } 6602 6603 if ( preventDefault ) { 6604 event.preventDefault(); 6605 } 6606 }, 6607 6608 _activate: function( event ) { 6609 if ( !this.active.is( ".ui-state-disabled" ) ) { 6610 if ( this.active.is( "[aria-haspopup='true']" ) ) { 6611 this.expand( event ); 6612 } else { 6613 this.select( event ); 6614 } 6615 } 6616 }, 6617 6618 refresh: function() { 6619 var menus, items, 6620 that = this, 6621 icon = this.options.icons.submenu, 6622 submenus = this.element.find( this.options.menus ); 6623 6624 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 6625 6626 // Initialize nested menus 6627 submenus.filter( ":not(.ui-menu)" ) 6628 .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) 6629 .hide() 6630 .attr({ 6631 role: this.options.role, 6632 "aria-hidden": "true", 6633 "aria-expanded": "false" 6634 }) 6635 .each(function() { 6636 var menu = $( this ), 6637 item = menu.parent(), 6638 submenuCarat = $( "<span>" ) 6639 .addClass( "ui-menu-icon ui-icon " + icon ) 6640 .data( "ui-menu-submenu-carat", true ); 6641 6642 item 6643 .attr( "aria-haspopup", "true" ) 6644 .prepend( submenuCarat ); 6645 menu.attr( "aria-labelledby", item.attr( "id" ) ); 6646 }); 6647 6648 menus = submenus.add( this.element ); 6649 items = menus.find( this.options.items ); 6650 6651 // Initialize menu-items containing spaces and/or dashes only as dividers 6652 items.not( ".ui-menu-item" ).each(function() { 6653 var item = $( this ); 6654 if ( that._isDivider( item ) ) { 6655 item.addClass( "ui-widget-content ui-menu-divider" ); 6656 } 6657 }); 6658 6659 // Don't refresh list items that are already adapted 6660 items.not( ".ui-menu-item, .ui-menu-divider" ) 6661 .addClass( "ui-menu-item" ) 6662 .uniqueId() 6663 .attr({ 6664 tabIndex: -1, 6665 role: this._itemRole() 6666 }); 6667 6668 // Add aria-disabled attribute to any disabled menu item 6669 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 6670 6671 // If the active item has been removed, blur the menu 6672 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6673 this.blur(); 6674 } 6675 }, 6676 6677 _itemRole: function() { 6678 return { 6679 menu: "menuitem", 6680 listbox: "option" 6681 }[ this.options.role ]; 6682 }, 6683 6684 _setOption: function( key, value ) { 6685 if ( key === "icons" ) { 6686 this.element.find( ".ui-menu-icon" ) 6687 .removeClass( this.options.icons.submenu ) 6688 .addClass( value.submenu ); 6689 } 6690 if ( key === "disabled" ) { 6691 this.element 6692 .toggleClass( "ui-state-disabled", !!value ) 6693 .attr( "aria-disabled", value ); 6694 } 6695 this._super( key, value ); 6696 }, 6697 6698 focus: function( event, item ) { 6699 var nested, focused; 6700 this.blur( event, event && event.type === "focus" ); 6701 6702 this._scrollIntoView( item ); 6703 6704 this.active = item.first(); 6705 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); 6706 // Only update aria-activedescendant if there's a role 6707 // otherwise we assume focus is managed elsewhere 6708 if ( this.options.role ) { 6709 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 6710 } 6711 6712 // Highlight active parent menu item, if any 6713 this.active 6714 .parent() 6715 .closest( ".ui-menu-item" ) 6716 .addClass( "ui-state-active" ); 6717 6718 if ( event && event.type === "keydown" ) { 6719 this._close(); 6720 } else { 6721 this.timer = this._delay(function() { 6722 this._close(); 6723 }, this.delay ); 6724 } 6725 6726 nested = item.children( ".ui-menu" ); 6727 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 6728 this._startOpening(nested); 6729 } 6730 this.activeMenu = item.parent(); 6731 6732 this._trigger( "focus", event, { item: item } ); 6733 }, 6734 6735 _scrollIntoView: function( item ) { 6736 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 6737 if ( this._hasScroll() ) { 6738 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 6739 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 6740 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 6741 scroll = this.activeMenu.scrollTop(); 6742 elementHeight = this.activeMenu.height(); 6743 itemHeight = item.outerHeight(); 6744 6745 if ( offset < 0 ) { 6746 this.activeMenu.scrollTop( scroll + offset ); 6747 } else if ( offset + itemHeight > elementHeight ) { 6748 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 6749 } 6750 } 6751 }, 6752 6753 blur: function( event, fromFocus ) { 6754 if ( !fromFocus ) { 6755 clearTimeout( this.timer ); 6756 } 6757 6758 if ( !this.active ) { 6759 return; 6760 } 6761 6762 this.active.removeClass( "ui-state-focus" ); 6763 this.active = null; 6764 6765 this._trigger( "blur", event, { item: this.active } ); 6766 }, 6767 6768 _startOpening: function( submenu ) { 6769 clearTimeout( this.timer ); 6770 6771 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 6772 // shift in the submenu position when mousing over the carat icon 6773 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 6774 return; 6775 } 6776 6777 this.timer = this._delay(function() { 6778 this._close(); 6779 this._open( submenu ); 6780 }, this.delay ); 6781 }, 6782 6783 _open: function( submenu ) { 6784 var position = $.extend({ 6785 of: this.active 6786 }, this.options.position ); 6787 6788 clearTimeout( this.timer ); 6789 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 6790 .hide() 6791 .attr( "aria-hidden", "true" ); 6792 6793 submenu 6794 .show() 6795 .removeAttr( "aria-hidden" ) 6796 .attr( "aria-expanded", "true" ) 6797 .position( position ); 6798 }, 6799 6800 collapseAll: function( event, all ) { 6801 clearTimeout( this.timer ); 6802 this.timer = this._delay(function() { 6803 // If we were passed an event, look for the submenu that contains the event 6804 var currentMenu = all ? this.element : 6805 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 6806 6807 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 6808 if ( !currentMenu.length ) { 6809 currentMenu = this.element; 6810 } 6811 6812 this._close( currentMenu ); 6813 6814 this.blur( event ); 6815 this.activeMenu = currentMenu; 6816 }, this.delay ); 6817 }, 6818 6819 // With no arguments, closes the currently active menu - if nothing is active 6820 // it closes all menus. If passed an argument, it will search for menus BELOW 6821 _close: function( startMenu ) { 6822 if ( !startMenu ) { 6823 startMenu = this.active ? this.active.parent() : this.element; 6824 } 6825 6826 startMenu 6827 .find( ".ui-menu" ) 6828 .hide() 6829 .attr( "aria-hidden", "true" ) 6830 .attr( "aria-expanded", "false" ) 6831 .end() 6832 .find( ".ui-state-active" ).not( ".ui-state-focus" ) 6833 .removeClass( "ui-state-active" ); 6834 }, 6835 6836 _closeOnDocumentClick: function( event ) { 6837 return !$( event.target ).closest( ".ui-menu" ).length; 6838 }, 6839 6840 _isDivider: function( item ) { 6841 6842 // Match hyphen, em dash, en dash 6843 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 6844 }, 6845 6846 collapse: function( event ) { 6847 var newItem = this.active && 6848 this.active.parent().closest( ".ui-menu-item", this.element ); 6849 if ( newItem && newItem.length ) { 6850 this._close(); 6851 this.focus( event, newItem ); 6852 } 6853 }, 6854 6855 expand: function( event ) { 6856 var newItem = this.active && 6857 this.active 6858 .children( ".ui-menu " ) 6859 .find( this.options.items ) 6860 .first(); 6861 6862 if ( newItem && newItem.length ) { 6863 this._open( newItem.parent() ); 6864 6865 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 6866 this._delay(function() { 6867 this.focus( event, newItem ); 6868 }); 6869 } 6870 }, 6871 6872 next: function( event ) { 6873 this._move( "next", "first", event ); 6874 }, 6875 6876 previous: function( event ) { 6877 this._move( "prev", "last", event ); 6878 }, 6879 6880 isFirstItem: function() { 6881 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 6882 }, 6883 6884 isLastItem: function() { 6885 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 6886 }, 6887 6888 _move: function( direction, filter, event ) { 6889 var next; 6890 if ( this.active ) { 6891 if ( direction === "first" || direction === "last" ) { 6892 next = this.active 6893 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 6894 .eq( -1 ); 6895 } else { 6896 next = this.active 6897 [ direction + "All" ]( ".ui-menu-item" ) 6898 .eq( 0 ); 6899 } 6900 } 6901 if ( !next || !next.length || !this.active ) { 6902 next = this.activeMenu.find( this.options.items )[ filter ](); 6903 } 6904 6905 this.focus( event, next ); 6906 }, 6907 6908 nextPage: function( event ) { 6909 var item, base, height; 6910 6911 if ( !this.active ) { 6912 this.next( event ); 6913 return; 6914 } 6915 if ( this.isLastItem() ) { 6916 return; 6917 } 6918 if ( this._hasScroll() ) { 6919 base = this.active.offset().top; 6920 height = this.element.height(); 6921 this.active.nextAll( ".ui-menu-item" ).each(function() { 6922 item = $( this ); 6923 return item.offset().top - base - height < 0; 6924 }); 6925 6926 this.focus( event, item ); 6927 } else { 6928 this.focus( event, this.activeMenu.find( this.options.items ) 6929 [ !this.active ? "first" : "last" ]() ); 6930 } 6931 }, 6932 6933 previousPage: function( event ) { 6934 var item, base, height; 6935 if ( !this.active ) { 6936 this.next( event ); 6937 return; 6938 } 6939 if ( this.isFirstItem() ) { 6940 return; 6941 } 6942 if ( this._hasScroll() ) { 6943 base = this.active.offset().top; 6944 height = this.element.height(); 6945 this.active.prevAll( ".ui-menu-item" ).each(function() { 6946 item = $( this ); 6947 return item.offset().top - base + height > 0; 6948 }); 6949 6950 this.focus( event, item ); 6951 } else { 6952 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 6953 } 6954 }, 6955 6956 _hasScroll: function() { 6957 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 6958 }, 6959 6960 select: function( event ) { 6961 // TODO: It should never be possible to not have an active item at this 6962 // point, but the tests don't trigger mouseenter before click. 6963 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 6964 var ui = { item: this.active }; 6965 if ( !this.active.has( ".ui-menu" ).length ) { 6966 this.collapseAll( event, true ); 6967 } 6968 this._trigger( "select", event, ui ); 6969 }, 6970 6971 _filterMenuItems: function(character) { 6972 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 6973 regex = new RegExp( "^" + escapedCharacter, "i" ); 6974 6975 return this.activeMenu 6976 .find( this.options.items ) 6977 6978 // Only match on items, not dividers or other content (#10571) 6979 .filter( ".ui-menu-item" ) 6980 .filter(function() { 6981 return regex.test( $.trim( $( this ).text() ) ); 6982 }); 6983 } 6984}); 6985 6986 6987/*! 6988 * jQuery UI Autocomplete 1.11.2 6989 * http://jqueryui.com 6990 * 6991 * Copyright 2014 jQuery Foundation and other contributors 6992 * Released under the MIT license. 6993 * http://jquery.org/license 6994 * 6995 * http://api.jqueryui.com/autocomplete/ 6996 */ 6997 6998 6999$.widget( "ui.autocomplete", { 7000 version: "1.11.2", 7001 defaultElement: "<input>", 7002 options: { 7003 appendTo: null, 7004 autoFocus: false, 7005 delay: 300, 7006 minLength: 1, 7007 position: { 7008 my: "left top", 7009 at: "left bottom", 7010 collision: "none" 7011 }, 7012 source: null, 7013 7014 // callbacks 7015 change: null, 7016 close: null, 7017 focus: null, 7018 open: null, 7019 response: null, 7020 search: null, 7021 select: null 7022 }, 7023 7024 requestIndex: 0, 7025 pending: 0, 7026 7027 _create: function() { 7028 // Some browsers only repeat keydown events, not keypress events, 7029 // so we use the suppressKeyPress flag to determine if we've already 7030 // handled the keydown event. #7269 7031 // Unfortunately the code for & in keypress is the same as the up arrow, 7032 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 7033 // events when we know the keydown event was used to modify the 7034 // search term. #7799 7035 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 7036 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 7037 isTextarea = nodeName === "textarea", 7038 isInput = nodeName === "input"; 7039 7040 this.isMultiLine = 7041 // Textareas are always multi-line 7042 isTextarea ? true : 7043 // Inputs are always single-line, even if inside a contentEditable element 7044 // IE also treats inputs as contentEditable 7045 isInput ? false : 7046 // All other element types are determined by whether or not they're contentEditable 7047 this.element.prop( "isContentEditable" ); 7048 7049 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 7050 this.isNewMenu = true; 7051 7052 this.element 7053 .addClass( "ui-autocomplete-input" ) 7054 .attr( "autocomplete", "off" ); 7055 7056 this._on( this.element, { 7057 keydown: function( event ) { 7058 if ( this.element.prop( "readOnly" ) ) { 7059 suppressKeyPress = true; 7060 suppressInput = true; 7061 suppressKeyPressRepeat = true; 7062 return; 7063 } 7064 7065 suppressKeyPress = false; 7066 suppressInput = false; 7067 suppressKeyPressRepeat = false; 7068 var keyCode = $.ui.keyCode; 7069 switch ( event.keyCode ) { 7070 case keyCode.PAGE_UP: 7071 suppressKeyPress = true; 7072 this._move( "previousPage", event ); 7073 break; 7074 case keyCode.PAGE_DOWN: 7075 suppressKeyPress = true; 7076 this._move( "nextPage", event ); 7077 break; 7078 case keyCode.UP: 7079 suppressKeyPress = true; 7080 this._keyEvent( "previous", event ); 7081 break; 7082 case keyCode.DOWN: 7083 suppressKeyPress = true; 7084 this._keyEvent( "next", event ); 7085 break; 7086 case keyCode.ENTER: 7087 // when menu is open and has focus 7088 if ( this.menu.active ) { 7089 // #6055 - Opera still allows the keypress to occur 7090 // which causes forms to submit 7091 suppressKeyPress = true; 7092 event.preventDefault(); 7093 this.menu.select( event ); 7094 } 7095 break; 7096 case keyCode.TAB: 7097 if ( this.menu.active ) { 7098 this.menu.select( event ); 7099 } 7100 break; 7101 case keyCode.ESCAPE: 7102 if ( this.menu.element.is( ":visible" ) ) { 7103 if ( !this.isMultiLine ) { 7104 this._value( this.term ); 7105 } 7106 this.close( event ); 7107 // Different browsers have different default behavior for escape 7108 // Single press can mean undo or clear 7109 // Double press in IE means clear the whole form 7110 event.preventDefault(); 7111 } 7112 break; 7113 default: 7114 suppressKeyPressRepeat = true; 7115 // search timeout should be triggered before the input value is changed 7116 this._searchTimeout( event ); 7117 break; 7118 } 7119 }, 7120 keypress: function( event ) { 7121 if ( suppressKeyPress ) { 7122 suppressKeyPress = false; 7123 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7124 event.preventDefault(); 7125 } 7126 return; 7127 } 7128 if ( suppressKeyPressRepeat ) { 7129 return; 7130 } 7131 7132 // replicate some key handlers to allow them to repeat in Firefox and Opera 7133 var keyCode = $.ui.keyCode; 7134 switch ( event.keyCode ) { 7135 case keyCode.PAGE_UP: 7136 this._move( "previousPage", event ); 7137 break; 7138 case keyCode.PAGE_DOWN: 7139 this._move( "nextPage", event ); 7140 break; 7141 case keyCode.UP: 7142 this._keyEvent( "previous", event ); 7143 break; 7144 case keyCode.DOWN: 7145 this._keyEvent( "next", event ); 7146 break; 7147 } 7148 }, 7149 input: function( event ) { 7150 if ( suppressInput ) { 7151 suppressInput = false; 7152 event.preventDefault(); 7153 return; 7154 } 7155 this._searchTimeout( event ); 7156 }, 7157 focus: function() { 7158 this.selectedItem = null; 7159 this.previous = this._value(); 7160 }, 7161 blur: function( event ) { 7162 if ( this.cancelBlur ) { 7163 delete this.cancelBlur; 7164 return; 7165 } 7166 7167 clearTimeout( this.searching ); 7168 this.close( event ); 7169 this._change( event ); 7170 } 7171 }); 7172 7173 this._initSource(); 7174 this.menu = $( "<ul>" ) 7175 .addClass( "ui-autocomplete ui-front" ) 7176 .appendTo( this._appendTo() ) 7177 .menu({ 7178 // disable ARIA support, the live region takes care of that 7179 role: null 7180 }) 7181 .hide() 7182 .menu( "instance" ); 7183 7184 this._on( this.menu.element, { 7185 mousedown: function( event ) { 7186 // prevent moving focus out of the text field 7187 event.preventDefault(); 7188 7189 // IE doesn't prevent moving focus even with event.preventDefault() 7190 // so we set a flag to know when we should ignore the blur event 7191 this.cancelBlur = true; 7192 this._delay(function() { 7193 delete this.cancelBlur; 7194 }); 7195 7196 // clicking on the scrollbar causes focus to shift to the body 7197 // but we can't detect a mouseup or a click immediately afterward 7198 // so we have to track the next mousedown and close the menu if 7199 // the user clicks somewhere outside of the autocomplete 7200 var menuElement = this.menu.element[ 0 ]; 7201 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 7202 this._delay(function() { 7203 var that = this; 7204 this.document.one( "mousedown", function( event ) { 7205 if ( event.target !== that.element[ 0 ] && 7206 event.target !== menuElement && 7207 !$.contains( menuElement, event.target ) ) { 7208 that.close(); 7209 } 7210 }); 7211 }); 7212 } 7213 }, 7214 menufocus: function( event, ui ) { 7215 var label, item; 7216 // support: Firefox 7217 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 7218 if ( this.isNewMenu ) { 7219 this.isNewMenu = false; 7220 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 7221 this.menu.blur(); 7222 7223 this.document.one( "mousemove", function() { 7224 $( event.target ).trigger( event.originalEvent ); 7225 }); 7226 7227 return; 7228 } 7229 } 7230 7231 item = ui.item.data( "ui-autocomplete-item" ); 7232 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 7233 // use value to match what will end up in the input, if it was a key event 7234 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 7235 this._value( item.value ); 7236 } 7237 } 7238 7239 // Announce the value in the liveRegion 7240 label = ui.item.attr( "aria-label" ) || item.value; 7241 if ( label && $.trim( label ).length ) { 7242 this.liveRegion.children().hide(); 7243 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 7244 } 7245 }, 7246 menuselect: function( event, ui ) { 7247 var item = ui.item.data( "ui-autocomplete-item" ), 7248 previous = this.previous; 7249 7250 // only trigger when focus was lost (click on menu) 7251 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 7252 this.element.focus(); 7253 this.previous = previous; 7254 // #6109 - IE triggers two focus events and the second 7255 // is asynchronous, so we need to reset the previous 7256 // term synchronously and asynchronously :-( 7257 this._delay(function() { 7258 this.previous = previous; 7259 this.selectedItem = item; 7260 }); 7261 } 7262 7263 if ( false !== this._trigger( "select", event, { item: item } ) ) { 7264 this._value( item.value ); 7265 } 7266 // reset the term after the select event 7267 // this allows custom select handling to work properly 7268 this.term = this._value(); 7269 7270 this.close( event ); 7271 this.selectedItem = item; 7272 } 7273 }); 7274 7275 this.liveRegion = $( "<span>", { 7276 role: "status", 7277 "aria-live": "assertive", 7278 "aria-relevant": "additions" 7279 }) 7280 .addClass( "ui-helper-hidden-accessible" ) 7281 .appendTo( this.document[ 0 ].body ); 7282 7283 // turning off autocomplete prevents the browser from remembering the 7284 // value when navigating through history, so we re-enable autocomplete 7285 // if the page is unloaded before the widget is destroyed. #7790 7286 this._on( this.window, { 7287 beforeunload: function() { 7288 this.element.removeAttr( "autocomplete" ); 7289 } 7290 }); 7291 }, 7292 7293 _destroy: function() { 7294 clearTimeout( this.searching ); 7295 this.element 7296 .removeClass( "ui-autocomplete-input" ) 7297 .removeAttr( "autocomplete" ); 7298 this.menu.element.remove(); 7299 this.liveRegion.remove(); 7300 }, 7301 7302 _setOption: function( key, value ) { 7303 this._super( key, value ); 7304 if ( key === "source" ) { 7305 this._initSource(); 7306 } 7307 if ( key === "appendTo" ) { 7308 this.menu.element.appendTo( this._appendTo() ); 7309 } 7310 if ( key === "disabled" && value && this.xhr ) { 7311 this.xhr.abort(); 7312 } 7313 }, 7314 7315 _appendTo: function() { 7316 var element = this.options.appendTo; 7317 7318 if ( element ) { 7319 element = element.jquery || element.nodeType ? 7320 $( element ) : 7321 this.document.find( element ).eq( 0 ); 7322 } 7323 7324 if ( !element || !element[ 0 ] ) { 7325 element = this.element.closest( ".ui-front" ); 7326 } 7327 7328 if ( !element.length ) { 7329 element = this.document[ 0 ].body; 7330 } 7331 7332 return element; 7333 }, 7334 7335 _initSource: function() { 7336 var array, url, 7337 that = this; 7338 if ( $.isArray( this.options.source ) ) { 7339 array = this.options.source; 7340 this.source = function( request, response ) { 7341 response( $.ui.autocomplete.filter( array, request.term ) ); 7342 }; 7343 } else if ( typeof this.options.source === "string" ) { 7344 url = this.options.source; 7345 this.source = function( request, response ) { 7346 if ( that.xhr ) { 7347 that.xhr.abort(); 7348 } 7349 that.xhr = $.ajax({ 7350 url: url, 7351 data: request, 7352 dataType: "json", 7353 success: function( data ) { 7354 response( data ); 7355 }, 7356 error: function() { 7357 response([]); 7358 } 7359 }); 7360 }; 7361 } else { 7362 this.source = this.options.source; 7363 } 7364 }, 7365 7366 _searchTimeout: function( event ) { 7367 clearTimeout( this.searching ); 7368 this.searching = this._delay(function() { 7369 7370 // Search if the value has changed, or if the user retypes the same value (see #7434) 7371 var equalValues = this.term === this._value(), 7372 menuVisible = this.menu.element.is( ":visible" ), 7373 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 7374 7375 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 7376 this.selectedItem = null; 7377 this.search( null, event ); 7378 } 7379 }, this.options.delay ); 7380 }, 7381 7382 search: function( value, event ) { 7383 value = value != null ? value : this._value(); 7384 7385 // always save the actual value, not the one passed as an argument 7386 this.term = this._value(); 7387 7388 if ( value.length < this.options.minLength ) { 7389 return this.close( event ); 7390 } 7391 7392 if ( this._trigger( "search", event ) === false ) { 7393 return; 7394 } 7395 7396 return this._search( value ); 7397 }, 7398 7399 _search: function( value ) { 7400 this.pending++; 7401 this.element.addClass( "ui-autocomplete-loading" ); 7402 this.cancelSearch = false; 7403 7404 this.source( { term: value }, this._response() ); 7405 }, 7406 7407 _response: function() { 7408 var index = ++this.requestIndex; 7409 7410 return $.proxy(function( content ) { 7411 if ( index === this.requestIndex ) { 7412 this.__response( content ); 7413 } 7414 7415 this.pending--; 7416 if ( !this.pending ) { 7417 this.element.removeClass( "ui-autocomplete-loading" ); 7418 } 7419 }, this ); 7420 }, 7421 7422 __response: function( content ) { 7423 if ( content ) { 7424 content = this._normalize( content ); 7425 } 7426 this._trigger( "response", null, { content: content } ); 7427 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7428 this._suggest( content ); 7429 this._trigger( "open" ); 7430 } else { 7431 // use ._close() instead of .close() so we don't cancel future searches 7432 this._close(); 7433 } 7434 }, 7435 7436 close: function( event ) { 7437 this.cancelSearch = true; 7438 this._close( event ); 7439 }, 7440 7441 _close: function( event ) { 7442 if ( this.menu.element.is( ":visible" ) ) { 7443 this.menu.element.hide(); 7444 this.menu.blur(); 7445 this.isNewMenu = true; 7446 this._trigger( "close", event ); 7447 } 7448 }, 7449 7450 _change: function( event ) { 7451 if ( this.previous !== this._value() ) { 7452 this._trigger( "change", event, { item: this.selectedItem } ); 7453 } 7454 }, 7455 7456 _normalize: function( items ) { 7457 // assume all items have the right format when the first item is complete 7458 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 7459 return items; 7460 } 7461 return $.map( items, function( item ) { 7462 if ( typeof item === "string" ) { 7463 return { 7464 label: item, 7465 value: item 7466 }; 7467 } 7468 return $.extend( {}, item, { 7469 label: item.label || item.value, 7470 value: item.value || item.label 7471 }); 7472 }); 7473 }, 7474 7475 _suggest: function( items ) { 7476 var ul = this.menu.element.empty(); 7477 this._renderMenu( ul, items ); 7478 this.isNewMenu = true; 7479 this.menu.refresh(); 7480 7481 // size and position menu 7482 ul.show(); 7483 this._resizeMenu(); 7484 ul.position( $.extend({ 7485 of: this.element 7486 }, this.options.position ) ); 7487 7488 if ( this.options.autoFocus ) { 7489 this.menu.next(); 7490 } 7491 }, 7492 7493 _resizeMenu: function() { 7494 var ul = this.menu.element; 7495 ul.outerWidth( Math.max( 7496 // Firefox wraps long text (possibly a rounding bug) 7497 // so we add 1px to avoid the wrapping (#7513) 7498 ul.width( "" ).outerWidth() + 1, 7499 this.element.outerWidth() 7500 ) ); 7501 }, 7502 7503 _renderMenu: function( ul, items ) { 7504 var that = this; 7505 $.each( items, function( index, item ) { 7506 that._renderItemData( ul, item ); 7507 }); 7508 }, 7509 7510 _renderItemData: function( ul, item ) { 7511 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7512 }, 7513 7514 _renderItem: function( ul, item ) { 7515 return $( "<li>" ).text( item.label ).appendTo( ul ); 7516 }, 7517 7518 _move: function( direction, event ) { 7519 if ( !this.menu.element.is( ":visible" ) ) { 7520 this.search( null, event ); 7521 return; 7522 } 7523 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7524 this.menu.isLastItem() && /^next/.test( direction ) ) { 7525 7526 if ( !this.isMultiLine ) { 7527 this._value( this.term ); 7528 } 7529 7530 this.menu.blur(); 7531 return; 7532 } 7533 this.menu[ direction ]( event ); 7534 }, 7535 7536 widget: function() { 7537 return this.menu.element; 7538 }, 7539 7540 _value: function() { 7541 return this.valueMethod.apply( this.element, arguments ); 7542 }, 7543 7544 _keyEvent: function( keyEvent, event ) { 7545 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7546 this._move( keyEvent, event ); 7547 7548 // prevents moving cursor to beginning/end of the text field in some browsers 7549 event.preventDefault(); 7550 } 7551 } 7552}); 7553 7554$.extend( $.ui.autocomplete, { 7555 escapeRegex: function( value ) { 7556 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 7557 }, 7558 filter: function( array, term ) { 7559 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 7560 return $.grep( array, function( value ) { 7561 return matcher.test( value.label || value.value || value ); 7562 }); 7563 } 7564}); 7565 7566// live region extension, adding a `messages` option 7567// NOTE: This is an experimental API. We are still investigating 7568// a full solution for string manipulation and internationalization. 7569$.widget( "ui.autocomplete", $.ui.autocomplete, { 7570 options: { 7571 messages: { 7572 noResults: "No search results.", 7573 results: function( amount ) { 7574 return amount + ( amount > 1 ? " results are" : " result is" ) + 7575 " available, use up and down arrow keys to navigate."; 7576 } 7577 } 7578 }, 7579 7580 __response: function( content ) { 7581 var message; 7582 this._superApply( arguments ); 7583 if ( this.options.disabled || this.cancelSearch ) { 7584 return; 7585 } 7586 if ( content && content.length ) { 7587 message = this.options.messages.results( content.length ); 7588 } else { 7589 message = this.options.messages.noResults; 7590 } 7591 this.liveRegion.children().hide(); 7592 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 7593 } 7594}); 7595 7596var autocomplete = $.ui.autocomplete; 7597 7598 7599/*! 7600 * jQuery UI Button 1.11.2 7601 * http://jqueryui.com 7602 * 7603 * Copyright 2014 jQuery Foundation and other contributors 7604 * Released under the MIT license. 7605 * http://jquery.org/license 7606 * 7607 * http://api.jqueryui.com/button/ 7608 */ 7609 7610 7611var lastActive, 7612 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7613 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", 7614 formResetHandler = function() { 7615 var form = $( this ); 7616 setTimeout(function() { 7617 form.find( ":ui-button" ).button( "refresh" ); 7618 }, 1 ); 7619 }, 7620 radioGroup = function( radio ) { 7621 var name = radio.name, 7622 form = radio.form, 7623 radios = $( [] ); 7624 if ( name ) { 7625 name = name.replace( /'/g, "\\'" ); 7626 if ( form ) { 7627 radios = $( form ).find( "[name='" + name + "'][type=radio]" ); 7628 } else { 7629 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) 7630 .filter(function() { 7631 return !this.form; 7632 }); 7633 } 7634 } 7635 return radios; 7636 }; 7637 7638$.widget( "ui.button", { 7639 version: "1.11.2", 7640 defaultElement: "<button>", 7641 options: { 7642 disabled: null, 7643 text: true, 7644 label: null, 7645 icons: { 7646 primary: null, 7647 secondary: null 7648 } 7649 }, 7650 _create: function() { 7651 this.element.closest( "form" ) 7652 .unbind( "reset" + this.eventNamespace ) 7653 .bind( "reset" + this.eventNamespace, formResetHandler ); 7654 7655 if ( typeof this.options.disabled !== "boolean" ) { 7656 this.options.disabled = !!this.element.prop( "disabled" ); 7657 } else { 7658 this.element.prop( "disabled", this.options.disabled ); 7659 } 7660 7661 this._determineButtonType(); 7662 this.hasTitle = !!this.buttonElement.attr( "title" ); 7663 7664 var that = this, 7665 options = this.options, 7666 toggleButton = this.type === "checkbox" || this.type === "radio", 7667 activeClass = !toggleButton ? "ui-state-active" : ""; 7668 7669 if ( options.label === null ) { 7670 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7671 } 7672 7673 this._hoverable( this.buttonElement ); 7674 7675 this.buttonElement 7676 .addClass( baseClasses ) 7677 .attr( "role", "button" ) 7678 .bind( "mouseenter" + this.eventNamespace, function() { 7679 if ( options.disabled ) { 7680 return; 7681 } 7682 if ( this === lastActive ) { 7683 $( this ).addClass( "ui-state-active" ); 7684 } 7685 }) 7686 .bind( "mouseleave" + this.eventNamespace, function() { 7687 if ( options.disabled ) { 7688 return; 7689 } 7690 $( this ).removeClass( activeClass ); 7691 }) 7692 .bind( "click" + this.eventNamespace, function( event ) { 7693 if ( options.disabled ) { 7694 event.preventDefault(); 7695 event.stopImmediatePropagation(); 7696 } 7697 }); 7698 7699 // Can't use _focusable() because the element that receives focus 7700 // and the element that gets the ui-state-focus class are different 7701 this._on({ 7702 focus: function() { 7703 this.buttonElement.addClass( "ui-state-focus" ); 7704 }, 7705 blur: function() { 7706 this.buttonElement.removeClass( "ui-state-focus" ); 7707 } 7708 }); 7709 7710 if ( toggleButton ) { 7711 this.element.bind( "change" + this.eventNamespace, function() { 7712 that.refresh(); 7713 }); 7714 } 7715 7716 if ( this.type === "checkbox" ) { 7717 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7718 if ( options.disabled ) { 7719 return false; 7720 } 7721 }); 7722 } else if ( this.type === "radio" ) { 7723 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7724 if ( options.disabled ) { 7725 return false; 7726 } 7727 $( this ).addClass( "ui-state-active" ); 7728 that.buttonElement.attr( "aria-pressed", "true" ); 7729 7730 var radio = that.element[ 0 ]; 7731 radioGroup( radio ) 7732 .not( radio ) 7733 .map(function() { 7734 return $( this ).button( "widget" )[ 0 ]; 7735 }) 7736 .removeClass( "ui-state-active" ) 7737 .attr( "aria-pressed", "false" ); 7738 }); 7739 } else { 7740 this.buttonElement 7741 .bind( "mousedown" + this.eventNamespace, function() { 7742 if ( options.disabled ) { 7743 return false; 7744 } 7745 $( this ).addClass( "ui-state-active" ); 7746 lastActive = this; 7747 that.document.one( "mouseup", function() { 7748 lastActive = null; 7749 }); 7750 }) 7751 .bind( "mouseup" + this.eventNamespace, function() { 7752 if ( options.disabled ) { 7753 return false; 7754 } 7755 $( this ).removeClass( "ui-state-active" ); 7756 }) 7757 .bind( "keydown" + this.eventNamespace, function(event) { 7758 if ( options.disabled ) { 7759 return false; 7760 } 7761 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7762 $( this ).addClass( "ui-state-active" ); 7763 } 7764 }) 7765 // see #8559, we bind to blur here in case the button element loses 7766 // focus between keydown and keyup, it would be left in an "active" state 7767 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7768 $( this ).removeClass( "ui-state-active" ); 7769 }); 7770 7771 if ( this.buttonElement.is("a") ) { 7772 this.buttonElement.keyup(function(event) { 7773 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7774 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7775 $( this ).click(); 7776 } 7777 }); 7778 } 7779 } 7780 7781 this._setOption( "disabled", options.disabled ); 7782 this._resetButton(); 7783 }, 7784 7785 _determineButtonType: function() { 7786 var ancestor, labelSelector, checked; 7787 7788 if ( this.element.is("[type=checkbox]") ) { 7789 this.type = "checkbox"; 7790 } else if ( this.element.is("[type=radio]") ) { 7791 this.type = "radio"; 7792 } else if ( this.element.is("input") ) { 7793 this.type = "input"; 7794 } else { 7795 this.type = "button"; 7796 } 7797 7798 if ( this.type === "checkbox" || this.type === "radio" ) { 7799 // we don't search against the document in case the element 7800 // is disconnected from the DOM 7801 ancestor = this.element.parents().last(); 7802 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7803 this.buttonElement = ancestor.find( labelSelector ); 7804 if ( !this.buttonElement.length ) { 7805 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7806 this.buttonElement = ancestor.filter( labelSelector ); 7807 if ( !this.buttonElement.length ) { 7808 this.buttonElement = ancestor.find( labelSelector ); 7809 } 7810 } 7811 this.element.addClass( "ui-helper-hidden-accessible" ); 7812 7813 checked = this.element.is( ":checked" ); 7814 if ( checked ) { 7815 this.buttonElement.addClass( "ui-state-active" ); 7816 } 7817 this.buttonElement.prop( "aria-pressed", checked ); 7818 } else { 7819 this.buttonElement = this.element; 7820 } 7821 }, 7822 7823 widget: function() { 7824 return this.buttonElement; 7825 }, 7826 7827 _destroy: function() { 7828 this.element 7829 .removeClass( "ui-helper-hidden-accessible" ); 7830 this.buttonElement 7831 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 7832 .removeAttr( "role" ) 7833 .removeAttr( "aria-pressed" ) 7834 .html( this.buttonElement.find(".ui-button-text").html() ); 7835 7836 if ( !this.hasTitle ) { 7837 this.buttonElement.removeAttr( "title" ); 7838 } 7839 }, 7840 7841 _setOption: function( key, value ) { 7842 this._super( key, value ); 7843 if ( key === "disabled" ) { 7844 this.widget().toggleClass( "ui-state-disabled", !!value ); 7845 this.element.prop( "disabled", !!value ); 7846 if ( value ) { 7847 if ( this.type === "checkbox" || this.type === "radio" ) { 7848 this.buttonElement.removeClass( "ui-state-focus" ); 7849 } else { 7850 this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); 7851 } 7852 } 7853 return; 7854 } 7855 this._resetButton(); 7856 }, 7857 7858 refresh: function() { 7859 //See #8237 & #8828 7860 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7861 7862 if ( isDisabled !== this.options.disabled ) { 7863 this._setOption( "disabled", isDisabled ); 7864 } 7865 if ( this.type === "radio" ) { 7866 radioGroup( this.element[0] ).each(function() { 7867 if ( $( this ).is( ":checked" ) ) { 7868 $( this ).button( "widget" ) 7869 .addClass( "ui-state-active" ) 7870 .attr( "aria-pressed", "true" ); 7871 } else { 7872 $( this ).button( "widget" ) 7873 .removeClass( "ui-state-active" ) 7874 .attr( "aria-pressed", "false" ); 7875 } 7876 }); 7877 } else if ( this.type === "checkbox" ) { 7878 if ( this.element.is( ":checked" ) ) { 7879 this.buttonElement 7880 .addClass( "ui-state-active" ) 7881 .attr( "aria-pressed", "true" ); 7882 } else { 7883 this.buttonElement 7884 .removeClass( "ui-state-active" ) 7885 .attr( "aria-pressed", "false" ); 7886 } 7887 } 7888 }, 7889 7890 _resetButton: function() { 7891 if ( this.type === "input" ) { 7892 if ( this.options.label ) { 7893 this.element.val( this.options.label ); 7894 } 7895 return; 7896 } 7897 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7898 buttonText = $( "<span></span>", this.document[0] ) 7899 .addClass( "ui-button-text" ) 7900 .html( this.options.label ) 7901 .appendTo( buttonElement.empty() ) 7902 .text(), 7903 icons = this.options.icons, 7904 multipleIcons = icons.primary && icons.secondary, 7905 buttonClasses = []; 7906 7907 if ( icons.primary || icons.secondary ) { 7908 if ( this.options.text ) { 7909 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7910 } 7911 7912 if ( icons.primary ) { 7913 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7914 } 7915 7916 if ( icons.secondary ) { 7917 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7918 } 7919 7920 if ( !this.options.text ) { 7921 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7922 7923 if ( !this.hasTitle ) { 7924 buttonElement.attr( "title", $.trim( buttonText ) ); 7925 } 7926 } 7927 } else { 7928 buttonClasses.push( "ui-button-text-only" ); 7929 } 7930 buttonElement.addClass( buttonClasses.join( " " ) ); 7931 } 7932}); 7933 7934$.widget( "ui.buttonset", { 7935 version: "1.11.2", 7936 options: { 7937 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7938 }, 7939 7940 _create: function() { 7941 this.element.addClass( "ui-buttonset" ); 7942 }, 7943 7944 _init: function() { 7945 this.refresh(); 7946 }, 7947 7948 _setOption: function( key, value ) { 7949 if ( key === "disabled" ) { 7950 this.buttons.button( "option", key, value ); 7951 } 7952 7953 this._super( key, value ); 7954 }, 7955 7956 refresh: function() { 7957 var rtl = this.element.css( "direction" ) === "rtl", 7958 allButtons = this.element.find( this.options.items ), 7959 existingButtons = allButtons.filter( ":ui-button" ); 7960 7961 // Initialize new buttons 7962 allButtons.not( ":ui-button" ).button(); 7963 7964 // Refresh existing buttons 7965 existingButtons.button( "refresh" ); 7966 7967 this.buttons = allButtons 7968 .map(function() { 7969 return $( this ).button( "widget" )[ 0 ]; 7970 }) 7971 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7972 .filter( ":first" ) 7973 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7974 .end() 7975 .filter( ":last" ) 7976 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7977 .end() 7978 .end(); 7979 }, 7980 7981 _destroy: function() { 7982 this.element.removeClass( "ui-buttonset" ); 7983 this.buttons 7984 .map(function() { 7985 return $( this ).button( "widget" )[ 0 ]; 7986 }) 7987 .removeClass( "ui-corner-left ui-corner-right" ) 7988 .end() 7989 .button( "destroy" ); 7990 } 7991}); 7992 7993var button = $.ui.button; 7994 7995 7996/*! 7997 * jQuery UI Datepicker 1.11.2 7998 * http://jqueryui.com 7999 * 8000 * Copyright 2014 jQuery Foundation and other contributors 8001 * Released under the MIT license. 8002 * http://jquery.org/license 8003 * 8004 * http://api.jqueryui.com/datepicker/ 8005 */ 8006 8007 8008$.extend($.ui, { datepicker: { version: "1.11.2" } }); 8009 8010var datepicker_instActive; 8011 8012function datepicker_getZindex( elem ) { 8013 var position, value; 8014 while ( elem.length && elem[ 0 ] !== document ) { 8015 // Ignore z-index if position is set to a value where z-index is ignored by the browser 8016 // This makes behavior of this function consistent across browsers 8017 // WebKit always returns auto if the element is positioned 8018 position = elem.css( "position" ); 8019 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 8020 // IE returns 0 when zIndex is not specified 8021 // other browsers return a string 8022 // we ignore the case of nested elements with an explicit value of 0 8023 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 8024 value = parseInt( elem.css( "zIndex" ), 10 ); 8025 if ( !isNaN( value ) && value !== 0 ) { 8026 return value; 8027 } 8028 } 8029 elem = elem.parent(); 8030 } 8031 8032 return 0; 8033} 8034/* Date picker manager. 8035 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 8036 Settings for (groups of) date pickers are maintained in an instance object, 8037 allowing multiple different settings on the same page. */ 8038 8039function Datepicker() { 8040 this._curInst = null; // The current instance in use 8041 this._keyEvent = false; // If the last event was a key event 8042 this._disabledInputs = []; // List of date picker inputs that have been disabled 8043 this._datepickerShowing = false; // True if the popup picker is showing , false if not 8044 this._inDialog = false; // True if showing within a "dialog", false if not 8045 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 8046 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 8047 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 8048 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 8049 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 8050 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 8051 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 8052 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 8053 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 8054 this.regional = []; // Available regional settings, indexed by language code 8055 this.regional[""] = { // Default regional settings 8056 closeText: "Done", // Display text for close link 8057 prevText: "Prev", // Display text for previous month link 8058 nextText: "Next", // Display text for next month link 8059 currentText: "Today", // Display text for current month link 8060 monthNames: ["January","February","March","April","May","June", 8061 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 8062 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 8063 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 8064 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 8065 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 8066 weekHeader: "Wk", // Column header for week of the year 8067 dateFormat: "mm/dd/yy", // See format options on parseDate 8068 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 8069 isRTL: false, // True if right-to-left language, false if left-to-right 8070 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 8071 yearSuffix: "" // Additional text to append to the year in the month headers 8072 }; 8073 this._defaults = { // Global defaults for all the date picker instances 8074 showOn: "focus", // "focus" for popup on focus, 8075 // "button" for trigger button, or "both" for either
vendor: 6,658 bytes, lines 8076-8207
8076 showAnim: "fadeIn", // Name of jQuery animation for popup 8077 showOptions: {}, // Options for enhanced animations 8078 defaultDate: null, // Used when field is blank: actual date, 8079 // +/-number for offset from today, null for today 8080 appendText: "", // Display text following the input box, e.g. showing the format 8081 buttonText: "...", // Text for trigger button 8082 buttonImage: "", // URL for trigger button image 8083 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 8084 hideIfNoPrevNext: false, // True to hide next/previous month links 8085 // if not applicable, false to just disable them 8086 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 8087 gotoCurrent: false, // True if today link goes back to current selection instead 8088 changeMonth: false, // True if month can be selected directly, false if only prev/next 8089 changeYear: false, // True if year can be selected directly, false if only prev/next 8090 yearRange: "c-10:c+10", // Range of years to display in drop-down, 8091 // either relative to today's year (-nn:+nn), relative to currently displayed year 8092 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 8093 showOtherMonths: false, // True to show dates in other months, false to leave blank 8094 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 8095 showWeek: false, // True to show week of the year, false to not show it 8096 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 8097 // takes a Date and returns the number of the week for it 8098 shortYearCutoff: "+10", // Short year values < this are in the current century, 8099 // > this are in the previous century, 8100 // string value starting with "+" for current year + value 8101 minDate: null, // The earliest selectable date, or null for no limit 8102 maxDate: null, // The latest selectable date, or null for no limit 8103 duration: "fast", // Duration of display/closure 8104 beforeShowDay: null, // Function that takes a date and returns an array with 8105 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 8106 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 8107 beforeShow: null, // Function that takes an input field and 8108 // returns a set of custom settings for the date picker 8109 onSelect: null, // Define a callback function when a date is selected 8110 onChangeMonthYear: null, // Define a callback function when the month or year is changed 8111 onClose: null, // Define a callback function when the datepicker is closed 8112 numberOfMonths: 1, // Number of months to show at a time 8113 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 8114 stepMonths: 1, // Number of months to step back/forward 8115 stepBigMonths: 12, // Number of months to step back/forward for the big links 8116 altField: "", // Selector for an alternate field to store selected dates into 8117 altFormat: "", // The date format to use for the alternate field 8118 constrainInput: true, // The input is constrained by the current date format 8119 showButtonPanel: false, // True to show button panel, false to not show it 8120 autoSize: false, // True to size the input for the date format, false to leave as is 8121 disabled: false // The initial disabled state 8122 }; 8123 $.extend(this._defaults, this.regional[""]); 8124 this.regional.en = $.extend( true, {}, this.regional[ "" ]); 8125 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 8126 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 8127} 8128 8129$.extend(Datepicker.prototype, { 8130 /* Class name added to elements to indicate already configured with a date picker. */ 8131 markerClassName: "hasDatepicker", 8132 8133 //Keep track of the maximum number of rows displayed (see #7043) 8134 maxRows: 4, 8135 8136 // TODO rename to "widget" when switching to widget factory 8137 _widgetDatepicker: function() { 8138 return this.dpDiv; 8139 }, 8140 8141 /* Override the default settings for all instances of the date picker. 8142 * @param settings object - the new settings to use as defaults (anonymous object) 8143 * @return the manager object 8144 */ 8145 setDefaults: function(settings) { 8146 datepicker_extendRemove(this._defaults, settings || {}); 8147 return this; 8148 }, 8149 8150 /* Attach the date picker to a jQuery selection. 8151 * @param target element - the target input field or division or span 8152 * @param settings object - the new settings to use for this date picker instance (anonymous) 8153 */ 8154 _attachDatepicker: function(target, settings) { 8155 var nodeName, inline, inst; 8156 nodeName = target.nodeName.toLowerCase(); 8157 inline = (nodeName === "div" || nodeName === "span"); 8158 if (!target.id) { 8159 this.uuid += 1; 8160 target.id = "dp" + this.uuid; 8161 } 8162 inst = this._newInst($(target), inline); 8163 inst.settings = $.extend({}, settings || {}); 8164 if (nodeName === "input") { 8165 this._connectDatepicker(target, inst); 8166 } else if (inline) { 8167 this._inlineDatepicker(target, inst); 8168 } 8169 }, 8170 8171 /* Create a new instance object. */ 8172 _newInst: function(target, inline) { 8173 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 8174 return {id: id, input: target, // associated target 8175 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 8176 drawMonth: 0, drawYear: 0, // month being drawn 8177 inline: inline, // is datepicker inline or not 8178 dpDiv: (!inline ? this.dpDiv : // presentation div 8179 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 8180 }, 8181 8182 /* Attach the date picker to an input field. */ 8183 _connectDatepicker: function(target, inst) { 8184 var input = $(target); 8185 inst.append = $([]); 8186 inst.trigger = $([]); 8187 if (input.hasClass(this.markerClassName)) { 8188 return; 8189 } 8190 this._attachments(input, inst); 8191 input.addClass(this.markerClassName).keydown(this._doKeyDown). 8192 keypress(this._doKeyPress).keyup(this._doKeyUp); 8193 this._autoSize(inst); 8194 $.data(target, "datepicker", inst); 8195 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 8196 if( inst.settings.disabled ) { 8197 this._disableDatepicker( target ); 8198 } 8199 }, 8200 8201 /* Make attachments based on settings. */ 8202 _attachments: function(input, inst) { 8203 var showOn, buttonText, buttonImage, 8204 appendText = this._get(inst, "appendText"), 8205 isRTL = this._get(inst, "isRTL"); 8206 8207 if (inst.append) {
vendor: 5,959 bytes, lines 8208-8363
8208 inst.append.remove(); 8209 } 8210 if (appendText) { 8211 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 8212 input[isRTL ? "before" : "after"](inst.append); 8213 } 8214 8215 input.unbind("focus", this._showDatepicker); 8216 8217 if (inst.trigger) { 8218 inst.trigger.remove(); 8219 } 8220 8221 showOn = this._get(inst, "showOn"); 8222 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 8223 input.focus(this._showDatepicker); 8224 } 8225 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 8226 buttonText = this._get(inst, "buttonText"); 8227 buttonImage = this._get(inst, "buttonImage"); 8228 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 8229 $("<img/>").addClass(this._triggerClass). 8230 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 8231 $("<button type='button'></button>").addClass(this._triggerClass). 8232 html(!buttonImage ? buttonText : $("<img/>").attr( 8233 { src:buttonImage, alt:buttonText, title:buttonText }))); 8234 input[isRTL ? "before" : "after"](inst.trigger); 8235 inst.trigger.click(function() { 8236 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 8237 $.datepicker._hideDatepicker(); 8238 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 8239 $.datepicker._hideDatepicker(); 8240 $.datepicker._showDatepicker(input[0]); 8241 } else { 8242 $.datepicker._showDatepicker(input[0]); 8243 } 8244 return false; 8245 }); 8246 } 8247 }, 8248 8249 /* Apply the maximum length for the date format. */ 8250 _autoSize: function(inst) { 8251 if (this._get(inst, "autoSize") && !inst.inline) { 8252 var findMax, max, maxI, i, 8253 date = new Date(2009, 12 - 1, 20), // Ensure double digits 8254 dateFormat = this._get(inst, "dateFormat"); 8255 8256 if (dateFormat.match(/[DM]/)) { 8257 findMax = function(names) { 8258 max = 0; 8259 maxI = 0; 8260 for (i = 0; i < names.length; i++) { 8261 if (names[i].length > max) { 8262 max = names[i].length; 8263 maxI = i; 8264 } 8265 } 8266 return maxI; 8267 }; 8268 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 8269 "monthNames" : "monthNamesShort")))); 8270 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 8271 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 8272 } 8273 inst.input.attr("size", this._formatDate(inst, date).length); 8274 } 8275 }, 8276 8277 /* Attach an inline date picker to a div. */ 8278 _inlineDatepicker: function(target, inst) { 8279 var divSpan = $(target); 8280 if (divSpan.hasClass(this.markerClassName)) { 8281 return; 8282 } 8283 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 8284 $.data(target, "datepicker", inst); 8285 this._setDate(inst, this._getDefaultDate(inst), true); 8286 this._updateDatepicker(inst); 8287 this._updateAlternate(inst); 8288 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 8289 if( inst.settings.disabled ) { 8290 this._disableDatepicker( target ); 8291 } 8292 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 8293 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 8294 inst.dpDiv.css( "display", "block" ); 8295 }, 8296 8297 /* Pop-up the date picker in a "dialog" box. 8298 * @param input element - ignored 8299 * @param date string or Date - the initial date to display 8300 * @param onSelect function - the function to call when a date is selected 8301 * @param settings object - update the dialog date picker instance's settings (anonymous object) 8302 * @param pos int[2] - coordinates for the dialog's position within the screen or 8303 * event - with x/y coordinates or 8304 * leave empty for default (screen centre) 8305 * @return the manager object 8306 */ 8307 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 8308 var id, browserWidth, browserHeight, scrollX, scrollY, 8309 inst = this._dialogInst; // internal instance 8310 8311 if (!inst) { 8312 this.uuid += 1; 8313 id = "dp" + this.uuid; 8314 this._dialogInput = $("<input type='text' id='" + id + 8315 "' style='position: absolute; top: -100px; width: 0px;'/>"); 8316 this._dialogInput.keydown(this._doKeyDown); 8317 $("body").append(this._dialogInput); 8318 inst = this._dialogInst = this._newInst(this._dialogInput, false); 8319 inst.settings = {}; 8320 $.data(this._dialogInput[0], "datepicker", inst); 8321 } 8322 datepicker_extendRemove(inst.settings, settings || {}); 8323 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 8324 this._dialogInput.val(date); 8325 8326 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 8327 if (!this._pos) { 8328 browserWidth = document.documentElement.clientWidth; 8329 browserHeight = document.documentElement.clientHeight; 8330 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 8331 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 8332 this._pos = // should use actual width/height below 8333 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 8334 } 8335 8336 // move input on screen for focus, but hidden behind dialog 8337 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 8338 inst.settings.onSelect = onSelect; 8339 this._inDialog = true; 8340 this.dpDiv.addClass(this._dialogClass); 8341 this._showDatepicker(this._dialogInput[0]); 8342 if ($.blockUI) { 8343 $.blockUI(this.dpDiv); 8344 } 8345 $.data(this._dialogInput[0], "datepicker", inst); 8346 return this; 8347 }, 8348 8349 /* Detach a datepicker from its control. 8350 * @param target element - the target input field or division or span 8351 */ 8352 _destroyDatepicker: function(target) { 8353 var nodeName, 8354 $target = $(target), 8355 inst = $.data(target, "datepicker"); 8356 8357 if (!$target.hasClass(this.markerClassName)) { 8358 return; 8359 } 8360 8361 nodeName = target.nodeName.toLowerCase(); 8362 $.removeData(target, "datepicker"); 8363 if (nodeName === "input") {
vendor: 11,681 bytes, lines 8364-8695
8364 inst.append.remove(); 8365 inst.trigger.remove(); 8366 $target.removeClass(this.markerClassName). 8367 unbind("focus", this._showDatepicker). 8368 unbind("keydown", this._doKeyDown). 8369 unbind("keypress", this._doKeyPress). 8370 unbind("keyup", this._doKeyUp); 8371 } else if (nodeName === "div" || nodeName === "span") { 8372 $target.removeClass(this.markerClassName).empty(); 8373 } 8374 }, 8375 8376 /* Enable the date picker to a jQuery selection. 8377 * @param target element - the target input field or division or span 8378 */ 8379 _enableDatepicker: function(target) { 8380 var nodeName, inline, 8381 $target = $(target), 8382 inst = $.data(target, "datepicker"); 8383 8384 if (!$target.hasClass(this.markerClassName)) { 8385 return; 8386 } 8387 8388 nodeName = target.nodeName.toLowerCase(); 8389 if (nodeName === "input") { 8390 target.disabled = false; 8391 inst.trigger.filter("button"). 8392 each(function() { this.disabled = false; }).end(). 8393 filter("img").css({opacity: "1.0", cursor: ""}); 8394 } else if (nodeName === "div" || nodeName === "span") { 8395 inline = $target.children("." + this._inlineClass); 8396 inline.children().removeClass("ui-state-disabled"); 8397 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8398 prop("disabled", false); 8399 } 8400 this._disabledInputs = $.map(this._disabledInputs, 8401 function(value) { return (value === target ? null : value); }); // delete entry 8402 }, 8403 8404 /* Disable the date picker to a jQuery selection. 8405 * @param target element - the target input field or division or span 8406 */ 8407 _disableDatepicker: function(target) { 8408 var nodeName, inline, 8409 $target = $(target), 8410 inst = $.data(target, "datepicker"); 8411 8412 if (!$target.hasClass(this.markerClassName)) { 8413 return; 8414 } 8415 8416 nodeName = target.nodeName.toLowerCase(); 8417 if (nodeName === "input") { 8418 target.disabled = true; 8419 inst.trigger.filter("button"). 8420 each(function() { this.disabled = true; }).end(). 8421 filter("img").css({opacity: "0.5", cursor: "default"}); 8422 } else if (nodeName === "div" || nodeName === "span") { 8423 inline = $target.children("." + this._inlineClass); 8424 inline.children().addClass("ui-state-disabled"); 8425 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8426 prop("disabled", true); 8427 } 8428 this._disabledInputs = $.map(this._disabledInputs, 8429 function(value) { return (value === target ? null : value); }); // delete entry 8430 this._disabledInputs[this._disabledInputs.length] = target; 8431 }, 8432 8433 /* Is the first field in a jQuery collection disabled as a datepicker? 8434 * @param target element - the target input field or division or span 8435 * @return boolean - true if disabled, false if enabled 8436 */ 8437 _isDisabledDatepicker: function(target) { 8438 if (!target) { 8439 return false; 8440 } 8441 for (var i = 0; i < this._disabledInputs.length; i++) { 8442 if (this._disabledInputs[i] === target) { 8443 return true; 8444 } 8445 } 8446 return false; 8447 }, 8448 8449 /* Retrieve the instance data for the target control. 8450 * @param target element - the target input field or division or span 8451 * @return object - the associated instance data 8452 * @throws error if a jQuery problem getting data 8453 */ 8454 _getInst: function(target) { 8455 try { 8456 return $.data(target, "datepicker"); 8457 } 8458 catch (err) { 8459 throw "Missing instance data for this datepicker"; 8460 } 8461 }, 8462 8463 /* Update or retrieve the settings for a date picker attached to an input field or division. 8464 * @param target element - the target input field or division or span 8465 * @param name object - the new settings to update or 8466 * string - the name of the setting to change or retrieve, 8467 * when retrieving also "all" for all instance settings or 8468 * "defaults" for all global defaults 8469 * @param value any - the new value for the setting 8470 * (omit if above is an object or to retrieve a value) 8471 */ 8472 _optionDatepicker: function(target, name, value) { 8473 var settings, date, minDate, maxDate, 8474 inst = this._getInst(target); 8475 8476 if (arguments.length === 2 && typeof name === "string") { 8477 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8478 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8479 this._get(inst, name)) : null)); 8480 } 8481 8482 settings = name || {}; 8483 if (typeof name === "string") { 8484 settings = {}; 8485 settings[name] = value; 8486 } 8487 8488 if (inst) { 8489 if (this._curInst === inst) { 8490 this._hideDatepicker(); 8491 } 8492 8493 date = this._getDateDatepicker(target, true); 8494 minDate = this._getMinMaxDate(inst, "min"); 8495 maxDate = this._getMinMaxDate(inst, "max"); 8496 datepicker_extendRemove(inst.settings, settings); 8497 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8498 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8499 inst.settings.minDate = this._formatDate(inst, minDate); 8500 } 8501 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8502 inst.settings.maxDate = this._formatDate(inst, maxDate); 8503 } 8504 if ( "disabled" in settings ) { 8505 if ( settings.disabled ) { 8506 this._disableDatepicker(target); 8507 } else { 8508 this._enableDatepicker(target); 8509 } 8510 } 8511 this._attachments($(target), inst); 8512 this._autoSize(inst); 8513 this._setDate(inst, date); 8514 this._updateAlternate(inst); 8515 this._updateDatepicker(inst); 8516 } 8517 }, 8518 8519 // change method deprecated 8520 _changeDatepicker: function(target, name, value) { 8521 this._optionDatepicker(target, name, value); 8522 }, 8523 8524 /* Redraw the date picker attached to an input field or division. 8525 * @param target element - the target input field or division or span 8526 */ 8527 _refreshDatepicker: function(target) { 8528 var inst = this._getInst(target); 8529 if (inst) { 8530 this._updateDatepicker(inst); 8531 } 8532 }, 8533 8534 /* Set the dates for a jQuery selection. 8535 * @param target element - the target input field or division or span 8536 * @param date Date - the new date 8537 */ 8538 _setDateDatepicker: function(target, date) { 8539 var inst = this._getInst(target); 8540 if (inst) { 8541 this._setDate(inst, date); 8542 this._updateDatepicker(inst); 8543 this._updateAlternate(inst); 8544 } 8545 }, 8546 8547 /* Get the date(s) for the first entry in a jQuery selection. 8548 * @param target element - the target input field or division or span 8549 * @param noDefault boolean - true if no default date is to be used 8550 * @return Date - the current date 8551 */ 8552 _getDateDatepicker: function(target, noDefault) { 8553 var inst = this._getInst(target); 8554 if (inst && !inst.inline) { 8555 this._setDateFromField(inst, noDefault); 8556 } 8557 return (inst ? this._getDate(inst) : null); 8558 }, 8559 8560 /* Handle keystrokes. */ 8561 _doKeyDown: function(event) { 8562 var onSelect, dateStr, sel, 8563 inst = $.datepicker._getInst(event.target), 8564 handled = true, 8565 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8566 8567 inst._keyEvent = true; 8568 if ($.datepicker._datepickerShowing) { 8569 switch (event.keyCode) { 8570 case 9: $.datepicker._hideDatepicker(); 8571 handled = false; 8572 break; // hide on tab out 8573 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8574 $.datepicker._currentClass + ")", inst.dpDiv); 8575 if (sel[0]) { 8576 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8577 } 8578 8579 onSelect = $.datepicker._get(inst, "onSelect"); 8580 if (onSelect) { 8581 dateStr = $.datepicker._formatDate(inst); 8582 8583 // trigger custom callback 8584 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8585 } else { 8586 $.datepicker._hideDatepicker(); 8587 } 8588 8589 return false; // don't submit the form 8590 case 27: $.datepicker._hideDatepicker(); 8591 break; // hide on escape 8592 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8593 -$.datepicker._get(inst, "stepBigMonths") : 8594 -$.datepicker._get(inst, "stepMonths")), "M"); 8595 break; // previous month/year on page up/+ ctrl 8596 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8597 +$.datepicker._get(inst, "stepBigMonths") : 8598 +$.datepicker._get(inst, "stepMonths")), "M"); 8599 break; // next month/year on page down/+ ctrl 8600 case 35: if (event.ctrlKey || event.metaKey) { 8601 $.datepicker._clearDate(event.target); 8602 } 8603 handled = event.ctrlKey || event.metaKey; 8604 break; // clear on ctrl or command +end 8605 case 36: if (event.ctrlKey || event.metaKey) { 8606 $.datepicker._gotoToday(event.target); 8607 } 8608 handled = event.ctrlKey || event.metaKey; 8609 break; // current on ctrl or command +home 8610 case 37: if (event.ctrlKey || event.metaKey) { 8611 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8612 } 8613 handled = event.ctrlKey || event.metaKey; 8614 // -1 day on ctrl or command +left 8615 if (event.originalEvent.altKey) { 8616 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8617 -$.datepicker._get(inst, "stepBigMonths") : 8618 -$.datepicker._get(inst, "stepMonths")), "M"); 8619 } 8620 // next month/year on alt +left on Mac 8621 break; 8622 case 38: if (event.ctrlKey || event.metaKey) { 8623 $.datepicker._adjustDate(event.target, -7, "D"); 8624 } 8625 handled = event.ctrlKey || event.metaKey; 8626 break; // -1 week on ctrl or command +up 8627 case 39: if (event.ctrlKey || event.metaKey) { 8628 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8629 } 8630 handled = event.ctrlKey || event.metaKey; 8631 // +1 day on ctrl or command +right 8632 if (event.originalEvent.altKey) { 8633 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8634 +$.datepicker._get(inst, "stepBigMonths") : 8635 +$.datepicker._get(inst, "stepMonths")), "M"); 8636 } 8637 // next month/year on alt +right 8638 break; 8639 case 40: if (event.ctrlKey || event.metaKey) { 8640 $.datepicker._adjustDate(event.target, +7, "D"); 8641 } 8642 handled = event.ctrlKey || event.metaKey; 8643 break; // +1 week on ctrl or command +down 8644 default: handled = false; 8645 } 8646 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8647 $.datepicker._showDatepicker(this); 8648 } else { 8649 handled = false; 8650 } 8651 8652 if (handled) { 8653 event.preventDefault(); 8654 event.stopPropagation(); 8655 } 8656 }, 8657 8658 /* Filter entered characters - based on date format. */ 8659 _doKeyPress: function(event) { 8660 var chars, chr, 8661 inst = $.datepicker._getInst(event.target); 8662 8663 if ($.datepicker._get(inst, "constrainInput")) { 8664 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8665 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8666 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8667 } 8668 }, 8669 8670 /* Synchronise manual entry and field/alternate field. */ 8671 _doKeyUp: function(event) { 8672 var date, 8673 inst = $.datepicker._getInst(event.target); 8674 8675 if (inst.input.val() !== inst.lastVal) { 8676 try { 8677 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8678 (inst.input ? inst.input.val() : null), 8679 $.datepicker._getFormatConfig(inst)); 8680 8681 if (date) { // only if valid 8682 $.datepicker._setDateFromField(inst); 8683 $.datepicker._updateAlternate(inst); 8684 $.datepicker._updateDatepicker(inst); 8685 } 8686 } 8687 catch (err) { 8688 } 8689 } 8690 return true; 8691 }, 8692 8693 /* Pop-up the date picker for a given input field. 8694 * If false returned from beforeShow event handler do not show. 8695 * @param input element - the input field attached to the date picker or
vendor: 14,240 bytes, lines 8696-9102
8696 * event - if triggered by focus 8697 */ 8698 _showDatepicker: function(input) { 8699 input = input.target || input; 8700 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8701 input = $("input", input.parentNode)[0]; 8702 } 8703 8704 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8705 return; 8706 } 8707 8708 var inst, beforeShow, beforeShowSettings, isFixed, 8709 offset, showAnim, duration; 8710 8711 inst = $.datepicker._getInst(input); 8712 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8713 $.datepicker._curInst.dpDiv.stop(true, true); 8714 if ( inst && $.datepicker._datepickerShowing ) { 8715 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8716 } 8717 } 8718 8719 beforeShow = $.datepicker._get(inst, "beforeShow"); 8720 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8721 if(beforeShowSettings === false){ 8722 return; 8723 } 8724 datepicker_extendRemove(inst.settings, beforeShowSettings); 8725 8726 inst.lastVal = null; 8727 $.datepicker._lastInput = input; 8728 $.datepicker._setDateFromField(inst); 8729 8730 if ($.datepicker._inDialog) { // hide cursor 8731 input.value = ""; 8732 } 8733 if (!$.datepicker._pos) { // position below input 8734 $.datepicker._pos = $.datepicker._findPos(input); 8735 $.datepicker._pos[1] += input.offsetHeight; // add the height 8736 } 8737 8738 isFixed = false; 8739 $(input).parents().each(function() { 8740 isFixed |= $(this).css("position") === "fixed"; 8741 return !isFixed; 8742 }); 8743 8744 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8745 $.datepicker._pos = null; 8746 //to avoid flashes on Firefox 8747 inst.dpDiv.empty(); 8748 // determine sizing offscreen 8749 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8750 $.datepicker._updateDatepicker(inst); 8751 // fix width for dynamic number of date pickers 8752 // and adjust position before showing 8753 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8754 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8755 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8756 left: offset.left + "px", top: offset.top + "px"}); 8757 8758 if (!inst.inline) { 8759 showAnim = $.datepicker._get(inst, "showAnim"); 8760 duration = $.datepicker._get(inst, "duration"); 8761 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 8762 $.datepicker._datepickerShowing = true; 8763 8764 if ( $.effects && $.effects.effect[ showAnim ] ) { 8765 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8766 } else { 8767 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8768 } 8769 8770 if ( $.datepicker._shouldFocusInput( inst ) ) { 8771 inst.input.focus(); 8772 } 8773 8774 $.datepicker._curInst = inst; 8775 } 8776 }, 8777 8778 /* Generate the date picker content. */ 8779 _updateDatepicker: function(inst) { 8780 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8781 datepicker_instActive = inst; // for delegate hover events 8782 inst.dpDiv.empty().append(this._generateHTML(inst)); 8783 this._attachHandlers(inst); 8784 8785 var origyearshtml, 8786 numMonths = this._getNumberOfMonths(inst), 8787 cols = numMonths[1], 8788 width = 17, 8789 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 8790 8791 if ( activeCell.length > 0 ) { 8792 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 8793 } 8794 8795 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8796 if (cols > 1) { 8797 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8798 } 8799 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8800 "Class"]("ui-datepicker-multi"); 8801 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8802 "Class"]("ui-datepicker-rtl"); 8803 8804 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8805 inst.input.focus(); 8806 } 8807 8808 // deffered render of the years select (to avoid flashes on Firefox) 8809 if( inst.yearshtml ){ 8810 origyearshtml = inst.yearshtml; 8811 setTimeout(function(){ 8812 //assure that inst.yearshtml didn't change. 8813 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8814 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8815 } 8816 origyearshtml = inst.yearshtml = null; 8817 }, 0); 8818 } 8819 }, 8820 8821 // #6694 - don't focus the input if it's already focused 8822 // this breaks the change event in IE 8823 // Support: IE and jQuery <1.9 8824 _shouldFocusInput: function( inst ) { 8825 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 8826 }, 8827 8828 /* Check positioning to remain on screen. */ 8829 _checkOffset: function(inst, offset, isFixed) { 8830 var dpWidth = inst.dpDiv.outerWidth(), 8831 dpHeight = inst.dpDiv.outerHeight(), 8832 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8833 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8834 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8835 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8836 8837 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8838 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8839 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8840 8841 // now check if datepicker is showing outside window viewport - move to a better place if so. 8842 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8843 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8844 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8845 Math.abs(dpHeight + inputHeight) : 0); 8846 8847 return offset; 8848 }, 8849 8850 /* Find an object's position on the screen. */ 8851 _findPos: function(obj) { 8852 var position, 8853 inst = this._getInst(obj), 8854 isRTL = this._get(inst, "isRTL"); 8855 8856 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8857 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8858 } 8859 8860 position = $(obj).offset(); 8861 return [position.left, position.top]; 8862 }, 8863 8864 /* Hide the date picker from view. 8865 * @param input element - the input field attached to the date picker 8866 */ 8867 _hideDatepicker: function(input) { 8868 var showAnim, duration, postProcess, onClose, 8869 inst = this._curInst; 8870 8871 if (!inst || (input && inst !== $.data(input, "datepicker"))) { 8872 return; 8873 } 8874 8875 if (this._datepickerShowing) { 8876 showAnim = this._get(inst, "showAnim"); 8877 duration = this._get(inst, "duration"); 8878 postProcess = function() { 8879 $.datepicker._tidyDialog(inst); 8880 }; 8881 8882 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8883 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8884 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8885 } else { 8886 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8887 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8888 } 8889 8890 if (!showAnim) { 8891 postProcess(); 8892 } 8893 this._datepickerShowing = false; 8894 8895 onClose = this._get(inst, "onClose"); 8896 if (onClose) { 8897 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8898 } 8899 8900 this._lastInput = null; 8901 if (this._inDialog) { 8902 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8903 if ($.blockUI) { 8904 $.unblockUI(); 8905 $("body").append(this.dpDiv); 8906 } 8907 } 8908 this._inDialog = false; 8909 } 8910 }, 8911 8912 /* Tidy up after a dialog display. */ 8913 _tidyDialog: function(inst) { 8914 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8915 }, 8916 8917 /* Close date picker if clicked elsewhere. */ 8918 _checkExternalClick: function(event) { 8919 if (!$.datepicker._curInst) { 8920 return; 8921 } 8922 8923 var $target = $(event.target), 8924 inst = $.datepicker._getInst($target[0]); 8925 8926 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8927 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8928 !$target.hasClass($.datepicker.markerClassName) && 8929 !$target.closest("." + $.datepicker._triggerClass).length && 8930 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8931 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8932 $.datepicker._hideDatepicker(); 8933 } 8934 }, 8935 8936 /* Adjust one of the date sub-fields. */ 8937 _adjustDate: function(id, offset, period) { 8938 var target = $(id), 8939 inst = this._getInst(target[0]); 8940 8941 if (this._isDisabledDatepicker(target[0])) { 8942 return; 8943 } 8944 this._adjustInstDate(inst, offset + 8945 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8946 period); 8947 this._updateDatepicker(inst); 8948 }, 8949 8950 /* Action for current link. */ 8951 _gotoToday: function(id) { 8952 var date, 8953 target = $(id), 8954 inst = this._getInst(target[0]); 8955 8956 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8957 inst.selectedDay = inst.currentDay; 8958 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8959 inst.drawYear = inst.selectedYear = inst.currentYear; 8960 } else { 8961 date = new Date(); 8962 inst.selectedDay = date.getDate(); 8963 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8964 inst.drawYear = inst.selectedYear = date.getFullYear(); 8965 } 8966 this._notifyChange(inst); 8967 this._adjustDate(target); 8968 }, 8969 8970 /* Action for selecting a new month/year. */ 8971 _selectMonthYear: function(id, select, period) { 8972 var target = $(id), 8973 inst = this._getInst(target[0]); 8974 8975 inst["selected" + (period === "M" ? "Month" : "Year")] = 8976 inst["draw" + (period === "M" ? "Month" : "Year")] = 8977 parseInt(select.options[select.selectedIndex].value,10); 8978 8979 this._notifyChange(inst); 8980 this._adjustDate(target); 8981 }, 8982 8983 /* Action for selecting a day. */ 8984 _selectDay: function(id, month, year, td) { 8985 var inst, 8986 target = $(id); 8987 8988 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8989 return; 8990 } 8991 8992 inst = this._getInst(target[0]); 8993 inst.selectedDay = inst.currentDay = $("a", td).html(); 8994 inst.selectedMonth = inst.currentMonth = month; 8995 inst.selectedYear = inst.currentYear = year; 8996 this._selectDate(id, this._formatDate(inst, 8997 inst.currentDay, inst.currentMonth, inst.currentYear)); 8998 }, 8999 9000 /* Erase the input field and hide the date picker. */ 9001 _clearDate: function(id) { 9002 var target = $(id); 9003 this._selectDate(target, ""); 9004 }, 9005 9006 /* Update the input field with the selected date. */ 9007 _selectDate: function(id, dateStr) { 9008 var onSelect, 9009 target = $(id), 9010 inst = this._getInst(target[0]); 9011 9012 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 9013 if (inst.input) { 9014 inst.input.val(dateStr); 9015 } 9016 this._updateAlternate(inst); 9017 9018 onSelect = this._get(inst, "onSelect"); 9019 if (onSelect) { 9020 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 9021 } else if (inst.input) { 9022 inst.input.trigger("change"); // fire the change event 9023 } 9024 9025 if (inst.inline){ 9026 this._updateDatepicker(inst); 9027 } else { 9028 this._hideDatepicker(); 9029 this._lastInput = inst.input[0]; 9030 if (typeof(inst.input[0]) !== "object") { 9031 inst.input.focus(); // restore focus 9032 } 9033 this._lastInput = null; 9034 } 9035 }, 9036 9037 /* Update any alternate field to synchronise with the main field. */ 9038 _updateAlternate: function(inst) { 9039 var altFormat, date, dateStr, 9040 altField = this._get(inst, "altField"); 9041 9042 if (altField) { // update alternate field too 9043 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 9044 date = this._getDate(inst); 9045 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 9046 $(altField).each(function() { $(this).val(dateStr); }); 9047 } 9048 }, 9049 9050 /* Set as beforeShowDay function to prevent selection of weekends. 9051 * @param date Date - the date to customise 9052 * @return [boolean, string] - is this date selectable?, what is its CSS class? 9053 */ 9054 noWeekends: function(date) { 9055 var day = date.getDay(); 9056 return [(day > 0 && day < 6), ""]; 9057 }, 9058 9059 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 9060 * @param date Date - the date to get the week for 9061 * @return number - the number of the week within the year that contains this date 9062 */ 9063 iso8601Week: function(date) { 9064 var time, 9065 checkDate = new Date(date.getTime()); 9066 9067 // Find Thursday of this week starting on Monday 9068 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 9069 9070 time = checkDate.getTime(); 9071 checkDate.setMonth(0); // Compare with Jan 1 9072 checkDate.setDate(1); 9073 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 9074 }, 9075 9076 /* Parse a string value into a date object. 9077 * See formatDate below for the possible formats. 9078 * 9079 * @param format string - the expected format of the date 9080 * @param value string - the date in the above format 9081 * @param settings Object - attributes include: 9082 * shortYearCutoff number - the cutoff year for determining the century (optional) 9083 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 9084 * dayNames string[7] - names of the days from Sunday (optional) 9085 * monthNamesShort string[12] - abbreviated names of the months (optional) 9086 * monthNames string[12] - names of the months (optional) 9087 * @return Date - the extracted date value or null if value is blank 9088 */ 9089 parseDate: function (format, value, settings) { 9090 if (format == null || value == null) { 9091 throw "Invalid arguments"; 9092 } 9093 9094 value = (typeof value === "object" ? value.toString() : value + ""); 9095 if (value === "") { 9096 return null; 9097 } 9098 9099 var iFormat, dim, extra, 9100 iValue = 0, 9101 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 9102 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 15,764 bytes, lines 9102-9603
9102: 9103 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 9104 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 9105 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 9106 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 9107 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 9108 year = -1, 9109 month = -1, 9110 day = -1, 9111 doy = -1, 9112 literal = false, 9113 date, 9114 // Check whether a format character is doubled 9115 lookAhead = function(match) { 9116 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 9117 if (matches) { 9118 iFormat++; 9119 } 9120 return matches; 9121 }, 9122 // Extract a number from the string value 9123 getNumber = function(match) { 9124 var isDoubled = lookAhead(match), 9125 size = (match === "@" ? 14 : (match === "!" ? 20 : 9126 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 9127 minSize = (match === "y" ? size : 1), 9128 digits = new RegExp("^\\d{" + minSize + "," + size + "}"), 9129 num = value.substring(iValue).match(digits); 9130 if (!num) { 9131 throw "Missing number at position " + iValue; 9132 } 9133 iValue += num[0].length; 9134 return parseInt(num[0], 10); 9135 }, 9136 // Extract a name from the string value and convert to an index 9137 getName = function(match, shortNames, longNames) { 9138 var index = -1, 9139 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 9140 return [ [k, v] ]; 9141 }).sort(function (a, b) { 9142 return -(a[1].length - b[1].length); 9143 }); 9144 9145 $.each(names, function (i, pair) { 9146 var name = pair[1]; 9147 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 9148 index = pair[0]; 9149 iValue += name.length; 9150 return false; 9151 } 9152 }); 9153 if (index !== -1) { 9154 return index + 1; 9155 } else { 9156 throw "Unknown name at position " + iValue; 9157 } 9158 }, 9159 // Confirm that a literal character matches the string value 9160 checkLiteral = function() { 9161 if (value.charAt(iValue) !== format.charAt(iFormat)) { 9162 throw "Unexpected literal at position " + iValue; 9163 } 9164 iValue++; 9165 }; 9166 9167 for (iFormat = 0; iFormat < format.length; iFormat++) { 9168 if (literal) { 9169 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9170 literal = false; 9171 } else { 9172 checkLiteral(); 9173 } 9174 } else { 9175 switch (format.charAt(iFormat)) { 9176 case "d": 9177 day = getNumber("d"); 9178 break; 9179 case "D": 9180 getName("D", dayNamesShort, dayNames); 9181 break; 9182 case "o": 9183 doy = getNumber("o"); 9184 break; 9185 case "m": 9186 month = getNumber("m"); 9187 break; 9188 case "M": 9189 month = getName("M", monthNamesShort, monthNames); 9190 break; 9191 case "y": 9192 year = getNumber("y"); 9193 break; 9194 case "@": 9195 date = new Date(getNumber("@")); 9196 year = date.getFullYear(); 9197 month = date.getMonth() + 1; 9198 day = date.getDate(); 9199 break; 9200 case "!": 9201 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 9202 year = date.getFullYear(); 9203 month = date.getMonth() + 1; 9204 day = date.getDate(); 9205 break; 9206 case "'": 9207 if (lookAhead("'")){ 9208 checkLiteral(); 9209 } else { 9210 literal = true; 9211 } 9212 break; 9213 default: 9214 checkLiteral(); 9215 } 9216 } 9217 } 9218 9219 if (iValue < value.length){ 9220 extra = value.substr(iValue); 9221 if (!/^\s+/.test(extra)) { 9222 throw "Extra/unparsed characters found in date: " + extra; 9223 } 9224 } 9225 9226 if (year === -1) { 9227 year = new Date().getFullYear(); 9228 } else if (year < 100) { 9229 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 9230 (year <= shortYearCutoff ? 0 : -100); 9231 } 9232 9233 if (doy > -1) { 9234 month = 1; 9235 day = doy; 9236 do { 9237 dim = this._getDaysInMonth(year, month - 1); 9238 if (day <= dim) { 9239 break; 9240 } 9241 month++; 9242 day -= dim; 9243 } while (true); 9244 } 9245 9246 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 9247 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 9248 throw "Invalid date"; // E.g. 31/02/00 9249 } 9250 return date; 9251 }, 9252 9253 /* Standard date formats. */ 9254 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 9255 COOKIE: "D, dd M yy", 9256 ISO_8601: "yy-mm-dd", 9257 RFC_822: "D, d M y", 9258 RFC_850: "DD, dd-M-y", 9259 RFC_1036: "D, d M y", 9260 RFC_1123: "D, d M yy", 9261 RFC_2822: "D, d M yy", 9262 RSS: "D, d M y", // RFC 822 9263 TICKS: "!", 9264 TIMESTAMP: "@", 9265 W3C: "yy-mm-dd", // ISO 8601 9266 9267 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 9268 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 9269 9270 /* Format a date object into a string value. 9271 * The format can be combinations of the following: 9272 * d - day of month (no leading zero) 9273 * dd - day of month (two digit) 9274 * o - day of year (no leading zeros) 9275 * oo - day of year (three digit) 9276 * D - day name short 9277 * DD - day name long 9278 * m - month of year (no leading zero) 9279 * mm - month of year (two digit) 9280 * M - month name short 9281 * MM - month name long 9282 * y - year (two digit) 9283 * yy - year (four digit) 9284 * @ - Unix timestamp (ms since 01/01/1970) 9285 * ! - Windows ticks (100ns since 01/01/0001) 9286 * "..." - literal text 9287 * '' - single quote 9288 * 9289 * @param format string - the desired format of the date 9290 * @param date Date - the date value to format 9291 * @param settings Object - attributes include: 9292 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 9293 * dayNames string[7] - names of the days from Sunday (optional) 9294 * monthNamesShort string[12] - abbreviated names of the months (optional) 9295 * monthNames string[12] - names of the months (optional) 9296 * @return string - the date in the above format 9297 */ 9298 formatDate: function (format, date, settings) { 9299 if (!date) { 9300 return ""; 9301 } 9302 9303 var iFormat, 9304 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 9305 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 9306 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 9307 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 9308 // Check whether a format character is doubled 9309 lookAhead = function(match) { 9310 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 9311 if (matches) { 9312 iFormat++; 9313 } 9314 return matches; 9315 }, 9316 // Format a number, with leading zero if necessary 9317 formatNumber = function(match, value, len) { 9318 var num = "" + value; 9319 if (lookAhead(match)) { 9320 while (num.length < len) { 9321 num = "0" + num; 9322 } 9323 } 9324 return num; 9325 }, 9326 // Format a name, short or long as requested 9327 formatName = function(match, value, shortNames, longNames) { 9328 return (lookAhead(match) ? longNames[value] : shortNames[value]); 9329 }, 9330 output = "", 9331 literal = false; 9332 9333 if (date) { 9334 for (iFormat = 0; iFormat < format.length; iFormat++) { 9335 if (literal) { 9336 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9337 literal = false; 9338 } else { 9339 output += format.charAt(iFormat); 9340 } 9341 } else { 9342 switch (format.charAt(iFormat)) { 9343 case "d": 9344 output += formatNumber("d", date.getDate(), 2); 9345 break; 9346 case "D": 9347 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 9348 break; 9349 case "o": 9350 output += formatNumber("o", 9351 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 9352 break; 9353 case "m": 9354 output += formatNumber("m", date.getMonth() + 1, 2); 9355 break; 9356 case "M": 9357 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 9358 break; 9359 case "y": 9360 output += (lookAhead("y") ? date.getFullYear() : 9361 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 9362 break; 9363 case "@": 9364 output += date.getTime(); 9365 break; 9366 case "!": 9367 output += date.getTime() * 10000 + this._ticksTo1970; 9368 break; 9369 case "'": 9370 if (lookAhead("'")) { 9371 output += "'"; 9372 } else { 9373 literal = true; 9374 } 9375 break; 9376 default: 9377 output += format.charAt(iFormat); 9378 } 9379 } 9380 } 9381 } 9382 return output; 9383 }, 9384 9385 /* Extract all possible characters from the date format. */ 9386 _possibleChars: function (format) { 9387 var iFormat, 9388 chars = "", 9389 literal = false, 9390 // Check whether a format character is doubled 9391 lookAhead = function(match) { 9392 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 9393 if (matches) { 9394 iFormat++; 9395 } 9396 return matches; 9397 }; 9398 9399 for (iFormat = 0; iFormat < format.length; iFormat++) { 9400 if (literal) { 9401 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9402 literal = false; 9403 } else { 9404 chars += format.charAt(iFormat); 9405 } 9406 } else { 9407 switch (format.charAt(iFormat)) { 9408 case "d": case "m": case "y": case "@": 9409 chars += "0123456789"; 9410 break; 9411 case "D": case "M": 9412 return null; // Accept anything 9413 case "'": 9414 if (lookAhead("'")) { 9415 chars += "'"; 9416 } else { 9417 literal = true; 9418 } 9419 break; 9420 default: 9421 chars += format.charAt(iFormat); 9422 } 9423 } 9424 } 9425 return chars; 9426 }, 9427 9428 /* Get a setting value, defaulting if necessary. */ 9429 _get: function(inst, name) { 9430 return inst.settings[name] !== undefined ? 9431 inst.settings[name] : this._defaults[name]; 9432 }, 9433 9434 /* Parse existing date and initialise date picker. */ 9435 _setDateFromField: function(inst, noDefault) { 9436 if (inst.input.val() === inst.lastVal) { 9437 return; 9438 } 9439 9440 var dateFormat = this._get(inst, "dateFormat"), 9441 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9442 defaultDate = this._getDefaultDate(inst), 9443 date = defaultDate, 9444 settings = this._getFormatConfig(inst); 9445 9446 try { 9447 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9448 } catch (event) { 9449 dates = (noDefault ? "" : dates); 9450 } 9451 inst.selectedDay = date.getDate(); 9452 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9453 inst.drawYear = inst.selectedYear = date.getFullYear(); 9454 inst.currentDay = (dates ? date.getDate() : 0); 9455 inst.currentMonth = (dates ? date.getMonth() : 0); 9456 inst.currentYear = (dates ? date.getFullYear() : 0); 9457 this._adjustInstDate(inst); 9458 }, 9459 9460 /* Retrieve the default date shown on opening. */ 9461 _getDefaultDate: function(inst) { 9462 return this._restrictMinMax(inst, 9463 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9464 }, 9465 9466 /* A date may be specified as an exact value or a relative one. */ 9467 _determineDate: function(inst, date, defaultDate) { 9468 var offsetNumeric = function(offset) { 9469 var date = new Date(); 9470 date.setDate(date.getDate() + offset); 9471 return date; 9472 }, 9473 offsetString = function(offset) { 9474 try { 9475 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9476 offset, $.datepicker._getFormatConfig(inst)); 9477 } 9478 catch (e) { 9479 // Ignore 9480 } 9481 9482 var date = (offset.toLowerCase().match(/^c/) ? 9483 $.datepicker._getDate(inst) : null) || new Date(), 9484 year = date.getFullYear(), 9485 month = date.getMonth(), 9486 day = date.getDate(), 9487 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9488 matches = pattern.exec(offset); 9489 9490 while (matches) { 9491 switch (matches[2] || "d") { 9492 case "d" : case "D" : 9493 day += parseInt(matches[1],10); break; 9494 case "w" : case "W" : 9495 day += parseInt(matches[1],10) * 7; break; 9496 case "m" : case "M" : 9497 month += parseInt(matches[1],10); 9498 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9499 break; 9500 case "y": case "Y" : 9501 year += parseInt(matches[1],10); 9502 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9503 break; 9504 } 9505 matches = pattern.exec(offset); 9506 } 9507 return new Date(year, month, day); 9508 }, 9509 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9510 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9511 9512 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9513 if (newDate) { 9514 newDate.setHours(0); 9515 newDate.setMinutes(0); 9516 newDate.setSeconds(0); 9517 newDate.setMilliseconds(0); 9518 } 9519 return this._daylightSavingAdjust(newDate); 9520 }, 9521 9522 /* Handle switch to/from daylight saving. 9523 * Hours may be non-zero on daylight saving cut-over: 9524 * > 12 when midnight changeover, but then cannot generate 9525 * midnight datetime, so jump to 1AM, otherwise reset. 9526 * @param date (Date) the date to check 9527 * @return (Date) the corrected date 9528 */ 9529 _daylightSavingAdjust: function(date) { 9530 if (!date) { 9531 return null; 9532 } 9533 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9534 return date; 9535 }, 9536 9537 /* Set the date(s) directly. */ 9538 _setDate: function(inst, date, noChange) { 9539 var clear = !date, 9540 origMonth = inst.selectedMonth, 9541 origYear = inst.selectedYear, 9542 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9543 9544 inst.selectedDay = inst.currentDay = newDate.getDate(); 9545 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9546 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9547 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9548 this._notifyChange(inst); 9549 } 9550 this._adjustInstDate(inst); 9551 if (inst.input) { 9552 inst.input.val(clear ? "" : this._formatDate(inst)); 9553 } 9554 }, 9555 9556 /* Retrieve the date(s) directly. */ 9557 _getDate: function(inst) { 9558 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9559 this._daylightSavingAdjust(new Date( 9560 inst.currentYear, inst.currentMonth, inst.currentDay))); 9561 return startDate; 9562 }, 9563 9564 /* Attach the onxxx handlers. These are declared statically so 9565 * they work with static code transformers like Caja. 9566 */ 9567 _attachHandlers: function(inst) { 9568 var stepMonths = this._get(inst, "stepMonths"), 9569 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9570 inst.dpDiv.find("[data-handler]").map(function () { 9571 var handler = { 9572 prev: function () { 9573 $.datepicker._adjustDate(id, -stepMonths, "M"); 9574 }, 9575 next: function () { 9576 $.datepicker._adjustDate(id, +stepMonths, "M"); 9577 }, 9578 hide: function () { 9579 $.datepicker._hideDatepicker(); 9580 }, 9581 today: function () { 9582 $.datepicker._gotoToday(id); 9583 }, 9584 selectDay: function () { 9585 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9586 return false; 9587 }, 9588 selectMonth: function () { 9589 $.datepicker._selectMonthYear(id, this, "M"); 9590 return false; 9591 }, 9592 selectYear: function () { 9593 $.datepicker._selectMonthYear(id, this, "Y"); 9594 return false; 9595 } 9596 }; 9597 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9598 }); 9599 }, 9600 9601 /* Generate the HTML for the current state of the date picker. */ 9602 _generateHTML: function(inst) { 9603 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
vendor: 178,643 bytes, lines 9604-16123
9604 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9605 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9606 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9607 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9608 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9609 tempDate = new Date(), 9610 today = this._daylightSavingAdjust( 9611 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9612 isRTL = this._get(inst, "isRTL"), 9613 showButtonPanel = this._get(inst, "showButtonPanel"), 9614 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9615 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9616 numMonths = this._getNumberOfMonths(inst), 9617 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9618 stepMonths = this._get(inst, "stepMonths"), 9619 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9620 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9621 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9622 minDate = this._getMinMaxDate(inst, "min"), 9623 maxDate = this._getMinMaxDate(inst, "max"), 9624 drawMonth = inst.drawMonth - showCurrentAtPos, 9625 drawYear = inst.drawYear; 9626 9627 if (drawMonth < 0) { 9628 drawMonth += 12; 9629 drawYear--; 9630 } 9631 if (maxDate) { 9632 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9633 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9634 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9635 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9636 drawMonth--; 9637 if (drawMonth < 0) { 9638 drawMonth = 11; 9639 drawYear--; 9640 } 9641 } 9642 } 9643 inst.drawMonth = drawMonth; 9644 inst.drawYear = drawYear; 9645 9646 prevText = this._get(inst, "prevText"); 9647 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9648 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9649 this._getFormatConfig(inst))); 9650 9651 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9652 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9653 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9654 (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>")); 9655 9656 nextText = this._get(inst, "nextText"); 9657 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9658 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9659 this._getFormatConfig(inst))); 9660 9661 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9662 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9663 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9664 (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>")); 9665 9666 currentText = this._get(inst, "currentText"); 9667 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9668 currentText = (!navigationAsDateFormat ? currentText : 9669 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9670 9671 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'>" + 9672 this._get(inst, "closeText") + "</button>" : ""); 9673 9674 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9675 (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'" + 9676 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9677 9678 firstDay = parseInt(this._get(inst, "firstDay"),10); 9679 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9680 9681 showWeek = this._get(inst, "showWeek"); 9682 dayNames = this._get(inst, "dayNames"); 9683 dayNamesMin = this._get(inst, "dayNamesMin"); 9684 monthNames = this._get(inst, "monthNames"); 9685 monthNamesShort = this._get(inst, "monthNamesShort"); 9686 beforeShowDay = this._get(inst, "beforeShowDay"); 9687 showOtherMonths = this._get(inst, "showOtherMonths"); 9688 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9689 defaultDate = this._getDefaultDate(inst); 9690 html = ""; 9691 dow; 9692 for (row = 0; row < numMonths[0]; row++) { 9693 group = ""; 9694 this.maxRows = 4; 9695 for (col = 0; col < numMonths[1]; col++) { 9696 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9697 cornerClass = " ui-corner-all"; 9698 calender = ""; 9699 if (isMultiMonth) { 9700 calender += "<div class='ui-datepicker-group"; 9701 if (numMonths[1] > 1) { 9702 switch (col) { 9703 case 0: calender += " ui-datepicker-group-first"; 9704 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9705 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9706 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9707 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9708 } 9709 } 9710 calender += "'>"; 9711 } 9712 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9713 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9714 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9715 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9716 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9717 "</div><table class='ui-datepicker-calendar'><thead>" + 9718 "<tr>"; 9719 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9720 for (dow = 0; dow < 7; dow++) { // days of the week 9721 day = (dow + firstDay) % 7; 9722 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9723 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9724 } 9725 calender += thead + "</tr></thead><tbody>"; 9726 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9727 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9728 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9729 } 9730 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9731 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9732 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9733 this.maxRows = numRows; 9734 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9735 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9736 calender += "<tr>"; 9737 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9738 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9739 for (dow = 0; dow < 7; dow++) { // create date picker days 9740 daySettings = (beforeShowDay ? 9741 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9742 otherMonth = (printDate.getMonth() !== drawMonth); 9743 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9744 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9745 tbody += "<td class='" + 9746 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9747 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9748 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9749 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9750 // or defaultDate is current printedDate and defaultDate is selectedDate 9751 " " + this._dayOverClass : "") + // highlight selected day 9752 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9753 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9754 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9755 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9756 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9757 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9758 (otherMonth && !showOtherMonths ? " " : // display for other months 9759 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9760 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9761 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9762 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9763 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9764 printDate.setDate(printDate.getDate() + 1); 9765 printDate = this._daylightSavingAdjust(printDate); 9766 } 9767 calender += tbody + "</tr>"; 9768 } 9769 drawMonth++; 9770 if (drawMonth > 11) { 9771 drawMonth = 0; 9772 drawYear++; 9773 } 9774 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9775 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9776 group += calender; 9777 } 9778 html += group; 9779 } 9780 html += buttonPanel; 9781 inst._keyEvent = false; 9782 return html; 9783 }, 9784 9785 /* Generate the month and year header. */ 9786 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9787 secondary, monthNames, monthNamesShort) { 9788 9789 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9790 changeMonth = this._get(inst, "changeMonth"), 9791 changeYear = this._get(inst, "changeYear"), 9792 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9793 html = "<div class='ui-datepicker-title'>", 9794 monthHtml = ""; 9795 9796 // month selection 9797 if (secondary || !changeMonth) { 9798 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9799 } else { 9800 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9801 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9802 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9803 for ( month = 0; month < 12; month++) { 9804 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9805 monthHtml += "<option value='" + month + "'" + 9806 (month === drawMonth ? " selected='selected'" : "") + 9807 ">" + monthNamesShort[month] + "</option>"; 9808 } 9809 } 9810 monthHtml += "</select>"; 9811 } 9812 9813 if (!showMonthAfterYear) { 9814 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9815 } 9816 9817 // year selection 9818 if ( !inst.yearshtml ) { 9819 inst.yearshtml = ""; 9820 if (secondary || !changeYear) { 9821 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9822 } else { 9823 // determine range of years to display 9824 years = this._get(inst, "yearRange").split(":"); 9825 thisYear = new Date().getFullYear(); 9826 determineYear = function(value) { 9827 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9828 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9829 parseInt(value, 10))); 9830 return (isNaN(year) ? thisYear : year); 9831 }; 9832 year = determineYear(years[0]); 9833 endYear = Math.max(year, determineYear(years[1] || "")); 9834 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9835 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9836 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9837 for (; year <= endYear; year++) { 9838 inst.yearshtml += "<option value='" + year + "'" + 9839 (year === drawYear ? " selected='selected'" : "") + 9840 ">" + year + "</option>"; 9841 } 9842 inst.yearshtml += "</select>"; 9843 9844 html += inst.yearshtml; 9845 inst.yearshtml = null; 9846 } 9847 } 9848 9849 html += this._get(inst, "yearSuffix"); 9850 if (showMonthAfterYear) { 9851 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9852 } 9853 html += "</div>"; // Close datepicker_header 9854 return html; 9855 }, 9856 9857 /* Adjust one of the date sub-fields. */ 9858 _adjustInstDate: function(inst, offset, period) { 9859 var year = inst.drawYear + (period === "Y" ? offset : 0), 9860 month = inst.drawMonth + (period === "M" ? offset : 0), 9861 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9862 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9863 9864 inst.selectedDay = date.getDate(); 9865 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9866 inst.drawYear = inst.selectedYear = date.getFullYear(); 9867 if (period === "M" || period === "Y") { 9868 this._notifyChange(inst); 9869 } 9870 }, 9871 9872 /* Ensure a date is within any min/max bounds. */ 9873 _restrictMinMax: function(inst, date) { 9874 var minDate = this._getMinMaxDate(inst, "min"), 9875 maxDate = this._getMinMaxDate(inst, "max"), 9876 newDate = (minDate && date < minDate ? minDate : date); 9877 return (maxDate && newDate > maxDate ? maxDate : newDate); 9878 }, 9879 9880 /* Notify change of month/year. */ 9881 _notifyChange: function(inst) { 9882 var onChange = this._get(inst, "onChangeMonthYear"); 9883 if (onChange) { 9884 onChange.apply((inst.input ? inst.input[0] : null), 9885 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9886 } 9887 }, 9888 9889 /* Determine the number of months to show. */ 9890 _getNumberOfMonths: function(inst) { 9891 var numMonths = this._get(inst, "numberOfMonths"); 9892 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9893 }, 9894 9895 /* Determine the current maximum date - ensure no time components are set. */ 9896 _getMinMaxDate: function(inst, minMax) { 9897 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9898 }, 9899 9900 /* Find the number of days in a given month. */ 9901 _getDaysInMonth: function(year, month) { 9902 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9903 }, 9904 9905 /* Find the day of the week of the first of a month. */ 9906 _getFirstDayOfMonth: function(year, month) { 9907 return new Date(year, month, 1).getDay(); 9908 }, 9909 9910 /* Determines if we should allow a "next/prev" month display change. */ 9911 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9912 var numMonths = this._getNumberOfMonths(inst), 9913 date = this._daylightSavingAdjust(new Date(curYear, 9914 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9915 9916 if (offset < 0) { 9917 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9918 } 9919 return this._isInRange(inst, date); 9920 }, 9921 9922 /* Is the given date in the accepted range? */ 9923 _isInRange: function(inst, date) { 9924 var yearSplit, currentYear, 9925 minDate = this._getMinMaxDate(inst, "min"), 9926 maxDate = this._getMinMaxDate(inst, "max"), 9927 minYear = null, 9928 maxYear = null, 9929 years = this._get(inst, "yearRange"); 9930 if (years){ 9931 yearSplit = years.split(":"); 9932 currentYear = new Date().getFullYear(); 9933 minYear = parseInt(yearSplit[0], 10); 9934 maxYear = parseInt(yearSplit[1], 10); 9935 if ( yearSplit[0].match(/[+\-].*/) ) { 9936 minYear += currentYear; 9937 } 9938 if ( yearSplit[1].match(/[+\-].*/) ) { 9939 maxYear += currentYear; 9940 } 9941 } 9942 9943 return ((!minDate || date.getTime() >= minDate.getTime()) && 9944 (!maxDate || date.getTime() <= maxDate.getTime()) && 9945 (!minYear || date.getFullYear() >= minYear) && 9946 (!maxYear || date.getFullYear() <= maxYear)); 9947 }, 9948 9949 /* Provide the configuration settings for formatting/parsing. */ 9950 _getFormatConfig: function(inst) { 9951 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9952 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9953 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9954 return {shortYearCutoff: shortYearCutoff, 9955 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9956 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9957 }, 9958 9959 /* Format the given date for display. */ 9960 _formatDate: function(inst, day, month, year) { 9961 if (!day) { 9962 inst.currentDay = inst.selectedDay; 9963 inst.currentMonth = inst.selectedMonth; 9964 inst.currentYear = inst.selectedYear; 9965 } 9966 var date = (day ? (typeof day === "object" ? day : 9967 this._daylightSavingAdjust(new Date(year, month, day))) : 9968 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9969 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9970 } 9971}); 9972 9973/* 9974 * Bind hover events for datepicker elements. 9975 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9976 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9977 */ 9978function datepicker_bindHover(dpDiv) { 9979 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9980 return dpDiv.delegate(selector, "mouseout", function() { 9981 $(this).removeClass("ui-state-hover"); 9982 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9983 $(this).removeClass("ui-datepicker-prev-hover"); 9984 } 9985 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9986 $(this).removeClass("ui-datepicker-next-hover"); 9987 } 9988 }) 9989 .delegate( selector, "mouseover", datepicker_handleMouseover ); 9990} 9991 9992function datepicker_handleMouseover() { 9993 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { 9994 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9995 $(this).addClass("ui-state-hover"); 9996 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9997 $(this).addClass("ui-datepicker-prev-hover"); 9998 } 9999 if (this.className.indexOf("ui-datepicker-next") !== -1) { 10000 $(this).addClass("ui-datepicker-next-hover"); 10001 } 10002 } 10003} 10004 10005/* jQuery extend now ignores nulls! */ 10006function datepicker_extendRemove(target, props) { 10007 $.extend(target, props); 10008 for (var name in props) { 10009 if (props[name] == null) { 10010 target[name] = props[name]; 10011 } 10012 } 10013 return target; 10014} 10015 10016/* Invoke the datepicker functionality. 10017 @param options string - a command, optionally followed by additional parameters or 10018 Object - settings for attaching new datepicker functionality 10019 @return jQuery object */ 10020$.fn.datepicker = function(options){ 10021 10022 /* Verify an empty collection wasn't passed - Fixes #6976 */ 10023 if ( !this.length ) { 10024 return this; 10025 } 10026 10027 /* Initialise the date picker. */ 10028 if (!$.datepicker.initialized) { 10029 $(document).mousedown($.datepicker._checkExternalClick); 10030 $.datepicker.initialized = true; 10031 } 10032 10033 /* Append datepicker main container to body if not exist. */ 10034 if ($("#"+$.datepicker._mainDivId).length === 0) { 10035 $("body").append($.datepicker.dpDiv); 10036 } 10037 10038 var otherArgs = Array.prototype.slice.call(arguments, 1); 10039 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 10040 return $.datepicker["_" + options + "Datepicker"]. 10041 apply($.datepicker, [this[0]].concat(otherArgs)); 10042 } 10043 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 10044 return $.datepicker["_" + options + "Datepicker"]. 10045 apply($.datepicker, [this[0]].concat(otherArgs)); 10046 } 10047 return this.each(function() { 10048 typeof options === "string" ? 10049 $.datepicker["_" + options + "Datepicker"]. 10050 apply($.datepicker, [this].concat(otherArgs)) : 10051 $.datepicker._attachDatepicker(this, options); 10052 }); 10053}; 10054 10055$.datepicker = new Datepicker(); // singleton instance 10056$.datepicker.initialized = false; 10057$.datepicker.uuid = new Date().getTime(); 10058$.datepicker.version = "1.11.2"; 10059 10060var datepicker = $.datepicker; 10061 10062 10063/*! 10064 * jQuery UI Dialog 1.11.2 10065 * http://jqueryui.com 10066 * 10067 * Copyright 2014 jQuery Foundation and other contributors 10068 * Released under the MIT license. 10069 * http://jquery.org/license 10070 * 10071 * http://api.jqueryui.com/dialog/ 10072 */ 10073 10074 10075var dialog = $.widget( "ui.dialog", { 10076 version: "1.11.2", 10077 options: { 10078 appendTo: "body", 10079 autoOpen: true, 10080 buttons: [], 10081 closeOnEscape: true, 10082 closeText: "Close", 10083 dialogClass: "", 10084 draggable: true, 10085 hide: null, 10086 height: "auto", 10087 maxHeight: null, 10088 maxWidth: null, 10089 minHeight: 150, 10090 minWidth: 150, 10091 modal: false, 10092 position: { 10093 my: "center", 10094 at: "center", 10095 of: window, 10096 collision: "fit", 10097 // Ensure the titlebar is always visible 10098 using: function( pos ) { 10099 var topOffset = $( this ).css( pos ).offset().top; 10100 if ( topOffset < 0 ) { 10101 $( this ).css( "top", pos.top - topOffset ); 10102 } 10103 } 10104 }, 10105 resizable: true, 10106 show: null, 10107 title: null, 10108 width: 300, 10109 10110 // callbacks 10111 beforeClose: null, 10112 close: null, 10113 drag: null, 10114 dragStart: null, 10115 dragStop: null, 10116 focus: null, 10117 open: null, 10118 resize: null, 10119 resizeStart: null, 10120 resizeStop: null 10121 }, 10122 10123 sizeRelatedOptions: { 10124 buttons: true, 10125 height: true, 10126 maxHeight: true, 10127 maxWidth: true, 10128 minHeight: true, 10129 minWidth: true, 10130 width: true 10131 }, 10132 10133 resizableRelatedOptions: { 10134 maxHeight: true, 10135 maxWidth: true, 10136 minHeight: true, 10137 minWidth: true 10138 }, 10139 10140 _create: function() { 10141 this.originalCss = { 10142 display: this.element[ 0 ].style.display, 10143 width: this.element[ 0 ].style.width, 10144 minHeight: this.element[ 0 ].style.minHeight, 10145 maxHeight: this.element[ 0 ].style.maxHeight, 10146 height: this.element[ 0 ].style.height 10147 }; 10148 this.originalPosition = { 10149 parent: this.element.parent(), 10150 index: this.element.parent().children().index( this.element ) 10151 }; 10152 this.originalTitle = this.element.attr( "title" ); 10153 this.options.title = this.options.title || this.originalTitle; 10154 10155 this._createWrapper(); 10156 10157 this.element 10158 .show() 10159 .removeAttr( "title" ) 10160 .addClass( "ui-dialog-content ui-widget-content" ) 10161 .appendTo( this.uiDialog ); 10162 10163 this._createTitlebar(); 10164 this._createButtonPane(); 10165 10166 if ( this.options.draggable && $.fn.draggable ) { 10167 this._makeDraggable(); 10168 } 10169 if ( this.options.resizable && $.fn.resizable ) { 10170 this._makeResizable(); 10171 } 10172 10173 this._isOpen = false; 10174 10175 this._trackFocus(); 10176 }, 10177 10178 _init: function() { 10179 if ( this.options.autoOpen ) { 10180 this.open(); 10181 } 10182 }, 10183 10184 _appendTo: function() { 10185 var element = this.options.appendTo; 10186 if ( element && (element.jquery || element.nodeType) ) { 10187 return $( element ); 10188 } 10189 return this.document.find( element || "body" ).eq( 0 ); 10190 }, 10191 10192 _destroy: function() { 10193 var next, 10194 originalPosition = this.originalPosition; 10195 10196 this._destroyOverlay(); 10197 10198 this.element 10199 .removeUniqueId() 10200 .removeClass( "ui-dialog-content ui-widget-content" ) 10201 .css( this.originalCss ) 10202 // Without detaching first, the following becomes really slow 10203 .detach(); 10204 10205 this.uiDialog.stop( true, true ).remove(); 10206 10207 if ( this.originalTitle ) { 10208 this.element.attr( "title", this.originalTitle ); 10209 } 10210 10211 next = originalPosition.parent.children().eq( originalPosition.index ); 10212 // Don't try to place the dialog next to itself (#8613) 10213 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 10214 next.before( this.element ); 10215 } else { 10216 originalPosition.parent.append( this.element ); 10217 } 10218 }, 10219 10220 widget: function() { 10221 return this.uiDialog; 10222 }, 10223 10224 disable: $.noop, 10225 enable: $.noop, 10226 10227 close: function( event ) { 10228 var activeElement, 10229 that = this; 10230 10231 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 10232 return; 10233 } 10234 10235 this._isOpen = false; 10236 this._focusedElement = null; 10237 this._destroyOverlay(); 10238 this._untrackInstance(); 10239 10240 if ( !this.opener.filter( ":focusable" ).focus().length ) { 10241 10242 // support: IE9 10243 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 10244 try { 10245 activeElement = this.document[ 0 ].activeElement; 10246 10247 // Support: IE9, IE10 10248 // If the <body> is blurred, IE will switch windows, see #4520 10249 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 10250 10251 // Hiding a focused element doesn't trigger blur in WebKit 10252 // so in case we have nothing to focus on, explicitly blur the active element 10253 // https://bugs.webkit.org/show_bug.cgi?id=47182 10254 $( activeElement ).blur(); 10255 } 10256 } catch ( error ) {} 10257 } 10258 10259 this._hide( this.uiDialog, this.options.hide, function() { 10260 that._trigger( "close", event ); 10261 }); 10262 }, 10263 10264 isOpen: function() { 10265 return this._isOpen; 10266 }, 10267 10268 moveToTop: function() { 10269 this._moveToTop(); 10270 }, 10271 10272 _moveToTop: function( event, silent ) { 10273 var moved = false, 10274 zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { 10275 return +$( this ).css( "z-index" ); 10276 }).get(), 10277 zIndexMax = Math.max.apply( null, zIndicies ); 10278 10279 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 10280 this.uiDialog.css( "z-index", zIndexMax + 1 ); 10281 moved = true; 10282 } 10283 10284 if ( moved && !silent ) { 10285 this._trigger( "focus", event ); 10286 } 10287 return moved; 10288 }, 10289 10290 open: function() { 10291 var that = this; 10292 if ( this._isOpen ) { 10293 if ( this._moveToTop() ) { 10294 this._focusTabbable(); 10295 } 10296 return; 10297 } 10298 10299 this._isOpen = true; 10300 this.opener = $( this.document[ 0 ].activeElement ); 10301 10302 this._size(); 10303 this._position(); 10304 this._createOverlay(); 10305 this._moveToTop( null, true ); 10306 10307 // Ensure the overlay is moved to the top with the dialog, but only when 10308 // opening. The overlay shouldn't move after the dialog is open so that 10309 // modeless dialogs opened after the modal dialog stack properly. 10310 if ( this.overlay ) { 10311 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 10312 } 10313 10314 this._show( this.uiDialog, this.options.show, function() { 10315 that._focusTabbable(); 10316 that._trigger( "focus" ); 10317 }); 10318 10319 // Track the dialog immediately upon openening in case a focus event 10320 // somehow occurs outside of the dialog before an element inside the 10321 // dialog is focused (#10152) 10322 this._makeFocusTarget(); 10323 10324 this._trigger( "open" ); 10325 }, 10326 10327 _focusTabbable: function() { 10328 // Set focus to the first match: 10329 // 1. An element that was focused previously 10330 // 2. First element inside the dialog matching [autofocus] 10331 // 3. Tabbable element inside the content element 10332 // 4. Tabbable element inside the buttonpane 10333 // 5. The close button 10334 // 6. The dialog itself 10335 var hasFocus = this._focusedElement; 10336 if ( !hasFocus ) { 10337 hasFocus = this.element.find( "[autofocus]" ); 10338 } 10339 if ( !hasFocus.length ) { 10340 hasFocus = this.element.find( ":tabbable" ); 10341 } 10342 if ( !hasFocus.length ) { 10343 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 10344 } 10345 if ( !hasFocus.length ) { 10346 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 10347 } 10348 if ( !hasFocus.length ) { 10349 hasFocus = this.uiDialog; 10350 } 10351 hasFocus.eq( 0 ).focus(); 10352 }, 10353 10354 _keepFocus: function( event ) { 10355 function checkFocus() { 10356 var activeElement = this.document[0].activeElement, 10357 isActive = this.uiDialog[0] === activeElement || 10358 $.contains( this.uiDialog[0], activeElement ); 10359 if ( !isActive ) { 10360 this._focusTabbable(); 10361 } 10362 } 10363 event.preventDefault(); 10364 checkFocus.call( this ); 10365 // support: IE 10366 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 10367 // so we check again later 10368 this._delay( checkFocus ); 10369 }, 10370 10371 _createWrapper: function() { 10372 this.uiDialog = $("<div>") 10373 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 10374 this.options.dialogClass ) 10375 .hide() 10376 .attr({ 10377 // Setting tabIndex makes the div focusable 10378 tabIndex: -1, 10379 role: "dialog" 10380 }) 10381 .appendTo( this._appendTo() ); 10382 10383 this._on( this.uiDialog, { 10384 keydown: function( event ) { 10385 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 10386 event.keyCode === $.ui.keyCode.ESCAPE ) { 10387 event.preventDefault(); 10388 this.close( event ); 10389 return; 10390 } 10391 10392 // prevent tabbing out of dialogs 10393 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 10394 return; 10395 } 10396 var tabbables = this.uiDialog.find( ":tabbable" ), 10397 first = tabbables.filter( ":first" ), 10398 last = tabbables.filter( ":last" ); 10399 10400 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 10401 this._delay(function() { 10402 first.focus(); 10403 }); 10404 event.preventDefault(); 10405 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 10406 this._delay(function() { 10407 last.focus(); 10408 }); 10409 event.preventDefault(); 10410 } 10411 }, 10412 mousedown: function( event ) { 10413 if ( this._moveToTop( event ) ) { 10414 this._focusTabbable(); 10415 } 10416 } 10417 }); 10418 10419 // We assume that any existing aria-describedby attribute means 10420 // that the dialog content is marked up properly 10421 // otherwise we brute force the content as the description 10422 if ( !this.element.find( "[aria-describedby]" ).length ) { 10423 this.uiDialog.attr({ 10424 "aria-describedby": this.element.uniqueId().attr( "id" ) 10425 }); 10426 } 10427 }, 10428 10429 _createTitlebar: function() { 10430 var uiDialogTitle; 10431 10432 this.uiDialogTitlebar = $( "<div>" ) 10433 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) 10434 .prependTo( this.uiDialog ); 10435 this._on( this.uiDialogTitlebar, { 10436 mousedown: function( event ) { 10437 // Don't prevent click on close button (#8838) 10438 // Focusing a dialog that is partially scrolled out of view 10439 // causes the browser to scroll it into view, preventing the click event 10440 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 10441 // Dialog isn't getting focus when dragging (#8063) 10442 this.uiDialog.focus(); 10443 } 10444 } 10445 }); 10446 10447 // support: IE 10448 // Use type="button" to prevent enter keypresses in textboxes from closing the 10449 // dialog in IE (#9312) 10450 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 10451 .button({ 10452 label: this.options.closeText, 10453 icons: { 10454 primary: "ui-icon-closethick" 10455 }, 10456 text: false 10457 }) 10458 .addClass( "ui-dialog-titlebar-close" ) 10459 .appendTo( this.uiDialogTitlebar ); 10460 this._on( this.uiDialogTitlebarClose, { 10461 click: function( event ) { 10462 event.preventDefault(); 10463 this.close( event ); 10464 } 10465 }); 10466 10467 uiDialogTitle = $( "<span>" ) 10468 .uniqueId() 10469 .addClass( "ui-dialog-title" ) 10470 .prependTo( this.uiDialogTitlebar ); 10471 this._title( uiDialogTitle ); 10472 10473 this.uiDialog.attr({ 10474 "aria-labelledby": uiDialogTitle.attr( "id" ) 10475 }); 10476 }, 10477 10478 _title: function( title ) { 10479 if ( !this.options.title ) { 10480 title.html( " " ); 10481 } 10482 title.text( this.options.title ); 10483 }, 10484 10485 _createButtonPane: function() { 10486 this.uiDialogButtonPane = $( "<div>" ) 10487 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 10488 10489 this.uiButtonSet = $( "<div>" ) 10490 .addClass( "ui-dialog-buttonset" ) 10491 .appendTo( this.uiDialogButtonPane ); 10492 10493 this._createButtons(); 10494 }, 10495 10496 _createButtons: function() { 10497 var that = this, 10498 buttons = this.options.buttons; 10499 10500 // if we already have a button pane, remove it 10501 this.uiDialogButtonPane.remove(); 10502 this.uiButtonSet.empty(); 10503 10504 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10505 this.uiDialog.removeClass( "ui-dialog-buttons" ); 10506 return; 10507 } 10508 10509 $.each( buttons, function( name, props ) { 10510 var click, buttonOptions; 10511 props = $.isFunction( props ) ? 10512 { click: props, text: name } : 10513 props; 10514 // Default to a non-submitting button 10515 props = $.extend( { type: "button" }, props ); 10516 // Change the context for the click callback to be the main element 10517 click = props.click; 10518 props.click = function() { 10519 click.apply( that.element[ 0 ], arguments ); 10520 }; 10521 buttonOptions = { 10522 icons: props.icons, 10523 text: props.showText 10524 }; 10525 delete props.icons; 10526 delete props.showText; 10527 $( "<button></button>", props ) 10528 .button( buttonOptions ) 10529 .appendTo( that.uiButtonSet ); 10530 }); 10531 this.uiDialog.addClass( "ui-dialog-buttons" ); 10532 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10533 }, 10534 10535 _makeDraggable: function() { 10536 var that = this, 10537 options = this.options; 10538 10539 function filteredUi( ui ) { 10540 return { 10541 position: ui.position, 10542 offset: ui.offset 10543 }; 10544 } 10545 10546 this.uiDialog.draggable({ 10547 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10548 handle: ".ui-dialog-titlebar", 10549 containment: "document", 10550 start: function( event, ui ) { 10551 $( this ).addClass( "ui-dialog-dragging" ); 10552 that._blockFrames(); 10553 that._trigger( "dragStart", event, filteredUi( ui ) ); 10554 }, 10555 drag: function( event, ui ) { 10556 that._trigger( "drag", event, filteredUi( ui ) ); 10557 }, 10558 stop: function( event, ui ) { 10559 var left = ui.offset.left - that.document.scrollLeft(), 10560 top = ui.offset.top - that.document.scrollTop(); 10561 10562 options.position = { 10563 my: "left top", 10564 at: "left" + (left >= 0 ? "+" : "") + left + " " + 10565 "top" + (top >= 0 ? "+" : "") + top, 10566 of: that.window 10567 }; 10568 $( this ).removeClass( "ui-dialog-dragging" ); 10569 that._unblockFrames(); 10570 that._trigger( "dragStop", event, filteredUi( ui ) ); 10571 } 10572 }); 10573 }, 10574 10575 _makeResizable: function() { 10576 var that = this, 10577 options = this.options, 10578 handles = options.resizable, 10579 // .ui-resizable has position: relative defined in the stylesheet 10580 // but dialogs have to use absolute or fixed positioning 10581 position = this.uiDialog.css("position"), 10582 resizeHandles = typeof handles === "string" ? 10583 handles : 10584 "n,e,s,w,se,sw,ne,nw"; 10585 10586 function filteredUi( ui ) { 10587 return { 10588 originalPosition: ui.originalPosition, 10589 originalSize: ui.originalSize, 10590 position: ui.position, 10591 size: ui.size 10592 }; 10593 } 10594 10595 this.uiDialog.resizable({ 10596 cancel: ".ui-dialog-content", 10597 containment: "document", 10598 alsoResize: this.element, 10599 maxWidth: options.maxWidth, 10600 maxHeight: options.maxHeight, 10601 minWidth: options.minWidth, 10602 minHeight: this._minHeight(), 10603 handles: resizeHandles, 10604 start: function( event, ui ) { 10605 $( this ).addClass( "ui-dialog-resizing" ); 10606 that._blockFrames(); 10607 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10608 }, 10609 resize: function( event, ui ) { 10610 that._trigger( "resize", event, filteredUi( ui ) ); 10611 }, 10612 stop: function( event, ui ) { 10613 var offset = that.uiDialog.offset(), 10614 left = offset.left - that.document.scrollLeft(), 10615 top = offset.top - that.document.scrollTop(); 10616 10617 options.height = that.uiDialog.height(); 10618 options.width = that.uiDialog.width(); 10619 options.position = { 10620 my: "left top", 10621 at: "left" + (left >= 0 ? "+" : "") + left + " " + 10622 "top" + (top >= 0 ? "+" : "") + top, 10623 of: that.window 10624 }; 10625 $( this ).removeClass( "ui-dialog-resizing" ); 10626 that._unblockFrames(); 10627 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10628 } 10629 }) 10630 .css( "position", position ); 10631 }, 10632 10633 _trackFocus: function() { 10634 this._on( this.widget(), { 10635 focusin: function( event ) { 10636 this._makeFocusTarget(); 10637 this._focusedElement = $( event.target ); 10638 } 10639 }); 10640 }, 10641 10642 _makeFocusTarget: function() { 10643 this._untrackInstance(); 10644 this._trackingInstances().unshift( this ); 10645 }, 10646 10647 _untrackInstance: function() { 10648 var instances = this._trackingInstances(), 10649 exists = $.inArray( this, instances ); 10650 if ( exists !== -1 ) { 10651 instances.splice( exists, 1 ); 10652 } 10653 }, 10654 10655 _trackingInstances: function() { 10656 var instances = this.document.data( "ui-dialog-instances" ); 10657 if ( !instances ) { 10658 instances = []; 10659 this.document.data( "ui-dialog-instances", instances ); 10660 } 10661 return instances; 10662 }, 10663 10664 _minHeight: function() { 10665 var options = this.options; 10666 10667 return options.height === "auto" ? 10668 options.minHeight : 10669 Math.min( options.minHeight, options.height ); 10670 }, 10671 10672 _position: function() { 10673 // Need to show the dialog to get the actual offset in the position plugin 10674 var isVisible = this.uiDialog.is( ":visible" ); 10675 if ( !isVisible ) { 10676 this.uiDialog.show(); 10677 } 10678 this.uiDialog.position( this.options.position ); 10679 if ( !isVisible ) { 10680 this.uiDialog.hide(); 10681 } 10682 }, 10683 10684 _setOptions: function( options ) { 10685 var that = this, 10686 resize = false, 10687 resizableOptions = {}; 10688 10689 $.each( options, function( key, value ) { 10690 that._setOption( key, value ); 10691 10692 if ( key in that.sizeRelatedOptions ) { 10693 resize = true; 10694 } 10695 if ( key in that.resizableRelatedOptions ) { 10696 resizableOptions[ key ] = value; 10697 } 10698 }); 10699 10700 if ( resize ) { 10701 this._size(); 10702 this._position(); 10703 } 10704 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 10705 this.uiDialog.resizable( "option", resizableOptions ); 10706 } 10707 }, 10708 10709 _setOption: function( key, value ) { 10710 var isDraggable, isResizable, 10711 uiDialog = this.uiDialog; 10712 10713 if ( key === "dialogClass" ) { 10714 uiDialog 10715 .removeClass( this.options.dialogClass ) 10716 .addClass( value ); 10717 } 10718 10719 if ( key === "disabled" ) { 10720 return; 10721 } 10722 10723 this._super( key, value ); 10724 10725 if ( key === "appendTo" ) { 10726 this.uiDialog.appendTo( this._appendTo() ); 10727 } 10728 10729 if ( key === "buttons" ) { 10730 this._createButtons(); 10731 } 10732 10733 if ( key === "closeText" ) { 10734 this.uiDialogTitlebarClose.button({ 10735 // Ensure that we always pass a string 10736 label: "" + value 10737 }); 10738 } 10739 10740 if ( key === "draggable" ) { 10741 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 10742 if ( isDraggable && !value ) { 10743 uiDialog.draggable( "destroy" ); 10744 } 10745 10746 if ( !isDraggable && value ) { 10747 this._makeDraggable(); 10748 } 10749 } 10750 10751 if ( key === "position" ) { 10752 this._position(); 10753 } 10754 10755 if ( key === "resizable" ) { 10756 // currently resizable, becoming non-resizable 10757 isResizable = uiDialog.is( ":data(ui-resizable)" ); 10758 if ( isResizable && !value ) { 10759 uiDialog.resizable( "destroy" ); 10760 } 10761 10762 // currently resizable, changing handles 10763 if ( isResizable && typeof value === "string" ) { 10764 uiDialog.resizable( "option", "handles", value ); 10765 } 10766 10767 // currently non-resizable, becoming resizable 10768 if ( !isResizable && value !== false ) { 10769 this._makeResizable(); 10770 } 10771 } 10772 10773 if ( key === "title" ) { 10774 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 10775 } 10776 }, 10777 10778 _size: function() { 10779 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10780 // divs will both have width and height set, so we need to reset them 10781 var nonContentHeight, minContentHeight, maxContentHeight, 10782 options = this.options; 10783 10784 // Reset content sizing 10785 this.element.show().css({ 10786 width: "auto", 10787 minHeight: 0, 10788 maxHeight: "none", 10789 height: 0 10790 }); 10791 10792 if ( options.minWidth > options.width ) { 10793 options.width = options.minWidth; 10794 } 10795 10796 // reset wrapper sizing 10797 // determine the height of all the non-content elements 10798 nonContentHeight = this.uiDialog.css({ 10799 height: "auto", 10800 width: options.width 10801 }) 10802 .outerHeight(); 10803 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10804 maxContentHeight = typeof options.maxHeight === "number" ? 10805 Math.max( 0, options.maxHeight - nonContentHeight ) : 10806 "none"; 10807 10808 if ( options.height === "auto" ) { 10809 this.element.css({ 10810 minHeight: minContentHeight, 10811 maxHeight: maxContentHeight, 10812 height: "auto" 10813 }); 10814 } else { 10815 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10816 } 10817 10818 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 10819 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10820 } 10821 }, 10822 10823 _blockFrames: function() { 10824 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10825 var iframe = $( this ); 10826 10827 return $( "<div>" ) 10828 .css({ 10829 position: "absolute", 10830 width: iframe.outerWidth(), 10831 height: iframe.outerHeight() 10832 }) 10833 .appendTo( iframe.parent() ) 10834 .offset( iframe.offset() )[0]; 10835 }); 10836 }, 10837 10838 _unblockFrames: function() { 10839 if ( this.iframeBlocks ) { 10840 this.iframeBlocks.remove(); 10841 delete this.iframeBlocks; 10842 } 10843 }, 10844 10845 _allowInteraction: function( event ) { 10846 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 10847 return true; 10848 } 10849 10850 // TODO: Remove hack when datepicker implements 10851 // the .ui-front logic (#8989) 10852 return !!$( event.target ).closest( ".ui-datepicker" ).length; 10853 }, 10854 10855 _createOverlay: function() { 10856 if ( !this.options.modal ) { 10857 return; 10858 } 10859 10860 // We use a delay in case the overlay is created from an 10861 // event that we're going to be cancelling (#2804) 10862 var isOpening = true; 10863 this._delay(function() { 10864 isOpening = false; 10865 }); 10866 10867 if ( !this.document.data( "ui-dialog-overlays" ) ) { 10868 10869 // Prevent use of anchors and inputs 10870 // Using _on() for an event handler shared across many instances is 10871 // safe because the dialogs stack and must be closed in reverse order 10872 this._on( this.document, { 10873 focusin: function( event ) { 10874 if ( isOpening ) { 10875 return; 10876 } 10877 10878 if ( !this._allowInteraction( event ) ) { 10879 event.preventDefault(); 10880 this._trackingInstances()[ 0 ]._focusTabbable(); 10881 } 10882 } 10883 }); 10884 } 10885 10886 this.overlay = $( "<div>" ) 10887 .addClass( "ui-widget-overlay ui-front" ) 10888 .appendTo( this._appendTo() ); 10889 this._on( this.overlay, { 10890 mousedown: "_keepFocus" 10891 }); 10892 this.document.data( "ui-dialog-overlays", 10893 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); 10894 }, 10895 10896 _destroyOverlay: function() { 10897 if ( !this.options.modal ) { 10898 return; 10899 } 10900 10901 if ( this.overlay ) { 10902 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 10903 10904 if ( !overlays ) { 10905 this.document 10906 .unbind( "focusin" ) 10907 .removeData( "ui-dialog-overlays" ); 10908 } else { 10909 this.document.data( "ui-dialog-overlays", overlays ); 10910 } 10911 10912 this.overlay.remove(); 10913 this.overlay = null; 10914 } 10915 } 10916}); 10917 10918 10919/*! 10920 * jQuery UI Progressbar 1.11.2 10921 * http://jqueryui.com 10922 * 10923 * Copyright 2014 jQuery Foundation and other contributors 10924 * Released under the MIT license. 10925 * http://jquery.org/license 10926 * 10927 * http://api.jqueryui.com/progressbar/ 10928 */ 10929 10930 10931var progressbar = $.widget( "ui.progressbar", { 10932 version: "1.11.2", 10933 options: { 10934 max: 100, 10935 value: 0, 10936 10937 change: null, 10938 complete: null 10939 }, 10940 10941 min: 0, 10942 10943 _create: function() { 10944 // Constrain initial value 10945 this.oldValue = this.options.value = this._constrainedValue(); 10946 10947 this.element 10948 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10949 .attr({ 10950 // Only set static values, aria-valuenow and aria-valuemax are 10951 // set inside _refreshValue() 10952 role: "progressbar", 10953 "aria-valuemin": this.min 10954 }); 10955 10956 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10957 .appendTo( this.element ); 10958 10959 this._refreshValue(); 10960 }, 10961 10962 _destroy: function() { 10963 this.element 10964 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10965 .removeAttr( "role" ) 10966 .removeAttr( "aria-valuemin" ) 10967 .removeAttr( "aria-valuemax" ) 10968 .removeAttr( "aria-valuenow" ); 10969 10970 this.valueDiv.remove(); 10971 }, 10972 10973 value: function( newValue ) { 10974 if ( newValue === undefined ) { 10975 return this.options.value; 10976 } 10977 10978 this.options.value = this._constrainedValue( newValue ); 10979 this._refreshValue(); 10980 }, 10981 10982 _constrainedValue: function( newValue ) { 10983 if ( newValue === undefined ) { 10984 newValue = this.options.value; 10985 } 10986 10987 this.indeterminate = newValue === false; 10988 10989 // sanitize value 10990 if ( typeof newValue !== "number" ) { 10991 newValue = 0; 10992 } 10993 10994 return this.indeterminate ? false : 10995 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10996 }, 10997 10998 _setOptions: function( options ) { 10999 // Ensure "value" option is set after other values (like max) 11000 var value = options.value; 11001 delete options.value; 11002 11003 this._super( options ); 11004 11005 this.options.value = this._constrainedValue( value ); 11006 this._refreshValue(); 11007 }, 11008 11009 _setOption: function( key, value ) { 11010 if ( key === "max" ) { 11011 // Don't allow a max less than min 11012 value = Math.max( this.min, value ); 11013 } 11014 if ( key === "disabled" ) { 11015 this.element 11016 .toggleClass( "ui-state-disabled", !!value ) 11017 .attr( "aria-disabled", value ); 11018 } 11019 this._super( key, value ); 11020 }, 11021 11022 _percentage: function() { 11023 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 11024 }, 11025 11026 _refreshValue: function() { 11027 var value = this.options.value, 11028 percentage = this._percentage(); 11029 11030 this.valueDiv 11031 .toggle( this.indeterminate || value > this.min ) 11032 .toggleClass( "ui-corner-right", value === this.options.max ) 11033 .width( percentage.toFixed(0) + "%" ); 11034 11035 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 11036 11037 if ( this.indeterminate ) { 11038 this.element.removeAttr( "aria-valuenow" ); 11039 if ( !this.overlayDiv ) { 11040 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 11041 } 11042 } else { 11043 this.element.attr({ 11044 "aria-valuemax": this.options.max, 11045 "aria-valuenow": value 11046 }); 11047 if ( this.overlayDiv ) { 11048 this.overlayDiv.remove(); 11049 this.overlayDiv = null; 11050 } 11051 } 11052 11053 if ( this.oldValue !== value ) { 11054 this.oldValue = value; 11055 this._trigger( "change" ); 11056 } 11057 if ( value === this.options.max ) { 11058 this._trigger( "complete" ); 11059 } 11060 } 11061}); 11062 11063 11064/*! 11065 * jQuery UI Selectmenu 1.11.2 11066 * http://jqueryui.com 11067 * 11068 * Copyright 2014 jQuery Foundation and other contributors 11069 * Released under the MIT license. 11070 * http://jquery.org/license 11071 * 11072 * http://api.jqueryui.com/selectmenu 11073 */ 11074 11075 11076var selectmenu = $.widget( "ui.selectmenu", { 11077 version: "1.11.2", 11078 defaultElement: "<select>", 11079 options: { 11080 appendTo: null, 11081 disabled: null, 11082 icons: { 11083 button: "ui-icon-triangle-1-s" 11084 }, 11085 position: { 11086 my: "left top", 11087 at: "left bottom", 11088 collision: "none" 11089 }, 11090 width: null, 11091 11092 // callbacks 11093 change: null, 11094 close: null, 11095 focus: null, 11096 open: null, 11097 select: null 11098 }, 11099 11100 _create: function() { 11101 var selectmenuId = this.element.uniqueId().attr( "id" ); 11102 this.ids = { 11103 element: selectmenuId, 11104 button: selectmenuId + "-button", 11105 menu: selectmenuId + "-menu" 11106 }; 11107 11108 this._drawButton(); 11109 this._drawMenu(); 11110 11111 if ( this.options.disabled ) { 11112 this.disable(); 11113 } 11114 }, 11115 11116 _drawButton: function() { 11117 var that = this, 11118 tabindex = this.element.attr( "tabindex" ); 11119 11120 // Associate existing label with the new button 11121 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); 11122 this._on( this.label, { 11123 click: function( event ) { 11124 this.button.focus(); 11125 event.preventDefault(); 11126 } 11127 }); 11128 11129 // Hide original select element 11130 this.element.hide(); 11131 11132 // Create button 11133 this.button = $( "<span>", { 11134 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", 11135 tabindex: tabindex || this.options.disabled ? -1 : 0, 11136 id: this.ids.button, 11137 role: "combobox", 11138 "aria-expanded": "false", 11139 "aria-autocomplete": "list", 11140 "aria-owns": this.ids.menu, 11141 "aria-haspopup": "true" 11142 }) 11143 .insertAfter( this.element ); 11144 11145 $( "<span>", { 11146 "class": "ui-icon " + this.options.icons.button 11147 }) 11148 .prependTo( this.button ); 11149 11150 this.buttonText = $( "<span>", { 11151 "class": "ui-selectmenu-text" 11152 }) 11153 .appendTo( this.button ); 11154 11155 this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); 11156 this._resizeButton(); 11157 11158 this._on( this.button, this._buttonEvents ); 11159 this.button.one( "focusin", function() { 11160 11161 // Delay rendering the menu items until the button receives focus. 11162 // The menu may have already been rendered via a programmatic open. 11163 if ( !that.menuItems ) { 11164 that._refreshMenu(); 11165 } 11166 }); 11167 this._hoverable( this.button ); 11168 this._focusable( this.button ); 11169 }, 11170 11171 _drawMenu: function() { 11172 var that = this; 11173 11174 // Create menu 11175 this.menu = $( "<ul>", { 11176 "aria-hidden": "true", 11177 "aria-labelledby": this.ids.button, 11178 id: this.ids.menu 11179 }); 11180 11181 // Wrap menu 11182 this.menuWrap = $( "<div>", { 11183 "class": "ui-selectmenu-menu ui-front" 11184 }) 11185 .append( this.menu ) 11186 .appendTo( this._appendTo() ); 11187 11188 // Initialize menu widget 11189 this.menuInstance = this.menu 11190 .menu({ 11191 role: "listbox", 11192 select: function( event, ui ) { 11193 event.preventDefault(); 11194 11195 // support: IE8 11196 // If the item was selected via a click, the text selection 11197 // will be destroyed in IE 11198 that._setSelection(); 11199 11200 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 11201 }, 11202 focus: function( event, ui ) { 11203 var item = ui.item.data( "ui-selectmenu-item" ); 11204 11205 // Prevent inital focus from firing and check if its a newly focused item 11206 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 11207 that._trigger( "focus", event, { item: item } ); 11208 if ( !that.isOpen ) { 11209 that._select( item, event ); 11210 } 11211 } 11212 that.focusIndex = item.index; 11213 11214 that.button.attr( "aria-activedescendant", 11215 that.menuItems.eq( item.index ).attr( "id" ) ); 11216 } 11217 }) 11218 .menu( "instance" ); 11219 11220 // Adjust menu styles to dropdown 11221 this.menu 11222 .addClass( "ui-corner-bottom" ) 11223 .removeClass( "ui-corner-all" ); 11224 11225 // Don't close the menu on mouseleave 11226 this.menuInstance._off( this.menu, "mouseleave" ); 11227 11228 // Cancel the menu's collapseAll on document click 11229 this.menuInstance._closeOnDocumentClick = function() { 11230 return false; 11231 }; 11232 11233 // Selects often contain empty items, but never contain dividers 11234 this.menuInstance._isDivider = function() { 11235 return false; 11236 }; 11237 }, 11238 11239 refresh: function() { 11240 this._refreshMenu(); 11241 this._setText( this.buttonText, this._getSelectedItem().text() ); 11242 if ( !this.options.width ) { 11243 this._resizeButton(); 11244 } 11245 }, 11246 11247 _refreshMenu: function() { 11248 this.menu.empty(); 11249 11250 var item, 11251 options = this.element.find( "option" ); 11252 11253 if ( !options.length ) { 11254 return; 11255 } 11256 11257 this._parseOptions( options ); 11258 this._renderMenu( this.menu, this.items ); 11259 11260 this.menuInstance.refresh(); 11261 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); 11262 11263 item = this._getSelectedItem(); 11264 11265 // Update the menu to have the correct item focused 11266 this.menuInstance.focus( null, item ); 11267 this._setAria( item.data( "ui-selectmenu-item" ) ); 11268 11269 // Set disabled state 11270 this._setOption( "disabled", this.element.prop( "disabled" ) ); 11271 }, 11272 11273 open: function( event ) { 11274 if ( this.options.disabled ) { 11275 return; 11276 } 11277 11278 // If this is the first time the menu is being opened, render the items 11279 if ( !this.menuItems ) { 11280 this._refreshMenu(); 11281 } else { 11282 11283 // Menu clears focus on close, reset focus to selected item 11284 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); 11285 this.menuInstance.focus( null, this._getSelectedItem() ); 11286 } 11287 11288 this.isOpen = true; 11289 this._toggleAttr(); 11290 this._resizeMenu(); 11291 this._position(); 11292 11293 this._on( this.document, this._documentClick ); 11294 11295 this._trigger( "open", event ); 11296 }, 11297 11298 _position: function() { 11299 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 11300 }, 11301 11302 close: function( event ) { 11303 if ( !this.isOpen ) { 11304 return; 11305 } 11306 11307 this.isOpen = false; 11308 this._toggleAttr(); 11309 11310 this.range = null; 11311 this._off( this.document ); 11312 11313 this._trigger( "close", event ); 11314 }, 11315 11316 widget: function() { 11317 return this.button; 11318 }, 11319 11320 menuWidget: function() { 11321 return this.menu; 11322 }, 11323 11324 _renderMenu: function( ul, items ) { 11325 var that = this, 11326 currentOptgroup = ""; 11327 11328 $.each( items, function( index, item ) { 11329 if ( item.optgroup !== currentOptgroup ) { 11330 $( "<li>", { 11331 "class": "ui-selectmenu-optgroup ui-menu-divider" + 11332 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 11333 " ui-state-disabled" : 11334 "" ), 11335 text: item.optgroup 11336 }) 11337 .appendTo( ul ); 11338 11339 currentOptgroup = item.optgroup; 11340 } 11341 11342 that._renderItemData( ul, item ); 11343 }); 11344 }, 11345 11346 _renderItemData: function( ul, item ) { 11347 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 11348 }, 11349 11350 _renderItem: function( ul, item ) { 11351 var li = $( "<li>" ); 11352 11353 if ( item.disabled ) { 11354 li.addClass( "ui-state-disabled" ); 11355 } 11356 this._setText( li, item.label ); 11357 11358 return li.appendTo( ul ); 11359 }, 11360 11361 _setText: function( element, value ) { 11362 if ( value ) { 11363 element.text( value ); 11364 } else { 11365 element.html( " " ); 11366 } 11367 }, 11368 11369 _move: function( direction, event ) { 11370 var item, next, 11371 filter = ".ui-menu-item"; 11372 11373 if ( this.isOpen ) { 11374 item = this.menuItems.eq( this.focusIndex ); 11375 } else { 11376 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); 11377 filter += ":not(.ui-state-disabled)"; 11378 } 11379 11380 if ( direction === "first" || direction === "last" ) { 11381 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 11382 } else { 11383 next = item[ direction + "All" ]( filter ).eq( 0 ); 11384 } 11385 11386 if ( next.length ) { 11387 this.menuInstance.focus( event, next ); 11388 } 11389 }, 11390 11391 _getSelectedItem: function() { 11392 return this.menuItems.eq( this.element[ 0 ].selectedIndex ); 11393 }, 11394 11395 _toggle: function( event ) { 11396 this[ this.isOpen ? "close" : "open" ]( event ); 11397 }, 11398 11399 _setSelection: function() { 11400 var selection; 11401 11402 if ( !this.range ) { 11403 return; 11404 } 11405 11406 if ( window.getSelection ) { 11407 selection = window.getSelection(); 11408 selection.removeAllRanges(); 11409 selection.addRange( this.range ); 11410 11411 // support: IE8 11412 } else { 11413 this.range.select(); 11414 } 11415 11416 // support: IE 11417 // Setting the text selection kills the button focus in IE, but 11418 // restoring the focus doesn't kill the selection. 11419 this.button.focus(); 11420 }, 11421 11422 _documentClick: { 11423 mousedown: function( event ) { 11424 if ( !this.isOpen ) { 11425 return; 11426 } 11427 11428 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { 11429 this.close( event ); 11430 } 11431 } 11432 }, 11433 11434 _buttonEvents: { 11435 11436 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 11437 mousedown: function() { 11438 var selection; 11439 11440 if ( window.getSelection ) { 11441 selection = window.getSelection(); 11442 if ( selection.rangeCount ) { 11443 this.range = selection.getRangeAt( 0 ); 11444 } 11445 11446 // support: IE8 11447 } else { 11448 this.range = document.selection.createRange(); 11449 } 11450 }, 11451 11452 click: function( event ) { 11453 this._setSelection(); 11454 this._toggle( event ); 11455 }, 11456 11457 keydown: function( event ) { 11458 var preventDefault = true; 11459 switch ( event.keyCode ) { 11460 case $.ui.keyCode.TAB: 11461 case $.ui.keyCode.ESCAPE: 11462 this.close( event ); 11463 preventDefault = false; 11464 break; 11465 case $.ui.keyCode.ENTER: 11466 if ( this.isOpen ) { 11467 this._selectFocusedItem( event ); 11468 } 11469 break; 11470 case $.ui.keyCode.UP: 11471 if ( event.altKey ) { 11472 this._toggle( event ); 11473 } else { 11474 this._move( "prev", event ); 11475 } 11476 break; 11477 case $.ui.keyCode.DOWN: 11478 if ( event.altKey ) { 11479 this._toggle( event ); 11480 } else { 11481 this._move( "next", event ); 11482 } 11483 break; 11484 case $.ui.keyCode.SPACE: 11485 if ( this.isOpen ) { 11486 this._selectFocusedItem( event ); 11487 } else { 11488 this._toggle( event ); 11489 } 11490 break; 11491 case $.ui.keyCode.LEFT: 11492 this._move( "prev", event ); 11493 break; 11494 case $.ui.keyCode.RIGHT: 11495 this._move( "next", event ); 11496 break; 11497 case $.ui.keyCode.HOME: 11498 case $.ui.keyCode.PAGE_UP: 11499 this._move( "first", event ); 11500 break; 11501 case $.ui.keyCode.END: 11502 case $.ui.keyCode.PAGE_DOWN: 11503 this._move( "last", event ); 11504 break; 11505 default: 11506 this.menu.trigger( event ); 11507 preventDefault = false; 11508 } 11509 11510 if ( preventDefault ) { 11511 event.preventDefault(); 11512 } 11513 } 11514 }, 11515 11516 _selectFocusedItem: function( event ) { 11517 var item = this.menuItems.eq( this.focusIndex ); 11518 if ( !item.hasClass( "ui-state-disabled" ) ) { 11519 this._select( item.data( "ui-selectmenu-item" ), event ); 11520 } 11521 }, 11522 11523 _select: function( item, event ) { 11524 var oldIndex = this.element[ 0 ].selectedIndex; 11525 11526 // Change native select element 11527 this.element[ 0 ].selectedIndex = item.index; 11528 this._setText( this.buttonText, item.label ); 11529 this._setAria( item ); 11530 this._trigger( "select", event, { item: item } ); 11531 11532 if ( item.index !== oldIndex ) { 11533 this._trigger( "change", event, { item: item } ); 11534 } 11535 11536 this.close( event ); 11537 }, 11538 11539 _setAria: function( item ) { 11540 var id = this.menuItems.eq( item.index ).attr( "id" ); 11541 11542 this.button.attr({ 11543 "aria-labelledby": id, 11544 "aria-activedescendant": id 11545 }); 11546 this.menu.attr( "aria-activedescendant", id ); 11547 }, 11548 11549 _setOption: function( key, value ) { 11550 if ( key === "icons" ) { 11551 this.button.find( "span.ui-icon" ) 11552 .removeClass( this.options.icons.button ) 11553 .addClass( value.button ); 11554 } 11555 11556 this._super( key, value ); 11557 11558 if ( key === "appendTo" ) { 11559 this.menuWrap.appendTo( this._appendTo() ); 11560 } 11561 11562 if ( key === "disabled" ) { 11563 this.menuInstance.option( "disabled", value ); 11564 this.button 11565 .toggleClass( "ui-state-disabled", value ) 11566 .attr( "aria-disabled", value ); 11567 11568 this.element.prop( "disabled", value ); 11569 if ( value ) { 11570 this.button.attr( "tabindex", -1 ); 11571 this.close(); 11572 } else { 11573 this.button.attr( "tabindex", 0 ); 11574 } 11575 } 11576 11577 if ( key === "width" ) { 11578 this._resizeButton(); 11579 } 11580 }, 11581 11582 _appendTo: function() { 11583 var element = this.options.appendTo; 11584 11585 if ( element ) { 11586 element = element.jquery || element.nodeType ? 11587 $( element ) : 11588 this.document.find( element ).eq( 0 ); 11589 } 11590 11591 if ( !element || !element[ 0 ] ) { 11592 element = this.element.closest( ".ui-front" ); 11593 } 11594 11595 if ( !element.length ) { 11596 element = this.document[ 0 ].body; 11597 } 11598 11599 return element; 11600 }, 11601 11602 _toggleAttr: function() { 11603 this.button 11604 .toggleClass( "ui-corner-top", this.isOpen ) 11605 .toggleClass( "ui-corner-all", !this.isOpen ) 11606 .attr( "aria-expanded", this.isOpen ); 11607 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); 11608 this.menu.attr( "aria-hidden", !this.isOpen ); 11609 }, 11610 11611 _resizeButton: function() { 11612 var width = this.options.width; 11613 11614 if ( !width ) { 11615 width = this.element.show().outerWidth(); 11616 this.element.hide(); 11617 } 11618 11619 this.button.outerWidth( width ); 11620 }, 11621 11622 _resizeMenu: function() { 11623 this.menu.outerWidth( Math.max( 11624 this.button.outerWidth(), 11625 11626 // support: IE10 11627 // IE10 wraps long text (possibly a rounding bug) 11628 // so we add 1px to avoid the wrapping 11629 this.menu.width( "" ).outerWidth() + 1 11630 ) ); 11631 }, 11632 11633 _getCreateOptions: function() { 11634 return { disabled: this.element.prop( "disabled" ) }; 11635 }, 11636 11637 _parseOptions: function( options ) { 11638 var data = []; 11639 options.each(function( index, item ) { 11640 var option = $( item ), 11641 optgroup = option.parent( "optgroup" ); 11642 data.push({ 11643 element: option, 11644 index: index, 11645 value: option.attr( "value" ), 11646 label: option.text(), 11647 optgroup: optgroup.attr( "label" ) || "", 11648 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 11649 }); 11650 }); 11651 this.items = data; 11652 }, 11653 11654 _destroy: function() { 11655 this.menuWrap.remove(); 11656 this.button.remove(); 11657 this.element.show(); 11658 this.element.removeUniqueId(); 11659 this.label.attr( "for", this.ids.element ); 11660 } 11661}); 11662 11663 11664/*! 11665 * jQuery UI Slider 1.11.2 11666 * http://jqueryui.com 11667 * 11668 * Copyright 2014 jQuery Foundation and other contributors 11669 * Released under the MIT license. 11670 * http://jquery.org/license 11671 * 11672 * http://api.jqueryui.com/slider/ 11673 */ 11674 11675 11676var slider = $.widget( "ui.slider", $.ui.mouse, { 11677 version: "1.11.2", 11678 widgetEventPrefix: "slide", 11679 11680 options: { 11681 animate: false, 11682 distance: 0, 11683 max: 100, 11684 min: 0, 11685 orientation: "horizontal", 11686 range: false, 11687 step: 1, 11688 value: 0, 11689 values: null, 11690 11691 // callbacks 11692 change: null, 11693 slide: null, 11694 start: null, 11695 stop: null 11696 }, 11697 11698 // number of pages in a slider 11699 // (how many times can you page up/down to go through the whole range) 11700 numPages: 5, 11701 11702 _create: function() { 11703 this._keySliding = false; 11704 this._mouseSliding = false; 11705 this._animateOff = true; 11706 this._handleIndex = null; 11707 this._detectOrientation(); 11708 this._mouseInit(); 11709 this._calculateNewMax(); 11710 11711 this.element 11712 .addClass( "ui-slider" + 11713 " ui-slider-" + this.orientation + 11714 " ui-widget" + 11715 " ui-widget-content" + 11716 " ui-corner-all"); 11717 11718 this._refresh(); 11719 this._setOption( "disabled", this.options.disabled ); 11720 11721 this._animateOff = false; 11722 }, 11723 11724 _refresh: function() { 11725 this._createRange(); 11726 this._createHandles(); 11727 this._setupEvents(); 11728 this._refreshValue(); 11729 }, 11730 11731 _createHandles: function() { 11732 var i, handleCount, 11733 options = this.options, 11734 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 11735 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", 11736 handles = []; 11737 11738 handleCount = ( options.values && options.values.length ) || 1; 11739 11740 if ( existingHandles.length > handleCount ) { 11741 existingHandles.slice( handleCount ).remove(); 11742 existingHandles = existingHandles.slice( 0, handleCount ); 11743 } 11744 11745 for ( i = existingHandles.length; i < handleCount; i++ ) { 11746 handles.push( handle ); 11747 } 11748 11749 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 11750 11751 this.handle = this.handles.eq( 0 ); 11752 11753 this.handles.each(function( i ) { 11754 $( this ).data( "ui-slider-handle-index", i ); 11755 }); 11756 }, 11757 11758 _createRange: function() { 11759 var options = this.options, 11760 classes = ""; 11761 11762 if ( options.range ) { 11763 if ( options.range === true ) { 11764 if ( !options.values ) { 11765 options.values = [ this._valueMin(), this._valueMin() ]; 11766 } else if ( options.values.length && options.values.length !== 2 ) { 11767 options.values = [ options.values[0], options.values[0] ]; 11768 } else if ( $.isArray( options.values ) ) { 11769 options.values = options.values.slice(0); 11770 } 11771 } 11772 11773 if ( !this.range || !this.range.length ) { 11774 this.range = $( "<div></div>" ) 11775 .appendTo( this.element ); 11776 11777 classes = "ui-slider-range" + 11778 // note: this isn't the most fittingly semantic framework class for this element, 11779 // but worked best visually with a variety of themes 11780 " ui-widget-header ui-corner-all"; 11781 } else { 11782 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 11783 // Handle range switching from true to min/max 11784 .css({ 11785 "left": "", 11786 "bottom": "" 11787 }); 11788 } 11789 11790 this.range.addClass( classes + 11791 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 11792 } else { 11793 if ( this.range ) { 11794 this.range.remove(); 11795 } 11796 this.range = null; 11797 } 11798 }, 11799 11800 _setupEvents: function() { 11801 this._off( this.handles ); 11802 this._on( this.handles, this._handleEvents ); 11803 this._hoverable( this.handles ); 11804 this._focusable( this.handles ); 11805 }, 11806 11807 _destroy: function() { 11808 this.handles.remove(); 11809 if ( this.range ) { 11810 this.range.remove(); 11811 } 11812 11813 this.element 11814 .removeClass( "ui-slider" + 11815 " ui-slider-horizontal" + 11816 " ui-slider-vertical" + 11817 " ui-widget" + 11818 " ui-widget-content" + 11819 " ui-corner-all" ); 11820 11821 this._mouseDestroy(); 11822 }, 11823 11824 _mouseCapture: function( event ) { 11825 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 11826 that = this, 11827 o = this.options; 11828 11829 if ( o.disabled ) { 11830 return false; 11831 } 11832 11833 this.elementSize = { 11834 width: this.element.outerWidth(), 11835 height: this.element.outerHeight() 11836 }; 11837 this.elementOffset = this.element.offset(); 11838 11839 position = { x: event.pageX, y: event.pageY }; 11840 normValue = this._normValueFromMouse( position ); 11841 distance = this._valueMax() - this._valueMin() + 1; 11842 this.handles.each(function( i ) { 11843 var thisDistance = Math.abs( normValue - that.values(i) ); 11844 if (( distance > thisDistance ) || 11845 ( distance === thisDistance && 11846 (i === that._lastChangedValue || that.values(i) === o.min ))) { 11847 distance = thisDistance; 11848 closestHandle = $( this ); 11849 index = i; 11850 } 11851 }); 11852 11853 allowed = this._start( event, index ); 11854 if ( allowed === false ) { 11855 return false; 11856 } 11857 this._mouseSliding = true; 11858 11859 this._handleIndex = index; 11860 11861 closestHandle 11862 .addClass( "ui-state-active" ) 11863 .focus(); 11864 11865 offset = closestHandle.offset(); 11866 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 11867 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 11868 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 11869 top: event.pageY - offset.top - 11870 ( closestHandle.height() / 2 ) - 11871 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 11872 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 11873 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 11874 }; 11875 11876 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 11877 this._slide( event, index, normValue ); 11878 } 11879 this._animateOff = true; 11880 return true; 11881 }, 11882 11883 _mouseStart: function() { 11884 return true; 11885 }, 11886 11887 _mouseDrag: function( event ) { 11888 var position = { x: event.pageX, y: event.pageY }, 11889 normValue = this._normValueFromMouse( position ); 11890 11891 this._slide( event, this._handleIndex, normValue ); 11892 11893 return false; 11894 }, 11895 11896 _mouseStop: function( event ) { 11897 this.handles.removeClass( "ui-state-active" ); 11898 this._mouseSliding = false; 11899 11900 this._stop( event, this._handleIndex ); 11901 this._change( event, this._handleIndex ); 11902 11903 this._handleIndex = null; 11904 this._clickOffset = null; 11905 this._animateOff = false; 11906 11907 return false; 11908 }, 11909 11910 _detectOrientation: function() { 11911 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 11912 }, 11913 11914 _normValueFromMouse: function( position ) { 11915 var pixelTotal, 11916 pixelMouse, 11917 percentMouse, 11918 valueTotal, 11919 valueMouse; 11920 11921 if ( this.orientation === "horizontal" ) { 11922 pixelTotal = this.elementSize.width; 11923 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 11924 } else { 11925 pixelTotal = this.elementSize.height; 11926 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 11927 } 11928 11929 percentMouse = ( pixelMouse / pixelTotal ); 11930 if ( percentMouse > 1 ) { 11931 percentMouse = 1; 11932 } 11933 if ( percentMouse < 0 ) { 11934 percentMouse = 0; 11935 } 11936 if ( this.orientation === "vertical" ) { 11937 percentMouse = 1 - percentMouse; 11938 } 11939 11940 valueTotal = this._valueMax() - this._valueMin(); 11941 valueMouse = this._valueMin() + percentMouse * valueTotal; 11942 11943 return this._trimAlignValue( valueMouse ); 11944 }, 11945 11946 _start: function( event, index ) { 11947 var uiHash = { 11948 handle: this.handles[ index ], 11949 value: this.value() 11950 }; 11951 if ( this.options.values && this.options.values.length ) { 11952 uiHash.value = this.values( index ); 11953 uiHash.values = this.values(); 11954 } 11955 return this._trigger( "start", event, uiHash ); 11956 }, 11957 11958 _slide: function( event, index, newVal ) { 11959 var otherVal, 11960 newValues, 11961 allowed; 11962 11963 if ( this.options.values && this.options.values.length ) { 11964 otherVal = this.values( index ? 0 : 1 ); 11965 11966 if ( ( this.options.values.length === 2 && this.options.range === true ) && 11967 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 11968 ) { 11969 newVal = otherVal; 11970 } 11971 11972 if ( newVal !== this.values( index ) ) { 11973 newValues = this.values(); 11974 newValues[ index ] = newVal; 11975 // A slide can be canceled by returning false from the slide callback 11976 allowed = this._trigger( "slide", event, { 11977 handle: this.handles[ index ], 11978 value: newVal, 11979 values: newValues 11980 } ); 11981 otherVal = this.values( index ? 0 : 1 ); 11982 if ( allowed !== false ) { 11983 this.values( index, newVal ); 11984 } 11985 } 11986 } else { 11987 if ( newVal !== this.value() ) { 11988 // A slide can be canceled by returning false from the slide callback 11989 allowed = this._trigger( "slide", event, { 11990 handle: this.handles[ index ], 11991 value: newVal 11992 } ); 11993 if ( allowed !== false ) { 11994 this.value( newVal ); 11995 } 11996 } 11997 } 11998 }, 11999 12000 _stop: function( event, index ) { 12001 var uiHash = { 12002 handle: this.handles[ index ], 12003 value: this.value() 12004 }; 12005 if ( this.options.values && this.options.values.length ) { 12006 uiHash.value = this.values( index ); 12007 uiHash.values = this.values(); 12008 } 12009 12010 this._trigger( "stop", event, uiHash ); 12011 }, 12012 12013 _change: function( event, index ) { 12014 if ( !this._keySliding && !this._mouseSliding ) { 12015 var uiHash = { 12016 handle: this.handles[ index ], 12017 value: this.value() 12018 }; 12019 if ( this.options.values && this.options.values.length ) { 12020 uiHash.value = this.values( index ); 12021 uiHash.values = this.values(); 12022 } 12023 12024 //store the last changed value index for reference when handles overlap 12025 this._lastChangedValue = index; 12026 12027 this._trigger( "change", event, uiHash ); 12028 } 12029 }, 12030 12031 value: function( newValue ) { 12032 if ( arguments.length ) { 12033 this.options.value = this._trimAlignValue( newValue ); 12034 this._refreshValue(); 12035 this._change( null, 0 ); 12036 return; 12037 } 12038 12039 return this._value(); 12040 }, 12041 12042 values: function( index, newValue ) { 12043 var vals, 12044 newValues, 12045 i; 12046 12047 if ( arguments.length > 1 ) { 12048 this.options.values[ index ] = this._trimAlignValue( newValue ); 12049 this._refreshValue(); 12050 this._change( null, index ); 12051 return; 12052 } 12053 12054 if ( arguments.length ) { 12055 if ( $.isArray( arguments[ 0 ] ) ) { 12056 vals = this.options.values; 12057 newValues = arguments[ 0 ]; 12058 for ( i = 0; i < vals.length; i += 1 ) { 12059 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 12060 this._change( null, i ); 12061 } 12062 this._refreshValue(); 12063 } else { 12064 if ( this.options.values && this.options.values.length ) { 12065 return this._values( index ); 12066 } else { 12067 return this.value(); 12068 } 12069 } 12070 } else { 12071 return this._values(); 12072 } 12073 }, 12074 12075 _setOption: function( key, value ) { 12076 var i, 12077 valsLength = 0; 12078 12079 if ( key === "range" && this.options.range === true ) { 12080 if ( value === "min" ) { 12081 this.options.value = this._values( 0 ); 12082 this.options.values = null; 12083 } else if ( value === "max" ) { 12084 this.options.value = this._values( this.options.values.length - 1 ); 12085 this.options.values = null; 12086 } 12087 } 12088 12089 if ( $.isArray( this.options.values ) ) { 12090 valsLength = this.options.values.length; 12091 } 12092 12093 if ( key === "disabled" ) { 12094 this.element.toggleClass( "ui-state-disabled", !!value ); 12095 } 12096 12097 this._super( key, value ); 12098 12099 switch ( key ) { 12100 case "orientation": 12101 this._detectOrientation(); 12102 this.element 12103 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 12104 .addClass( "ui-slider-" + this.orientation ); 12105 this._refreshValue(); 12106 12107 // Reset positioning from previous orientation 12108 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 12109 break; 12110 case "value": 12111 this._animateOff = true; 12112 this._refreshValue(); 12113 this._change( null, 0 ); 12114 this._animateOff = false; 12115 break; 12116 case "values": 12117 this._animateOff = true; 12118 this._refreshValue(); 12119 for ( i = 0; i < valsLength; i += 1 ) { 12120 this._change( null, i ); 12121 } 12122 this._animateOff = false; 12123 break; 12124 case "step": 12125 case "min": 12126 case "max": 12127 this._animateOff = true; 12128 this._calculateNewMax(); 12129 this._refreshValue(); 12130 this._animateOff = false; 12131 break; 12132 case "range": 12133 this._animateOff = true; 12134 this._refresh(); 12135 this._animateOff = false; 12136 break; 12137 } 12138 }, 12139 12140 //internal value getter 12141 // _value() returns value trimmed by min and max, aligned by step 12142 _value: function() { 12143 var val = this.options.value; 12144 val = this._trimAlignValue( val ); 12145 12146 return val; 12147 }, 12148 12149 //internal values getter 12150 // _values() returns array of values trimmed by min and max, aligned by step 12151 // _values( index ) returns single value trimmed by min and max, aligned by step 12152 _values: function( index ) { 12153 var val, 12154 vals, 12155 i; 12156 12157 if ( arguments.length ) { 12158 val = this.options.values[ index ]; 12159 val = this._trimAlignValue( val ); 12160 12161 return val; 12162 } else if ( this.options.values && this.options.values.length ) { 12163 // .slice() creates a copy of the array 12164 // this copy gets trimmed by min and max and then returned 12165 vals = this.options.values.slice(); 12166 for ( i = 0; i < vals.length; i += 1) { 12167 vals[ i ] = this._trimAlignValue( vals[ i ] ); 12168 } 12169 12170 return vals; 12171 } else { 12172 return []; 12173 } 12174 }, 12175 12176 // returns the step-aligned value that val is closest to, between (inclusive) min and max 12177 _trimAlignValue: function( val ) { 12178 if ( val <= this._valueMin() ) { 12179 return this._valueMin(); 12180 } 12181 if ( val >= this._valueMax() ) { 12182 return this._valueMax(); 12183 } 12184 var step = ( this.options.step > 0 ) ? this.options.step : 1, 12185 valModStep = (val - this._valueMin()) % step, 12186 alignValue = val - valModStep; 12187 12188 if ( Math.abs(valModStep) * 2 >= step ) { 12189 alignValue += ( valModStep > 0 ) ? step : ( -step ); 12190 } 12191 12192 // Since JavaScript has problems with large floats, round 12193 // the final value to 5 digits after the decimal point (see #4124) 12194 return parseFloat( alignValue.toFixed(5) ); 12195 }, 12196 12197 _calculateNewMax: function() { 12198 var remainder = ( this.options.max - this._valueMin() ) % this.options.step; 12199 this.max = this.options.max - remainder; 12200 }, 12201 12202 _valueMin: function() { 12203 return this.options.min; 12204 }, 12205 12206 _valueMax: function() { 12207 return this.max; 12208 }, 12209 12210 _refreshValue: function() { 12211 var lastValPercent, valPercent, value, valueMin, valueMax, 12212 oRange = this.options.range, 12213 o = this.options, 12214 that = this, 12215 animate = ( !this._animateOff ) ? o.animate : false, 12216 _set = {}; 12217 12218 if ( this.options.values && this.options.values.length ) { 12219 this.handles.each(function( i ) { 12220 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 12221 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12222 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12223 if ( that.options.range === true ) { 12224 if ( that.orientation === "horizontal" ) { 12225 if ( i === 0 ) { 12226 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 12227 } 12228 if ( i === 1 ) { 12229 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12230 } 12231 } else { 12232 if ( i === 0 ) { 12233 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 12234 } 12235 if ( i === 1 ) { 12236 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12237 } 12238 } 12239 } 12240 lastValPercent = valPercent; 12241 }); 12242 } else { 12243 value = this.value(); 12244 valueMin = this._valueMin(); 12245 valueMax = this._valueMax(); 12246 valPercent = ( valueMax !== valueMin ) ? 12247 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 12248 0; 12249 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12250 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12251 12252 if ( oRange === "min" && this.orientation === "horizontal" ) { 12253 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 12254 } 12255 if ( oRange === "max" && this.orientation === "horizontal" ) { 12256 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12257 } 12258 if ( oRange === "min" && this.orientation === "vertical" ) { 12259 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 12260 } 12261 if ( oRange === "max" && this.orientation === "vertical" ) { 12262 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12263 } 12264 } 12265 }, 12266 12267 _handleEvents: { 12268 keydown: function( event ) { 12269 var allowed, curVal, newVal, step, 12270 index = $( event.target ).data( "ui-slider-handle-index" ); 12271 12272 switch ( event.keyCode ) { 12273 case $.ui.keyCode.HOME: 12274 case $.ui.keyCode.END: 12275 case $.ui.keyCode.PAGE_UP: 12276 case $.ui.keyCode.PAGE_DOWN: 12277 case $.ui.keyCode.UP: 12278 case $.ui.keyCode.RIGHT: 12279 case $.ui.keyCode.DOWN: 12280 case $.ui.keyCode.LEFT: 12281 event.preventDefault(); 12282 if ( !this._keySliding ) { 12283 this._keySliding = true; 12284 $( event.target ).addClass( "ui-state-active" ); 12285 allowed = this._start( event, index ); 12286 if ( allowed === false ) { 12287 return; 12288 } 12289 } 12290 break; 12291 } 12292 12293 step = this.options.step; 12294 if ( this.options.values && this.options.values.length ) { 12295 curVal = newVal = this.values( index ); 12296 } else { 12297 curVal = newVal = this.value(); 12298 } 12299 12300 switch ( event.keyCode ) { 12301 case $.ui.keyCode.HOME: 12302 newVal = this._valueMin(); 12303 break; 12304 case $.ui.keyCode.END: 12305 newVal = this._valueMax(); 12306 break; 12307 case $.ui.keyCode.PAGE_UP: 12308 newVal = this._trimAlignValue( 12309 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 12310 ); 12311 break; 12312 case $.ui.keyCode.PAGE_DOWN: 12313 newVal = this._trimAlignValue( 12314 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); 12315 break; 12316 case $.ui.keyCode.UP: 12317 case $.ui.keyCode.RIGHT: 12318 if ( curVal === this._valueMax() ) { 12319 return; 12320 } 12321 newVal = this._trimAlignValue( curVal + step ); 12322 break; 12323 case $.ui.keyCode.DOWN: 12324 case $.ui.keyCode.LEFT: 12325 if ( curVal === this._valueMin() ) { 12326 return; 12327 } 12328 newVal = this._trimAlignValue( curVal - step ); 12329 break; 12330 } 12331 12332 this._slide( event, index, newVal ); 12333 }, 12334 keyup: function( event ) { 12335 var index = $( event.target ).data( "ui-slider-handle-index" ); 12336 12337 if ( this._keySliding ) { 12338 this._keySliding = false; 12339 this._stop( event, index ); 12340 this._change( event, index ); 12341 $( event.target ).removeClass( "ui-state-active" ); 12342 } 12343 } 12344 } 12345}); 12346 12347 12348/*! 12349 * jQuery UI Spinner 1.11.2 12350 * http://jqueryui.com 12351 * 12352 * Copyright 2014 jQuery Foundation and other contributors 12353 * Released under the MIT license. 12354 * http://jquery.org/license 12355 * 12356 * http://api.jqueryui.com/spinner/ 12357 */ 12358 12359 12360function spinner_modifier( fn ) { 12361 return function() { 12362 var previous = this.element.val(); 12363 fn.apply( this, arguments ); 12364 this._refresh(); 12365 if ( previous !== this.element.val() ) { 12366 this._trigger( "change" ); 12367 } 12368 }; 12369} 12370 12371var spinner = $.widget( "ui.spinner", { 12372 version: "1.11.2", 12373 defaultElement: "<input>", 12374 widgetEventPrefix: "spin", 12375 options: { 12376 culture: null, 12377 icons: { 12378 down: "ui-icon-triangle-1-s", 12379 up: "ui-icon-triangle-1-n" 12380 }, 12381 incremental: true, 12382 max: null, 12383 min: null, 12384 numberFormat: null, 12385 page: 10, 12386 step: 1, 12387 12388 change: null, 12389 spin: null, 12390 start: null, 12391 stop: null 12392 }, 12393 12394 _create: function() { 12395 // handle string values that need to be parsed 12396 this._setOption( "max", this.options.max ); 12397 this._setOption( "min", this.options.min ); 12398 this._setOption( "step", this.options.step ); 12399 12400 // Only format if there is a value, prevents the field from being marked 12401 // as invalid in Firefox, see #9573. 12402 if ( this.value() !== "" ) { 12403 // Format the value, but don't constrain. 12404 this._value( this.element.val(), true ); 12405 } 12406 12407 this._draw(); 12408 this._on( this._events ); 12409 this._refresh(); 12410 12411 // turning off autocomplete prevents the browser from remembering the 12412 // value when navigating through history, so we re-enable autocomplete 12413 // if the page is unloaded before the widget is destroyed. #7790 12414 this._on( this.window, { 12415 beforeunload: function() { 12416 this.element.removeAttr( "autocomplete" ); 12417 } 12418 }); 12419 }, 12420 12421 _getCreateOptions: function() { 12422 var options = {}, 12423 element = this.element; 12424 12425 $.each( [ "min", "max", "step" ], function( i, option ) { 12426 var value = element.attr( option ); 12427 if ( value !== undefined && value.length ) { 12428 options[ option ] = value; 12429 } 12430 }); 12431 12432 return options; 12433 }, 12434 12435 _events: { 12436 keydown: function( event ) { 12437 if ( this._start( event ) && this._keydown( event ) ) { 12438 event.preventDefault(); 12439 } 12440 }, 12441 keyup: "_stop", 12442 focus: function() { 12443 this.previous = this.element.val(); 12444 }, 12445 blur: function( event ) { 12446 if ( this.cancelBlur ) { 12447 delete this.cancelBlur; 12448 return; 12449 } 12450 12451 this._stop(); 12452 this._refresh(); 12453 if ( this.previous !== this.element.val() ) { 12454 this._trigger( "change", event ); 12455 } 12456 }, 12457 mousewheel: function( event, delta ) { 12458 if ( !delta ) { 12459 return; 12460 } 12461 if ( !this.spinning && !this._start( event ) ) { 12462 return false; 12463 } 12464 12465 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 12466 clearTimeout( this.mousewheelTimer ); 12467 this.mousewheelTimer = this._delay(function() { 12468 if ( this.spinning ) { 12469 this._stop( event ); 12470 } 12471 }, 100 ); 12472 event.preventDefault(); 12473 }, 12474 "mousedown .ui-spinner-button": function( event ) { 12475 var previous; 12476 12477 // We never want the buttons to have focus; whenever the user is 12478 // interacting with the spinner, the focus should be on the input. 12479 // If the input is focused then this.previous is properly set from 12480 // when the input first received focus. If the input is not focused 12481 // then we need to set this.previous based on the value before spinning. 12482 previous = this.element[0] === this.document[0].activeElement ? 12483 this.previous : this.element.val(); 12484 function checkFocus() { 12485 var isActive = this.element[0] === this.document[0].activeElement; 12486 if ( !isActive ) { 12487 this.element.focus(); 12488 this.previous = previous; 12489 // support: IE 12490 // IE sets focus asynchronously, so we need to check if focus 12491 // moved off of the input because the user clicked on the button. 12492 this._delay(function() { 12493 this.previous = previous; 12494 }); 12495 } 12496 } 12497 12498 // ensure focus is on (or stays on) the text field 12499 event.preventDefault(); 12500 checkFocus.call( this ); 12501 12502 // support: IE 12503 // IE doesn't prevent moving focus even with event.preventDefault() 12504 // so we set a flag to know when we should ignore the blur event 12505 // and check (again) if focus moved off of the input. 12506 this.cancelBlur = true; 12507 this._delay(function() { 12508 delete this.cancelBlur; 12509 checkFocus.call( this ); 12510 }); 12511 12512 if ( this._start( event ) === false ) { 12513 return; 12514 } 12515 12516 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12517 }, 12518 "mouseup .ui-spinner-button": "_stop", 12519 "mouseenter .ui-spinner-button": function( event ) { 12520 // button will add ui-state-active if mouse was down while mouseleave and kept down 12521 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 12522 return; 12523 } 12524 12525 if ( this._start( event ) === false ) { 12526 return false; 12527 } 12528 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12529 }, 12530 // TODO: do we really want to consider this a stop? 12531 // shouldn't we just stop the repeater and wait until mouseup before 12532 // we trigger the stop event? 12533 "mouseleave .ui-spinner-button": "_stop" 12534 }, 12535 12536 _draw: function() { 12537 var uiSpinner = this.uiSpinner = this.element 12538 .addClass( "ui-spinner-input" ) 12539 .attr( "autocomplete", "off" ) 12540 .wrap( this._uiSpinnerHtml() ) 12541 .parent() 12542 // add buttons 12543 .append( this._buttonHtml() ); 12544 12545 this.element.attr( "role", "spinbutton" ); 12546 12547 // button bindings 12548 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 12549 .attr( "tabIndex", -1 ) 12550 .button() 12551 .removeClass( "ui-corner-all" ); 12552 12553 // IE 6 doesn't understand height: 50% for the buttons 12554 // unless the wrapper has an explicit height 12555 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 12556 uiSpinner.height() > 0 ) { 12557 uiSpinner.height( uiSpinner.height() ); 12558 } 12559 12560 // disable spinner if element was already disabled 12561 if ( this.options.disabled ) { 12562 this.disable(); 12563 } 12564 }, 12565 12566 _keydown: function( event ) { 12567 var options = this.options, 12568 keyCode = $.ui.keyCode; 12569 12570 switch ( event.keyCode ) { 12571 case keyCode.UP: 12572 this._repeat( null, 1, event ); 12573 return true; 12574 case keyCode.DOWN: 12575 this._repeat( null, -1, event ); 12576 return true; 12577 case keyCode.PAGE_UP: 12578 this._repeat( null, options.page, event ); 12579 return true; 12580 case keyCode.PAGE_DOWN: 12581 this._repeat( null, -options.page, event ); 12582 return true; 12583 } 12584 12585 return false; 12586 }, 12587 12588 _uiSpinnerHtml: function() { 12589 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 12590 }, 12591 12592 _buttonHtml: function() { 12593 return "" + 12594 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 12595 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 12596 "</a>" + 12597 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 12598 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 12599 "</a>"; 12600 }, 12601 12602 _start: function( event ) { 12603 if ( !this.spinning && this._trigger( "start", event ) === false ) { 12604 return false; 12605 } 12606 12607 if ( !this.counter ) { 12608 this.counter = 1; 12609 } 12610 this.spinning = true; 12611 return true; 12612 }, 12613 12614 _repeat: function( i, steps, event ) { 12615 i = i || 500; 12616 12617 clearTimeout( this.timer ); 12618 this.timer = this._delay(function() { 12619 this._repeat( 40, steps, event ); 12620 }, i ); 12621 12622 this._spin( steps * this.options.step, event ); 12623 }, 12624 12625 _spin: function( step, event ) { 12626 var value = this.value() || 0; 12627 12628 if ( !this.counter ) { 12629 this.counter = 1; 12630 } 12631 12632 value = this._adjustValue( value + step * this._increment( this.counter ) ); 12633 12634 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 12635 this._value( value ); 12636 this.counter++; 12637 } 12638 }, 12639 12640 _increment: function( i ) { 12641 var incremental = this.options.incremental; 12642 12643 if ( incremental ) { 12644 return $.isFunction( incremental ) ? 12645 incremental( i ) : 12646 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 12647 } 12648 12649 return 1; 12650 }, 12651 12652 _precision: function() { 12653 var precision = this._precisionOf( this.options.step ); 12654 if ( this.options.min !== null ) { 12655 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 12656 } 12657 return precision; 12658 }, 12659 12660 _precisionOf: function( num ) { 12661 var str = num.toString(), 12662 decimal = str.indexOf( "." ); 12663 return decimal === -1 ? 0 : str.length - decimal - 1; 12664 }, 12665 12666 _adjustValue: function( value ) { 12667 var base, aboveMin, 12668 options = this.options; 12669 12670 // make sure we're at a valid step 12671 // - find out where we are relative to the base (min or 0) 12672 base = options.min !== null ? options.min : 0; 12673 aboveMin = value - base; 12674 // - round to the nearest step 12675 aboveMin = Math.round(aboveMin / options.step) * options.step; 12676 // - rounding is based on 0, so adjust back to our base 12677 value = base + aboveMin; 12678 12679 // fix precision from bad JS floating point math 12680 value = parseFloat( value.toFixed( this._precision() ) ); 12681 12682 // clamp the value 12683 if ( options.max !== null && value > options.max) { 12684 return options.max; 12685 } 12686 if ( options.min !== null && value < options.min ) { 12687 return options.min; 12688 } 12689 12690 return value; 12691 }, 12692 12693 _stop: function( event ) { 12694 if ( !this.spinning ) { 12695 return; 12696 } 12697 12698 clearTimeout( this.timer ); 12699 clearTimeout( this.mousewheelTimer ); 12700 this.counter = 0; 12701 this.spinning = false; 12702 this._trigger( "stop", event ); 12703 }, 12704 12705 _setOption: function( key, value ) { 12706 if ( key === "culture" || key === "numberFormat" ) { 12707 var prevValue = this._parse( this.element.val() ); 12708 this.options[ key ] = value; 12709 this.element.val( this._format( prevValue ) ); 12710 return; 12711 } 12712 12713 if ( key === "max" || key === "min" || key === "step" ) { 12714 if ( typeof value === "string" ) { 12715 value = this._parse( value ); 12716 } 12717 } 12718 if ( key === "icons" ) { 12719 this.buttons.first().find( ".ui-icon" ) 12720 .removeClass( this.options.icons.up ) 12721 .addClass( value.up ); 12722 this.buttons.last().find( ".ui-icon" ) 12723 .removeClass( this.options.icons.down ) 12724 .addClass( value.down ); 12725 } 12726 12727 this._super( key, value ); 12728 12729 if ( key === "disabled" ) { 12730 this.widget().toggleClass( "ui-state-disabled", !!value ); 12731 this.element.prop( "disabled", !!value ); 12732 this.buttons.button( value ? "disable" : "enable" ); 12733 } 12734 }, 12735 12736 _setOptions: spinner_modifier(function( options ) { 12737 this._super( options ); 12738 }), 12739 12740 _parse: function( val ) { 12741 if ( typeof val === "string" && val !== "" ) { 12742 val = window.Globalize && this.options.numberFormat ? 12743 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 12744 } 12745 return val === "" || isNaN( val ) ? null : val; 12746 }, 12747 12748 _format: function( value ) { 12749 if ( value === "" ) { 12750 return ""; 12751 } 12752 return window.Globalize && this.options.numberFormat ? 12753 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 12754 value; 12755 }, 12756 12757 _refresh: function() { 12758 this.element.attr({ 12759 "aria-valuemin": this.options.min, 12760 "aria-valuemax": this.options.max, 12761 // TODO: what should we do with values that can't be parsed? 12762 "aria-valuenow": this._parse( this.element.val() ) 12763 }); 12764 }, 12765 12766 isValid: function() { 12767 var value = this.value(); 12768 12769 // null is invalid 12770 if ( value === null ) { 12771 return false; 12772 } 12773 12774 // if value gets adjusted, it's invalid 12775 return value === this._adjustValue( value ); 12776 }, 12777 12778 // update the value without triggering change 12779 _value: function( value, allowAny ) { 12780 var parsed; 12781 if ( value !== "" ) { 12782 parsed = this._parse( value ); 12783 if ( parsed !== null ) { 12784 if ( !allowAny ) { 12785 parsed = this._adjustValue( parsed ); 12786 } 12787 value = this._format( parsed ); 12788 } 12789 } 12790 this.element.val( value ); 12791 this._refresh(); 12792 }, 12793 12794 _destroy: function() { 12795 this.element 12796 .removeClass( "ui-spinner-input" ) 12797 .prop( "disabled", false ) 12798 .removeAttr( "autocomplete" ) 12799 .removeAttr( "role" ) 12800 .removeAttr( "aria-valuemin" ) 12801 .removeAttr( "aria-valuemax" ) 12802 .removeAttr( "aria-valuenow" ); 12803 this.uiSpinner.replaceWith( this.element ); 12804 }, 12805 12806 stepUp: spinner_modifier(function( steps ) { 12807 this._stepUp( steps ); 12808 }), 12809 _stepUp: function( steps ) { 12810 if ( this._start() ) { 12811 this._spin( (steps || 1) * this.options.step ); 12812 this._stop(); 12813 } 12814 }, 12815 12816 stepDown: spinner_modifier(function( steps ) { 12817 this._stepDown( steps ); 12818 }), 12819 _stepDown: function( steps ) { 12820 if ( this._start() ) { 12821 this._spin( (steps || 1) * -this.options.step ); 12822 this._stop(); 12823 } 12824 }, 12825 12826 pageUp: spinner_modifier(function( pages ) { 12827 this._stepUp( (pages || 1) * this.options.page ); 12828 }), 12829 12830 pageDown: spinner_modifier(function( pages ) { 12831 this._stepDown( (pages || 1) * this.options.page ); 12832 }), 12833 12834 value: function( newVal ) { 12835 if ( !arguments.length ) { 12836 return this._parse( this.element.val() ); 12837 } 12838 spinner_modifier( this._value ).call( this, newVal ); 12839 }, 12840 12841 widget: function() { 12842 return this.uiSpinner; 12843 } 12844}); 12845 12846 12847/*! 12848 * jQuery UI Tabs 1.11.2 12849 * http://jqueryui.com 12850 * 12851 * Copyright 2014 jQuery Foundation and other contributors 12852 * Released under the MIT license. 12853 * http://jquery.org/license 12854 * 12855 * http://api.jqueryui.com/tabs/ 12856 */ 12857 12858 12859var tabs = $.widget( "ui.tabs", { 12860 version: "1.11.2", 12861 delay: 300, 12862 options: { 12863 active: null, 12864 collapsible: false, 12865 event: "click", 12866 heightStyle: "content", 12867 hide: null, 12868 show: null, 12869 12870 // callbacks 12871 activate: null, 12872 beforeActivate: null, 12873 beforeLoad: null, 12874 load: null 12875 }, 12876 12877 _isLocal: (function() { 12878 var rhash = /#.*$/; 12879 12880 return function( anchor ) { 12881 var anchorUrl, locationUrl; 12882 12883 // support: IE7 12884 // IE7 doesn't normalize the href property when set via script (#9317) 12885 anchor = anchor.cloneNode( false ); 12886 12887 anchorUrl = anchor.href.replace( rhash, "" ); 12888 locationUrl = location.href.replace( rhash, "" ); 12889 12890 // decoding may throw an error if the URL isn't UTF-8 (#9518) 12891 try { 12892 anchorUrl = decodeURIComponent( anchorUrl ); 12893 } catch ( error ) {} 12894 try { 12895 locationUrl = decodeURIComponent( locationUrl ); 12896 } catch ( error ) {} 12897 12898 return anchor.hash.length > 1 && anchorUrl === locationUrl; 12899 }; 12900 })(), 12901 12902 _create: function() { 12903 var that = this, 12904 options = this.options; 12905 12906 this.running = false; 12907 12908 this.element 12909 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 12910 .toggleClass( "ui-tabs-collapsible", options.collapsible ); 12911 12912 this._processTabs(); 12913 options.active = this._initialActive(); 12914 12915 // Take disabling tabs via class attribute from HTML 12916 // into account and update option properly. 12917 if ( $.isArray( options.disabled ) ) { 12918 options.disabled = $.unique( options.disabled.concat( 12919 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 12920 return that.tabs.index( li ); 12921 }) 12922 ) ).sort(); 12923 } 12924 12925 // check for length avoids error when initializing empty list 12926 if ( this.options.active !== false && this.anchors.length ) { 12927 this.active = this._findActive( options.active ); 12928 } else { 12929 this.active = $(); 12930 } 12931 12932 this._refresh(); 12933 12934 if ( this.active.length ) { 12935 this.load( options.active ); 12936 } 12937 }, 12938 12939 _initialActive: function() { 12940 var active = this.options.active, 12941 collapsible = this.options.collapsible, 12942 locationHash = location.hash.substring( 1 ); 12943 12944 if ( active === null ) { 12945 // check the fragment identifier in the URL 12946 if ( locationHash ) { 12947 this.tabs.each(function( i, tab ) { 12948 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 12949 active = i; 12950 return false; 12951 } 12952 }); 12953 } 12954 12955 // check for a tab marked active via a class 12956 if ( active === null ) { 12957 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 12958 } 12959 12960 // no active tab, set to false 12961 if ( active === null || active === -1 ) { 12962 active = this.tabs.length ? 0 : false; 12963 } 12964 } 12965 12966 // handle numbers: negative, out of range 12967 if ( active !== false ) { 12968 active = this.tabs.index( this.tabs.eq( active ) ); 12969 if ( active === -1 ) { 12970 active = collapsible ? false : 0; 12971 } 12972 } 12973 12974 // don't allow collapsible: false and active: false 12975 if ( !collapsible && active === false && this.anchors.length ) { 12976 active = 0; 12977 } 12978 12979 return active; 12980 }, 12981 12982 _getCreateEventData: function() { 12983 return { 12984 tab: this.active, 12985 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 12986 }; 12987 }, 12988 12989 _tabKeydown: function( event ) { 12990 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 12991 selectedIndex = this.tabs.index( focusedTab ), 12992 goingForward = true; 12993 12994 if ( this._handlePageNav( event ) ) { 12995 return; 12996 } 12997 12998 switch ( event.keyCode ) { 12999 case $.ui.keyCode.RIGHT: 13000 case $.ui.keyCode.DOWN: 13001 selectedIndex++; 13002 break; 13003 case $.ui.keyCode.UP: 13004 case $.ui.keyCode.LEFT: 13005 goingForward = false; 13006 selectedIndex--; 13007 break; 13008 case $.ui.keyCode.END: 13009 selectedIndex = this.anchors.length - 1; 13010 break; 13011 case $.ui.keyCode.HOME: 13012 selectedIndex = 0; 13013 break; 13014 case $.ui.keyCode.SPACE: 13015 // Activate only, no collapsing 13016 event.preventDefault(); 13017 clearTimeout( this.activating ); 13018 this._activate( selectedIndex ); 13019 return; 13020 case $.ui.keyCode.ENTER: 13021 // Toggle (cancel delayed activation, allow collapsing) 13022 event.preventDefault(); 13023 clearTimeout( this.activating ); 13024 // Determine if we should collapse or activate 13025 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13026 return; 13027 default: 13028 return; 13029 } 13030 13031 // Focus the appropriate tab, based on which key was pressed 13032 event.preventDefault(); 13033 clearTimeout( this.activating ); 13034 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13035 13036 // Navigating with control key will prevent automatic activation 13037 if ( !event.ctrlKey ) { 13038 // Update aria-selected immediately so that AT think the tab is already selected. 13039 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13040 // but the tab will already be activated by the time the announcement finishes. 13041 focusedTab.attr( "aria-selected", "false" ); 13042 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13043 13044 this.activating = this._delay(function() { 13045 this.option( "active", selectedIndex ); 13046 }, this.delay ); 13047 } 13048 }, 13049 13050 _panelKeydown: function( event ) { 13051 if ( this._handlePageNav( event ) ) { 13052 return; 13053 } 13054 13055 // Ctrl+up moves focus to the current tab 13056 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13057 event.preventDefault(); 13058 this.active.focus(); 13059 } 13060 }, 13061 13062 // Alt+page up/down moves focus to the previous/next tab (and activates) 13063 _handlePageNav: function( event ) { 13064 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13065 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13066 return true; 13067 } 13068 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 13069 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 13070 return true; 13071 } 13072 }, 13073 13074 _findNextTab: function( index, goingForward ) { 13075 var lastTabIndex = this.tabs.length - 1; 13076 13077 function constrain() { 13078 if ( index > lastTabIndex ) { 13079 index = 0; 13080 } 13081 if ( index < 0 ) { 13082 index = lastTabIndex; 13083 } 13084 return index; 13085 } 13086 13087 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 13088 index = goingForward ? index + 1 : index - 1; 13089 } 13090 13091 return index; 13092 }, 13093 13094 _focusNextTab: function( index, goingForward ) { 13095 index = this._findNextTab( index, goingForward ); 13096 this.tabs.eq( index ).focus(); 13097 return index; 13098 }, 13099 13100 _setOption: function( key, value ) { 13101 if ( key === "active" ) { 13102 // _activate() will handle invalid values and update this.options 13103 this._activate( value ); 13104 return; 13105 } 13106 13107 if ( key === "disabled" ) { 13108 // don't use the widget factory's disabled handling 13109 this._setupDisabled( value ); 13110 return; 13111 } 13112 13113 this._super( key, value); 13114 13115 if ( key === "collapsible" ) { 13116 this.element.toggleClass( "ui-tabs-collapsible", value ); 13117 // Setting collapsible: false while collapsed; open first panel 13118 if ( !value && this.options.active === false ) { 13119 this._activate( 0 ); 13120 } 13121 } 13122 13123 if ( key === "event" ) { 13124 this._setupEvents( value ); 13125 } 13126 13127 if ( key === "heightStyle" ) { 13128 this._setupHeightStyle( value ); 13129 } 13130 }, 13131 13132 _sanitizeSelector: function( hash ) { 13133 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 13134 }, 13135 13136 refresh: function() { 13137 var options = this.options, 13138 lis = this.tablist.children( ":has(a[href])" ); 13139 13140 // get disabled tabs from class attribute from HTML 13141 // this will get converted to a boolean if needed in _refresh() 13142 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 13143 return lis.index( tab ); 13144 }); 13145 13146 this._processTabs(); 13147 13148 // was collapsed or no tabs 13149 if ( options.active === false || !this.anchors.length ) { 13150 options.active = false; 13151 this.active = $(); 13152 // was active, but active tab is gone 13153 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 13154 // all remaining tabs are disabled 13155 if ( this.tabs.length === options.disabled.length ) { 13156 options.active = false; 13157 this.active = $(); 13158 // activate previous tab 13159 } else { 13160 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 13161 } 13162 // was active, active tab still exists 13163 } else { 13164 // make sure active index is correct 13165 options.active = this.tabs.index( this.active ); 13166 } 13167 13168 this._refresh(); 13169 }, 13170 13171 _refresh: function() { 13172 this._setupDisabled( this.options.disabled ); 13173 this._setupEvents( this.options.event ); 13174 this._setupHeightStyle( this.options.heightStyle ); 13175 13176 this.tabs.not( this.active ).attr({ 13177 "aria-selected": "false", 13178 "aria-expanded": "false", 13179 tabIndex: -1 13180 }); 13181 this.panels.not( this._getPanelForTab( this.active ) ) 13182 .hide() 13183 .attr({ 13184 "aria-hidden": "true" 13185 }); 13186 13187 // Make sure one tab is in the tab order 13188 if ( !this.active.length ) { 13189 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 13190 } else { 13191 this.active 13192 .addClass( "ui-tabs-active ui-state-active" ) 13193 .attr({ 13194 "aria-selected": "true", 13195 "aria-expanded": "true", 13196 tabIndex: 0 13197 }); 13198 this._getPanelForTab( this.active ) 13199 .show() 13200 .attr({ 13201 "aria-hidden": "false" 13202 }); 13203 } 13204 }, 13205 13206 _processTabs: function() { 13207 var that = this, 13208 prevTabs = this.tabs, 13209 prevAnchors = this.anchors, 13210 prevPanels = this.panels; 13211 13212 this.tablist = this._getList() 13213 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13214 .attr( "role", "tablist" ) 13215 13216 // Prevent users from focusing disabled tabs via click 13217 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { 13218 if ( $( this ).is( ".ui-state-disabled" ) ) { 13219 event.preventDefault(); 13220 } 13221 }) 13222 13223 // support: IE <9 13224 // Preventing the default action in mousedown doesn't prevent IE 13225 // from focusing the element, so if the anchor gets focused, blur. 13226 // We don't have to worry about focusing the previously focused 13227 // element since clicking on a non-focusable element should focus 13228 // the body anyway. 13229 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13230 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13231 this.blur(); 13232 } 13233 }); 13234 13235 this.tabs = this.tablist.find( "> li:has(a[href])" ) 13236 .addClass( "ui-state-default ui-corner-top" ) 13237 .attr({ 13238 role: "tab", 13239 tabIndex: -1 13240 }); 13241 13242 this.anchors = this.tabs.map(function() { 13243 return $( "a", this )[ 0 ]; 13244 }) 13245 .addClass( "ui-tabs-anchor" ) 13246 .attr({ 13247 role: "presentation", 13248 tabIndex: -1 13249 }); 13250 13251 this.panels = $(); 13252 13253 this.anchors.each(function( i, anchor ) { 13254 var selector, panel, panelId, 13255 anchorId = $( anchor ).uniqueId().attr( "id" ), 13256 tab = $( anchor ).closest( "li" ), 13257 originalAriaControls = tab.attr( "aria-controls" ); 13258 13259 // inline tab 13260 if ( that._isLocal( anchor ) ) { 13261 selector = anchor.hash; 13262 panelId = selector.substring( 1 ); 13263 panel = that.element.find( that._sanitizeSelector( selector ) ); 13264 // remote tab 13265 } else { 13266 // If the tab doesn't already have aria-controls, 13267 // generate an id by using a throw-away element 13268 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 13269 selector = "#" + panelId; 13270 panel = that.element.find( selector ); 13271 if ( !panel.length ) { 13272 panel = that._createPanel( panelId ); 13273 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 13274 } 13275 panel.attr( "aria-live", "polite" ); 13276 } 13277 13278 if ( panel.length) { 13279 that.panels = that.panels.add( panel ); 13280 } 13281 if ( originalAriaControls ) { 13282 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 13283 } 13284 tab.attr({ 13285 "aria-controls": panelId, 13286 "aria-labelledby": anchorId 13287 }); 13288 panel.attr( "aria-labelledby", anchorId ); 13289 }); 13290 13291 this.panels 13292 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13293 .attr( "role", "tabpanel" ); 13294 13295 // Avoid memory leaks (#10056) 13296 if ( prevTabs ) { 13297 this._off( prevTabs.not( this.tabs ) ); 13298 this._off( prevAnchors.not( this.anchors ) ); 13299 this._off( prevPanels.not( this.panels ) ); 13300 } 13301 }, 13302 13303 // allow overriding how to find the list for rare usage scenarios (#7715) 13304 _getList: function() { 13305 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 13306 }, 13307 13308 _createPanel: function( id ) { 13309 return $( "<div>" ) 13310 .attr( "id", id ) 13311 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13312 .data( "ui-tabs-destroy", true ); 13313 }, 13314 13315 _setupDisabled: function( disabled ) { 13316 if ( $.isArray( disabled ) ) { 13317 if ( !disabled.length ) { 13318 disabled = false; 13319 } else if ( disabled.length === this.anchors.length ) { 13320 disabled = true; 13321 } 13322 } 13323 13324 // disable tabs 13325 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 13326 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 13327 $( li ) 13328 .addClass( "ui-state-disabled" ) 13329 .attr( "aria-disabled", "true" ); 13330 } else { 13331 $( li ) 13332 .removeClass( "ui-state-disabled" ) 13333 .removeAttr( "aria-disabled" ); 13334 } 13335 } 13336 13337 this.options.disabled = disabled; 13338 }, 13339 13340 _setupEvents: function( event ) { 13341 var events = {}; 13342 if ( event ) { 13343 $.each( event.split(" "), function( index, eventName ) { 13344 events[ eventName ] = "_eventHandler"; 13345 }); 13346 } 13347 13348 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 13349 // Always prevent the default action, even when disabled 13350 this._on( true, this.anchors, { 13351 click: function( event ) { 13352 event.preventDefault(); 13353 } 13354 }); 13355 this._on( this.anchors, events ); 13356 this._on( this.tabs, { keydown: "_tabKeydown" } ); 13357 this._on( this.panels, { keydown: "_panelKeydown" } ); 13358 13359 this._focusable( this.tabs ); 13360 this._hoverable( this.tabs ); 13361 }, 13362 13363 _setupHeightStyle: function( heightStyle ) { 13364 var maxHeight, 13365 parent = this.element.parent(); 13366 13367 if ( heightStyle === "fill" ) { 13368 maxHeight = parent.height(); 13369 maxHeight -= this.element.outerHeight() - this.element.height(); 13370 13371 this.element.siblings( ":visible" ).each(function() { 13372 var elem = $( this ), 13373 position = elem.css( "position" ); 13374 13375 if ( position === "absolute" || position === "fixed" ) { 13376 return; 13377 } 13378 maxHeight -= elem.outerHeight( true ); 13379 }); 13380 13381 this.element.children().not( this.panels ).each(function() { 13382 maxHeight -= $( this ).outerHeight( true ); 13383 }); 13384 13385 this.panels.each(function() { 13386 $( this ).height( Math.max( 0, maxHeight - 13387 $( this ).innerHeight() + $( this ).height() ) ); 13388 }) 13389 .css( "overflow", "auto" ); 13390 } else if ( heightStyle === "auto" ) { 13391 maxHeight = 0; 13392 this.panels.each(function() { 13393 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 13394 }).height( maxHeight ); 13395 } 13396 }, 13397 13398 _eventHandler: function( event ) { 13399 var options = this.options, 13400 active = this.active, 13401 anchor = $( event.currentTarget ), 13402 tab = anchor.closest( "li" ), 13403 clickedIsActive = tab[ 0 ] === active[ 0 ], 13404 collapsing = clickedIsActive && options.collapsible, 13405 toShow = collapsing ? $() : this._getPanelForTab( tab ), 13406 toHide = !active.length ? $() : this._getPanelForTab( active ), 13407 eventData = { 13408 oldTab: active, 13409 oldPanel: toHide, 13410 newTab: collapsing ? $() : tab, 13411 newPanel: toShow 13412 }; 13413 13414 event.preventDefault(); 13415 13416 if ( tab.hasClass( "ui-state-disabled" ) || 13417 // tab is already loading 13418 tab.hasClass( "ui-tabs-loading" ) || 13419 // can't switch durning an animation 13420 this.running || 13421 // click on active header, but not collapsible 13422 ( clickedIsActive && !options.collapsible ) || 13423 // allow canceling activation 13424 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 13425 return; 13426 } 13427 13428 options.active = collapsing ? false : this.tabs.index( tab ); 13429 13430 this.active = clickedIsActive ? $() : tab; 13431 if ( this.xhr ) { 13432 this.xhr.abort(); 13433 } 13434 13435 if ( !toHide.length && !toShow.length ) { 13436 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 13437 } 13438 13439 if ( toShow.length ) { 13440 this.load( this.tabs.index( tab ), event ); 13441 } 13442 this._toggle( event, eventData ); 13443 }, 13444 13445 // handles show/hide for selecting tabs 13446 _toggle: function( event, eventData ) { 13447 var that = this, 13448 toShow = eventData.newPanel, 13449 toHide = eventData.oldPanel; 13450 13451 this.running = true; 13452 13453 function complete() { 13454 that.running = false; 13455 that._trigger( "activate", event, eventData ); 13456 } 13457 13458 function show() { 13459 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 13460 13461 if ( toShow.length && that.options.show ) { 13462 that._show( toShow, that.options.show, complete ); 13463 } else { 13464 toShow.show(); 13465 complete(); 13466 } 13467 } 13468 13469 // start out by hiding, then showing, then completing 13470 if ( toHide.length && this.options.hide ) { 13471 this._hide( toHide, this.options.hide, function() { 13472 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13473 show(); 13474 }); 13475 } else { 13476 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13477 toHide.hide(); 13478 show(); 13479 } 13480 13481 toHide.attr( "aria-hidden", "true" ); 13482 eventData.oldTab.attr({ 13483 "aria-selected": "false", 13484 "aria-expanded": "false" 13485 }); 13486 // If we're switching tabs, remove the old tab from the tab order. 13487 // If we're opening from collapsed state, remove the previous tab from the tab order. 13488 // If we're collapsing, then keep the collapsing tab in the tab order. 13489 if ( toShow.length && toHide.length ) { 13490 eventData.oldTab.attr( "tabIndex", -1 ); 13491 } else if ( toShow.length ) { 13492 this.tabs.filter(function() { 13493 return $( this ).attr( "tabIndex" ) === 0; 13494 }) 13495 .attr( "tabIndex", -1 ); 13496 } 13497 13498 toShow.attr( "aria-hidden", "false" ); 13499 eventData.newTab.attr({ 13500 "aria-selected": "true", 13501 "aria-expanded": "true", 13502 tabIndex: 0 13503 }); 13504 }, 13505 13506 _activate: function( index ) { 13507 var anchor, 13508 active = this._findActive( index ); 13509 13510 // trying to activate the already active panel 13511 if ( active[ 0 ] === this.active[ 0 ] ) { 13512 return; 13513 } 13514 13515 // trying to collapse, simulate a click on the current active header 13516 if ( !active.length ) { 13517 active = this.active; 13518 } 13519 13520 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 13521 this._eventHandler({ 13522 target: anchor, 13523 currentTarget: anchor, 13524 preventDefault: $.noop 13525 }); 13526 }, 13527 13528 _findActive: function( index ) { 13529 return index === false ? $() : this.tabs.eq( index ); 13530 }, 13531 13532 _getIndex: function( index ) { 13533 // meta-function to give users option to provide a href string instead of a numerical index. 13534 if ( typeof index === "string" ) { 13535 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 13536 } 13537 13538 return index; 13539 }, 13540 13541 _destroy: function() { 13542 if ( this.xhr ) { 13543 this.xhr.abort(); 13544 } 13545 13546 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 13547 13548 this.tablist 13549 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13550 .removeAttr( "role" ); 13551 13552 this.anchors 13553 .removeClass( "ui-tabs-anchor" ) 13554 .removeAttr( "role" ) 13555 .removeAttr( "tabIndex" ) 13556 .removeUniqueId(); 13557 13558 this.tablist.unbind( this.eventNamespace ); 13559 13560 this.tabs.add( this.panels ).each(function() { 13561 if ( $.data( this, "ui-tabs-destroy" ) ) { 13562 $( this ).remove(); 13563 } else { 13564 $( this ) 13565 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 13566 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 13567 .removeAttr( "tabIndex" ) 13568 .removeAttr( "aria-live" ) 13569 .removeAttr( "aria-busy" ) 13570 .removeAttr( "aria-selected" ) 13571 .removeAttr( "aria-labelledby" ) 13572 .removeAttr( "aria-hidden" ) 13573 .removeAttr( "aria-expanded" ) 13574 .removeAttr( "role" ); 13575 } 13576 }); 13577 13578 this.tabs.each(function() { 13579 var li = $( this ), 13580 prev = li.data( "ui-tabs-aria-controls" ); 13581 if ( prev ) { 13582 li 13583 .attr( "aria-controls", prev ) 13584 .removeData( "ui-tabs-aria-controls" ); 13585 } else { 13586 li.removeAttr( "aria-controls" ); 13587 } 13588 }); 13589 13590 this.panels.show(); 13591 13592 if ( this.options.heightStyle !== "content" ) { 13593 this.panels.css( "height", "" ); 13594 } 13595 }, 13596 13597 enable: function( index ) { 13598 var disabled = this.options.disabled; 13599 if ( disabled === false ) { 13600 return; 13601 } 13602 13603 if ( index === undefined ) { 13604 disabled = false; 13605 } else { 13606 index = this._getIndex( index ); 13607 if ( $.isArray( disabled ) ) { 13608 disabled = $.map( disabled, function( num ) { 13609 return num !== index ? num : null; 13610 }); 13611 } else { 13612 disabled = $.map( this.tabs, function( li, num ) { 13613 return num !== index ? num : null; 13614 }); 13615 } 13616 } 13617 this._setupDisabled( disabled ); 13618 }, 13619 13620 disable: function( index ) { 13621 var disabled = this.options.disabled; 13622 if ( disabled === true ) { 13623 return; 13624 } 13625 13626 if ( index === undefined ) { 13627 disabled = true; 13628 } else { 13629 index = this._getIndex( index ); 13630 if ( $.inArray( index, disabled ) !== -1 ) { 13631 return; 13632 } 13633 if ( $.isArray( disabled ) ) { 13634 disabled = $.merge( [ index ], disabled ).sort(); 13635 } else { 13636 disabled = [ index ]; 13637 } 13638 } 13639 this._setupDisabled( disabled ); 13640 }, 13641 13642 load: function( index, event ) { 13643 index = this._getIndex( index ); 13644 var that = this, 13645 tab = this.tabs.eq( index ), 13646 anchor = tab.find( ".ui-tabs-anchor" ), 13647 panel = this._getPanelForTab( tab ), 13648 eventData = { 13649 tab: tab, 13650 panel: panel 13651 }; 13652 13653 // not remote 13654 if ( this._isLocal( anchor[ 0 ] ) ) { 13655 return; 13656 } 13657 13658 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 13659 13660 // support: jQuery <1.8 13661 // jQuery <1.8 returns false if the request is canceled in beforeSend, 13662 // but as of 1.8, $.ajax() always returns a jqXHR object. 13663 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 13664 tab.addClass( "ui-tabs-loading" ); 13665 panel.attr( "aria-busy", "true" ); 13666 13667 this.xhr 13668 .success(function( response ) { 13669 // support: jQuery <1.8 13670 // http://bugs.jquery.com/ticket/11778 13671 setTimeout(function() { 13672 panel.html( response ); 13673 that._trigger( "load", event, eventData ); 13674 }, 1 ); 13675 }) 13676 .complete(function( jqXHR, status ) { 13677 // support: jQuery <1.8 13678 // http://bugs.jquery.com/ticket/11778 13679 setTimeout(function() { 13680 if ( status === "abort" ) { 13681 that.panels.stop( false, true ); 13682 } 13683 13684 tab.removeClass( "ui-tabs-loading" ); 13685 panel.removeAttr( "aria-busy" ); 13686 13687 if ( jqXHR === that.xhr ) { 13688 delete that.xhr; 13689 } 13690 }, 1 ); 13691 }); 13692 } 13693 }, 13694 13695 _ajaxSettings: function( anchor, event, eventData ) { 13696 var that = this; 13697 return { 13698 url: anchor.attr( "href" ), 13699 beforeSend: function( jqXHR, settings ) { 13700 return that._trigger( "beforeLoad", event, 13701 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 13702 } 13703 }; 13704 }, 13705 13706 _getPanelForTab: function( tab ) { 13707 var id = $( tab ).attr( "aria-controls" ); 13708 return this.element.find( this._sanitizeSelector( "#" + id ) ); 13709 } 13710}); 13711 13712 13713/*! 13714 * jQuery UI Effects 1.11.2 13715 * http://jqueryui.com 13716 * 13717 * Copyright 2014 jQuery Foundation and other contributors 13718 * Released under the MIT license. 13719 * http://jquery.org/license 13720 * 13721 * http://api.jqueryui.com/category/effects-core/ 13722 */ 13723 13724 13725var dataSpace = "ui-effects-", 13726 13727 // Create a local jQuery because jQuery Color relies on it and the 13728 // global may not exist with AMD and a custom build (#10199) 13729 jQuery = $; 13730 13731$.effects = { 13732 effect: {} 13733}; 13734 13735/*! 13736 * jQuery Color Animations v2.1.2 13737 * https://github.com/jquery/jquery-color 13738 * 13739 * Copyright 2014 jQuery Foundation and other contributors 13740 * Released under the MIT license. 13741 * http://jquery.org/license 13742 * 13743 * Date: Wed Jan 16 08:47:09 2013 -0600 13744 */ 13745(function( jQuery, undefined ) { 13746 13747 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 13748 13749 // plusequals test for += 100 -= 100 13750 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 13751 // a set of RE's that can match strings and generate color tuples. 13752 stringParsers = [ { 13753 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13754 parse: function( execResult ) { 13755 return [ 13756 execResult[ 1 ], 13757 execResult[ 2 ], 13758 execResult[ 3 ], 13759 execResult[ 4 ] 13760 ]; 13761 } 13762 }, { 13763 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13764 parse: function( execResult ) { 13765 return [ 13766 execResult[ 1 ] * 2.55, 13767 execResult[ 2 ] * 2.55, 13768 execResult[ 3 ] * 2.55, 13769 execResult[ 4 ] 13770 ]; 13771 } 13772 }, { 13773 // this regex ignores A-F because it's compared against an already lowercased string 13774 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 13775 parse: function( execResult ) { 13776 return [ 13777 parseInt( execResult[ 1 ], 16 ), 13778 parseInt( execResult[ 2 ], 16 ), 13779 parseInt( execResult[ 3 ], 16 ) 13780 ]; 13781 } 13782 }, { 13783 // this regex ignores A-F because it's compared against an already lowercased string 13784 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 13785 parse: function( execResult ) { 13786 return [ 13787 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 13788 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 13789 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 13790 ]; 13791 } 13792 }, { 13793 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13794 space: "hsla", 13795 parse: function( execResult ) { 13796 return [ 13797 execResult[ 1 ], 13798 execResult[ 2 ] / 100, 13799 execResult[ 3 ] / 100, 13800 execResult[ 4 ] 13801 ]; 13802 } 13803 } ], 13804 13805 // jQuery.Color( ) 13806 color = jQuery.Color = function( color, green, blue, alpha ) { 13807 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 13808 }, 13809 spaces = { 13810 rgba: { 13811 props: { 13812 red: { 13813 idx: 0, 13814 type: "byte" 13815 }, 13816 green: { 13817 idx: 1, 13818 type: "byte" 13819 }, 13820 blue: { 13821 idx: 2, 13822 type: "byte" 13823 } 13824 } 13825 }, 13826 13827 hsla: { 13828 props: { 13829 hue: { 13830 idx: 0, 13831 type: "degrees" 13832 }, 13833 saturation: { 13834 idx: 1, 13835 type: "percent" 13836 }, 13837 lightness: { 13838 idx: 2, 13839 type: "percent" 13840 } 13841 } 13842 } 13843 }, 13844 propTypes = { 13845 "byte": { 13846 floor: true, 13847 max: 255 13848 }, 13849 "percent": { 13850 max: 1 13851 }, 13852 "degrees": { 13853 mod: 360, 13854 floor: true 13855 } 13856 }, 13857 support = color.support = {}, 13858 13859 // element for support tests 13860 supportElem = jQuery( "<p>" )[ 0 ], 13861 13862 // colors = jQuery.Color.names 13863 colors, 13864 13865 // local aliases of functions called often 13866 each = jQuery.each; 13867 13868// determine rgba support immediately 13869supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 13870support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 13871 13872// define cache name and alpha properties 13873// for rgba and hsla spaces 13874each( spaces, function( spaceName, space ) { 13875 space.cache = "_" + spaceName; 13876 space.props.alpha = { 13877 idx: 3, 13878 type: "percent", 13879 def: 1 13880 }; 13881}); 13882 13883function clamp( value, prop, allowEmpty ) { 13884 var type = propTypes[ prop.type ] || {}; 13885 13886 if ( value == null ) { 13887 return (allowEmpty || !prop.def) ? null : prop.def; 13888 } 13889 13890 // ~~ is an short way of doing floor for positive numbers 13891 value = type.floor ? ~~value : parseFloat( value ); 13892 13893 // IE will pass in empty strings as value for alpha, 13894 // which will hit this case 13895 if ( isNaN( value ) ) { 13896 return prop.def; 13897 } 13898 13899 if ( type.mod ) { 13900 // we add mod before modding to make sure that negatives values 13901 // get converted properly: -10 -> 350 13902 return (value + type.mod) % type.mod; 13903 } 13904 13905 // for now all property types without mod have min and max 13906 return 0 > value ? 0 : type.max < value ? type.max : value; 13907} 13908 13909function stringParse( string ) { 13910 var inst = color(), 13911 rgba = inst._rgba = []; 13912 13913 string = string.toLowerCase(); 13914 13915 each( stringParsers, function( i, parser ) { 13916 var parsed, 13917 match = parser.re.exec( string ), 13918 values = match && parser.parse( match ), 13919 spaceName = parser.space || "rgba"; 13920 13921 if ( values ) { 13922 parsed = inst[ spaceName ]( values ); 13923 13924 // if this was an rgba parse the assignment might happen twice 13925 // oh well.... 13926 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 13927 rgba = inst._rgba = parsed._rgba; 13928 13929 // exit each( stringParsers ) here because we matched 13930 return false; 13931 } 13932 }); 13933 13934 // Found a stringParser that handled it 13935 if ( rgba.length ) { 13936 13937 // if this came from a parsed string, force "transparent" when alpha is 0 13938 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 13939 if ( rgba.join() === "0,0,0,0" ) { 13940 jQuery.extend( rgba, colors.transparent ); 13941 } 13942 return inst; 13943 } 13944 13945 // named colors 13946 return colors[ string ]; 13947} 13948 13949color.fn = jQuery.extend( color.prototype, { 13950 parse: function( red, green, blue, alpha ) { 13951 if ( red === undefined ) { 13952 this._rgba = [ null, null, null, null ]; 13953 return this; 13954 } 13955 if ( red.jquery || red.nodeType ) { 13956 red = jQuery( red ).css( green ); 13957 green = undefined; 13958 } 13959 13960 var inst = this, 13961 type = jQuery.type( red ), 13962 rgba = this._rgba = []; 13963 13964 // more than 1 argument specified - assume ( red, green, blue, alpha ) 13965 if ( green !== undefined ) { 13966 red = [ red, green, blue, alpha ]; 13967 type = "array"; 13968 } 13969 13970 if ( type === "string" ) { 13971 return this.parse( stringParse( red ) || colors._default ); 13972 } 13973 13974 if ( type === "array" ) { 13975 each( spaces.rgba.props, function( key, prop ) { 13976 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 13977 }); 13978 return this; 13979 } 13980 13981 if ( type === "object" ) { 13982 if ( red instanceof color ) { 13983 each( spaces, function( spaceName, space ) { 13984 if ( red[ space.cache ] ) { 13985 inst[ space.cache ] = red[ space.cache ].slice(); 13986 } 13987 }); 13988 } else { 13989 each( spaces, function( spaceName, space ) { 13990 var cache = space.cache; 13991 each( space.props, function( key, prop ) { 13992 13993 // if the cache doesn't exist, and we know how to convert 13994 if ( !inst[ cache ] && space.to ) { 13995 13996 // if the value was null, we don't need to copy it 13997 // if the key was alpha, we don't need to copy it either 13998 if ( key === "alpha" || red[ key ] == null ) { 13999 return; 14000 } 14001 inst[ cache ] = space.to( inst._rgba ); 14002 } 14003 14004 // this is the only case where we allow nulls for ALL properties. 14005 // call clamp with alwaysAllowEmpty 14006 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 14007 }); 14008 14009 // everything defined but alpha? 14010 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 14011 // use the default of 1 14012 inst[ cache ][ 3 ] = 1; 14013 if ( space.from ) { 14014 inst._rgba = space.from( inst[ cache ] ); 14015 } 14016 } 14017 }); 14018 } 14019 return this; 14020 } 14021 }, 14022 is: function( compare ) { 14023 var is = color( compare ), 14024 same = true, 14025 inst = this; 14026 14027 each( spaces, function( _, space ) { 14028 var localCache, 14029 isCache = is[ space.cache ]; 14030 if (isCache) { 14031 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 14032 each( space.props, function( _, prop ) { 14033 if ( isCache[ prop.idx ] != null ) { 14034 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 14035 return same; 14036 } 14037 }); 14038 } 14039 return same; 14040 }); 14041 return same; 14042 }, 14043 _space: function() { 14044 var used = [], 14045 inst = this; 14046 each( spaces, function( spaceName, space ) { 14047 if ( inst[ space.cache ] ) { 14048 used.push( spaceName ); 14049 } 14050 }); 14051 return used.pop(); 14052 }, 14053 transition: function( other, distance ) { 14054 var end = color( other ), 14055 spaceName = end._space(), 14056 space = spaces[ spaceName ], 14057 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 14058 start = startColor[ space.cache ] || space.to( startColor._rgba ), 14059 result = start.slice(); 14060 14061 end = end[ space.cache ]; 14062 each( space.props, function( key, prop ) { 14063 var index = prop.idx, 14064 startValue = start[ index ], 14065 endValue = end[ index ], 14066 type = propTypes[ prop.type ] || {}; 14067 14068 // if null, don't override start value 14069 if ( endValue === null ) { 14070 return; 14071 } 14072 // if null - use end 14073 if ( startValue === null ) { 14074 result[ index ] = endValue; 14075 } else { 14076 if ( type.mod ) { 14077 if ( endValue - startValue > type.mod / 2 ) { 14078 startValue += type.mod; 14079 } else if ( startValue - endValue > type.mod / 2 ) { 14080 startValue -= type.mod; 14081 } 14082 } 14083 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 14084 } 14085 }); 14086 return this[ spaceName ]( result ); 14087 }, 14088 blend: function( opaque ) { 14089 // if we are already opaque - return ourself 14090 if ( this._rgba[ 3 ] === 1 ) { 14091 return this; 14092 } 14093 14094 var rgb = this._rgba.slice(), 14095 a = rgb.pop(), 14096 blend = color( opaque )._rgba; 14097 14098 return color( jQuery.map( rgb, function( v, i ) { 14099 return ( 1 - a ) * blend[ i ] + a * v; 14100 })); 14101 }, 14102 toRgbaString: function() { 14103 var prefix = "rgba(", 14104 rgba = jQuery.map( this._rgba, function( v, i ) { 14105 return v == null ? ( i > 2 ? 1 : 0 ) : v; 14106 }); 14107 14108 if ( rgba[ 3 ] === 1 ) { 14109 rgba.pop(); 14110 prefix = "rgb("; 14111 } 14112 14113 return prefix + rgba.join() + ")"; 14114 }, 14115 toHslaString: function() { 14116 var prefix = "hsla(", 14117 hsla = jQuery.map( this.hsla(), function( v, i ) { 14118 if ( v == null ) { 14119 v = i > 2 ? 1 : 0; 14120 } 14121 14122 // catch 1 and 2 14123 if ( i && i < 3 ) { 14124 v = Math.round( v * 100 ) + "%"; 14125 } 14126 return v; 14127 }); 14128 14129 if ( hsla[ 3 ] === 1 ) { 14130 hsla.pop(); 14131 prefix = "hsl("; 14132 } 14133 return prefix + hsla.join() + ")"; 14134 }, 14135 toHexString: function( includeAlpha ) { 14136 var rgba = this._rgba.slice(), 14137 alpha = rgba.pop(); 14138 14139 if ( includeAlpha ) { 14140 rgba.push( ~~( alpha * 255 ) ); 14141 } 14142 14143 return "#" + jQuery.map( rgba, function( v ) { 14144 14145 // default to 0 when nulls exist 14146 v = ( v || 0 ).toString( 16 ); 14147 return v.length === 1 ? "0" + v : v; 14148 }).join(""); 14149 }, 14150 toString: function() { 14151 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 14152 } 14153}); 14154color.fn.parse.prototype = color.fn; 14155 14156// hsla conversions adapted from: 14157// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 14158 14159function hue2rgb( p, q, h ) { 14160 h = ( h + 1 ) % 1; 14161 if ( h * 6 < 1 ) { 14162 return p + ( q - p ) * h * 6; 14163 } 14164 if ( h * 2 < 1) { 14165 return q; 14166 } 14167 if ( h * 3 < 2 ) { 14168 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 14169 } 14170 return p; 14171} 14172 14173spaces.hsla.to = function( rgba ) { 14174 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 14175 return [ null, null, null, rgba[ 3 ] ]; 14176 } 14177 var r = rgba[ 0 ] / 255, 14178 g = rgba[ 1 ] / 255, 14179 b = rgba[ 2 ] / 255, 14180 a = rgba[ 3 ], 14181 max = Math.max( r, g, b ), 14182 min = Math.min( r, g, b ), 14183 diff = max - min, 14184 add = max + min, 14185 l = add * 0.5, 14186 h, s; 14187 14188 if ( min === max ) { 14189 h = 0; 14190 } else if ( r === max ) { 14191 h = ( 60 * ( g - b ) / diff ) + 360; 14192 } else if ( g === max ) { 14193 h = ( 60 * ( b - r ) / diff ) + 120; 14194 } else { 14195 h = ( 60 * ( r - g ) / diff ) + 240; 14196 } 14197 14198 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 14199 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 14200 if ( diff === 0 ) { 14201 s = 0; 14202 } else if ( l <= 0.5 ) { 14203 s = diff / add; 14204 } else { 14205 s = diff / ( 2 - add ); 14206 } 14207 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 14208}; 14209 14210spaces.hsla.from = function( hsla ) { 14211 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 14212 return [ null, null, null, hsla[ 3 ] ]; 14213 } 14214 var h = hsla[ 0 ] / 360, 14215 s = hsla[ 1 ], 14216 l = hsla[ 2 ], 14217 a = hsla[ 3 ], 14218 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 14219 p = 2 * l - q; 14220 14221 return [ 14222 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 14223 Math.round( hue2rgb( p, q, h ) * 255 ), 14224 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 14225 a 14226 ]; 14227}; 14228 14229each( spaces, function( spaceName, space ) { 14230 var props = space.props, 14231 cache = space.cache, 14232 to = space.to, 14233 from = space.from; 14234 14235 // makes rgba() and hsla() 14236 color.fn[ spaceName ] = function( value ) { 14237 14238 // generate a cache for this space if it doesn't exist 14239 if ( to && !this[ cache ] ) { 14240 this[ cache ] = to( this._rgba ); 14241 } 14242 if ( value === undefined ) { 14243 return this[ cache ].slice(); 14244 } 14245 14246 var ret, 14247 type = jQuery.type( value ), 14248 arr = ( type === "array" || type === "object" ) ? value : arguments, 14249 local = this[ cache ].slice(); 14250 14251 each( props, function( key, prop ) { 14252 var val = arr[ type === "object" ? key : prop.idx ]; 14253 if ( val == null ) { 14254 val = local[ prop.idx ]; 14255 } 14256 local[ prop.idx ] = clamp( val, prop ); 14257 }); 14258 14259 if ( from ) { 14260 ret = color( from( local ) ); 14261 ret[ cache ] = local; 14262 return ret; 14263 } else { 14264 return color( local ); 14265 } 14266 }; 14267 14268 // makes red() green() blue() alpha() hue() saturation() lightness() 14269 each( props, function( key, prop ) { 14270 // alpha is included in more than one space 14271 if ( color.fn[ key ] ) { 14272 return; 14273 } 14274 color.fn[ key ] = function( value ) { 14275 var vtype = jQuery.type( value ), 14276 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 14277 local = this[ fn ](), 14278 cur = local[ prop.idx ], 14279 match; 14280 14281 if ( vtype === "undefined" ) { 14282 return cur; 14283 } 14284 14285 if ( vtype === "function" ) { 14286 value = value.call( this, cur ); 14287 vtype = jQuery.type( value ); 14288 } 14289 if ( value == null && prop.empty ) { 14290 return this; 14291 } 14292 if ( vtype === "string" ) { 14293 match = rplusequals.exec( value ); 14294 if ( match ) { 14295 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 14296 } 14297 } 14298 local[ prop.idx ] = value; 14299 return this[ fn ]( local ); 14300 }; 14301 }); 14302}); 14303 14304// add cssHook and .fx.step function for each named hook. 14305// accept a space separated string of properties 14306color.hook = function( hook ) { 14307 var hooks = hook.split( " " ); 14308 each( hooks, function( i, hook ) { 14309 jQuery.cssHooks[ hook ] = { 14310 set: function( elem, value ) { 14311 var parsed, curElem, 14312 backgroundColor = ""; 14313 14314 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 14315 value = color( parsed || value ); 14316 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 14317 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 14318 while ( 14319 (backgroundColor === "" || backgroundColor === "transparent") && 14320 curElem && curElem.style 14321 ) { 14322 try { 14323 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 14324 curElem = curElem.parentNode; 14325 } catch ( e ) { 14326 } 14327 } 14328 14329 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 14330 backgroundColor : 14331 "_default" ); 14332 } 14333 14334 value = value.toRgbaString(); 14335 } 14336 try { 14337 elem.style[ hook ] = value; 14338 } catch ( e ) { 14339 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 14340 } 14341 } 14342 }; 14343 jQuery.fx.step[ hook ] = function( fx ) { 14344 if ( !fx.colorInit ) { 14345 fx.start = color( fx.elem, hook ); 14346 fx.end = color( fx.end ); 14347 fx.colorInit = true; 14348 } 14349 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 14350 }; 14351 }); 14352 14353}; 14354 14355color.hook( stepHooks ); 14356 14357jQuery.cssHooks.borderColor = { 14358 expand: function( value ) { 14359 var expanded = {}; 14360 14361 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 14362 expanded[ "border" + part + "Color" ] = value; 14363 }); 14364 return expanded; 14365 } 14366}; 14367 14368// Basic color names only. 14369// Usage of any of the other color names requires adding yourself or including 14370// jquery.color.svg-names.js. 14371colors = jQuery.Color.names = { 14372 // 4.1. Basic color keywords 14373 aqua: "#00ffff", 14374 black: "#000000", 14375 blue: "#0000ff", 14376 fuchsia: "#ff00ff", 14377 gray: "#808080", 14378 green: "#008000", 14379 lime: "#00ff00", 14380 maroon: "#800000", 14381 navy: "#000080", 14382 olive: "#808000", 14383 purple: "#800080", 14384 red: "#ff0000", 14385 silver: "#c0c0c0", 14386 teal: "#008080", 14387 white: "#ffffff", 14388 yellow: "#ffff00", 14389 14390 // 4.2.3. "transparent" color keyword 14391 transparent: [ null, null, null, 0 ], 14392 14393 _default: "#ffffff" 14394}; 14395 14396})( jQuery ); 14397 14398/******************************************************************************/ 14399/****************************** CLASS ANIMATIONS ******************************/ 14400/******************************************************************************/ 14401(function() { 14402 14403var classAnimationActions = [ "add", "remove", "toggle" ], 14404 shorthandStyles = { 14405 border: 1, 14406 borderBottom: 1, 14407 borderColor: 1, 14408 borderLeft: 1, 14409 borderRight: 1, 14410 borderTop: 1, 14411 borderWidth: 1, 14412 margin: 1, 14413 padding: 1 14414 }; 14415 14416$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 14417 $.fx.step[ prop ] = function( fx ) { 14418 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 14419 jQuery.style( fx.elem, prop, fx.end ); 14420 fx.setAttr = true; 14421 } 14422 }; 14423}); 14424 14425function getElementStyles( elem ) { 14426 var key, len, 14427 style = elem.ownerDocument.defaultView ? 14428 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 14429 elem.currentStyle, 14430 styles = {}; 14431 14432 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 14433 len = style.length; 14434 while ( len-- ) { 14435 key = style[ len ]; 14436 if ( typeof style[ key ] === "string" ) { 14437 styles[ $.camelCase( key ) ] = style[ key ]; 14438 } 14439 } 14440 // support: Opera, IE <9 14441 } else { 14442 for ( key in style ) { 14443 if ( typeof style[ key ] === "string" ) { 14444 styles[ key ] = style[ key ]; 14445 } 14446 } 14447 } 14448 14449 return styles; 14450} 14451 14452function styleDifference( oldStyle, newStyle ) { 14453 var diff = {}, 14454 name, value; 14455 14456 for ( name in newStyle ) { 14457 value = newStyle[ name ]; 14458 if ( oldStyle[ name ] !== value ) { 14459 if ( !shorthandStyles[ name ] ) { 14460 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 14461 diff[ name ] = value; 14462 } 14463 } 14464 } 14465 } 14466 14467 return diff; 14468} 14469 14470// support: jQuery <1.8 14471if ( !$.fn.addBack ) { 14472 $.fn.addBack = function( selector ) { 14473 return this.add( selector == null ? 14474 this.prevObject : this.prevObject.filter( selector ) 14475 ); 14476 }; 14477} 14478 14479$.effects.animateClass = function( value, duration, easing, callback ) { 14480 var o = $.speed( duration, easing, callback ); 14481 14482 return this.queue( function() { 14483 var animated = $( this ), 14484 baseClass = animated.attr( "class" ) || "", 14485 applyClassChange, 14486 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 14487 14488 // map the animated objects to store the original styles. 14489 allAnimations = allAnimations.map(function() { 14490 var el = $( this ); 14491 return { 14492 el: el, 14493 start: getElementStyles( this ) 14494 }; 14495 }); 14496 14497 // apply class change 14498 applyClassChange = function() { 14499 $.each( classAnimationActions, function(i, action) { 14500 if ( value[ action ] ) { 14501 animated[ action + "Class" ]( value[ action ] ); 14502 } 14503 }); 14504 }; 14505 applyClassChange(); 14506 14507 // map all animated objects again - calculate new styles and diff 14508 allAnimations = allAnimations.map(function() { 14509 this.end = getElementStyles( this.el[ 0 ] ); 14510 this.diff = styleDifference( this.start, this.end ); 14511 return this; 14512 }); 14513 14514 // apply original class 14515 animated.attr( "class", baseClass ); 14516 14517 // map all animated objects again - this time collecting a promise 14518 allAnimations = allAnimations.map(function() { 14519 var styleInfo = this, 14520 dfd = $.Deferred(), 14521 opts = $.extend({}, o, { 14522 queue: false, 14523 complete: function() { 14524 dfd.resolve( styleInfo ); 14525 } 14526 }); 14527 14528 this.el.animate( this.diff, opts ); 14529 return dfd.promise(); 14530 }); 14531 14532 // once all animations have completed: 14533 $.when.apply( $, allAnimations.get() ).done(function() { 14534 14535 // set the final class 14536 applyClassChange(); 14537 14538 // for each animated element, 14539 // clear all css properties that were animated 14540 $.each( arguments, function() { 14541 var el = this.el; 14542 $.each( this.diff, function(key) { 14543 el.css( key, "" ); 14544 }); 14545 }); 14546 14547 // this is guarnteed to be there if you use jQuery.speed() 14548 // it also handles dequeuing the next anim... 14549 o.complete.call( animated[ 0 ] ); 14550 }); 14551 }); 14552}; 14553 14554$.fn.extend({ 14555 addClass: (function( orig ) { 14556 return function( classNames, speed, easing, callback ) { 14557 return speed ? 14558 $.effects.animateClass.call( this, 14559 { add: classNames }, speed, easing, callback ) : 14560 orig.apply( this, arguments ); 14561 }; 14562 })( $.fn.addClass ), 14563 14564 removeClass: (function( orig ) { 14565 return function( classNames, speed, easing, callback ) { 14566 return arguments.length > 1 ? 14567 $.effects.animateClass.call( this, 14568 { remove: classNames }, speed, easing, callback ) : 14569 orig.apply( this, arguments ); 14570 }; 14571 })( $.fn.removeClass ), 14572 14573 toggleClass: (function( orig ) { 14574 return function( classNames, force, speed, easing, callback ) { 14575 if ( typeof force === "boolean" || force === undefined ) { 14576 if ( !speed ) { 14577 // without speed parameter 14578 return orig.apply( this, arguments ); 14579 } else { 14580 return $.effects.animateClass.call( this, 14581 (force ? { add: classNames } : { remove: classNames }), 14582 speed, easing, callback ); 14583 } 14584 } else { 14585 // without force parameter 14586 return $.effects.animateClass.call( this, 14587 { toggle: classNames }, force, speed, easing ); 14588 } 14589 }; 14590 })( $.fn.toggleClass ), 14591 14592 switchClass: function( remove, add, speed, easing, callback) { 14593 return $.effects.animateClass.call( this, { 14594 add: add, 14595 remove: remove 14596 }, speed, easing, callback ); 14597 } 14598}); 14599 14600})(); 14601 14602/******************************************************************************/ 14603/*********************************** EFFECTS **********************************/ 14604/******************************************************************************/ 14605 14606(function() { 14607 14608$.extend( $.effects, { 14609 version: "1.11.2", 14610 14611 // Saves a set of properties in a data storage 14612 save: function( element, set ) { 14613 for ( var i = 0; i < set.length; i++ ) { 14614 if ( set[ i ] !== null ) { 14615 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 14616 } 14617 } 14618 }, 14619 14620 // Restores a set of previously saved properties from a data storage 14621 restore: function( element, set ) { 14622 var val, i; 14623 for ( i = 0; i < set.length; i++ ) { 14624 if ( set[ i ] !== null ) { 14625 val = element.data( dataSpace + set[ i ] ); 14626 // support: jQuery 1.6.2 14627 // http://bugs.jquery.com/ticket/9917 14628 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 14629 // We can't differentiate between "" and 0 here, so we just assume 14630 // empty string since it's likely to be a more common value... 14631 if ( val === undefined ) { 14632 val = ""; 14633 } 14634 element.css( set[ i ], val ); 14635 } 14636 } 14637 }, 14638 14639 setMode: function( el, mode ) { 14640 if (mode === "toggle") { 14641 mode = el.is( ":hidden" ) ? "show" : "hide"; 14642 } 14643 return mode; 14644 }, 14645 14646 // Translates a [top,left] array into a baseline value 14647 // this should be a little more flexible in the future to handle a string & hash 14648 getBaseline: function( origin, original ) { 14649 var y, x; 14650 switch ( origin[ 0 ] ) { 14651 case "top": y = 0; break; 14652 case "middle": y = 0.5; break; 14653 case "bottom": y = 1; break; 14654 default: y = origin[ 0 ] / original.height; 14655 } 14656 switch ( origin[ 1 ] ) { 14657 case "left": x = 0; break; 14658 case "center": x = 0.5; break; 14659 case "right": x = 1; break; 14660 default: x = origin[ 1 ] / original.width; 14661 } 14662 return { 14663 x: x, 14664 y: y 14665 }; 14666 }, 14667 14668 // Wraps the element around a wrapper that copies position properties 14669 createWrapper: function( element ) { 14670 14671 // if the element is already wrapped, return it 14672 if ( element.parent().is( ".ui-effects-wrapper" )) { 14673 return element.parent(); 14674 } 14675 14676 // wrap the element 14677 var props = { 14678 width: element.outerWidth(true), 14679 height: element.outerHeight(true), 14680 "float": element.css( "float" ) 14681 }, 14682 wrapper = $( "<div></div>" ) 14683 .addClass( "ui-effects-wrapper" ) 14684 .css({ 14685 fontSize: "100%", 14686 background: "transparent", 14687 border: "none", 14688 margin: 0, 14689 padding: 0 14690 }), 14691 // Store the size in case width/height are defined in % - Fixes #5245 14692 size = { 14693 width: element.width(), 14694 height: element.height() 14695 }, 14696 active = document.activeElement; 14697 14698 // support: Firefox 14699 // Firefox incorrectly exposes anonymous content 14700 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 14701 try { 14702 active.id; 14703 } catch ( e ) { 14704 active = document.body; 14705 } 14706 14707 element.wrap( wrapper ); 14708 14709 // Fixes #7595 - Elements lose focus when wrapped. 14710 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14711 $( active ).focus(); 14712 } 14713 14714 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 14715 14716 // transfer positioning properties to the wrapper 14717 if ( element.css( "position" ) === "static" ) { 14718 wrapper.css({ position: "relative" }); 14719 element.css({ position: "relative" }); 14720 } else { 14721 $.extend( props, { 14722 position: element.css( "position" ), 14723 zIndex: element.css( "z-index" ) 14724 }); 14725 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 14726 props[ pos ] = element.css( pos ); 14727 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 14728 props[ pos ] = "auto"; 14729 } 14730 }); 14731 element.css({ 14732 position: "relative", 14733 top: 0, 14734 left: 0, 14735 right: "auto", 14736 bottom: "auto" 14737 }); 14738 } 14739 element.css(size); 14740 14741 return wrapper.css( props ).show(); 14742 }, 14743 14744 removeWrapper: function( element ) { 14745 var active = document.activeElement; 14746 14747 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 14748 element.parent().replaceWith( element ); 14749 14750 // Fixes #7595 - Elements lose focus when wrapped. 14751 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14752 $( active ).focus(); 14753 } 14754 } 14755 14756 return element; 14757 }, 14758 14759 setTransition: function( element, list, factor, value ) { 14760 value = value || {}; 14761 $.each( list, function( i, x ) { 14762 var unit = element.cssUnit( x ); 14763 if ( unit[ 0 ] > 0 ) { 14764 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 14765 } 14766 }); 14767 return value; 14768 } 14769}); 14770 14771// return an effect options object for the given parameters: 14772function _normalizeArguments( effect, options, speed, callback ) { 14773 14774 // allow passing all options as the first parameter 14775 if ( $.isPlainObject( effect ) ) { 14776 options = effect; 14777 effect = effect.effect; 14778 } 14779 14780 // convert to an object 14781 effect = { effect: effect }; 14782 14783 // catch (effect, null, ...) 14784 if ( options == null ) { 14785 options = {}; 14786 } 14787 14788 // catch (effect, callback) 14789 if ( $.isFunction( options ) ) { 14790 callback = options; 14791 speed = null; 14792 options = {}; 14793 } 14794 14795 // catch (effect, speed, ?) 14796 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 14797 callback = speed; 14798 speed = options; 14799 options = {}; 14800 } 14801 14802 // catch (effect, options, callback) 14803 if ( $.isFunction( speed ) ) { 14804 callback = speed; 14805 speed = null; 14806 } 14807 14808 // add options to effect 14809 if ( options ) { 14810 $.extend( effect, options ); 14811 } 14812 14813 speed = speed || options.duration; 14814 effect.duration = $.fx.off ? 0 : 14815 typeof speed === "number" ? speed : 14816 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 14817 $.fx.speeds._default; 14818 14819 effect.complete = callback || options.complete; 14820 14821 return effect; 14822} 14823 14824function standardAnimationOption( option ) { 14825 // Valid standard speeds (nothing, number, named speed) 14826 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 14827 return true; 14828 } 14829 14830 // Invalid strings - treat as "normal" speed 14831 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 14832 return true; 14833 } 14834 14835 // Complete callback 14836 if ( $.isFunction( option ) ) { 14837 return true; 14838 } 14839 14840 // Options hash (but not naming an effect) 14841 if ( typeof option === "object" && !option.effect ) { 14842 return true; 14843 } 14844 14845 // Didn't match any standard API 14846 return false; 14847} 14848 14849$.fn.extend({ 14850 effect: function( /* effect, options, speed, callback */ ) { 14851 var args = _normalizeArguments.apply( this, arguments ), 14852 mode = args.mode, 14853 queue = args.queue, 14854 effectMethod = $.effects.effect[ args.effect ]; 14855 14856 if ( $.fx.off || !effectMethod ) { 14857 // delegate to the original method (e.g., .show()) if possible 14858 if ( mode ) { 14859 return this[ mode ]( args.duration, args.complete ); 14860 } else { 14861 return this.each( function() { 14862 if ( args.complete ) { 14863 args.complete.call( this ); 14864 } 14865 }); 14866 } 14867 } 14868 14869 function run( next ) { 14870 var elem = $( this ), 14871 complete = args.complete, 14872 mode = args.mode; 14873 14874 function done() { 14875 if ( $.isFunction( complete ) ) { 14876 complete.call( elem[0] ); 14877 } 14878 if ( $.isFunction( next ) ) { 14879 next(); 14880 } 14881 } 14882 14883 // If the element already has the correct final state, delegate to 14884 // the core methods so the internal tracking of "olddisplay" works. 14885 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 14886 elem[ mode ](); 14887 done(); 14888 } else { 14889 effectMethod.call( elem[0], args, done ); 14890 } 14891 } 14892 14893 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 14894 }, 14895 14896 show: (function( orig ) { 14897 return function( option ) { 14898 if ( standardAnimationOption( option ) ) { 14899 return orig.apply( this, arguments ); 14900 } else { 14901 var args = _normalizeArguments.apply( this, arguments ); 14902 args.mode = "show"; 14903 return this.effect.call( this, args ); 14904 } 14905 }; 14906 })( $.fn.show ), 14907 14908 hide: (function( orig ) { 14909 return function( option ) { 14910 if ( standardAnimationOption( option ) ) { 14911 return orig.apply( this, arguments ); 14912 } else { 14913 var args = _normalizeArguments.apply( this, arguments ); 14914 args.mode = "hide"; 14915 return this.effect.call( this, args ); 14916 } 14917 }; 14918 })( $.fn.hide ), 14919 14920 toggle: (function( orig ) { 14921 return function( option ) { 14922 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 14923 return orig.apply( this, arguments ); 14924 } else { 14925 var args = _normalizeArguments.apply( this, arguments ); 14926 args.mode = "toggle"; 14927 return this.effect.call( this, args ); 14928 } 14929 }; 14930 })( $.fn.toggle ), 14931 14932 // helper functions 14933 cssUnit: function(key) { 14934 var style = this.css( key ), 14935 val = []; 14936 14937 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 14938 if ( style.indexOf( unit ) > 0 ) { 14939 val = [ parseFloat( style ), unit ]; 14940 } 14941 }); 14942 return val; 14943 } 14944}); 14945 14946})(); 14947 14948/******************************************************************************/ 14949/*********************************** EASING ***********************************/ 14950/******************************************************************************/ 14951 14952(function() { 14953 14954// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 14955 14956var baseEasings = {}; 14957 14958$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 14959 baseEasings[ name ] = function( p ) { 14960 return Math.pow( p, i + 2 ); 14961 }; 14962}); 14963 14964$.extend( baseEasings, { 14965 Sine: function( p ) { 14966 return 1 - Math.cos( p * Math.PI / 2 ); 14967 }, 14968 Circ: function( p ) { 14969 return 1 - Math.sqrt( 1 - p * p ); 14970 }, 14971 Elastic: function( p ) { 14972 return p === 0 || p === 1 ? p : 14973 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 14974 }, 14975 Back: function( p ) { 14976 return p * p * ( 3 * p - 2 ); 14977 }, 14978 Bounce: function( p ) { 14979 var pow2, 14980 bounce = 4; 14981 14982 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 14983 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 14984 } 14985}); 14986 14987$.each( baseEasings, function( name, easeIn ) { 14988 $.easing[ "easeIn" + name ] = easeIn; 14989 $.easing[ "easeOut" + name ] = function( p ) { 14990 return 1 - easeIn( 1 - p ); 14991 }; 14992 $.easing[ "easeInOut" + name ] = function( p ) { 14993 return p < 0.5 ? 14994 easeIn( p * 2 ) / 2 : 14995 1 - easeIn( p * -2 + 2 ) / 2; 14996 }; 14997}); 14998 14999})(); 15000 15001var effect = $.effects; 15002 15003 15004/*! 15005 * jQuery UI Effects Blind 1.11.2 15006 * http://jqueryui.com 15007 * 15008 * Copyright 2014 jQuery Foundation and other contributors 15009 * Released under the MIT license. 15010 * http://jquery.org/license 15011 * 15012 * http://api.jqueryui.com/blind-effect/ 15013 */ 15014 15015 15016var effectBlind = $.effects.effect.blind = function( o, done ) { 15017 // Create element 15018 var el = $( this ), 15019 rvertical = /up|down|vertical/, 15020 rpositivemotion = /up|left|vertical|horizontal/, 15021 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15022 mode = $.effects.setMode( el, o.mode || "hide" ), 15023 direction = o.direction || "up", 15024 vertical = rvertical.test( direction ), 15025 ref = vertical ? "height" : "width", 15026 ref2 = vertical ? "top" : "left", 15027 motion = rpositivemotion.test( direction ), 15028 animation = {}, 15029 show = mode === "show", 15030 wrapper, distance, margin; 15031 15032 // if already wrapped, the wrapper's properties are my property. #6245 15033 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 15034 $.effects.save( el.parent(), props ); 15035 } else { 15036 $.effects.save( el, props ); 15037 } 15038 el.show(); 15039 wrapper = $.effects.createWrapper( el ).css({ 15040 overflow: "hidden" 15041 }); 15042 15043 distance = wrapper[ ref ](); 15044 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 15045 15046 animation[ ref ] = show ? distance : 0; 15047 if ( !motion ) { 15048 el 15049 .css( vertical ? "bottom" : "right", 0 ) 15050 .css( vertical ? "top" : "left", "auto" ) 15051 .css({ position: "absolute" }); 15052 15053 animation[ ref2 ] = show ? margin : distance + margin; 15054 } 15055 15056 // start at 0 if we are showing 15057 if ( show ) { 15058 wrapper.css( ref, 0 ); 15059 if ( !motion ) { 15060 wrapper.css( ref2, margin + distance ); 15061 } 15062 } 15063 15064 // Animate 15065 wrapper.animate( animation, { 15066 duration: o.duration, 15067 easing: o.easing, 15068 queue: false, 15069 complete: function() { 15070 if ( mode === "hide" ) { 15071 el.hide(); 15072 } 15073 $.effects.restore( el, props ); 15074 $.effects.removeWrapper( el ); 15075 done(); 15076 } 15077 }); 15078}; 15079 15080 15081/*! 15082 * jQuery UI Effects Bounce 1.11.2 15083 * http://jqueryui.com 15084 * 15085 * Copyright 2014 jQuery Foundation and other contributors 15086 * Released under the MIT license. 15087 * http://jquery.org/license 15088 * 15089 * http://api.jqueryui.com/bounce-effect/ 15090 */ 15091 15092 15093var effectBounce = $.effects.effect.bounce = function( o, done ) { 15094 var el = $( this ), 15095 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15096 15097 // defaults: 15098 mode = $.effects.setMode( el, o.mode || "effect" ), 15099 hide = mode === "hide", 15100 show = mode === "show", 15101 direction = o.direction || "up", 15102 distance = o.distance, 15103 times = o.times || 5, 15104 15105 // number of internal animations 15106 anims = times * 2 + ( show || hide ? 1 : 0 ), 15107 speed = o.duration / anims, 15108 easing = o.easing, 15109 15110 // utility: 15111 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15112 motion = ( direction === "up" || direction === "left" ), 15113 i, 15114 upAnim, 15115 downAnim, 15116 15117 // we will need to re-assemble the queue to stack our animations in place 15118 queue = el.queue(), 15119 queuelen = queue.length; 15120 15121 // Avoid touching opacity to prevent clearType and PNG issues in IE 15122 if ( show || hide ) { 15123 props.push( "opacity" ); 15124 } 15125 15126 $.effects.save( el, props ); 15127 el.show(); 15128 $.effects.createWrapper( el ); // Create Wrapper 15129 15130 // default distance for the BIGGEST bounce is the outer Distance / 3 15131 if ( !distance ) { 15132 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 15133 } 15134 15135 if ( show ) { 15136 downAnim = { opacity: 1 }; 15137 downAnim[ ref ] = 0; 15138 15139 // if we are showing, force opacity 0 and set the initial position 15140 // then do the "first" animation 15141 el.css( "opacity", 0 ) 15142 .css( ref, motion ? -distance * 2 : distance * 2 ) 15143 .animate( downAnim, speed, easing ); 15144 } 15145 15146 // start at the smallest distance if we are hiding 15147 if ( hide ) { 15148 distance = distance / Math.pow( 2, times - 1 ); 15149 } 15150 15151 downAnim = {}; 15152 downAnim[ ref ] = 0; 15153 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 15154 for ( i = 0; i < times; i++ ) { 15155 upAnim = {}; 15156 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15157 15158 el.animate( upAnim, speed, easing ) 15159 .animate( downAnim, speed, easing ); 15160 15161 distance = hide ? distance * 2 : distance / 2; 15162 } 15163 15164 // Last Bounce when Hiding 15165 if ( hide ) { 15166 upAnim = { opacity: 0 }; 15167 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15168 15169 el.animate( upAnim, speed, easing ); 15170 } 15171 15172 el.queue(function() { 15173 if ( hide ) { 15174 el.hide(); 15175 } 15176 $.effects.restore( el, props ); 15177 $.effects.removeWrapper( el ); 15178 done(); 15179 }); 15180 15181 // inject all the animations we just queued to be first in line (after "inprogress") 15182 if ( queuelen > 1) { 15183 queue.splice.apply( queue, 15184 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15185 } 15186 el.dequeue(); 15187 15188}; 15189 15190 15191/*! 15192 * jQuery UI Effects Clip 1.11.2 15193 * http://jqueryui.com 15194 * 15195 * Copyright 2014 jQuery Foundation and other contributors 15196 * Released under the MIT license. 15197 * http://jquery.org/license 15198 * 15199 * http://api.jqueryui.com/clip-effect/ 15200 */ 15201 15202 15203var effectClip = $.effects.effect.clip = function( o, done ) { 15204 // Create element 15205 var el = $( this ), 15206 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15207 mode = $.effects.setMode( el, o.mode || "hide" ), 15208 show = mode === "show", 15209 direction = o.direction || "vertical", 15210 vert = direction === "vertical", 15211 size = vert ? "height" : "width", 15212 position = vert ? "top" : "left", 15213 animation = {}, 15214 wrapper, animate, distance; 15215 15216 // Save & Show 15217 $.effects.save( el, props ); 15218 el.show(); 15219 15220 // Create Wrapper 15221 wrapper = $.effects.createWrapper( el ).css({ 15222 overflow: "hidden" 15223 }); 15224 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 15225 distance = animate[ size ](); 15226 15227 // Shift 15228 if ( show ) { 15229 animate.css( size, 0 ); 15230 animate.css( position, distance / 2 ); 15231 } 15232 15233 // Create Animation Object: 15234 animation[ size ] = show ? distance : 0; 15235 animation[ position ] = show ? 0 : distance / 2; 15236 15237 // Animate 15238 animate.animate( animation, { 15239 queue: false, 15240 duration: o.duration, 15241 easing: o.easing, 15242 complete: function() { 15243 if ( !show ) { 15244 el.hide(); 15245 } 15246 $.effects.restore( el, props ); 15247 $.effects.removeWrapper( el ); 15248 done(); 15249 } 15250 }); 15251 15252}; 15253 15254 15255/*! 15256 * jQuery UI Effects Drop 1.11.2 15257 * http://jqueryui.com 15258 * 15259 * Copyright 2014 jQuery Foundation and other contributors 15260 * Released under the MIT license. 15261 * http://jquery.org/license 15262 * 15263 * http://api.jqueryui.com/drop-effect/ 15264 */ 15265 15266 15267var effectDrop = $.effects.effect.drop = function( o, done ) { 15268 15269 var el = $( this ), 15270 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 15271 mode = $.effects.setMode( el, o.mode || "hide" ), 15272 show = mode === "show", 15273 direction = o.direction || "left", 15274 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15275 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 15276 animation = { 15277 opacity: show ? 1 : 0 15278 }, 15279 distance; 15280 15281 // Adjust 15282 $.effects.save( el, props ); 15283 el.show(); 15284 $.effects.createWrapper( el ); 15285 15286 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 15287 15288 if ( show ) { 15289 el 15290 .css( "opacity", 0 ) 15291 .css( ref, motion === "pos" ? -distance : distance ); 15292 } 15293 15294 // Animation 15295 animation[ ref ] = ( show ? 15296 ( motion === "pos" ? "+=" : "-=" ) : 15297 ( motion === "pos" ? "-=" : "+=" ) ) + 15298 distance; 15299 15300 // Animate 15301 el.animate( animation, { 15302 queue: false, 15303 duration: o.duration, 15304 easing: o.easing, 15305 complete: function() { 15306 if ( mode === "hide" ) { 15307 el.hide(); 15308 } 15309 $.effects.restore( el, props ); 15310 $.effects.removeWrapper( el ); 15311 done(); 15312 } 15313 }); 15314}; 15315 15316 15317/*! 15318 * jQuery UI Effects Explode 1.11.2 15319 * http://jqueryui.com 15320 * 15321 * Copyright 2014 jQuery Foundation and other contributors 15322 * Released under the MIT license. 15323 * http://jquery.org/license 15324 * 15325 * http://api.jqueryui.com/explode-effect/ 15326 */ 15327 15328 15329var effectExplode = $.effects.effect.explode = function( o, done ) { 15330 15331 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 15332 cells = rows, 15333 el = $( this ), 15334 mode = $.effects.setMode( el, o.mode || "hide" ), 15335 show = mode === "show", 15336 15337 // show and then visibility:hidden the element before calculating offset 15338 offset = el.show().css( "visibility", "hidden" ).offset(), 15339 15340 // width and height of a piece 15341 width = Math.ceil( el.outerWidth() / cells ), 15342 height = Math.ceil( el.outerHeight() / rows ), 15343 pieces = [], 15344 15345 // loop 15346 i, j, left, top, mx, my; 15347 15348 // children animate complete: 15349 function childComplete() { 15350 pieces.push( this ); 15351 if ( pieces.length === rows * cells ) { 15352 animComplete(); 15353 } 15354 } 15355 15356 // clone the element for each row and cell. 15357 for ( i = 0; i < rows ; i++ ) { // ===> 15358 top = offset.top + i * height; 15359 my = i - ( rows - 1 ) / 2 ; 15360 15361 for ( j = 0; j < cells ; j++ ) { // ||| 15362 left = offset.left + j * width; 15363 mx = j - ( cells - 1 ) / 2 ; 15364 15365 // Create a clone of the now hidden main element that will be absolute positioned 15366 // within a wrapper div off the -left and -top equal to size of our pieces 15367 el 15368 .clone() 15369 .appendTo( "body" ) 15370 .wrap( "<div></div>" ) 15371 .css({ 15372 position: "absolute", 15373 visibility: "visible", 15374 left: -j * width, 15375 top: -i * height 15376 }) 15377 15378 // select the wrapper - make it overflow: hidden and absolute positioned based on 15379 // where the original was located +left and +top equal to the size of pieces 15380 .parent() 15381 .addClass( "ui-effects-explode" ) 15382 .css({ 15383 position: "absolute", 15384 overflow: "hidden", 15385 width: width, 15386 height: height, 15387 left: left + ( show ? mx * width : 0 ), 15388 top: top + ( show ? my * height : 0 ), 15389 opacity: show ? 0 : 1 15390 }).animate({ 15391 left: left + ( show ? 0 : mx * width ), 15392 top: top + ( show ? 0 : my * height ), 15393 opacity: show ? 1 : 0 15394 }, o.duration || 500, o.easing, childComplete ); 15395 } 15396 } 15397 15398 function animComplete() { 15399 el.css({ 15400 visibility: "visible" 15401 }); 15402 $( pieces ).remove(); 15403 if ( !show ) { 15404 el.hide(); 15405 } 15406 done(); 15407 } 15408}; 15409 15410 15411/*! 15412 * jQuery UI Effects Fade 1.11.2 15413 * http://jqueryui.com 15414 * 15415 * Copyright 2014 jQuery Foundation and other contributors 15416 * Released under the MIT license. 15417 * http://jquery.org/license 15418 * 15419 * http://api.jqueryui.com/fade-effect/ 15420 */ 15421 15422 15423var effectFade = $.effects.effect.fade = function( o, done ) { 15424 var el = $( this ), 15425 mode = $.effects.setMode( el, o.mode || "toggle" ); 15426 15427 el.animate({ 15428 opacity: mode 15429 }, { 15430 queue: false, 15431 duration: o.duration, 15432 easing: o.easing, 15433 complete: done 15434 }); 15435}; 15436 15437 15438/*! 15439 * jQuery UI Effects Fold 1.11.2 15440 * http://jqueryui.com 15441 * 15442 * Copyright 2014 jQuery Foundation and other contributors 15443 * Released under the MIT license. 15444 * http://jquery.org/license 15445 * 15446 * http://api.jqueryui.com/fold-effect/ 15447 */ 15448 15449 15450var effectFold = $.effects.effect.fold = function( o, done ) { 15451 15452 // Create element 15453 var el = $( this ), 15454 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15455 mode = $.effects.setMode( el, o.mode || "hide" ), 15456 show = mode === "show", 15457 hide = mode === "hide", 15458 size = o.size || 15, 15459 percent = /([0-9]+)%/.exec( size ), 15460 horizFirst = !!o.horizFirst, 15461 widthFirst = show !== horizFirst, 15462 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 15463 duration = o.duration / 2, 15464 wrapper, distance, 15465 animation1 = {}, 15466 animation2 = {}; 15467 15468 $.effects.save( el, props ); 15469 el.show(); 15470 15471 // Create Wrapper 15472 wrapper = $.effects.createWrapper( el ).css({ 15473 overflow: "hidden" 15474 }); 15475 distance = widthFirst ? 15476 [ wrapper.width(), wrapper.height() ] : 15477 [ wrapper.height(), wrapper.width() ]; 15478 15479 if ( percent ) { 15480 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 15481 } 15482 if ( show ) { 15483 wrapper.css( horizFirst ? { 15484 height: 0, 15485 width: size 15486 } : { 15487 height: size, 15488 width: 0 15489 }); 15490 } 15491 15492 // Animation 15493 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 15494 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 15495 15496 // Animate 15497 wrapper 15498 .animate( animation1, duration, o.easing ) 15499 .animate( animation2, duration, o.easing, function() { 15500 if ( hide ) { 15501 el.hide(); 15502 } 15503 $.effects.restore( el, props ); 15504 $.effects.removeWrapper( el ); 15505 done(); 15506 }); 15507 15508}; 15509 15510 15511/*! 15512 * jQuery UI Effects Highlight 1.11.2 15513 * http://jqueryui.com 15514 * 15515 * Copyright 2014 jQuery Foundation and other contributors 15516 * Released under the MIT license. 15517 * http://jquery.org/license 15518 * 15519 * http://api.jqueryui.com/highlight-effect/ 15520 */ 15521 15522 15523var effectHighlight = $.effects.effect.highlight = function( o, done ) { 15524 var elem = $( this ), 15525 props = [ "backgroundImage", "backgroundColor", "opacity" ], 15526 mode = $.effects.setMode( elem, o.mode || "show" ), 15527 animation = { 15528 backgroundColor: elem.css( "backgroundColor" ) 15529 }; 15530 15531 if (mode === "hide") { 15532 animation.opacity = 0; 15533 } 15534 15535 $.effects.save( elem, props ); 15536 15537 elem 15538 .show() 15539 .css({ 15540 backgroundImage: "none", 15541 backgroundColor: o.color || "#ffff99" 15542 }) 15543 .animate( animation, { 15544 queue: false, 15545 duration: o.duration, 15546 easing: o.easing, 15547 complete: function() { 15548 if ( mode === "hide" ) { 15549 elem.hide(); 15550 } 15551 $.effects.restore( elem, props ); 15552 done(); 15553 } 15554 }); 15555}; 15556 15557 15558/*! 15559 * jQuery UI Effects Size 1.11.2 15560 * http://jqueryui.com 15561 * 15562 * Copyright 2014 jQuery Foundation and other contributors 15563 * Released under the MIT license. 15564 * http://jquery.org/license 15565 * 15566 * http://api.jqueryui.com/size-effect/ 15567 */ 15568 15569 15570var effectSize = $.effects.effect.size = function( o, done ) { 15571 15572 // Create element 15573 var original, baseline, factor, 15574 el = $( this ), 15575 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 15576 15577 // Always restore 15578 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 15579 15580 // Copy for children 15581 props2 = [ "width", "height", "overflow" ], 15582 cProps = [ "fontSize" ], 15583 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 15584 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 15585 15586 // Set options 15587 mode = $.effects.setMode( el, o.mode || "effect" ), 15588 restore = o.restore || mode !== "effect", 15589 scale = o.scale || "both", 15590 origin = o.origin || [ "middle", "center" ], 15591 position = el.css( "position" ), 15592 props = restore ? props0 : props1, 15593 zero = { 15594 height: 0, 15595 width: 0, 15596 outerHeight: 0, 15597 outerWidth: 0 15598 }; 15599 15600 if ( mode === "show" ) { 15601 el.show(); 15602 } 15603 original = { 15604 height: el.height(), 15605 width: el.width(), 15606 outerHeight: el.outerHeight(), 15607 outerWidth: el.outerWidth() 15608 }; 15609 15610 if ( o.mode === "toggle" && mode === "show" ) { 15611 el.from = o.to || zero; 15612 el.to = o.from || original; 15613 } else { 15614 el.from = o.from || ( mode === "show" ? zero : original ); 15615 el.to = o.to || ( mode === "hide" ? zero : original ); 15616 } 15617 15618 // Set scaling factor 15619 factor = { 15620 from: { 15621 y: el.from.height / original.height, 15622 x: el.from.width / original.width 15623 }, 15624 to: { 15625 y: el.to.height / original.height, 15626 x: el.to.width / original.width 15627 } 15628 }; 15629 15630 // Scale the css box 15631 if ( scale === "box" || scale === "both" ) { 15632 15633 // Vertical props scaling 15634 if ( factor.from.y !== factor.to.y ) { 15635 props = props.concat( vProps ); 15636 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 15637 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 15638 } 15639 15640 // Horizontal props scaling 15641 if ( factor.from.x !== factor.to.x ) { 15642 props = props.concat( hProps ); 15643 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 15644 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 15645 } 15646 } 15647 15648 // Scale the content 15649 if ( scale === "content" || scale === "both" ) { 15650 15651 // Vertical props scaling 15652 if ( factor.from.y !== factor.to.y ) { 15653 props = props.concat( cProps ).concat( props2 ); 15654 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 15655 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 15656 } 15657 } 15658 15659 $.effects.save( el, props ); 15660 el.show(); 15661 $.effects.createWrapper( el ); 15662 el.css( "overflow", "hidden" ).css( el.from ); 15663 15664 // Adjust 15665 if (origin) { // Calculate baseline shifts 15666 baseline = $.effects.getBaseline( origin, original ); 15667 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 15668 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 15669 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 15670 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 15671 } 15672 el.css( el.from ); // set top & left 15673 15674 // Animate 15675 if ( scale === "content" || scale === "both" ) { // Scale the children 15676 15677 // Add margins/font-size 15678 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 15679 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 15680 props2 = props0.concat(vProps).concat(hProps); 15681 15682 el.find( "*[width]" ).each( function() { 15683 var child = $( this ), 15684 c_original = { 15685 height: child.height(), 15686 width: child.width(), 15687 outerHeight: child.outerHeight(), 15688 outerWidth: child.outerWidth() 15689 }; 15690 if (restore) { 15691 $.effects.save(child, props2); 15692 } 15693 15694 child.from = { 15695 height: c_original.height * factor.from.y, 15696 width: c_original.width * factor.from.x, 15697 outerHeight: c_original.outerHeight * factor.from.y, 15698 outerWidth: c_original.outerWidth * factor.from.x 15699 }; 15700 child.to = { 15701 height: c_original.height * factor.to.y, 15702 width: c_original.width * factor.to.x, 15703 outerHeight: c_original.height * factor.to.y, 15704 outerWidth: c_original.width * factor.to.x 15705 }; 15706 15707 // Vertical props scaling 15708 if ( factor.from.y !== factor.to.y ) { 15709 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 15710 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 15711 } 15712 15713 // Horizontal props scaling 15714 if ( factor.from.x !== factor.to.x ) { 15715 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 15716 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 15717 } 15718 15719 // Animate children 15720 child.css( child.from ); 15721 child.animate( child.to, o.duration, o.easing, function() { 15722 15723 // Restore children 15724 if ( restore ) { 15725 $.effects.restore( child, props2 ); 15726 } 15727 }); 15728 }); 15729 } 15730 15731 // Animate 15732 el.animate( el.to, { 15733 queue: false, 15734 duration: o.duration, 15735 easing: o.easing, 15736 complete: function() { 15737 if ( el.to.opacity === 0 ) { 15738 el.css( "opacity", el.from.opacity ); 15739 } 15740 if ( mode === "hide" ) { 15741 el.hide(); 15742 } 15743 $.effects.restore( el, props ); 15744 if ( !restore ) { 15745 15746 // we need to calculate our new positioning based on the scaling 15747 if ( position === "static" ) { 15748 el.css({ 15749 position: "relative", 15750 top: el.to.top, 15751 left: el.to.left 15752 }); 15753 } else { 15754 $.each([ "top", "left" ], function( idx, pos ) { 15755 el.css( pos, function( _, str ) { 15756 var val = parseInt( str, 10 ), 15757 toRef = idx ? el.to.left : el.to.top; 15758 15759 // if original was "auto", recalculate the new value from wrapper 15760 if ( str === "auto" ) { 15761 return toRef + "px"; 15762 } 15763 15764 return val + toRef + "px"; 15765 }); 15766 }); 15767 } 15768 } 15769 15770 $.effects.removeWrapper( el ); 15771 done(); 15772 } 15773 }); 15774 15775}; 15776 15777 15778/*! 15779 * jQuery UI Effects Scale 1.11.2 15780 * http://jqueryui.com 15781 * 15782 * Copyright 2014 jQuery Foundation and other contributors 15783 * Released under the MIT license. 15784 * http://jquery.org/license 15785 * 15786 * http://api.jqueryui.com/scale-effect/ 15787 */ 15788 15789 15790var effectScale = $.effects.effect.scale = function( o, done ) { 15791 15792 // Create element 15793 var el = $( this ), 15794 options = $.extend( true, {}, o ), 15795 mode = $.effects.setMode( el, o.mode || "effect" ), 15796 percent = parseInt( o.percent, 10 ) || 15797 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 15798 direction = o.direction || "both", 15799 origin = o.origin, 15800 original = { 15801 height: el.height(), 15802 width: el.width(), 15803 outerHeight: el.outerHeight(), 15804 outerWidth: el.outerWidth() 15805 }, 15806 factor = { 15807 y: direction !== "horizontal" ? (percent / 100) : 1, 15808 x: direction !== "vertical" ? (percent / 100) : 1 15809 }; 15810 15811 // We are going to pass this effect to the size effect: 15812 options.effect = "size"; 15813 options.queue = false; 15814 options.complete = done; 15815 15816 // Set default origin and restore for show/hide 15817 if ( mode !== "effect" ) { 15818 options.origin = origin || [ "middle", "center" ]; 15819 options.restore = true; 15820 } 15821 15822 options.from = o.from || ( mode === "show" ? { 15823 height: 0, 15824 width: 0, 15825 outerHeight: 0, 15826 outerWidth: 0 15827 } : original ); 15828 options.to = { 15829 height: original.height * factor.y, 15830 width: original.width * factor.x, 15831 outerHeight: original.outerHeight * factor.y, 15832 outerWidth: original.outerWidth * factor.x 15833 }; 15834 15835 // Fade option to support puff 15836 if ( options.fade ) { 15837 if ( mode === "show" ) { 15838 options.from.opacity = 0; 15839 options.to.opacity = 1; 15840 } 15841 if ( mode === "hide" ) { 15842 options.from.opacity = 1; 15843 options.to.opacity = 0; 15844 } 15845 } 15846 15847 // Animate 15848 el.effect( options ); 15849 15850}; 15851 15852 15853/*! 15854 * jQuery UI Effects Puff 1.11.2 15855 * http://jqueryui.com 15856 * 15857 * Copyright 2014 jQuery Foundation and other contributors 15858 * Released under the MIT license. 15859 * http://jquery.org/license 15860 * 15861 * http://api.jqueryui.com/puff-effect/ 15862 */ 15863 15864 15865var effectPuff = $.effects.effect.puff = function( o, done ) { 15866 var elem = $( this ), 15867 mode = $.effects.setMode( elem, o.mode || "hide" ), 15868 hide = mode === "hide", 15869 percent = parseInt( o.percent, 10 ) || 150, 15870 factor = percent / 100, 15871 original = { 15872 height: elem.height(), 15873 width: elem.width(), 15874 outerHeight: elem.outerHeight(), 15875 outerWidth: elem.outerWidth() 15876 }; 15877 15878 $.extend( o, { 15879 effect: "scale", 15880 queue: false, 15881 fade: true, 15882 mode: mode, 15883 complete: done, 15884 percent: hide ? percent : 100, 15885 from: hide ? 15886 original : 15887 { 15888 height: original.height * factor, 15889 width: original.width * factor, 15890 outerHeight: original.outerHeight * factor, 15891 outerWidth: original.outerWidth * factor 15892 } 15893 }); 15894 15895 elem.effect( o ); 15896}; 15897 15898 15899/*! 15900 * jQuery UI Effects Pulsate 1.11.2 15901 * http://jqueryui.com 15902 * 15903 * Copyright 2014 jQuery Foundation and other contributors 15904 * Released under the MIT license. 15905 * http://jquery.org/license 15906 * 15907 * http://api.jqueryui.com/pulsate-effect/ 15908 */ 15909 15910 15911var effectPulsate = $.effects.effect.pulsate = function( o, done ) { 15912 var elem = $( this ), 15913 mode = $.effects.setMode( elem, o.mode || "show" ), 15914 show = mode === "show", 15915 hide = mode === "hide", 15916 showhide = ( show || mode === "hide" ), 15917 15918 // showing or hiding leaves of the "last" animation 15919 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 15920 duration = o.duration / anims, 15921 animateTo = 0, 15922 queue = elem.queue(), 15923 queuelen = queue.length, 15924 i; 15925 15926 if ( show || !elem.is(":visible")) { 15927 elem.css( "opacity", 0 ).show(); 15928 animateTo = 1; 15929 } 15930 15931 // anims - 1 opacity "toggles" 15932 for ( i = 1; i < anims; i++ ) { 15933 elem.animate({ 15934 opacity: animateTo 15935 }, duration, o.easing ); 15936 animateTo = 1 - animateTo; 15937 } 15938 15939 elem.animate({ 15940 opacity: animateTo 15941 }, duration, o.easing); 15942 15943 elem.queue(function() { 15944 if ( hide ) { 15945 elem.hide(); 15946 } 15947 done(); 15948 }); 15949 15950 // We just queued up "anims" animations, we need to put them next in the queue 15951 if ( queuelen > 1 ) { 15952 queue.splice.apply( queue, 15953 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15954 } 15955 elem.dequeue(); 15956}; 15957 15958 15959/*! 15960 * jQuery UI Effects Shake 1.11.2 15961 * http://jqueryui.com 15962 * 15963 * Copyright 2014 jQuery Foundation and other contributors 15964 * Released under the MIT license. 15965 * http://jquery.org/license 15966 * 15967 * http://api.jqueryui.com/shake-effect/ 15968 */ 15969 15970 15971var effectShake = $.effects.effect.shake = function( o, done ) { 15972 15973 var el = $( this ), 15974 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15975 mode = $.effects.setMode( el, o.mode || "effect" ), 15976 direction = o.direction || "left", 15977 distance = o.distance || 20, 15978 times = o.times || 3, 15979 anims = times * 2 + 1, 15980 speed = Math.round( o.duration / anims ), 15981 ref = (direction === "up" || direction === "down") ? "top" : "left", 15982 positiveMotion = (direction === "up" || direction === "left"), 15983 animation = {}, 15984 animation1 = {}, 15985 animation2 = {}, 15986 i, 15987 15988 // we will need to re-assemble the queue to stack our animations in place 15989 queue = el.queue(), 15990 queuelen = queue.length; 15991 15992 $.effects.save( el, props ); 15993 el.show(); 15994 $.effects.createWrapper( el ); 15995 15996 // Animation 15997 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 15998 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 15999 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 16000 16001 // Animate 16002 el.animate( animation, speed, o.easing ); 16003 16004 // Shakes 16005 for ( i = 1; i < times; i++ ) { 16006 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 16007 } 16008 el 16009 .animate( animation1, speed, o.easing ) 16010 .animate( animation, speed / 2, o.easing ) 16011 .queue(function() { 16012 if ( mode === "hide" ) { 16013 el.hide(); 16014 } 16015 $.effects.restore( el, props ); 16016 $.effects.removeWrapper( el ); 16017 done(); 16018 }); 16019 16020 // inject all the animations we just queued to be first in line (after "inprogress") 16021 if ( queuelen > 1) { 16022 queue.splice.apply( queue, 16023 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 16024 } 16025 el.dequeue(); 16026 16027}; 16028 16029 16030/*! 16031 * jQuery UI Effects Slide 1.11.2 16032 * http://jqueryui.com 16033 * 16034 * Copyright 2014 jQuery Foundation and other contributors 16035 * Released under the MIT license. 16036 * http://jquery.org/license 16037 * 16038 * http://api.jqueryui.com/slide-effect/ 16039 */ 16040 16041 16042var effectSlide = $.effects.effect.slide = function( o, done ) { 16043 16044 // Create element 16045 var el = $( this ), 16046 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 16047 mode = $.effects.setMode( el, o.mode || "show" ), 16048 show = mode === "show", 16049 direction = o.direction || "left", 16050 ref = (direction === "up" || direction === "down") ? "top" : "left", 16051 positiveMotion = (direction === "up" || direction === "left"), 16052 distance, 16053 animation = {}; 16054 16055 // Adjust 16056 $.effects.save( el, props ); 16057 el.show(); 16058 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 16059 16060 $.effects.createWrapper( el ).css({ 16061 overflow: "hidden" 16062 }); 16063 16064 if ( show ) { 16065 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 16066 } 16067 16068 // Animation 16069 animation[ ref ] = ( show ? 16070 ( positiveMotion ? "+=" : "-=") : 16071 ( positiveMotion ? "-=" : "+=")) + 16072 distance; 16073 16074 // Animate 16075 el.animate( animation, { 16076 queue: false, 16077 duration: o.duration, 16078 easing: o.easing, 16079 complete: function() { 16080 if ( mode === "hide" ) { 16081 el.hide(); 16082 } 16083 $.effects.restore( el, props ); 16084 $.effects.removeWrapper( el ); 16085 done(); 16086 } 16087 }); 16088}; 16089 16090 16091/*! 16092 * jQuery UI Effects Transfer 1.11.2 16093 * http://jqueryui.com 16094 * 16095 * Copyright 2014 jQuery Foundation and other contributors 16096 * Released under the MIT license. 16097 * http://jquery.org/license 16098 * 16099 * http://api.jqueryui.com/transfer-effect/ 16100 */ 16101 16102 16103var effectTransfer = $.effects.effect.transfer = function( o, done ) { 16104 var elem = $( this ), 16105 target = $( o.to ), 16106 targetFixed = target.css( "position" ) === "fixed", 16107 body = $("body"), 16108 fixTop = targetFixed ? body.scrollTop() : 0, 16109 fixLeft = targetFixed ? body.scrollLeft() : 0, 16110 endPosition = target.offset(), 16111 animation = { 16112 top: endPosition.top - fixTop, 16113 left: endPosition.left - fixLeft, 16114 height: target.innerHeight(), 16115 width: target.innerWidth() 16116 }, 16117 startPosition = elem.offset(), 16118 transfer = $( "<div class='ui-effects-transfer'></div>" ) 16119 .appendTo( document.body ) 16120 .addClass( o.className ) 16121 .css({ 16122 top: startPosition.top - fixTop, 16123 left: startPosition.left - fixLeft,
16124 height: elem.innerHeight(), 16125 width: elem.innerWidth(), 16126 position: targetFixed ? "fixed" : "absolute" 16127 }) 16128 .animate( animation, o.duration, o.easing, function() { 16129 transfer.remove(); 16130 done(); 16131 }); 16132}; 16133 16134 16135 16136}));
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.