1/*! jQuery UI - v1.11.1 - 2014-08-24 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, tooltip.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
vendor: 116,211 bytes, lines 3-4100
3.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.1 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.1", 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.1 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 this.options = $.widget.extend( {}, 558 this.options, 559 this._getCreateOptions(), 560 options ); 561 562 this.bindings = $(); 563 this.hoverable = $(); 564 this.focusable = $(); 565 566 if ( element !== this ) { 567 $.data( element, this.widgetFullName, this ); 568 this._on( true, this.element, { 569 remove: function( event ) { 570 if ( event.target === element ) { 571 this.destroy(); 572 } 573 } 574 }); 575 this.document = $( element.style ? 576 // element within the document 577 element.ownerDocument : 578 // element is window or document 579 element.document || element ); 580 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 581 } 582 583 this._create(); 584 this._trigger( "create", null, this._getCreateEventData() ); 585 this._init(); 586 }, 587 _getCreateOptions: $.noop, 588 _getCreateEventData: $.noop, 589 _create: $.noop, 590 _init: $.noop, 591 592 destroy: function() { 593 this._destroy(); 594 // we can probably remove the unbind calls in 2.0 595 // all event bindings should go through this._on() 596 this.element 597 .unbind( this.eventNamespace ) 598 .removeData( this.widgetFullName ) 599 // support: jquery <1.6.3 600 // http://bugs.jquery.com/ticket/9413 601 .removeData( $.camelCase( this.widgetFullName ) ); 602 this.widget() 603 .unbind( this.eventNamespace ) 604 .removeAttr( "aria-disabled" ) 605 .removeClass( 606 this.widgetFullName + "-disabled " + 607 "ui-state-disabled" ); 608 609 // clean up events and states 610 this.bindings.unbind( this.eventNamespace ); 611 this.hoverable.removeClass( "ui-state-hover" ); 612 this.focusable.removeClass( "ui-state-focus" ); 613 }, 614 _destroy: $.noop, 615 616 widget: function() { 617 return this.element; 618 }, 619 620 option: function( key, value ) { 621 var options = key, 622 parts, 623 curOption, 624 i; 625 626 if ( arguments.length === 0 ) { 627 // don't return a reference to the internal hash 628 return $.widget.extend( {}, this.options ); 629 } 630 631 if ( typeof key === "string" ) { 632 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 633 options = {}; 634 parts = key.split( "." ); 635 key = parts.shift(); 636 if ( parts.length ) { 637 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 638 for ( i = 0; i < parts.length - 1; i++ ) { 639 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 640 curOption = curOption[ parts[ i ] ]; 641 } 642 key = parts.pop(); 643 if ( arguments.length === 1 ) { 644 return curOption[ key ] === undefined ? null : curOption[ key ]; 645 } 646 curOption[ key ] = value; 647 } else { 648 if ( arguments.length === 1 ) { 649 return this.options[ key ] === undefined ? null : this.options[ key ]; 650 } 651 options[ key ] = value; 652 } 653 } 654 655 this._setOptions( options ); 656 657 return this; 658 }, 659 _setOptions: function( options ) { 660 var key; 661 662 for ( key in options ) { 663 this._setOption( key, options[ key ] ); 664 } 665 666 return this; 667 }, 668 _setOption: function( key, value ) { 669 this.options[ key ] = value; 670 671 if ( key === "disabled" ) { 672 this.widget() 673 .toggleClass( this.widgetFullName + "-disabled", !!value ); 674 675 // If the widget is becoming disabled, then nothing is interactive 676 if ( value ) { 677 this.hoverable.removeClass( "ui-state-hover" ); 678 this.focusable.removeClass( "ui-state-focus" ); 679 } 680 } 681 682 return this; 683 }, 684 685 enable: function() { 686 return this._setOptions({ disabled: false }); 687 }, 688 disable: function() { 689 return this._setOptions({ disabled: true }); 690 }, 691 692 _on: function( suppressDisabledCheck, element, handlers ) { 693 var delegateElement, 694 instance = this; 695 696 // no suppressDisabledCheck flag, shuffle arguments 697 if ( typeof suppressDisabledCheck !== "boolean" ) { 698 handlers = element; 699 element = suppressDisabledCheck; 700 suppressDisabledCheck = false; 701 } 702 703 // no element argument, shuffle and use this.element 704 if ( !handlers ) { 705 handlers = element; 706 element = this.element; 707 delegateElement = this.widget(); 708 } else { 709 element = delegateElement = $( element ); 710 this.bindings = this.bindings.add( element ); 711 } 712 713 $.each( handlers, function( event, handler ) { 714 function handlerProxy() { 715 // allow widgets to customize the disabled handling 716 // - disabled as an array instead of boolean 717 // - disabled class as method for disabling individual parts 718 if ( !suppressDisabledCheck && 719 ( instance.options.disabled === true || 720 $( this ).hasClass( "ui-state-disabled" ) ) ) { 721 return; 722 } 723 return ( typeof handler === "string" ? instance[ handler ] : handler ) 724 .apply( instance, arguments ); 725 } 726 727 // copy the guid so direct unbinding works 728 if ( typeof handler !== "string" ) { 729 handlerProxy.guid = handler.guid = 730 handler.guid || handlerProxy.guid || $.guid++; 731 } 732 733 var match = event.match( /^([\w:-]*)\s*(.*)$/ ), 734 eventName = match[1] + instance.eventNamespace, 735 selector = match[2]; 736 if ( selector ) { 737 delegateElement.delegate( selector, eventName, handlerProxy ); 738 } else { 739 element.bind( eventName, handlerProxy ); 740 } 741 }); 742 }, 743 744 _off: function( element, eventName ) { 745 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 746 element.unbind( eventName ).undelegate( eventName ); 747 }, 748 749 _delay: function( handler, delay ) { 750 function handlerProxy() { 751 return ( typeof handler === "string" ? instance[ handler ] : handler ) 752 .apply( instance, arguments ); 753 } 754 var instance = this; 755 return setTimeout( handlerProxy, delay || 0 ); 756 }, 757 758 _hoverable: function( element ) { 759 this.hoverable = this.hoverable.add( element ); 760 this._on( element, { 761 mouseenter: function( event ) { 762 $( event.currentTarget ).addClass( "ui-state-hover" ); 763 }, 764 mouseleave: function( event ) { 765 $( event.currentTarget ).removeClass( "ui-state-hover" ); 766 } 767 }); 768 }, 769 770 _focusable: function( element ) { 771 this.focusable = this.focusable.add( element ); 772 this._on( element, { 773 focusin: function( event ) { 774 $( event.currentTarget ).addClass( "ui-state-focus" ); 775 }, 776 focusout: function( event ) { 777 $( event.currentTarget ).removeClass( "ui-state-focus" ); 778 } 779 }); 780 }, 781 782 _trigger: function( type, event, data ) { 783 var prop, orig, 784 callback = this.options[ type ]; 785 786 data = data || {}; 787 event = $.Event( event ); 788 event.type = ( type === this.widgetEventPrefix ? 789 type : 790 this.widgetEventPrefix + type ).toLowerCase(); 791 // the original event may come from any element 792 // so we need to reset the target on the new event 793 event.target = this.element[ 0 ]; 794 795 // copy original event properties over to the new event 796 orig = event.originalEvent; 797 if ( orig ) { 798 for ( prop in orig ) { 799 if ( !( prop in event ) ) { 800 event[ prop ] = orig[ prop ]; 801 } 802 } 803 } 804 805 this.element.trigger( event, data ); 806 return !( $.isFunction( callback ) && 807 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 808 event.isDefaultPrevented() ); 809 } 810}; 811 812$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 813 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 814 if ( typeof options === "string" ) { 815 options = { effect: options }; 816 } 817 var hasOptions, 818 effectName = !options ? 819 method : 820 options === true || typeof options === "number" ? 821 defaultEffect : 822 options.effect || defaultEffect; 823 options = options || {}; 824 if ( typeof options === "number" ) { 825 options = { duration: options }; 826 } 827 hasOptions = !$.isEmptyObject( options ); 828 options.complete = callback; 829 if ( options.delay ) { 830 element.delay( options.delay ); 831 } 832 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 833 element[ method ]( options ); 834 } else if ( effectName !== method && element[ effectName ] ) { 835 element[ effectName ]( options.duration, options.easing, callback ); 836 } else { 837 element.queue(function( next ) { 838 $( this )[ method ](); 839 if ( callback ) { 840 callback.call( element[ 0 ] ); 841 } 842 next(); 843 }); 844 } 845 }; 846}); 847 848var widget = $.widget; 849 850 851/*! 852 * jQuery UI Mouse 1.11.1 853 * http://jqueryui.com 854 * 855 * Copyright 2014 jQuery Foundation and other contributors 856 * Released under the MIT license. 857 * http://jquery.org/license 858 * 859 * http://api.jqueryui.com/mouse/ 860 */ 861 862 863var mouseHandled = false; 864$( document ).mouseup( function() { 865 mouseHandled = false; 866}); 867 868var mouse = $.widget("ui.mouse", { 869 version: "1.11.1", 870 options: { 871 cancel: "input,textarea,button,select,option", 872 distance: 1, 873 delay: 0 874 }, 875 _mouseInit: function() { 876 var that = this; 877 878 this.element 879 .bind("mousedown." + this.widgetName, function(event) { 880 return that._mouseDown(event); 881 }) 882 .bind("click." + this.widgetName, function(event) { 883 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 884 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 885 event.stopImmediatePropagation(); 886 return false; 887 } 888 }); 889 890 this.started = false; 891 }, 892 893 // TODO: make sure destroying one instance of mouse doesn't mess with 894 // other instances of mouse 895 _mouseDestroy: function() { 896 this.element.unbind("." + this.widgetName); 897 if ( this._mouseMoveDelegate ) { 898 this.document 899 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) 900 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); 901 } 902 }, 903 904 _mouseDown: function(event) { 905 // don't let more than one widget handle mouseStart 906 if ( mouseHandled ) { 907 return; 908 } 909 910 // we may have missed mouseup (out of window) 911 (this._mouseStarted && this._mouseUp(event)); 912 913 this._mouseDownEvent = event; 914 915 var that = this, 916 btnIsLeft = (event.which === 1), 917 // event.target.nodeName works around a bug in IE 8 with 918 // disabled inputs (#7620) 919 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 920 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 921 return true; 922 } 923 924 this.mouseDelayMet = !this.options.delay; 925 if (!this.mouseDelayMet) { 926 this._mouseDelayTimer = setTimeout(function() { 927 that.mouseDelayMet = true; 928 }, this.options.delay); 929 } 930 931 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 932 this._mouseStarted = (this._mouseStart(event) !== false); 933 if (!this._mouseStarted) { 934 event.preventDefault(); 935 return true; 936 } 937 } 938 939 // Click event may never have fired (Gecko & Opera) 940 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 941 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 942 } 943 944 // these delegates are required to keep context 945 this._mouseMoveDelegate = function(event) { 946 return that._mouseMove(event); 947 }; 948 this._mouseUpDelegate = function(event) { 949 return that._mouseUp(event); 950 }; 951 952 this.document 953 .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 954 .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 955 956 event.preventDefault(); 957 958 mouseHandled = true; 959 return true; 960 }, 961 962 _mouseMove: function(event) { 963 // IE mouseup check - mouseup happened when mouse was out of window 964 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 965 return this._mouseUp(event); 966 967 // Iframe mouseup check - mouseup occurred in another document 968 } else if ( !event.which ) { 969 return this._mouseUp( event ); 970 } 971 972 if (this._mouseStarted) { 973 this._mouseDrag(event); 974 return event.preventDefault(); 975 } 976 977 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 978 this._mouseStarted = 979 (this._mouseStart(this._mouseDownEvent, event) !== false); 980 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 981 } 982 983 return !this._mouseStarted; 984 }, 985 986 _mouseUp: function(event) { 987 this.document 988 .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 989 .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 990 991 if (this._mouseStarted) { 992 this._mouseStarted = false; 993 994 if (event.target === this._mouseDownEvent.target) { 995 $.data(event.target, this.widgetName + ".preventClickEvent", true); 996 } 997 998 this._mouseStop(event); 999 } 1000 1001 mouseHandled = false; 1002 return false; 1003 }, 1004 1005 _mouseDistanceMet: function(event) { 1006 return (Math.max( 1007 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1008 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1009 ) >= this.options.distance 1010 ); 1011 }, 1012 1013 _mouseDelayMet: function(/* event */) { 1014 return this.mouseDelayMet; 1015 }, 1016 1017 // These are placeholder methods, to be overriden by extending plugin 1018 _mouseStart: function(/* event */) {}, 1019 _mouseDrag: function(/* event */) {}, 1020 _mouseStop: function(/* event */) {}, 1021 _mouseCapture: function(/* event */) { return true; } 1022}); 1023 1024 1025/*! 1026 * jQuery UI Position 1.11.1 1027 * http://jqueryui.com 1028 * 1029 * Copyright 2014 jQuery Foundation and other contributors 1030 * Released under the MIT license. 1031 * http://jquery.org/license 1032 * 1033 * http://api.jqueryui.com/position/ 1034 */ 1035 1036(function() { 1037 1038$.ui = $.ui || {}; 1039 1040var cachedScrollbarWidth, supportsOffsetFractions, 1041 max = Math.max, 1042 abs = Math.abs, 1043 round = Math.round, 1044 rhorizontal = /left|center|right/, 1045 rvertical = /top|center|bottom/, 1046 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 1047 rposition = /^\w+/, 1048 rpercent = /%$/, 1049 _position = $.fn.position; 1050 1051function getOffsets( offsets, width, height ) { 1052 return [ 1053 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1054 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1055 ]; 1056} 1057 1058function parseCss( element, property ) { 1059 return parseInt( $.css( element, property ), 10 ) || 0; 1060} 1061 1062function getDimensions( elem ) { 1063 var raw = elem[0]; 1064 if ( raw.nodeType === 9 ) { 1065 return { 1066 width: elem.width(), 1067 height: elem.height(), 1068 offset: { top: 0, left: 0 } 1069 }; 1070 } 1071 if ( $.isWindow( raw ) ) { 1072 return { 1073 width: elem.width(), 1074 height: elem.height(), 1075 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1076 }; 1077 } 1078 if ( raw.preventDefault ) { 1079 return { 1080 width: 0, 1081 height: 0, 1082 offset: { top: raw.pageY, left: raw.pageX } 1083 }; 1084 } 1085 return { 1086 width: elem.outerWidth(), 1087 height: elem.outerHeight(), 1088 offset: elem.offset() 1089 }; 1090} 1091 1092$.position = { 1093 scrollbarWidth: function() { 1094 if ( cachedScrollbarWidth !== undefined ) { 1095 return cachedScrollbarWidth; 1096 } 1097 var w1, w2, 1098 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1099 innerDiv = div.children()[0]; 1100 1101 $( "body" ).append( div ); 1102 w1 = innerDiv.offsetWidth; 1103 div.css( "overflow", "scroll" ); 1104 1105 w2 = innerDiv.offsetWidth; 1106 1107 if ( w1 === w2 ) { 1108 w2 = div[0].clientWidth; 1109 } 1110 1111 div.remove(); 1112 1113 return (cachedScrollbarWidth = w1 - w2); 1114 }, 1115 getScrollInfo: function( within ) { 1116 var overflowX = within.isWindow || within.isDocument ? "" : 1117 within.element.css( "overflow-x" ), 1118 overflowY = within.isWindow || within.isDocument ? "" : 1119 within.element.css( "overflow-y" ), 1120 hasOverflowX = overflowX === "scroll" || 1121 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1122 hasOverflowY = overflowY === "scroll" || 1123 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1124 return { 1125 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1126 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1127 }; 1128 }, 1129 getWithinInfo: function( element ) { 1130 var withinElement = $( element || window ), 1131 isWindow = $.isWindow( withinElement[0] ), 1132 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1133 return { 1134 element: withinElement, 1135 isWindow: isWindow, 1136 isDocument: isDocument, 1137 offset: withinElement.offset() || { left: 0, top: 0 }, 1138 scrollLeft: withinElement.scrollLeft(), 1139 scrollTop: withinElement.scrollTop(), 1140 1141 // support: jQuery 1.6.x 1142 // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows 1143 width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), 1144 height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() 1145 }; 1146 } 1147}; 1148 1149$.fn.position = function( options ) { 1150 if ( !options || !options.of ) { 1151 return _position.apply( this, arguments ); 1152 } 1153 1154 // make a copy, we don't want to modify arguments 1155 options = $.extend( {}, options ); 1156 1157 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1158 target = $( options.of ), 1159 within = $.position.getWithinInfo( options.within ), 1160 scrollInfo = $.position.getScrollInfo( within ), 1161 collision = ( options.collision || "flip" ).split( " " ), 1162 offsets = {}; 1163 1164 dimensions = getDimensions( target ); 1165 if ( target[0].preventDefault ) { 1166 // force left top to allow flipping 1167 options.at = "left top"; 1168 } 1169 targetWidth = dimensions.width; 1170 targetHeight = dimensions.height; 1171 targetOffset = dimensions.offset; 1172 // clone to reuse original targetOffset later 1173 basePosition = $.extend( {}, targetOffset ); 1174 1175 // force my and at to have valid horizontal and vertical positions 1176 // if a value is missing or invalid, it will be converted to center 1177 $.each( [ "my", "at" ], function() { 1178 var pos = ( options[ this ] || "" ).split( " " ), 1179 horizontalOffset, 1180 verticalOffset; 1181 1182 if ( pos.length === 1) { 1183 pos = rhorizontal.test( pos[ 0 ] ) ? 1184 pos.concat( [ "center" ] ) : 1185 rvertical.test( pos[ 0 ] ) ? 1186 [ "center" ].concat( pos ) : 1187 [ "center", "center" ]; 1188 } 1189 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1190 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1191 1192 // calculate offsets 1193 horizontalOffset = roffset.exec( pos[ 0 ] ); 1194 verticalOffset = roffset.exec( pos[ 1 ] ); 1195 offsets[ this ] = [ 1196 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1197 verticalOffset ? verticalOffset[ 0 ] : 0 1198 ]; 1199 1200 // reduce to just the positions without the offsets 1201 options[ this ] = [ 1202 rposition.exec( pos[ 0 ] )[ 0 ], 1203 rposition.exec( pos[ 1 ] )[ 0 ] 1204 ]; 1205 }); 1206 1207 // normalize collision option 1208 if ( collision.length === 1 ) { 1209 collision[ 1 ] = collision[ 0 ]; 1210 } 1211 1212 if ( options.at[ 0 ] === "right" ) { 1213 basePosition.left += targetWidth; 1214 } else if ( options.at[ 0 ] === "center" ) { 1215 basePosition.left += targetWidth / 2; 1216 } 1217 1218 if ( options.at[ 1 ] === "bottom" ) { 1219 basePosition.top += targetHeight; 1220 } else if ( options.at[ 1 ] === "center" ) { 1221 basePosition.top += targetHeight / 2; 1222 } 1223 1224 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1225 basePosition.left += atOffset[ 0 ]; 1226 basePosition.top += atOffset[ 1 ]; 1227 1228 return this.each(function() { 1229 var collisionPosition, using, 1230 elem = $( this ), 1231 elemWidth = elem.outerWidth(), 1232 elemHeight = elem.outerHeight(), 1233 marginLeft = parseCss( this, "marginLeft" ), 1234 marginTop = parseCss( this, "marginTop" ), 1235 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1236 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1237 position = $.extend( {}, basePosition ), 1238 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1239 1240 if ( options.my[ 0 ] === "right" ) { 1241 position.left -= elemWidth; 1242 } else if ( options.my[ 0 ] === "center" ) { 1243 position.left -= elemWidth / 2; 1244 } 1245 1246 if ( options.my[ 1 ] === "bottom" ) { 1247 position.top -= elemHeight; 1248 } else if ( options.my[ 1 ] === "center" ) { 1249 position.top -= elemHeight / 2; 1250 } 1251 1252 position.left += myOffset[ 0 ]; 1253 position.top += myOffset[ 1 ]; 1254 1255 // if the browser doesn't support fractions, then round for consistent results 1256 if ( !supportsOffsetFractions ) { 1257 position.left = round( position.left ); 1258 position.top = round( position.top ); 1259 } 1260 1261 collisionPosition = { 1262 marginLeft: marginLeft, 1263 marginTop: marginTop 1264 }; 1265 1266 $.each( [ "left", "top" ], function( i, dir ) { 1267 if ( $.ui.position[ collision[ i ] ] ) { 1268 $.ui.position[ collision[ i ] ][ dir ]( position, { 1269 targetWidth: targetWidth, 1270 targetHeight: targetHeight, 1271 elemWidth: elemWidth, 1272 elemHeight: elemHeight, 1273 collisionPosition: collisionPosition, 1274 collisionWidth: collisionWidth, 1275 collisionHeight: collisionHeight, 1276 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1277 my: options.my, 1278 at: options.at, 1279 within: within, 1280 elem: elem 1281 }); 1282 } 1283 }); 1284 1285 if ( options.using ) { 1286 // adds feedback as second argument to using callback, if present 1287 using = function( props ) { 1288 var left = targetOffset.left - position.left, 1289 right = left + targetWidth - elemWidth, 1290 top = targetOffset.top - position.top, 1291 bottom = top + targetHeight - elemHeight, 1292 feedback = { 1293 target: { 1294 element: target, 1295 left: targetOffset.left, 1296 top: targetOffset.top, 1297 width: targetWidth, 1298 height: targetHeight 1299 }, 1300 element: { 1301 element: elem, 1302 left: position.left, 1303 top: position.top, 1304 width: elemWidth, 1305 height: elemHeight 1306 }, 1307 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1308 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1309 }; 1310 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1311 feedback.horizontal = "center"; 1312 } 1313 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1314 feedback.vertical = "middle"; 1315 } 1316 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1317 feedback.important = "horizontal"; 1318 } else { 1319 feedback.important = "vertical"; 1320 } 1321 options.using.call( this, props, feedback ); 1322 }; 1323 } 1324 1325 elem.offset( $.extend( position, { using: using } ) ); 1326 }); 1327}; 1328 1329$.ui.position = { 1330 fit: { 1331 left: function( position, data ) { 1332 var within = data.within, 1333 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1334 outerWidth = within.width, 1335 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1336 overLeft = withinOffset - collisionPosLeft, 1337 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1338 newOverRight; 1339 1340 // element is wider than within 1341 if ( data.collisionWidth > outerWidth ) { 1342 // element is initially over the left side of within 1343 if ( overLeft > 0 && overRight <= 0 ) { 1344 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1345 position.left += overLeft - newOverRight; 1346 // element is initially over right side of within 1347 } else if ( overRight > 0 && overLeft <= 0 ) { 1348 position.left = withinOffset; 1349 // element is initially over both left and right sides of within 1350 } else { 1351 if ( overLeft > overRight ) { 1352 position.left = withinOffset + outerWidth - data.collisionWidth; 1353 } else { 1354 position.left = withinOffset; 1355 } 1356 } 1357 // too far left -> align with left edge 1358 } else if ( overLeft > 0 ) { 1359 position.left += overLeft; 1360 // too far right -> align with right edge 1361 } else if ( overRight > 0 ) { 1362 position.left -= overRight; 1363 // adjust based on position and margin 1364 } else { 1365 position.left = max( position.left - collisionPosLeft, position.left ); 1366 } 1367 }, 1368 top: function( position, data ) { 1369 var within = data.within, 1370 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1371 outerHeight = data.within.height, 1372 collisionPosTop = position.top - data.collisionPosition.marginTop, 1373 overTop = withinOffset - collisionPosTop, 1374 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1375 newOverBottom; 1376 1377 // element is taller than within 1378 if ( data.collisionHeight > outerHeight ) { 1379 // element is initially over the top of within 1380 if ( overTop > 0 && overBottom <= 0 ) { 1381 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1382 position.top += overTop - newOverBottom; 1383 // element is initially over bottom of within 1384 } else if ( overBottom > 0 && overTop <= 0 ) { 1385 position.top = withinOffset; 1386 // element is initially over both top and bottom of within 1387 } else { 1388 if ( overTop > overBottom ) { 1389 position.top = withinOffset + outerHeight - data.collisionHeight; 1390 } else { 1391 position.top = withinOffset; 1392 } 1393 } 1394 // too far up -> align with top 1395 } else if ( overTop > 0 ) { 1396 position.top += overTop; 1397 // too far down -> align with bottom edge 1398 } else if ( overBottom > 0 ) { 1399 position.top -= overBottom; 1400 // adjust based on position and margin 1401 } else { 1402 position.top = max( position.top - collisionPosTop, position.top ); 1403 } 1404 } 1405 }, 1406 flip: { 1407 left: function( position, data ) { 1408 var within = data.within, 1409 withinOffset = within.offset.left + within.scrollLeft, 1410 outerWidth = within.width, 1411 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1412 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1413 overLeft = collisionPosLeft - offsetLeft, 1414 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1415 myOffset = data.my[ 0 ] === "left" ? 1416 -data.elemWidth : 1417 data.my[ 0 ] === "right" ? 1418 data.elemWidth : 1419 0, 1420 atOffset = data.at[ 0 ] === "left" ? 1421 data.targetWidth : 1422 data.at[ 0 ] === "right" ? 1423 -data.targetWidth : 1424 0, 1425 offset = -2 * data.offset[ 0 ], 1426 newOverRight, 1427 newOverLeft; 1428 1429 if ( overLeft < 0 ) { 1430 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1431 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1432 position.left += myOffset + atOffset + offset; 1433 } 1434 } else if ( overRight > 0 ) { 1435 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1436 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1437 position.left += myOffset + atOffset + offset; 1438 } 1439 } 1440 }, 1441 top: function( position, data ) { 1442 var within = data.within, 1443 withinOffset = within.offset.top + within.scrollTop, 1444 outerHeight = within.height, 1445 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1446 collisionPosTop = position.top - data.collisionPosition.marginTop, 1447 overTop = collisionPosTop - offsetTop, 1448 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1449 top = data.my[ 1 ] === "top", 1450 myOffset = top ? 1451 -data.elemHeight : 1452 data.my[ 1 ] === "bottom" ? 1453 data.elemHeight : 1454 0, 1455 atOffset = data.at[ 1 ] === "top" ? 1456 data.targetHeight : 1457 data.at[ 1 ] === "bottom" ? 1458 -data.targetHeight : 1459 0, 1460 offset = -2 * data.offset[ 1 ], 1461 newOverTop, 1462 newOverBottom; 1463 if ( overTop < 0 ) { 1464 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1465 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1466 position.top += myOffset + atOffset + offset; 1467 } 1468 } else if ( overBottom > 0 ) { 1469 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1470 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1471 position.top += myOffset + atOffset + offset; 1472 } 1473 } 1474 } 1475 }, 1476 flipfit: { 1477 left: function() { 1478 $.ui.position.flip.left.apply( this, arguments ); 1479 $.ui.position.fit.left.apply( this, arguments ); 1480 }, 1481 top: function() { 1482 $.ui.position.flip.top.apply( this, arguments ); 1483 $.ui.position.fit.top.apply( this, arguments ); 1484 } 1485 } 1486}; 1487 1488// fraction support test 1489(function() { 1490 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1491 body = document.getElementsByTagName( "body" )[ 0 ], 1492 div = document.createElement( "div" ); 1493 1494 //Create a "fake body" for testing based on method used in jQuery.support 1495 testElement = document.createElement( body ? "div" : "body" ); 1496 testElementStyle = { 1497 visibility: "hidden", 1498 width: 0, 1499 height: 0, 1500 border: 0, 1501 margin: 0, 1502 background: "none" 1503 }; 1504 if ( body ) { 1505 $.extend( testElementStyle, { 1506 position: "absolute", 1507 left: "-1000px", 1508 top: "-1000px" 1509 }); 1510 } 1511 for ( i in testElementStyle ) { 1512 testElement.style[ i ] = testElementStyle[ i ]; 1513 } 1514 testElement.appendChild( div ); 1515 testElementParent = body || document.documentElement; 1516 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1517 1518 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1519 1520 offsetLeft = $( div ).offset().left; 1521 supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; 1522 1523 testElement.innerHTML = ""; 1524 testElementParent.removeChild( testElement ); 1525})(); 1526 1527})(); 1528 1529var position = $.ui.position; 1530 1531 1532/*! 1533 * jQuery UI Draggable 1.11.1 1534 * http://jqueryui.com 1535 * 1536 * Copyright 2014 jQuery Foundation and other contributors 1537 * Released under the MIT license. 1538 * http://jquery.org/license 1539 * 1540 * http://api.jqueryui.com/draggable/ 1541 */ 1542 1543 1544$.widget("ui.draggable", $.ui.mouse, { 1545 version: "1.11.1", 1546 widgetEventPrefix: "drag", 1547 options: { 1548 addClasses: true, 1549 appendTo: "parent", 1550 axis: false, 1551 connectToSortable: false, 1552 containment: false, 1553 cursor: "auto", 1554 cursorAt: false, 1555 grid: false, 1556 handle: false, 1557 helper: "original", 1558 iframeFix: false, 1559 opacity: false, 1560 refreshPositions: false, 1561 revert: false, 1562 revertDuration: 500, 1563 scope: "default", 1564 scroll: true, 1565 scrollSensitivity: 20, 1566 scrollSpeed: 20, 1567 snap: false, 1568 snapMode: "both", 1569 snapTolerance: 20, 1570 stack: false, 1571 zIndex: false, 1572 1573 // callbacks 1574 drag: null, 1575 start: null, 1576 stop: null 1577 }, 1578 _create: function() { 1579 1580 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1581 this.element[0].style.position = "relative"; 1582 } 1583 if (this.options.addClasses){ 1584 this.element.addClass("ui-draggable"); 1585 } 1586 if (this.options.disabled){ 1587 this.element.addClass("ui-draggable-disabled"); 1588 } 1589 this._setHandleClassName(); 1590 1591 this._mouseInit(); 1592 }, 1593 1594 _setOption: function( key, value ) { 1595 this._super( key, value ); 1596 if ( key === "handle" ) { 1597 this._removeHandleClassName(); 1598 this._setHandleClassName(); 1599 } 1600 }, 1601 1602 _destroy: function() { 1603 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 1604 this.destroyOnClear = true; 1605 return; 1606 } 1607 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1608 this._removeHandleClassName(); 1609 this._mouseDestroy(); 1610 }, 1611 1612 _mouseCapture: function(event) { 1613 1614 var document = this.document[ 0 ], 1615 o = this.options; 1616 1617 // support: IE9 1618 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1619 try { 1620 // Support: IE9+ 1621 // If the <body> is blurred, IE will switch windows, see #9520 1622 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { 1623 // Blur any element that currently has focus, see #4261 1624 $( document.activeElement ).blur(); 1625 } 1626 } catch ( error ) {} 1627 1628 // among others, prevent a drag on a resizable-handle 1629 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1630 return false; 1631 } 1632 1633 //Quit if we're not on a valid handle 1634 this.handle = this._getHandle(event); 1635 if (!this.handle) { 1636 return false; 1637 } 1638 1639 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1640 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1641 .css({ 1642 width: this.offsetWidth + "px", height: this.offsetHeight + "px", 1643 position: "absolute", opacity: "0.001", zIndex: 1000 1644 }) 1645 .css($(this).offset()) 1646 .appendTo("body"); 1647 }); 1648 1649 return true; 1650 1651 }, 1652 1653 _mouseStart: function(event) { 1654 1655 var o = this.options; 1656 1657 //Create and append the visible helper 1658 this.helper = this._createHelper(event); 1659 1660 this.helper.addClass("ui-draggable-dragging"); 1661 1662 //Cache the helper size 1663 this._cacheHelperProportions(); 1664 1665 //If ddmanager is used for droppables, set the global draggable 1666 if ($.ui.ddmanager) { 1667 $.ui.ddmanager.current = this; 1668 } 1669 1670 /* 1671 * - Position generation - 1672 * This block generates everything position related - it's the core of draggables. 1673 */ 1674 1675 //Cache the margins of the original element 1676 this._cacheMargins(); 1677 1678 //Store the helper's css position 1679 this.cssPosition = this.helper.css( "position" ); 1680 this.scrollParent = this.helper.scrollParent( true ); 1681 this.offsetParent = this.helper.offsetParent(); 1682 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 1683 1684 //The element's absolute position on the page minus margins 1685 this.offset = this.positionAbs = this.element.offset(); 1686 this.offset = { 1687 top: this.offset.top - this.margins.top, 1688 left: this.offset.left - this.margins.left 1689 }; 1690 1691 //Reset scroll cache 1692 this.offset.scroll = false; 1693 1694 $.extend(this.offset, { 1695 click: { //Where the click happened, relative to the element 1696 left: event.pageX - this.offset.left, 1697 top: event.pageY - this.offset.top 1698 }, 1699 parent: this._getParentOffset(), 1700 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1701 }); 1702 1703 //Generate the original position 1704 this.originalPosition = this.position = this._generatePosition( event, false ); 1705 this.originalPageX = event.pageX; 1706 this.originalPageY = event.pageY; 1707 1708 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1709 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1710 1711 //Set a containment if given in the options 1712 this._setContainment(); 1713 1714 //Trigger event + callbacks 1715 if (this._trigger("start", event) === false) { 1716 this._clear(); 1717 return false; 1718 } 1719 1720 //Recache the helper size 1721 this._cacheHelperProportions(); 1722 1723 //Prepare the droppable offsets 1724 if ($.ui.ddmanager && !o.dropBehaviour) { 1725 $.ui.ddmanager.prepareOffsets(this, event); 1726 } 1727 1728 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1729 1730 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1731 if ( $.ui.ddmanager ) { 1732 $.ui.ddmanager.dragStart(this, event); 1733 } 1734 1735 return true; 1736 }, 1737 1738 _mouseDrag: function(event, noPropagation) { 1739 // reset any necessary cached properties (see #5009) 1740 if ( this.offsetParentCssPosition === "fixed" ) { 1741 this.offset.parent = this._getParentOffset(); 1742 } 1743 1744 //Compute the helpers position 1745 this.position = this._generatePosition( event, true ); 1746 this.positionAbs = this._convertPositionTo("absolute"); 1747 1748 //Call plugins and callbacks and use the resulting position if something is returned 1749 if (!noPropagation) { 1750 var ui = this._uiHash(); 1751 if (this._trigger("drag", event, ui) === false) { 1752 this._mouseUp({}); 1753 return false; 1754 } 1755 this.position = ui.position; 1756 } 1757 1758 this.helper[ 0 ].style.left = this.position.left + "px"; 1759 this.helper[ 0 ].style.top = this.position.top + "px"; 1760 1761 if ($.ui.ddmanager) { 1762 $.ui.ddmanager.drag(this, event); 1763 } 1764 1765 return false; 1766 }, 1767 1768 _mouseStop: function(event) { 1769 1770 //If we are using droppables, inform the manager about the drop 1771 var that = this, 1772 dropped = false; 1773 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1774 dropped = $.ui.ddmanager.drop(this, event); 1775 } 1776 1777 //if a drop comes from outside (a sortable) 1778 if (this.dropped) { 1779 dropped = this.dropped; 1780 this.dropped = false; 1781 } 1782 1783 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))) { 1784 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1785 if (that._trigger("stop", event) !== false) { 1786 that._clear(); 1787 } 1788 }); 1789 } else { 1790 if (this._trigger("stop", event) !== false) { 1791 this._clear(); 1792 } 1793 } 1794 1795 return false; 1796 }, 1797 1798 _mouseUp: function(event) { 1799 //Remove frame helpers 1800 $("div.ui-draggable-iframeFix").each(function() { 1801 this.parentNode.removeChild(this); 1802 }); 1803 1804 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1805 if ( $.ui.ddmanager ) { 1806 $.ui.ddmanager.dragStop(this, event); 1807 } 1808 1809 // The interaction is over; whether or not the click resulted in a drag, focus the element 1810 this.element.focus(); 1811 1812 return $.ui.mouse.prototype._mouseUp.call(this, event); 1813 }, 1814 1815 cancel: function() { 1816 1817 if (this.helper.is(".ui-draggable-dragging")) { 1818 this._mouseUp({}); 1819 } else { 1820 this._clear(); 1821 } 1822 1823 return this; 1824 1825 }, 1826 1827 _getHandle: function(event) { 1828 return this.options.handle ? 1829 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1830 true; 1831 }, 1832 1833 _setHandleClassName: function() { 1834 this.handleElement = this.options.handle ? 1835 this.element.find( this.options.handle ) : this.element; 1836 this.handleElement.addClass( "ui-draggable-handle" ); 1837 }, 1838 1839 _removeHandleClassName: function() { 1840 this.handleElement.removeClass( "ui-draggable-handle" ); 1841 }, 1842 1843 _createHelper: function(event) { 1844 1845 var o = this.options, 1846 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[ 0 ], [ event ])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1847 1848 if (!helper.parents("body").length) { 1849 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1850 } 1851 1852 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1853 helper.css("position", "absolute"); 1854 } 1855 1856 return helper; 1857 1858 }, 1859 1860 _adjustOffsetFromHelper: function(obj) { 1861 if (typeof obj === "string") { 1862 obj = obj.split(" "); 1863 } 1864 if ($.isArray(obj)) { 1865 obj = { left: +obj[0], top: +obj[1] || 0 }; 1866 } 1867 if ("left" in obj) { 1868 this.offset.click.left = obj.left + this.margins.left; 1869 } 1870 if ("right" in obj) { 1871 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1872 } 1873 if ("top" in obj) { 1874 this.offset.click.top = obj.top + this.margins.top; 1875 } 1876 if ("bottom" in obj) { 1877 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1878 } 1879 }, 1880 1881 _isRootNode: function( element ) { 1882 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 1883 }, 1884 1885 _getParentOffset: function() { 1886 1887 //Get the offsetParent and cache its position 1888 var po = this.offsetParent.offset(), 1889 document = this.document[ 0 ]; 1890 1891 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1892 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1893 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1894 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1895 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1896 po.left += this.scrollParent.scrollLeft(); 1897 po.top += this.scrollParent.scrollTop(); 1898 } 1899 1900 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 1901 po = { top: 0, left: 0 }; 1902 } 1903 1904 return { 1905 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 1906 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 1907 }; 1908 1909 }, 1910 1911 _getRelativeOffset: function() { 1912 if ( this.cssPosition !== "relative" ) { 1913 return { top: 0, left: 0 }; 1914 } 1915 1916 var p = this.element.position(), 1917 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 1918 1919 return { 1920 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 1921 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 1922 }; 1923 1924 }, 1925 1926 _cacheMargins: function() { 1927 this.margins = { 1928 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 1929 top: (parseInt(this.element.css("marginTop"), 10) || 0), 1930 right: (parseInt(this.element.css("marginRight"), 10) || 0), 1931 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 1932 }; 1933 }, 1934 1935 _cacheHelperProportions: function() { 1936 this.helperProportions = { 1937 width: this.helper.outerWidth(), 1938 height: this.helper.outerHeight() 1939 }; 1940 }, 1941 1942 _setContainment: function() { 1943 1944 var over, c, ce, 1945 o = this.options, 1946 document = this.document[ 0 ]; 1947 1948 this.relativeContainer = null; 1949 1950 if ( !o.containment ) { 1951 this.containment = null; 1952 return; 1953 } 1954 1955 if ( o.containment === "window" ) { 1956 this.containment = [ 1957 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1958 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1959 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 1960 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1961 ]; 1962 return; 1963 } 1964 1965 if ( o.containment === "document") { 1966 this.containment = [ 1967 0, 1968 0, 1969 $( document ).width() - this.helperProportions.width - this.margins.left, 1970 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1971 ]; 1972 return; 1973 } 1974 1975 if ( o.containment.constructor === Array ) { 1976 this.containment = o.containment; 1977 return; 1978 } 1979 1980 if ( o.containment === "parent" ) { 1981 o.containment = this.helper[ 0 ].parentNode; 1982 } 1983 1984 c = $( o.containment ); 1985 ce = c[ 0 ]; 1986 1987 if ( !ce ) { 1988 return; 1989 } 1990 1991 over = c.css( "overflow" ) !== "hidden"; 1992 1993 this.containment = [ 1994 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 1995 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 1996 ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, 1997 ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom 1998 ]; 1999 this.relativeContainer = c; 2000 }, 2001 2002 _convertPositionTo: function(d, pos) { 2003 2004 if (!pos) { 2005 pos = this.position; 2006 } 2007 2008 var mod = d === "absolute" ? 1 : -1, 2009 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 2010 2011 return { 2012 top: ( 2013 pos.top + // The absolute mouse position 2014 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 2015 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 2016 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) 2017 ), 2018 left: ( 2019 pos.left + // The absolute mouse position 2020 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 2021 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 2022 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) 2023 ) 2024 }; 2025 2026 }, 2027 2028 _generatePosition: function( event, constrainPosition ) { 2029 2030 var containment, co, top, left, 2031 o = this.options, 2032 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 2033 pageX = event.pageX, 2034 pageY = event.pageY; 2035 2036 // Cache the scroll 2037 if ( !scrollIsRootNode || !this.offset.scroll ) { 2038 this.offset.scroll = { 2039 top: this.scrollParent.scrollTop(), 2040 left: this.scrollParent.scrollLeft() 2041 }; 2042 } 2043 2044 /* 2045 * - Position constraining - 2046 * Constrain the position to a mix of grid, containment. 2047 */ 2048 2049 // If we are not dragging yet, we won't check for options 2050 if ( constrainPosition ) { 2051 if ( this.containment ) { 2052 if ( this.relativeContainer ){ 2053 co = this.relativeContainer.offset(); 2054 containment = [ 2055 this.containment[ 0 ] + co.left, 2056 this.containment[ 1 ] + co.top, 2057 this.containment[ 2 ] + co.left, 2058 this.containment[ 3 ] + co.top 2059 ]; 2060 } else { 2061 containment = this.containment; 2062 } 2063 2064 if (event.pageX - this.offset.click.left < containment[0]) { 2065 pageX = containment[0] + this.offset.click.left; 2066 } 2067 if (event.pageY - this.offset.click.top < containment[1]) { 2068 pageY = containment[1] + this.offset.click.top; 2069 } 2070 if (event.pageX - this.offset.click.left > containment[2]) { 2071 pageX = containment[2] + this.offset.click.left; 2072 } 2073 if (event.pageY - this.offset.click.top > containment[3]) { 2074 pageY = containment[3] + this.offset.click.top; 2075 } 2076 } 2077 2078 if (o.grid) { 2079 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 2080 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 2081 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; 2082 2083 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 2084 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; 2085 } 2086 2087 if ( o.axis === "y" ) { 2088 pageX = this.originalPageX; 2089 } 2090 2091 if ( o.axis === "x" ) { 2092 pageY = this.originalPageY; 2093 } 2094 } 2095 2096 return { 2097 top: ( 2098 pageY - // The absolute mouse position 2099 this.offset.click.top - // Click offset (relative to the element) 2100 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 2101 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 2102 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 2103 ), 2104 left: ( 2105 pageX - // The absolute mouse position 2106 this.offset.click.left - // Click offset (relative to the element) 2107 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 2108 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 2109 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 2110 ) 2111 }; 2112 2113 }, 2114 2115 _clear: function() { 2116 this.helper.removeClass("ui-draggable-dragging"); 2117 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 2118 this.helper.remove(); 2119 } 2120 this.helper = null; 2121 this.cancelHelperRemoval = false; 2122 if ( this.destroyOnClear ) { 2123 this.destroy(); 2124 } 2125 }, 2126 2127 // From now on bulk stuff - mainly helpers 2128 2129 _trigger: function(type, event, ui) { 2130 ui = ui || this._uiHash(); 2131 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 2132 //The absolute position has to be recalculated after plugins 2133 if (type === "drag") { 2134 this.positionAbs = this._convertPositionTo("absolute"); 2135 } 2136 return $.Widget.prototype._trigger.call(this, type, event, ui); 2137 }, 2138 2139 plugins: {}, 2140 2141 _uiHash: function() { 2142 return { 2143 helper: this.helper, 2144 position: this.position, 2145 originalPosition: this.originalPosition, 2146 offset: this.positionAbs 2147 }; 2148 } 2149 2150}); 2151 2152$.ui.plugin.add("draggable", "connectToSortable", { 2153 start: function( event, ui, inst ) { 2154 2155 var o = inst.options, 2156 uiSortable = $.extend({}, ui, { item: inst.element }); 2157 inst.sortables = []; 2158 $(o.connectToSortable).each(function() { 2159 var sortable = $( this ).sortable( "instance" ); 2160 if (sortable && !sortable.options.disabled) { 2161 inst.sortables.push({ 2162 instance: sortable, 2163 shouldRevert: sortable.options.revert 2164 }); 2165 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). 2166 sortable._trigger("activate", event, uiSortable); 2167 } 2168 }); 2169 2170 }, 2171 stop: function( event, ui, inst ) { 2172 2173 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2174 var uiSortable = $.extend( {}, ui, { 2175 item: inst.element 2176 }); 2177 2178 $.each(inst.sortables, function() { 2179 if (this.instance.isOver) { 2180 2181 this.instance.isOver = 0; 2182 2183 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2184 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2185 2186 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 2187 if (this.shouldRevert) { 2188 this.instance.options.revert = this.shouldRevert; 2189 } 2190 2191 //Trigger the stop of the sortable 2192 this.instance._mouseStop(event); 2193 2194 this.instance.options.helper = this.instance.options._helper; 2195 2196 //If the helper has been the original item, restore properties in the sortable 2197 if (inst.options.helper === "original") { 2198 this.instance.currentItem.css({ top: "auto", left: "auto" }); 2199 } 2200 2201 } else { 2202 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2203 this.instance._trigger("deactivate", event, uiSortable); 2204 } 2205 2206 }); 2207 2208 }, 2209 drag: function( event, ui, inst ) { 2210 2211 var that = this; 2212 2213 $.each(inst.sortables, function() { 2214 2215 var innermostIntersecting = false, 2216 thisSortable = this; 2217 2218 //Copy over some variables to allow calling the sortable's native _intersectsWith 2219 this.instance.positionAbs = inst.positionAbs; 2220 this.instance.helperProportions = inst.helperProportions; 2221 this.instance.offset.click = inst.offset.click; 2222 2223 if (this.instance._intersectsWith(this.instance.containerCache)) { 2224 innermostIntersecting = true; 2225 $.each(inst.sortables, function() { 2226 this.instance.positionAbs = inst.positionAbs; 2227 this.instance.helperProportions = inst.helperProportions; 2228 this.instance.offset.click = inst.offset.click; 2229 if (this !== thisSortable && 2230 this.instance._intersectsWith(this.instance.containerCache) && 2231 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 2232 ) { 2233 innermostIntersecting = false; 2234 } 2235 return innermostIntersecting; 2236 }); 2237 } 2238 2239 if (innermostIntersecting) { 2240 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 2241 if (!this.instance.isOver) { 2242 2243 this.instance.isOver = 1; 2244 //Now we fake the start of dragging for the sortable instance, 2245 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 2246 //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) 2247 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 2248 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 2249 this.instance.options.helper = function() { return ui.helper[0]; }; 2250 2251 event.target = this.instance.currentItem[0]; 2252 this.instance._mouseCapture(event, true); 2253 this.instance._mouseStart(event, true, true); 2254 2255 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 2256 this.instance.offset.click.top = inst.offset.click.top; 2257 this.instance.offset.click.left = inst.offset.click.left; 2258 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 2259 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 2260 2261 inst._trigger("toSortable", event); 2262 inst.dropped = this.instance.element; //draggable revert needs that 2263 //hack so receive/update callbacks work (mostly) 2264 inst.currentItem = inst.element; 2265 this.instance.fromOutside = inst; 2266 2267 } 2268 2269 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable 2270 if (this.instance.currentItem) { 2271 this.instance._mouseDrag(event); 2272 } 2273 2274 } else { 2275 2276 //If it doesn't intersect with the sortable, and it intersected before, 2277 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2278 if (this.instance.isOver) { 2279 2280 this.instance.isOver = 0; 2281 this.instance.cancelHelperRemoval = true; 2282 2283 //Prevent reverting on this forced stop 2284 this.instance.options.revert = false; 2285 2286 // The out event needs to be triggered independently 2287 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 2288 2289 this.instance._mouseStop(event, true); 2290 this.instance.options.helper = this.instance.options._helper; 2291 2292 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2293 this.instance.currentItem.remove(); 2294 if (this.instance.placeholder) { 2295 this.instance.placeholder.remove(); 2296 } 2297 2298 inst._trigger("fromSortable", event); 2299 inst.dropped = false; //draggable revert needs that 2300 } 2301 2302 } 2303 2304 }); 2305 2306 } 2307}); 2308 2309$.ui.plugin.add("draggable", "cursor", { 2310 start: function( event, ui, instance ) { 2311 var t = $( "body" ), 2312 o = instance.options; 2313 2314 if (t.css("cursor")) { 2315 o._cursor = t.css("cursor"); 2316 } 2317 t.css("cursor", o.cursor); 2318 }, 2319 stop: function( event, ui, instance ) { 2320 var o = instance.options; 2321 if (o._cursor) { 2322 $("body").css("cursor", o._cursor); 2323 } 2324 } 2325}); 2326 2327$.ui.plugin.add("draggable", "opacity", { 2328 start: function( event, ui, instance ) { 2329 var t = $( ui.helper ), 2330 o = instance.options; 2331 if (t.css("opacity")) { 2332 o._opacity = t.css("opacity"); 2333 } 2334 t.css("opacity", o.opacity); 2335 }, 2336 stop: function( event, ui, instance ) { 2337 var o = instance.options; 2338 if (o._opacity) { 2339 $(ui.helper).css("opacity", o._opacity); 2340 } 2341 } 2342}); 2343 2344$.ui.plugin.add("draggable", "scroll", { 2345 start: function( event, ui, i ) { 2346 if ( !i.scrollParentNotHidden ) { 2347 i.scrollParentNotHidden = i.helper.scrollParent( false ); 2348 } 2349 2350 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 2351 i.overflowOffset = i.scrollParentNotHidden.offset(); 2352 } 2353 }, 2354 drag: function( event, ui, i ) { 2355 2356 var o = i.options, 2357 scrolled = false, 2358 scrollParent = i.scrollParentNotHidden[ 0 ], 2359 document = i.document[ 0 ]; 2360 2361 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 2362 if ( !o.axis || o.axis !== "x" ) { 2363 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { 2364 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 2365 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 2366 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 2367 } 2368 } 2369 2370 if ( !o.axis || o.axis !== "y" ) { 2371 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { 2372 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 2373 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 2374 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 2375 } 2376 } 2377 2378 } else { 2379 2380 if (!o.axis || o.axis !== "x") { 2381 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 2382 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2383 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 2384 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2385 } 2386 } 2387 2388 if (!o.axis || o.axis !== "y") { 2389 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 2390 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2391 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 2392 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2393 } 2394 } 2395 2396 } 2397 2398 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 2399 $.ui.ddmanager.prepareOffsets(i, event); 2400 } 2401 2402 } 2403}); 2404 2405$.ui.plugin.add("draggable", "snap", { 2406 start: function( event, ui, i ) { 2407 2408 var o = i.options; 2409 2410 i.snapElements = []; 2411 2412 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 2413 var $t = $(this), 2414 $o = $t.offset(); 2415 if (this !== i.element[0]) { 2416 i.snapElements.push({ 2417 item: this, 2418 width: $t.outerWidth(), height: $t.outerHeight(), 2419 top: $o.top, left: $o.left 2420 }); 2421 } 2422 }); 2423 2424 }, 2425 drag: function( event, ui, inst ) { 2426 2427 var ts, bs, ls, rs, l, r, t, b, i, first, 2428 o = inst.options, 2429 d = o.snapTolerance, 2430 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2431 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2432 2433 for (i = inst.snapElements.length - 1; i >= 0; i--){ 2434 2435 l = inst.snapElements[i].left; 2436 r = l + inst.snapElements[i].width; 2437 t = inst.snapElements[i].top; 2438 b = t + inst.snapElements[i].height; 2439 2440 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 2441 if (inst.snapElements[i].snapping) { 2442 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2443 } 2444 inst.snapElements[i].snapping = false; 2445 continue; 2446 } 2447 2448 if (o.snapMode !== "inner") { 2449 ts = Math.abs(t - y2) <= d; 2450 bs = Math.abs(b - y1) <= d; 2451 ls = Math.abs(l - x2) <= d; 2452 rs = Math.abs(r - x1) <= d; 2453 if (ts) { 2454 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2455 } 2456 if (bs) { 2457 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2458 } 2459 if (ls) { 2460 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2461 } 2462 if (rs) { 2463 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2464 } 2465 } 2466 2467 first = (ts || bs || ls || rs); 2468 2469 if (o.snapMode !== "outer") { 2470 ts = Math.abs(t - y1) <= d; 2471 bs = Math.abs(b - y2) <= d; 2472 ls = Math.abs(l - x1) <= d; 2473 rs = Math.abs(r - x2) <= d; 2474 if (ts) { 2475 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2476 } 2477 if (bs) { 2478 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2479 } 2480 if (ls) { 2481 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2482 } 2483 if (rs) { 2484 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2485 } 2486 } 2487 2488 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 2489 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2490 } 2491 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2492 2493 } 2494 2495 } 2496}); 2497 2498$.ui.plugin.add("draggable", "stack", { 2499 start: function( event, ui, instance ) { 2500 var min, 2501 o = instance.options, 2502 group = $.makeArray($(o.stack)).sort(function(a, b) { 2503 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 2504 }); 2505 2506 if (!group.length) { return; } 2507 2508 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 2509 $(group).each(function(i) { 2510 $(this).css("zIndex", min + i); 2511 }); 2512 this.css("zIndex", (min + group.length)); 2513 } 2514}); 2515 2516$.ui.plugin.add("draggable", "zIndex", { 2517 start: function( event, ui, instance ) { 2518 var t = $( ui.helper ), 2519 o = instance.options; 2520 2521 if (t.css("zIndex")) { 2522 o._zIndex = t.css("zIndex"); 2523 } 2524 t.css("zIndex", o.zIndex); 2525 }, 2526 stop: function( event, ui, instance ) { 2527 var o = instance.options; 2528 2529 if (o._zIndex) { 2530 $(ui.helper).css("zIndex", o._zIndex); 2531 } 2532 } 2533}); 2534 2535var draggable = $.ui.draggable; 2536 2537 2538/*! 2539 * jQuery UI Droppable 1.11.1 2540 * http://jqueryui.com 2541 * 2542 * Copyright 2014 jQuery Foundation and other contributors 2543 * Released under the MIT license. 2544 * http://jquery.org/license 2545 * 2546 * http://api.jqueryui.com/droppable/ 2547 */ 2548 2549 2550$.widget( "ui.droppable", { 2551 version: "1.11.1", 2552 widgetEventPrefix: "drop", 2553 options: { 2554 accept: "*", 2555 activeClass: false, 2556 addClasses: true, 2557 greedy: false, 2558 hoverClass: false, 2559 scope: "default", 2560 tolerance: "intersect", 2561 2562 // callbacks 2563 activate: null, 2564 deactivate: null, 2565 drop: null, 2566 out: null, 2567 over: null 2568 }, 2569 _create: function() { 2570 2571 var proportions, 2572 o = this.options, 2573 accept = o.accept; 2574 2575 this.isover = false; 2576 this.isout = true; 2577 2578 this.accept = $.isFunction( accept ) ? accept : function( d ) { 2579 return d.is( accept ); 2580 }; 2581 2582 this.proportions = function( /* valueToWrite */ ) { 2583 if ( arguments.length ) { 2584 // Store the droppable's proportions 2585 proportions = arguments[ 0 ]; 2586 } else { 2587 // Retrieve or derive the droppable's proportions 2588 return proportions ? 2589 proportions : 2590 proportions = { 2591 width: this.element[ 0 ].offsetWidth, 2592 height: this.element[ 0 ].offsetHeight 2593 }; 2594 } 2595 }; 2596 2597 this._addToManager( o.scope ); 2598 2599 o.addClasses && this.element.addClass( "ui-droppable" ); 2600 2601 }, 2602 2603 _addToManager: function( scope ) { 2604 // Add the reference and positions to the manager 2605 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 2606 $.ui.ddmanager.droppables[ scope ].push( this ); 2607 }, 2608 2609 _splice: function( drop ) { 2610 var i = 0; 2611 for ( ; i < drop.length; i++ ) { 2612 if ( drop[ i ] === this ) { 2613 drop.splice( i, 1 ); 2614 } 2615 } 2616 }, 2617 2618 _destroy: function() { 2619 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 2620 2621 this._splice( drop ); 2622 2623 this.element.removeClass( "ui-droppable ui-droppable-disabled" ); 2624 }, 2625 2626 _setOption: function( key, value ) { 2627 2628 if ( key === "accept" ) { 2629 this.accept = $.isFunction( value ) ? value : function( d ) { 2630 return d.is( value ); 2631 }; 2632 } else if ( key === "scope" ) { 2633 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 2634 2635 this._splice( drop ); 2636 this._addToManager( value ); 2637 } 2638 2639 this._super( key, value ); 2640 }, 2641 2642 _activate: function( event ) { 2643 var draggable = $.ui.ddmanager.current; 2644 if ( this.options.activeClass ) { 2645 this.element.addClass( this.options.activeClass ); 2646 } 2647 if ( draggable ){ 2648 this._trigger( "activate", event, this.ui( draggable ) ); 2649 } 2650 }, 2651 2652 _deactivate: function( event ) { 2653 var draggable = $.ui.ddmanager.current; 2654 if ( this.options.activeClass ) { 2655 this.element.removeClass( this.options.activeClass ); 2656 } 2657 if ( draggable ){ 2658 this._trigger( "deactivate", event, this.ui( draggable ) ); 2659 } 2660 }, 2661 2662 _over: function( event ) { 2663 2664 var draggable = $.ui.ddmanager.current; 2665 2666 // Bail if draggable and droppable are same element 2667 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2668 return; 2669 } 2670 2671 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2672 if ( this.options.hoverClass ) { 2673 this.element.addClass( this.options.hoverClass ); 2674 } 2675 this._trigger( "over", event, this.ui( draggable ) ); 2676 } 2677 2678 }, 2679 2680 _out: function( event ) { 2681 2682 var draggable = $.ui.ddmanager.current; 2683 2684 // Bail if draggable and droppable are same element 2685 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2686 return; 2687 } 2688 2689 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2690 if ( this.options.hoverClass ) { 2691 this.element.removeClass( this.options.hoverClass ); 2692 } 2693 this._trigger( "out", event, this.ui( draggable ) ); 2694 } 2695 2696 }, 2697 2698 _drop: function( event, custom ) { 2699 2700 var draggable = custom || $.ui.ddmanager.current, 2701 childrenIntersection = false; 2702 2703 // Bail if draggable and droppable are same element 2704 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 2705 return false; 2706 } 2707 2708 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { 2709 var inst = $( this ).droppable( "instance" ); 2710 if ( 2711 inst.options.greedy && 2712 !inst.options.disabled && 2713 inst.options.scope === draggable.options.scope && 2714 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && 2715 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) 2716 ) { childrenIntersection = true; return false; } 2717 }); 2718 if ( childrenIntersection ) { 2719 return false; 2720 } 2721 2722 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2723 if ( this.options.activeClass ) { 2724 this.element.removeClass( this.options.activeClass ); 2725 } 2726 if ( this.options.hoverClass ) { 2727 this.element.removeClass( this.options.hoverClass ); 2728 } 2729 this._trigger( "drop", event, this.ui( draggable ) ); 2730 return this.element; 2731 } 2732 2733 return false; 2734 2735 }, 2736 2737 ui: function( c ) { 2738 return { 2739 draggable: ( c.currentItem || c.element ), 2740 helper: c.helper, 2741 position: c.position, 2742 offset: c.positionAbs 2743 }; 2744 } 2745 2746}); 2747 2748$.ui.intersect = (function() { 2749 function isOverAxis( x, reference, size ) { 2750 return ( x >= reference ) && ( x < ( reference + size ) ); 2751 } 2752 2753 return function( draggable, droppable, toleranceMode, event ) { 2754 2755 if ( !droppable.offset ) { 2756 return false; 2757 } 2758 2759 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left, 2760 y1 = ( draggable.positionAbs || draggable.position.absolute ).top, 2761 x2 = x1 + draggable.helperProportions.width, 2762 y2 = y1 + draggable.helperProportions.height, 2763 l = droppable.offset.left, 2764 t = droppable.offset.top, 2765 r = l + droppable.proportions().width, 2766 b = t + droppable.proportions().height; 2767 2768 switch ( toleranceMode ) { 2769 case "fit": 2770 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 2771 case "intersect": 2772 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 2773 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 2774 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 2775 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 2776 case "pointer": 2777 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); 2778 case "touch": 2779 return ( 2780 ( y1 >= t && y1 <= b ) || // Top edge touching 2781 ( y2 >= t && y2 <= b ) || // Bottom edge touching 2782 ( y1 < t && y2 > b ) // Surrounded vertically 2783 ) && ( 2784 ( x1 >= l && x1 <= r ) || // Left edge touching 2785 ( x2 >= l && x2 <= r ) || // Right edge touching 2786 ( x1 < l && x2 > r ) // Surrounded horizontally 2787 ); 2788 default: 2789 return false; 2790 } 2791 }; 2792})(); 2793 2794/* 2795 This manager tracks offsets of draggables and droppables 2796*/ 2797$.ui.ddmanager = { 2798 current: null, 2799 droppables: { "default": [] }, 2800 prepareOffsets: function( t, event ) { 2801 2802 var i, j, 2803 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 2804 type = event ? event.type : null, // workaround for #2317 2805 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 2806 2807 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 2808 2809 // No disabled and non-accepted 2810 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { 2811 continue; 2812 } 2813 2814 // Filter out elements in the current dragged item 2815 for ( j = 0; j < list.length; j++ ) { 2816 if ( list[ j ] === m[ i ].element[ 0 ] ) { 2817 m[ i ].proportions().height = 0; 2818 continue droppablesLoop; 2819 } 2820 } 2821 2822 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 2823 if ( !m[ i ].visible ) { 2824 continue; 2825 } 2826 2827 // Activate the droppable if used directly from draggables 2828 if ( type === "mousedown" ) { 2829 m[ i ]._activate.call( m[ i ], event ); 2830 } 2831 2832 m[ i ].offset = m[ i ].element.offset(); 2833 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 2834 2835 } 2836 2837 }, 2838 drop: function( draggable, event ) { 2839 2840 var dropped = false; 2841 // Create a copy of the droppables in case the list changes during the drop (#9116) 2842 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 2843 2844 if ( !this.options ) { 2845 return; 2846 } 2847 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 2848 dropped = this._drop.call( this, event ) || dropped; 2849 } 2850 2851 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 2852 this.isout = true; 2853 this.isover = false; 2854 this._deactivate.call( this, event ); 2855 } 2856 2857 }); 2858 return dropped; 2859 2860 }, 2861 dragStart: function( draggable, event ) { 2862 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2863 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2864 if ( !draggable.options.refreshPositions ) { 2865 $.ui.ddmanager.prepareOffsets( draggable, event ); 2866 } 2867 }); 2868 }, 2869 drag: function( draggable, event ) { 2870 2871 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2872 if ( draggable.options.refreshPositions ) { 2873 $.ui.ddmanager.prepareOffsets( draggable, event ); 2874 } 2875 2876 // Run through all droppables and check their positions based on specific tolerance options 2877 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 2878 2879 if ( this.options.disabled || this.greedyChild || !this.visible ) { 2880 return; 2881 } 2882 2883 var parentInstance, scope, parent, 2884 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 2885 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); 2886 if ( !c ) { 2887 return; 2888 } 2889 2890 if ( this.options.greedy ) { 2891 // find droppable parents with same scope 2892 scope = this.options.scope; 2893 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { 2894 return $( this ).droppable( "instance" ).options.scope === scope; 2895 }); 2896 2897 if ( parent.length ) { 2898 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 2899 parentInstance.greedyChild = ( c === "isover" ); 2900 } 2901 } 2902 2903 // we just moved into a greedy child 2904 if ( parentInstance && c === "isover" ) { 2905 parentInstance.isover = false; 2906 parentInstance.isout = true; 2907 parentInstance._out.call( parentInstance, event ); 2908 } 2909 2910 this[ c ] = true; 2911 this[c === "isout" ? "isover" : "isout"] = false; 2912 this[c === "isover" ? "_over" : "_out"].call( this, event ); 2913 2914 // we just moved out of a greedy child 2915 if ( parentInstance && c === "isout" ) { 2916 parentInstance.isout = false; 2917 parentInstance.isover = true; 2918 parentInstance._over.call( parentInstance, event ); 2919 } 2920 }); 2921 2922 }, 2923 dragStop: function( draggable, event ) { 2924 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2925 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2926 if ( !draggable.options.refreshPositions ) { 2927 $.ui.ddmanager.prepareOffsets( draggable, event ); 2928 } 2929 } 2930}; 2931 2932var droppable = $.ui.droppable; 2933 2934 2935/*! 2936 * jQuery UI Resizable 1.11.1 2937 * http://jqueryui.com 2938 * 2939 * Copyright 2014 jQuery Foundation and other contributors 2940 * Released under the MIT license. 2941 * http://jquery.org/license 2942 * 2943 * http://api.jqueryui.com/resizable/ 2944 */ 2945 2946 2947$.widget("ui.resizable", $.ui.mouse, { 2948 version: "1.11.1", 2949 widgetEventPrefix: "resize", 2950 options: { 2951 alsoResize: false, 2952 animate: false, 2953 animateDuration: "slow", 2954 animateEasing: "swing", 2955 aspectRatio: false, 2956 autoHide: false, 2957 containment: false, 2958 ghost: false, 2959 grid: false, 2960 handles: "e,s,se", 2961 helper: false, 2962 maxHeight: null, 2963 maxWidth: null, 2964 minHeight: 10, 2965 minWidth: 10, 2966 // See #7960 2967 zIndex: 90, 2968 2969 // callbacks 2970 resize: null, 2971 start: null, 2972 stop: null 2973 }, 2974 2975 _num: function( value ) { 2976 return parseInt( value, 10 ) || 0; 2977 }, 2978 2979 _isNumber: function( value ) { 2980 return !isNaN( parseInt( value, 10 ) ); 2981 }, 2982 2983 _hasScroll: function( el, a ) { 2984 2985 if ( $( el ).css( "overflow" ) === "hidden") { 2986 return false; 2987 } 2988 2989 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 2990 has = false; 2991 2992 if ( el[ scroll ] > 0 ) { 2993 return true; 2994 } 2995 2996 // TODO: determine which cases actually cause this to happen 2997 // if the element doesn't have the scroll set, see if it's possible to 2998 // set the scroll 2999 el[ scroll ] = 1; 3000 has = ( el[ scroll ] > 0 ); 3001 el[ scroll ] = 0; 3002 return has; 3003 }, 3004 3005 _create: function() { 3006 3007 var n, i, handle, axis, hname, 3008 that = this, 3009 o = this.options; 3010 this.element.addClass("ui-resizable"); 3011 3012 $.extend(this, { 3013 _aspectRatio: !!(o.aspectRatio), 3014 aspectRatio: o.aspectRatio, 3015 originalElement: this.element, 3016 _proportionallyResizeElements: [], 3017 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 3018 }); 3019 3020 // Wrap the element if it cannot hold child nodes 3021 if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 3022 3023 this.element.wrap( 3024 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 3025 position: this.element.css("position"), 3026 width: this.element.outerWidth(), 3027 height: this.element.outerHeight(), 3028 top: this.element.css("top"), 3029 left: this.element.css("left") 3030 }) 3031 ); 3032 3033 this.element = this.element.parent().data( 3034 "ui-resizable", this.element.resizable( "instance" ) 3035 ); 3036 3037 this.elementIsWrapper = true; 3038 3039 this.element.css({ 3040 marginLeft: this.originalElement.css("marginLeft"), 3041 marginTop: this.originalElement.css("marginTop"), 3042 marginRight: this.originalElement.css("marginRight"), 3043 marginBottom: this.originalElement.css("marginBottom") 3044 }); 3045 this.originalElement.css({ 3046 marginLeft: 0, 3047 marginTop: 0, 3048 marginRight: 0, 3049 marginBottom: 0 3050 }); 3051 // support: Safari 3052 // Prevent Safari textarea resize 3053 this.originalResizeStyle = this.originalElement.css("resize"); 3054 this.originalElement.css("resize", "none"); 3055 3056 this._proportionallyResizeElements.push( this.originalElement.css({ 3057 position: "static", 3058 zoom: 1, 3059 display: "block" 3060 }) ); 3061 3062 // support: IE9 3063 // avoid IE jump (hard set the margin) 3064 this.originalElement.css({ margin: this.originalElement.css("margin") }); 3065 3066 this._proportionallyResize(); 3067 } 3068 3069 this.handles = o.handles || 3070 ( !$(".ui-resizable-handle", this.element).length ? 3071 "e,s,se" : { 3072 n: ".ui-resizable-n", 3073 e: ".ui-resizable-e", 3074 s: ".ui-resizable-s", 3075 w: ".ui-resizable-w", 3076 se: ".ui-resizable-se", 3077 sw: ".ui-resizable-sw", 3078 ne: ".ui-resizable-ne", 3079 nw: ".ui-resizable-nw" 3080 } ); 3081 3082 if (this.handles.constructor === String) { 3083 3084 if ( this.handles === "all") { 3085 this.handles = "n,e,s,w,se,sw,ne,nw"; 3086 } 3087 3088 n = this.handles.split(","); 3089 this.handles = {}; 3090 3091 for (i = 0; i < n.length; i++) { 3092 3093 handle = $.trim(n[i]); 3094 hname = "ui-resizable-" + handle; 3095 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 3096 3097 axis.css({ zIndex: o.zIndex }); 3098 3099 // TODO : What's going on here? 3100 if ("se" === handle) { 3101 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 3102 } 3103 3104 this.handles[handle] = ".ui-resizable-" + handle; 3105 this.element.append(axis); 3106 } 3107 3108 } 3109 3110 this._renderAxis = function(target) { 3111 3112 var i, axis, padPos, padWrapper; 3113 3114 target = target || this.element; 3115 3116 for (i in this.handles) { 3117 3118 if (this.handles[i].constructor === String) { 3119 this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); 3120 } 3121 3122 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 3123 3124 axis = $(this.handles[i], this.element); 3125 3126 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 3127 3128 padPos = [ "padding", 3129 /ne|nw|n/.test(i) ? "Top" : 3130 /se|sw|s/.test(i) ? "Bottom" : 3131 /^e$/.test(i) ? "Right" : "Left" ].join(""); 3132 3133 target.css(padPos, padWrapper); 3134 3135 this._proportionallyResize(); 3136 3137 } 3138 3139 // TODO: What's that good for? There's not anything to be executed left 3140 if (!$(this.handles[i]).length) { 3141 continue; 3142 } 3143 } 3144 }; 3145 3146 // TODO: make renderAxis a prototype function 3147 this._renderAxis(this.element); 3148 3149 this._handles = $(".ui-resizable-handle", this.element) 3150 .disableSelection(); 3151 3152 this._handles.mouseover(function() { 3153 if (!that.resizing) { 3154 if (this.className) { 3155 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 3156 } 3157 that.axis = axis && axis[1] ? axis[1] : "se"; 3158 } 3159 }); 3160 3161 if (o.autoHide) { 3162 this._handles.hide(); 3163 $(this.element) 3164 .addClass("ui-resizable-autohide") 3165 .mouseenter(function() { 3166 if (o.disabled) { 3167 return; 3168 } 3169 $(this).removeClass("ui-resizable-autohide"); 3170 that._handles.show(); 3171 }) 3172 .mouseleave(function() { 3173 if (o.disabled) { 3174 return; 3175 } 3176 if (!that.resizing) { 3177 $(this).addClass("ui-resizable-autohide"); 3178 that._handles.hide(); 3179 } 3180 }); 3181 } 3182 3183 this._mouseInit(); 3184 3185 }, 3186 3187 _destroy: function() { 3188 3189 this._mouseDestroy(); 3190 3191 var wrapper, 3192 _destroy = function(exp) { 3193 $(exp) 3194 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 3195 .removeData("resizable") 3196 .removeData("ui-resizable") 3197 .unbind(".resizable") 3198 .find(".ui-resizable-handle") 3199 .remove(); 3200 }; 3201 3202 // TODO: Unwrap at same DOM position 3203 if (this.elementIsWrapper) { 3204 _destroy(this.element); 3205 wrapper = this.element; 3206 this.originalElement.css({ 3207 position: wrapper.css("position"), 3208 width: wrapper.outerWidth(), 3209 height: wrapper.outerHeight(), 3210 top: wrapper.css("top"), 3211 left: wrapper.css("left") 3212 }).insertAfter( wrapper ); 3213 wrapper.remove(); 3214 } 3215 3216 this.originalElement.css("resize", this.originalResizeStyle); 3217 _destroy(this.originalElement); 3218 3219 return this; 3220 }, 3221 3222 _mouseCapture: function(event) { 3223 var i, handle, 3224 capture = false; 3225 3226 for (i in this.handles) { 3227 handle = $(this.handles[i])[0]; 3228 if (handle === event.target || $.contains(handle, event.target)) { 3229 capture = true; 3230 } 3231 } 3232 3233 return !this.options.disabled && capture; 3234 }, 3235 3236 _mouseStart: function(event) { 3237 3238 var curleft, curtop, cursor, 3239 o = this.options, 3240 el = this.element; 3241 3242 this.resizing = true; 3243 3244 this._renderProxy(); 3245 3246 curleft = this._num(this.helper.css("left")); 3247 curtop = this._num(this.helper.css("top")); 3248 3249 if (o.containment) { 3250 curleft += $(o.containment).scrollLeft() || 0; 3251 curtop += $(o.containment).scrollTop() || 0; 3252 } 3253 3254 this.offset = this.helper.offset(); 3255 this.position = { left: curleft, top: curtop }; 3256 3257 this.size = this._helper ? { 3258 width: this.helper.width(), 3259 height: this.helper.height() 3260 } : { 3261 width: el.width(), 3262 height: el.height() 3263 }; 3264 3265 this.originalSize = this._helper ? { 3266 width: el.outerWidth(), 3267 height: el.outerHeight() 3268 } : { 3269 width: el.width(), 3270 height: el.height() 3271 }; 3272 3273 this.sizeDiff = { 3274 width: el.outerWidth() - el.width(), 3275 height: el.outerHeight() - el.height() 3276 }; 3277 3278 this.originalPosition = { left: curleft, top: curtop }; 3279 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 3280 3281 this.aspectRatio = (typeof o.aspectRatio === "number") ? 3282 o.aspectRatio : 3283 ((this.originalSize.width / this.originalSize.height) || 1); 3284 3285 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 3286 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 3287 3288 el.addClass("ui-resizable-resizing"); 3289 this._propagate("start", event); 3290 return true; 3291 }, 3292 3293 _mouseDrag: function(event) { 3294 3295 var data, props, 3296 smp = this.originalMousePosition, 3297 a = this.axis, 3298 dx = (event.pageX - smp.left) || 0, 3299 dy = (event.pageY - smp.top) || 0, 3300 trigger = this._change[a]; 3301 3302 this._updatePrevProperties(); 3303 3304 if (!trigger) { 3305 return false; 3306 } 3307 3308 data = trigger.apply(this, [ event, dx, dy ]); 3309 3310 this._updateVirtualBoundaries(event.shiftKey); 3311 if (this._aspectRatio || event.shiftKey) { 3312 data = this._updateRatio(data, event); 3313 } 3314 3315 data = this._respectSize(data, event); 3316 3317 this._updateCache(data); 3318 3319 this._propagate("resize", event); 3320 3321 props = this._applyChanges(); 3322 3323 if ( !this._helper && this._proportionallyResizeElements.length ) { 3324 this._proportionallyResize(); 3325 } 3326 3327 if ( !$.isEmptyObject( props ) ) { 3328 this._updatePrevProperties(); 3329 this._trigger( "resize", event, this.ui() ); 3330 this._applyChanges(); 3331 } 3332 3333 return false; 3334 }, 3335 3336 _mouseStop: function(event) { 3337 3338 this.resizing = false; 3339 var pr, ista, soffseth, soffsetw, s, left, top, 3340 o = this.options, that = this; 3341 3342 if (this._helper) { 3343 3344 pr = this._proportionallyResizeElements; 3345 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 3346 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; 3347 soffsetw = ista ? 0 : that.sizeDiff.width; 3348 3349 s = { 3350 width: (that.helper.width() - soffsetw), 3351 height: (that.helper.height() - soffseth) 3352 }; 3353 left = (parseInt(that.element.css("left"), 10) + 3354 (that.position.left - that.originalPosition.left)) || null; 3355 top = (parseInt(that.element.css("top"), 10) + 3356 (that.position.top - that.originalPosition.top)) || null; 3357 3358 if (!o.animate) { 3359 this.element.css($.extend(s, { top: top, left: left })); 3360 } 3361 3362 that.helper.height(that.size.height); 3363 that.helper.width(that.size.width); 3364 3365 if (this._helper && !o.animate) { 3366 this._proportionallyResize(); 3367 } 3368 } 3369 3370 $("body").css("cursor", "auto"); 3371 3372 this.element.removeClass("ui-resizable-resizing"); 3373 3374 this._propagate("stop", event); 3375 3376 if (this._helper) { 3377 this.helper.remove(); 3378 } 3379 3380 return false; 3381 3382 }, 3383 3384 _updatePrevProperties: function() { 3385 this.prevPosition = { 3386 top: this.position.top, 3387 left: this.position.left 3388 }; 3389 this.prevSize = { 3390 width: this.size.width, 3391 height: this.size.height 3392 }; 3393 }, 3394 3395 _applyChanges: function() { 3396 var props = {}; 3397 3398 if ( this.position.top !== this.prevPosition.top ) { 3399 props.top = this.position.top + "px"; 3400 } 3401 if ( this.position.left !== this.prevPosition.left ) { 3402 props.left = this.position.left + "px"; 3403 } 3404 if ( this.size.width !== this.prevSize.width ) { 3405 props.width = this.size.width + "px"; 3406 } 3407 if ( this.size.height !== this.prevSize.height ) { 3408 props.height = this.size.height + "px"; 3409 } 3410 3411 this.helper.css( props ); 3412 3413 return props; 3414 }, 3415 3416 _updateVirtualBoundaries: function(forceAspectRatio) { 3417 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 3418 o = this.options; 3419 3420 b = { 3421 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, 3422 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, 3423 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, 3424 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity 3425 }; 3426 3427 if (this._aspectRatio || forceAspectRatio) { 3428 pMinWidth = b.minHeight * this.aspectRatio; 3429 pMinHeight = b.minWidth / this.aspectRatio; 3430 pMaxWidth = b.maxHeight * this.aspectRatio; 3431 pMaxHeight = b.maxWidth / this.aspectRatio; 3432 3433 if (pMinWidth > b.minWidth) { 3434 b.minWidth = pMinWidth; 3435 } 3436 if (pMinHeight > b.minHeight) { 3437 b.minHeight = pMinHeight; 3438 } 3439 if (pMaxWidth < b.maxWidth) { 3440 b.maxWidth = pMaxWidth; 3441 } 3442 if (pMaxHeight < b.maxHeight) { 3443 b.maxHeight = pMaxHeight; 3444 } 3445 } 3446 this._vBoundaries = b; 3447 }, 3448 3449 _updateCache: function(data) { 3450 this.offset = this.helper.offset(); 3451 if (this._isNumber(data.left)) { 3452 this.position.left = data.left; 3453 } 3454 if (this._isNumber(data.top)) { 3455 this.position.top = data.top; 3456 } 3457 if (this._isNumber(data.height)) { 3458 this.size.height = data.height; 3459 } 3460 if (this._isNumber(data.width)) { 3461 this.size.width = data.width; 3462 } 3463 }, 3464 3465 _updateRatio: function( data ) { 3466 3467 var cpos = this.position, 3468 csize = this.size, 3469 a = this.axis; 3470 3471 if (this._isNumber(data.height)) { 3472 data.width = (data.height * this.aspectRatio); 3473 } else if (this._isNumber(data.width)) { 3474 data.height = (data.width / this.aspectRatio); 3475 } 3476 3477 if (a === "sw") { 3478 data.left = cpos.left + (csize.width - data.width); 3479 data.top = null; 3480 } 3481 if (a === "nw") { 3482 data.top = cpos.top + (csize.height - data.height); 3483 data.left = cpos.left + (csize.width - data.width); 3484 } 3485 3486 return data; 3487 }, 3488 3489 _respectSize: function( data ) { 3490 3491 var o = this._vBoundaries, 3492 a = this.axis, 3493 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), 3494 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3495 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), 3496 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 3497 dw = this.originalPosition.left + this.originalSize.width, 3498 dh = this.position.top + this.size.height, 3499 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3500 if (isminw) { 3501 data.width = o.minWidth; 3502 } 3503 if (isminh) { 3504 data.height = o.minHeight; 3505 } 3506 if (ismaxw) { 3507 data.width = o.maxWidth; 3508 } 3509 if (ismaxh) { 3510 data.height = o.maxHeight; 3511 } 3512 3513 if (isminw && cw) { 3514 data.left = dw - o.minWidth; 3515 } 3516 if (ismaxw && cw) { 3517 data.left = dw - o.maxWidth; 3518 } 3519 if (isminh && ch) { 3520 data.top = dh - o.minHeight; 3521 } 3522 if (ismaxh && ch) { 3523 data.top = dh - o.maxHeight; 3524 } 3525 3526 // Fixing jump error on top/left - bug #2330 3527 if (!data.width && !data.height && !data.left && data.top) { 3528 data.top = null; 3529 } else if (!data.width && !data.height && !data.top && data.left) { 3530 data.left = null; 3531 } 3532 3533 return data; 3534 }, 3535 3536 _getPaddingPlusBorderDimensions: function( element ) { 3537 var i = 0, 3538 widths = [], 3539 borders = [ 3540 element.css( "borderTopWidth" ), 3541 element.css( "borderRightWidth" ), 3542 element.css( "borderBottomWidth" ), 3543 element.css( "borderLeftWidth" ) 3544 ], 3545 paddings = [ 3546 element.css( "paddingTop" ), 3547 element.css( "paddingRight" ), 3548 element.css( "paddingBottom" ), 3549 element.css( "paddingLeft" ) 3550 ]; 3551 3552 for ( ; i < 4; i++ ) { 3553 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); 3554 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); 3555 } 3556 3557 return { 3558 height: widths[ 0 ] + widths[ 2 ], 3559 width: widths[ 1 ] + widths[ 3 ] 3560 }; 3561 }, 3562 3563 _proportionallyResize: function() { 3564 3565 if (!this._proportionallyResizeElements.length) { 3566 return; 3567 } 3568 3569 var prel, 3570 i = 0, 3571 element = this.helper || this.element; 3572 3573 for ( ; i < this._proportionallyResizeElements.length; i++) { 3574 3575 prel = this._proportionallyResizeElements[i]; 3576 3577 // TODO: Seems like a bug to cache this.outerDimensions 3578 // considering that we are in a loop. 3579 if (!this.outerDimensions) { 3580 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 3581 } 3582 3583 prel.css({ 3584 height: (element.height() - this.outerDimensions.height) || 0, 3585 width: (element.width() - this.outerDimensions.width) || 0 3586 }); 3587 3588 } 3589 3590 }, 3591 3592 _renderProxy: function() { 3593 3594 var el = this.element, o = this.options; 3595 this.elementOffset = el.offset(); 3596 3597 if (this._helper) { 3598 3599 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 3600 3601 this.helper.addClass(this._helper).css({ 3602 width: this.element.outerWidth() - 1, 3603 height: this.element.outerHeight() - 1, 3604 position: "absolute", 3605 left: this.elementOffset.left + "px", 3606 top: this.elementOffset.top + "px", 3607 zIndex: ++o.zIndex //TODO: Don't modify option 3608 }); 3609 3610 this.helper 3611 .appendTo("body") 3612 .disableSelection(); 3613 3614 } else { 3615 this.helper = this.element; 3616 } 3617 3618 }, 3619 3620 _change: { 3621 e: function(event, dx) { 3622 return { width: this.originalSize.width + dx }; 3623 }, 3624 w: function(event, dx) { 3625 var cs = this.originalSize, sp = this.originalPosition; 3626 return { left: sp.left + dx, width: cs.width - dx }; 3627 }, 3628 n: function(event, dx, dy) { 3629 var cs = this.originalSize, sp = this.originalPosition; 3630 return { top: sp.top + dy, height: cs.height - dy }; 3631 }, 3632 s: function(event, dx, dy) { 3633 return { height: this.originalSize.height + dy }; 3634 }, 3635 se: function(event, dx, dy) { 3636 return $.extend(this._change.s.apply(this, arguments), 3637 this._change.e.apply(this, [ event, dx, dy ])); 3638 }, 3639 sw: function(event, dx, dy) { 3640 return $.extend(this._change.s.apply(this, arguments), 3641 this._change.w.apply(this, [ event, dx, dy ])); 3642 }, 3643 ne: function(event, dx, dy) { 3644 return $.extend(this._change.n.apply(this, arguments), 3645 this._change.e.apply(this, [ event, dx, dy ])); 3646 }, 3647 nw: function(event, dx, dy) { 3648 return $.extend(this._change.n.apply(this, arguments), 3649 this._change.w.apply(this, [ event, dx, dy ])); 3650 } 3651 }, 3652 3653 _propagate: function(n, event) { 3654 $.ui.plugin.call(this, n, [ event, this.ui() ]); 3655 (n !== "resize" && this._trigger(n, event, this.ui())); 3656 }, 3657 3658 plugins: {}, 3659 3660 ui: function() { 3661 return { 3662 originalElement: this.originalElement, 3663 element: this.element, 3664 helper: this.helper, 3665 position: this.position, 3666 size: this.size, 3667 originalSize: this.originalSize, 3668 originalPosition: this.originalPosition 3669 }; 3670 } 3671 3672}); 3673 3674/* 3675 * Resizable Extensions 3676 */ 3677 3678$.ui.plugin.add("resizable", "animate", { 3679 3680 stop: function( event ) { 3681 var that = $(this).resizable( "instance" ), 3682 o = that.options, 3683 pr = that._proportionallyResizeElements, 3684 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3685 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, 3686 soffsetw = ista ? 0 : that.sizeDiff.width, 3687 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3688 left = (parseInt(that.element.css("left"), 10) + 3689 (that.position.left - that.originalPosition.left)) || null, 3690 top = (parseInt(that.element.css("top"), 10) + 3691 (that.position.top - that.originalPosition.top)) || null; 3692 3693 that.element.animate( 3694 $.extend(style, top && left ? { top: top, left: left } : {}), { 3695 duration: o.animateDuration, 3696 easing: o.animateEasing, 3697 step: function() { 3698 3699 var data = { 3700 width: parseInt(that.element.css("width"), 10), 3701 height: parseInt(that.element.css("height"), 10), 3702 top: parseInt(that.element.css("top"), 10), 3703 left: parseInt(that.element.css("left"), 10) 3704 }; 3705 3706 if (pr && pr.length) { 3707 $(pr[0]).css({ width: data.width, height: data.height }); 3708 } 3709 3710 // propagating resize, and updating values for each animation step 3711 that._updateCache(data); 3712 that._propagate("resize", event); 3713 3714 } 3715 } 3716 ); 3717 } 3718 3719}); 3720 3721$.ui.plugin.add( "resizable", "containment", { 3722 3723 start: function() { 3724 var element, p, co, ch, cw, width, height, 3725 that = $( this ).resizable( "instance" ), 3726 o = that.options, 3727 el = that.element, 3728 oc = o.containment, 3729 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 3730 3731 if ( !ce ) { 3732 return; 3733 } 3734 3735 that.containerElement = $( ce ); 3736 3737 if ( /document/.test( oc ) || oc === document ) { 3738 that.containerOffset = { 3739 left: 0, 3740 top: 0 3741 }; 3742 that.containerPosition = { 3743 left: 0, 3744 top: 0 3745 }; 3746 3747 that.parentData = { 3748 element: $( document ), 3749 left: 0, 3750 top: 0, 3751 width: $( document ).width(), 3752 height: $( document ).height() || document.body.parentNode.scrollHeight 3753 }; 3754 } else { 3755 element = $( ce ); 3756 p = []; 3757 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { 3758 p[ i ] = that._num( element.css( "padding" + name ) ); 3759 }); 3760 3761 that.containerOffset = element.offset(); 3762 that.containerPosition = element.position(); 3763 that.containerSize = { 3764 height: ( element.innerHeight() - p[ 3 ] ), 3765 width: ( element.innerWidth() - p[ 1 ] ) 3766 }; 3767 3768 co = that.containerOffset; 3769 ch = that.containerSize.height; 3770 cw = that.containerSize.width; 3771 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 3772 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 3773 3774 that.parentData = { 3775 element: ce, 3776 left: co.left, 3777 top: co.top, 3778 width: width, 3779 height: height 3780 }; 3781 } 3782 }, 3783 3784 resize: function( event ) { 3785 var woset, hoset, isParent, isOffsetRelative, 3786 that = $( this ).resizable( "instance" ), 3787 o = that.options, 3788 co = that.containerOffset, 3789 cp = that.position, 3790 pRatio = that._aspectRatio || event.shiftKey, 3791 cop = { 3792 top: 0, 3793 left: 0 3794 }, 3795 ce = that.containerElement, 3796 continueResize = true; 3797 3798 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 3799 cop = co; 3800 } 3801 3802 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 3803 that.size.width = that.size.width + 3804 ( that._helper ? 3805 ( that.position.left - co.left ) : 3806 ( that.position.left - cop.left ) ); 3807 3808 if ( pRatio ) { 3809 that.size.height = that.size.width / that.aspectRatio; 3810 continueResize = false; 3811 } 3812 that.position.left = o.helper ? co.left : 0; 3813 } 3814 3815 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 3816 that.size.height = that.size.height + 3817 ( that._helper ? 3818 ( that.position.top - co.top ) : 3819 that.position.top ); 3820 3821 if ( pRatio ) { 3822 that.size.width = that.size.height * that.aspectRatio; 3823 continueResize = false; 3824 } 3825 that.position.top = that._helper ? co.top : 0; 3826 } 3827 3828 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 3829 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 3830 3831 if ( isParent && isOffsetRelative ) { 3832 that.offset.left = that.parentData.left + that.position.left; 3833 that.offset.top = that.parentData.top + that.position.top; 3834 } else { 3835 that.offset.left = that.element.offset().left; 3836 that.offset.top = that.element.offset().top; 3837 } 3838 3839 woset = Math.abs( that.sizeDiff.width + 3840 (that._helper ? 3841 that.offset.left - cop.left : 3842 (that.offset.left - co.left)) ); 3843 3844 hoset = Math.abs( that.sizeDiff.height + 3845 (that._helper ? 3846 that.offset.top - cop.top : 3847 (that.offset.top - co.top)) ); 3848 3849 if ( woset + that.size.width >= that.parentData.width ) { 3850 that.size.width = that.parentData.width - woset; 3851 if ( pRatio ) { 3852 that.size.height = that.size.width / that.aspectRatio; 3853 continueResize = false; 3854 } 3855 } 3856 3857 if ( hoset + that.size.height >= that.parentData.height ) { 3858 that.size.height = that.parentData.height - hoset; 3859 if ( pRatio ) { 3860 that.size.width = that.size.height * that.aspectRatio; 3861 continueResize = false; 3862 } 3863 } 3864 3865 if ( !continueResize ){ 3866 that.position.left = that.prevPosition.left; 3867 that.position.top = that.prevPosition.top; 3868 that.size.width = that.prevSize.width; 3869 that.size.height = that.prevSize.height; 3870 } 3871 }, 3872 3873 stop: function() { 3874 var that = $( this ).resizable( "instance" ), 3875 o = that.options, 3876 co = that.containerOffset, 3877 cop = that.containerPosition, 3878 ce = that.containerElement, 3879 helper = $( that.helper ), 3880 ho = helper.offset(), 3881 w = helper.outerWidth() - that.sizeDiff.width, 3882 h = helper.outerHeight() - that.sizeDiff.height; 3883 3884 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 3885 $( this ).css({ 3886 left: ho.left - cop.left - co.left, 3887 width: w, 3888 height: h 3889 }); 3890 } 3891 3892 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 3893 $( this ).css({ 3894 left: ho.left - cop.left - co.left, 3895 width: w, 3896 height: h 3897 }); 3898 } 3899 } 3900}); 3901 3902$.ui.plugin.add("resizable", "alsoResize", { 3903 3904 start: function() { 3905 var that = $(this).resizable( "instance" ), 3906 o = that.options, 3907 _store = function(exp) { 3908 $(exp).each(function() { 3909 var el = $(this); 3910 el.data("ui-resizable-alsoresize", { 3911 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3912 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3913 }); 3914 }); 3915 }; 3916 3917 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3918 if (o.alsoResize.length) { 3919 o.alsoResize = o.alsoResize[0]; 3920 _store(o.alsoResize); 3921 } else { 3922 $.each(o.alsoResize, function(exp) { 3923 _store(exp); 3924 }); 3925 } 3926 } else { 3927 _store(o.alsoResize); 3928 } 3929 }, 3930 3931 resize: function(event, ui) { 3932 var that = $(this).resizable( "instance" ), 3933 o = that.options, 3934 os = that.originalSize, 3935 op = that.originalPosition, 3936 delta = { 3937 height: (that.size.height - os.height) || 0, 3938 width: (that.size.width - os.width) || 0, 3939 top: (that.position.top - op.top) || 0, 3940 left: (that.position.left - op.left) || 0 3941 }, 3942 3943 _alsoResize = function(exp, c) { 3944 $(exp).each(function() { 3945 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3946 css = c && c.length ? 3947 c : 3948 el.parents(ui.originalElement[0]).length ? 3949 [ "width", "height" ] : 3950 [ "width", "height", "top", "left" ]; 3951 3952 $.each(css, function(i, prop) { 3953 var sum = (start[prop] || 0) + (delta[prop] || 0); 3954 if (sum && sum >= 0) { 3955 style[prop] = sum || null; 3956 } 3957 }); 3958 3959 el.css(style); 3960 }); 3961 }; 3962 3963 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3964 $.each(o.alsoResize, function(exp, c) { 3965 _alsoResize(exp, c); 3966 }); 3967 } else { 3968 _alsoResize(o.alsoResize); 3969 } 3970 }, 3971 3972 stop: function() { 3973 $(this).removeData("resizable-alsoresize"); 3974 } 3975}); 3976 3977$.ui.plugin.add("resizable", "ghost", { 3978 3979 start: function() { 3980 3981 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; 3982 3983 that.ghost = that.originalElement.clone(); 3984 that.ghost 3985 .css({ 3986 opacity: 0.25, 3987 display: "block", 3988 position: "relative", 3989 height: cs.height, 3990 width: cs.width, 3991 margin: 0, 3992 left: 0, 3993 top: 0 3994 }) 3995 .addClass("ui-resizable-ghost") 3996 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3997 3998 that.ghost.appendTo(that.helper); 3999 4000 }, 4001 4002 resize: function() { 4003 var that = $(this).resizable( "instance" ); 4004 if (that.ghost) { 4005 that.ghost.css({ 4006 position: "relative", 4007 height: that.size.height, 4008 width: that.size.width 4009 }); 4010 } 4011 }, 4012 4013 stop: function() { 4014 var that = $(this).resizable( "instance" ); 4015 if (that.ghost && that.helper) { 4016 that.helper.get(0).removeChild(that.ghost.get(0)); 4017 } 4018 } 4019 4020}); 4021 4022$.ui.plugin.add("resizable", "grid", { 4023 4024 resize: function() { 4025 var outerDimensions, 4026 that = $(this).resizable( "instance" ), 4027 o = that.options, 4028 cs = that.size, 4029 os = that.originalSize, 4030 op = that.originalPosition, 4031 a = that.axis, 4032 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 4033 gridX = (grid[0] || 1), 4034 gridY = (grid[1] || 1), 4035 ox = Math.round((cs.width - os.width) / gridX) * gridX, 4036 oy = Math.round((cs.height - os.height) / gridY) * gridY, 4037 newWidth = os.width + ox, 4038 newHeight = os.height + oy, 4039 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 4040 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 4041 isMinWidth = o.minWidth && (o.minWidth > newWidth), 4042 isMinHeight = o.minHeight && (o.minHeight > newHeight); 4043 4044 o.grid = grid; 4045 4046 if (isMinWidth) { 4047 newWidth += gridX; 4048 } 4049 if (isMinHeight) { 4050 newHeight += gridY; 4051 } 4052 if (isMaxWidth) { 4053 newWidth -= gridX; 4054 } 4055 if (isMaxHeight) { 4056 newHeight -= gridY; 4057 } 4058 4059 if (/^(se|s|e)$/.test(a)) { 4060 that.size.width = newWidth; 4061 that.size.height = newHeight; 4062 } else if (/^(ne)$/.test(a)) { 4063 that.size.width = newWidth; 4064 that.size.height = newHeight; 4065 that.position.top = op.top - oy; 4066 } else if (/^(sw)$/.test(a)) { 4067 that.size.width = newWidth; 4068 that.size.height = newHeight; 4069 that.position.left = op.left - ox; 4070 } else { 4071 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { 4072 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 4073 } 4074 4075 if ( newHeight - gridY > 0 ) { 4076 that.size.height = newHeight; 4077 that.position.top = op.top - oy; 4078 } else { 4079 newHeight = gridY - outerDimensions.height; 4080 that.size.height = newHeight; 4081 that.position.top = op.top + os.height - newHeight; 4082 } 4083 if ( newWidth - gridX > 0 ) { 4084 that.size.width = newWidth; 4085 that.position.left = op.left - ox; 4086 } else { 4087 newWidth = gridY - outerDimensions.height; 4088 that.size.width = newWidth; 4089 that.position.left = op.left + os.width - newWidth; 4090 } 4091 } 4092 } 4093 4094}); 4095 4096var resizable = $.ui.resizable; 4097 4098 4099/*! 4100 * jQuery UI
vendor: 6,627 bytes, lines 4100-4354
4100Selectable 1.11.1 4101 * http://jqueryui.com 4102 * 4103 * Copyright 2014 jQuery Foundation and other contributors 4104 * Released under the MIT license. 4105 * http://jquery.org/license 4106 * 4107 * http://api.jqueryui.com/selectable/ 4108 */ 4109 4110 4111var selectable = $.widget("ui.selectable", $.ui.mouse, { 4112 version: "1.11.1", 4113 options: { 4114 appendTo: "body", 4115 autoRefresh: true, 4116 distance: 0, 4117 filter: "*", 4118 tolerance: "touch", 4119 4120 // callbacks 4121 selected: null, 4122 selecting: null, 4123 start: null, 4124 stop: null, 4125 unselected: null, 4126 unselecting: null 4127 }, 4128 _create: function() { 4129 var selectees, 4130 that = this; 4131 4132 this.element.addClass("ui-selectable"); 4133 4134 this.dragged = false; 4135 4136 // cache selectee children based on filter 4137 this.refresh = function() { 4138 selectees = $(that.options.filter, that.element[0]); 4139 selectees.addClass("ui-selectee"); 4140 selectees.each(function() { 4141 var $this = $(this), 4142 pos = $this.offset(); 4143 $.data(this, "selectable-item", { 4144 element: this, 4145 $element: $this, 4146 left: pos.left, 4147 top: pos.top, 4148 right: pos.left + $this.outerWidth(), 4149 bottom: pos.top + $this.outerHeight(), 4150 startselected: false, 4151 selected: $this.hasClass("ui-selected"), 4152 selecting: $this.hasClass("ui-selecting"), 4153 unselecting: $this.hasClass("ui-unselecting") 4154 }); 4155 }); 4156 }; 4157 this.refresh(); 4158 4159 this.selectees = selectees.addClass("ui-selectee"); 4160 4161 this._mouseInit(); 4162 4163 this.helper = $("<div class='ui-selectable-helper'></div>"); 4164 }, 4165 4166 _destroy: function() { 4167 this.selectees 4168 .removeClass("ui-selectee") 4169 .removeData("selectable-item"); 4170 this.element 4171 .removeClass("ui-selectable ui-selectable-disabled"); 4172 this._mouseDestroy(); 4173 }, 4174 4175 _mouseStart: function(event) { 4176 var that = this, 4177 options = this.options; 4178 4179 this.opos = [ event.pageX, event.pageY ]; 4180 4181 if (this.options.disabled) { 4182 return; 4183 } 4184 4185 this.selectees = $(options.filter, this.element[0]); 4186 4187 this._trigger("start", event); 4188 4189 $(options.appendTo).append(this.helper); 4190 // position helper (lasso) 4191 this.helper.css({ 4192 "left": event.pageX, 4193 "top": event.pageY, 4194 "width": 0, 4195 "height": 0 4196 }); 4197 4198 if (options.autoRefresh) { 4199 this.refresh(); 4200 } 4201 4202 this.selectees.filter(".ui-selected").each(function() { 4203 var selectee = $.data(this, "selectable-item"); 4204 selectee.startselected = true; 4205 if (!event.metaKey && !event.ctrlKey) { 4206 selectee.$element.removeClass("ui-selected"); 4207 selectee.selected = false; 4208 selectee.$element.addClass("ui-unselecting"); 4209 selectee.unselecting = true; 4210 // selectable UNSELECTING callback 4211 that._trigger("unselecting", event, { 4212 unselecting: selectee.element 4213 }); 4214 } 4215 }); 4216 4217 $(event.target).parents().addBack().each(function() { 4218 var doSelect, 4219 selectee = $.data(this, "selectable-item"); 4220 if (selectee) { 4221 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 4222 selectee.$element 4223 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 4224 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 4225 selectee.unselecting = !doSelect; 4226 selectee.selecting = doSelect; 4227 selectee.selected = doSelect; 4228 // selectable (UN)SELECTING callback 4229 if (doSelect) { 4230 that._trigger("selecting", event, { 4231 selecting: selectee.element 4232 }); 4233 } else { 4234 that._trigger("unselecting", event, { 4235 unselecting: selectee.element 4236 }); 4237 } 4238 return false; 4239 } 4240 }); 4241 4242 }, 4243 4244 _mouseDrag: function(event) { 4245 4246 this.dragged = true; 4247 4248 if (this.options.disabled) { 4249 return; 4250 } 4251 4252 var tmp, 4253 that = this, 4254 options = this.options, 4255 x1 = this.opos[0], 4256 y1 = this.opos[1], 4257 x2 = event.pageX, 4258 y2 = event.pageY; 4259 4260 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 4261 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 4262 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 4263 4264 this.selectees.each(function() { 4265 var selectee = $.data(this, "selectable-item"), 4266 hit = false; 4267 4268 //prevent helper from being selected if appendTo: selectable 4269 if (!selectee || selectee.element === that.element[0]) { 4270 return; 4271 } 4272 4273 if (options.tolerance === "touch") { 4274 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 4275 } else if (options.tolerance === "fit") { 4276 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 4277 } 4278 4279 if (hit) { 4280 // SELECT 4281 if (selectee.selected) { 4282 selectee.$element.removeClass("ui-selected"); 4283 selectee.selected = false; 4284 } 4285 if (selectee.unselecting) { 4286 selectee.$element.removeClass("ui-unselecting"); 4287 selectee.unselecting = false; 4288 } 4289 if (!selectee.selecting) { 4290 selectee.$element.addClass("ui-selecting"); 4291 selectee.selecting = true; 4292 // selectable SELECTING callback 4293 that._trigger("selecting", event, { 4294 selecting: selectee.element 4295 }); 4296 } 4297 } else { 4298 // UNSELECT 4299 if (selectee.selecting) { 4300 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 4301 selectee.$element.removeClass("ui-selecting"); 4302 selectee.selecting = false; 4303 selectee.$element.addClass("ui-selected"); 4304 selectee.selected = true; 4305 } else { 4306 selectee.$element.removeClass("ui-selecting"); 4307 selectee.selecting = false; 4308 if (selectee.startselected) { 4309 selectee.$element.addClass("ui-unselecting"); 4310 selectee.unselecting = true; 4311 } 4312 // selectable UNSELECTING callback 4313 that._trigger("unselecting", event, { 4314 unselecting: selectee.element 4315 }); 4316 } 4317 } 4318 if (selectee.selected) { 4319 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 4320 selectee.$element.removeClass("ui-selected"); 4321 selectee.selected = false; 4322 4323 selectee.$element.addClass("ui-unselecting"); 4324 selectee.unselecting = true; 4325 // selectable UNSELECTING callback 4326 that._trigger("unselecting", event, { 4327 unselecting: selectee.element 4328 }); 4329 } 4330 } 4331 } 4332 }); 4333 4334 return false; 4335 }, 4336 4337 _mouseStop: function(event) { 4338 var that = this; 4339 4340 this.dragged = false; 4341 4342 $(".ui-unselecting", this.element[0]).each(function() { 4343 var selectee = $.data(this, "selectable-item"); 4344 selectee.$element.removeClass("ui-unselecting"); 4345 selectee.unselecting = false; 4346 selectee.startselected = false; 4347 that._trigger("unselected", event, { 4348 unselected: selectee.element 4349 }); 4350 }); 4351 $(".ui-selecting", this.element[0]).each(function() { 4352 var selectee = $.data(this, "selectable-item"); 4353 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 4354 selectee.selecting = false;
4355 selectee.selected = true; 4356 selectee.startselected = true; 4357 that._trigger("selected", event, { 4358 selected: selectee.element 4359 }); 4360 }); 4361 this._trigger("stop", event); 4362 4363 this.helper.remove(); 4364 4365 return false; 4366 }
vendor: 105,008 bytes, lines 4367-7940
4367 4368}); 4369 4370 4371/*! 4372 * jQuery UI Sortable 1.11.1 4373 * http://jqueryui.com 4374 * 4375 * Copyright 2014 jQuery Foundation and other contributors 4376 * Released under the MIT license. 4377 * http://jquery.org/license 4378 * 4379 * http://api.jqueryui.com/sortable/ 4380 */ 4381 4382 4383var sortable = $.widget("ui.sortable", $.ui.mouse, { 4384 version: "1.11.1", 4385 widgetEventPrefix: "sort", 4386 ready: false, 4387 options: { 4388 appendTo: "parent", 4389 axis: false, 4390 connectWith: false, 4391 containment: false, 4392 cursor: "auto", 4393 cursorAt: false, 4394 dropOnEmpty: true, 4395 forcePlaceholderSize: false, 4396 forceHelperSize: false, 4397 grid: false, 4398 handle: false, 4399 helper: "original", 4400 items: "> *", 4401 opacity: false, 4402 placeholder: false, 4403 revert: false, 4404 scroll: true, 4405 scrollSensitivity: 20, 4406 scrollSpeed: 20, 4407 scope: "default", 4408 tolerance: "intersect", 4409 zIndex: 1000, 4410 4411 // callbacks 4412 activate: null, 4413 beforeStop: null, 4414 change: null, 4415 deactivate: null, 4416 out: null, 4417 over: null, 4418 receive: null, 4419 remove: null, 4420 sort: null, 4421 start: null, 4422 stop: null, 4423 update: null 4424 }, 4425 4426 _isOverAxis: function( x, reference, size ) { 4427 return ( x >= reference ) && ( x < ( reference + size ) ); 4428 }, 4429 4430 _isFloating: function( item ) { 4431 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 4432 }, 4433 4434 _create: function() { 4435 4436 var o = this.options; 4437 this.containerCache = {}; 4438 this.element.addClass("ui-sortable"); 4439 4440 //Get the items 4441 this.refresh(); 4442 4443 //Let's determine if the items are being displayed horizontally 4444 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false; 4445 4446 //Let's determine the parent's offset 4447 this.offset = this.element.offset(); 4448 4449 //Initialize mouse events for interaction 4450 this._mouseInit(); 4451 4452 this._setHandleClassName(); 4453 4454 //We're ready to go 4455 this.ready = true; 4456 4457 }, 4458 4459 _setOption: function( key, value ) { 4460 this._super( key, value ); 4461 4462 if ( key === "handle" ) { 4463 this._setHandleClassName(); 4464 } 4465 }, 4466 4467 _setHandleClassName: function() { 4468 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); 4469 $.each( this.items, function() { 4470 ( this.instance.options.handle ? 4471 this.item.find( this.instance.options.handle ) : this.item ) 4472 .addClass( "ui-sortable-handle" ); 4473 }); 4474 }, 4475 4476 _destroy: function() { 4477 this.element 4478 .removeClass( "ui-sortable ui-sortable-disabled" ) 4479 .find( ".ui-sortable-handle" ) 4480 .removeClass( "ui-sortable-handle" ); 4481 this._mouseDestroy(); 4482 4483 for ( var i = this.items.length - 1; i >= 0; i-- ) { 4484 this.items[i].item.removeData(this.widgetName + "-item"); 4485 } 4486 4487 return this; 4488 }, 4489 4490 _mouseCapture: function(event, overrideHandle) { 4491 var currentItem = null, 4492 validHandle = false, 4493 that = this; 4494 4495 if (this.reverting) { 4496 return false; 4497 } 4498 4499 if(this.options.disabled || this.options.type === "static") { 4500 return false; 4501 } 4502 4503 //We have to refresh the items data once first 4504 this._refreshItems(event); 4505 4506 //Find out if the clicked node (or one of its parents) is a actual item in this.items 4507 $(event.target).parents().each(function() { 4508 if($.data(this, that.widgetName + "-item") === that) { 4509 currentItem = $(this); 4510 return false; 4511 } 4512 }); 4513 if($.data(event.target, that.widgetName + "-item") === that) { 4514 currentItem = $(event.target); 4515 } 4516 4517 if(!currentItem) { 4518 return false; 4519 } 4520 if(this.options.handle && !overrideHandle) { 4521 $(this.options.handle, currentItem).find("*").addBack().each(function() { 4522 if(this === event.target) { 4523 validHandle = true; 4524 } 4525 }); 4526 if(!validHandle) { 4527 return false; 4528 } 4529 } 4530 4531 this.currentItem = currentItem; 4532 this._removeCurrentsFromItems(); 4533 return true; 4534 4535 }, 4536 4537 _mouseStart: function(event, overrideHandle, noActivation) { 4538 4539 var i, body, 4540 o = this.options; 4541 4542 this.currentContainer = this; 4543 4544 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 4545 this.refreshPositions(); 4546 4547 //Create and append the visible helper 4548 this.helper = this._createHelper(event); 4549 4550 //Cache the helper size 4551 this._cacheHelperProportions(); 4552 4553 /* 4554 * - Position generation - 4555 * This block generates everything position related - it's the core of draggables. 4556 */ 4557 4558 //Cache the margins of the original element 4559 this._cacheMargins(); 4560 4561 //Get the next scrolling parent 4562 this.scrollParent = this.helper.scrollParent(); 4563 4564 //The element's absolute position on the page minus margins 4565 this.offset = this.currentItem.offset(); 4566 this.offset = { 4567 top: this.offset.top - this.margins.top, 4568 left: this.offset.left - this.margins.left 4569 }; 4570 4571 $.extend(this.offset, { 4572 click: { //Where the click happened, relative to the element 4573 left: event.pageX - this.offset.left, 4574 top: event.pageY - this.offset.top 4575 }, 4576 parent: this._getParentOffset(), 4577 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 4578 }); 4579 4580 // Only after we got the offset, we can change the helper's position to absolute 4581 // TODO: Still need to figure out a way to make relative sorting possible 4582 this.helper.css("position", "absolute"); 4583 this.cssPosition = this.helper.css("position"); 4584 4585 //Generate the original position 4586 this.originalPosition = this._generatePosition(event); 4587 this.originalPageX = event.pageX; 4588 this.originalPageY = event.pageY; 4589 4590 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 4591 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 4592 4593 //Cache the former DOM position 4594 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 4595 4596 //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 4597 if(this.helper[0] !== this.currentItem[0]) { 4598 this.currentItem.hide(); 4599 } 4600 4601 //Create the placeholder 4602 this._createPlaceholder(); 4603 4604 //Set a containment if given in the options 4605 if(o.containment) { 4606 this._setContainment(); 4607 } 4608 4609 if( o.cursor && o.cursor !== "auto" ) { // cursor option 4610 body = this.document.find( "body" ); 4611 4612 // support: IE 4613 this.storedCursor = body.css( "cursor" ); 4614 body.css( "cursor", o.cursor ); 4615 4616 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 4617 } 4618 4619 if(o.opacity) { // opacity option 4620 if (this.helper.css("opacity")) { 4621 this._storedOpacity = this.helper.css("opacity"); 4622 } 4623 this.helper.css("opacity", o.opacity); 4624 } 4625 4626 if(o.zIndex) { // zIndex option 4627 if (this.helper.css("zIndex")) { 4628 this._storedZIndex = this.helper.css("zIndex"); 4629 } 4630 this.helper.css("zIndex", o.zIndex); 4631 } 4632 4633 //Prepare scrolling 4634 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4635 this.overflowOffset = this.scrollParent.offset(); 4636 } 4637 4638 //Call callbacks 4639 this._trigger("start", event, this._uiHash()); 4640 4641 //Recache the helper size 4642 if(!this._preserveHelperProportions) { 4643 this._cacheHelperProportions(); 4644 } 4645 4646 4647 //Post "activate" events to possible containers 4648 if( !noActivation ) { 4649 for ( i = this.containers.length - 1; i >= 0; i-- ) { 4650 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 4651 } 4652 } 4653 4654 //Prepare possible droppables 4655 if($.ui.ddmanager) { 4656 $.ui.ddmanager.current = this; 4657 } 4658 4659 if ($.ui.ddmanager && !o.dropBehaviour) { 4660 $.ui.ddmanager.prepareOffsets(this, event); 4661 } 4662 4663 this.dragging = true; 4664 4665 this.helper.addClass("ui-sortable-helper"); 4666 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 4667 return true; 4668 4669 }, 4670 4671 _mouseDrag: function(event) { 4672 var i, item, itemElement, intersection, 4673 o = this.options, 4674 scrolled = false; 4675 4676 //Compute the helpers position 4677 this.position = this._generatePosition(event); 4678 this.positionAbs = this._convertPositionTo("absolute"); 4679 4680 if (!this.lastPositionAbs) { 4681 this.lastPositionAbs = this.positionAbs; 4682 } 4683 4684 //Do scrolling 4685 if(this.options.scroll) { 4686 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4687 4688 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 4689 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 4690 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 4691 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 4692 } 4693 4694 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 4695 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 4696 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 4697 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 4698 } 4699 4700 } else { 4701 4702 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 4703 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4704 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 4705 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4706 } 4707 4708 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 4709 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4710 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 4711 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4712 } 4713 4714 } 4715 4716 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 4717 $.ui.ddmanager.prepareOffsets(this, event); 4718 } 4719 } 4720 4721 //Regenerate the absolute position used for position checks 4722 this.positionAbs = this._convertPositionTo("absolute"); 4723 4724 //Set the helper position 4725 if(!this.options.axis || this.options.axis !== "y") { 4726 this.helper[0].style.left = this.position.left+"px"; 4727 } 4728 if(!this.options.axis || this.options.axis !== "x") { 4729 this.helper[0].style.top = this.position.top+"px"; 4730 } 4731 4732 //Rearrange 4733 for (i = this.items.length - 1; i >= 0; i--) { 4734 4735 //Cache variables and intersection, continue if no intersection 4736 item = this.items[i]; 4737 itemElement = item.item[0]; 4738 intersection = this._intersectsWithPointer(item); 4739 if (!intersection) { 4740 continue; 4741 } 4742 4743 // Only put the placeholder inside the current Container, skip all 4744 // items from other containers. This works because when moving 4745 // an item from one container to another the 4746 // currentContainer is switched before the placeholder is moved. 4747 // 4748 // Without this, moving items in "sub-sortables" can cause 4749 // the placeholder to jitter between the outer and inner container. 4750 if (item.instance !== this.currentContainer) { 4751 continue; 4752 } 4753 4754 // cannot intersect with itself 4755 // no useless actions that have been done before 4756 // no action if the item moved is the parent of the item checked 4757 if (itemElement !== this.currentItem[0] && 4758 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 4759 !$.contains(this.placeholder[0], itemElement) && 4760 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 4761 ) { 4762 4763 this.direction = intersection === 1 ? "down" : "up"; 4764 4765 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 4766 this._rearrange(event, item); 4767 } else { 4768 break; 4769 } 4770 4771 this._trigger("change", event, this._uiHash()); 4772 break; 4773 } 4774 } 4775 4776 //Post events to containers 4777 this._contactContainers(event); 4778 4779 //Interconnect with droppables 4780 if($.ui.ddmanager) { 4781 $.ui.ddmanager.drag(this, event); 4782 } 4783 4784 //Call callbacks 4785 this._trigger("sort", event, this._uiHash()); 4786 4787 this.lastPositionAbs = this.positionAbs; 4788 return false; 4789 4790 }, 4791 4792 _mouseStop: function(event, noPropagation) { 4793 4794 if(!event) { 4795 return; 4796 } 4797 4798 //If we are using droppables, inform the manager about the drop 4799 if ($.ui.ddmanager && !this.options.dropBehaviour) { 4800 $.ui.ddmanager.drop(this, event); 4801 } 4802 4803 if(this.options.revert) { 4804 var that = this, 4805 cur = this.placeholder.offset(), 4806 axis = this.options.axis, 4807 animation = {}; 4808 4809 if ( !axis || axis === "x" ) { 4810 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 4811 } 4812 if ( !axis || axis === "y" ) { 4813 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 4814 } 4815 this.reverting = true; 4816 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 4817 that._clear(event); 4818 }); 4819 } else { 4820 this._clear(event, noPropagation); 4821 } 4822 4823 return false; 4824 4825 }, 4826 4827 cancel: function() { 4828 4829 if(this.dragging) { 4830 4831 this._mouseUp({ target: null }); 4832 4833 if(this.options.helper === "original") { 4834 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4835 } else { 4836 this.currentItem.show(); 4837 } 4838 4839 //Post deactivating events to containers 4840 for (var i = this.containers.length - 1; i >= 0; i--){ 4841 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4842 if(this.containers[i].containerCache.over) { 4843 this.containers[i]._trigger("out", null, this._uiHash(this)); 4844 this.containers[i].containerCache.over = 0; 4845 } 4846 } 4847 4848 } 4849 4850 if (this.placeholder) { 4851 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4852 if(this.placeholder[0].parentNode) { 4853 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4854 } 4855 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 4856 this.helper.remove(); 4857 } 4858 4859 $.extend(this, { 4860 helper: null, 4861 dragging: false, 4862 reverting: false, 4863 _noFinalSort: null 4864 }); 4865 4866 if(this.domPosition.prev) { 4867 $(this.domPosition.prev).after(this.currentItem); 4868 } else { 4869 $(this.domPosition.parent).prepend(this.currentItem); 4870 } 4871 } 4872 4873 return this; 4874 4875 }, 4876 4877 serialize: function(o) { 4878 4879 var items = this._getItemsAsjQuery(o && o.connected), 4880 str = []; 4881 o = o || {}; 4882 4883 $(items).each(function() { 4884 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 4885 if (res) { 4886 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4887 } 4888 }); 4889 4890 if(!str.length && o.key) { 4891 str.push(o.key + "="); 4892 } 4893 4894 return str.join("&"); 4895 4896 }, 4897 4898 toArray: function(o) { 4899 4900 var items = this._getItemsAsjQuery(o && o.connected), 4901 ret = []; 4902 4903 o = o || {}; 4904 4905 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4906 return ret; 4907 4908 }, 4909 4910 /* Be careful with the following core functions */ 4911 _intersectsWith: function(item) { 4912 4913 var x1 = this.positionAbs.left, 4914 x2 = x1 + this.helperProportions.width, 4915 y1 = this.positionAbs.top, 4916 y2 = y1 + this.helperProportions.height, 4917 l = item.left, 4918 r = l + item.width, 4919 t = item.top, 4920 b = t + item.height, 4921 dyClick = this.offset.click.top, 4922 dxClick = this.offset.click.left, 4923 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 4924 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 4925 isOverElement = isOverElementHeight && isOverElementWidth; 4926 4927 if ( this.options.tolerance === "pointer" || 4928 this.options.forcePointerForContainers || 4929 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4930 ) { 4931 return isOverElement; 4932 } else { 4933 4934 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4935 x2 - (this.helperProportions.width / 2) < r && // Left Half 4936 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4937 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4938 4939 } 4940 }, 4941 4942 _intersectsWithPointer: function(item) { 4943 4944 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4945 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4946 isOverElement = isOverElementHeight && isOverElementWidth, 4947 verticalDirection = this._getDragVerticalDirection(), 4948 horizontalDirection = this._getDragHorizontalDirection(); 4949 4950 if (!isOverElement) { 4951 return false; 4952 } 4953 4954 return this.floating ? 4955 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4956 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4957 4958 }, 4959 4960 _intersectsWithSides: function(item) { 4961 4962 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4963 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4964 verticalDirection = this._getDragVerticalDirection(), 4965 horizontalDirection = this._getDragHorizontalDirection(); 4966 4967 if (this.floating && horizontalDirection) { 4968 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4969 } else { 4970 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4971 } 4972 4973 }, 4974 4975 _getDragVerticalDirection: function() { 4976 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4977 return delta !== 0 && (delta > 0 ? "down" : "up"); 4978 }, 4979 4980 _getDragHorizontalDirection: function() { 4981 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4982 return delta !== 0 && (delta > 0 ? "right" : "left"); 4983 }, 4984 4985 refresh: function(event) { 4986 this._refreshItems(event); 4987 this._setHandleClassName(); 4988 this.refreshPositions(); 4989 return this; 4990 }, 4991 4992 _connectWith: function() { 4993 var options = this.options; 4994 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4995 }, 4996 4997 _getItemsAsjQuery: function(connected) { 4998 4999 var i, j, cur, inst, 5000 items = [], 5001 queries = [], 5002 connectWith = this._connectWith(); 5003 5004 if(connectWith && connected) { 5005 for (i = connectWith.length - 1; i >= 0; i--){ 5006 cur = $(connectWith[i]); 5007 for ( j = cur.length - 1; j >= 0; j--){ 5008 inst = $.data(cur[j], this.widgetFullName); 5009 if(inst && inst !== this && !inst.options.disabled) { 5010 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]); 5011 } 5012 } 5013 } 5014 } 5015 5016 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]); 5017 5018 function addItems() { 5019 items.push( this ); 5020 } 5021 for (i = queries.length - 1; i >= 0; i--){ 5022 queries[i][0].each( addItems ); 5023 } 5024 5025 return $(items); 5026 5027 }, 5028 5029 _removeCurrentsFromItems: function() { 5030 5031 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 5032 5033 this.items = $.grep(this.items, function (item) { 5034 for (var j=0; j < list.length; j++) { 5035 if(list[j] === item.item[0]) { 5036 return false; 5037 } 5038 } 5039 return true; 5040 }); 5041 5042 }, 5043 5044 _refreshItems: function(event) { 5045 5046 this.items = []; 5047 this.containers = [this]; 5048 5049 var i, j, cur, inst, targetData, _queries, item, queriesLength, 5050 items = this.items, 5051 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 5052 connectWith = this._connectWith(); 5053 5054 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 5055 for (i = connectWith.length - 1; i >= 0; i--){ 5056 cur = $(connectWith[i]); 5057 for (j = cur.length - 1; j >= 0; j--){ 5058 inst = $.data(cur[j], this.widgetFullName); 5059 if(inst && inst !== this && !inst.options.disabled) { 5060 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 5061 this.containers.push(inst); 5062 } 5063 } 5064 } 5065 } 5066 5067 for (i = queries.length - 1; i >= 0; i--) { 5068 targetData = queries[i][1]; 5069 _queries = queries[i][0]; 5070 5071 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 5072 item = $(_queries[j]); 5073 5074 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 5075 5076 items.push({ 5077 item: item, 5078 instance: targetData, 5079 width: 0, height: 0, 5080 left: 0, top: 0 5081 }); 5082 } 5083 } 5084 5085 }, 5086 5087 refreshPositions: function(fast) { 5088 5089 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 5090 if(this.offsetParent && this.helper) { 5091 this.offset.parent = this._getParentOffset(); 5092 } 5093 5094 var i, item, t, p; 5095 5096 for (i = this.items.length - 1; i >= 0; i--){ 5097 item = this.items[i]; 5098 5099 //We ignore calculating positions of all connected containers when we're not over them 5100 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 5101 continue; 5102 } 5103 5104 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 5105 5106 if (!fast) { 5107 item.width = t.outerWidth(); 5108 item.height = t.outerHeight(); 5109 } 5110 5111 p = t.offset(); 5112 item.left = p.left; 5113 item.top = p.top; 5114 } 5115 5116 if(this.options.custom && this.options.custom.refreshContainers) { 5117 this.options.custom.refreshContainers.call(this); 5118 } else { 5119 for (i = this.containers.length - 1; i >= 0; i--){ 5120 p = this.containers[i].element.offset(); 5121 this.containers[i].containerCache.left = p.left; 5122 this.containers[i].containerCache.top = p.top; 5123 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 5124 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 5125 } 5126 } 5127 5128 return this; 5129 }, 5130 5131 _createPlaceholder: function(that) { 5132 that = that || this; 5133 var className, 5134 o = that.options; 5135 5136 if(!o.placeholder || o.placeholder.constructor === String) { 5137 className = o.placeholder; 5138 o.placeholder = { 5139 element: function() { 5140 5141 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 5142 element = $( "<" + nodeName + ">", that.document[0] ) 5143 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 5144 .removeClass("ui-sortable-helper"); 5145 5146 if ( nodeName === "tr" ) { 5147 that.currentItem.children().each(function() { 5148 $( "<td> </td>", that.document[0] ) 5149 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 5150 .appendTo( element ); 5151 }); 5152 } else if ( nodeName === "img" ) { 5153 element.attr( "src", that.currentItem.attr( "src" ) ); 5154 } 5155 5156 if ( !className ) { 5157 element.css( "visibility", "hidden" ); 5158 } 5159 5160 return element; 5161 }, 5162 update: function(container, p) { 5163 5164 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 5165 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 5166 if(className && !o.forcePlaceholderSize) { 5167 return; 5168 } 5169 5170 //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 5171 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 5172 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 5173 } 5174 }; 5175 } 5176 5177 //Create the placeholder 5178 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 5179 5180 //Append it after the actual current item 5181 that.currentItem.after(that.placeholder); 5182 5183 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 5184 o.placeholder.update(that, that.placeholder); 5185 5186 }, 5187 5188 _contactContainers: function(event) { 5189 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, 5190 innermostContainer = null, 5191 innermostIndex = null; 5192 5193 // get innermost container that intersects with item 5194 for (i = this.containers.length - 1; i >= 0; i--) { 5195 5196 // never consider a container that's located within the item itself 5197 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 5198 continue; 5199 } 5200 5201 if(this._intersectsWith(this.containers[i].containerCache)) { 5202 5203 // if we've already found a container and it's more "inner" than this, then continue 5204 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 5205 continue; 5206 } 5207 5208 innermostContainer = this.containers[i]; 5209 innermostIndex = i; 5210 5211 } else { 5212 // container doesn't intersect. trigger "out" event if necessary 5213 if(this.containers[i].containerCache.over) { 5214 this.containers[i]._trigger("out", event, this._uiHash(this)); 5215 this.containers[i].containerCache.over = 0; 5216 } 5217 } 5218 5219 } 5220 5221 // if no intersecting containers found, return 5222 if(!innermostContainer) { 5223 return; 5224 } 5225 5226 // move the item into the container if it's not there already 5227 if(this.containers.length === 1) { 5228 if (!this.containers[innermostIndex].containerCache.over) { 5229 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5230 this.containers[innermostIndex].containerCache.over = 1; 5231 } 5232 } else { 5233 5234 //When entering a new container, we will find the item with the least distance and append our item near it 5235 dist = 10000; 5236 itemWithLeastDistance = null; 5237 floating = innermostContainer.floating || this._isFloating(this.currentItem); 5238 posProperty = floating ? "left" : "top"; 5239 sizeProperty = floating ? "width" : "height"; 5240 axis = floating ? "clientX" : "clientY"; 5241 5242 for (j = this.items.length - 1; j >= 0; j--) { 5243 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 5244 continue; 5245 } 5246 if(this.items[j].item[0] === this.currentItem[0]) { 5247 continue; 5248 } 5249 5250 cur = this.items[j].item.offset()[posProperty]; 5251 nearBottom = false; 5252 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 5253 nearBottom = true; 5254 } 5255 5256 if ( Math.abs( event[ axis ] - cur ) < dist ) { 5257 dist = Math.abs( event[ axis ] - cur ); 5258 itemWithLeastDistance = this.items[ j ]; 5259 this.direction = nearBottom ? "up": "down"; 5260 } 5261 } 5262 5263 //Check if dropOnEmpty is enabled 5264 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 5265 return; 5266 } 5267 5268 if(this.currentContainer === this.containers[innermostIndex]) { 5269 return; 5270 } 5271 5272 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 5273 this._trigger("change", event, this._uiHash()); 5274 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 5275 this.currentContainer = this.containers[innermostIndex]; 5276 5277 //Update the placeholder 5278 this.options.placeholder.update(this.currentContainer, this.placeholder); 5279 5280 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5281 this.containers[innermostIndex].containerCache.over = 1; 5282 } 5283 5284 5285 }, 5286 5287 _createHelper: function(event) { 5288 5289 var o = this.options, 5290 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 5291 5292 //Add the helper to the DOM if that didn't happen already 5293 if(!helper.parents("body").length) { 5294 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 5295 } 5296 5297 if(helper[0] === this.currentItem[0]) { 5298 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; 5299 } 5300 5301 if(!helper[0].style.width || o.forceHelperSize) { 5302 helper.width(this.currentItem.width()); 5303 } 5304 if(!helper[0].style.height || o.forceHelperSize) { 5305 helper.height(this.currentItem.height()); 5306 } 5307 5308 return helper; 5309 5310 }, 5311 5312 _adjustOffsetFromHelper: function(obj) { 5313 if (typeof obj === "string") { 5314 obj = obj.split(" "); 5315 } 5316 if ($.isArray(obj)) { 5317 obj = {left: +obj[0], top: +obj[1] || 0}; 5318 } 5319 if ("left" in obj) { 5320 this.offset.click.left = obj.left + this.margins.left; 5321 } 5322 if ("right" in obj) { 5323 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 5324 } 5325 if ("top" in obj) { 5326 this.offset.click.top = obj.top + this.margins.top; 5327 } 5328 if ("bottom" in obj) { 5329 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 5330 } 5331 }, 5332 5333 _getParentOffset: function() { 5334 5335 5336 //Get the offsetParent and cache its position 5337 this.offsetParent = this.helper.offsetParent(); 5338 var po = this.offsetParent.offset(); 5339 5340 // This is a special case where we need to modify a offset calculated on start, since the following happened: 5341 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 5342 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 5343 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 5344 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 5345 po.left += this.scrollParent.scrollLeft(); 5346 po.top += this.scrollParent.scrollTop(); 5347 } 5348 5349 // This needs to be actually done for all browsers, since pageX/pageY includes this information 5350 // with an ugly IE fix 5351 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 5352 po = { top: 0, left: 0 }; 5353 } 5354 5355 return { 5356 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 5357 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 5358 }; 5359 5360 }, 5361 5362 _getRelativeOffset: function() { 5363 5364 if(this.cssPosition === "relative") { 5365 var p = this.currentItem.position(); 5366 return { 5367 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 5368 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 5369 }; 5370 } else { 5371 return { top: 0, left: 0 }; 5372 } 5373 5374 }, 5375 5376 _cacheMargins: function() { 5377 this.margins = { 5378 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 5379 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 5380 }; 5381 }, 5382 5383 _cacheHelperProportions: function() { 5384 this.helperProportions = { 5385 width: this.helper.outerWidth(), 5386 height: this.helper.outerHeight() 5387 }; 5388 }, 5389 5390 _setContainment: function() { 5391 5392 var ce, co, over, 5393 o = this.options; 5394 if(o.containment === "parent") { 5395 o.containment = this.helper[0].parentNode; 5396 } 5397 if(o.containment === "document" || o.containment === "window") { 5398 this.containment = [ 5399 0 - this.offset.relative.left - this.offset.parent.left, 5400 0 - this.offset.relative.top - this.offset.parent.top, 5401 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 5402 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 5403 ]; 5404 } 5405 5406 if(!(/^(document|window|parent)$/).test(o.containment)) { 5407 ce = $(o.containment)[0]; 5408 co = $(o.containment).offset(); 5409 over = ($(ce).css("overflow") !== "hidden"); 5410 5411 this.containment = [ 5412 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 5413 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 5414 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, 5415 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 5416 ]; 5417 } 5418 5419 }, 5420 5421 _convertPositionTo: function(d, pos) { 5422 5423 if(!pos) { 5424 pos = this.position; 5425 } 5426 var mod = d === "absolute" ? 1 : -1, 5427 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 5428 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 5429 5430 return { 5431 top: ( 5432 pos.top + // The absolute mouse position 5433 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5434 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 5435 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 5436 ), 5437 left: ( 5438 pos.left + // The absolute mouse position 5439 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5440 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 5441 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 5442 ) 5443 }; 5444 5445 }, 5446 5447 _generatePosition: function(event) { 5448 5449 var top, left, 5450 o = this.options, 5451 pageX = event.pageX, 5452 pageY = event.pageY, 5453 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); 5454 5455 // This is another very weird special case that only happens for relative elements: 5456 // 1. If the css position is relative 5457 // 2. and the scroll parent is the document or similar to the offset parent 5458 // we have to refresh the relative offset during the scroll so there are no jumps 5459 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 5460 this.offset.relative = this._getRelativeOffset(); 5461 } 5462 5463 /* 5464 * - Position constraining - 5465 * Constrain the position to a mix of grid, containment. 5466 */ 5467 5468 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 5469 5470 if(this.containment) { 5471 if(event.pageX - this.offset.click.left < this.containment[0]) { 5472 pageX = this.containment[0] + this.offset.click.left; 5473 } 5474 if(event.pageY - this.offset.click.top < this.containment[1]) { 5475 pageY = this.containment[1] + this.offset.click.top; 5476 } 5477 if(event.pageX - this.offset.click.left > this.containment[2]) { 5478 pageX = this.containment[2] + this.offset.click.left; 5479 } 5480 if(event.pageY - this.offset.click.top > this.containment[3]) { 5481 pageY = this.containment[3] + this.offset.click.top; 5482 } 5483 } 5484 5485 if(o.grid) { 5486 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 5487 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; 5488 5489 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 5490 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; 5491 } 5492 5493 } 5494 5495 return { 5496 top: ( 5497 pageY - // The absolute mouse position 5498 this.offset.click.top - // Click offset (relative to the element) 5499 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 5500 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 5501 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 5502 ), 5503 left: ( 5504 pageX - // The absolute mouse position 5505 this.offset.click.left - // Click offset (relative to the element) 5506 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 5507 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 5508 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 5509 ) 5510 }; 5511 5512 }, 5513 5514 _rearrange: function(event, i, a, hardRefresh) { 5515 5516 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)); 5517 5518 //Various things done here to improve the performance: 5519 // 1. we create a setTimeout, that calls refreshPositions 5520 // 2. on the instance, we have a counter variable, that get's higher after every append 5521 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 5522 // 4. this lets only the last addition to the timeout stack through 5523 this.counter = this.counter ? ++this.counter : 1; 5524 var counter = this.counter; 5525 5526 this._delay(function() { 5527 if(counter === this.counter) { 5528 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 5529 } 5530 }); 5531 5532 }, 5533 5534 _clear: function(event, noPropagation) { 5535 5536 this.reverting = false; 5537 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 5538 // everything else normalized again 5539 var i, 5540 delayedTriggers = []; 5541 5542 // We first have to update the dom position of the actual currentItem 5543 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 5544 if(!this._noFinalSort && this.currentItem.parent().length) { 5545 this.placeholder.before(this.currentItem); 5546 } 5547 this._noFinalSort = null; 5548 5549 if(this.helper[0] === this.currentItem[0]) { 5550 for(i in this._storedCSS) { 5551 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 5552 this._storedCSS[i] = ""; 5553 } 5554 } 5555 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 5556 } else { 5557 this.currentItem.show(); 5558 } 5559 5560 if(this.fromOutside && !noPropagation) { 5561 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 5562 } 5563 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 5564 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 5565 } 5566 5567 // Check if the items Container has Changed and trigger appropriate 5568 // events. 5569 if (this !== this.currentContainer) { 5570 if(!noPropagation) { 5571 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 5572 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5573 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5574 } 5575 } 5576 5577 5578 //Post events to containers 5579 function delayEvent( type, instance, container ) { 5580 return function( event ) { 5581 container._trigger( type, event, instance._uiHash( instance ) ); 5582 }; 5583 } 5584 for (i = this.containers.length - 1; i >= 0; i--){ 5585 if (!noPropagation) { 5586 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 5587 } 5588 if(this.containers[i].containerCache.over) { 5589 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 5590 this.containers[i].containerCache.over = 0; 5591 } 5592 } 5593 5594 //Do what was originally in plugins 5595 if ( this.storedCursor ) { 5596 this.document.find( "body" ).css( "cursor", this.storedCursor ); 5597 this.storedStylesheet.remove(); 5598 } 5599 if(this._storedOpacity) { 5600 this.helper.css("opacity", this._storedOpacity); 5601 } 5602 if(this._storedZIndex) { 5603 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 5604 } 5605 5606 this.dragging = false; 5607 if(this.cancelHelperRemoval) { 5608 if(!noPropagation) { 5609 this._trigger("beforeStop", event, this._uiHash()); 5610 for (i=0; i < delayedTriggers.length; i++) { 5611 delayedTriggers[i].call(this, event); 5612 } //Trigger all delayed events 5613 this._trigger("stop", event, this._uiHash()); 5614 } 5615 5616 this.fromOutside = false; 5617 return false; 5618 } 5619 5620 if(!noPropagation) { 5621 this._trigger("beforeStop", event, this._uiHash()); 5622 } 5623 5624 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 5625 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 5626 5627 if(this.helper[0] !== this.currentItem[0]) { 5628 this.helper.remove(); 5629 } 5630 this.helper = null; 5631 5632 if(!noPropagation) { 5633 for (i=0; i < delayedTriggers.length; i++) { 5634 delayedTriggers[i].call(this, event); 5635 } //Trigger all delayed events 5636 this._trigger("stop", event, this._uiHash()); 5637 } 5638 5639 this.fromOutside = false; 5640 return true; 5641 5642 }, 5643 5644 _trigger: function() { 5645 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 5646 this.cancel(); 5647 } 5648 }, 5649 5650 _uiHash: function(_inst) { 5651 var inst = _inst || this; 5652 return { 5653 helper: inst.helper, 5654 placeholder: inst.placeholder || $([]), 5655 position: inst.position, 5656 originalPosition: inst.originalPosition, 5657 offset: inst.positionAbs, 5658 item: inst.currentItem, 5659 sender: _inst ? _inst.element : null 5660 }; 5661 } 5662 5663}); 5664 5665 5666/*! 5667 * jQuery UI Accordion 1.11.1 5668 * http://jqueryui.com 5669 * 5670 * Copyright 2014 jQuery Foundation and other contributors 5671 * Released under the MIT license. 5672 * http://jquery.org/license 5673 * 5674 * http://api.jqueryui.com/accordion/ 5675 */ 5676 5677 5678var accordion = $.widget( "ui.accordion", { 5679 version: "1.11.1", 5680 options: { 5681 active: 0, 5682 animate: {}, 5683 collapsible: false, 5684 event: "click", 5685 header: "> li > :first-child,> :not(li):even", 5686 heightStyle: "auto", 5687 icons: { 5688 activeHeader: "ui-icon-triangle-1-s", 5689 header: "ui-icon-triangle-1-e" 5690 }, 5691 5692 // callbacks 5693 activate: null, 5694 beforeActivate: null 5695 }, 5696 5697 hideProps: { 5698 borderTopWidth: "hide", 5699 borderBottomWidth: "hide", 5700 paddingTop: "hide", 5701 paddingBottom: "hide", 5702 height: "hide" 5703 }, 5704 5705 showProps: { 5706 borderTopWidth: "show", 5707 borderBottomWidth: "show", 5708 paddingTop: "show", 5709 paddingBottom: "show", 5710 height: "show" 5711 }, 5712 5713 _create: function() { 5714 var options = this.options; 5715 this.prevShow = this.prevHide = $(); 5716 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 5717 // ARIA 5718 .attr( "role", "tablist" ); 5719 5720 // don't allow collapsible: false and active: false / null 5721 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5722 options.active = 0; 5723 } 5724 5725 this._processPanels(); 5726 // handle negative values 5727 if ( options.active < 0 ) { 5728 options.active += this.headers.length; 5729 } 5730 this._refresh(); 5731 }, 5732 5733 _getCreateEventData: function() { 5734 return { 5735 header: this.active, 5736 panel: !this.active.length ? $() : this.active.next() 5737 }; 5738 }, 5739 5740 _createIcons: function() { 5741 var icons = this.options.icons; 5742 if ( icons ) { 5743 $( "<span>" ) 5744 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5745 .prependTo( this.headers ); 5746 this.active.children( ".ui-accordion-header-icon" ) 5747 .removeClass( icons.header ) 5748 .addClass( icons.activeHeader ); 5749 this.headers.addClass( "ui-accordion-icons" ); 5750 } 5751 }, 5752 5753 _destroyIcons: function() { 5754 this.headers 5755 .removeClass( "ui-accordion-icons" ) 5756 .children( ".ui-accordion-header-icon" ) 5757 .remove(); 5758 }, 5759 5760 _destroy: function() { 5761 var contents; 5762 5763 // clean up main element 5764 this.element 5765 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5766 .removeAttr( "role" ); 5767 5768 // clean up headers 5769 this.headers 5770 .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + 5771 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 5772 .removeAttr( "role" ) 5773 .removeAttr( "aria-expanded" ) 5774 .removeAttr( "aria-selected" ) 5775 .removeAttr( "aria-controls" ) 5776 .removeAttr( "tabIndex" ) 5777 .removeUniqueId(); 5778 5779 this._destroyIcons(); 5780 5781 // clean up content panels 5782 contents = this.headers.next() 5783 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + 5784 "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5785 .css( "display", "" ) 5786 .removeAttr( "role" ) 5787 .removeAttr( "aria-hidden" ) 5788 .removeAttr( "aria-labelledby" ) 5789 .removeUniqueId(); 5790 5791 if ( this.options.heightStyle !== "content" ) { 5792 contents.css( "height", "" ); 5793 } 5794 }, 5795 5796 _setOption: function( key, value ) { 5797 if ( key === "active" ) { 5798 // _activate() will handle invalid values and update this.options 5799 this._activate( value ); 5800 return; 5801 } 5802 5803 if ( key === "event" ) { 5804 if ( this.options.event ) { 5805 this._off( this.headers, this.options.event ); 5806 } 5807 this._setupEvents( value ); 5808 } 5809 5810 this._super( key, value ); 5811 5812 // setting collapsible: false while collapsed; open first panel 5813 if ( key === "collapsible" && !value && this.options.active === false ) { 5814 this._activate( 0 ); 5815 } 5816 5817 if ( key === "icons" ) { 5818 this._destroyIcons(); 5819 if ( value ) { 5820 this._createIcons(); 5821 } 5822 } 5823 5824 // #5332 - opacity doesn't cascade to positioned elements in IE 5825 // so we need to add the disabled class to the headers and panels 5826 if ( key === "disabled" ) { 5827 this.element 5828 .toggleClass( "ui-state-disabled", !!value ) 5829 .attr( "aria-disabled", value ); 5830 this.headers.add( this.headers.next() ) 5831 .toggleClass( "ui-state-disabled", !!value ); 5832 } 5833 }, 5834 5835 _keydown: function( event ) { 5836 if ( event.altKey || event.ctrlKey ) { 5837 return; 5838 } 5839 5840 var keyCode = $.ui.keyCode, 5841 length = this.headers.length, 5842 currentIndex = this.headers.index( event.target ), 5843 toFocus = false; 5844 5845 switch ( event.keyCode ) { 5846 case keyCode.RIGHT: 5847 case keyCode.DOWN: 5848 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5849 break; 5850 case keyCode.LEFT: 5851 case keyCode.UP: 5852 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5853 break; 5854 case keyCode.SPACE: 5855 case keyCode.ENTER: 5856 this._eventHandler( event ); 5857 break; 5858 case keyCode.HOME: 5859 toFocus = this.headers[ 0 ]; 5860 break; 5861 case keyCode.END: 5862 toFocus = this.headers[ length - 1 ]; 5863 break; 5864 } 5865 5866 if ( toFocus ) { 5867 $( event.target ).attr( "tabIndex", -1 ); 5868 $( toFocus ).attr( "tabIndex", 0 ); 5869 toFocus.focus(); 5870 event.preventDefault(); 5871 } 5872 }, 5873 5874 _panelKeyDown: function( event ) { 5875 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5876 $( event.currentTarget ).prev().focus(); 5877 } 5878 }, 5879 5880 refresh: function() { 5881 var options = this.options; 5882 this._processPanels(); 5883 5884 // was collapsed or no panel 5885 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 5886 options.active = false; 5887 this.active = $(); 5888 // active false only when collapsible is true 5889 } else if ( options.active === false ) { 5890 this._activate( 0 ); 5891 // was active, but active panel is gone 5892 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5893 // all remaining panel are disabled 5894 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 5895 options.active = false; 5896 this.active = $(); 5897 // activate previous panel 5898 } else { 5899 this._activate( Math.max( 0, options.active - 1 ) ); 5900 } 5901 // was active, active panel still exists 5902 } else { 5903 // make sure active index is correct 5904 options.active = this.headers.index( this.active ); 5905 } 5906 5907 this._destroyIcons(); 5908 5909 this._refresh(); 5910 }, 5911 5912 _processPanels: function() { 5913 this.headers = this.element.find( this.options.header ) 5914 .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); 5915 5916 this.headers.next() 5917 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 5918 .filter( ":not(.ui-accordion-content-active)" ) 5919 .hide(); 5920 }, 5921 5922 _refresh: function() { 5923 var maxHeight, 5924 options = this.options, 5925 heightStyle = options.heightStyle, 5926 parent = this.element.parent(); 5927 5928 this.active = this._findActive( options.active ) 5929 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 5930 .removeClass( "ui-corner-all" ); 5931 this.active.next() 5932 .addClass( "ui-accordion-content-active" ) 5933 .show(); 5934 5935 this.headers 5936 .attr( "role", "tab" ) 5937 .each(function() { 5938 var header = $( this ), 5939 headerId = header.uniqueId().attr( "id" ), 5940 panel = header.next(), 5941 panelId = panel.uniqueId().attr( "id" ); 5942 header.attr( "aria-controls", panelId ); 5943 panel.attr( "aria-labelledby", headerId ); 5944 }) 5945 .next() 5946 .attr( "role", "tabpanel" ); 5947 5948 this.headers 5949 .not( this.active ) 5950 .attr({ 5951 "aria-selected": "false", 5952 "aria-expanded": "false", 5953 tabIndex: -1 5954 }) 5955 .next() 5956 .attr({ 5957 "aria-hidden": "true" 5958 }) 5959 .hide(); 5960 5961 // make sure at least one header is in the tab order 5962 if ( !this.active.length ) { 5963 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5964 } else { 5965 this.active.attr({ 5966 "aria-selected": "true", 5967 "aria-expanded": "true", 5968 tabIndex: 0 5969 }) 5970 .next() 5971 .attr({ 5972 "aria-hidden": "false" 5973 }); 5974 } 5975 5976 this._createIcons(); 5977 5978 this._setupEvents( options.event ); 5979 5980 if ( heightStyle === "fill" ) { 5981 maxHeight = parent.height(); 5982 this.element.siblings( ":visible" ).each(function() { 5983 var elem = $( this ), 5984 position = elem.css( "position" ); 5985 5986 if ( position === "absolute" || position === "fixed" ) { 5987 return; 5988 } 5989 maxHeight -= elem.outerHeight( true ); 5990 }); 5991 5992 this.headers.each(function() { 5993 maxHeight -= $( this ).outerHeight( true ); 5994 }); 5995 5996 this.headers.next() 5997 .each(function() { 5998 $( this ).height( Math.max( 0, maxHeight - 5999 $( this ).innerHeight() + $( this ).height() ) ); 6000 }) 6001 .css( "overflow", "auto" ); 6002 } else if ( heightStyle === "auto" ) { 6003 maxHeight = 0; 6004 this.headers.next() 6005 .each(function() { 6006 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6007 }) 6008 .height( maxHeight ); 6009 } 6010 }, 6011 6012 _activate: function( index ) { 6013 var active = this._findActive( index )[ 0 ]; 6014 6015 // trying to activate the already active panel 6016 if ( active === this.active[ 0 ] ) { 6017 return; 6018 } 6019 6020 // trying to collapse, simulate a click on the currently active header 6021 active = active || this.active[ 0 ]; 6022 6023 this._eventHandler({ 6024 target: active, 6025 currentTarget: active, 6026 preventDefault: $.noop 6027 }); 6028 }, 6029 6030 _findActive: function( selector ) { 6031 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6032 }, 6033 6034 _setupEvents: function( event ) { 6035 var events = { 6036 keydown: "_keydown" 6037 }; 6038 if ( event ) { 6039 $.each( event.split( " " ), function( index, eventName ) { 6040 events[ eventName ] = "_eventHandler"; 6041 }); 6042 } 6043 6044 this._off( this.headers.add( this.headers.next() ) ); 6045 this._on( this.headers, events ); 6046 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6047 this._hoverable( this.headers ); 6048 this._focusable( this.headers ); 6049 }, 6050 6051 _eventHandler: function( event ) { 6052 var options = this.options, 6053 active = this.active, 6054 clicked = $( event.currentTarget ), 6055 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6056 collapsing = clickedIsActive && options.collapsible, 6057 toShow = collapsing ? $() : clicked.next(), 6058 toHide = active.next(), 6059 eventData = { 6060 oldHeader: active, 6061 oldPanel: toHide, 6062 newHeader: collapsing ? $() : clicked, 6063 newPanel: toShow 6064 }; 6065 6066 event.preventDefault(); 6067 6068 if ( 6069 // click on active header, but not collapsible 6070 ( clickedIsActive && !options.collapsible ) || 6071 // allow canceling activation 6072 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6073 return; 6074 } 6075 6076 options.active = collapsing ? false : this.headers.index( clicked ); 6077 6078 // when the call to ._toggle() comes after the class changes 6079 // it causes a very odd bug in IE 8 (see #6720) 6080 this.active = clickedIsActive ? $() : clicked; 6081 this._toggle( eventData ); 6082 6083 // switch classes 6084 // corner classes on the previously active header stay after the animation 6085 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6086 if ( options.icons ) { 6087 active.children( ".ui-accordion-header-icon" ) 6088 .removeClass( options.icons.activeHeader ) 6089 .addClass( options.icons.header ); 6090 } 6091 6092 if ( !clickedIsActive ) { 6093 clicked 6094 .removeClass( "ui-corner-all" ) 6095 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6096 if ( options.icons ) { 6097 clicked.children( ".ui-accordion-header-icon" ) 6098 .removeClass( options.icons.header ) 6099 .addClass( options.icons.activeHeader ); 6100 } 6101 6102 clicked 6103 .next() 6104 .addClass( "ui-accordion-content-active" ); 6105 } 6106 }, 6107 6108 _toggle: function( data ) { 6109 var toShow = data.newPanel, 6110 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6111 6112 // handle activating a panel during the animation for another activation 6113 this.prevShow.add( this.prevHide ).stop( true, true ); 6114 this.prevShow = toShow; 6115 this.prevHide = toHide; 6116 6117 if ( this.options.animate ) { 6118 this._animate( toShow, toHide, data ); 6119 } else { 6120 toHide.hide(); 6121 toShow.show(); 6122 this._toggleComplete( data ); 6123 } 6124 6125 toHide.attr({ 6126 "aria-hidden": "true" 6127 }); 6128 toHide.prev().attr( "aria-selected", "false" ); 6129 // if we're switching panels, remove the old header from the tab order 6130 // if we're opening from collapsed state, remove the previous header from the tab order 6131 // if we're collapsing, then keep the collapsing header in the tab order 6132 if ( toShow.length && toHide.length ) { 6133 toHide.prev().attr({ 6134 "tabIndex": -1, 6135 "aria-expanded": "false" 6136 }); 6137 } else if ( toShow.length ) { 6138 this.headers.filter(function() { 6139 return $( this ).attr( "tabIndex" ) === 0; 6140 }) 6141 .attr( "tabIndex", -1 ); 6142 } 6143 6144 toShow 6145 .attr( "aria-hidden", "false" ) 6146 .prev() 6147 .attr({ 6148 "aria-selected": "true", 6149 tabIndex: 0, 6150 "aria-expanded": "true" 6151 }); 6152 }, 6153 6154 _animate: function( toShow, toHide, data ) { 6155 var total, easing, duration, 6156 that = this, 6157 adjust = 0, 6158 down = toShow.length && 6159 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6160 animate = this.options.animate || {}, 6161 options = down && animate.down || animate, 6162 complete = function() { 6163 that._toggleComplete( data ); 6164 }; 6165 6166 if ( typeof options === "number" ) { 6167 duration = options; 6168 } 6169 if ( typeof options === "string" ) { 6170 easing = options; 6171 } 6172 // fall back from options to animation in case of partial down settings 6173 easing = easing || options.easing || animate.easing; 6174 duration = duration || options.duration || animate.duration; 6175 6176 if ( !toHide.length ) { 6177 return toShow.animate( this.showProps, duration, easing, complete ); 6178 } 6179 if ( !toShow.length ) { 6180 return toHide.animate( this.hideProps, duration, easing, complete ); 6181 } 6182 6183 total = toShow.show().outerHeight(); 6184 toHide.animate( this.hideProps, { 6185 duration: duration, 6186 easing: easing, 6187 step: function( now, fx ) { 6188 fx.now = Math.round( now ); 6189 } 6190 }); 6191 toShow 6192 .hide() 6193 .animate( this.showProps, { 6194 duration: duration, 6195 easing: easing, 6196 complete: complete, 6197 step: function( now, fx ) { 6198 fx.now = Math.round( now ); 6199 if ( fx.prop !== "height" ) { 6200 adjust += fx.now; 6201 } else if ( that.options.heightStyle !== "content" ) { 6202 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6203 adjust = 0; 6204 } 6205 } 6206 }); 6207 }, 6208 6209 _toggleComplete: function( data ) { 6210 var toHide = data.oldPanel; 6211 6212 toHide 6213 .removeClass( "ui-accordion-content-active" ) 6214 .prev() 6215 .removeClass( "ui-corner-top" ) 6216 .addClass( "ui-corner-all" ); 6217 6218 // Work around for rendering bug in IE (#5421) 6219 if ( toHide.length ) { 6220 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 6221 } 6222 this._trigger( "activate", null, data ); 6223 } 6224}); 6225 6226 6227/*! 6228 * jQuery UI Menu 1.11.1 6229 * http://jqueryui.com 6230 * 6231 * Copyright 2014 jQuery Foundation and other contributors 6232 * Released under the MIT license. 6233 * http://jquery.org/license 6234 * 6235 * http://api.jqueryui.com/menu/ 6236 */ 6237 6238 6239var menu = $.widget( "ui.menu", { 6240 version: "1.11.1", 6241 defaultElement: "<ul>", 6242 delay: 300, 6243 options: { 6244 icons: { 6245 submenu: "ui-icon-carat-1-e" 6246 }, 6247 items: "> *", 6248 menus: "ul", 6249 position: { 6250 my: "left-1 top", 6251 at: "right top" 6252 }, 6253 role: "menu", 6254 6255 // callbacks 6256 blur: null, 6257 focus: null, 6258 select: null 6259 }, 6260 6261 _create: function() { 6262 this.activeMenu = this.element; 6263 6264 // Flag used to prevent firing of the click handler 6265 // as the event bubbles up through nested menus 6266 this.mouseHandled = false; 6267 this.element 6268 .uniqueId() 6269 .addClass( "ui-menu ui-widget ui-widget-content" ) 6270 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 6271 .attr({ 6272 role: this.options.role, 6273 tabIndex: 0 6274 }); 6275 6276 if ( this.options.disabled ) { 6277 this.element 6278 .addClass( "ui-state-disabled" ) 6279 .attr( "aria-disabled", "true" ); 6280 } 6281 6282 this._on({ 6283 // Prevent focus from sticking to links inside menu after clicking 6284 // them (focus should always stay on UL during navigation). 6285 "mousedown .ui-menu-item": function( event ) { 6286 event.preventDefault(); 6287 }, 6288 "click .ui-menu-item": function( event ) { 6289 var target = $( event.target ); 6290 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 6291 this.select( event ); 6292 6293 // Only set the mouseHandled flag if the event will bubble, see #9469. 6294 if ( !event.isPropagationStopped() ) { 6295 this.mouseHandled = true; 6296 } 6297 6298 // Open submenu on click 6299 if ( target.has( ".ui-menu" ).length ) { 6300 this.expand( event ); 6301 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 6302 6303 // Redirect focus to the menu 6304 this.element.trigger( "focus", [ true ] ); 6305 6306 // If the active item is on the top level, let it stay active. 6307 // Otherwise, blur the active item since it is no longer visible. 6308 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 6309 clearTimeout( this.timer ); 6310 } 6311 } 6312 } 6313 }, 6314 "mouseenter .ui-menu-item": function( event ) { 6315 var target = $( event.currentTarget ); 6316 // Remove ui-state-active class from siblings of the newly focused menu item 6317 // to avoid a jump caused by adjacent elements both having a class with a border 6318 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); 6319 this.focus( event, target ); 6320 }, 6321 mouseleave: "collapseAll", 6322 "mouseleave .ui-menu": "collapseAll", 6323 focus: function( event, keepActiveItem ) { 6324 // If there's already an active item, keep it active 6325 // If not, activate the first item 6326 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 6327 6328 if ( !keepActiveItem ) { 6329 this.focus( event, item ); 6330 } 6331 }, 6332 blur: function( event ) { 6333 this._delay(function() { 6334 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 6335 this.collapseAll( event ); 6336 } 6337 }); 6338 }, 6339 keydown: "_keydown" 6340 }); 6341 6342 this.refresh(); 6343 6344 // Clicks outside of a menu collapse any open menus 6345 this._on( this.document, { 6346 click: function( event ) { 6347 if ( this._closeOnDocumentClick( event ) ) { 6348 this.collapseAll( event ); 6349 } 6350 6351 // Reset the mouseHandled flag 6352 this.mouseHandled = false; 6353 } 6354 }); 6355 }, 6356 6357 _destroy: function() { 6358 // Destroy (sub)menus 6359 this.element 6360 .removeAttr( "aria-activedescendant" ) 6361 .find( ".ui-menu" ).addBack() 6362 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) 6363 .removeAttr( "role" ) 6364 .removeAttr( "tabIndex" ) 6365 .removeAttr( "aria-labelledby" ) 6366 .removeAttr( "aria-expanded" ) 6367 .removeAttr( "aria-hidden" ) 6368 .removeAttr( "aria-disabled" ) 6369 .removeUniqueId() 6370 .show(); 6371 6372 // Destroy menu items 6373 this.element.find( ".ui-menu-item" ) 6374 .removeClass( "ui-menu-item" ) 6375 .removeAttr( "role" ) 6376 .removeAttr( "aria-disabled" ) 6377 .removeUniqueId() 6378 .removeClass( "ui-state-hover" ) 6379 .removeAttr( "tabIndex" ) 6380 .removeAttr( "role" ) 6381 .removeAttr( "aria-haspopup" ) 6382 .children().each( function() { 6383 var elem = $( this ); 6384 if ( elem.data( "ui-menu-submenu-carat" ) ) { 6385 elem.remove(); 6386 } 6387 }); 6388 6389 // Destroy menu dividers 6390 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 6391 }, 6392 6393 _keydown: function( event ) { 6394 var match, prev, character, skip, regex, 6395 preventDefault = true; 6396 6397 function escape( value ) { 6398 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 6399 } 6400 6401 switch ( event.keyCode ) { 6402 case $.ui.keyCode.PAGE_UP: 6403 this.previousPage( event ); 6404 break; 6405 case $.ui.keyCode.PAGE_DOWN: 6406 this.nextPage( event ); 6407 break; 6408 case $.ui.keyCode.HOME: 6409 this._move( "first", "first", event ); 6410 break; 6411 case $.ui.keyCode.END: 6412 this._move( "last", "last", event ); 6413 break; 6414 case $.ui.keyCode.UP: 6415 this.previous( event ); 6416 break; 6417 case $.ui.keyCode.DOWN: 6418 this.next( event ); 6419 break; 6420 case $.ui.keyCode.LEFT: 6421 this.collapse( event ); 6422 break; 6423 case $.ui.keyCode.RIGHT: 6424 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 6425 this.expand( event ); 6426 } 6427 break; 6428 case $.ui.keyCode.ENTER: 6429 case $.ui.keyCode.SPACE: 6430 this._activate( event ); 6431 break; 6432 case $.ui.keyCode.ESCAPE: 6433 this.collapse( event ); 6434 break; 6435 default: 6436 preventDefault = false; 6437 prev = this.previousFilter || ""; 6438 character = String.fromCharCode( event.keyCode ); 6439 skip = false; 6440 6441 clearTimeout( this.filterTimer ); 6442 6443 if ( character === prev ) { 6444 skip = true; 6445 } else { 6446 character = prev + character; 6447 } 6448 6449 regex = new RegExp( "^" + escape( character ), "i" ); 6450 match = this.activeMenu.find( this.options.items ).filter(function() { 6451 return regex.test( $( this ).text() ); 6452 }); 6453 match = skip && match.index( this.active.next() ) !== -1 ? 6454 this.active.nextAll( ".ui-menu-item" ) : 6455 match; 6456 6457 // If no matches on the current filter, reset to the last character pressed 6458 // to move down the menu to the first item that starts with that character 6459 if ( !match.length ) { 6460 character = String.fromCharCode( event.keyCode ); 6461 regex = new RegExp( "^" + escape( character ), "i" ); 6462 match = this.activeMenu.find( this.options.items ).filter(function() { 6463 return regex.test( $( this ).text() ); 6464 }); 6465 } 6466 6467 if ( match.length ) { 6468 this.focus( event, match ); 6469 if ( match.length > 1 ) { 6470 this.previousFilter = character; 6471 this.filterTimer = this._delay(function() { 6472 delete this.previousFilter; 6473 }, 1000 ); 6474 } else { 6475 delete this.previousFilter; 6476 } 6477 } else { 6478 delete this.previousFilter; 6479 } 6480 } 6481 6482 if ( preventDefault ) { 6483 event.preventDefault(); 6484 } 6485 }, 6486 6487 _activate: function( event ) { 6488 if ( !this.active.is( ".ui-state-disabled" ) ) { 6489 if ( this.active.is( "[aria-haspopup='true']" ) ) { 6490 this.expand( event ); 6491 } else { 6492 this.select( event ); 6493 } 6494 } 6495 }, 6496 6497 refresh: function() { 6498 var menus, items, 6499 that = this, 6500 icon = this.options.icons.submenu, 6501 submenus = this.element.find( this.options.menus ); 6502 6503 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 6504 6505 // Initialize nested menus 6506 submenus.filter( ":not(.ui-menu)" ) 6507 .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) 6508 .hide() 6509 .attr({ 6510 role: this.options.role, 6511 "aria-hidden": "true", 6512 "aria-expanded": "false" 6513 }) 6514 .each(function() { 6515 var menu = $( this ), 6516 item = menu.parent(), 6517 submenuCarat = $( "<span>" ) 6518 .addClass( "ui-menu-icon ui-icon " + icon ) 6519 .data( "ui-menu-submenu-carat", true ); 6520 6521 item 6522 .attr( "aria-haspopup", "true" ) 6523 .prepend( submenuCarat ); 6524 menu.attr( "aria-labelledby", item.attr( "id" ) ); 6525 }); 6526 6527 menus = submenus.add( this.element ); 6528 items = menus.find( this.options.items ); 6529 6530 // Initialize menu-items containing spaces and/or dashes only as dividers 6531 items.not( ".ui-menu-item" ).each(function() { 6532 var item = $( this ); 6533 if ( that._isDivider( item ) ) { 6534 item.addClass( "ui-widget-content ui-menu-divider" ); 6535 } 6536 }); 6537 6538 // Don't refresh list items that are already adapted 6539 items.not( ".ui-menu-item, .ui-menu-divider" ) 6540 .addClass( "ui-menu-item" ) 6541 .uniqueId() 6542 .attr({ 6543 tabIndex: -1, 6544 role: this._itemRole() 6545 }); 6546 6547 // Add aria-disabled attribute to any disabled menu item 6548 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 6549 6550 // If the active item has been removed, blur the menu 6551 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6552 this.blur(); 6553 } 6554 }, 6555 6556 _itemRole: function() { 6557 return { 6558 menu: "menuitem", 6559 listbox: "option" 6560 }[ this.options.role ]; 6561 }, 6562 6563 _setOption: function( key, value ) { 6564 if ( key === "icons" ) { 6565 this.element.find( ".ui-menu-icon" ) 6566 .removeClass( this.options.icons.submenu ) 6567 .addClass( value.submenu ); 6568 } 6569 if ( key === "disabled" ) { 6570 this.element 6571 .toggleClass( "ui-state-disabled", !!value ) 6572 .attr( "aria-disabled", value ); 6573 } 6574 this._super( key, value ); 6575 }, 6576 6577 focus: function( event, item ) { 6578 var nested, focused; 6579 this.blur( event, event && event.type === "focus" ); 6580 6581 this._scrollIntoView( item ); 6582 6583 this.active = item.first(); 6584 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); 6585 // Only update aria-activedescendant if there's a role 6586 // otherwise we assume focus is managed elsewhere 6587 if ( this.options.role ) { 6588 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 6589 } 6590 6591 // Highlight active parent menu item, if any 6592 this.active 6593 .parent() 6594 .closest( ".ui-menu-item" ) 6595 .addClass( "ui-state-active" ); 6596 6597 if ( event && event.type === "keydown" ) { 6598 this._close(); 6599 } else { 6600 this.timer = this._delay(function() { 6601 this._close(); 6602 }, this.delay ); 6603 } 6604 6605 nested = item.children( ".ui-menu" ); 6606 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 6607 this._startOpening(nested); 6608 } 6609 this.activeMenu = item.parent(); 6610 6611 this._trigger( "focus", event, { item: item } ); 6612 }, 6613 6614 _scrollIntoView: function( item ) { 6615 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 6616 if ( this._hasScroll() ) { 6617 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 6618 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 6619 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 6620 scroll = this.activeMenu.scrollTop(); 6621 elementHeight = this.activeMenu.height(); 6622 itemHeight = item.outerHeight(); 6623 6624 if ( offset < 0 ) { 6625 this.activeMenu.scrollTop( scroll + offset ); 6626 } else if ( offset + itemHeight > elementHeight ) { 6627 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 6628 } 6629 } 6630 }, 6631 6632 blur: function( event, fromFocus ) { 6633 if ( !fromFocus ) { 6634 clearTimeout( this.timer ); 6635 } 6636 6637 if ( !this.active ) { 6638 return; 6639 } 6640 6641 this.active.removeClass( "ui-state-focus" ); 6642 this.active = null; 6643 6644 this._trigger( "blur", event, { item: this.active } ); 6645 }, 6646 6647 _startOpening: function( submenu ) { 6648 clearTimeout( this.timer ); 6649 6650 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 6651 // shift in the submenu position when mousing over the carat icon 6652 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 6653 return; 6654 } 6655 6656 this.timer = this._delay(function() { 6657 this._close(); 6658 this._open( submenu ); 6659 }, this.delay ); 6660 }, 6661 6662 _open: function( submenu ) { 6663 var position = $.extend({ 6664 of: this.active 6665 }, this.options.position ); 6666 6667 clearTimeout( this.timer ); 6668 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 6669 .hide() 6670 .attr( "aria-hidden", "true" ); 6671 6672 submenu 6673 .show() 6674 .removeAttr( "aria-hidden" ) 6675 .attr( "aria-expanded", "true" ) 6676 .position( position ); 6677 }, 6678 6679 collapseAll: function( event, all ) { 6680 clearTimeout( this.timer ); 6681 this.timer = this._delay(function() { 6682 // If we were passed an event, look for the submenu that contains the event 6683 var currentMenu = all ? this.element : 6684 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 6685 6686 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 6687 if ( !currentMenu.length ) { 6688 currentMenu = this.element; 6689 } 6690 6691 this._close( currentMenu ); 6692 6693 this.blur( event ); 6694 this.activeMenu = currentMenu; 6695 }, this.delay ); 6696 }, 6697 6698 // With no arguments, closes the currently active menu - if nothing is active 6699 // it closes all menus. If passed an argument, it will search for menus BELOW 6700 _close: function( startMenu ) { 6701 if ( !startMenu ) { 6702 startMenu = this.active ? this.active.parent() : this.element; 6703 } 6704 6705 startMenu 6706 .find( ".ui-menu" ) 6707 .hide() 6708 .attr( "aria-hidden", "true" ) 6709 .attr( "aria-expanded", "false" ) 6710 .end() 6711 .find( ".ui-state-active" ).not( ".ui-state-focus" ) 6712 .removeClass( "ui-state-active" ); 6713 }, 6714 6715 _closeOnDocumentClick: function( event ) { 6716 return !$( event.target ).closest( ".ui-menu" ).length; 6717 }, 6718 6719 _isDivider: function( item ) { 6720 6721 // Match hyphen, em dash, en dash 6722 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 6723 }, 6724 6725 collapse: function( event ) { 6726 var newItem = this.active && 6727 this.active.parent().closest( ".ui-menu-item", this.element ); 6728 if ( newItem && newItem.length ) { 6729 this._close(); 6730 this.focus( event, newItem ); 6731 } 6732 }, 6733 6734 expand: function( event ) { 6735 var newItem = this.active && 6736 this.active 6737 .children( ".ui-menu " ) 6738 .find( this.options.items ) 6739 .first(); 6740 6741 if ( newItem && newItem.length ) { 6742 this._open( newItem.parent() ); 6743 6744 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 6745 this._delay(function() { 6746 this.focus( event, newItem ); 6747 }); 6748 } 6749 }, 6750 6751 next: function( event ) { 6752 this._move( "next", "first", event ); 6753 }, 6754 6755 previous: function( event ) { 6756 this._move( "prev", "last", event ); 6757 }, 6758 6759 isFirstItem: function() { 6760 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 6761 }, 6762 6763 isLastItem: function() { 6764 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 6765 }, 6766 6767 _move: function( direction, filter, event ) { 6768 var next; 6769 if ( this.active ) { 6770 if ( direction === "first" || direction === "last" ) { 6771 next = this.active 6772 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 6773 .eq( -1 ); 6774 } else { 6775 next = this.active 6776 [ direction + "All" ]( ".ui-menu-item" ) 6777 .eq( 0 ); 6778 } 6779 } 6780 if ( !next || !next.length || !this.active ) { 6781 next = this.activeMenu.find( this.options.items )[ filter ](); 6782 } 6783 6784 this.focus( event, next ); 6785 }, 6786 6787 nextPage: function( event ) { 6788 var item, base, height; 6789 6790 if ( !this.active ) { 6791 this.next( event ); 6792 return; 6793 } 6794 if ( this.isLastItem() ) { 6795 return; 6796 } 6797 if ( this._hasScroll() ) { 6798 base = this.active.offset().top; 6799 height = this.element.height(); 6800 this.active.nextAll( ".ui-menu-item" ).each(function() { 6801 item = $( this ); 6802 return item.offset().top - base - height < 0; 6803 }); 6804 6805 this.focus( event, item ); 6806 } else { 6807 this.focus( event, this.activeMenu.find( this.options.items ) 6808 [ !this.active ? "first" : "last" ]() ); 6809 } 6810 }, 6811 6812 previousPage: function( event ) { 6813 var item, base, height; 6814 if ( !this.active ) { 6815 this.next( event ); 6816 return; 6817 } 6818 if ( this.isFirstItem() ) { 6819 return; 6820 } 6821 if ( this._hasScroll() ) { 6822 base = this.active.offset().top; 6823 height = this.element.height(); 6824 this.active.prevAll( ".ui-menu-item" ).each(function() { 6825 item = $( this ); 6826 return item.offset().top - base + height > 0; 6827 }); 6828 6829 this.focus( event, item ); 6830 } else { 6831 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 6832 } 6833 }, 6834 6835 _hasScroll: function() { 6836 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 6837 }, 6838 6839 select: function( event ) { 6840 // TODO: It should never be possible to not have an active item at this 6841 // point, but the tests don't trigger mouseenter before click. 6842 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 6843 var ui = { item: this.active }; 6844 if ( !this.active.has( ".ui-menu" ).length ) { 6845 this.collapseAll( event, true ); 6846 } 6847 this._trigger( "select", event, ui ); 6848 } 6849}); 6850 6851 6852/*! 6853 * jQuery UI Autocomplete 1.11.1 6854 * http://jqueryui.com 6855 * 6856 * Copyright 2014 jQuery Foundation and other contributors 6857 * Released under the MIT license. 6858 * http://jquery.org/license 6859 * 6860 * http://api.jqueryui.com/autocomplete/ 6861 */ 6862 6863 6864$.widget( "ui.autocomplete", { 6865 version: "1.11.1", 6866 defaultElement: "<input>", 6867 options: { 6868 appendTo: null, 6869 autoFocus: false, 6870 delay: 300, 6871 minLength: 1, 6872 position: { 6873 my: "left top", 6874 at: "left bottom", 6875 collision: "none" 6876 }, 6877 source: null, 6878 6879 // callbacks 6880 change: null, 6881 close: null, 6882 focus: null, 6883 open: null, 6884 response: null, 6885 search: null, 6886 select: null 6887 }, 6888 6889 requestIndex: 0, 6890 pending: 0, 6891 6892 _create: function() { 6893 // Some browsers only repeat keydown events, not keypress events, 6894 // so we use the suppressKeyPress flag to determine if we've already 6895 // handled the keydown event. #7269 6896 // Unfortunately the code for & in keypress is the same as the up arrow, 6897 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6898 // events when we know the keydown event was used to modify the 6899 // search term. #7799 6900 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6901 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 6902 isTextarea = nodeName === "textarea", 6903 isInput = nodeName === "input"; 6904 6905 this.isMultiLine = 6906 // Textareas are always multi-line 6907 isTextarea ? true : 6908 // Inputs are always single-line, even if inside a contentEditable element 6909 // IE also treats inputs as contentEditable 6910 isInput ? false : 6911 // All other element types are determined by whether or not they're contentEditable 6912 this.element.prop( "isContentEditable" ); 6913 6914 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6915 this.isNewMenu = true; 6916 6917 this.element 6918 .addClass( "ui-autocomplete-input" ) 6919 .attr( "autocomplete", "off" ); 6920 6921 this._on( this.element, { 6922 keydown: function( event ) { 6923 if ( this.element.prop( "readOnly" ) ) { 6924 suppressKeyPress = true; 6925 suppressInput = true; 6926 suppressKeyPressRepeat = true; 6927 return; 6928 } 6929 6930 suppressKeyPress = false; 6931 suppressInput = false; 6932 suppressKeyPressRepeat = false; 6933 var keyCode = $.ui.keyCode; 6934 switch ( event.keyCode ) { 6935 case keyCode.PAGE_UP: 6936 suppressKeyPress = true; 6937 this._move( "previousPage", event ); 6938 break; 6939 case keyCode.PAGE_DOWN: 6940 suppressKeyPress = true; 6941 this._move( "nextPage", event ); 6942 break; 6943 case keyCode.UP: 6944 suppressKeyPress = true; 6945 this._keyEvent( "previous", event ); 6946 break; 6947 case keyCode.DOWN: 6948 suppressKeyPress = true; 6949 this._keyEvent( "next", event ); 6950 break; 6951 case keyCode.ENTER: 6952 // when menu is open and has focus 6953 if ( this.menu.active ) { 6954 // #6055 - Opera still allows the keypress to occur 6955 // which causes forms to submit 6956 suppressKeyPress = true; 6957 event.preventDefault(); 6958 this.menu.select( event ); 6959 } 6960 break; 6961 case keyCode.TAB: 6962 if ( this.menu.active ) { 6963 this.menu.select( event ); 6964 } 6965 break; 6966 case keyCode.ESCAPE: 6967 if ( this.menu.element.is( ":visible" ) ) { 6968 if ( !this.isMultiLine ) { 6969 this._value( this.term ); 6970 } 6971 this.close( event ); 6972 // Different browsers have different default behavior for escape 6973 // Single press can mean undo or clear 6974 // Double press in IE means clear the whole form 6975 event.preventDefault(); 6976 } 6977 break; 6978 default: 6979 suppressKeyPressRepeat = true; 6980 // search timeout should be triggered before the input value is changed 6981 this._searchTimeout( event ); 6982 break; 6983 } 6984 }, 6985 keypress: function( event ) { 6986 if ( suppressKeyPress ) { 6987 suppressKeyPress = false; 6988 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6989 event.preventDefault(); 6990 } 6991 return; 6992 } 6993 if ( suppressKeyPressRepeat ) { 6994 return; 6995 } 6996 6997 // replicate some key handlers to allow them to repeat in Firefox and Opera 6998 var keyCode = $.ui.keyCode; 6999 switch ( event.keyCode ) { 7000 case keyCode.PAGE_UP: 7001 this._move( "previousPage", event ); 7002 break; 7003 case keyCode.PAGE_DOWN: 7004 this._move( "nextPage", event ); 7005 break; 7006 case keyCode.UP: 7007 this._keyEvent( "previous", event ); 7008 break; 7009 case keyCode.DOWN: 7010 this._keyEvent( "next", event ); 7011 break; 7012 } 7013 }, 7014 input: function( event ) { 7015 if ( suppressInput ) { 7016 suppressInput = false; 7017 event.preventDefault(); 7018 return; 7019 } 7020 this._searchTimeout( event ); 7021 }, 7022 focus: function() { 7023 this.selectedItem = null; 7024 this.previous = this._value(); 7025 }, 7026 blur: function( event ) { 7027 if ( this.cancelBlur ) { 7028 delete this.cancelBlur; 7029 return; 7030 } 7031 7032 clearTimeout( this.searching ); 7033 this.close( event ); 7034 this._change( event ); 7035 } 7036 }); 7037 7038 this._initSource(); 7039 this.menu = $( "<ul>" ) 7040 .addClass( "ui-autocomplete ui-front" ) 7041 .appendTo( this._appendTo() ) 7042 .menu({ 7043 // disable ARIA support, the live region takes care of that 7044 role: null 7045 }) 7046 .hide() 7047 .menu( "instance" ); 7048 7049 this._on( this.menu.element, { 7050 mousedown: function( event ) { 7051 // prevent moving focus out of the text field 7052 event.preventDefault(); 7053 7054 // IE doesn't prevent moving focus even with event.preventDefault() 7055 // so we set a flag to know when we should ignore the blur event 7056 this.cancelBlur = true; 7057 this._delay(function() { 7058 delete this.cancelBlur; 7059 }); 7060 7061 // clicking on the scrollbar causes focus to shift to the body 7062 // but we can't detect a mouseup or a click immediately afterward 7063 // so we have to track the next mousedown and close the menu if 7064 // the user clicks somewhere outside of the autocomplete 7065 var menuElement = this.menu.element[ 0 ]; 7066 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 7067 this._delay(function() { 7068 var that = this; 7069 this.document.one( "mousedown", function( event ) { 7070 if ( event.target !== that.element[ 0 ] && 7071 event.target !== menuElement && 7072 !$.contains( menuElement, event.target ) ) { 7073 that.close(); 7074 } 7075 }); 7076 }); 7077 } 7078 }, 7079 menufocus: function( event, ui ) { 7080 var label, item; 7081 // support: Firefox 7082 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 7083 if ( this.isNewMenu ) { 7084 this.isNewMenu = false; 7085 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 7086 this.menu.blur(); 7087 7088 this.document.one( "mousemove", function() { 7089 $( event.target ).trigger( event.originalEvent ); 7090 }); 7091 7092 return; 7093 } 7094 } 7095 7096 item = ui.item.data( "ui-autocomplete-item" ); 7097 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 7098 // use value to match what will end up in the input, if it was a key event 7099 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 7100 this._value( item.value ); 7101 } 7102 } 7103 7104 // Announce the value in the liveRegion 7105 label = ui.item.attr( "aria-label" ) || item.value; 7106 if ( label && $.trim( label ).length ) { 7107 this.liveRegion.children().hide(); 7108 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 7109 } 7110 }, 7111 menuselect: function( event, ui ) { 7112 var item = ui.item.data( "ui-autocomplete-item" ), 7113 previous = this.previous; 7114 7115 // only trigger when focus was lost (click on menu) 7116 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 7117 this.element.focus(); 7118 this.previous = previous; 7119 // #6109 - IE triggers two focus events and the second 7120 // is asynchronous, so we need to reset the previous 7121 // term synchronously and asynchronously :-( 7122 this._delay(function() { 7123 this.previous = previous; 7124 this.selectedItem = item; 7125 }); 7126 } 7127 7128 if ( false !== this._trigger( "select", event, { item: item } ) ) { 7129 this._value( item.value ); 7130 } 7131 // reset the term after the select event 7132 // this allows custom select handling to work properly 7133 this.term = this._value(); 7134 7135 this.close( event ); 7136 this.selectedItem = item; 7137 } 7138 }); 7139 7140 this.liveRegion = $( "<span>", { 7141 role: "status", 7142 "aria-live": "assertive", 7143 "aria-relevant": "additions" 7144 }) 7145 .addClass( "ui-helper-hidden-accessible" ) 7146 .appendTo( this.document[ 0 ].body ); 7147 7148 // turning off autocomplete prevents the browser from remembering the 7149 // value when navigating through history, so we re-enable autocomplete 7150 // if the page is unloaded before the widget is destroyed. #7790 7151 this._on( this.window, { 7152 beforeunload: function() { 7153 this.element.removeAttr( "autocomplete" ); 7154 } 7155 }); 7156 }, 7157 7158 _destroy: function() { 7159 clearTimeout( this.searching ); 7160 this.element 7161 .removeClass( "ui-autocomplete-input" ) 7162 .removeAttr( "autocomplete" ); 7163 this.menu.element.remove(); 7164 this.liveRegion.remove(); 7165 }, 7166 7167 _setOption: function( key, value ) { 7168 this._super( key, value ); 7169 if ( key === "source" ) { 7170 this._initSource(); 7171 } 7172 if ( key === "appendTo" ) { 7173 this.menu.element.appendTo( this._appendTo() ); 7174 } 7175 if ( key === "disabled" && value && this.xhr ) { 7176 this.xhr.abort(); 7177 } 7178 }, 7179 7180 _appendTo: function() { 7181 var element = this.options.appendTo; 7182 7183 if ( element ) { 7184 element = element.jquery || element.nodeType ? 7185 $( element ) : 7186 this.document.find( element ).eq( 0 ); 7187 } 7188 7189 if ( !element || !element[ 0 ] ) { 7190 element = this.element.closest( ".ui-front" ); 7191 } 7192 7193 if ( !element.length ) { 7194 element = this.document[ 0 ].body; 7195 } 7196 7197 return element; 7198 }, 7199 7200 _initSource: function() { 7201 var array, url, 7202 that = this; 7203 if ( $.isArray( this.options.source ) ) { 7204 array = this.options.source; 7205 this.source = function( request, response ) { 7206 response( $.ui.autocomplete.filter( array, request.term ) ); 7207 }; 7208 } else if ( typeof this.options.source === "string" ) { 7209 url = this.options.source; 7210 this.source = function( request, response ) { 7211 if ( that.xhr ) { 7212 that.xhr.abort(); 7213 } 7214 that.xhr = $.ajax({ 7215 url: url, 7216 data: request, 7217 dataType: "json", 7218 success: function( data ) { 7219 response( data ); 7220 }, 7221 error: function() { 7222 response([]); 7223 } 7224 }); 7225 }; 7226 } else { 7227 this.source = this.options.source; 7228 } 7229 }, 7230 7231 _searchTimeout: function( event ) { 7232 clearTimeout( this.searching ); 7233 this.searching = this._delay(function() { 7234 7235 // Search if the value has changed, or if the user retypes the same value (see #7434) 7236 var equalValues = this.term === this._value(), 7237 menuVisible = this.menu.element.is( ":visible" ), 7238 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 7239 7240 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 7241 this.selectedItem = null; 7242 this.search( null, event ); 7243 } 7244 }, this.options.delay ); 7245 }, 7246 7247 search: function( value, event ) { 7248 value = value != null ? value : this._value(); 7249 7250 // always save the actual value, not the one passed as an argument 7251 this.term = this._value(); 7252 7253 if ( value.length < this.options.minLength ) { 7254 return this.close( event ); 7255 } 7256 7257 if ( this._trigger( "search", event ) === false ) { 7258 return; 7259 } 7260 7261 return this._search( value ); 7262 }, 7263 7264 _search: function( value ) { 7265 this.pending++; 7266 this.element.addClass( "ui-autocomplete-loading" ); 7267 this.cancelSearch = false; 7268 7269 this.source( { term: value }, this._response() ); 7270 }, 7271 7272 _response: function() { 7273 var index = ++this.requestIndex; 7274 7275 return $.proxy(function( content ) { 7276 if ( index === this.requestIndex ) { 7277 this.__response( content ); 7278 } 7279 7280 this.pending--; 7281 if ( !this.pending ) { 7282 this.element.removeClass( "ui-autocomplete-loading" ); 7283 } 7284 }, this ); 7285 }, 7286 7287 __response: function( content ) { 7288 if ( content ) { 7289 content = this._normalize( content ); 7290 } 7291 this._trigger( "response", null, { content: content } ); 7292 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7293 this._suggest( content ); 7294 this._trigger( "open" ); 7295 } else { 7296 // use ._close() instead of .close() so we don't cancel future searches 7297 this._close(); 7298 } 7299 }, 7300 7301 close: function( event ) { 7302 this.cancelSearch = true; 7303 this._close( event ); 7304 }, 7305 7306 _close: function( event ) { 7307 if ( this.menu.element.is( ":visible" ) ) { 7308 this.menu.element.hide(); 7309 this.menu.blur(); 7310 this.isNewMenu = true; 7311 this._trigger( "close", event ); 7312 } 7313 }, 7314 7315 _change: function( event ) { 7316 if ( this.previous !== this._value() ) { 7317 this._trigger( "change", event, { item: this.selectedItem } ); 7318 } 7319 }, 7320 7321 _normalize: function( items ) { 7322 // assume all items have the right format when the first item is complete 7323 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 7324 return items; 7325 } 7326 return $.map( items, function( item ) { 7327 if ( typeof item === "string" ) { 7328 return { 7329 label: item, 7330 value: item 7331 }; 7332 } 7333 return $.extend( {}, item, { 7334 label: item.label || item.value, 7335 value: item.value || item.label 7336 }); 7337 }); 7338 }, 7339 7340 _suggest: function( items ) { 7341 var ul = this.menu.element.empty(); 7342 this._renderMenu( ul, items ); 7343 this.isNewMenu = true; 7344 this.menu.refresh(); 7345 7346 // size and position menu 7347 ul.show(); 7348 this._resizeMenu(); 7349 ul.position( $.extend({ 7350 of: this.element 7351 }, this.options.position ) ); 7352 7353 if ( this.options.autoFocus ) { 7354 this.menu.next(); 7355 } 7356 }, 7357 7358 _resizeMenu: function() { 7359 var ul = this.menu.element; 7360 ul.outerWidth( Math.max( 7361 // Firefox wraps long text (possibly a rounding bug) 7362 // so we add 1px to avoid the wrapping (#7513) 7363 ul.width( "" ).outerWidth() + 1, 7364 this.element.outerWidth() 7365 ) ); 7366 }, 7367 7368 _renderMenu: function( ul, items ) { 7369 var that = this; 7370 $.each( items, function( index, item ) { 7371 that._renderItemData( ul, item ); 7372 }); 7373 }, 7374 7375 _renderItemData: function( ul, item ) { 7376 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7377 }, 7378 7379 _renderItem: function( ul, item ) { 7380 return $( "<li>" ).text( item.label ).appendTo( ul ); 7381 }, 7382 7383 _move: function( direction, event ) { 7384 if ( !this.menu.element.is( ":visible" ) ) { 7385 this.search( null, event ); 7386 return; 7387 } 7388 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7389 this.menu.isLastItem() && /^next/.test( direction ) ) { 7390 7391 if ( !this.isMultiLine ) { 7392 this._value( this.term ); 7393 } 7394 7395 this.menu.blur(); 7396 return; 7397 } 7398 this.menu[ direction ]( event ); 7399 }, 7400 7401 widget: function() { 7402 return this.menu.element; 7403 }, 7404 7405 _value: function() { 7406 return this.valueMethod.apply( this.element, arguments ); 7407 }, 7408 7409 _keyEvent: function( keyEvent, event ) { 7410 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7411 this._move( keyEvent, event ); 7412 7413 // prevents moving cursor to beginning/end of the text field in some browsers 7414 event.preventDefault(); 7415 } 7416 } 7417}); 7418 7419$.extend( $.ui.autocomplete, { 7420 escapeRegex: function( value ) { 7421 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 7422 }, 7423 filter: function( array, term ) { 7424 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 7425 return $.grep( array, function( value ) { 7426 return matcher.test( value.label || value.value || value ); 7427 }); 7428 } 7429}); 7430 7431// live region extension, adding a `messages` option 7432// NOTE: This is an experimental API. We are still investigating 7433// a full solution for string manipulation and internationalization. 7434$.widget( "ui.autocomplete", $.ui.autocomplete, { 7435 options: { 7436 messages: { 7437 noResults: "No search results.", 7438 results: function( amount ) { 7439 return amount + ( amount > 1 ? " results are" : " result is" ) + 7440 " available, use up and down arrow keys to navigate."; 7441 } 7442 } 7443 }, 7444 7445 __response: function( content ) { 7446 var message; 7447 this._superApply( arguments ); 7448 if ( this.options.disabled || this.cancelSearch ) { 7449 return; 7450 } 7451 if ( content && content.length ) { 7452 message = this.options.messages.results( content.length ); 7453 } else { 7454 message = this.options.messages.noResults; 7455 } 7456 this.liveRegion.children().hide(); 7457 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 7458 } 7459}); 7460 7461var autocomplete = $.ui.autocomplete; 7462 7463 7464/*! 7465 * jQuery UI Button 1.11.1 7466 * http://jqueryui.com 7467 * 7468 * Copyright 2014 jQuery Foundation and other contributors 7469 * Released under the MIT license. 7470 * http://jquery.org/license 7471 * 7472 * http://api.jqueryui.com/button/ 7473 */ 7474 7475 7476var lastActive, 7477 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7478 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", 7479 formResetHandler = function() { 7480 var form = $( this ); 7481 setTimeout(function() { 7482 form.find( ":ui-button" ).button( "refresh" ); 7483 }, 1 ); 7484 }, 7485 radioGroup = function( radio ) { 7486 var name = radio.name, 7487 form = radio.form, 7488 radios = $( [] ); 7489 if ( name ) { 7490 name = name.replace( /'/g, "\\'" ); 7491 if ( form ) { 7492 radios = $( form ).find( "[name='" + name + "'][type=radio]" ); 7493 } else { 7494 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) 7495 .filter(function() { 7496 return !this.form; 7497 }); 7498 } 7499 } 7500 return radios; 7501 }; 7502 7503$.widget( "ui.button", { 7504 version: "1.11.1", 7505 defaultElement: "<button>", 7506 options: { 7507 disabled: null, 7508 text: true, 7509 label: null, 7510 icons: { 7511 primary: null, 7512 secondary: null 7513 } 7514 }, 7515 _create: function() { 7516 this.element.closest( "form" ) 7517 .unbind( "reset" + this.eventNamespace ) 7518 .bind( "reset" + this.eventNamespace, formResetHandler ); 7519 7520 if ( typeof this.options.disabled !== "boolean" ) { 7521 this.options.disabled = !!this.element.prop( "disabled" ); 7522 } else { 7523 this.element.prop( "disabled", this.options.disabled ); 7524 } 7525 7526 this._determineButtonType(); 7527 this.hasTitle = !!this.buttonElement.attr( "title" ); 7528 7529 var that = this, 7530 options = this.options, 7531 toggleButton = this.type === "checkbox" || this.type === "radio", 7532 activeClass = !toggleButton ? "ui-state-active" : ""; 7533 7534 if ( options.label === null ) { 7535 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7536 } 7537 7538 this._hoverable( this.buttonElement ); 7539 7540 this.buttonElement 7541 .addClass( baseClasses ) 7542 .attr( "role", "button" ) 7543 .bind( "mouseenter" + this.eventNamespace, function() { 7544 if ( options.disabled ) { 7545 return; 7546 } 7547 if ( this === lastActive ) { 7548 $( this ).addClass( "ui-state-active" ); 7549 } 7550 }) 7551 .bind( "mouseleave" + this.eventNamespace, function() { 7552 if ( options.disabled ) { 7553 return; 7554 } 7555 $( this ).removeClass( activeClass ); 7556 }) 7557 .bind( "click" + this.eventNamespace, function( event ) { 7558 if ( options.disabled ) { 7559 event.preventDefault(); 7560 event.stopImmediatePropagation(); 7561 } 7562 }); 7563 7564 // Can't use _focusable() because the element that receives focus 7565 // and the element that gets the ui-state-focus class are different 7566 this._on({ 7567 focus: function() { 7568 this.buttonElement.addClass( "ui-state-focus" ); 7569 }, 7570 blur: function() { 7571 this.buttonElement.removeClass( "ui-state-focus" ); 7572 } 7573 }); 7574 7575 if ( toggleButton ) { 7576 this.element.bind( "change" + this.eventNamespace, function() { 7577 that.refresh(); 7578 }); 7579 } 7580 7581 if ( this.type === "checkbox" ) { 7582 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7583 if ( options.disabled ) { 7584 return false; 7585 } 7586 }); 7587 } else if ( this.type === "radio" ) { 7588 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7589 if ( options.disabled ) { 7590 return false; 7591 } 7592 $( this ).addClass( "ui-state-active" ); 7593 that.buttonElement.attr( "aria-pressed", "true" ); 7594 7595 var radio = that.element[ 0 ]; 7596 radioGroup( radio ) 7597 .not( radio ) 7598 .map(function() { 7599 return $( this ).button( "widget" )[ 0 ]; 7600 }) 7601 .removeClass( "ui-state-active" ) 7602 .attr( "aria-pressed", "false" ); 7603 }); 7604 } else { 7605 this.buttonElement 7606 .bind( "mousedown" + this.eventNamespace, function() { 7607 if ( options.disabled ) { 7608 return false; 7609 } 7610 $( this ).addClass( "ui-state-active" ); 7611 lastActive = this; 7612 that.document.one( "mouseup", function() { 7613 lastActive = null; 7614 }); 7615 }) 7616 .bind( "mouseup" + this.eventNamespace, function() { 7617 if ( options.disabled ) { 7618 return false; 7619 } 7620 $( this ).removeClass( "ui-state-active" ); 7621 }) 7622 .bind( "keydown" + this.eventNamespace, function(event) { 7623 if ( options.disabled ) { 7624 return false; 7625 } 7626 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7627 $( this ).addClass( "ui-state-active" ); 7628 } 7629 }) 7630 // see #8559, we bind to blur here in case the button element loses 7631 // focus between keydown and keyup, it would be left in an "active" state 7632 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7633 $( this ).removeClass( "ui-state-active" ); 7634 }); 7635 7636 if ( this.buttonElement.is("a") ) { 7637 this.buttonElement.keyup(function(event) { 7638 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7639 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7640 $( this ).click(); 7641 } 7642 }); 7643 } 7644 } 7645 7646 this._setOption( "disabled", options.disabled ); 7647 this._resetButton(); 7648 }, 7649 7650 _determineButtonType: function() { 7651 var ancestor, labelSelector, checked; 7652 7653 if ( this.element.is("[type=checkbox]") ) { 7654 this.type = "checkbox"; 7655 } else if ( this.element.is("[type=radio]") ) { 7656 this.type = "radio"; 7657 } else if ( this.element.is("input") ) { 7658 this.type = "input"; 7659 } else { 7660 this.type = "button"; 7661 } 7662 7663 if ( this.type === "checkbox" || this.type === "radio" ) { 7664 // we don't search against the document in case the element 7665 // is disconnected from the DOM 7666 ancestor = this.element.parents().last(); 7667 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7668 this.buttonElement = ancestor.find( labelSelector ); 7669 if ( !this.buttonElement.length ) { 7670 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7671 this.buttonElement = ancestor.filter( labelSelector ); 7672 if ( !this.buttonElement.length ) { 7673 this.buttonElement = ancestor.find( labelSelector ); 7674 } 7675 } 7676 this.element.addClass( "ui-helper-hidden-accessible" ); 7677 7678 checked = this.element.is( ":checked" ); 7679 if ( checked ) { 7680 this.buttonElement.addClass( "ui-state-active" ); 7681 } 7682 this.buttonElement.prop( "aria-pressed", checked ); 7683 } else { 7684 this.buttonElement = this.element; 7685 } 7686 }, 7687 7688 widget: function() { 7689 return this.buttonElement; 7690 }, 7691 7692 _destroy: function() { 7693 this.element 7694 .removeClass( "ui-helper-hidden-accessible" ); 7695 this.buttonElement 7696 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 7697 .removeAttr( "role" ) 7698 .removeAttr( "aria-pressed" ) 7699 .html( this.buttonElement.find(".ui-button-text").html() ); 7700 7701 if ( !this.hasTitle ) { 7702 this.buttonElement.removeAttr( "title" ); 7703 } 7704 }, 7705 7706 _setOption: function( key, value ) { 7707 this._super( key, value ); 7708 if ( key === "disabled" ) { 7709 this.widget().toggleClass( "ui-state-disabled", !!value ); 7710 this.element.prop( "disabled", !!value ); 7711 if ( value ) { 7712 if ( this.type === "checkbox" || this.type === "radio" ) { 7713 this.buttonElement.removeClass( "ui-state-focus" ); 7714 } else { 7715 this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); 7716 } 7717 } 7718 return; 7719 } 7720 this._resetButton(); 7721 }, 7722 7723 refresh: function() { 7724 //See #8237 & #8828 7725 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7726 7727 if ( isDisabled !== this.options.disabled ) { 7728 this._setOption( "disabled", isDisabled ); 7729 } 7730 if ( this.type === "radio" ) { 7731 radioGroup( this.element[0] ).each(function() { 7732 if ( $( this ).is( ":checked" ) ) { 7733 $( this ).button( "widget" ) 7734 .addClass( "ui-state-active" ) 7735 .attr( "aria-pressed", "true" ); 7736 } else { 7737 $( this ).button( "widget" ) 7738 .removeClass( "ui-state-active" ) 7739 .attr( "aria-pressed", "false" ); 7740 } 7741 }); 7742 } else if ( this.type === "checkbox" ) { 7743 if ( this.element.is( ":checked" ) ) { 7744 this.buttonElement 7745 .addClass( "ui-state-active" ) 7746 .attr( "aria-pressed", "true" ); 7747 } else { 7748 this.buttonElement 7749 .removeClass( "ui-state-active" ) 7750 .attr( "aria-pressed", "false" ); 7751 } 7752 } 7753 }, 7754 7755 _resetButton: function() { 7756 if ( this.type === "input" ) { 7757 if ( this.options.label ) { 7758 this.element.val( this.options.label ); 7759 } 7760 return; 7761 } 7762 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7763 buttonText = $( "<span></span>", this.document[0] ) 7764 .addClass( "ui-button-text" ) 7765 .html( this.options.label ) 7766 .appendTo( buttonElement.empty() ) 7767 .text(), 7768 icons = this.options.icons, 7769 multipleIcons = icons.primary && icons.secondary, 7770 buttonClasses = []; 7771 7772 if ( icons.primary || icons.secondary ) { 7773 if ( this.options.text ) { 7774 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7775 } 7776 7777 if ( icons.primary ) { 7778 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7779 } 7780 7781 if ( icons.secondary ) { 7782 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7783 } 7784 7785 if ( !this.options.text ) { 7786 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7787 7788 if ( !this.hasTitle ) { 7789 buttonElement.attr( "title", $.trim( buttonText ) ); 7790 } 7791 } 7792 } else { 7793 buttonClasses.push( "ui-button-text-only" ); 7794 } 7795 buttonElement.addClass( buttonClasses.join( " " ) ); 7796 } 7797}); 7798 7799$.widget( "ui.buttonset", { 7800 version: "1.11.1", 7801 options: { 7802 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7803 }, 7804 7805 _create: function() { 7806 this.element.addClass( "ui-buttonset" ); 7807 }, 7808 7809 _init: function() { 7810 this.refresh(); 7811 }, 7812 7813 _setOption: function( key, value ) { 7814 if ( key === "disabled" ) { 7815 this.buttons.button( "option", key, value ); 7816 } 7817 7818 this._super( key, value ); 7819 }, 7820 7821 refresh: function() { 7822 var rtl = this.element.css( "direction" ) === "rtl", 7823 allButtons = this.element.find( this.options.items ), 7824 existingButtons = allButtons.filter( ":ui-button" ); 7825 7826 // Initialize new buttons 7827 allButtons.not( ":ui-button" ).button(); 7828 7829 // Refresh existing buttons 7830 existingButtons.button( "refresh" ); 7831 7832 this.buttons = allButtons 7833 .map(function() { 7834 return $( this ).button( "widget" )[ 0 ]; 7835 }) 7836 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7837 .filter( ":first" ) 7838 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7839 .end() 7840 .filter( ":last" ) 7841 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7842 .end() 7843 .end(); 7844 }, 7845 7846 _destroy: function() { 7847 this.element.removeClass( "ui-buttonset" ); 7848 this.buttons 7849 .map(function() { 7850 return $( this ).button( "widget" )[ 0 ]; 7851 }) 7852 .removeClass( "ui-corner-left ui-corner-right" ) 7853 .end() 7854 .button( "destroy" ); 7855 } 7856}); 7857 7858var button = $.ui.button; 7859 7860 7861/*! 7862 * jQuery UI Datepicker 1.11.1 7863 * http://jqueryui.com 7864 * 7865 * Copyright 2014 jQuery Foundation and other contributors 7866 * Released under the MIT license. 7867 * http://jquery.org/license 7868 * 7869 * http://api.jqueryui.com/datepicker/ 7870 */ 7871 7872 7873$.extend($.ui, { datepicker: { version: "1.11.1" } }); 7874 7875var datepicker_instActive; 7876 7877function datepicker_getZindex( elem ) { 7878 var position, value; 7879 while ( elem.length && elem[ 0 ] !== document ) { 7880 // Ignore z-index if position is set to a value where z-index is ignored by the browser 7881 // This makes behavior of this function consistent across browsers 7882 // WebKit always returns auto if the element is positioned 7883 position = elem.css( "position" ); 7884 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 7885 // IE returns 0 when zIndex is not specified 7886 // other browsers return a string 7887 // we ignore the case of nested elements with an explicit value of 0 7888 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 7889 value = parseInt( elem.css( "zIndex" ), 10 ); 7890 if ( !isNaN( value ) && value !== 0 ) { 7891 return value; 7892 } 7893 } 7894 elem = elem.parent(); 7895 } 7896 7897 return 0; 7898} 7899/* Date picker manager. 7900 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7901 Settings for (groups of) date pickers are maintained in an instance object, 7902 allowing multiple different settings on the same page. */ 7903 7904function Datepicker() { 7905 this._curInst = null; // The current instance in use 7906 this._keyEvent = false; // If the last event was a key event 7907 this._disabledInputs = []; // List of date picker inputs that have been disabled 7908 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7909 this._inDialog = false; // True if showing within a "dialog", false if not 7910 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7911 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7912 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7913 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7914 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7915 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7916 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7917 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7918 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7919 this.regional = []; // Available regional settings, indexed by language code 7920 this.regional[""] = { // Default regional settings 7921 closeText: "Done", // Display text for close link 7922 prevText: "Prev", // Display text for previous month link 7923 nextText: "Next", // Display text for next month link 7924 currentText: "Today", // Display text for current month link 7925 monthNames: ["January","February","March","April","May","June", 7926 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7927 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7928 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7929 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7930 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7931 weekHeader: "Wk", // Column header for week of the year 7932 dateFormat: "mm/dd/yy", // See format options on parseDate 7933 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7934 isRTL: false, // True if right-to-left language, false if left-to-right 7935 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7936 yearSuffix: "" // Additional text to append to the year in the month headers 7937 }; 7938 this._defaults = { // Global defaults for all the date picker instances 7939 showOn: "focus", // "focus" for popup on focus, 7940 // "button" for trigger button, or "both" for either
vendor: 12,329 bytes, lines 7941-8228
7941 showAnim: "fadeIn", // Name of jQuery animation for popup 7942 showOptions: {}, // Options for enhanced animations 7943 defaultDate: null, // Used when field is blank: actual date, 7944 // +/-number for offset from today, null for today 7945 appendText: "", // Display text following the input box, e.g. showing the format 7946 buttonText: "...", // Text for trigger button 7947 buttonImage: "", // URL for trigger button image 7948 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7949 hideIfNoPrevNext: false, // True to hide next/previous month links 7950 // if not applicable, false to just disable them 7951 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7952 gotoCurrent: false, // True if today link goes back to current selection instead 7953 changeMonth: false, // True if month can be selected directly, false if only prev/next 7954 changeYear: false, // True if year can be selected directly, false if only prev/next 7955 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7956 // either relative to today's year (-nn:+nn), relative to currently displayed year 7957 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7958 showOtherMonths: false, // True to show dates in other months, false to leave blank 7959 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7960 showWeek: false, // True to show week of the year, false to not show it 7961 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7962 // takes a Date and returns the number of the week for it 7963 shortYearCutoff: "+10", // Short year values < this are in the current century, 7964 // > this are in the previous century, 7965 // string value starting with "+" for current year + value 7966 minDate: null, // The earliest selectable date, or null for no limit 7967 maxDate: null, // The latest selectable date, or null for no limit 7968 duration: "fast", // Duration of display/closure 7969 beforeShowDay: null, // Function that takes a date and returns an array with 7970 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7971 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7972 beforeShow: null, // Function that takes an input field and 7973 // returns a set of custom settings for the date picker 7974 onSelect: null, // Define a callback function when a date is selected 7975 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7976 onClose: null, // Define a callback function when the datepicker is closed 7977 numberOfMonths: 1, // Number of months to show at a time 7978 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7979 stepMonths: 1, // Number of months to step back/forward 7980 stepBigMonths: 12, // Number of months to step back/forward for the big links 7981 altField: "", // Selector for an alternate field to store selected dates into 7982 altFormat: "", // The date format to use for the alternate field 7983 constrainInput: true, // The input is constrained by the current date format 7984 showButtonPanel: false, // True to show button panel, false to not show it 7985 autoSize: false, // True to size the input for the date format, false to leave as is 7986 disabled: false // The initial disabled state 7987 }; 7988 $.extend(this._defaults, this.regional[""]); 7989 this.regional.en = $.extend( true, {}, this.regional[ "" ]); 7990 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 7991 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7992} 7993 7994$.extend(Datepicker.prototype, { 7995 /* Class name added to elements to indicate already configured with a date picker. */ 7996 markerClassName: "hasDatepicker", 7997 7998 //Keep track of the maximum number of rows displayed (see #7043) 7999 maxRows: 4, 8000 8001 // TODO rename to "widget" when switching to widget factory 8002 _widgetDatepicker: function() { 8003 return this.dpDiv; 8004 }, 8005 8006 /* Override the default settings for all instances of the date picker. 8007 * @param settings object - the new settings to use as defaults (anonymous object) 8008 * @return the manager object 8009 */ 8010 setDefaults: function(settings) { 8011 datepicker_extendRemove(this._defaults, settings || {}); 8012 return this; 8013 }, 8014 8015 /* Attach the date picker to a jQuery selection. 8016 * @param target element - the target input field or division or span 8017 * @param settings object - the new settings to use for this date picker instance (anonymous) 8018 */ 8019 _attachDatepicker: function(target, settings) { 8020 var nodeName, inline, inst; 8021 nodeName = target.nodeName.toLowerCase(); 8022 inline = (nodeName === "div" || nodeName === "span"); 8023 if (!target.id) { 8024 this.uuid += 1; 8025 target.id = "dp" + this.uuid; 8026 } 8027 inst = this._newInst($(target), inline); 8028 inst.settings = $.extend({}, settings || {}); 8029 if (nodeName === "input") { 8030 this._connectDatepicker(target, inst); 8031 } else if (inline) { 8032 this._inlineDatepicker(target, inst); 8033 } 8034 }, 8035 8036 /* Create a new instance object. */ 8037 _newInst: function(target, inline) { 8038 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 8039 return {id: id, input: target, // associated target 8040 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 8041 drawMonth: 0, drawYear: 0, // month being drawn 8042 inline: inline, // is datepicker inline or not 8043 dpDiv: (!inline ? this.dpDiv : // presentation div 8044 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 8045 }, 8046 8047 /* Attach the date picker to an input field. */ 8048 _connectDatepicker: function(target, inst) { 8049 var input = $(target); 8050 inst.append = $([]); 8051 inst.trigger = $([]); 8052 if (input.hasClass(this.markerClassName)) { 8053 return; 8054 } 8055 this._attachments(input, inst); 8056 input.addClass(this.markerClassName).keydown(this._doKeyDown). 8057 keypress(this._doKeyPress).keyup(this._doKeyUp); 8058 this._autoSize(inst); 8059 $.data(target, "datepicker", inst); 8060 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 8061 if( inst.settings.disabled ) { 8062 this._disableDatepicker( target ); 8063 } 8064 }, 8065 8066 /* Make attachments based on settings. */ 8067 _attachments: function(input, inst) { 8068 var showOn, buttonText, buttonImage, 8069 appendText = this._get(inst, "appendText"), 8070 isRTL = this._get(inst, "isRTL"); 8071 8072 if (inst.append) { 8073 inst.append.remove(); 8074 } 8075 if (appendText) { 8076 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 8077 input[isRTL ? "before" : "after"](inst.append); 8078 } 8079 8080 input.unbind("focus", this._showDatepicker); 8081 8082 if (inst.trigger) { 8083 inst.trigger.remove(); 8084 } 8085 8086 showOn = this._get(inst, "showOn"); 8087 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 8088 input.focus(this._showDatepicker); 8089 } 8090 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 8091 buttonText = this._get(inst, "buttonText"); 8092 buttonImage = this._get(inst, "buttonImage"); 8093 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 8094 $("<img/>").addClass(this._triggerClass). 8095 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 8096 $("<button type='button'></button>").addClass(this._triggerClass). 8097 html(!buttonImage ? buttonText : $("<img/>").attr( 8098 { src:buttonImage, alt:buttonText, title:buttonText }))); 8099 input[isRTL ? "before" : "after"](inst.trigger); 8100 inst.trigger.click(function() { 8101 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 8102 $.datepicker._hideDatepicker(); 8103 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 8104 $.datepicker._hideDatepicker(); 8105 $.datepicker._showDatepicker(input[0]); 8106 } else { 8107 $.datepicker._showDatepicker(input[0]); 8108 } 8109 return false; 8110 }); 8111 } 8112 }, 8113 8114 /* Apply the maximum length for the date format. */ 8115 _autoSize: function(inst) { 8116 if (this._get(inst, "autoSize") && !inst.inline) { 8117 var findMax, max, maxI, i, 8118 date = new Date(2009, 12 - 1, 20), // Ensure double digits 8119 dateFormat = this._get(inst, "dateFormat"); 8120 8121 if (dateFormat.match(/[DM]/)) { 8122 findMax = function(names) { 8123 max = 0; 8124 maxI = 0; 8125 for (i = 0; i < names.length; i++) { 8126 if (names[i].length > max) { 8127 max = names[i].length; 8128 maxI = i; 8129 } 8130 } 8131 return maxI; 8132 }; 8133 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 8134 "monthNames" : "monthNamesShort")))); 8135 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 8136 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 8137 } 8138 inst.input.attr("size", this._formatDate(inst, date).length); 8139 } 8140 }, 8141 8142 /* Attach an inline date picker to a div. */ 8143 _inlineDatepicker: function(target, inst) { 8144 var divSpan = $(target); 8145 if (divSpan.hasClass(this.markerClassName)) { 8146 return; 8147 } 8148 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 8149 $.data(target, "datepicker", inst); 8150 this._setDate(inst, this._getDefaultDate(inst), true); 8151 this._updateDatepicker(inst); 8152 this._updateAlternate(inst); 8153 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 8154 if( inst.settings.disabled ) { 8155 this._disableDatepicker( target ); 8156 } 8157 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 8158 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 8159 inst.dpDiv.css( "display", "block" ); 8160 }, 8161 8162 /* Pop-up the date picker in a "dialog" box. 8163 * @param input element - ignored 8164 * @param date string or Date - the initial date to display 8165 * @param onSelect function - the function to call when a date is selected 8166 * @param settings object - update the dialog date picker instance's settings (anonymous object) 8167 * @param pos int[2] - coordinates for the dialog's position within the screen or 8168 * event - with x/y coordinates or 8169 * leave empty for default (screen centre) 8170 * @return the manager object 8171 */ 8172 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 8173 var id, browserWidth, browserHeight, scrollX, scrollY, 8174 inst = this._dialogInst; // internal instance 8175 8176 if (!inst) { 8177 this.uuid += 1; 8178 id = "dp" + this.uuid; 8179 this._dialogInput = $("<input type='text' id='" + id + 8180 "' style='position: absolute; top: -100px; width: 0px;'/>"); 8181 this._dialogInput.keydown(this._doKeyDown); 8182 $("body").append(this._dialogInput); 8183 inst = this._dialogInst = this._newInst(this._dialogInput, false); 8184 inst.settings = {}; 8185 $.data(this._dialogInput[0], "datepicker", inst); 8186 } 8187 datepicker_extendRemove(inst.settings, settings || {}); 8188 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 8189 this._dialogInput.val(date); 8190 8191 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 8192 if (!this._pos) { 8193 browserWidth = document.documentElement.clientWidth; 8194 browserHeight = document.documentElement.clientHeight; 8195 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 8196 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 8197 this._pos = // should use actual width/height below 8198 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 8199 } 8200 8201 // move input on screen for focus, but hidden behind dialog 8202 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 8203 inst.settings.onSelect = onSelect; 8204 this._inDialog = true; 8205 this.dpDiv.addClass(this._dialogClass); 8206 this._showDatepicker(this._dialogInput[0]); 8207 if ($.blockUI) { 8208 $.blockUI(this.dpDiv); 8209 } 8210 $.data(this._dialogInput[0], "datepicker", inst); 8211 return this; 8212 }, 8213 8214 /* Detach a datepicker from its control. 8215 * @param target element - the target input field or division or span 8216 */ 8217 _destroyDatepicker: function(target) { 8218 var nodeName, 8219 $target = $(target), 8220 inst = $.data(target, "datepicker"); 8221 8222 if (!$target.hasClass(this.markerClassName)) { 8223 return; 8224 } 8225 8226 nodeName = target.nodeName.toLowerCase(); 8227 $.removeData(target, "datepicker"); 8228 if (nodeName === "input") {
vendor: 6,854 bytes, lines 8229-8436
8229 inst.append.remove(); 8230 inst.trigger.remove(); 8231 $target.removeClass(this.markerClassName). 8232 unbind("focus", this._showDatepicker). 8233 unbind("keydown", this._doKeyDown). 8234 unbind("keypress", this._doKeyPress). 8235 unbind("keyup", this._doKeyUp); 8236 } else if (nodeName === "div" || nodeName === "span") { 8237 $target.removeClass(this.markerClassName).empty(); 8238 } 8239 }, 8240 8241 /* Enable the date picker to a jQuery selection. 8242 * @param target element - the target input field or division or span 8243 */ 8244 _enableDatepicker: function(target) { 8245 var nodeName, inline, 8246 $target = $(target), 8247 inst = $.data(target, "datepicker"); 8248 8249 if (!$target.hasClass(this.markerClassName)) { 8250 return; 8251 } 8252 8253 nodeName = target.nodeName.toLowerCase(); 8254 if (nodeName === "input") { 8255 target.disabled = false; 8256 inst.trigger.filter("button"). 8257 each(function() { this.disabled = false; }).end(). 8258 filter("img").css({opacity: "1.0", cursor: ""}); 8259 } else if (nodeName === "div" || nodeName === "span") { 8260 inline = $target.children("." + this._inlineClass); 8261 inline.children().removeClass("ui-state-disabled"); 8262 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8263 prop("disabled", false); 8264 } 8265 this._disabledInputs = $.map(this._disabledInputs, 8266 function(value) { return (value === target ? null : value); }); // delete entry 8267 }, 8268 8269 /* Disable the date picker to a jQuery selection. 8270 * @param target element - the target input field or division or span 8271 */ 8272 _disableDatepicker: function(target) { 8273 var nodeName, inline, 8274 $target = $(target), 8275 inst = $.data(target, "datepicker"); 8276 8277 if (!$target.hasClass(this.markerClassName)) { 8278 return; 8279 } 8280 8281 nodeName = target.nodeName.toLowerCase(); 8282 if (nodeName === "input") { 8283 target.disabled = true; 8284 inst.trigger.filter("button"). 8285 each(function() { this.disabled = true; }).end(). 8286 filter("img").css({opacity: "0.5", cursor: "default"}); 8287 } else if (nodeName === "div" || nodeName === "span") { 8288 inline = $target.children("." + this._inlineClass); 8289 inline.children().addClass("ui-state-disabled"); 8290 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8291 prop("disabled", true); 8292 } 8293 this._disabledInputs = $.map(this._disabledInputs, 8294 function(value) { return (value === target ? null : value); }); // delete entry 8295 this._disabledInputs[this._disabledInputs.length] = target; 8296 }, 8297 8298 /* Is the first field in a jQuery collection disabled as a datepicker? 8299 * @param target element - the target input field or division or span 8300 * @return boolean - true if disabled, false if enabled 8301 */ 8302 _isDisabledDatepicker: function(target) { 8303 if (!target) { 8304 return false; 8305 } 8306 for (var i = 0; i < this._disabledInputs.length; i++) { 8307 if (this._disabledInputs[i] === target) { 8308 return true; 8309 } 8310 } 8311 return false; 8312 }, 8313 8314 /* Retrieve the instance data for the target control. 8315 * @param target element - the target input field or division or span 8316 * @return object - the associated instance data 8317 * @throws error if a jQuery problem getting data 8318 */ 8319 _getInst: function(target) { 8320 try { 8321 return $.data(target, "datepicker"); 8322 } 8323 catch (err) { 8324 throw "Missing instance data for this datepicker"; 8325 } 8326 }, 8327 8328 /* Update or retrieve the settings for a date picker attached to an input field or division. 8329 * @param target element - the target input field or division or span 8330 * @param name object - the new settings to update or 8331 * string - the name of the setting to change or retrieve, 8332 * when retrieving also "all" for all instance settings or 8333 * "defaults" for all global defaults 8334 * @param value any - the new value for the setting 8335 * (omit if above is an object or to retrieve a value) 8336 */ 8337 _optionDatepicker: function(target, name, value) { 8338 var settings, date, minDate, maxDate, 8339 inst = this._getInst(target); 8340 8341 if (arguments.length === 2 && typeof name === "string") { 8342 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8343 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8344 this._get(inst, name)) : null)); 8345 } 8346 8347 settings = name || {}; 8348 if (typeof name === "string") { 8349 settings = {}; 8350 settings[name] = value; 8351 } 8352 8353 if (inst) { 8354 if (this._curInst === inst) { 8355 this._hideDatepicker(); 8356 } 8357 8358 date = this._getDateDatepicker(target, true); 8359 minDate = this._getMinMaxDate(inst, "min"); 8360 maxDate = this._getMinMaxDate(inst, "max"); 8361 datepicker_extendRemove(inst.settings, settings); 8362 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8363 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8364 inst.settings.minDate = this._formatDate(inst, minDate); 8365 } 8366 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8367 inst.settings.maxDate = this._formatDate(inst, maxDate); 8368 } 8369 if ( "disabled" in settings ) { 8370 if ( settings.disabled ) { 8371 this._disableDatepicker(target); 8372 } else { 8373 this._enableDatepicker(target); 8374 } 8375 } 8376 this._attachments($(target), inst); 8377 this._autoSize(inst); 8378 this._setDate(inst, date); 8379 this._updateAlternate(inst); 8380 this._updateDatepicker(inst); 8381 } 8382 }, 8383 8384 // change method deprecated 8385 _changeDatepicker: function(target, name, value) { 8386 this._optionDatepicker(target, name, value); 8387 }, 8388 8389 /* Redraw the date picker attached to an input field or division. 8390 * @param target element - the target input field or division or span 8391 */ 8392 _refreshDatepicker: function(target) { 8393 var inst = this._getInst(target); 8394 if (inst) { 8395 this._updateDatepicker(inst); 8396 } 8397 }, 8398 8399 /* Set the dates for a jQuery selection. 8400 * @param target element - the target input field or division or span 8401 * @param date Date - the new date 8402 */ 8403 _setDateDatepicker: function(target, date) { 8404 var inst = this._getInst(target); 8405 if (inst) { 8406 this._setDate(inst, date); 8407 this._updateDatepicker(inst); 8408 this._updateAlternate(inst); 8409 } 8410 }, 8411 8412 /* Get the date(s) for the first entry in a jQuery selection. 8413 * @param target element - the target input field or division or span 8414 * @param noDefault boolean - true if no default date is to be used 8415 * @return Date - the current date 8416 */ 8417 _getDateDatepicker: function(target, noDefault) { 8418 var inst = this._getInst(target); 8419 if (inst && !inst.inline) { 8420 this._setDateFromField(inst, noDefault); 8421 } 8422 return (inst ? this._getDate(inst) : null); 8423 }, 8424 8425 /* Handle keystrokes. */ 8426 _doKeyDown: function(event) { 8427 var onSelect, dateStr, sel, 8428 inst = $.datepicker._getInst(event.target), 8429 handled = true, 8430 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8431 8432 inst._keyEvent = true; 8433 if ($.datepicker._datepickerShowing) { 8434 switch (event.keyCode) { 8435 case 9: $.datepicker._hideDatepicker(); 8436 handled = false;
vendor: 4,495 bytes, lines 8437-8560
8437 break; // hide on tab out 8438 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8439 $.datepicker._currentClass + ")", inst.dpDiv); 8440 if (sel[0]) { 8441 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8442 } 8443 8444 onSelect = $.datepicker._get(inst, "onSelect"); 8445 if (onSelect) { 8446 dateStr = $.datepicker._formatDate(inst); 8447 8448 // trigger custom callback 8449 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8450 } else { 8451 $.datepicker._hideDatepicker(); 8452 } 8453 8454 return false; // don't submit the form 8455 case 27: $.datepicker._hideDatepicker(); 8456 break; // hide on escape 8457 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8458 -$.datepicker._get(inst, "stepBigMonths") : 8459 -$.datepicker._get(inst, "stepMonths")), "M"); 8460 break; // previous month/year on page up/+ ctrl 8461 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8462 +$.datepicker._get(inst, "stepBigMonths") : 8463 +$.datepicker._get(inst, "stepMonths")), "M"); 8464 break; // next month/year on page down/+ ctrl 8465 case 35: if (event.ctrlKey || event.metaKey) { 8466 $.datepicker._clearDate(event.target); 8467 } 8468 handled = event.ctrlKey || event.metaKey; 8469 break; // clear on ctrl or command +end 8470 case 36: if (event.ctrlKey || event.metaKey) { 8471 $.datepicker._gotoToday(event.target); 8472 } 8473 handled = event.ctrlKey || event.metaKey; 8474 break; // current on ctrl or command +home 8475 case 37: if (event.ctrlKey || event.metaKey) { 8476 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8477 } 8478 handled = event.ctrlKey || event.metaKey; 8479 // -1 day on ctrl or command +left 8480 if (event.originalEvent.altKey) { 8481 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8482 -$.datepicker._get(inst, "stepBigMonths") : 8483 -$.datepicker._get(inst, "stepMonths")), "M"); 8484 } 8485 // next month/year on alt +left on Mac 8486 break; 8487 case 38: if (event.ctrlKey || event.metaKey) { 8488 $.datepicker._adjustDate(event.target, -7, "D"); 8489 } 8490 handled = event.ctrlKey || event.metaKey; 8491 break; // -1 week on ctrl or command +up 8492 case 39: if (event.ctrlKey || event.metaKey) { 8493 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8494 } 8495 handled = event.ctrlKey || event.metaKey; 8496 // +1 day on ctrl or command +right 8497 if (event.originalEvent.altKey) { 8498 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8499 +$.datepicker._get(inst, "stepBigMonths") : 8500 +$.datepicker._get(inst, "stepMonths")), "M"); 8501 } 8502 // next month/year on alt +right 8503 break; 8504 case 40: if (event.ctrlKey || event.metaKey) { 8505 $.datepicker._adjustDate(event.target, +7, "D"); 8506 } 8507 handled = event.ctrlKey || event.metaKey; 8508 break; // +1 week on ctrl or command +down 8509 default: handled = false; 8510 } 8511 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8512 $.datepicker._showDatepicker(this); 8513 } else { 8514 handled = false; 8515 } 8516 8517 if (handled) { 8518 event.preventDefault(); 8519 event.stopPropagation(); 8520 } 8521 }, 8522 8523 /* Filter entered characters - based on date format. */ 8524 _doKeyPress: function(event) { 8525 var chars, chr, 8526 inst = $.datepicker._getInst(event.target); 8527 8528 if ($.datepicker._get(inst, "constrainInput")) { 8529 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8530 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8531 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8532 } 8533 }, 8534 8535 /* Synchronise manual entry and field/alternate field. */ 8536 _doKeyUp: function(event) { 8537 var date, 8538 inst = $.datepicker._getInst(event.target); 8539 8540 if (inst.input.val() !== inst.lastVal) { 8541 try { 8542 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8543 (inst.input ? inst.input.val() : null), 8544 $.datepicker._getFormatConfig(inst)); 8545 8546 if (date) { // only if valid 8547 $.datepicker._setDateFromField(inst); 8548 $.datepicker._updateAlternate(inst); 8549 $.datepicker._updateDatepicker(inst); 8550 } 8551 } 8552 catch (err) { 8553 } 8554 } 8555 return true; 8556 }, 8557 8558 /* Pop-up the date picker for a given input field. 8559 * If false returned from beforeShow event handler do not show. 8560 * @param input element - the input field attached to the date picker or
vendor: 9,398 bytes, lines 8561-8835
8561 * event - if triggered by focus 8562 */ 8563 _showDatepicker: function(input) { 8564 input = input.target || input; 8565 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8566 input = $("input", input.parentNode)[0]; 8567 } 8568 8569 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8570 return; 8571 } 8572 8573 var inst, beforeShow, beforeShowSettings, isFixed, 8574 offset, showAnim, duration; 8575 8576 inst = $.datepicker._getInst(input); 8577 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8578 $.datepicker._curInst.dpDiv.stop(true, true); 8579 if ( inst && $.datepicker._datepickerShowing ) { 8580 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8581 } 8582 } 8583 8584 beforeShow = $.datepicker._get(inst, "beforeShow"); 8585 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8586 if(beforeShowSettings === false){ 8587 return; 8588 } 8589 datepicker_extendRemove(inst.settings, beforeShowSettings); 8590 8591 inst.lastVal = null; 8592 $.datepicker._lastInput = input; 8593 $.datepicker._setDateFromField(inst); 8594 8595 if ($.datepicker._inDialog) { // hide cursor 8596 input.value = ""; 8597 } 8598 if (!$.datepicker._pos) { // position below input 8599 $.datepicker._pos = $.datepicker._findPos(input); 8600 $.datepicker._pos[1] += input.offsetHeight; // add the height 8601 } 8602 8603 isFixed = false; 8604 $(input).parents().each(function() { 8605 isFixed |= $(this).css("position") === "fixed"; 8606 return !isFixed; 8607 }); 8608 8609 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8610 $.datepicker._pos = null; 8611 //to avoid flashes on Firefox 8612 inst.dpDiv.empty(); 8613 // determine sizing offscreen 8614 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8615 $.datepicker._updateDatepicker(inst); 8616 // fix width for dynamic number of date pickers 8617 // and adjust position before showing 8618 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8619 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8620 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8621 left: offset.left + "px", top: offset.top + "px"}); 8622 8623 if (!inst.inline) { 8624 showAnim = $.datepicker._get(inst, "showAnim"); 8625 duration = $.datepicker._get(inst, "duration"); 8626 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 8627 $.datepicker._datepickerShowing = true; 8628 8629 if ( $.effects && $.effects.effect[ showAnim ] ) { 8630 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8631 } else { 8632 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8633 } 8634 8635 if ( $.datepicker._shouldFocusInput( inst ) ) { 8636 inst.input.focus(); 8637 } 8638 8639 $.datepicker._curInst = inst; 8640 } 8641 }, 8642 8643 /* Generate the date picker content. */ 8644 _updateDatepicker: function(inst) { 8645 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8646 datepicker_instActive = inst; // for delegate hover events 8647 inst.dpDiv.empty().append(this._generateHTML(inst)); 8648 this._attachHandlers(inst); 8649 8650 var origyearshtml, 8651 numMonths = this._getNumberOfMonths(inst), 8652 cols = numMonths[1], 8653 width = 17, 8654 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 8655 8656 if ( activeCell.length > 0 ) { 8657 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 8658 } 8659 8660 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8661 if (cols > 1) { 8662 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8663 } 8664 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8665 "Class"]("ui-datepicker-multi"); 8666 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8667 "Class"]("ui-datepicker-rtl"); 8668 8669 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8670 inst.input.focus(); 8671 } 8672 8673 // deffered render of the years select (to avoid flashes on Firefox) 8674 if( inst.yearshtml ){ 8675 origyearshtml = inst.yearshtml; 8676 setTimeout(function(){ 8677 //assure that inst.yearshtml didn't change. 8678 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8679 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8680 } 8681 origyearshtml = inst.yearshtml = null; 8682 }, 0); 8683 } 8684 }, 8685 8686 // #6694 - don't focus the input if it's already focused 8687 // this breaks the change event in IE 8688 // Support: IE and jQuery <1.9 8689 _shouldFocusInput: function( inst ) { 8690 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 8691 }, 8692 8693 /* Check positioning to remain on screen. */ 8694 _checkOffset: function(inst, offset, isFixed) { 8695 var dpWidth = inst.dpDiv.outerWidth(), 8696 dpHeight = inst.dpDiv.outerHeight(), 8697 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8698 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8699 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8700 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8701 8702 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8703 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8704 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8705 8706 // now check if datepicker is showing outside window viewport - move to a better place if so. 8707 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8708 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8709 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8710 Math.abs(dpHeight + inputHeight) : 0); 8711 8712 return offset; 8713 }, 8714 8715 /* Find an object's position on the screen. */ 8716 _findPos: function(obj) { 8717 var position, 8718 inst = this._getInst(obj), 8719 isRTL = this._get(inst, "isRTL"); 8720 8721 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8722 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8723 } 8724 8725 position = $(obj).offset(); 8726 return [position.left, position.top]; 8727 }, 8728 8729 /* Hide the date picker from view. 8730 * @param input element - the input field attached to the date picker 8731 */ 8732 _hideDatepicker: function(input) { 8733 var showAnim, duration, postProcess, onClose, 8734 inst = this._curInst; 8735 8736 if (!inst || (input && inst !== $.data(input, "datepicker"))) { 8737 return; 8738 } 8739 8740 if (this._datepickerShowing) { 8741 showAnim = this._get(inst, "showAnim"); 8742 duration = this._get(inst, "duration"); 8743 postProcess = function() { 8744 $.datepicker._tidyDialog(inst); 8745 }; 8746 8747 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8748 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8749 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8750 } else { 8751 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8752 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8753 } 8754 8755 if (!showAnim) { 8756 postProcess(); 8757 } 8758 this._datepickerShowing = false; 8759 8760 onClose = this._get(inst, "onClose"); 8761 if (onClose) { 8762 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8763 } 8764 8765 this._lastInput = null; 8766 if (this._inDialog) { 8767 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8768 if ($.blockUI) { 8769 $.unblockUI(); 8770 $("body").append(this.dpDiv); 8771 } 8772 } 8773 this._inDialog = false; 8774 } 8775 }, 8776 8777 /* Tidy up after a dialog display. */ 8778 _tidyDialog: function(inst) { 8779 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8780 }, 8781 8782 /* Close date picker if clicked elsewhere. */ 8783 _checkExternalClick: function(event) { 8784 if (!$.datepicker._curInst) { 8785 return; 8786 } 8787 8788 var $target = $(event.target), 8789 inst = $.datepicker._getInst($target[0]); 8790 8791 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8792 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8793 !$target.hasClass($.datepicker.markerClassName) && 8794 !$target.closest("." + $.datepicker._triggerClass).length && 8795 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8796 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8797 $.datepicker._hideDatepicker(); 8798 } 8799 }, 8800 8801 /* Adjust one of the date sub-fields. */ 8802 _adjustDate: function(id, offset, period) { 8803 var target = $(id), 8804 inst = this._getInst(target[0]); 8805 8806 if (this._isDisabledDatepicker(target[0])) { 8807 return; 8808 } 8809 this._adjustInstDate(inst, offset + 8810 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8811 period); 8812 this._updateDatepicker(inst); 8813 }, 8814 8815 /* Action for current link. */ 8816 _gotoToday: function(id) { 8817 var date, 8818 target = $(id), 8819 inst = this._getInst(target[0]); 8820 8821 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8822 inst.selectedDay = inst.currentDay; 8823 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8824 inst.drawYear = inst.selectedYear = inst.currentYear; 8825 } else { 8826 date = new Date(); 8827 inst.selectedDay = date.getDate(); 8828 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8829 inst.drawYear = inst.selectedYear = date.getFullYear(); 8830 } 8831 this._notifyChange(inst); 8832 this._adjustDate(target); 8833 }, 8834 8835 /* Action for selecting a new month/year. */
vendor: 4,436 bytes, lines 8836-8967
8836 _selectMonthYear: function(id, select, period) { 8837 var target = $(id), 8838 inst = this._getInst(target[0]); 8839 8840 inst["selected" + (period === "M" ? "Month" : "Year")] = 8841 inst["draw" + (period === "M" ? "Month" : "Year")] = 8842 parseInt(select.options[select.selectedIndex].value,10); 8843 8844 this._notifyChange(inst); 8845 this._adjustDate(target); 8846 }, 8847 8848 /* Action for selecting a day. */ 8849 _selectDay: function(id, month, year, td) { 8850 var inst, 8851 target = $(id); 8852 8853 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8854 return; 8855 } 8856 8857 inst = this._getInst(target[0]); 8858 inst.selectedDay = inst.currentDay = $("a", td).html(); 8859 inst.selectedMonth = inst.currentMonth = month; 8860 inst.selectedYear = inst.currentYear = year; 8861 this._selectDate(id, this._formatDate(inst, 8862 inst.currentDay, inst.currentMonth, inst.currentYear)); 8863 }, 8864 8865 /* Erase the input field and hide the date picker. */ 8866 _clearDate: function(id) { 8867 var target = $(id); 8868 this._selectDate(target, ""); 8869 }, 8870 8871 /* Update the input field with the selected date. */ 8872 _selectDate: function(id, dateStr) { 8873 var onSelect, 8874 target = $(id), 8875 inst = this._getInst(target[0]); 8876 8877 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8878 if (inst.input) { 8879 inst.input.val(dateStr); 8880 } 8881 this._updateAlternate(inst); 8882 8883 onSelect = this._get(inst, "onSelect"); 8884 if (onSelect) { 8885 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8886 } else if (inst.input) { 8887 inst.input.trigger("change"); // fire the change event 8888 } 8889 8890 if (inst.inline){ 8891 this._updateDatepicker(inst); 8892 } else { 8893 this._hideDatepicker(); 8894 this._lastInput = inst.input[0]; 8895 if (typeof(inst.input[0]) !== "object") { 8896 inst.input.focus(); // restore focus 8897 } 8898 this._lastInput = null; 8899 } 8900 }, 8901 8902 /* Update any alternate field to synchronise with the main field. */ 8903 _updateAlternate: function(inst) { 8904 var altFormat, date, dateStr, 8905 altField = this._get(inst, "altField"); 8906 8907 if (altField) { // update alternate field too 8908 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8909 date = this._getDate(inst); 8910 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8911 $(altField).each(function() { $(this).val(dateStr); }); 8912 } 8913 }, 8914 8915 /* Set as beforeShowDay function to prevent selection of weekends. 8916 * @param date Date - the date to customise 8917 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8918 */ 8919 noWeekends: function(date) { 8920 var day = date.getDay(); 8921 return [(day > 0 && day < 6), ""]; 8922 }, 8923 8924 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8925 * @param date Date - the date to get the week for 8926 * @return number - the number of the week within the year that contains this date 8927 */ 8928 iso8601Week: function(date) { 8929 var time, 8930 checkDate = new Date(date.getTime()); 8931 8932 // Find Thursday of this week starting on Monday 8933 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8934 8935 time = checkDate.getTime(); 8936 checkDate.setMonth(0); // Compare with Jan 1 8937 checkDate.setDate(1); 8938 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8939 }, 8940 8941 /* Parse a string value into a date object. 8942 * See formatDate below for the possible formats. 8943 * 8944 * @param format string - the expected format of the date 8945 * @param value string - the date in the above format 8946 * @param settings Object - attributes include: 8947 * shortYearCutoff number - the cutoff year for determining the century (optional) 8948 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8949 * dayNames string[7] - names of the days from Sunday (optional) 8950 * monthNamesShort string[12] - abbreviated names of the months (optional) 8951 * monthNames string[12] - names of the months (optional) 8952 * @return Date - the extracted date value or null if value is blank 8953 */ 8954 parseDate: function (format, value, settings) { 8955 if (format == null || value == null) { 8956 throw "Invalid arguments"; 8957 } 8958 8959 value = (typeof value === "object" ? value.toString() : value + ""); 8960 if (value === "") { 8961 return null; 8962 } 8963 8964 var iFormat, dim, extra, 8965 iValue = 0, 8966 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8967 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,261 bytes, lines 8967-9153
8967: 8968 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8969 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8970 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8971 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8972 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8973 year = -1, 8974 month = -1, 8975 day = -1, 8976 doy = -1, 8977 literal = false, 8978 date, 8979 // Check whether a format character is doubled 8980 lookAhead = function(match) { 8981 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8982 if (matches) { 8983 iFormat++; 8984 } 8985 return matches; 8986 }, 8987 // Extract a number from the string value 8988 getNumber = function(match) { 8989 var isDoubled = lookAhead(match), 8990 size = (match === "@" ? 14 : (match === "!" ? 20 : 8991 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8992 minSize = (match === "y" ? size : 1), 8993 digits = new RegExp("^\\d{" + minSize + "," + size + "}"), 8994 num = value.substring(iValue).match(digits); 8995 if (!num) { 8996 throw "Missing number at position " + iValue; 8997 } 8998 iValue += num[0].length; 8999 return parseInt(num[0], 10); 9000 }, 9001 // Extract a name from the string value and convert to an index 9002 getName = function(match, shortNames, longNames) { 9003 var index = -1, 9004 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 9005 return [ [k, v] ]; 9006 }).sort(function (a, b) { 9007 return -(a[1].length - b[1].length); 9008 }); 9009 9010 $.each(names, function (i, pair) { 9011 var name = pair[1]; 9012 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 9013 index = pair[0]; 9014 iValue += name.length; 9015 return false; 9016 } 9017 }); 9018 if (index !== -1) { 9019 return index + 1; 9020 } else { 9021 throw "Unknown name at position " + iValue; 9022 } 9023 }, 9024 // Confirm that a literal character matches the string value 9025 checkLiteral = function() { 9026 if (value.charAt(iValue) !== format.charAt(iFormat)) { 9027 throw "Unexpected literal at position " + iValue; 9028 } 9029 iValue++; 9030 }; 9031 9032 for (iFormat = 0; iFormat < format.length; iFormat++) { 9033 if (literal) { 9034 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9035 literal = false; 9036 } else { 9037 checkLiteral(); 9038 } 9039 } else { 9040 switch (format.charAt(iFormat)) { 9041 case "d": 9042 day = getNumber("d"); 9043 break; 9044 case "D": 9045 getName("D", dayNamesShort, dayNames); 9046 break; 9047 case "o": 9048 doy = getNumber("o"); 9049 break; 9050 case "m": 9051 month = getNumber("m"); 9052 break; 9053 case "M": 9054 month = getName("M", monthNamesShort, monthNames); 9055 break; 9056 case "y": 9057 year = getNumber("y"); 9058 break; 9059 case "@": 9060 date = new Date(getNumber("@")); 9061 year = date.getFullYear(); 9062 month = date.getMonth() + 1; 9063 day = date.getDate(); 9064 break; 9065 case "!": 9066 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 9067 year = date.getFullYear(); 9068 month = date.getMonth() + 1; 9069 day = date.getDate(); 9070 break; 9071 case "'": 9072 if (lookAhead("'")){ 9073 checkLiteral(); 9074 } else { 9075 literal = true; 9076 } 9077 break; 9078 default: 9079 checkLiteral(); 9080 } 9081 } 9082 } 9083 9084 if (iValue < value.length){ 9085 extra = value.substr(iValue); 9086 if (!/^\s+/.test(extra)) { 9087 throw "Extra/unparsed characters found in date: " + extra; 9088 } 9089 } 9090 9091 if (year === -1) { 9092 year = new Date().getFullYear(); 9093 } else if (year < 100) { 9094 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 9095 (year <= shortYearCutoff ? 0 : -100); 9096 } 9097 9098 if (doy > -1) { 9099 month = 1; 9100 day = doy; 9101 do { 9102 dim = this._getDaysInMonth(year, month - 1); 9103 if (day <= dim) { 9104 break; 9105 } 9106 month++; 9107 day -= dim; 9108 } while (true); 9109 } 9110 9111 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 9112 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 9113 throw "Invalid date"; // E.g. 31/02/00 9114 } 9115 return date; 9116 }, 9117 9118 /* Standard date formats. */ 9119 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 9120 COOKIE: "D, dd M yy", 9121 ISO_8601: "yy-mm-dd", 9122 RFC_822: "D, d M y", 9123 RFC_850: "DD, dd-M-y", 9124 RFC_1036: "D, d M y", 9125 RFC_1123: "D, d M yy", 9126 RFC_2822: "D, d M yy", 9127 RSS: "D, d M y", // RFC 822 9128 TICKS: "!", 9129 TIMESTAMP: "@", 9130 W3C: "yy-mm-dd", // ISO 8601 9131 9132 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 9133 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 9134 9135 /* Format a date object into a string value. 9136 * The format can be combinations of the following: 9137 * d - day of month (no leading zero) 9138 * dd - day of month (two digit) 9139 * o - day of year (no leading zeros) 9140 * oo - day of year (three digit) 9141 * D - day name short 9142 * DD - day name long 9143 * m - month of year (no leading zero) 9144 * mm - month of year (two digit) 9145 * M - month name short 9146 * MM - month name long 9147 * y - year (two digit) 9148 * yy - year (four digit) 9149 * @ - Unix timestamp (ms since 01/01/1970) 9150 * ! - Windows ticks (100ns since 01/01/0001) 9151 * "..." - literal text 9152 * '' - single quote 9153 *
vendor: 11,157 bytes, lines 9154-9487
9154 * @param format string - the desired format of the date 9155 * @param date Date - the date value to format 9156 * @param settings Object - attributes include: 9157 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 9158 * dayNames string[7] - names of the days from Sunday (optional) 9159 * monthNamesShort string[12] - abbreviated names of the months (optional) 9160 * monthNames string[12] - names of the months (optional) 9161 * @return string - the date in the above format 9162 */ 9163 formatDate: function (format, date, settings) { 9164 if (!date) { 9165 return ""; 9166 } 9167 9168 var iFormat, 9169 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 9170 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 9171 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 9172 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 9173 // Check whether a format character is doubled 9174 lookAhead = function(match) { 9175 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 9176 if (matches) { 9177 iFormat++; 9178 } 9179 return matches; 9180 }, 9181 // Format a number, with leading zero if necessary 9182 formatNumber = function(match, value, len) { 9183 var num = "" + value; 9184 if (lookAhead(match)) { 9185 while (num.length < len) { 9186 num = "0" + num; 9187 } 9188 } 9189 return num; 9190 }, 9191 // Format a name, short or long as requested 9192 formatName = function(match, value, shortNames, longNames) { 9193 return (lookAhead(match) ? longNames[value] : shortNames[value]); 9194 }, 9195 output = "", 9196 literal = false; 9197 9198 if (date) { 9199 for (iFormat = 0; iFormat < format.length; iFormat++) { 9200 if (literal) { 9201 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9202 literal = false; 9203 } else { 9204 output += format.charAt(iFormat); 9205 } 9206 } else { 9207 switch (format.charAt(iFormat)) { 9208 case "d": 9209 output += formatNumber("d", date.getDate(), 2); 9210 break; 9211 case "D": 9212 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 9213 break; 9214 case "o": 9215 output += formatNumber("o", 9216 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 9217 break; 9218 case "m": 9219 output += formatNumber("m", date.getMonth() + 1, 2); 9220 break; 9221 case "M": 9222 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 9223 break; 9224 case "y": 9225 output += (lookAhead("y") ? date.getFullYear() : 9226 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 9227 break; 9228 case "@": 9229 output += date.getTime(); 9230 break; 9231 case "!": 9232 output += date.getTime() * 10000 + this._ticksTo1970; 9233 break; 9234 case "'": 9235 if (lookAhead("'")) { 9236 output += "'"; 9237 } else { 9238 literal = true; 9239 } 9240 break; 9241 default: 9242 output += format.charAt(iFormat); 9243 } 9244 } 9245 } 9246 } 9247 return output; 9248 }, 9249 9250 /* Extract all possible characters from the date format. */ 9251 _possibleChars: function (format) { 9252 var iFormat, 9253 chars = "", 9254 literal = false, 9255 // Check whether a format character is doubled 9256 lookAhead = function(match) { 9257 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 9258 if (matches) { 9259 iFormat++; 9260 } 9261 return matches; 9262 }; 9263 9264 for (iFormat = 0; iFormat < format.length; iFormat++) { 9265 if (literal) { 9266 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 9267 literal = false; 9268 } else { 9269 chars += format.charAt(iFormat); 9270 } 9271 } else { 9272 switch (format.charAt(iFormat)) { 9273 case "d": case "m": case "y": case "@": 9274 chars += "0123456789"; 9275 break; 9276 case "D": case "M": 9277 return null; // Accept anything 9278 case "'": 9279 if (lookAhead("'")) { 9280 chars += "'"; 9281 } else { 9282 literal = true; 9283 } 9284 break; 9285 default: 9286 chars += format.charAt(iFormat); 9287 } 9288 } 9289 } 9290 return chars; 9291 }, 9292 9293 /* Get a setting value, defaulting if necessary. */ 9294 _get: function(inst, name) { 9295 return inst.settings[name] !== undefined ? 9296 inst.settings[name] : this._defaults[name]; 9297 }, 9298 9299 /* Parse existing date and initialise date picker. */ 9300 _setDateFromField: function(inst, noDefault) { 9301 if (inst.input.val() === inst.lastVal) { 9302 return; 9303 } 9304 9305 var dateFormat = this._get(inst, "dateFormat"), 9306 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9307 defaultDate = this._getDefaultDate(inst), 9308 date = defaultDate, 9309 settings = this._getFormatConfig(inst); 9310 9311 try { 9312 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9313 } catch (event) { 9314 dates = (noDefault ? "" : dates); 9315 } 9316 inst.selectedDay = date.getDate(); 9317 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9318 inst.drawYear = inst.selectedYear = date.getFullYear(); 9319 inst.currentDay = (dates ? date.getDate() : 0); 9320 inst.currentMonth = (dates ? date.getMonth() : 0); 9321 inst.currentYear = (dates ? date.getFullYear() : 0); 9322 this._adjustInstDate(inst); 9323 }, 9324 9325 /* Retrieve the default date shown on opening. */ 9326 _getDefaultDate: function(inst) { 9327 return this._restrictMinMax(inst, 9328 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9329 }, 9330 9331 /* A date may be specified as an exact value or a relative one. */ 9332 _determineDate: function(inst, date, defaultDate) { 9333 var offsetNumeric = function(offset) { 9334 var date = new Date(); 9335 date.setDate(date.getDate() + offset); 9336 return date; 9337 }, 9338 offsetString = function(offset) { 9339 try { 9340 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9341 offset, $.datepicker._getFormatConfig(inst)); 9342 } 9343 catch (e) { 9344 // Ignore 9345 } 9346 9347 var date = (offset.toLowerCase().match(/^c/) ? 9348 $.datepicker._getDate(inst) : null) || new Date(), 9349 year = date.getFullYear(), 9350 month = date.getMonth(), 9351 day = date.getDate(), 9352 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9353 matches = pattern.exec(offset); 9354 9355 while (matches) { 9356 switch (matches[2] || "d") { 9357 case "d" : case "D" : 9358 day += parseInt(matches[1],10); break; 9359 case "w" : case "W" : 9360 day += parseInt(matches[1],10) * 7; break; 9361 case "m" : case "M" : 9362 month += parseInt(matches[1],10); 9363 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9364 break; 9365 case "y": case "Y" : 9366 year += parseInt(matches[1],10); 9367 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9368 break; 9369 } 9370 matches = pattern.exec(offset); 9371 } 9372 return new Date(year, month, day); 9373 }, 9374 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9375 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9376 9377 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9378 if (newDate) { 9379 newDate.setHours(0); 9380 newDate.setMinutes(0); 9381 newDate.setSeconds(0); 9382 newDate.setMilliseconds(0); 9383 } 9384 return this._daylightSavingAdjust(newDate); 9385 }, 9386 9387 /* Handle switch to/from daylight saving. 9388 * Hours may be non-zero on daylight saving cut-over: 9389 * > 12 when midnight changeover, but then cannot generate 9390 * midnight datetime, so jump to 1AM, otherwise reset. 9391 * @param date (Date) the date to check 9392 * @return (Date) the corrected date 9393 */ 9394 _daylightSavingAdjust: function(date) { 9395 if (!date) { 9396 return null; 9397 } 9398 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9399 return date; 9400 }, 9401 9402 /* Set the date(s) directly. */ 9403 _setDate: function(inst, date, noChange) { 9404 var clear = !date, 9405 origMonth = inst.selectedMonth, 9406 origYear = inst.selectedYear, 9407 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9408 9409 inst.selectedDay = inst.currentDay = newDate.getDate(); 9410 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9411 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9412 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9413 this._notifyChange(inst); 9414 } 9415 this._adjustInstDate(inst); 9416 if (inst.input) { 9417 inst.input.val(clear ? "" : this._formatDate(inst)); 9418 } 9419 }, 9420 9421 /* Retrieve the date(s) directly. */ 9422 _getDate: function(inst) { 9423 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9424 this._daylightSavingAdjust(new Date( 9425 inst.currentYear, inst.currentMonth, inst.currentDay))); 9426 return startDate; 9427 }, 9428 9429 /* Attach the onxxx handlers. These are declared statically so 9430 * they work with static code transformers like Caja. 9431 */ 9432 _attachHandlers: function(inst) { 9433 var stepMonths = this._get(inst, "stepMonths"), 9434 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9435 inst.dpDiv.find("[data-handler]").map(function () { 9436 var handler = { 9437 prev: function () { 9438 $.datepicker._adjustDate(id, -stepMonths, "M"); 9439 }, 9440 next: function () { 9441 $.datepicker._adjustDate(id, +stepMonths, "M"); 9442 }, 9443 hide: function () { 9444 $.datepicker._hideDatepicker(); 9445 }, 9446 today: function () { 9447 $.datepicker._gotoToday(id); 9448 }, 9449 selectDay: function () { 9450 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9451 return false; 9452 }, 9453 selectMonth: function () { 9454 $.datepicker._selectMonthYear(id, this, "M"); 9455 return false; 9456 }, 9457 selectYear: function () { 9458 $.datepicker._selectMonthYear(id, this, "Y"); 9459 return false; 9460 } 9461 }; 9462 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9463 }); 9464 }, 9465 9466 /* Generate the HTML for the current state of the date picker. */ 9467 _generateHTML: function(inst) { 9468 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 9469 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9470 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9471 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9472 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9473 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9474 tempDate = new Date(), 9475 today = this._daylightSavingAdjust( 9476 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9477 isRTL = this._get(inst, "isRTL"), 9478 showButtonPanel = this._get(inst, "showButtonPanel"), 9479 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9480 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9481 numMonths = this._getNumberOfMonths(inst), 9482 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9483 stepMonths = this._get(inst, "stepMonths"), 9484 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9485 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9486 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9487 minDate = this._getMinMaxDate(inst, "min"),
vendor: 9,139 bytes, lines 9488-9646
9488 maxDate = this._getMinMaxDate(inst, "max"), 9489 drawMonth = inst.drawMonth - showCurrentAtPos, 9490 drawYear = inst.drawYear; 9491 9492 if (drawMonth < 0) { 9493 drawMonth += 12; 9494 drawYear--; 9495 } 9496 if (maxDate) { 9497 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9498 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9499 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9500 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9501 drawMonth--; 9502 if (drawMonth < 0) { 9503 drawMonth = 11; 9504 drawYear--; 9505 } 9506 } 9507 } 9508 inst.drawMonth = drawMonth; 9509 inst.drawYear = drawYear; 9510 9511 prevText = this._get(inst, "prevText"); 9512 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9513 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9514 this._getFormatConfig(inst))); 9515 9516 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9517 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9518 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9519 (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>")); 9520 9521 nextText = this._get(inst, "nextText"); 9522 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9523 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9524 this._getFormatConfig(inst))); 9525 9526 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9527 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9528 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9529 (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>")); 9530 9531 currentText = this._get(inst, "currentText"); 9532 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9533 currentText = (!navigationAsDateFormat ? currentText : 9534 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9535 9536 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'>" + 9537 this._get(inst, "closeText") + "</button>" : ""); 9538 9539 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9540 (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'" + 9541 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9542 9543 firstDay = parseInt(this._get(inst, "firstDay"),10); 9544 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9545 9546 showWeek = this._get(inst, "showWeek"); 9547 dayNames = this._get(inst, "dayNames"); 9548 dayNamesMin = this._get(inst, "dayNamesMin"); 9549 monthNames = this._get(inst, "monthNames"); 9550 monthNamesShort = this._get(inst, "monthNamesShort"); 9551 beforeShowDay = this._get(inst, "beforeShowDay"); 9552 showOtherMonths = this._get(inst, "showOtherMonths"); 9553 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9554 defaultDate = this._getDefaultDate(inst); 9555 html = ""; 9556 dow; 9557 for (row = 0; row < numMonths[0]; row++) { 9558 group = ""; 9559 this.maxRows = 4; 9560 for (col = 0; col < numMonths[1]; col++) { 9561 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9562 cornerClass = " ui-corner-all"; 9563 calender = ""; 9564 if (isMultiMonth) { 9565 calender += "<div class='ui-datepicker-group"; 9566 if (numMonths[1] > 1) { 9567 switch (col) { 9568 case 0: calender += " ui-datepicker-group-first"; 9569 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9570 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9571 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9572 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9573 } 9574 } 9575 calender += "'>"; 9576 } 9577 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9578 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9579 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9580 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9581 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9582 "</div><table class='ui-datepicker-calendar'><thead>" + 9583 "<tr>"; 9584 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9585 for (dow = 0; dow < 7; dow++) { // days of the week 9586 day = (dow + firstDay) % 7; 9587 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9588 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9589 } 9590 calender += thead + "</tr></thead><tbody>"; 9591 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9592 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9593 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9594 } 9595 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9596 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9597 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9598 this.maxRows = numRows; 9599 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9600 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9601 calender += "<tr>"; 9602 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9603 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9604 for (dow = 0; dow < 7; dow++) { // create date picker days 9605 daySettings = (beforeShowDay ? 9606 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9607 otherMonth = (printDate.getMonth() !== drawMonth); 9608 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9609 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9610 tbody += "<td class='" + 9611 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9612 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9613 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9614 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9615 // or defaultDate is current printedDate and defaultDate is selectedDate 9616 " " + this._dayOverClass : "") + // highlight selected day 9617 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9618 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9619 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9620 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9621 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9622 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9623 (otherMonth && !showOtherMonths ? " " : // display for other months 9624 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9625 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9626 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9627 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9628 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9629 printDate.setDate(printDate.getDate() + 1); 9630 printDate = this._daylightSavingAdjust(printDate); 9631 } 9632 calender += tbody + "</tr>"; 9633 } 9634 drawMonth++; 9635 if (drawMonth > 11) { 9636 drawMonth = 0; 9637 drawYear++; 9638 } 9639 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9640 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9641 group += calender; 9642 } 9643 html += group; 9644 } 9645 html += buttonPanel; 9646 inst._keyEvent = false;
vendor: 5,431 bytes, lines 9647-9790
9647 return html; 9648 }, 9649 9650 /* Generate the month and year header. */ 9651 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9652 secondary, monthNames, monthNamesShort) { 9653 9654 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9655 changeMonth = this._get(inst, "changeMonth"), 9656 changeYear = this._get(inst, "changeYear"), 9657 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9658 html = "<div class='ui-datepicker-title'>", 9659 monthHtml = ""; 9660 9661 // month selection 9662 if (secondary || !changeMonth) { 9663 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9664 } else { 9665 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9666 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9667 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9668 for ( month = 0; month < 12; month++) { 9669 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9670 monthHtml += "<option value='" + month + "'" + 9671 (month === drawMonth ? " selected='selected'" : "") + 9672 ">" + monthNamesShort[month] + "</option>"; 9673 } 9674 } 9675 monthHtml += "</select>"; 9676 } 9677 9678 if (!showMonthAfterYear) { 9679 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9680 } 9681 9682 // year selection 9683 if ( !inst.yearshtml ) { 9684 inst.yearshtml = ""; 9685 if (secondary || !changeYear) { 9686 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9687 } else { 9688 // determine range of years to display 9689 years = this._get(inst, "yearRange").split(":"); 9690 thisYear = new Date().getFullYear(); 9691 determineYear = function(value) { 9692 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9693 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9694 parseInt(value, 10))); 9695 return (isNaN(year) ? thisYear : year); 9696 }; 9697 year = determineYear(years[0]); 9698 endYear = Math.max(year, determineYear(years[1] || "")); 9699 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9700 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9701 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9702 for (; year <= endYear; year++) { 9703 inst.yearshtml += "<option value='" + year + "'" + 9704 (year === drawYear ? " selected='selected'" : "") + 9705 ">" + year + "</option>"; 9706 } 9707 inst.yearshtml += "</select>"; 9708 9709 html += inst.yearshtml; 9710 inst.yearshtml = null; 9711 } 9712 } 9713 9714 html += this._get(inst, "yearSuffix"); 9715 if (showMonthAfterYear) { 9716 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9717 } 9718 html += "</div>"; // Close datepicker_header 9719 return html; 9720 }, 9721 9722 /* Adjust one of the date sub-fields. */ 9723 _adjustInstDate: function(inst, offset, period) { 9724 var year = inst.drawYear + (period === "Y" ? offset : 0), 9725 month = inst.drawMonth + (period === "M" ? offset : 0), 9726 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9727 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9728 9729 inst.selectedDay = date.getDate(); 9730 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9731 inst.drawYear = inst.selectedYear = date.getFullYear(); 9732 if (period === "M" || period === "Y") { 9733 this._notifyChange(inst); 9734 } 9735 }, 9736 9737 /* Ensure a date is within any min/max bounds. */ 9738 _restrictMinMax: function(inst, date) { 9739 var minDate = this._getMinMaxDate(inst, "min"), 9740 maxDate = this._getMinMaxDate(inst, "max"), 9741 newDate = (minDate && date < minDate ? minDate : date); 9742 return (maxDate && newDate > maxDate ? maxDate : newDate); 9743 }, 9744 9745 /* Notify change of month/year. */ 9746 _notifyChange: function(inst) { 9747 var onChange = this._get(inst, "onChangeMonthYear"); 9748 if (onChange) { 9749 onChange.apply((inst.input ? inst.input[0] : null), 9750 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9751 } 9752 }, 9753 9754 /* Determine the number of months to show. */ 9755 _getNumberOfMonths: function(inst) { 9756 var numMonths = this._get(inst, "numberOfMonths"); 9757 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9758 }, 9759 9760 /* Determine the current maximum date - ensure no time components are set. */ 9761 _getMinMaxDate: function(inst, minMax) { 9762 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9763 }, 9764 9765 /* Find the number of days in a given month. */ 9766 _getDaysInMonth: function(year, month) { 9767 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9768 }, 9769 9770 /* Find the day of the week of the first of a month. */ 9771 _getFirstDayOfMonth: function(year, month) { 9772 return new Date(year, month, 1).getDay(); 9773 }, 9774 9775 /* Determines if we should allow a "next/prev" month display change. */ 9776 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9777 var numMonths = this._getNumberOfMonths(inst), 9778 date = this._daylightSavingAdjust(new Date(curYear, 9779 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9780 9781 if (offset < 0) { 9782 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9783 } 9784 return this._isInRange(inst, date); 9785 }, 9786 9787 /* Is the given date in the accepted range? */ 9788 _isInRange: function(inst, date) { 9789 var yearSplit, currentYear, 9790 minDate = this._getMinMaxDate(inst, "min"),
vendor: 4,921 bytes, lines 9791-9923
9791 maxDate = this._getMinMaxDate(inst, "max"), 9792 minYear = null, 9793 maxYear = null, 9794 years = this._get(inst, "yearRange"); 9795 if (years){ 9796 yearSplit = years.split(":"); 9797 currentYear = new Date().getFullYear(); 9798 minYear = parseInt(yearSplit[0], 10); 9799 maxYear = parseInt(yearSplit[1], 10); 9800 if ( yearSplit[0].match(/[+\-].*/) ) { 9801 minYear += currentYear; 9802 } 9803 if ( yearSplit[1].match(/[+\-].*/) ) { 9804 maxYear += currentYear; 9805 } 9806 } 9807 9808 return ((!minDate || date.getTime() >= minDate.getTime()) && 9809 (!maxDate || date.getTime() <= maxDate.getTime()) && 9810 (!minYear || date.getFullYear() >= minYear) && 9811 (!maxYear || date.getFullYear() <= maxYear)); 9812 }, 9813 9814 /* Provide the configuration settings for formatting/parsing. */ 9815 _getFormatConfig: function(inst) { 9816 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9817 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9818 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9819 return {shortYearCutoff: shortYearCutoff, 9820 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9821 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9822 }, 9823 9824 /* Format the given date for display. */ 9825 _formatDate: function(inst, day, month, year) { 9826 if (!day) { 9827 inst.currentDay = inst.selectedDay; 9828 inst.currentMonth = inst.selectedMonth; 9829 inst.currentYear = inst.selectedYear; 9830 } 9831 var date = (day ? (typeof day === "object" ? day : 9832 this._daylightSavingAdjust(new Date(year, month, day))) : 9833 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9834 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9835 } 9836}); 9837 9838/* 9839 * Bind hover events for datepicker elements. 9840 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9841 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9842 */ 9843function datepicker_bindHover(dpDiv) { 9844 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9845 return dpDiv.delegate(selector, "mouseout", function() { 9846 $(this).removeClass("ui-state-hover"); 9847 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9848 $(this).removeClass("ui-datepicker-prev-hover"); 9849 } 9850 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9851 $(this).removeClass("ui-datepicker-next-hover"); 9852 } 9853 }) 9854 .delegate( selector, "mouseover", datepicker_handleMouseover ); 9855} 9856 9857function datepicker_handleMouseover() { 9858 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { 9859 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9860 $(this).addClass("ui-state-hover"); 9861 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9862 $(this).addClass("ui-datepicker-prev-hover"); 9863 } 9864 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9865 $(this).addClass("ui-datepicker-next-hover"); 9866 } 9867 } 9868} 9869 9870/* jQuery extend now ignores nulls! */ 9871function datepicker_extendRemove(target, props) { 9872 $.extend(target, props); 9873 for (var name in props) { 9874 if (props[name] == null) { 9875 target[name] = props[name]; 9876 } 9877 } 9878 return target; 9879} 9880 9881/* Invoke the datepicker functionality. 9882 @param options string - a command, optionally followed by additional parameters or 9883 Object - settings for attaching new datepicker functionality 9884 @return jQuery object */ 9885$.fn.datepicker = function(options){ 9886 9887 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9888 if ( !this.length ) { 9889 return this; 9890 } 9891 9892 /* Initialise the date picker. */ 9893 if (!$.datepicker.initialized) { 9894 $(document).mousedown($.datepicker._checkExternalClick); 9895 $.datepicker.initialized = true; 9896 } 9897 9898 /* Append datepicker main container to body if not exist. */ 9899 if ($("#"+$.datepicker._mainDivId).length === 0) { 9900 $("body").append($.datepicker.dpDiv); 9901 } 9902 9903 var otherArgs = Array.prototype.slice.call(arguments, 1); 9904 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9905 return $.datepicker["_" + options + "Datepicker"]. 9906 apply($.datepicker, [this[0]].concat(otherArgs)); 9907 } 9908 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9909 return $.datepicker["_" + options + "Datepicker"]. 9910 apply($.datepicker, [this[0]].concat(otherArgs)); 9911 } 9912 return this.each(function() { 9913 typeof options === "string" ? 9914 $.datepicker["_" + options + "Datepicker"]. 9915 apply($.datepicker, [this].concat(otherArgs)) : 9916 $.datepicker._attachDatepicker(this, options); 9917 }); 9918}; 9919 9920$.datepicker = new Datepicker(); // singleton instance 9921$.datepicker.initialized = false; 9922$.datepicker.uuid = new Date().getTime(); 9923$.datepicker.version = "1.11.
vendor: 24,894 bytes, lines 9923-10925
99231"; 9924 9925var datepicker = $.datepicker; 9926 9927 9928/*! 9929 * jQuery UI Dialog 1.11.1 9930 * http://jqueryui.com 9931 * 9932 * Copyright 2014 jQuery Foundation and other contributors 9933 * Released under the MIT license. 9934 * http://jquery.org/license 9935 * 9936 * http://api.jqueryui.com/dialog/ 9937 */ 9938 9939 9940var dialog = $.widget( "ui.dialog", { 9941 version: "1.11.1", 9942 options: { 9943 appendTo: "body", 9944 autoOpen: true, 9945 buttons: [], 9946 closeOnEscape: true, 9947 closeText: "Close", 9948 dialogClass: "", 9949 draggable: true, 9950 hide: null, 9951 height: "auto", 9952 maxHeight: null, 9953 maxWidth: null, 9954 minHeight: 150, 9955 minWidth: 150, 9956 modal: false, 9957 position: { 9958 my: "center", 9959 at: "center", 9960 of: window, 9961 collision: "fit", 9962 // Ensure the titlebar is always visible 9963 using: function( pos ) { 9964 var topOffset = $( this ).css( pos ).offset().top; 9965 if ( topOffset < 0 ) { 9966 $( this ).css( "top", pos.top - topOffset ); 9967 } 9968 } 9969 }, 9970 resizable: true, 9971 show: null, 9972 title: null, 9973 width: 300, 9974 9975 // callbacks 9976 beforeClose: null, 9977 close: null, 9978 drag: null, 9979 dragStart: null, 9980 dragStop: null, 9981 focus: null, 9982 open: null, 9983 resize: null, 9984 resizeStart: null, 9985 resizeStop: null 9986 }, 9987 9988 sizeRelatedOptions: { 9989 buttons: true, 9990 height: true, 9991 maxHeight: true, 9992 maxWidth: true, 9993 minHeight: true, 9994 minWidth: true, 9995 width: true 9996 }, 9997 9998 resizableRelatedOptions: { 9999 maxHeight: true, 10000 maxWidth: true, 10001 minHeight: true, 10002 minWidth: true 10003 }, 10004 10005 _create: function() { 10006 this.originalCss = { 10007 display: this.element[ 0 ].style.display, 10008 width: this.element[ 0 ].style.width, 10009 minHeight: this.element[ 0 ].style.minHeight, 10010 maxHeight: this.element[ 0 ].style.maxHeight, 10011 height: this.element[ 0 ].style.height 10012 }; 10013 this.originalPosition = { 10014 parent: this.element.parent(), 10015 index: this.element.parent().children().index( this.element ) 10016 }; 10017 this.originalTitle = this.element.attr( "title" ); 10018 this.options.title = this.options.title || this.originalTitle; 10019 10020 this._createWrapper(); 10021 10022 this.element 10023 .show() 10024 .removeAttr( "title" ) 10025 .addClass( "ui-dialog-content ui-widget-content" ) 10026 .appendTo( this.uiDialog ); 10027 10028 this._createTitlebar(); 10029 this._createButtonPane(); 10030 10031 if ( this.options.draggable && $.fn.draggable ) { 10032 this._makeDraggable(); 10033 } 10034 if ( this.options.resizable && $.fn.resizable ) { 10035 this._makeResizable(); 10036 } 10037 10038 this._isOpen = false; 10039 10040 this._trackFocus(); 10041 }, 10042 10043 _init: function() { 10044 if ( this.options.autoOpen ) { 10045 this.open(); 10046 } 10047 }, 10048 10049 _appendTo: function() { 10050 var element = this.options.appendTo; 10051 if ( element && (element.jquery || element.nodeType) ) { 10052 return $( element ); 10053 } 10054 return this.document.find( element || "body" ).eq( 0 ); 10055 }, 10056 10057 _destroy: function() { 10058 var next, 10059 originalPosition = this.originalPosition; 10060 10061 this._destroyOverlay(); 10062 10063 this.element 10064 .removeUniqueId() 10065 .removeClass( "ui-dialog-content ui-widget-content" ) 10066 .css( this.originalCss ) 10067 // Without detaching first, the following becomes really slow 10068 .detach(); 10069 10070 this.uiDialog.stop( true, true ).remove(); 10071 10072 if ( this.originalTitle ) { 10073 this.element.attr( "title", this.originalTitle ); 10074 } 10075 10076 next = originalPosition.parent.children().eq( originalPosition.index ); 10077 // Don't try to place the dialog next to itself (#8613) 10078 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 10079 next.before( this.element ); 10080 } else { 10081 originalPosition.parent.append( this.element ); 10082 } 10083 }, 10084 10085 widget: function() { 10086 return this.uiDialog; 10087 }, 10088 10089 disable: $.noop, 10090 enable: $.noop, 10091 10092 close: function( event ) { 10093 var activeElement, 10094 that = this; 10095 10096 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 10097 return; 10098 } 10099 10100 this._isOpen = false; 10101 this._focusedElement = null; 10102 this._destroyOverlay(); 10103 this._untrackInstance(); 10104 10105 if ( !this.opener.filter( ":focusable" ).focus().length ) { 10106 10107 // support: IE9 10108 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 10109 try { 10110 activeElement = this.document[ 0 ].activeElement; 10111 10112 // Support: IE9, IE10 10113 // If the <body> is blurred, IE will switch windows, see #4520 10114 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 10115 10116 // Hiding a focused element doesn't trigger blur in WebKit 10117 // so in case we have nothing to focus on, explicitly blur the active element 10118 // https://bugs.webkit.org/show_bug.cgi?id=47182 10119 $( activeElement ).blur(); 10120 } 10121 } catch ( error ) {} 10122 } 10123 10124 this._hide( this.uiDialog, this.options.hide, function() { 10125 that._trigger( "close", event ); 10126 }); 10127 }, 10128 10129 isOpen: function() { 10130 return this._isOpen; 10131 }, 10132 10133 moveToTop: function() { 10134 this._moveToTop(); 10135 }, 10136 10137 _moveToTop: function( event, silent ) { 10138 var moved = false, 10139 zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { 10140 return +$( this ).css( "z-index" ); 10141 }).get(), 10142 zIndexMax = Math.max.apply( null, zIndicies ); 10143 10144 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 10145 this.uiDialog.css( "z-index", zIndexMax + 1 ); 10146 moved = true; 10147 } 10148 10149 if ( moved && !silent ) { 10150 this._trigger( "focus", event ); 10151 } 10152 return moved; 10153 }, 10154 10155 open: function() { 10156 var that = this; 10157 if ( this._isOpen ) { 10158 if ( this._moveToTop() ) { 10159 this._focusTabbable(); 10160 } 10161 return; 10162 } 10163 10164 this._isOpen = true; 10165 this.opener = $( this.document[ 0 ].activeElement ); 10166 10167 this._size(); 10168 this._position(); 10169 this._createOverlay(); 10170 this._moveToTop( null, true ); 10171 10172 // Ensure the overlay is moved to the top with the dialog, but only when 10173 // opening. The overlay shouldn't move after the dialog is open so that 10174 // modeless dialogs opened after the modal dialog stack properly. 10175 if ( this.overlay ) { 10176 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 10177 } 10178 10179 this._show( this.uiDialog, this.options.show, function() { 10180 that._focusTabbable(); 10181 that._trigger( "focus" ); 10182 }); 10183 10184 // Track the dialog immediately upon openening in case a focus event 10185 // somehow occurs outside of the dialog before an element inside the 10186 // dialog is focused (#10152) 10187 this._makeFocusTarget(); 10188 10189 this._trigger( "open" ); 10190 }, 10191 10192 _focusTabbable: function() { 10193 // Set focus to the first match: 10194 // 1. An element that was focused previously 10195 // 2. First element inside the dialog matching [autofocus] 10196 // 3. Tabbable element inside the content element 10197 // 4. Tabbable element inside the buttonpane 10198 // 5. The close button 10199 // 6. The dialog itself 10200 var hasFocus = this._focusedElement; 10201 if ( !hasFocus ) { 10202 hasFocus = this.element.find( "[autofocus]" ); 10203 } 10204 if ( !hasFocus.length ) { 10205 hasFocus = this.element.find( ":tabbable" ); 10206 } 10207 if ( !hasFocus.length ) { 10208 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 10209 } 10210 if ( !hasFocus.length ) { 10211 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 10212 } 10213 if ( !hasFocus.length ) { 10214 hasFocus = this.uiDialog; 10215 } 10216 hasFocus.eq( 0 ).focus(); 10217 }, 10218 10219 _keepFocus: function( event ) { 10220 function checkFocus() { 10221 var activeElement = this.document[0].activeElement, 10222 isActive = this.uiDialog[0] === activeElement || 10223 $.contains( this.uiDialog[0], activeElement ); 10224 if ( !isActive ) { 10225 this._focusTabbable(); 10226 } 10227 } 10228 event.preventDefault(); 10229 checkFocus.call( this ); 10230 // support: IE 10231 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 10232 // so we check again later 10233 this._delay( checkFocus ); 10234 }, 10235 10236 _createWrapper: function() { 10237 this.uiDialog = $("<div>") 10238 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 10239 this.options.dialogClass ) 10240 .hide() 10241 .attr({ 10242 // Setting tabIndex makes the div focusable 10243 tabIndex: -1, 10244 role: "dialog" 10245 }) 10246 .appendTo( this._appendTo() ); 10247 10248 this._on( this.uiDialog, { 10249 keydown: function( event ) { 10250 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 10251 event.keyCode === $.ui.keyCode.ESCAPE ) { 10252 event.preventDefault(); 10253 this.close( event ); 10254 return; 10255 } 10256 10257 // prevent tabbing out of dialogs 10258 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 10259 return; 10260 } 10261 var tabbables = this.uiDialog.find( ":tabbable" ), 10262 first = tabbables.filter( ":first" ), 10263 last = tabbables.filter( ":last" ); 10264 10265 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 10266 this._delay(function() { 10267 first.focus(); 10268 }); 10269 event.preventDefault(); 10270 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 10271 this._delay(function() { 10272 last.focus(); 10273 }); 10274 event.preventDefault(); 10275 } 10276 }, 10277 mousedown: function( event ) { 10278 if ( this._moveToTop( event ) ) { 10279 this._focusTabbable(); 10280 } 10281 } 10282 }); 10283 10284 // We assume that any existing aria-describedby attribute means 10285 // that the dialog content is marked up properly 10286 // otherwise we brute force the content as the description 10287 if ( !this.element.find( "[aria-describedby]" ).length ) { 10288 this.uiDialog.attr({ 10289 "aria-describedby": this.element.uniqueId().attr( "id" ) 10290 }); 10291 } 10292 }, 10293 10294 _createTitlebar: function() { 10295 var uiDialogTitle; 10296 10297 this.uiDialogTitlebar = $( "<div>" ) 10298 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) 10299 .prependTo( this.uiDialog ); 10300 this._on( this.uiDialogTitlebar, { 10301 mousedown: function( event ) { 10302 // Don't prevent click on close button (#8838) 10303 // Focusing a dialog that is partially scrolled out of view 10304 // causes the browser to scroll it into view, preventing the click event 10305 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 10306 // Dialog isn't getting focus when dragging (#8063) 10307 this.uiDialog.focus(); 10308 } 10309 } 10310 }); 10311 10312 // support: IE 10313 // Use type="button" to prevent enter keypresses in textboxes from closing the 10314 // dialog in IE (#9312) 10315 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 10316 .button({ 10317 label: this.options.closeText, 10318 icons: { 10319 primary: "ui-icon-closethick" 10320 }, 10321 text: false 10322 }) 10323 .addClass( "ui-dialog-titlebar-close" ) 10324 .appendTo( this.uiDialogTitlebar ); 10325 this._on( this.uiDialogTitlebarClose, { 10326 click: function( event ) { 10327 event.preventDefault(); 10328 this.close( event ); 10329 } 10330 }); 10331 10332 uiDialogTitle = $( "<span>" ) 10333 .uniqueId() 10334 .addClass( "ui-dialog-title" ) 10335 .prependTo( this.uiDialogTitlebar ); 10336 this._title( uiDialogTitle ); 10337 10338 this.uiDialog.attr({ 10339 "aria-labelledby": uiDialogTitle.attr( "id" ) 10340 }); 10341 }, 10342 10343 _title: function( title ) { 10344 if ( !this.options.title ) { 10345 title.html( " " ); 10346 } 10347 title.text( this.options.title ); 10348 }, 10349 10350 _createButtonPane: function() { 10351 this.uiDialogButtonPane = $( "<div>" ) 10352 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 10353 10354 this.uiButtonSet = $( "<div>" ) 10355 .addClass( "ui-dialog-buttonset" ) 10356 .appendTo( this.uiDialogButtonPane ); 10357 10358 this._createButtons(); 10359 }, 10360 10361 _createButtons: function() { 10362 var that = this, 10363 buttons = this.options.buttons; 10364 10365 // if we already have a button pane, remove it 10366 this.uiDialogButtonPane.remove(); 10367 this.uiButtonSet.empty(); 10368 10369 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10370 this.uiDialog.removeClass( "ui-dialog-buttons" ); 10371 return; 10372 } 10373 10374 $.each( buttons, function( name, props ) { 10375 var click, buttonOptions; 10376 props = $.isFunction( props ) ? 10377 { click: props, text: name } : 10378 props; 10379 // Default to a non-submitting button 10380 props = $.extend( { type: "button" }, props ); 10381 // Change the context for the click callback to be the main element 10382 click = props.click; 10383 props.click = function() { 10384 click.apply( that.element[ 0 ], arguments ); 10385 }; 10386 buttonOptions = { 10387 icons: props.icons, 10388 text: props.showText 10389 }; 10390 delete props.icons; 10391 delete props.showText; 10392 $( "<button></button>", props ) 10393 .button( buttonOptions ) 10394 .appendTo( that.uiButtonSet ); 10395 }); 10396 this.uiDialog.addClass( "ui-dialog-buttons" ); 10397 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10398 }, 10399 10400 _makeDraggable: function() { 10401 var that = this, 10402 options = this.options; 10403 10404 function filteredUi( ui ) { 10405 return { 10406 position: ui.position, 10407 offset: ui.offset 10408 }; 10409 } 10410 10411 this.uiDialog.draggable({ 10412 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10413 handle: ".ui-dialog-titlebar", 10414 containment: "document", 10415 start: function( event, ui ) { 10416 $( this ).addClass( "ui-dialog-dragging" ); 10417 that._blockFrames(); 10418 that._trigger( "dragStart", event, filteredUi( ui ) ); 10419 }, 10420 drag: function( event, ui ) { 10421 that._trigger( "drag", event, filteredUi( ui ) ); 10422 }, 10423 stop: function( event, ui ) { 10424 var left = ui.offset.left - that.document.scrollLeft(), 10425 top = ui.offset.top - that.document.scrollTop(); 10426 10427 options.position = { 10428 my: "left top", 10429 at: "left" + (left >= 0 ? "+" : "") + left + " " + 10430 "top" + (top >= 0 ? "+" : "") + top, 10431 of: that.window 10432 }; 10433 $( this ).removeClass( "ui-dialog-dragging" ); 10434 that._unblockFrames(); 10435 that._trigger( "dragStop", event, filteredUi( ui ) ); 10436 } 10437 }); 10438 }, 10439 10440 _makeResizable: function() { 10441 var that = this, 10442 options = this.options, 10443 handles = options.resizable, 10444 // .ui-resizable has position: relative defined in the stylesheet 10445 // but dialogs have to use absolute or fixed positioning 10446 position = this.uiDialog.css("position"), 10447 resizeHandles = typeof handles === "string" ? 10448 handles : 10449 "n,e,s,w,se,sw,ne,nw"; 10450 10451 function filteredUi( ui ) { 10452 return { 10453 originalPosition: ui.originalPosition, 10454 originalSize: ui.originalSize, 10455 position: ui.position, 10456 size: ui.size 10457 }; 10458 } 10459 10460 this.uiDialog.resizable({ 10461 cancel: ".ui-dialog-content", 10462 containment: "document", 10463 alsoResize: this.element, 10464 maxWidth: options.maxWidth, 10465 maxHeight: options.maxHeight, 10466 minWidth: options.minWidth, 10467 minHeight: this._minHeight(), 10468 handles: resizeHandles, 10469 start: function( event, ui ) { 10470 $( this ).addClass( "ui-dialog-resizing" ); 10471 that._blockFrames(); 10472 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10473 }, 10474 resize: function( event, ui ) { 10475 that._trigger( "resize", event, filteredUi( ui ) ); 10476 }, 10477 stop: function( event, ui ) { 10478 var offset = that.uiDialog.offset(), 10479 left = offset.left - that.document.scrollLeft(), 10480 top = offset.top - that.document.scrollTop(); 10481 10482 options.height = that.uiDialog.height(); 10483 options.width = that.uiDialog.width(); 10484 options.position = { 10485 my: "left top", 10486 at: "left" + (left >= 0 ? "+" : "") + left + " " + 10487 "top" + (top >= 0 ? "+" : "") + top, 10488 of: that.window 10489 }; 10490 $( this ).removeClass( "ui-dialog-resizing" ); 10491 that._unblockFrames(); 10492 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10493 } 10494 }) 10495 .css( "position", position ); 10496 }, 10497 10498 _trackFocus: function() { 10499 this._on( this.widget(), { 10500 focusin: function( event ) { 10501 this._makeFocusTarget(); 10502 this._focusedElement = $( event.target ); 10503 } 10504 }); 10505 }, 10506 10507 _makeFocusTarget: function() { 10508 this._untrackInstance(); 10509 this._trackingInstances().unshift( this ); 10510 }, 10511 10512 _untrackInstance: function() { 10513 var instances = this._trackingInstances(), 10514 exists = $.inArray( this, instances ); 10515 if ( exists !== -1 ) { 10516 instances.splice( exists, 1 ); 10517 } 10518 }, 10519 10520 _trackingInstances: function() { 10521 var instances = this.document.data( "ui-dialog-instances" ); 10522 if ( !instances ) { 10523 instances = []; 10524 this.document.data( "ui-dialog-instances", instances ); 10525 } 10526 return instances; 10527 }, 10528 10529 _minHeight: function() { 10530 var options = this.options; 10531 10532 return options.height === "auto" ? 10533 options.minHeight : 10534 Math.min( options.minHeight, options.height ); 10535 }, 10536 10537 _position: function() { 10538 // Need to show the dialog to get the actual offset in the position plugin 10539 var isVisible = this.uiDialog.is( ":visible" ); 10540 if ( !isVisible ) { 10541 this.uiDialog.show(); 10542 } 10543 this.uiDialog.position( this.options.position ); 10544 if ( !isVisible ) { 10545 this.uiDialog.hide(); 10546 } 10547 }, 10548 10549 _setOptions: function( options ) { 10550 var that = this, 10551 resize = false, 10552 resizableOptions = {}; 10553 10554 $.each( options, function( key, value ) { 10555 that._setOption( key, value ); 10556 10557 if ( key in that.sizeRelatedOptions ) { 10558 resize = true; 10559 } 10560 if ( key in that.resizableRelatedOptions ) { 10561 resizableOptions[ key ] = value; 10562 } 10563 }); 10564 10565 if ( resize ) { 10566 this._size(); 10567 this._position(); 10568 } 10569 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 10570 this.uiDialog.resizable( "option", resizableOptions ); 10571 } 10572 }, 10573 10574 _setOption: function( key, value ) { 10575 var isDraggable, isResizable, 10576 uiDialog = this.uiDialog; 10577 10578 if ( key === "dialogClass" ) { 10579 uiDialog 10580 .removeClass( this.options.dialogClass ) 10581 .addClass( value ); 10582 } 10583 10584 if ( key === "disabled" ) { 10585 return; 10586 } 10587 10588 this._super( key, value ); 10589 10590 if ( key === "appendTo" ) { 10591 this.uiDialog.appendTo( this._appendTo() ); 10592 } 10593 10594 if ( key === "buttons" ) { 10595 this._createButtons(); 10596 } 10597 10598 if ( key === "closeText" ) { 10599 this.uiDialogTitlebarClose.button({ 10600 // Ensure that we always pass a string 10601 label: "" + value 10602 }); 10603 } 10604 10605 if ( key === "draggable" ) { 10606 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 10607 if ( isDraggable && !value ) { 10608 uiDialog.draggable( "destroy" ); 10609 } 10610 10611 if ( !isDraggable && value ) { 10612 this._makeDraggable(); 10613 } 10614 } 10615 10616 if ( key === "position" ) { 10617 this._position(); 10618 } 10619 10620 if ( key === "resizable" ) { 10621 // currently resizable, becoming non-resizable 10622 isResizable = uiDialog.is( ":data(ui-resizable)" ); 10623 if ( isResizable && !value ) { 10624 uiDialog.resizable( "destroy" ); 10625 } 10626 10627 // currently resizable, changing handles 10628 if ( isResizable && typeof value === "string" ) { 10629 uiDialog.resizable( "option", "handles", value ); 10630 } 10631 10632 // currently non-resizable, becoming resizable 10633 if ( !isResizable && value !== false ) { 10634 this._makeResizable(); 10635 } 10636 } 10637 10638 if ( key === "title" ) { 10639 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 10640 } 10641 }, 10642 10643 _size: function() { 10644 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10645 // divs will both have width and height set, so we need to reset them 10646 var nonContentHeight, minContentHeight, maxContentHeight, 10647 options = this.options; 10648 10649 // Reset content sizing 10650 this.element.show().css({ 10651 width: "auto", 10652 minHeight: 0, 10653 maxHeight: "none", 10654 height: 0 10655 }); 10656 10657 if ( options.minWidth > options.width ) { 10658 options.width = options.minWidth; 10659 } 10660 10661 // reset wrapper sizing 10662 // determine the height of all the non-content elements 10663 nonContentHeight = this.uiDialog.css({ 10664 height: "auto", 10665 width: options.width 10666 }) 10667 .outerHeight(); 10668 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10669 maxContentHeight = typeof options.maxHeight === "number" ? 10670 Math.max( 0, options.maxHeight - nonContentHeight ) : 10671 "none"; 10672 10673 if ( options.height === "auto" ) { 10674 this.element.css({ 10675 minHeight: minContentHeight, 10676 maxHeight: maxContentHeight, 10677 height: "auto" 10678 }); 10679 } else { 10680 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10681 } 10682 10683 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 10684 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10685 } 10686 }, 10687 10688 _blockFrames: function() { 10689 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10690 var iframe = $( this ); 10691 10692 return $( "<div>" ) 10693 .css({ 10694 position: "absolute", 10695 width: iframe.outerWidth(), 10696 height: iframe.outerHeight() 10697 }) 10698 .appendTo( iframe.parent() ) 10699 .offset( iframe.offset() )[0]; 10700 }); 10701 }, 10702 10703 _unblockFrames: function() { 10704 if ( this.iframeBlocks ) { 10705 this.iframeBlocks.remove(); 10706 delete this.iframeBlocks; 10707 } 10708 }, 10709 10710 _allowInteraction: function( event ) { 10711 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 10712 return true; 10713 } 10714 10715 // TODO: Remove hack when datepicker implements 10716 // the .ui-front logic (#8989) 10717 return !!$( event.target ).closest( ".ui-datepicker" ).length; 10718 }, 10719 10720 _createOverlay: function() { 10721 if ( !this.options.modal ) { 10722 return; 10723 } 10724 10725 // We use a delay in case the overlay is created from an 10726 // event that we're going to be cancelling (#2804) 10727 var isOpening = true; 10728 this._delay(function() { 10729 isOpening = false; 10730 }); 10731 10732 if ( !this.document.data( "ui-dialog-overlays" ) ) { 10733 10734 // Prevent use of anchors and inputs 10735 // Using _on() for an event handler shared across many instances is 10736 // safe because the dialogs stack and must be closed in reverse order 10737 this._on( this.document, { 10738 focusin: function( event ) { 10739 if ( isOpening ) { 10740 return; 10741 } 10742 10743 if ( !this._allowInteraction( event ) ) { 10744 event.preventDefault(); 10745 this._trackingInstances()[ 0 ]._focusTabbable(); 10746 } 10747 } 10748 }); 10749 } 10750 10751 this.overlay = $( "<div>" ) 10752 .addClass( "ui-widget-overlay ui-front" ) 10753 .appendTo( this._appendTo() ); 10754 this._on( this.overlay, { 10755 mousedown: "_keepFocus" 10756 }); 10757 this.document.data( "ui-dialog-overlays", 10758 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); 10759 }, 10760 10761 _destroyOverlay: function() { 10762 if ( !this.options.modal ) { 10763 return; 10764 } 10765 10766 if ( this.overlay ) { 10767 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 10768 10769 if ( !overlays ) { 10770 this.document 10771 .unbind( "focusin" ) 10772 .removeData( "ui-dialog-overlays" ); 10773 } else { 10774 this.document.data( "ui-dialog-overlays", overlays ); 10775 } 10776 10777 this.overlay.remove(); 10778 this.overlay = null; 10779 } 10780 } 10781}); 10782 10783 10784/*! 10785 * jQuery UI Progressbar 1.11.1 10786 * http://jqueryui.com 10787 * 10788 * Copyright 2014 jQuery Foundation and other contributors 10789 * Released under the MIT license. 10790 * http://jquery.org/license 10791 * 10792 * http://api.jqueryui.com/progressbar/ 10793 */ 10794 10795 10796var progressbar = $.widget( "ui.progressbar", { 10797 version: "1.11.1", 10798 options: { 10799 max: 100, 10800 value: 0, 10801 10802 change: null, 10803 complete: null 10804 }, 10805 10806 min: 0, 10807 10808 _create: function() { 10809 // Constrain initial value 10810 this.oldValue = this.options.value = this._constrainedValue(); 10811 10812 this.element 10813 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10814 .attr({ 10815 // Only set static values, aria-valuenow and aria-valuemax are 10816 // set inside _refreshValue() 10817 role: "progressbar", 10818 "aria-valuemin": this.min 10819 }); 10820 10821 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10822 .appendTo( this.element ); 10823 10824 this._refreshValue(); 10825 }, 10826 10827 _destroy: function() { 10828 this.element 10829 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10830 .removeAttr( "role" ) 10831 .removeAttr( "aria-valuemin" ) 10832 .removeAttr( "aria-valuemax" ) 10833 .removeAttr( "aria-valuenow" ); 10834 10835 this.valueDiv.remove(); 10836 }, 10837 10838 value: function( newValue ) { 10839 if ( newValue === undefined ) { 10840 return this.options.value; 10841 } 10842 10843 this.options.value = this._constrainedValue( newValue ); 10844 this._refreshValue(); 10845 }, 10846 10847 _constrainedValue: function( newValue ) { 10848 if ( newValue === undefined ) { 10849 newValue = this.options.value; 10850 } 10851 10852 this.indeterminate = newValue === false; 10853 10854 // sanitize value 10855 if ( typeof newValue !== "number" ) { 10856 newValue = 0; 10857 } 10858 10859 return this.indeterminate ? false : 10860 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10861 }, 10862 10863 _setOptions: function( options ) { 10864 // Ensure "value" option is set after other values (like max) 10865 var value = options.value; 10866 delete options.value; 10867 10868 this._super( options ); 10869 10870 this.options.value = this._constrainedValue( value ); 10871 this._refreshValue(); 10872 }, 10873 10874 _setOption: function( key, value ) { 10875 if ( key === "max" ) { 10876 // Don't allow a max less than min 10877 value = Math.max( this.min, value ); 10878 } 10879 if ( key === "disabled" ) { 10880 this.element 10881 .toggleClass( "ui-state-disabled", !!value ) 10882 .attr( "aria-disabled", value ); 10883 } 10884 this._super( key, value ); 10885 }, 10886 10887 _percentage: function() { 10888 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 10889 }, 10890 10891 _refreshValue: function() { 10892 var value = this.options.value, 10893 percentage = this._percentage(); 10894 10895 this.valueDiv 10896 .toggle( this.indeterminate || value > this.min ) 10897 .toggleClass( "ui-corner-right", value === this.options.max ) 10898 .width( percentage.toFixed(0) + "%" ); 10899 10900 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 10901 10902 if ( this.indeterminate ) { 10903 this.element.removeAttr( "aria-valuenow" ); 10904 if ( !this.overlayDiv ) { 10905 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 10906 } 10907 } else { 10908 this.element.attr({ 10909 "aria-valuemax": this.options.max, 10910 "aria-valuenow": value 10911 }); 10912 if ( this.overlayDiv ) { 10913 this.overlayDiv.remove(); 10914 this.overlayDiv = null; 10915 } 10916 } 10917 10918 if ( this.oldValue !== value ) { 10919 this.oldValue = value; 10920 this._trigger( "change" ); 10921 } 10922 if ( value === this.options.max ) { 10923 this._trigger( "complete" ); 10924 } 10925 }
vendor: 137,444 bytes, lines 10925-16373
10925 10926}); 10927 10928 10929/*! 10930 * jQuery UI Selectmenu 1.11.1 10931 * http://jqueryui.com 10932 * 10933 * Copyright 2014 jQuery Foundation and other contributors 10934 * Released under the MIT license. 10935 * http://jquery.org/license 10936 * 10937 * http://api.jqueryui.com/selectmenu 10938 */ 10939 10940 10941var selectmenu = $.widget( "ui.selectmenu", { 10942 version: "1.11.1", 10943 defaultElement: "<select>", 10944 options: { 10945 appendTo: null, 10946 disabled: null, 10947 icons: { 10948 button: "ui-icon-triangle-1-s" 10949 }, 10950 position: { 10951 my: "left top", 10952 at: "left bottom", 10953 collision: "none" 10954 }, 10955 width: null, 10956 10957 // callbacks 10958 change: null, 10959 close: null, 10960 focus: null, 10961 open: null, 10962 select: null 10963 }, 10964 10965 _create: function() { 10966 var selectmenuId = this.element.uniqueId().attr( "id" ); 10967 this.ids = { 10968 element: selectmenuId, 10969 button: selectmenuId + "-button", 10970 menu: selectmenuId + "-menu" 10971 }; 10972 10973 this._drawButton(); 10974 this._drawMenu(); 10975 10976 if ( this.options.disabled ) { 10977 this.disable(); 10978 } 10979 }, 10980 10981 _drawButton: function() { 10982 var that = this, 10983 tabindex = this.element.attr( "tabindex" ); 10984 10985 // Associate existing label with the new button 10986 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); 10987 this._on( this.label, { 10988 click: function( event ) { 10989 this.button.focus(); 10990 event.preventDefault(); 10991 } 10992 }); 10993 10994 // Hide original select element 10995 this.element.hide(); 10996 10997 // Create button 10998 this.button = $( "<span>", { 10999 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", 11000 tabindex: tabindex || this.options.disabled ? -1 : 0, 11001 id: this.ids.button, 11002 role: "combobox", 11003 "aria-expanded": "false", 11004 "aria-autocomplete": "list", 11005 "aria-owns": this.ids.menu, 11006 "aria-haspopup": "true" 11007 }) 11008 .insertAfter( this.element ); 11009 11010 $( "<span>", { 11011 "class": "ui-icon " + this.options.icons.button 11012 }) 11013 .prependTo( this.button ); 11014 11015 this.buttonText = $( "<span>", { 11016 "class": "ui-selectmenu-text" 11017 }) 11018 .appendTo( this.button ); 11019 11020 this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); 11021 this._resizeButton(); 11022 11023 this._on( this.button, this._buttonEvents ); 11024 this.button.one( "focusin", function() { 11025 11026 // Delay rendering the menu items until the button receives focus. 11027 // The menu may have already been rendered via a programmatic open. 11028 if ( !that.menuItems ) { 11029 that._refreshMenu(); 11030 } 11031 }); 11032 this._hoverable( this.button ); 11033 this._focusable( this.button ); 11034 }, 11035 11036 _drawMenu: function() { 11037 var that = this; 11038 11039 // Create menu 11040 this.menu = $( "<ul>", { 11041 "aria-hidden": "true", 11042 "aria-labelledby": this.ids.button, 11043 id: this.ids.menu 11044 }); 11045 11046 // Wrap menu 11047 this.menuWrap = $( "<div>", { 11048 "class": "ui-selectmenu-menu ui-front" 11049 }) 11050 .append( this.menu ) 11051 .appendTo( this._appendTo() ); 11052 11053 // Initialize menu widget 11054 this.menuInstance = this.menu 11055 .menu({ 11056 role: "listbox", 11057 select: function( event, ui ) { 11058 event.preventDefault(); 11059 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 11060 }, 11061 focus: function( event, ui ) { 11062 var item = ui.item.data( "ui-selectmenu-item" ); 11063 11064 // Prevent inital focus from firing and check if its a newly focused item 11065 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 11066 that._trigger( "focus", event, { item: item } ); 11067 if ( !that.isOpen ) { 11068 that._select( item, event ); 11069 } 11070 } 11071 that.focusIndex = item.index; 11072 11073 that.button.attr( "aria-activedescendant", 11074 that.menuItems.eq( item.index ).attr( "id" ) ); 11075 } 11076 }) 11077 .menu( "instance" ); 11078 11079 // Adjust menu styles to dropdown 11080 this.menu 11081 .addClass( "ui-corner-bottom" ) 11082 .removeClass( "ui-corner-all" ); 11083 11084 // Don't close the menu on mouseleave 11085 this.menuInstance._off( this.menu, "mouseleave" ); 11086 11087 // Cancel the menu's collapseAll on document click 11088 this.menuInstance._closeOnDocumentClick = function() { 11089 return false; 11090 }; 11091 11092 // Selects often contain empty items, but never contain dividers 11093 this.menuInstance._isDivider = function() { 11094 return false; 11095 }; 11096 }, 11097 11098 refresh: function() { 11099 this._refreshMenu(); 11100 this._setText( this.buttonText, this._getSelectedItem().text() ); 11101 if ( !this.options.width ) { 11102 this._resizeButton(); 11103 } 11104 }, 11105 11106 _refreshMenu: function() { 11107 this.menu.empty(); 11108 11109 var item, 11110 options = this.element.find( "option" ); 11111 11112 if ( !options.length ) { 11113 return; 11114 } 11115 11116 this._parseOptions( options ); 11117 this._renderMenu( this.menu, this.items ); 11118 11119 this.menuInstance.refresh(); 11120 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); 11121 11122 item = this._getSelectedItem(); 11123 11124 // Update the menu to have the correct item focused 11125 this.menuInstance.focus( null, item ); 11126 this._setAria( item.data( "ui-selectmenu-item" ) ); 11127 11128 // Set disabled state 11129 this._setOption( "disabled", this.element.prop( "disabled" ) ); 11130 }, 11131 11132 open: function( event ) { 11133 if ( this.options.disabled ) { 11134 return; 11135 } 11136 11137 // If this is the first time the menu is being opened, render the items 11138 if ( !this.menuItems ) { 11139 this._refreshMenu(); 11140 } else { 11141 11142 // Menu clears focus on close, reset focus to selected item 11143 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); 11144 this.menuInstance.focus( null, this._getSelectedItem() ); 11145 } 11146 11147 this.isOpen = true; 11148 this._toggleAttr(); 11149 this._resizeMenu(); 11150 this._position(); 11151 11152 this._on( this.document, this._documentClick ); 11153 11154 this._trigger( "open", event ); 11155 }, 11156 11157 _position: function() { 11158 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 11159 }, 11160 11161 close: function( event ) { 11162 if ( !this.isOpen ) { 11163 return; 11164 } 11165 11166 this.isOpen = false; 11167 this._toggleAttr(); 11168 11169 this._off( this.document ); 11170 11171 this._trigger( "close", event ); 11172 }, 11173 11174 widget: function() { 11175 return this.button; 11176 }, 11177 11178 menuWidget: function() { 11179 return this.menu; 11180 }, 11181 11182 _renderMenu: function( ul, items ) { 11183 var that = this, 11184 currentOptgroup = ""; 11185 11186 $.each( items, function( index, item ) { 11187 if ( item.optgroup !== currentOptgroup ) { 11188 $( "<li>", { 11189 "class": "ui-selectmenu-optgroup ui-menu-divider" + 11190 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 11191 " ui-state-disabled" : 11192 "" ), 11193 text: item.optgroup 11194 }) 11195 .appendTo( ul ); 11196 11197 currentOptgroup = item.optgroup; 11198 } 11199 11200 that._renderItemData( ul, item ); 11201 }); 11202 }, 11203 11204 _renderItemData: function( ul, item ) { 11205 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 11206 }, 11207 11208 _renderItem: function( ul, item ) { 11209 var li = $( "<li>" ); 11210 11211 if ( item.disabled ) { 11212 li.addClass( "ui-state-disabled" ); 11213 } 11214 this._setText( li, item.label ); 11215 11216 return li.appendTo( ul ); 11217 }, 11218 11219 _setText: function( element, value ) { 11220 if ( value ) { 11221 element.text( value ); 11222 } else { 11223 element.html( " " ); 11224 } 11225 }, 11226 11227 _move: function( direction, event ) { 11228 var item, next, 11229 filter = ".ui-menu-item"; 11230 11231 if ( this.isOpen ) { 11232 item = this.menuItems.eq( this.focusIndex ); 11233 } else { 11234 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); 11235 filter += ":not(.ui-state-disabled)"; 11236 } 11237 11238 if ( direction === "first" || direction === "last" ) { 11239 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 11240 } else { 11241 next = item[ direction + "All" ]( filter ).eq( 0 ); 11242 } 11243 11244 if ( next.length ) { 11245 this.menuInstance.focus( event, next ); 11246 } 11247 }, 11248 11249 _getSelectedItem: function() { 11250 return this.menuItems.eq( this.element[ 0 ].selectedIndex ); 11251 }, 11252 11253 _toggle: function( event ) { 11254 this[ this.isOpen ? "close" : "open" ]( event ); 11255 }, 11256 11257 _documentClick: { 11258 mousedown: function( event ) { 11259 if ( !this.isOpen ) { 11260 return; 11261 } 11262 11263 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { 11264 this.close( event ); 11265 } 11266 } 11267 }, 11268 11269 _buttonEvents: { 11270 11271 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 11272 mousedown: function( event ) { 11273 event.preventDefault(); 11274 }, 11275 11276 click: "_toggle", 11277 11278 keydown: function( event ) { 11279 var preventDefault = true; 11280 switch ( event.keyCode ) { 11281 case $.ui.keyCode.TAB: 11282 case $.ui.keyCode.ESCAPE: 11283 this.close( event ); 11284 preventDefault = false; 11285 break; 11286 case $.ui.keyCode.ENTER: 11287 if ( this.isOpen ) { 11288 this._selectFocusedItem( event ); 11289 } 11290 break; 11291 case $.ui.keyCode.UP: 11292 if ( event.altKey ) { 11293 this._toggle( event ); 11294 } else { 11295 this._move( "prev", event ); 11296 } 11297 break; 11298 case $.ui.keyCode.DOWN: 11299 if ( event.altKey ) { 11300 this._toggle( event ); 11301 } else { 11302 this._move( "next", event ); 11303 } 11304 break; 11305 case $.ui.keyCode.SPACE: 11306 if ( this.isOpen ) { 11307 this._selectFocusedItem( event ); 11308 } else { 11309 this._toggle( event ); 11310 } 11311 break; 11312 case $.ui.keyCode.LEFT: 11313 this._move( "prev", event ); 11314 break; 11315 case $.ui.keyCode.RIGHT: 11316 this._move( "next", event ); 11317 break; 11318 case $.ui.keyCode.HOME: 11319 case $.ui.keyCode.PAGE_UP: 11320 this._move( "first", event ); 11321 break; 11322 case $.ui.keyCode.END: 11323 case $.ui.keyCode.PAGE_DOWN: 11324 this._move( "last", event ); 11325 break; 11326 default: 11327 this.menu.trigger( event ); 11328 preventDefault = false; 11329 } 11330 11331 if ( preventDefault ) { 11332 event.preventDefault(); 11333 } 11334 } 11335 }, 11336 11337 _selectFocusedItem: function( event ) { 11338 var item = this.menuItems.eq( this.focusIndex ); 11339 if ( !item.hasClass( "ui-state-disabled" ) ) { 11340 this._select( item.data( "ui-selectmenu-item" ), event ); 11341 } 11342 }, 11343 11344 _select: function( item, event ) { 11345 var oldIndex = this.element[ 0 ].selectedIndex; 11346 11347 // Change native select element 11348 this.element[ 0 ].selectedIndex = item.index; 11349 this._setText( this.buttonText, item.label ); 11350 this._setAria( item ); 11351 this._trigger( "select", event, { item: item } ); 11352 11353 if ( item.index !== oldIndex ) { 11354 this._trigger( "change", event, { item: item } ); 11355 } 11356 11357 this.close( event ); 11358 }, 11359 11360 _setAria: function( item ) { 11361 var id = this.menuItems.eq( item.index ).attr( "id" ); 11362 11363 this.button.attr({ 11364 "aria-labelledby": id, 11365 "aria-activedescendant": id 11366 }); 11367 this.menu.attr( "aria-activedescendant", id ); 11368 }, 11369 11370 _setOption: function( key, value ) { 11371 if ( key === "icons" ) { 11372 this.button.find( "span.ui-icon" ) 11373 .removeClass( this.options.icons.button ) 11374 .addClass( value.button ); 11375 } 11376 11377 this._super( key, value ); 11378 11379 if ( key === "appendTo" ) { 11380 this.menuWrap.appendTo( this._appendTo() ); 11381 } 11382 11383 if ( key === "disabled" ) { 11384 this.menuInstance.option( "disabled", value ); 11385 this.button 11386 .toggleClass( "ui-state-disabled", value ) 11387 .attr( "aria-disabled", value ); 11388 11389 this.element.prop( "disabled", value ); 11390 if ( value ) { 11391 this.button.attr( "tabindex", -1 ); 11392 this.close(); 11393 } else { 11394 this.button.attr( "tabindex", 0 ); 11395 } 11396 } 11397 11398 if ( key === "width" ) { 11399 this._resizeButton(); 11400 } 11401 }, 11402 11403 _appendTo: function() { 11404 var element = this.options.appendTo; 11405 11406 if ( element ) { 11407 element = element.jquery || element.nodeType ? 11408 $( element ) : 11409 this.document.find( element ).eq( 0 ); 11410 } 11411 11412 if ( !element || !element[ 0 ] ) { 11413 element = this.element.closest( ".ui-front" ); 11414 } 11415 11416 if ( !element.length ) { 11417 element = this.document[ 0 ].body; 11418 } 11419 11420 return element; 11421 }, 11422 11423 _toggleAttr: function() { 11424 this.button 11425 .toggleClass( "ui-corner-top", this.isOpen ) 11426 .toggleClass( "ui-corner-all", !this.isOpen ) 11427 .attr( "aria-expanded", this.isOpen ); 11428 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); 11429 this.menu.attr( "aria-hidden", !this.isOpen ); 11430 }, 11431 11432 _resizeButton: function() { 11433 var width = this.options.width; 11434 11435 if ( !width ) { 11436 width = this.element.show().outerWidth(); 11437 this.element.hide(); 11438 } 11439 11440 this.button.outerWidth( width ); 11441 }, 11442 11443 _resizeMenu: function() { 11444 this.menu.outerWidth( Math.max( 11445 this.button.outerWidth(), 11446 11447 // support: IE10 11448 // IE10 wraps long text (possibly a rounding bug) 11449 // so we add 1px to avoid the wrapping 11450 this.menu.width( "" ).outerWidth() + 1 11451 ) ); 11452 }, 11453 11454 _getCreateOptions: function() { 11455 return { disabled: this.element.prop( "disabled" ) }; 11456 }, 11457 11458 _parseOptions: function( options ) { 11459 var data = []; 11460 options.each(function( index, item ) { 11461 var option = $( item ), 11462 optgroup = option.parent( "optgroup" ); 11463 data.push({ 11464 element: option, 11465 index: index, 11466 value: option.attr( "value" ), 11467 label: option.text(), 11468 optgroup: optgroup.attr( "label" ) || "", 11469 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 11470 }); 11471 }); 11472 this.items = data; 11473 }, 11474 11475 _destroy: function() { 11476 this.menuWrap.remove(); 11477 this.button.remove(); 11478 this.element.show(); 11479 this.element.removeUniqueId(); 11480 this.label.attr( "for", this.ids.element ); 11481 } 11482}); 11483 11484 11485/*! 11486 * jQuery UI Slider 1.11.1 11487 * http://jqueryui.com 11488 * 11489 * Copyright 2014 jQuery Foundation and other contributors 11490 * Released under the MIT license. 11491 * http://jquery.org/license 11492 * 11493 * http://api.jqueryui.com/slider/ 11494 */ 11495 11496 11497var slider = $.widget( "ui.slider", $.ui.mouse, { 11498 version: "1.11.1", 11499 widgetEventPrefix: "slide", 11500 11501 options: { 11502 animate: false, 11503 distance: 0, 11504 max: 100, 11505 min: 0, 11506 orientation: "horizontal", 11507 range: false, 11508 step: 1, 11509 value: 0, 11510 values: null, 11511 11512 // callbacks 11513 change: null, 11514 slide: null, 11515 start: null, 11516 stop: null 11517 }, 11518 11519 // number of pages in a slider 11520 // (how many times can you page up/down to go through the whole range) 11521 numPages: 5, 11522 11523 _create: function() { 11524 this._keySliding = false; 11525 this._mouseSliding = false; 11526 this._animateOff = true; 11527 this._handleIndex = null; 11528 this._detectOrientation(); 11529 this._mouseInit(); 11530 11531 this.element 11532 .addClass( "ui-slider" + 11533 " ui-slider-" + this.orientation + 11534 " ui-widget" + 11535 " ui-widget-content" + 11536 " ui-corner-all"); 11537 11538 this._refresh(); 11539 this._setOption( "disabled", this.options.disabled ); 11540 11541 this._animateOff = false; 11542 }, 11543 11544 _refresh: function() { 11545 this._createRange(); 11546 this._createHandles(); 11547 this._setupEvents(); 11548 this._refreshValue(); 11549 }, 11550 11551 _createHandles: function() { 11552 var i, handleCount, 11553 options = this.options, 11554 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 11555 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", 11556 handles = []; 11557 11558 handleCount = ( options.values && options.values.length ) || 1; 11559 11560 if ( existingHandles.length > handleCount ) { 11561 existingHandles.slice( handleCount ).remove(); 11562 existingHandles = existingHandles.slice( 0, handleCount ); 11563 } 11564 11565 for ( i = existingHandles.length; i < handleCount; i++ ) { 11566 handles.push( handle ); 11567 } 11568 11569 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 11570 11571 this.handle = this.handles.eq( 0 ); 11572 11573 this.handles.each(function( i ) { 11574 $( this ).data( "ui-slider-handle-index", i ); 11575 }); 11576 }, 11577 11578 _createRange: function() { 11579 var options = this.options, 11580 classes = ""; 11581 11582 if ( options.range ) { 11583 if ( options.range === true ) { 11584 if ( !options.values ) { 11585 options.values = [ this._valueMin(), this._valueMin() ]; 11586 } else if ( options.values.length && options.values.length !== 2 ) { 11587 options.values = [ options.values[0], options.values[0] ]; 11588 } else if ( $.isArray( options.values ) ) { 11589 options.values = options.values.slice(0); 11590 } 11591 } 11592 11593 if ( !this.range || !this.range.length ) { 11594 this.range = $( "<div></div>" ) 11595 .appendTo( this.element ); 11596 11597 classes = "ui-slider-range" + 11598 // note: this isn't the most fittingly semantic framework class for this element, 11599 // but worked best visually with a variety of themes 11600 " ui-widget-header ui-corner-all"; 11601 } else { 11602 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 11603 // Handle range switching from true to min/max 11604 .css({ 11605 "left": "", 11606 "bottom": "" 11607 }); 11608 } 11609 11610 this.range.addClass( classes + 11611 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 11612 } else { 11613 if ( this.range ) { 11614 this.range.remove(); 11615 } 11616 this.range = null; 11617 } 11618 }, 11619 11620 _setupEvents: function() { 11621 this._off( this.handles ); 11622 this._on( this.handles, this._handleEvents ); 11623 this._hoverable( this.handles ); 11624 this._focusable( this.handles ); 11625 }, 11626 11627 _destroy: function() { 11628 this.handles.remove(); 11629 if ( this.range ) { 11630 this.range.remove(); 11631 } 11632 11633 this.element 11634 .removeClass( "ui-slider" + 11635 " ui-slider-horizontal" + 11636 " ui-slider-vertical" + 11637 " ui-widget" + 11638 " ui-widget-content" + 11639 " ui-corner-all" ); 11640 11641 this._mouseDestroy(); 11642 }, 11643 11644 _mouseCapture: function( event ) { 11645 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 11646 that = this, 11647 o = this.options; 11648 11649 if ( o.disabled ) { 11650 return false; 11651 } 11652 11653 this.elementSize = { 11654 width: this.element.outerWidth(), 11655 height: this.element.outerHeight() 11656 }; 11657 this.elementOffset = this.element.offset(); 11658 11659 position = { x: event.pageX, y: event.pageY }; 11660 normValue = this._normValueFromMouse( position ); 11661 distance = this._valueMax() - this._valueMin() + 1; 11662 this.handles.each(function( i ) { 11663 var thisDistance = Math.abs( normValue - that.values(i) ); 11664 if (( distance > thisDistance ) || 11665 ( distance === thisDistance && 11666 (i === that._lastChangedValue || that.values(i) === o.min ))) { 11667 distance = thisDistance; 11668 closestHandle = $( this ); 11669 index = i; 11670 } 11671 }); 11672 11673 allowed = this._start( event, index ); 11674 if ( allowed === false ) { 11675 return false; 11676 } 11677 this._mouseSliding = true; 11678 11679 this._handleIndex = index; 11680 11681 closestHandle 11682 .addClass( "ui-state-active" ) 11683 .focus(); 11684 11685 offset = closestHandle.offset(); 11686 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 11687 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 11688 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 11689 top: event.pageY - offset.top - 11690 ( closestHandle.height() / 2 ) - 11691 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 11692 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 11693 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 11694 }; 11695 11696 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 11697 this._slide( event, index, normValue ); 11698 } 11699 this._animateOff = true; 11700 return true; 11701 }, 11702 11703 _mouseStart: function() { 11704 return true; 11705 }, 11706 11707 _mouseDrag: function( event ) { 11708 var position = { x: event.pageX, y: event.pageY }, 11709 normValue = this._normValueFromMouse( position ); 11710 11711 this._slide( event, this._handleIndex, normValue ); 11712 11713 return false; 11714 }, 11715 11716 _mouseStop: function( event ) { 11717 this.handles.removeClass( "ui-state-active" ); 11718 this._mouseSliding = false; 11719 11720 this._stop( event, this._handleIndex ); 11721 this._change( event, this._handleIndex ); 11722 11723 this._handleIndex = null; 11724 this._clickOffset = null; 11725 this._animateOff = false; 11726 11727 return false; 11728 }, 11729 11730 _detectOrientation: function() { 11731 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 11732 }, 11733 11734 _normValueFromMouse: function( position ) { 11735 var pixelTotal, 11736 pixelMouse, 11737 percentMouse, 11738 valueTotal, 11739 valueMouse; 11740 11741 if ( this.orientation === "horizontal" ) { 11742 pixelTotal = this.elementSize.width; 11743 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 11744 } else { 11745 pixelTotal = this.elementSize.height; 11746 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 11747 } 11748 11749 percentMouse = ( pixelMouse / pixelTotal ); 11750 if ( percentMouse > 1 ) { 11751 percentMouse = 1; 11752 } 11753 if ( percentMouse < 0 ) { 11754 percentMouse = 0; 11755 } 11756 if ( this.orientation === "vertical" ) { 11757 percentMouse = 1 - percentMouse; 11758 } 11759 11760 valueTotal = this._valueMax() - this._valueMin(); 11761 valueMouse = this._valueMin() + percentMouse * valueTotal; 11762 11763 return this._trimAlignValue( valueMouse ); 11764 }, 11765 11766 _start: function( event, index ) { 11767 var uiHash = { 11768 handle: this.handles[ index ], 11769 value: this.value() 11770 }; 11771 if ( this.options.values && this.options.values.length ) { 11772 uiHash.value = this.values( index ); 11773 uiHash.values = this.values(); 11774 } 11775 return this._trigger( "start", event, uiHash ); 11776 }, 11777 11778 _slide: function( event, index, newVal ) { 11779 var otherVal, 11780 newValues, 11781 allowed; 11782 11783 if ( this.options.values && this.options.values.length ) { 11784 otherVal = this.values( index ? 0 : 1 ); 11785 11786 if ( ( this.options.values.length === 2 && this.options.range === true ) && 11787 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 11788 ) { 11789 newVal = otherVal; 11790 } 11791 11792 if ( newVal !== this.values( index ) ) { 11793 newValues = this.values(); 11794 newValues[ index ] = newVal; 11795 // A slide can be canceled by returning false from the slide callback 11796 allowed = this._trigger( "slide", event, { 11797 handle: this.handles[ index ], 11798 value: newVal, 11799 values: newValues 11800 } ); 11801 otherVal = this.values( index ? 0 : 1 ); 11802 if ( allowed !== false ) { 11803 this.values( index, newVal ); 11804 } 11805 } 11806 } else { 11807 if ( newVal !== this.value() ) { 11808 // A slide can be canceled by returning false from the slide callback 11809 allowed = this._trigger( "slide", event, { 11810 handle: this.handles[ index ], 11811 value: newVal 11812 } ); 11813 if ( allowed !== false ) { 11814 this.value( newVal ); 11815 } 11816 } 11817 } 11818 }, 11819 11820 _stop: function( event, index ) { 11821 var uiHash = { 11822 handle: this.handles[ index ], 11823 value: this.value() 11824 }; 11825 if ( this.options.values && this.options.values.length ) { 11826 uiHash.value = this.values( index ); 11827 uiHash.values = this.values(); 11828 } 11829 11830 this._trigger( "stop", event, uiHash ); 11831 }, 11832 11833 _change: function( event, index ) { 11834 if ( !this._keySliding && !this._mouseSliding ) { 11835 var uiHash = { 11836 handle: this.handles[ index ], 11837 value: this.value() 11838 }; 11839 if ( this.options.values && this.options.values.length ) { 11840 uiHash.value = this.values( index ); 11841 uiHash.values = this.values(); 11842 } 11843 11844 //store the last changed value index for reference when handles overlap 11845 this._lastChangedValue = index; 11846 11847 this._trigger( "change", event, uiHash ); 11848 } 11849 }, 11850 11851 value: function( newValue ) { 11852 if ( arguments.length ) { 11853 this.options.value = this._trimAlignValue( newValue ); 11854 this._refreshValue(); 11855 this._change( null, 0 ); 11856 return; 11857 } 11858 11859 return this._value(); 11860 }, 11861 11862 values: function( index, newValue ) { 11863 var vals, 11864 newValues, 11865 i; 11866 11867 if ( arguments.length > 1 ) { 11868 this.options.values[ index ] = this._trimAlignValue( newValue ); 11869 this._refreshValue(); 11870 this._change( null, index ); 11871 return; 11872 } 11873 11874 if ( arguments.length ) { 11875 if ( $.isArray( arguments[ 0 ] ) ) { 11876 vals = this.options.values; 11877 newValues = arguments[ 0 ]; 11878 for ( i = 0; i < vals.length; i += 1 ) { 11879 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 11880 this._change( null, i ); 11881 } 11882 this._refreshValue(); 11883 } else { 11884 if ( this.options.values && this.options.values.length ) { 11885 return this._values( index ); 11886 } else { 11887 return this.value(); 11888 } 11889 } 11890 } else { 11891 return this._values(); 11892 } 11893 }, 11894 11895 _setOption: function( key, value ) { 11896 var i, 11897 valsLength = 0; 11898 11899 if ( key === "range" && this.options.range === true ) { 11900 if ( value === "min" ) { 11901 this.options.value = this._values( 0 ); 11902 this.options.values = null; 11903 } else if ( value === "max" ) { 11904 this.options.value = this._values( this.options.values.length - 1 ); 11905 this.options.values = null; 11906 } 11907 } 11908 11909 if ( $.isArray( this.options.values ) ) { 11910 valsLength = this.options.values.length; 11911 } 11912 11913 if ( key === "disabled" ) { 11914 this.element.toggleClass( "ui-state-disabled", !!value ); 11915 } 11916 11917 this._super( key, value ); 11918 11919 switch ( key ) { 11920 case "orientation": 11921 this._detectOrientation(); 11922 this.element 11923 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 11924 .addClass( "ui-slider-" + this.orientation ); 11925 this._refreshValue(); 11926 11927 // Reset positioning from previous orientation 11928 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 11929 break; 11930 case "value": 11931 this._animateOff = true; 11932 this._refreshValue(); 11933 this._change( null, 0 ); 11934 this._animateOff = false; 11935 break; 11936 case "values": 11937 this._animateOff = true; 11938 this._refreshValue(); 11939 for ( i = 0; i < valsLength; i += 1 ) { 11940 this._change( null, i ); 11941 } 11942 this._animateOff = false; 11943 break; 11944 case "min": 11945 case "max": 11946 this._animateOff = true; 11947 this._refreshValue(); 11948 this._animateOff = false; 11949 break; 11950 case "range": 11951 this._animateOff = true; 11952 this._refresh(); 11953 this._animateOff = false; 11954 break; 11955 } 11956 }, 11957 11958 //internal value getter 11959 // _value() returns value trimmed by min and max, aligned by step 11960 _value: function() { 11961 var val = this.options.value; 11962 val = this._trimAlignValue( val ); 11963 11964 return val; 11965 }, 11966 11967 //internal values getter 11968 // _values() returns array of values trimmed by min and max, aligned by step 11969 // _values( index ) returns single value trimmed by min and max, aligned by step 11970 _values: function( index ) { 11971 var val, 11972 vals, 11973 i; 11974 11975 if ( arguments.length ) { 11976 val = this.options.values[ index ]; 11977 val = this._trimAlignValue( val ); 11978 11979 return val; 11980 } else if ( this.options.values && this.options.values.length ) { 11981 // .slice() creates a copy of the array 11982 // this copy gets trimmed by min and max and then returned 11983 vals = this.options.values.slice(); 11984 for ( i = 0; i < vals.length; i+= 1) { 11985 vals[ i ] = this._trimAlignValue( vals[ i ] ); 11986 } 11987 11988 return vals; 11989 } else { 11990 return []; 11991 } 11992 }, 11993 11994 // returns the step-aligned value that val is closest to, between (inclusive) min and max 11995 _trimAlignValue: function( val ) { 11996 if ( val <= this._valueMin() ) { 11997 return this._valueMin(); 11998 } 11999 if ( val >= this._valueMax() ) { 12000 return this._valueMax(); 12001 } 12002 var step = ( this.options.step > 0 ) ? this.options.step : 1, 12003 valModStep = (val - this._valueMin()) % step, 12004 alignValue = val - valModStep; 12005 12006 if ( Math.abs(valModStep) * 2 >= step ) { 12007 alignValue += ( valModStep > 0 ) ? step : ( -step ); 12008 } 12009 12010 // Since JavaScript has problems with large floats, round 12011 // the final value to 5 digits after the decimal point (see #4124) 12012 return parseFloat( alignValue.toFixed(5) ); 12013 }, 12014 12015 _valueMin: function() { 12016 return this.options.min; 12017 }, 12018 12019 _valueMax: function() { 12020 return this.options.max; 12021 }, 12022 12023 _refreshValue: function() { 12024 var lastValPercent, valPercent, value, valueMin, valueMax, 12025 oRange = this.options.range, 12026 o = this.options, 12027 that = this, 12028 animate = ( !this._animateOff ) ? o.animate : false, 12029 _set = {}; 12030 12031 if ( this.options.values && this.options.values.length ) { 12032 this.handles.each(function( i ) { 12033 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 12034 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12035 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12036 if ( that.options.range === true ) { 12037 if ( that.orientation === "horizontal" ) { 12038 if ( i === 0 ) { 12039 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 12040 } 12041 if ( i === 1 ) { 12042 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12043 } 12044 } else { 12045 if ( i === 0 ) { 12046 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 12047 } 12048 if ( i === 1 ) { 12049 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12050 } 12051 } 12052 } 12053 lastValPercent = valPercent; 12054 }); 12055 } else { 12056 value = this.value(); 12057 valueMin = this._valueMin(); 12058 valueMax = this._valueMax(); 12059 valPercent = ( valueMax !== valueMin ) ? 12060 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 12061 0; 12062 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12063 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12064 12065 if ( oRange === "min" && this.orientation === "horizontal" ) { 12066 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 12067 } 12068 if ( oRange === "max" && this.orientation === "horizontal" ) { 12069 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12070 } 12071 if ( oRange === "min" && this.orientation === "vertical" ) { 12072 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 12073 } 12074 if ( oRange === "max" && this.orientation === "vertical" ) { 12075 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12076 } 12077 } 12078 }, 12079 12080 _handleEvents: { 12081 keydown: function( event ) { 12082 var allowed, curVal, newVal, step, 12083 index = $( event.target ).data( "ui-slider-handle-index" ); 12084 12085 switch ( event.keyCode ) { 12086 case $.ui.keyCode.HOME: 12087 case $.ui.keyCode.END: 12088 case $.ui.keyCode.PAGE_UP: 12089 case $.ui.keyCode.PAGE_DOWN: 12090 case $.ui.keyCode.UP: 12091 case $.ui.keyCode.RIGHT: 12092 case $.ui.keyCode.DOWN: 12093 case $.ui.keyCode.LEFT: 12094 event.preventDefault(); 12095 if ( !this._keySliding ) { 12096 this._keySliding = true; 12097 $( event.target ).addClass( "ui-state-active" ); 12098 allowed = this._start( event, index ); 12099 if ( allowed === false ) { 12100 return; 12101 } 12102 } 12103 break; 12104 } 12105 12106 step = this.options.step; 12107 if ( this.options.values && this.options.values.length ) { 12108 curVal = newVal = this.values( index ); 12109 } else { 12110 curVal = newVal = this.value(); 12111 } 12112 12113 switch ( event.keyCode ) { 12114 case $.ui.keyCode.HOME: 12115 newVal = this._valueMin(); 12116 break; 12117 case $.ui.keyCode.END: 12118 newVal = this._valueMax(); 12119 break; 12120 case $.ui.keyCode.PAGE_UP: 12121 newVal = this._trimAlignValue( 12122 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 12123 ); 12124 break; 12125 case $.ui.keyCode.PAGE_DOWN: 12126 newVal = this._trimAlignValue( 12127 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); 12128 break; 12129 case $.ui.keyCode.UP: 12130 case $.ui.keyCode.RIGHT: 12131 if ( curVal === this._valueMax() ) { 12132 return; 12133 } 12134 newVal = this._trimAlignValue( curVal + step ); 12135 break; 12136 case $.ui.keyCode.DOWN: 12137 case $.ui.keyCode.LEFT: 12138 if ( curVal === this._valueMin() ) { 12139 return; 12140 } 12141 newVal = this._trimAlignValue( curVal - step ); 12142 break; 12143 } 12144 12145 this._slide( event, index, newVal ); 12146 }, 12147 keyup: function( event ) { 12148 var index = $( event.target ).data( "ui-slider-handle-index" ); 12149 12150 if ( this._keySliding ) { 12151 this._keySliding = false; 12152 this._stop( event, index ); 12153 this._change( event, index ); 12154 $( event.target ).removeClass( "ui-state-active" ); 12155 } 12156 } 12157 } 12158}); 12159 12160 12161/*! 12162 * jQuery UI Spinner 1.11.1 12163 * http://jqueryui.com 12164 * 12165 * Copyright 2014 jQuery Foundation and other contributors 12166 * Released under the MIT license. 12167 * http://jquery.org/license 12168 * 12169 * http://api.jqueryui.com/spinner/ 12170 */ 12171 12172 12173function spinner_modifier( fn ) { 12174 return function() { 12175 var previous = this.element.val(); 12176 fn.apply( this, arguments ); 12177 this._refresh(); 12178 if ( previous !== this.element.val() ) { 12179 this._trigger( "change" ); 12180 } 12181 }; 12182} 12183 12184var spinner = $.widget( "ui.spinner", { 12185 version: "1.11.1", 12186 defaultElement: "<input>", 12187 widgetEventPrefix: "spin", 12188 options: { 12189 culture: null, 12190 icons: { 12191 down: "ui-icon-triangle-1-s", 12192 up: "ui-icon-triangle-1-n" 12193 }, 12194 incremental: true, 12195 max: null, 12196 min: null, 12197 numberFormat: null, 12198 page: 10, 12199 step: 1, 12200 12201 change: null, 12202 spin: null, 12203 start: null, 12204 stop: null 12205 }, 12206 12207 _create: function() { 12208 // handle string values that need to be parsed 12209 this._setOption( "max", this.options.max ); 12210 this._setOption( "min", this.options.min ); 12211 this._setOption( "step", this.options.step ); 12212 12213 // Only format if there is a value, prevents the field from being marked 12214 // as invalid in Firefox, see #9573. 12215 if ( this.value() !== "" ) { 12216 // Format the value, but don't constrain. 12217 this._value( this.element.val(), true ); 12218 } 12219 12220 this._draw(); 12221 this._on( this._events ); 12222 this._refresh(); 12223 12224 // turning off autocomplete prevents the browser from remembering the 12225 // value when navigating through history, so we re-enable autocomplete 12226 // if the page is unloaded before the widget is destroyed. #7790 12227 this._on( this.window, { 12228 beforeunload: function() { 12229 this.element.removeAttr( "autocomplete" ); 12230 } 12231 }); 12232 }, 12233 12234 _getCreateOptions: function() { 12235 var options = {}, 12236 element = this.element; 12237 12238 $.each( [ "min", "max", "step" ], function( i, option ) { 12239 var value = element.attr( option ); 12240 if ( value !== undefined && value.length ) { 12241 options[ option ] = value; 12242 } 12243 }); 12244 12245 return options; 12246 }, 12247 12248 _events: { 12249 keydown: function( event ) { 12250 if ( this._start( event ) && this._keydown( event ) ) { 12251 event.preventDefault(); 12252 } 12253 }, 12254 keyup: "_stop", 12255 focus: function() { 12256 this.previous = this.element.val(); 12257 }, 12258 blur: function( event ) { 12259 if ( this.cancelBlur ) { 12260 delete this.cancelBlur; 12261 return; 12262 } 12263 12264 this._stop(); 12265 this._refresh(); 12266 if ( this.previous !== this.element.val() ) { 12267 this._trigger( "change", event ); 12268 } 12269 }, 12270 mousewheel: function( event, delta ) { 12271 if ( !delta ) { 12272 return; 12273 } 12274 if ( !this.spinning && !this._start( event ) ) { 12275 return false; 12276 } 12277 12278 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 12279 clearTimeout( this.mousewheelTimer ); 12280 this.mousewheelTimer = this._delay(function() { 12281 if ( this.spinning ) { 12282 this._stop( event ); 12283 } 12284 }, 100 ); 12285 event.preventDefault(); 12286 }, 12287 "mousedown .ui-spinner-button": function( event ) { 12288 var previous; 12289 12290 // We never want the buttons to have focus; whenever the user is 12291 // interacting with the spinner, the focus should be on the input. 12292 // If the input is focused then this.previous is properly set from 12293 // when the input first received focus. If the input is not focused 12294 // then we need to set this.previous based on the value before spinning. 12295 previous = this.element[0] === this.document[0].activeElement ? 12296 this.previous : this.element.val(); 12297 function checkFocus() { 12298 var isActive = this.element[0] === this.document[0].activeElement; 12299 if ( !isActive ) { 12300 this.element.focus(); 12301 this.previous = previous; 12302 // support: IE 12303 // IE sets focus asynchronously, so we need to check if focus 12304 // moved off of the input because the user clicked on the button. 12305 this._delay(function() { 12306 this.previous = previous; 12307 }); 12308 } 12309 } 12310 12311 // ensure focus is on (or stays on) the text field 12312 event.preventDefault(); 12313 checkFocus.call( this ); 12314 12315 // support: IE 12316 // IE doesn't prevent moving focus even with event.preventDefault() 12317 // so we set a flag to know when we should ignore the blur event 12318 // and check (again) if focus moved off of the input. 12319 this.cancelBlur = true; 12320 this._delay(function() { 12321 delete this.cancelBlur; 12322 checkFocus.call( this ); 12323 }); 12324 12325 if ( this._start( event ) === false ) { 12326 return; 12327 } 12328 12329 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12330 }, 12331 "mouseup .ui-spinner-button": "_stop", 12332 "mouseenter .ui-spinner-button": function( event ) { 12333 // button will add ui-state-active if mouse was down while mouseleave and kept down 12334 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 12335 return; 12336 } 12337 12338 if ( this._start( event ) === false ) { 12339 return false; 12340 } 12341 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12342 }, 12343 // TODO: do we really want to consider this a stop? 12344 // shouldn't we just stop the repeater and wait until mouseup before 12345 // we trigger the stop event? 12346 "mouseleave .ui-spinner-button": "_stop" 12347 }, 12348 12349 _draw: function() { 12350 var uiSpinner = this.uiSpinner = this.element 12351 .addClass( "ui-spinner-input" ) 12352 .attr( "autocomplete", "off" ) 12353 .wrap( this._uiSpinnerHtml() ) 12354 .parent() 12355 // add buttons 12356 .append( this._buttonHtml() ); 12357 12358 this.element.attr( "role", "spinbutton" ); 12359 12360 // button bindings 12361 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 12362 .attr( "tabIndex", -1 ) 12363 .button() 12364 .removeClass( "ui-corner-all" ); 12365 12366 // IE 6 doesn't understand height: 50% for the buttons 12367 // unless the wrapper has an explicit height 12368 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 12369 uiSpinner.height() > 0 ) { 12370 uiSpinner.height( uiSpinner.height() ); 12371 } 12372 12373 // disable spinner if element was already disabled 12374 if ( this.options.disabled ) { 12375 this.disable(); 12376 } 12377 }, 12378 12379 _keydown: function( event ) { 12380 var options = this.options, 12381 keyCode = $.ui.keyCode; 12382 12383 switch ( event.keyCode ) { 12384 case keyCode.UP: 12385 this._repeat( null, 1, event ); 12386 return true; 12387 case keyCode.DOWN: 12388 this._repeat( null, -1, event ); 12389 return true; 12390 case keyCode.PAGE_UP: 12391 this._repeat( null, options.page, event ); 12392 return true; 12393 case keyCode.PAGE_DOWN: 12394 this._repeat( null, -options.page, event ); 12395 return true; 12396 } 12397 12398 return false; 12399 }, 12400 12401 _uiSpinnerHtml: function() { 12402 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 12403 }, 12404 12405 _buttonHtml: function() { 12406 return "" + 12407 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 12408 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 12409 "</a>" + 12410 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 12411 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 12412 "</a>"; 12413 }, 12414 12415 _start: function( event ) { 12416 if ( !this.spinning && this._trigger( "start", event ) === false ) { 12417 return false; 12418 } 12419 12420 if ( !this.counter ) { 12421 this.counter = 1; 12422 } 12423 this.spinning = true; 12424 return true; 12425 }, 12426 12427 _repeat: function( i, steps, event ) { 12428 i = i || 500; 12429 12430 clearTimeout( this.timer ); 12431 this.timer = this._delay(function() { 12432 this._repeat( 40, steps, event ); 12433 }, i ); 12434 12435 this._spin( steps * this.options.step, event ); 12436 }, 12437 12438 _spin: function( step, event ) { 12439 var value = this.value() || 0; 12440 12441 if ( !this.counter ) { 12442 this.counter = 1; 12443 } 12444 12445 value = this._adjustValue( value + step * this._increment( this.counter ) ); 12446 12447 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 12448 this._value( value ); 12449 this.counter++; 12450 } 12451 }, 12452 12453 _increment: function( i ) { 12454 var incremental = this.options.incremental; 12455 12456 if ( incremental ) { 12457 return $.isFunction( incremental ) ? 12458 incremental( i ) : 12459 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 12460 } 12461 12462 return 1; 12463 }, 12464 12465 _precision: function() { 12466 var precision = this._precisionOf( this.options.step ); 12467 if ( this.options.min !== null ) { 12468 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 12469 } 12470 return precision; 12471 }, 12472 12473 _precisionOf: function( num ) { 12474 var str = num.toString(), 12475 decimal = str.indexOf( "." ); 12476 return decimal === -1 ? 0 : str.length - decimal - 1; 12477 }, 12478 12479 _adjustValue: function( value ) { 12480 var base, aboveMin, 12481 options = this.options; 12482 12483 // make sure we're at a valid step 12484 // - find out where we are relative to the base (min or 0) 12485 base = options.min !== null ? options.min : 0; 12486 aboveMin = value - base; 12487 // - round to the nearest step 12488 aboveMin = Math.round(aboveMin / options.step) * options.step; 12489 // - rounding is based on 0, so adjust back to our base 12490 value = base + aboveMin; 12491 12492 // fix precision from bad JS floating point math 12493 value = parseFloat( value.toFixed( this._precision() ) ); 12494 12495 // clamp the value 12496 if ( options.max !== null && value > options.max) { 12497 return options.max; 12498 } 12499 if ( options.min !== null && value < options.min ) { 12500 return options.min; 12501 } 12502 12503 return value; 12504 }, 12505 12506 _stop: function( event ) { 12507 if ( !this.spinning ) { 12508 return; 12509 } 12510 12511 clearTimeout( this.timer ); 12512 clearTimeout( this.mousewheelTimer ); 12513 this.counter = 0; 12514 this.spinning = false; 12515 this._trigger( "stop", event ); 12516 }, 12517 12518 _setOption: function( key, value ) { 12519 if ( key === "culture" || key === "numberFormat" ) { 12520 var prevValue = this._parse( this.element.val() ); 12521 this.options[ key ] = value; 12522 this.element.val( this._format( prevValue ) ); 12523 return; 12524 } 12525 12526 if ( key === "max" || key === "min" || key === "step" ) { 12527 if ( typeof value === "string" ) { 12528 value = this._parse( value ); 12529 } 12530 } 12531 if ( key === "icons" ) { 12532 this.buttons.first().find( ".ui-icon" ) 12533 .removeClass( this.options.icons.up ) 12534 .addClass( value.up ); 12535 this.buttons.last().find( ".ui-icon" ) 12536 .removeClass( this.options.icons.down ) 12537 .addClass( value.down ); 12538 } 12539 12540 this._super( key, value ); 12541 12542 if ( key === "disabled" ) { 12543 this.widget().toggleClass( "ui-state-disabled", !!value ); 12544 this.element.prop( "disabled", !!value ); 12545 this.buttons.button( value ? "disable" : "enable" ); 12546 } 12547 }, 12548 12549 _setOptions: spinner_modifier(function( options ) { 12550 this._super( options ); 12551 }), 12552 12553 _parse: function( val ) { 12554 if ( typeof val === "string" && val !== "" ) { 12555 val = window.Globalize && this.options.numberFormat ? 12556 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 12557 } 12558 return val === "" || isNaN( val ) ? null : val; 12559 }, 12560 12561 _format: function( value ) { 12562 if ( value === "" ) { 12563 return ""; 12564 } 12565 return window.Globalize && this.options.numberFormat ? 12566 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 12567 value; 12568 }, 12569 12570 _refresh: function() { 12571 this.element.attr({ 12572 "aria-valuemin": this.options.min, 12573 "aria-valuemax": this.options.max, 12574 // TODO: what should we do with values that can't be parsed? 12575 "aria-valuenow": this._parse( this.element.val() ) 12576 }); 12577 }, 12578 12579 isValid: function() { 12580 var value = this.value(); 12581 12582 // null is invalid 12583 if ( value === null ) { 12584 return false; 12585 } 12586 12587 // if value gets adjusted, it's invalid 12588 return value === this._adjustValue( value ); 12589 }, 12590 12591 // update the value without triggering change 12592 _value: function( value, allowAny ) { 12593 var parsed; 12594 if ( value !== "" ) { 12595 parsed = this._parse( value ); 12596 if ( parsed !== null ) { 12597 if ( !allowAny ) { 12598 parsed = this._adjustValue( parsed ); 12599 } 12600 value = this._format( parsed ); 12601 } 12602 } 12603 this.element.val( value ); 12604 this._refresh(); 12605 }, 12606 12607 _destroy: function() { 12608 this.element 12609 .removeClass( "ui-spinner-input" ) 12610 .prop( "disabled", false ) 12611 .removeAttr( "autocomplete" ) 12612 .removeAttr( "role" ) 12613 .removeAttr( "aria-valuemin" ) 12614 .removeAttr( "aria-valuemax" ) 12615 .removeAttr( "aria-valuenow" ); 12616 this.uiSpinner.replaceWith( this.element ); 12617 }, 12618 12619 stepUp: spinner_modifier(function( steps ) { 12620 this._stepUp( steps ); 12621 }), 12622 _stepUp: function( steps ) { 12623 if ( this._start() ) { 12624 this._spin( (steps || 1) * this.options.step ); 12625 this._stop(); 12626 } 12627 }, 12628 12629 stepDown: spinner_modifier(function( steps ) { 12630 this._stepDown( steps ); 12631 }), 12632 _stepDown: function( steps ) { 12633 if ( this._start() ) { 12634 this._spin( (steps || 1) * -this.options.step ); 12635 this._stop(); 12636 } 12637 }, 12638 12639 pageUp: spinner_modifier(function( pages ) { 12640 this._stepUp( (pages || 1) * this.options.page ); 12641 }), 12642 12643 pageDown: spinner_modifier(function( pages ) { 12644 this._stepDown( (pages || 1) * this.options.page ); 12645 }), 12646 12647 value: function( newVal ) { 12648 if ( !arguments.length ) { 12649 return this._parse( this.element.val() ); 12650 } 12651 spinner_modifier( this._value ).call( this, newVal ); 12652 }, 12653 12654 widget: function() { 12655 return this.uiSpinner; 12656 } 12657}); 12658 12659 12660/*! 12661 * jQuery UI Tabs 1.11.1 12662 * http://jqueryui.com 12663 * 12664 * Copyright 2014 jQuery Foundation and other contributors 12665 * Released under the MIT license. 12666 * http://jquery.org/license 12667 * 12668 * http://api.jqueryui.com/tabs/ 12669 */ 12670 12671 12672var tabs = $.widget( "ui.tabs", { 12673 version: "1.11.1", 12674 delay: 300, 12675 options: { 12676 active: null, 12677 collapsible: false, 12678 event: "click", 12679 heightStyle: "content", 12680 hide: null, 12681 show: null, 12682 12683 // callbacks 12684 activate: null, 12685 beforeActivate: null, 12686 beforeLoad: null, 12687 load: null 12688 }, 12689 12690 _isLocal: (function() { 12691 var rhash = /#.*$/; 12692 12693 return function( anchor ) { 12694 var anchorUrl, locationUrl; 12695 12696 // support: IE7 12697 // IE7 doesn't normalize the href property when set via script (#9317) 12698 anchor = anchor.cloneNode( false ); 12699 12700 anchorUrl = anchor.href.replace( rhash, "" ); 12701 locationUrl = location.href.replace( rhash, "" ); 12702 12703 // decoding may throw an error if the URL isn't UTF-8 (#9518) 12704 try { 12705 anchorUrl = decodeURIComponent( anchorUrl ); 12706 } catch ( error ) {} 12707 try { 12708 locationUrl = decodeURIComponent( locationUrl ); 12709 } catch ( error ) {} 12710 12711 return anchor.hash.length > 1 && anchorUrl === locationUrl; 12712 }; 12713 })(), 12714 12715 _create: function() { 12716 var that = this, 12717 options = this.options; 12718 12719 this.running = false; 12720 12721 this.element 12722 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 12723 .toggleClass( "ui-tabs-collapsible", options.collapsible ); 12724 12725 this._processTabs(); 12726 options.active = this._initialActive(); 12727 12728 // Take disabling tabs via class attribute from HTML 12729 // into account and update option properly. 12730 if ( $.isArray( options.disabled ) ) { 12731 options.disabled = $.unique( options.disabled.concat( 12732 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 12733 return that.tabs.index( li ); 12734 }) 12735 ) ).sort(); 12736 } 12737 12738 // check for length avoids error when initializing empty list 12739 if ( this.options.active !== false && this.anchors.length ) { 12740 this.active = this._findActive( options.active ); 12741 } else { 12742 this.active = $(); 12743 } 12744 12745 this._refresh(); 12746 12747 if ( this.active.length ) { 12748 this.load( options.active ); 12749 } 12750 }, 12751 12752 _initialActive: function() { 12753 var active = this.options.active, 12754 collapsible = this.options.collapsible, 12755 locationHash = location.hash.substring( 1 ); 12756 12757 if ( active === null ) { 12758 // check the fragment identifier in the URL 12759 if ( locationHash ) { 12760 this.tabs.each(function( i, tab ) { 12761 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 12762 active = i; 12763 return false; 12764 } 12765 }); 12766 } 12767 12768 // check for a tab marked active via a class 12769 if ( active === null ) { 12770 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 12771 } 12772 12773 // no active tab, set to false 12774 if ( active === null || active === -1 ) { 12775 active = this.tabs.length ? 0 : false; 12776 } 12777 } 12778 12779 // handle numbers: negative, out of range 12780 if ( active !== false ) { 12781 active = this.tabs.index( this.tabs.eq( active ) ); 12782 if ( active === -1 ) { 12783 active = collapsible ? false : 0; 12784 } 12785 } 12786 12787 // don't allow collapsible: false and active: false 12788 if ( !collapsible && active === false && this.anchors.length ) { 12789 active = 0; 12790 } 12791 12792 return active; 12793 }, 12794 12795 _getCreateEventData: function() { 12796 return { 12797 tab: this.active, 12798 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 12799 }; 12800 }, 12801 12802 _tabKeydown: function( event ) { 12803 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 12804 selectedIndex = this.tabs.index( focusedTab ), 12805 goingForward = true; 12806 12807 if ( this._handlePageNav( event ) ) { 12808 return; 12809 } 12810 12811 switch ( event.keyCode ) { 12812 case $.ui.keyCode.RIGHT: 12813 case $.ui.keyCode.DOWN: 12814 selectedIndex++; 12815 break; 12816 case $.ui.keyCode.UP: 12817 case $.ui.keyCode.LEFT: 12818 goingForward = false; 12819 selectedIndex--; 12820 break; 12821 case $.ui.keyCode.END: 12822 selectedIndex = this.anchors.length - 1; 12823 break; 12824 case $.ui.keyCode.HOME: 12825 selectedIndex = 0; 12826 break; 12827 case $.ui.keyCode.SPACE: 12828 // Activate only, no collapsing 12829 event.preventDefault(); 12830 clearTimeout( this.activating ); 12831 this._activate( selectedIndex ); 12832 return; 12833 case $.ui.keyCode.ENTER: 12834 // Toggle (cancel delayed activation, allow collapsing) 12835 event.preventDefault(); 12836 clearTimeout( this.activating ); 12837 // Determine if we should collapse or activate 12838 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 12839 return; 12840 default: 12841 return; 12842 } 12843 12844 // Focus the appropriate tab, based on which key was pressed 12845 event.preventDefault(); 12846 clearTimeout( this.activating ); 12847 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 12848 12849 // Navigating with control key will prevent automatic activation 12850 if ( !event.ctrlKey ) { 12851 // Update aria-selected immediately so that AT think the tab is already selected. 12852 // Otherwise AT may confuse the user by stating that they need to activate the tab, 12853 // but the tab will already be activated by the time the announcement finishes. 12854 focusedTab.attr( "aria-selected", "false" ); 12855 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 12856 12857 this.activating = this._delay(function() { 12858 this.option( "active", selectedIndex ); 12859 }, this.delay ); 12860 } 12861 }, 12862 12863 _panelKeydown: function( event ) { 12864 if ( this._handlePageNav( event ) ) { 12865 return; 12866 } 12867 12868 // Ctrl+up moves focus to the current tab 12869 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 12870 event.preventDefault(); 12871 this.active.focus(); 12872 } 12873 }, 12874 12875 // Alt+page up/down moves focus to the previous/next tab (and activates) 12876 _handlePageNav: function( event ) { 12877 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 12878 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 12879 return true; 12880 } 12881 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 12882 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 12883 return true; 12884 } 12885 }, 12886 12887 _findNextTab: function( index, goingForward ) { 12888 var lastTabIndex = this.tabs.length - 1; 12889 12890 function constrain() { 12891 if ( index > lastTabIndex ) { 12892 index = 0; 12893 } 12894 if ( index < 0 ) { 12895 index = lastTabIndex; 12896 } 12897 return index; 12898 } 12899 12900 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 12901 index = goingForward ? index + 1 : index - 1; 12902 } 12903 12904 return index; 12905 }, 12906 12907 _focusNextTab: function( index, goingForward ) { 12908 index = this._findNextTab( index, goingForward ); 12909 this.tabs.eq( index ).focus(); 12910 return index; 12911 }, 12912 12913 _setOption: function( key, value ) { 12914 if ( key === "active" ) { 12915 // _activate() will handle invalid values and update this.options 12916 this._activate( value ); 12917 return; 12918 } 12919 12920 if ( key === "disabled" ) { 12921 // don't use the widget factory's disabled handling 12922 this._setupDisabled( value ); 12923 return; 12924 } 12925 12926 this._super( key, value); 12927 12928 if ( key === "collapsible" ) { 12929 this.element.toggleClass( "ui-tabs-collapsible", value ); 12930 // Setting collapsible: false while collapsed; open first panel 12931 if ( !value && this.options.active === false ) { 12932 this._activate( 0 ); 12933 } 12934 } 12935 12936 if ( key === "event" ) { 12937 this._setupEvents( value ); 12938 } 12939 12940 if ( key === "heightStyle" ) { 12941 this._setupHeightStyle( value ); 12942 } 12943 }, 12944 12945 _sanitizeSelector: function( hash ) { 12946 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 12947 }, 12948 12949 refresh: function() { 12950 var options = this.options, 12951 lis = this.tablist.children( ":has(a[href])" ); 12952 12953 // get disabled tabs from class attribute from HTML 12954 // this will get converted to a boolean if needed in _refresh() 12955 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 12956 return lis.index( tab ); 12957 }); 12958 12959 this._processTabs(); 12960 12961 // was collapsed or no tabs 12962 if ( options.active === false || !this.anchors.length ) { 12963 options.active = false; 12964 this.active = $(); 12965 // was active, but active tab is gone 12966 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 12967 // all remaining tabs are disabled 12968 if ( this.tabs.length === options.disabled.length ) { 12969 options.active = false; 12970 this.active = $(); 12971 // activate previous tab 12972 } else { 12973 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 12974 } 12975 // was active, active tab still exists 12976 } else { 12977 // make sure active index is correct 12978 options.active = this.tabs.index( this.active ); 12979 } 12980 12981 this._refresh(); 12982 }, 12983 12984 _refresh: function() { 12985 this._setupDisabled( this.options.disabled ); 12986 this._setupEvents( this.options.event ); 12987 this._setupHeightStyle( this.options.heightStyle ); 12988 12989 this.tabs.not( this.active ).attr({ 12990 "aria-selected": "false", 12991 "aria-expanded": "false", 12992 tabIndex: -1 12993 }); 12994 this.panels.not( this._getPanelForTab( this.active ) ) 12995 .hide() 12996 .attr({ 12997 "aria-hidden": "true" 12998 }); 12999 13000 // Make sure one tab is in the tab order 13001 if ( !this.active.length ) { 13002 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 13003 } else { 13004 this.active 13005 .addClass( "ui-tabs-active ui-state-active" ) 13006 .attr({ 13007 "aria-selected": "true", 13008 "aria-expanded": "true", 13009 tabIndex: 0 13010 }); 13011 this._getPanelForTab( this.active ) 13012 .show() 13013 .attr({ 13014 "aria-hidden": "false" 13015 }); 13016 } 13017 }, 13018 13019 _processTabs: function() { 13020 var that = this; 13021 13022 this.tablist = this._getList() 13023 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13024 .attr( "role", "tablist" ) 13025 13026 // Prevent users from focusing disabled tabs via click 13027 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { 13028 if ( $( this ).is( ".ui-state-disabled" ) ) { 13029 event.preventDefault(); 13030 } 13031 }) 13032 13033 // support: IE <9 13034 // Preventing the default action in mousedown doesn't prevent IE 13035 // from focusing the element, so if the anchor gets focused, blur. 13036 // We don't have to worry about focusing the previously focused 13037 // element since clicking on a non-focusable element should focus 13038 // the body anyway. 13039 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13040 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13041 this.blur(); 13042 } 13043 }); 13044 13045 this.tabs = this.tablist.find( "> li:has(a[href])" ) 13046 .addClass( "ui-state-default ui-corner-top" ) 13047 .attr({ 13048 role: "tab", 13049 tabIndex: -1 13050 }); 13051 13052 this.anchors = this.tabs.map(function() { 13053 return $( "a", this )[ 0 ]; 13054 }) 13055 .addClass( "ui-tabs-anchor" ) 13056 .attr({ 13057 role: "presentation", 13058 tabIndex: -1 13059 }); 13060 13061 this.panels = $(); 13062 13063 this.anchors.each(function( i, anchor ) { 13064 var selector, panel, panelId, 13065 anchorId = $( anchor ).uniqueId().attr( "id" ), 13066 tab = $( anchor ).closest( "li" ), 13067 originalAriaControls = tab.attr( "aria-controls" ); 13068 13069 // inline tab 13070 if ( that._isLocal( anchor ) ) { 13071 selector = anchor.hash; 13072 panelId = selector.substring( 1 ); 13073 panel = that.element.find( that._sanitizeSelector( selector ) ); 13074 // remote tab 13075 } else { 13076 // If the tab doesn't already have aria-controls, 13077 // generate an id by using a throw-away element 13078 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 13079 selector = "#" + panelId; 13080 panel = that.element.find( selector ); 13081 if ( !panel.length ) { 13082 panel = that._createPanel( panelId ); 13083 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 13084 } 13085 panel.attr( "aria-live", "polite" ); 13086 } 13087 13088 if ( panel.length) { 13089 that.panels = that.panels.add( panel ); 13090 } 13091 if ( originalAriaControls ) { 13092 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 13093 } 13094 tab.attr({ 13095 "aria-controls": panelId, 13096 "aria-labelledby": anchorId 13097 }); 13098 panel.attr( "aria-labelledby", anchorId ); 13099 }); 13100 13101 this.panels 13102 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13103 .attr( "role", "tabpanel" ); 13104 }, 13105 13106 // allow overriding how to find the list for rare usage scenarios (#7715) 13107 _getList: function() { 13108 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 13109 }, 13110 13111 _createPanel: function( id ) { 13112 return $( "<div>" ) 13113 .attr( "id", id ) 13114 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13115 .data( "ui-tabs-destroy", true ); 13116 }, 13117 13118 _setupDisabled: function( disabled ) { 13119 if ( $.isArray( disabled ) ) { 13120 if ( !disabled.length ) { 13121 disabled = false; 13122 } else if ( disabled.length === this.anchors.length ) { 13123 disabled = true; 13124 } 13125 } 13126 13127 // disable tabs 13128 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 13129 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 13130 $( li ) 13131 .addClass( "ui-state-disabled" ) 13132 .attr( "aria-disabled", "true" ); 13133 } else { 13134 $( li ) 13135 .removeClass( "ui-state-disabled" ) 13136 .removeAttr( "aria-disabled" ); 13137 } 13138 } 13139 13140 this.options.disabled = disabled; 13141 }, 13142 13143 _setupEvents: function( event ) { 13144 var events = {}; 13145 if ( event ) { 13146 $.each( event.split(" "), function( index, eventName ) { 13147 events[ eventName ] = "_eventHandler"; 13148 }); 13149 } 13150 13151 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 13152 // Always prevent the default action, even when disabled 13153 this._on( true, this.anchors, { 13154 click: function( event ) { 13155 event.preventDefault(); 13156 } 13157 }); 13158 this._on( this.anchors, events ); 13159 this._on( this.tabs, { keydown: "_tabKeydown" } ); 13160 this._on( this.panels, { keydown: "_panelKeydown" } ); 13161 13162 this._focusable( this.tabs ); 13163 this._hoverable( this.tabs ); 13164 }, 13165 13166 _setupHeightStyle: function( heightStyle ) { 13167 var maxHeight, 13168 parent = this.element.parent(); 13169 13170 if ( heightStyle === "fill" ) { 13171 maxHeight = parent.height(); 13172 maxHeight -= this.element.outerHeight() - this.element.height(); 13173 13174 this.element.siblings( ":visible" ).each(function() { 13175 var elem = $( this ), 13176 position = elem.css( "position" ); 13177 13178 if ( position === "absolute" || position === "fixed" ) { 13179 return; 13180 } 13181 maxHeight -= elem.outerHeight( true ); 13182 }); 13183 13184 this.element.children().not( this.panels ).each(function() { 13185 maxHeight -= $( this ).outerHeight( true ); 13186 }); 13187 13188 this.panels.each(function() { 13189 $( this ).height( Math.max( 0, maxHeight - 13190 $( this ).innerHeight() + $( this ).height() ) ); 13191 }) 13192 .css( "overflow", "auto" ); 13193 } else if ( heightStyle === "auto" ) { 13194 maxHeight = 0; 13195 this.panels.each(function() { 13196 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 13197 }).height( maxHeight ); 13198 } 13199 }, 13200 13201 _eventHandler: function( event ) { 13202 var options = this.options, 13203 active = this.active, 13204 anchor = $( event.currentTarget ), 13205 tab = anchor.closest( "li" ), 13206 clickedIsActive = tab[ 0 ] === active[ 0 ], 13207 collapsing = clickedIsActive && options.collapsible, 13208 toShow = collapsing ? $() : this._getPanelForTab( tab ), 13209 toHide = !active.length ? $() : this._getPanelForTab( active ), 13210 eventData = { 13211 oldTab: active, 13212 oldPanel: toHide, 13213 newTab: collapsing ? $() : tab, 13214 newPanel: toShow 13215 }; 13216 13217 event.preventDefault(); 13218 13219 if ( tab.hasClass( "ui-state-disabled" ) || 13220 // tab is already loading 13221 tab.hasClass( "ui-tabs-loading" ) || 13222 // can't switch durning an animation 13223 this.running || 13224 // click on active header, but not collapsible 13225 ( clickedIsActive && !options.collapsible ) || 13226 // allow canceling activation 13227 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 13228 return; 13229 } 13230 13231 options.active = collapsing ? false : this.tabs.index( tab ); 13232 13233 this.active = clickedIsActive ? $() : tab; 13234 if ( this.xhr ) { 13235 this.xhr.abort(); 13236 } 13237 13238 if ( !toHide.length && !toShow.length ) { 13239 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 13240 } 13241 13242 if ( toShow.length ) { 13243 this.load( this.tabs.index( tab ), event ); 13244 } 13245 this._toggle( event, eventData ); 13246 }, 13247 13248 // handles show/hide for selecting tabs 13249 _toggle: function( event, eventData ) { 13250 var that = this, 13251 toShow = eventData.newPanel, 13252 toHide = eventData.oldPanel; 13253 13254 this.running = true; 13255 13256 function complete() { 13257 that.running = false; 13258 that._trigger( "activate", event, eventData ); 13259 } 13260 13261 function show() { 13262 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 13263 13264 if ( toShow.length && that.options.show ) { 13265 that._show( toShow, that.options.show, complete ); 13266 } else { 13267 toShow.show(); 13268 complete(); 13269 } 13270 } 13271 13272 // start out by hiding, then showing, then completing 13273 if ( toHide.length && this.options.hide ) { 13274 this._hide( toHide, this.options.hide, function() { 13275 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13276 show(); 13277 }); 13278 } else { 13279 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13280 toHide.hide(); 13281 show(); 13282 } 13283 13284 toHide.attr( "aria-hidden", "true" ); 13285 eventData.oldTab.attr({ 13286 "aria-selected": "false", 13287 "aria-expanded": "false" 13288 }); 13289 // If we're switching tabs, remove the old tab from the tab order. 13290 // If we're opening from collapsed state, remove the previous tab from the tab order. 13291 // If we're collapsing, then keep the collapsing tab in the tab order. 13292 if ( toShow.length && toHide.length ) { 13293 eventData.oldTab.attr( "tabIndex", -1 ); 13294 } else if ( toShow.length ) { 13295 this.tabs.filter(function() { 13296 return $( this ).attr( "tabIndex" ) === 0; 13297 }) 13298 .attr( "tabIndex", -1 ); 13299 } 13300 13301 toShow.attr( "aria-hidden", "false" ); 13302 eventData.newTab.attr({ 13303 "aria-selected": "true", 13304 "aria-expanded": "true", 13305 tabIndex: 0 13306 }); 13307 }, 13308 13309 _activate: function( index ) { 13310 var anchor, 13311 active = this._findActive( index ); 13312 13313 // trying to activate the already active panel 13314 if ( active[ 0 ] === this.active[ 0 ] ) { 13315 return; 13316 } 13317 13318 // trying to collapse, simulate a click on the current active header 13319 if ( !active.length ) { 13320 active = this.active; 13321 } 13322 13323 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 13324 this._eventHandler({ 13325 target: anchor, 13326 currentTarget: anchor, 13327 preventDefault: $.noop 13328 }); 13329 }, 13330 13331 _findActive: function( index ) { 13332 return index === false ? $() : this.tabs.eq( index ); 13333 }, 13334 13335 _getIndex: function( index ) { 13336 // meta-function to give users option to provide a href string instead of a numerical index. 13337 if ( typeof index === "string" ) { 13338 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 13339 } 13340 13341 return index; 13342 }, 13343 13344 _destroy: function() { 13345 if ( this.xhr ) { 13346 this.xhr.abort(); 13347 } 13348 13349 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 13350 13351 this.tablist 13352 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13353 .removeAttr( "role" ); 13354 13355 this.anchors 13356 .removeClass( "ui-tabs-anchor" ) 13357 .removeAttr( "role" ) 13358 .removeAttr( "tabIndex" ) 13359 .removeUniqueId(); 13360 13361 this.tablist.unbind( this.eventNamespace ); 13362 13363 this.tabs.add( this.panels ).each(function() { 13364 if ( $.data( this, "ui-tabs-destroy" ) ) { 13365 $( this ).remove(); 13366 } else { 13367 $( this ) 13368 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 13369 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 13370 .removeAttr( "tabIndex" ) 13371 .removeAttr( "aria-live" ) 13372 .removeAttr( "aria-busy" ) 13373 .removeAttr( "aria-selected" ) 13374 .removeAttr( "aria-labelledby" ) 13375 .removeAttr( "aria-hidden" ) 13376 .removeAttr( "aria-expanded" ) 13377 .removeAttr( "role" ); 13378 } 13379 }); 13380 13381 this.tabs.each(function() { 13382 var li = $( this ), 13383 prev = li.data( "ui-tabs-aria-controls" ); 13384 if ( prev ) { 13385 li 13386 .attr( "aria-controls", prev ) 13387 .removeData( "ui-tabs-aria-controls" ); 13388 } else { 13389 li.removeAttr( "aria-controls" ); 13390 } 13391 }); 13392 13393 this.panels.show(); 13394 13395 if ( this.options.heightStyle !== "content" ) { 13396 this.panels.css( "height", "" ); 13397 } 13398 }, 13399 13400 enable: function( index ) { 13401 var disabled = this.options.disabled; 13402 if ( disabled === false ) { 13403 return; 13404 } 13405 13406 if ( index === undefined ) { 13407 disabled = false; 13408 } else { 13409 index = this._getIndex( index ); 13410 if ( $.isArray( disabled ) ) { 13411 disabled = $.map( disabled, function( num ) { 13412 return num !== index ? num : null; 13413 }); 13414 } else { 13415 disabled = $.map( this.tabs, function( li, num ) { 13416 return num !== index ? num : null; 13417 }); 13418 } 13419 } 13420 this._setupDisabled( disabled ); 13421 }, 13422 13423 disable: function( index ) { 13424 var disabled = this.options.disabled; 13425 if ( disabled === true ) { 13426 return; 13427 } 13428 13429 if ( index === undefined ) { 13430 disabled = true; 13431 } else { 13432 index = this._getIndex( index ); 13433 if ( $.inArray( index, disabled ) !== -1 ) { 13434 return; 13435 } 13436 if ( $.isArray( disabled ) ) { 13437 disabled = $.merge( [ index ], disabled ).sort(); 13438 } else { 13439 disabled = [ index ]; 13440 } 13441 } 13442 this._setupDisabled( disabled ); 13443 }, 13444 13445 load: function( index, event ) { 13446 index = this._getIndex( index ); 13447 var that = this, 13448 tab = this.tabs.eq( index ), 13449 anchor = tab.find( ".ui-tabs-anchor" ), 13450 panel = this._getPanelForTab( tab ), 13451 eventData = { 13452 tab: tab, 13453 panel: panel 13454 }; 13455 13456 // not remote 13457 if ( this._isLocal( anchor[ 0 ] ) ) { 13458 return; 13459 } 13460 13461 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 13462 13463 // support: jQuery <1.8 13464 // jQuery <1.8 returns false if the request is canceled in beforeSend, 13465 // but as of 1.8, $.ajax() always returns a jqXHR object. 13466 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 13467 tab.addClass( "ui-tabs-loading" ); 13468 panel.attr( "aria-busy", "true" ); 13469 13470 this.xhr 13471 .success(function( response ) { 13472 // support: jQuery <1.8 13473 // http://bugs.jquery.com/ticket/11778 13474 setTimeout(function() { 13475 panel.html( response ); 13476 that._trigger( "load", event, eventData ); 13477 }, 1 ); 13478 }) 13479 .complete(function( jqXHR, status ) { 13480 // support: jQuery <1.8 13481 // http://bugs.jquery.com/ticket/11778 13482 setTimeout(function() { 13483 if ( status === "abort" ) { 13484 that.panels.stop( false, true ); 13485 } 13486 13487 tab.removeClass( "ui-tabs-loading" ); 13488 panel.removeAttr( "aria-busy" ); 13489 13490 if ( jqXHR === that.xhr ) { 13491 delete that.xhr; 13492 } 13493 }, 1 ); 13494 }); 13495 } 13496 }, 13497 13498 _ajaxSettings: function( anchor, event, eventData ) { 13499 var that = this; 13500 return { 13501 url: anchor.attr( "href" ), 13502 beforeSend: function( jqXHR, settings ) { 13503 return that._trigger( "beforeLoad", event, 13504 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 13505 } 13506 }; 13507 }, 13508 13509 _getPanelForTab: function( tab ) { 13510 var id = $( tab ).attr( "aria-controls" ); 13511 return this.element.find( this._sanitizeSelector( "#" + id ) ); 13512 } 13513}); 13514 13515 13516/*! 13517 * jQuery UI Tooltip 1.11.1 13518 * http://jqueryui.com 13519 * 13520 * Copyright 2014 jQuery Foundation and other contributors 13521 * Released under the MIT license. 13522 * http://jquery.org/license 13523 * 13524 * http://api.jqueryui.com/tooltip/ 13525 */ 13526 13527 13528var tooltip = $.widget( "ui.tooltip", { 13529 version: "1.11.1", 13530 options: { 13531 content: function() { 13532 // support: IE<9, Opera in jQuery <1.7 13533 // .text() can't accept undefined, so coerce to a string 13534 var title = $( this ).attr( "title" ) || ""; 13535 // Escape title, since we're going from an attribute to raw HTML 13536 return $( "<a>" ).text( title ).html(); 13537 }, 13538 hide: true, 13539 // Disabled elements have inconsistent behavior across browsers (#8661) 13540 items: "[title]:not([disabled])", 13541 position: { 13542 my: "left top+15", 13543 at: "left bottom", 13544 collision: "flipfit flip" 13545 }, 13546 show: true, 13547 tooltipClass: null, 13548 track: false, 13549 13550 // callbacks 13551 close: null, 13552 open: null 13553 }, 13554 13555 _addDescribedBy: function( elem, id ) { 13556 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 13557 describedby.push( id ); 13558 elem 13559 .data( "ui-tooltip-id", id ) 13560 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 13561 }, 13562 13563 _removeDescribedBy: function( elem ) { 13564 var id = elem.data( "ui-tooltip-id" ), 13565 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 13566 index = $.inArray( id, describedby ); 13567 13568 if ( index !== -1 ) { 13569 describedby.splice( index, 1 ); 13570 } 13571 13572 elem.removeData( "ui-tooltip-id" ); 13573 describedby = $.trim( describedby.join( " " ) ); 13574 if ( describedby ) { 13575 elem.attr( "aria-describedby", describedby ); 13576 } else { 13577 elem.removeAttr( "aria-describedby" ); 13578 } 13579 }, 13580 13581 _create: function() { 13582 this._on({ 13583 mouseover: "open", 13584 focusin: "open" 13585 }); 13586 13587 // IDs of generated tooltips, needed for destroy 13588 this.tooltips = {}; 13589 // IDs of parent tooltips where we removed the title attribute 13590 this.parents = {}; 13591 13592 if ( this.options.disabled ) { 13593 this._disable(); 13594 } 13595 13596 // Append the aria-live region so tooltips announce correctly 13597 this.liveRegion = $( "<div>" ) 13598 .attr({ 13599 role: "log", 13600 "aria-live": "assertive", 13601 "aria-relevant": "additions" 13602 }) 13603 .addClass( "ui-helper-hidden-accessible" ) 13604 .appendTo( this.document[ 0 ].body ); 13605 }, 13606 13607 _setOption: function( key, value ) { 13608 var that = this; 13609 13610 if ( key === "disabled" ) { 13611 this[ value ? "_disable" : "_enable" ](); 13612 this.options[ key ] = value; 13613 // disable element style changes 13614 return; 13615 } 13616 13617 this._super( key, value ); 13618 13619 if ( key === "content" ) { 13620 $.each( this.tooltips, function( id, element ) { 13621 that._updateContent( element ); 13622 }); 13623 } 13624 }, 13625 13626 _disable: function() { 13627 var that = this; 13628 13629 // close open tooltips 13630 $.each( this.tooltips, function( id, element ) { 13631 var event = $.Event( "blur" ); 13632 event.target = event.currentTarget = element[0]; 13633 that.close( event, true ); 13634 }); 13635 13636 // remove title attributes to prevent native tooltips 13637 this.element.find( this.options.items ).addBack().each(function() { 13638 var element = $( this ); 13639 if ( element.is( "[title]" ) ) { 13640 element 13641 .data( "ui-tooltip-title", element.attr( "title" ) ) 13642 .removeAttr( "title" ); 13643 } 13644 }); 13645 }, 13646 13647 _enable: function() { 13648 // restore title attributes 13649 this.element.find( this.options.items ).addBack().each(function() { 13650 var element = $( this ); 13651 if ( element.data( "ui-tooltip-title" ) ) { 13652 element.attr( "title", element.data( "ui-tooltip-title" ) ); 13653 } 13654 }); 13655 }, 13656 13657 open: function( event ) { 13658 var that = this, 13659 target = $( event ? event.target : this.element ) 13660 // we need closest here due to mouseover bubbling, 13661 // but always pointing at the same event target 13662 .closest( this.options.items ); 13663 13664 // No element to show a tooltip for or the tooltip is already open 13665 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 13666 return; 13667 } 13668 13669 if ( target.attr( "title" ) ) { 13670 target.data( "ui-tooltip-title", target.attr( "title" ) ); 13671 } 13672 13673 target.data( "ui-tooltip-open", true ); 13674 13675 // kill parent tooltips, custom or native, for hover 13676 if ( event && event.type === "mouseover" ) { 13677 target.parents().each(function() { 13678 var parent = $( this ), 13679 blurEvent; 13680 if ( parent.data( "ui-tooltip-open" ) ) { 13681 blurEvent = $.Event( "blur" ); 13682 blurEvent.target = blurEvent.currentTarget = this; 13683 that.close( blurEvent, true ); 13684 } 13685 if ( parent.attr( "title" ) ) { 13686 parent.uniqueId(); 13687 that.parents[ this.id ] = { 13688 element: this, 13689 title: parent.attr( "title" ) 13690 }; 13691 parent.attr( "title", "" ); 13692 } 13693 }); 13694 } 13695 13696 this._updateContent( target, event ); 13697 }, 13698 13699 _updateContent: function( target, event ) { 13700 var content, 13701 contentOption = this.options.content, 13702 that = this, 13703 eventType = event ? event.type : null; 13704 13705 if ( typeof contentOption === "string" ) { 13706 return this._open( event, target, contentOption ); 13707 } 13708 13709 content = contentOption.call( target[0], function( response ) { 13710 // ignore async response if tooltip was closed already 13711 if ( !target.data( "ui-tooltip-open" ) ) { 13712 return; 13713 } 13714 // IE may instantly serve a cached response for ajax requests 13715 // delay this call to _open so the other call to _open runs first 13716 that._delay(function() { 13717 // jQuery creates a special event for focusin when it doesn't 13718 // exist natively. To improve performance, the native event 13719 // object is reused and the type is changed. Therefore, we can't 13720 // rely on the type being correct after the event finished 13721 // bubbling, so we set it back to the previous value. (#8740) 13722 if ( event ) { 13723 event.type = eventType; 13724 } 13725 this._open( event, target, response ); 13726 }); 13727 }); 13728 if ( content ) { 13729 this._open( event, target, content ); 13730 } 13731 }, 13732 13733 _open: function( event, target, content ) { 13734 var tooltip, events, delayedShow, a11yContent, 13735 positionOption = $.extend( {}, this.options.position ); 13736 13737 if ( !content ) { 13738 return; 13739 } 13740 13741 // Content can be updated multiple times. If the tooltip already 13742 // exists, then just update the content and bail. 13743 tooltip = this._find( target ); 13744 if ( tooltip.length ) { 13745 tooltip.find( ".ui-tooltip-content" ).html( content ); 13746 return; 13747 } 13748 13749 // if we have a title, clear it to prevent the native tooltip 13750 // we have to check first to avoid defining a title if none exists 13751 // (we don't want to cause an element to start matching [title]) 13752 // 13753 // We use removeAttr only for key events, to allow IE to export the correct 13754 // accessible attributes. For mouse events, set to empty string to avoid 13755 // native tooltip showing up (happens only when removing inside mouseover). 13756 if ( target.is( "[title]" ) ) { 13757 if ( event && event.type === "mouseover" ) { 13758 target.attr( "title", "" ); 13759 } else { 13760 target.removeAttr( "title" ); 13761 } 13762 } 13763 13764 tooltip = this._tooltip( target ); 13765 this._addDescribedBy( target, tooltip.attr( "id" ) ); 13766 tooltip.find( ".ui-tooltip-content" ).html( content ); 13767 13768 // Support: Voiceover on OS X, JAWS on IE <= 9 13769 // JAWS announces deletions even when aria-relevant="additions" 13770 // Voiceover will sometimes re-read the entire log region's contents from the beginning 13771 this.liveRegion.children().hide(); 13772 if ( content.clone ) { 13773 a11yContent = content.clone(); 13774 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 13775 } else { 13776 a11yContent = content; 13777 } 13778 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion ); 13779 13780 function position( event ) { 13781 positionOption.of = event; 13782 if ( tooltip.is( ":hidden" ) ) { 13783 return; 13784 } 13785 tooltip.position( positionOption ); 13786 } 13787 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 13788 this._on( this.document, { 13789 mousemove: position 13790 }); 13791 // trigger once to override element-relative positioning 13792 position( event ); 13793 } else { 13794 tooltip.position( $.extend({ 13795 of: target 13796 }, this.options.position ) ); 13797 } 13798 13799 this.hiding = false; 13800 this.closing = false; 13801 tooltip.hide(); 13802 13803 this._show( tooltip, this.options.show ); 13804 // Handle tracking tooltips that are shown with a delay (#8644). As soon 13805 // as the tooltip is visible, position the tooltip using the most recent 13806 // event. 13807 if ( this.options.show && this.options.show.delay ) { 13808 delayedShow = this.delayedShow = setInterval(function() { 13809 if ( tooltip.is( ":visible" ) ) { 13810 position( positionOption.of ); 13811 clearInterval( delayedShow ); 13812 } 13813 }, $.fx.interval ); 13814 } 13815 13816 this._trigger( "open", event, { tooltip: tooltip } ); 13817 13818 events = { 13819 keyup: function( event ) { 13820 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 13821 var fakeEvent = $.Event(event); 13822 fakeEvent.currentTarget = target[0]; 13823 this.close( fakeEvent, true ); 13824 } 13825 } 13826 }; 13827 13828 // Only bind remove handler for delegated targets. Non-delegated 13829 // tooltips will handle this in destroy. 13830 if ( target[ 0 ] !== this.element[ 0 ] ) { 13831 events.remove = function() { 13832 this._removeTooltip( tooltip ); 13833 }; 13834 } 13835 13836 if ( !event || event.type === "mouseover" ) { 13837 events.mouseleave = "close"; 13838 } 13839 if ( !event || event.type === "focusin" ) { 13840 events.focusout = "close"; 13841 } 13842 this._on( true, target, events ); 13843 }, 13844 13845 close: function( event ) { 13846 var that = this, 13847 target = $( event ? event.currentTarget : this.element ), 13848 tooltip = this._find( target ); 13849 13850 // disabling closes the tooltip, so we need to track when we're closing 13851 // to avoid an infinite loop in case the tooltip becomes disabled on close 13852 if ( this.closing ) { 13853 return; 13854 } 13855 13856 // Clear the interval for delayed tracking tooltips 13857 clearInterval( this.delayedShow ); 13858 13859 // only set title if we had one before (see comment in _open()) 13860 // If the title attribute has changed since open(), don't restore 13861 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 13862 target.attr( "title", target.data( "ui-tooltip-title" ) ); 13863 } 13864 13865 this._removeDescribedBy( target ); 13866 13867 this.hiding = true; 13868 tooltip.stop( true ); 13869 this._hide( tooltip, this.options.hide, function() { 13870 that._removeTooltip( $( this ) ); 13871 this.hiding = false; 13872 this.closing = false; 13873 }); 13874 13875 target.removeData( "ui-tooltip-open" ); 13876 this._off( target, "mouseleave focusout keyup" ); 13877 13878 // Remove 'remove' binding only on delegated targets 13879 if ( target[ 0 ] !== this.element[ 0 ] ) { 13880 this._off( target, "remove" ); 13881 } 13882 this._off( this.document, "mousemove" ); 13883 13884 if ( event && event.type === "mouseleave" ) { 13885 $.each( this.parents, function( id, parent ) { 13886 $( parent.element ).attr( "title", parent.title ); 13887 delete that.parents[ id ]; 13888 }); 13889 } 13890 13891 this.closing = true; 13892 this._trigger( "close", event, { tooltip: tooltip } ); 13893 if ( !this.hiding ) { 13894 this.closing = false; 13895 } 13896 }, 13897 13898 _tooltip: function( element ) { 13899 var tooltip = $( "<div>" ) 13900 .attr( "role", "tooltip" ) 13901 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 13902 ( this.options.tooltipClass || "" ) ), 13903 id = tooltip.uniqueId().attr( "id" ); 13904 13905 $( "<div>" ) 13906 .addClass( "ui-tooltip-content" ) 13907 .appendTo( tooltip ); 13908 13909 tooltip.appendTo( this.document[0].body ); 13910 this.tooltips[ id ] = element; 13911 return tooltip; 13912 }, 13913 13914 _find: function( target ) { 13915 var id = target.data( "ui-tooltip-id" ); 13916 return id ? $( "#" + id ) : $(); 13917 }, 13918 13919 _removeTooltip: function( tooltip ) { 13920 tooltip.remove(); 13921 delete this.tooltips[ tooltip.attr( "id" ) ]; 13922 }, 13923 13924 _destroy: function() { 13925 var that = this; 13926 13927 // close open tooltips 13928 $.each( this.tooltips, function( id, element ) { 13929 // Delegate to close method to handle common cleanup 13930 var event = $.Event( "blur" ); 13931 event.target = event.currentTarget = element[0]; 13932 that.close( event, true ); 13933 13934 // Remove immediately; destroying an open tooltip doesn't use the 13935 // hide animation 13936 $( "#" + id ).remove(); 13937 13938 // Restore the title 13939 if ( element.data( "ui-tooltip-title" ) ) { 13940 // If the title attribute has changed since open(), don't restore 13941 if ( !element.attr( "title" ) ) { 13942 element.attr( "title", element.data( "ui-tooltip-title" ) ); 13943 } 13944 element.removeData( "ui-tooltip-title" ); 13945 } 13946 }); 13947 this.liveRegion.remove(); 13948 } 13949}); 13950 13951 13952/*! 13953 * jQuery UI Effects 1.11.1 13954 * http://jqueryui.com 13955 * 13956 * Copyright 2014 jQuery Foundation and other contributors 13957 * Released under the MIT license. 13958 * http://jquery.org/license 13959 * 13960 * http://api.jqueryui.com/category/effects-core/ 13961 */ 13962 13963 13964var dataSpace = "ui-effects-", 13965 13966 // Create a local jQuery because jQuery Color relies on it and the 13967 // global may not exist with AMD and a custom build (#10199) 13968 jQuery = $; 13969 13970$.effects = { 13971 effect: {} 13972}; 13973 13974/*! 13975 * jQuery Color Animations v2.1.2 13976 * https://github.com/jquery/jquery-color 13977 * 13978 * Copyright 2014 jQuery Foundation and other contributors 13979 * Released under the MIT license. 13980 * http://jquery.org/license 13981 * 13982 * Date: Wed Jan 16 08:47:09 2013 -0600 13983 */ 13984(function( jQuery, undefined ) { 13985 13986 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 13987 13988 // plusequals test for += 100 -= 100 13989 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 13990 // a set of RE's that can match strings and generate color tuples. 13991 stringParsers = [ { 13992 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13993 parse: function( execResult ) { 13994 return [ 13995 execResult[ 1 ], 13996 execResult[ 2 ], 13997 execResult[ 3 ], 13998 execResult[ 4 ] 13999 ]; 14000 } 14001 }, { 14002 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 14003 parse: function( execResult ) { 14004 return [ 14005 execResult[ 1 ] * 2.55, 14006 execResult[ 2 ] * 2.55, 14007 execResult[ 3 ] * 2.55, 14008 execResult[ 4 ] 14009 ]; 14010 } 14011 }, { 14012 // this regex ignores A-F because it's compared against an already lowercased string 14013 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 14014 parse: function( execResult ) { 14015 return [ 14016 parseInt( execResult[ 1 ], 16 ), 14017 parseInt( execResult[ 2 ], 16 ), 14018 parseInt( execResult[ 3 ], 16 ) 14019 ]; 14020 } 14021 }, { 14022 // this regex ignores A-F because it's compared against an already lowercased string 14023 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 14024 parse: function( execResult ) { 14025 return [ 14026 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 14027 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 14028 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 14029 ]; 14030 } 14031 }, { 14032 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 14033 space: "hsla", 14034 parse: function( execResult ) { 14035 return [ 14036 execResult[ 1 ], 14037 execResult[ 2 ] / 100, 14038 execResult[ 3 ] / 100, 14039 execResult[ 4 ] 14040 ]; 14041 } 14042 } ], 14043 14044 // jQuery.Color( ) 14045 color = jQuery.Color = function( color, green, blue, alpha ) { 14046 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 14047 }, 14048 spaces = { 14049 rgba: { 14050 props: { 14051 red: { 14052 idx: 0, 14053 type: "byte" 14054 }, 14055 green: { 14056 idx: 1, 14057 type: "byte" 14058 }, 14059 blue: { 14060 idx: 2, 14061 type: "byte" 14062 } 14063 } 14064 }, 14065 14066 hsla: { 14067 props: { 14068 hue: { 14069 idx: 0, 14070 type: "degrees" 14071 }, 14072 saturation: { 14073 idx: 1, 14074 type: "percent" 14075 }, 14076 lightness: { 14077 idx: 2, 14078 type: "percent" 14079 } 14080 } 14081 } 14082 }, 14083 propTypes = { 14084 "byte": { 14085 floor: true, 14086 max: 255 14087 }, 14088 "percent": { 14089 max: 1 14090 }, 14091 "degrees": { 14092 mod: 360, 14093 floor: true 14094 } 14095 }, 14096 support = color.support = {}, 14097 14098 // element for support tests 14099 supportElem = jQuery( "<p>" )[ 0 ], 14100 14101 // colors = jQuery.Color.names 14102 colors, 14103 14104 // local aliases of functions called often 14105 each = jQuery.each; 14106 14107// determine rgba support immediately 14108supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 14109support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 14110 14111// define cache name and alpha properties 14112// for rgba and hsla spaces 14113each( spaces, function( spaceName, space ) { 14114 space.cache = "_" + spaceName; 14115 space.props.alpha = { 14116 idx: 3, 14117 type: "percent", 14118 def: 1 14119 }; 14120}); 14121 14122function clamp( value, prop, allowEmpty ) { 14123 var type = propTypes[ prop.type ] || {}; 14124 14125 if ( value == null ) { 14126 return (allowEmpty || !prop.def) ? null : prop.def; 14127 } 14128 14129 // ~~ is an short way of doing floor for positive numbers 14130 value = type.floor ? ~~value : parseFloat( value ); 14131 14132 // IE will pass in empty strings as value for alpha, 14133 // which will hit this case 14134 if ( isNaN( value ) ) { 14135 return prop.def; 14136 } 14137 14138 if ( type.mod ) { 14139 // we add mod before modding to make sure that negatives values 14140 // get converted properly: -10 -> 350 14141 return (value + type.mod) % type.mod; 14142 } 14143 14144 // for now all property types without mod have min and max 14145 return 0 > value ? 0 : type.max < value ? type.max : value; 14146} 14147 14148function stringParse( string ) { 14149 var inst = color(), 14150 rgba = inst._rgba = []; 14151 14152 string = string.toLowerCase(); 14153 14154 each( stringParsers, function( i, parser ) { 14155 var parsed, 14156 match = parser.re.exec( string ), 14157 values = match && parser.parse( match ), 14158 spaceName = parser.space || "rgba"; 14159 14160 if ( values ) { 14161 parsed = inst[ spaceName ]( values ); 14162 14163 // if this was an rgba parse the assignment might happen twice 14164 // oh well.... 14165 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 14166 rgba = inst._rgba = parsed._rgba; 14167 14168 // exit each( stringParsers ) here because we matched 14169 return false; 14170 } 14171 }); 14172 14173 // Found a stringParser that handled it 14174 if ( rgba.length ) { 14175 14176 // if this came from a parsed string, force "transparent" when alpha is 0 14177 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 14178 if ( rgba.join() === "0,0,0,0" ) { 14179 jQuery.extend( rgba, colors.transparent ); 14180 } 14181 return inst; 14182 } 14183 14184 // named colors 14185 return colors[ string ]; 14186} 14187 14188color.fn = jQuery.extend( color.prototype, { 14189 parse: function( red, green, blue, alpha ) { 14190 if ( red === undefined ) { 14191 this._rgba = [ null, null, null, null ]; 14192 return this; 14193 } 14194 if ( red.jquery || red.nodeType ) { 14195 red = jQuery( red ).css( green ); 14196 green = undefined; 14197 } 14198 14199 var inst = this, 14200 type = jQuery.type( red ), 14201 rgba = this._rgba = []; 14202 14203 // more than 1 argument specified - assume ( red, green, blue, alpha ) 14204 if ( green !== undefined ) { 14205 red = [ red, green, blue, alpha ]; 14206 type = "array"; 14207 } 14208 14209 if ( type === "string" ) { 14210 return this.parse( stringParse( red ) || colors._default ); 14211 } 14212 14213 if ( type === "array" ) { 14214 each( spaces.rgba.props, function( key, prop ) { 14215 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 14216 }); 14217 return this; 14218 } 14219 14220 if ( type === "object" ) { 14221 if ( red instanceof color ) { 14222 each( spaces, function( spaceName, space ) { 14223 if ( red[ space.cache ] ) { 14224 inst[ space.cache ] = red[ space.cache ].slice(); 14225 } 14226 }); 14227 } else { 14228 each( spaces, function( spaceName, space ) { 14229 var cache = space.cache; 14230 each( space.props, function( key, prop ) { 14231 14232 // if the cache doesn't exist, and we know how to convert 14233 if ( !inst[ cache ] && space.to ) { 14234 14235 // if the value was null, we don't need to copy it 14236 // if the key was alpha, we don't need to copy it either 14237 if ( key === "alpha" || red[ key ] == null ) { 14238 return; 14239 } 14240 inst[ cache ] = space.to( inst._rgba ); 14241 } 14242 14243 // this is the only case where we allow nulls for ALL properties. 14244 // call clamp with alwaysAllowEmpty 14245 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 14246 }); 14247 14248 // everything defined but alpha? 14249 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 14250 // use the default of 1 14251 inst[ cache ][ 3 ] = 1; 14252 if ( space.from ) { 14253 inst._rgba = space.from( inst[ cache ] ); 14254 } 14255 } 14256 }); 14257 } 14258 return this; 14259 } 14260 }, 14261 is: function( compare ) { 14262 var is = color( compare ), 14263 same = true, 14264 inst = this; 14265 14266 each( spaces, function( _, space ) { 14267 var localCache, 14268 isCache = is[ space.cache ]; 14269 if (isCache) { 14270 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 14271 each( space.props, function( _, prop ) { 14272 if ( isCache[ prop.idx ] != null ) { 14273 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 14274 return same; 14275 } 14276 }); 14277 } 14278 return same; 14279 }); 14280 return same; 14281 }, 14282 _space: function() { 14283 var used = [], 14284 inst = this; 14285 each( spaces, function( spaceName, space ) { 14286 if ( inst[ space.cache ] ) { 14287 used.push( spaceName ); 14288 } 14289 }); 14290 return used.pop(); 14291 }, 14292 transition: function( other, distance ) { 14293 var end = color( other ), 14294 spaceName = end._space(), 14295 space = spaces[ spaceName ], 14296 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 14297 start = startColor[ space.cache ] || space.to( startColor._rgba ), 14298 result = start.slice(); 14299 14300 end = end[ space.cache ]; 14301 each( space.props, function( key, prop ) { 14302 var index = prop.idx, 14303 startValue = start[ index ], 14304 endValue = end[ index ], 14305 type = propTypes[ prop.type ] || {}; 14306 14307 // if null, don't override start value 14308 if ( endValue === null ) { 14309 return; 14310 } 14311 // if null - use end 14312 if ( startValue === null ) { 14313 result[ index ] = endValue; 14314 } else { 14315 if ( type.mod ) { 14316 if ( endValue - startValue > type.mod / 2 ) { 14317 startValue += type.mod; 14318 } else if ( startValue - endValue > type.mod / 2 ) { 14319 startValue -= type.mod; 14320 } 14321 } 14322 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 14323 } 14324 }); 14325 return this[ spaceName ]( result ); 14326 }, 14327 blend: function( opaque ) { 14328 // if we are already opaque - return ourself 14329 if ( this._rgba[ 3 ] === 1 ) { 14330 return this; 14331 } 14332 14333 var rgb = this._rgba.slice(), 14334 a = rgb.pop(), 14335 blend = color( opaque )._rgba; 14336 14337 return color( jQuery.map( rgb, function( v, i ) { 14338 return ( 1 - a ) * blend[ i ] + a * v; 14339 })); 14340 }, 14341 toRgbaString: function() { 14342 var prefix = "rgba(", 14343 rgba = jQuery.map( this._rgba, function( v, i ) { 14344 return v == null ? ( i > 2 ? 1 : 0 ) : v; 14345 }); 14346 14347 if ( rgba[ 3 ] === 1 ) { 14348 rgba.pop(); 14349 prefix = "rgb("; 14350 } 14351 14352 return prefix + rgba.join() + ")"; 14353 }, 14354 toHslaString: function() { 14355 var prefix = "hsla(", 14356 hsla = jQuery.map( this.hsla(), function( v, i ) { 14357 if ( v == null ) { 14358 v = i > 2 ? 1 : 0; 14359 } 14360 14361 // catch 1 and 2 14362 if ( i && i < 3 ) { 14363 v = Math.round( v * 100 ) + "%"; 14364 } 14365 return v; 14366 }); 14367 14368 if ( hsla[ 3 ] === 1 ) { 14369 hsla.pop(); 14370 prefix = "hsl("; 14371 } 14372 return prefix + hsla.join() + ")"; 14373 }, 14374 toHexString: function( includeAlpha ) { 14375 var rgba = this._rgba.slice(), 14376 alpha = rgba.pop(); 14377 14378 if ( includeAlpha ) { 14379 rgba.push( ~~( alpha * 255 ) ); 14380 } 14381 14382 return "#" + jQuery.map( rgba, function( v ) { 14383 14384 // default to 0 when nulls exist 14385 v = ( v || 0 ).toString( 16 ); 14386 return v.length === 1 ? "0" + v : v; 14387 }).join(""); 14388 }, 14389 toString: function() { 14390 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 14391 } 14392}); 14393color.fn.parse.prototype = color.fn; 14394 14395// hsla conversions adapted from: 14396// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 14397 14398function hue2rgb( p, q, h ) { 14399 h = ( h + 1 ) % 1; 14400 if ( h * 6 < 1 ) { 14401 return p + ( q - p ) * h * 6; 14402 } 14403 if ( h * 2 < 1) { 14404 return q; 14405 } 14406 if ( h * 3 < 2 ) { 14407 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 14408 } 14409 return p; 14410} 14411 14412spaces.hsla.to = function( rgba ) { 14413 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 14414 return [ null, null, null, rgba[ 3 ] ]; 14415 } 14416 var r = rgba[ 0 ] / 255, 14417 g = rgba[ 1 ] / 255, 14418 b = rgba[ 2 ] / 255, 14419 a = rgba[ 3 ], 14420 max = Math.max( r, g, b ), 14421 min = Math.min( r, g, b ), 14422 diff = max - min, 14423 add = max + min, 14424 l = add * 0.5, 14425 h, s; 14426 14427 if ( min === max ) { 14428 h = 0; 14429 } else if ( r === max ) { 14430 h = ( 60 * ( g - b ) / diff ) + 360; 14431 } else if ( g === max ) { 14432 h = ( 60 * ( b - r ) / diff ) + 120; 14433 } else { 14434 h = ( 60 * ( r - g ) / diff ) + 240; 14435 } 14436 14437 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 14438 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 14439 if ( diff === 0 ) { 14440 s = 0; 14441 } else if ( l <= 0.5 ) { 14442 s = diff / add; 14443 } else { 14444 s = diff / ( 2 - add ); 14445 } 14446 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 14447}; 14448 14449spaces.hsla.from = function( hsla ) { 14450 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 14451 return [ null, null, null, hsla[ 3 ] ]; 14452 } 14453 var h = hsla[ 0 ] / 360, 14454 s = hsla[ 1 ], 14455 l = hsla[ 2 ], 14456 a = hsla[ 3 ], 14457 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 14458 p = 2 * l - q; 14459 14460 return [ 14461 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 14462 Math.round( hue2rgb( p, q, h ) * 255 ), 14463 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 14464 a 14465 ]; 14466}; 14467 14468each( spaces, function( spaceName, space ) { 14469 var props = space.props, 14470 cache = space.cache, 14471 to = space.to, 14472 from = space.from; 14473 14474 // makes rgba() and hsla() 14475 color.fn[ spaceName ] = function( value ) { 14476 14477 // generate a cache for this space if it doesn't exist 14478 if ( to && !this[ cache ] ) { 14479 this[ cache ] = to( this._rgba ); 14480 } 14481 if ( value === undefined ) { 14482 return this[ cache ].slice(); 14483 } 14484 14485 var ret, 14486 type = jQuery.type( value ), 14487 arr = ( type === "array" || type === "object" ) ? value : arguments, 14488 local = this[ cache ].slice(); 14489 14490 each( props, function( key, prop ) { 14491 var val = arr[ type === "object" ? key : prop.idx ]; 14492 if ( val == null ) { 14493 val = local[ prop.idx ]; 14494 } 14495 local[ prop.idx ] = clamp( val, prop ); 14496 }); 14497 14498 if ( from ) { 14499 ret = color( from( local ) ); 14500 ret[ cache ] = local; 14501 return ret; 14502 } else { 14503 return color( local ); 14504 } 14505 }; 14506 14507 // makes red() green() blue() alpha() hue() saturation() lightness() 14508 each( props, function( key, prop ) { 14509 // alpha is included in more than one space 14510 if ( color.fn[ key ] ) { 14511 return; 14512 } 14513 color.fn[ key ] = function( value ) { 14514 var vtype = jQuery.type( value ), 14515 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 14516 local = this[ fn ](), 14517 cur = local[ prop.idx ], 14518 match; 14519 14520 if ( vtype === "undefined" ) { 14521 return cur; 14522 } 14523 14524 if ( vtype === "function" ) { 14525 value = value.call( this, cur ); 14526 vtype = jQuery.type( value ); 14527 } 14528 if ( value == null && prop.empty ) { 14529 return this; 14530 } 14531 if ( vtype === "string" ) { 14532 match = rplusequals.exec( value ); 14533 if ( match ) { 14534 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 14535 } 14536 } 14537 local[ prop.idx ] = value; 14538 return this[ fn ]( local ); 14539 }; 14540 }); 14541}); 14542 14543// add cssHook and .fx.step function for each named hook. 14544// accept a space separated string of properties 14545color.hook = function( hook ) { 14546 var hooks = hook.split( " " ); 14547 each( hooks, function( i, hook ) { 14548 jQuery.cssHooks[ hook ] = { 14549 set: function( elem, value ) { 14550 var parsed, curElem, 14551 backgroundColor = ""; 14552 14553 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 14554 value = color( parsed || value ); 14555 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 14556 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 14557 while ( 14558 (backgroundColor === "" || backgroundColor === "transparent") && 14559 curElem && curElem.style 14560 ) { 14561 try { 14562 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 14563 curElem = curElem.parentNode; 14564 } catch ( e ) { 14565 } 14566 } 14567 14568 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 14569 backgroundColor : 14570 "_default" ); 14571 } 14572 14573 value = value.toRgbaString(); 14574 } 14575 try { 14576 elem.style[ hook ] = value; 14577 } catch( e ) { 14578 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 14579 } 14580 } 14581 }; 14582 jQuery.fx.step[ hook ] = function( fx ) { 14583 if ( !fx.colorInit ) { 14584 fx.start = color( fx.elem, hook ); 14585 fx.end = color( fx.end ); 14586 fx.colorInit = true; 14587 } 14588 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 14589 }; 14590 }); 14591 14592}; 14593 14594color.hook( stepHooks ); 14595 14596jQuery.cssHooks.borderColor = { 14597 expand: function( value ) { 14598 var expanded = {}; 14599 14600 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 14601 expanded[ "border" + part + "Color" ] = value; 14602 }); 14603 return expanded; 14604 } 14605}; 14606 14607// Basic color names only. 14608// Usage of any of the other color names requires adding yourself or including 14609// jquery.color.svg-names.js. 14610colors = jQuery.Color.names = { 14611 // 4.1. Basic color keywords 14612 aqua: "#00ffff", 14613 black: "#000000", 14614 blue: "#0000ff", 14615 fuchsia: "#ff00ff", 14616 gray: "#808080", 14617 green: "#008000", 14618 lime: "#00ff00", 14619 maroon: "#800000", 14620 navy: "#000080", 14621 olive: "#808000", 14622 purple: "#800080", 14623 red: "#ff0000", 14624 silver: "#c0c0c0", 14625 teal: "#008080", 14626 white: "#ffffff", 14627 yellow: "#ffff00", 14628 14629 // 4.2.3. "transparent" color keyword 14630 transparent: [ null, null, null, 0 ], 14631 14632 _default: "#ffffff" 14633}; 14634 14635})( jQuery ); 14636 14637/******************************************************************************/ 14638/****************************** CLASS ANIMATIONS ******************************/ 14639/******************************************************************************/ 14640(function() { 14641 14642var classAnimationActions = [ "add", "remove", "toggle" ], 14643 shorthandStyles = { 14644 border: 1, 14645 borderBottom: 1, 14646 borderColor: 1, 14647 borderLeft: 1, 14648 borderRight: 1, 14649 borderTop: 1, 14650 borderWidth: 1, 14651 margin: 1, 14652 padding: 1 14653 }; 14654 14655$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 14656 $.fx.step[ prop ] = function( fx ) { 14657 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 14658 jQuery.style( fx.elem, prop, fx.end ); 14659 fx.setAttr = true; 14660 } 14661 }; 14662}); 14663 14664function getElementStyles( elem ) { 14665 var key, len, 14666 style = elem.ownerDocument.defaultView ? 14667 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 14668 elem.currentStyle, 14669 styles = {}; 14670 14671 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 14672 len = style.length; 14673 while ( len-- ) { 14674 key = style[ len ]; 14675 if ( typeof style[ key ] === "string" ) { 14676 styles[ $.camelCase( key ) ] = style[ key ]; 14677 } 14678 } 14679 // support: Opera, IE <9 14680 } else { 14681 for ( key in style ) { 14682 if ( typeof style[ key ] === "string" ) { 14683 styles[ key ] = style[ key ]; 14684 } 14685 } 14686 } 14687 14688 return styles; 14689} 14690 14691function styleDifference( oldStyle, newStyle ) { 14692 var diff = {}, 14693 name, value; 14694 14695 for ( name in newStyle ) { 14696 value = newStyle[ name ]; 14697 if ( oldStyle[ name ] !== value ) { 14698 if ( !shorthandStyles[ name ] ) { 14699 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 14700 diff[ name ] = value; 14701 } 14702 } 14703 } 14704 } 14705 14706 return diff; 14707} 14708 14709// support: jQuery <1.8 14710if ( !$.fn.addBack ) { 14711 $.fn.addBack = function( selector ) { 14712 return this.add( selector == null ? 14713 this.prevObject : this.prevObject.filter( selector ) 14714 ); 14715 }; 14716} 14717 14718$.effects.animateClass = function( value, duration, easing, callback ) { 14719 var o = $.speed( duration, easing, callback ); 14720 14721 return this.queue( function() { 14722 var animated = $( this ), 14723 baseClass = animated.attr( "class" ) || "", 14724 applyClassChange, 14725 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 14726 14727 // map the animated objects to store the original styles. 14728 allAnimations = allAnimations.map(function() { 14729 var el = $( this ); 14730 return { 14731 el: el, 14732 start: getElementStyles( this ) 14733 }; 14734 }); 14735 14736 // apply class change 14737 applyClassChange = function() { 14738 $.each( classAnimationActions, function(i, action) { 14739 if ( value[ action ] ) { 14740 animated[ action + "Class" ]( value[ action ] ); 14741 } 14742 }); 14743 }; 14744 applyClassChange(); 14745 14746 // map all animated objects again - calculate new styles and diff 14747 allAnimations = allAnimations.map(function() { 14748 this.end = getElementStyles( this.el[ 0 ] ); 14749 this.diff = styleDifference( this.start, this.end ); 14750 return this; 14751 }); 14752 14753 // apply original class 14754 animated.attr( "class", baseClass ); 14755 14756 // map all animated objects again - this time collecting a promise 14757 allAnimations = allAnimations.map(function() { 14758 var styleInfo = this, 14759 dfd = $.Deferred(), 14760 opts = $.extend({}, o, { 14761 queue: false, 14762 complete: function() { 14763 dfd.resolve( styleInfo ); 14764 } 14765 }); 14766 14767 this.el.animate( this.diff, opts ); 14768 return dfd.promise(); 14769 }); 14770 14771 // once all animations have completed: 14772 $.when.apply( $, allAnimations.get() ).done(function() { 14773 14774 // set the final class 14775 applyClassChange(); 14776 14777 // for each animated element, 14778 // clear all css properties that were animated 14779 $.each( arguments, function() { 14780 var el = this.el; 14781 $.each( this.diff, function(key) { 14782 el.css( key, "" ); 14783 }); 14784 }); 14785 14786 // this is guarnteed to be there if you use jQuery.speed() 14787 // it also handles dequeuing the next anim... 14788 o.complete.call( animated[ 0 ] ); 14789 }); 14790 }); 14791}; 14792 14793$.fn.extend({ 14794 addClass: (function( orig ) { 14795 return function( classNames, speed, easing, callback ) { 14796 return speed ? 14797 $.effects.animateClass.call( this, 14798 { add: classNames }, speed, easing, callback ) : 14799 orig.apply( this, arguments ); 14800 }; 14801 })( $.fn.addClass ), 14802 14803 removeClass: (function( orig ) { 14804 return function( classNames, speed, easing, callback ) { 14805 return arguments.length > 1 ? 14806 $.effects.animateClass.call( this, 14807 { remove: classNames }, speed, easing, callback ) : 14808 orig.apply( this, arguments ); 14809 }; 14810 })( $.fn.removeClass ), 14811 14812 toggleClass: (function( orig ) { 14813 return function( classNames, force, speed, easing, callback ) { 14814 if ( typeof force === "boolean" || force === undefined ) { 14815 if ( !speed ) { 14816 // without speed parameter 14817 return orig.apply( this, arguments ); 14818 } else { 14819 return $.effects.animateClass.call( this, 14820 (force ? { add: classNames } : { remove: classNames }), 14821 speed, easing, callback ); 14822 } 14823 } else { 14824 // without force parameter 14825 return $.effects.animateClass.call( this, 14826 { toggle: classNames }, force, speed, easing ); 14827 } 14828 }; 14829 })( $.fn.toggleClass ), 14830 14831 switchClass: function( remove, add, speed, easing, callback) { 14832 return $.effects.animateClass.call( this, { 14833 add: add, 14834 remove: remove 14835 }, speed, easing, callback ); 14836 } 14837}); 14838 14839})(); 14840 14841/******************************************************************************/ 14842/*********************************** EFFECTS **********************************/ 14843/******************************************************************************/ 14844 14845(function() { 14846 14847$.extend( $.effects, { 14848 version: "1.11.1", 14849 14850 // Saves a set of properties in a data storage 14851 save: function( element, set ) { 14852 for ( var i = 0; i < set.length; i++ ) { 14853 if ( set[ i ] !== null ) { 14854 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 14855 } 14856 } 14857 }, 14858 14859 // Restores a set of previously saved properties from a data storage 14860 restore: function( element, set ) { 14861 var val, i; 14862 for ( i = 0; i < set.length; i++ ) { 14863 if ( set[ i ] !== null ) { 14864 val = element.data( dataSpace + set[ i ] ); 14865 // support: jQuery 1.6.2 14866 // http://bugs.jquery.com/ticket/9917 14867 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 14868 // We can't differentiate between "" and 0 here, so we just assume 14869 // empty string since it's likely to be a more common value... 14870 if ( val === undefined ) { 14871 val = ""; 14872 } 14873 element.css( set[ i ], val ); 14874 } 14875 } 14876 }, 14877 14878 setMode: function( el, mode ) { 14879 if (mode === "toggle") { 14880 mode = el.is( ":hidden" ) ? "show" : "hide"; 14881 } 14882 return mode; 14883 }, 14884 14885 // Translates a [top,left] array into a baseline value 14886 // this should be a little more flexible in the future to handle a string & hash 14887 getBaseline: function( origin, original ) { 14888 var y, x; 14889 switch ( origin[ 0 ] ) { 14890 case "top": y = 0; break; 14891 case "middle": y = 0.5; break; 14892 case "bottom": y = 1; break; 14893 default: y = origin[ 0 ] / original.height; 14894 } 14895 switch ( origin[ 1 ] ) { 14896 case "left": x = 0; break; 14897 case "center": x = 0.5; break; 14898 case "right": x = 1; break; 14899 default: x = origin[ 1 ] / original.width; 14900 } 14901 return { 14902 x: x, 14903 y: y 14904 }; 14905 }, 14906 14907 // Wraps the element around a wrapper that copies position properties 14908 createWrapper: function( element ) { 14909 14910 // if the element is already wrapped, return it 14911 if ( element.parent().is( ".ui-effects-wrapper" )) { 14912 return element.parent(); 14913 } 14914 14915 // wrap the element 14916 var props = { 14917 width: element.outerWidth(true), 14918 height: element.outerHeight(true), 14919 "float": element.css( "float" ) 14920 }, 14921 wrapper = $( "<div></div>" ) 14922 .addClass( "ui-effects-wrapper" ) 14923 .css({ 14924 fontSize: "100%", 14925 background: "transparent", 14926 border: "none", 14927 margin: 0, 14928 padding: 0 14929 }), 14930 // Store the size in case width/height are defined in % - Fixes #5245 14931 size = { 14932 width: element.width(), 14933 height: element.height() 14934 }, 14935 active = document.activeElement; 14936 14937 // support: Firefox 14938 // Firefox incorrectly exposes anonymous content 14939 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 14940 try { 14941 active.id; 14942 } catch( e ) { 14943 active = document.body; 14944 } 14945 14946 element.wrap( wrapper ); 14947 14948 // Fixes #7595 - Elements lose focus when wrapped. 14949 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14950 $( active ).focus(); 14951 } 14952 14953 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 14954 14955 // transfer positioning properties to the wrapper 14956 if ( element.css( "position" ) === "static" ) { 14957 wrapper.css({ position: "relative" }); 14958 element.css({ position: "relative" }); 14959 } else { 14960 $.extend( props, { 14961 position: element.css( "position" ), 14962 zIndex: element.css( "z-index" ) 14963 }); 14964 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 14965 props[ pos ] = element.css( pos ); 14966 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 14967 props[ pos ] = "auto"; 14968 } 14969 }); 14970 element.css({ 14971 position: "relative", 14972 top: 0, 14973 left: 0, 14974 right: "auto", 14975 bottom: "auto" 14976 }); 14977 } 14978 element.css(size); 14979 14980 return wrapper.css( props ).show(); 14981 }, 14982 14983 removeWrapper: function( element ) { 14984 var active = document.activeElement; 14985 14986 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 14987 element.parent().replaceWith( element ); 14988 14989 // Fixes #7595 - Elements lose focus when wrapped. 14990 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14991 $( active ).focus(); 14992 } 14993 } 14994 14995 return element; 14996 }, 14997 14998 setTransition: function( element, list, factor, value ) { 14999 value = value || {}; 15000 $.each( list, function( i, x ) { 15001 var unit = element.cssUnit( x ); 15002 if ( unit[ 0 ] > 0 ) { 15003 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 15004 } 15005 }); 15006 return value; 15007 } 15008}); 15009 15010// return an effect options object for the given parameters: 15011function _normalizeArguments( effect, options, speed, callback ) { 15012 15013 // allow passing all options as the first parameter 15014 if ( $.isPlainObject( effect ) ) { 15015 options = effect; 15016 effect = effect.effect; 15017 } 15018 15019 // convert to an object 15020 effect = { effect: effect }; 15021 15022 // catch (effect, null, ...) 15023 if ( options == null ) { 15024 options = {}; 15025 } 15026 15027 // catch (effect, callback) 15028 if ( $.isFunction( options ) ) { 15029 callback = options; 15030 speed = null; 15031 options = {}; 15032 } 15033 15034 // catch (effect, speed, ?) 15035 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 15036 callback = speed; 15037 speed = options; 15038 options = {}; 15039 } 15040 15041 // catch (effect, options, callback) 15042 if ( $.isFunction( speed ) ) { 15043 callback = speed; 15044 speed = null; 15045 } 15046 15047 // add options to effect 15048 if ( options ) { 15049 $.extend( effect, options ); 15050 } 15051 15052 speed = speed || options.duration; 15053 effect.duration = $.fx.off ? 0 : 15054 typeof speed === "number" ? speed : 15055 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 15056 $.fx.speeds._default; 15057 15058 effect.complete = callback || options.complete; 15059 15060 return effect; 15061} 15062 15063function standardAnimationOption( option ) { 15064 // Valid standard speeds (nothing, number, named speed) 15065 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 15066 return true; 15067 } 15068 15069 // Invalid strings - treat as "normal" speed 15070 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 15071 return true; 15072 } 15073 15074 // Complete callback 15075 if ( $.isFunction( option ) ) { 15076 return true; 15077 } 15078 15079 // Options hash (but not naming an effect) 15080 if ( typeof option === "object" && !option.effect ) { 15081 return true; 15082 } 15083 15084 // Didn't match any standard API 15085 return false; 15086} 15087 15088$.fn.extend({ 15089 effect: function( /* effect, options, speed, callback */ ) { 15090 var args = _normalizeArguments.apply( this, arguments ), 15091 mode = args.mode, 15092 queue = args.queue, 15093 effectMethod = $.effects.effect[ args.effect ]; 15094 15095 if ( $.fx.off || !effectMethod ) { 15096 // delegate to the original method (e.g., .show()) if possible 15097 if ( mode ) { 15098 return this[ mode ]( args.duration, args.complete ); 15099 } else { 15100 return this.each( function() { 15101 if ( args.complete ) { 15102 args.complete.call( this ); 15103 } 15104 }); 15105 } 15106 } 15107 15108 function run( next ) { 15109 var elem = $( this ), 15110 complete = args.complete, 15111 mode = args.mode; 15112 15113 function done() { 15114 if ( $.isFunction( complete ) ) { 15115 complete.call( elem[0] ); 15116 } 15117 if ( $.isFunction( next ) ) { 15118 next(); 15119 } 15120 } 15121 15122 // If the element already has the correct final state, delegate to 15123 // the core methods so the internal tracking of "olddisplay" works. 15124 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 15125 elem[ mode ](); 15126 done(); 15127 } else { 15128 effectMethod.call( elem[0], args, done ); 15129 } 15130 } 15131 15132 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 15133 }, 15134 15135 show: (function( orig ) { 15136 return function( option ) { 15137 if ( standardAnimationOption( option ) ) { 15138 return orig.apply( this, arguments ); 15139 } else { 15140 var args = _normalizeArguments.apply( this, arguments ); 15141 args.mode = "show"; 15142 return this.effect.call( this, args ); 15143 } 15144 }; 15145 })( $.fn.show ), 15146 15147 hide: (function( orig ) { 15148 return function( option ) { 15149 if ( standardAnimationOption( option ) ) { 15150 return orig.apply( this, arguments ); 15151 } else { 15152 var args = _normalizeArguments.apply( this, arguments ); 15153 args.mode = "hide"; 15154 return this.effect.call( this, args ); 15155 } 15156 }; 15157 })( $.fn.hide ), 15158 15159 toggle: (function( orig ) { 15160 return function( option ) { 15161 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 15162 return orig.apply( this, arguments ); 15163 } else { 15164 var args = _normalizeArguments.apply( this, arguments ); 15165 args.mode = "toggle"; 15166 return this.effect.call( this, args ); 15167 } 15168 }; 15169 })( $.fn.toggle ), 15170 15171 // helper functions 15172 cssUnit: function(key) { 15173 var style = this.css( key ), 15174 val = []; 15175 15176 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 15177 if ( style.indexOf( unit ) > 0 ) { 15178 val = [ parseFloat( style ), unit ]; 15179 } 15180 }); 15181 return val; 15182 } 15183}); 15184 15185})(); 15186 15187/******************************************************************************/ 15188/*********************************** EASING ***********************************/ 15189/******************************************************************************/ 15190 15191(function() { 15192 15193// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 15194 15195var baseEasings = {}; 15196 15197$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 15198 baseEasings[ name ] = function( p ) { 15199 return Math.pow( p, i + 2 ); 15200 }; 15201}); 15202 15203$.extend( baseEasings, { 15204 Sine: function( p ) { 15205 return 1 - Math.cos( p * Math.PI / 2 ); 15206 }, 15207 Circ: function( p ) { 15208 return 1 - Math.sqrt( 1 - p * p ); 15209 }, 15210 Elastic: function( p ) { 15211 return p === 0 || p === 1 ? p : 15212 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 15213 }, 15214 Back: function( p ) { 15215 return p * p * ( 3 * p - 2 ); 15216 }, 15217 Bounce: function( p ) { 15218 var pow2, 15219 bounce = 4; 15220 15221 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 15222 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 15223 } 15224}); 15225 15226$.each( baseEasings, function( name, easeIn ) { 15227 $.easing[ "easeIn" + name ] = easeIn; 15228 $.easing[ "easeOut" + name ] = function( p ) { 15229 return 1 - easeIn( 1 - p ); 15230 }; 15231 $.easing[ "easeInOut" + name ] = function( p ) { 15232 return p < 0.5 ? 15233 easeIn( p * 2 ) / 2 : 15234 1 - easeIn( p * -2 + 2 ) / 2; 15235 }; 15236}); 15237 15238})(); 15239 15240var effect = $.effects; 15241 15242 15243/*! 15244 * jQuery UI Effects Blind 1.11.1 15245 * http://jqueryui.com 15246 * 15247 * Copyright 2014 jQuery Foundation and other contributors 15248 * Released under the MIT license. 15249 * http://jquery.org/license 15250 * 15251 * http://api.jqueryui.com/blind-effect/ 15252 */ 15253 15254 15255var effectBlind = $.effects.effect.blind = function( o, done ) { 15256 // Create element 15257 var el = $( this ), 15258 rvertical = /up|down|vertical/, 15259 rpositivemotion = /up|left|vertical|horizontal/, 15260 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15261 mode = $.effects.setMode( el, o.mode || "hide" ), 15262 direction = o.direction || "up", 15263 vertical = rvertical.test( direction ), 15264 ref = vertical ? "height" : "width", 15265 ref2 = vertical ? "top" : "left", 15266 motion = rpositivemotion.test( direction ), 15267 animation = {}, 15268 show = mode === "show", 15269 wrapper, distance, margin; 15270 15271 // if already wrapped, the wrapper's properties are my property. #6245 15272 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 15273 $.effects.save( el.parent(), props ); 15274 } else { 15275 $.effects.save( el, props ); 15276 } 15277 el.show(); 15278 wrapper = $.effects.createWrapper( el ).css({ 15279 overflow: "hidden" 15280 }); 15281 15282 distance = wrapper[ ref ](); 15283 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 15284 15285 animation[ ref ] = show ? distance : 0; 15286 if ( !motion ) { 15287 el 15288 .css( vertical ? "bottom" : "right", 0 ) 15289 .css( vertical ? "top" : "left", "auto" ) 15290 .css({ position: "absolute" }); 15291 15292 animation[ ref2 ] = show ? margin : distance + margin; 15293 } 15294 15295 // start at 0 if we are showing 15296 if ( show ) { 15297 wrapper.css( ref, 0 ); 15298 if ( !motion ) { 15299 wrapper.css( ref2, margin + distance ); 15300 } 15301 } 15302 15303 // Animate 15304 wrapper.animate( animation, { 15305 duration: o.duration, 15306 easing: o.easing, 15307 queue: false, 15308 complete: function() { 15309 if ( mode === "hide" ) { 15310 el.hide(); 15311 } 15312 $.effects.restore( el, props ); 15313 $.effects.removeWrapper( el ); 15314 done(); 15315 } 15316 }); 15317}; 15318 15319 15320/*! 15321 * jQuery UI Effects Bounce 1.11.1 15322 * http://jqueryui.com 15323 * 15324 * Copyright 2014 jQuery Foundation and other contributors 15325 * Released under the MIT license. 15326 * http://jquery.org/license 15327 * 15328 * http://api.jqueryui.com/bounce-effect/ 15329 */ 15330 15331 15332var effectBounce = $.effects.effect.bounce = function( o, done ) { 15333 var el = $( this ), 15334 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15335 15336 // defaults: 15337 mode = $.effects.setMode( el, o.mode || "effect" ), 15338 hide = mode === "hide", 15339 show = mode === "show", 15340 direction = o.direction || "up", 15341 distance = o.distance, 15342 times = o.times || 5, 15343 15344 // number of internal animations 15345 anims = times * 2 + ( show || hide ? 1 : 0 ), 15346 speed = o.duration / anims, 15347 easing = o.easing, 15348 15349 // utility: 15350 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15351 motion = ( direction === "up" || direction === "left" ), 15352 i, 15353 upAnim, 15354 downAnim, 15355 15356 // we will need to re-assemble the queue to stack our animations in place 15357 queue = el.queue(), 15358 queuelen = queue.length; 15359 15360 // Avoid touching opacity to prevent clearType and PNG issues in IE 15361 if ( show || hide ) { 15362 props.push( "opacity" ); 15363 } 15364 15365 $.effects.save( el, props ); 15366 el.show(); 15367 $.effects.createWrapper( el ); // Create Wrapper 15368 15369 // default distance for the BIGGEST bounce is the outer Distance / 3 15370 if ( !distance ) { 15371 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 15372 } 15373 15374 if ( show ) { 15375 downAnim = { opacity: 1 }; 15376 downAnim[ ref ] = 0; 15377 15378 // if we are showing, force opacity 0 and set the initial position 15379 // then do the "first" animation 15380 el.css( "opacity", 0 ) 15381 .css( ref, motion ? -distance * 2 : distance * 2 ) 15382 .animate( downAnim, speed, easing ); 15383 } 15384 15385 // start at the smallest distance if we are hiding 15386 if ( hide ) { 15387 distance = distance / Math.pow( 2, times - 1 ); 15388 } 15389 15390 downAnim = {}; 15391 downAnim[ ref ] = 0; 15392 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 15393 for ( i = 0; i < times; i++ ) { 15394 upAnim = {}; 15395 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15396 15397 el.animate( upAnim, speed, easing ) 15398 .animate( downAnim, speed, easing ); 15399 15400 distance = hide ? distance * 2 : distance / 2; 15401 } 15402 15403 // Last Bounce when Hiding 15404 if ( hide ) { 15405 upAnim = { opacity: 0 }; 15406 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15407 15408 el.animate( upAnim, speed, easing ); 15409 } 15410 15411 el.queue(function() { 15412 if ( hide ) { 15413 el.hide(); 15414 } 15415 $.effects.restore( el, props ); 15416 $.effects.removeWrapper( el ); 15417 done(); 15418 }); 15419 15420 // inject all the animations we just queued to be first in line (after "inprogress") 15421 if ( queuelen > 1) { 15422 queue.splice.apply( queue, 15423 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15424 } 15425 el.dequeue(); 15426 15427}; 15428 15429 15430/*! 15431 * jQuery UI Effects Clip 1.11.1 15432 * http://jqueryui.com 15433 * 15434 * Copyright 2014 jQuery Foundation and other contributors 15435 * Released under the MIT license. 15436 * http://jquery.org/license 15437 * 15438 * http://api.jqueryui.com/clip-effect/ 15439 */ 15440 15441 15442var effectClip = $.effects.effect.clip = function( o, done ) { 15443 // Create element 15444 var el = $( this ), 15445 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15446 mode = $.effects.setMode( el, o.mode || "hide" ), 15447 show = mode === "show", 15448 direction = o.direction || "vertical", 15449 vert = direction === "vertical", 15450 size = vert ? "height" : "width", 15451 position = vert ? "top" : "left", 15452 animation = {}, 15453 wrapper, animate, distance; 15454 15455 // Save & Show 15456 $.effects.save( el, props ); 15457 el.show(); 15458 15459 // Create Wrapper 15460 wrapper = $.effects.createWrapper( el ).css({ 15461 overflow: "hidden" 15462 }); 15463 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 15464 distance = animate[ size ](); 15465 15466 // Shift 15467 if ( show ) { 15468 animate.css( size, 0 ); 15469 animate.css( position, distance / 2 ); 15470 } 15471 15472 // Create Animation Object: 15473 animation[ size ] = show ? distance : 0; 15474 animation[ position ] = show ? 0 : distance / 2; 15475 15476 // Animate 15477 animate.animate( animation, { 15478 queue: false, 15479 duration: o.duration, 15480 easing: o.easing, 15481 complete: function() { 15482 if ( !show ) { 15483 el.hide(); 15484 } 15485 $.effects.restore( el, props ); 15486 $.effects.removeWrapper( el ); 15487 done(); 15488 } 15489 }); 15490 15491}; 15492 15493 15494/*! 15495 * jQuery UI Effects Drop 1.11.1 15496 * http://jqueryui.com 15497 * 15498 * Copyright 2014 jQuery Foundation and other contributors 15499 * Released under the MIT license. 15500 * http://jquery.org/license 15501 * 15502 * http://api.jqueryui.com/drop-effect/ 15503 */ 15504 15505 15506var effectDrop = $.effects.effect.drop = function( o, done ) { 15507 15508 var el = $( this ), 15509 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 15510 mode = $.effects.setMode( el, o.mode || "hide" ), 15511 show = mode === "show", 15512 direction = o.direction || "left", 15513 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15514 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 15515 animation = { 15516 opacity: show ? 1 : 0 15517 }, 15518 distance; 15519 15520 // Adjust 15521 $.effects.save( el, props ); 15522 el.show(); 15523 $.effects.createWrapper( el ); 15524 15525 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 15526 15527 if ( show ) { 15528 el 15529 .css( "opacity", 0 ) 15530 .css( ref, motion === "pos" ? -distance : distance ); 15531 } 15532 15533 // Animation 15534 animation[ ref ] = ( show ? 15535 ( motion === "pos" ? "+=" : "-=" ) : 15536 ( motion === "pos" ? "-=" : "+=" ) ) + 15537 distance; 15538 15539 // Animate 15540 el.animate( animation, { 15541 queue: false, 15542 duration: o.duration, 15543 easing: o.easing, 15544 complete: function() { 15545 if ( mode === "hide" ) { 15546 el.hide(); 15547 } 15548 $.effects.restore( el, props ); 15549 $.effects.removeWrapper( el ); 15550 done(); 15551 } 15552 }); 15553}; 15554 15555 15556/*! 15557 * jQuery UI Effects Explode 1.11.1 15558 * http://jqueryui.com 15559 * 15560 * Copyright 2014 jQuery Foundation and other contributors 15561 * Released under the MIT license. 15562 * http://jquery.org/license 15563 * 15564 * http://api.jqueryui.com/explode-effect/ 15565 */ 15566 15567 15568var effectExplode = $.effects.effect.explode = function( o, done ) { 15569 15570 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 15571 cells = rows, 15572 el = $( this ), 15573 mode = $.effects.setMode( el, o.mode || "hide" ), 15574 show = mode === "show", 15575 15576 // show and then visibility:hidden the element before calculating offset 15577 offset = el.show().css( "visibility", "hidden" ).offset(), 15578 15579 // width and height of a piece 15580 width = Math.ceil( el.outerWidth() / cells ), 15581 height = Math.ceil( el.outerHeight() / rows ), 15582 pieces = [], 15583 15584 // loop 15585 i, j, left, top, mx, my; 15586 15587 // children animate complete: 15588 function childComplete() { 15589 pieces.push( this ); 15590 if ( pieces.length === rows * cells ) { 15591 animComplete(); 15592 } 15593 } 15594 15595 // clone the element for each row and cell. 15596 for ( i = 0; i < rows ; i++ ) { // ===> 15597 top = offset.top + i * height; 15598 my = i - ( rows - 1 ) / 2 ; 15599 15600 for ( j = 0; j < cells ; j++ ) { // ||| 15601 left = offset.left + j * width; 15602 mx = j - ( cells - 1 ) / 2 ; 15603 15604 // Create a clone of the now hidden main element that will be absolute positioned 15605 // within a wrapper div off the -left and -top equal to size of our pieces 15606 el 15607 .clone() 15608 .appendTo( "body" ) 15609 .wrap( "<div></div>" ) 15610 .css({ 15611 position: "absolute", 15612 visibility: "visible", 15613 left: -j * width, 15614 top: -i * height 15615 }) 15616 15617 // select the wrapper - make it overflow: hidden and absolute positioned based on 15618 // where the original was located +left and +top equal to the size of pieces 15619 .parent() 15620 .addClass( "ui-effects-explode" ) 15621 .css({ 15622 position: "absolute", 15623 overflow: "hidden", 15624 width: width, 15625 height: height, 15626 left: left + ( show ? mx * width : 0 ), 15627 top: top + ( show ? my * height : 0 ), 15628 opacity: show ? 0 : 1 15629 }).animate({ 15630 left: left + ( show ? 0 : mx * width ), 15631 top: top + ( show ? 0 : my * height ), 15632 opacity: show ? 1 : 0 15633 }, o.duration || 500, o.easing, childComplete ); 15634 } 15635 } 15636 15637 function animComplete() { 15638 el.css({ 15639 visibility: "visible" 15640 }); 15641 $( pieces ).remove(); 15642 if ( !show ) { 15643 el.hide(); 15644 } 15645 done(); 15646 } 15647}; 15648 15649 15650/*! 15651 * jQuery UI Effects Fade 1.11.1 15652 * http://jqueryui.com 15653 * 15654 * Copyright 2014 jQuery Foundation and other contributors 15655 * Released under the MIT license. 15656 * http://jquery.org/license 15657 * 15658 * http://api.jqueryui.com/fade-effect/ 15659 */ 15660 15661 15662var effectFade = $.effects.effect.fade = function( o, done ) { 15663 var el = $( this ), 15664 mode = $.effects.setMode( el, o.mode || "toggle" ); 15665 15666 el.animate({ 15667 opacity: mode 15668 }, { 15669 queue: false, 15670 duration: o.duration, 15671 easing: o.easing, 15672 complete: done 15673 }); 15674}; 15675 15676 15677/*! 15678 * jQuery UI Effects Fold 1.11.1 15679 * http://jqueryui.com 15680 * 15681 * Copyright 2014 jQuery Foundation and other contributors 15682 * Released under the MIT license. 15683 * http://jquery.org/license 15684 * 15685 * http://api.jqueryui.com/fold-effect/ 15686 */ 15687 15688 15689var effectFold = $.effects.effect.fold = function( o, done ) { 15690 15691 // Create element 15692 var el = $( this ), 15693 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15694 mode = $.effects.setMode( el, o.mode || "hide" ), 15695 show = mode === "show", 15696 hide = mode === "hide", 15697 size = o.size || 15, 15698 percent = /([0-9]+)%/.exec( size ), 15699 horizFirst = !!o.horizFirst, 15700 widthFirst = show !== horizFirst, 15701 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 15702 duration = o.duration / 2, 15703 wrapper, distance, 15704 animation1 = {}, 15705 animation2 = {}; 15706 15707 $.effects.save( el, props ); 15708 el.show(); 15709 15710 // Create Wrapper 15711 wrapper = $.effects.createWrapper( el ).css({ 15712 overflow: "hidden" 15713 }); 15714 distance = widthFirst ? 15715 [ wrapper.width(), wrapper.height() ] : 15716 [ wrapper.height(), wrapper.width() ]; 15717 15718 if ( percent ) { 15719 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 15720 } 15721 if ( show ) { 15722 wrapper.css( horizFirst ? { 15723 height: 0, 15724 width: size 15725 } : { 15726 height: size, 15727 width: 0 15728 }); 15729 } 15730 15731 // Animation 15732 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 15733 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 15734 15735 // Animate 15736 wrapper 15737 .animate( animation1, duration, o.easing ) 15738 .animate( animation2, duration, o.easing, function() { 15739 if ( hide ) { 15740 el.hide(); 15741 } 15742 $.effects.restore( el, props ); 15743 $.effects.removeWrapper( el ); 15744 done(); 15745 }); 15746 15747}; 15748 15749 15750/*! 15751 * jQuery UI Effects Highlight 1.11.1 15752 * http://jqueryui.com 15753 * 15754 * Copyright 2014 jQuery Foundation and other contributors 15755 * Released under the MIT license. 15756 * http://jquery.org/license 15757 * 15758 * http://api.jqueryui.com/highlight-effect/ 15759 */ 15760 15761 15762var effectHighlight = $.effects.effect.highlight = function( o, done ) { 15763 var elem = $( this ), 15764 props = [ "backgroundImage", "backgroundColor", "opacity" ], 15765 mode = $.effects.setMode( elem, o.mode || "show" ), 15766 animation = { 15767 backgroundColor: elem.css( "backgroundColor" ) 15768 }; 15769 15770 if (mode === "hide") { 15771 animation.opacity = 0; 15772 } 15773 15774 $.effects.save( elem, props ); 15775 15776 elem 15777 .show() 15778 .css({ 15779 backgroundImage: "none", 15780 backgroundColor: o.color || "#ffff99" 15781 }) 15782 .animate( animation, { 15783 queue: false, 15784 duration: o.duration, 15785 easing: o.easing, 15786 complete: function() { 15787 if ( mode === "hide" ) { 15788 elem.hide(); 15789 } 15790 $.effects.restore( elem, props ); 15791 done(); 15792 } 15793 }); 15794}; 15795 15796 15797/*! 15798 * jQuery UI Effects Size 1.11.1 15799 * http://jqueryui.com 15800 * 15801 * Copyright 2014 jQuery Foundation and other contributors 15802 * Released under the MIT license. 15803 * http://jquery.org/license 15804 * 15805 * http://api.jqueryui.com/size-effect/ 15806 */ 15807 15808 15809var effectSize = $.effects.effect.size = function( o, done ) { 15810 15811 // Create element 15812 var original, baseline, factor, 15813 el = $( this ), 15814 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 15815 15816 // Always restore 15817 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 15818 15819 // Copy for children 15820 props2 = [ "width", "height", "overflow" ], 15821 cProps = [ "fontSize" ], 15822 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 15823 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 15824 15825 // Set options 15826 mode = $.effects.setMode( el, o.mode || "effect" ), 15827 restore = o.restore || mode !== "effect", 15828 scale = o.scale || "both", 15829 origin = o.origin || [ "middle", "center" ], 15830 position = el.css( "position" ), 15831 props = restore ? props0 : props1, 15832 zero = { 15833 height: 0, 15834 width: 0, 15835 outerHeight: 0, 15836 outerWidth: 0 15837 }; 15838 15839 if ( mode === "show" ) { 15840 el.show(); 15841 } 15842 original = { 15843 height: el.height(), 15844 width: el.width(), 15845 outerHeight: el.outerHeight(), 15846 outerWidth: el.outerWidth() 15847 }; 15848 15849 if ( o.mode === "toggle" && mode === "show" ) { 15850 el.from = o.to || zero; 15851 el.to = o.from || original; 15852 } else { 15853 el.from = o.from || ( mode === "show" ? zero : original ); 15854 el.to = o.to || ( mode === "hide" ? zero : original ); 15855 } 15856 15857 // Set scaling factor 15858 factor = { 15859 from: { 15860 y: el.from.height / original.height, 15861 x: el.from.width / original.width 15862 }, 15863 to: { 15864 y: el.to.height / original.height, 15865 x: el.to.width / original.width 15866 } 15867 }; 15868 15869 // Scale the css box 15870 if ( scale === "box" || scale === "both" ) { 15871 15872 // Vertical props scaling 15873 if ( factor.from.y !== factor.to.y ) { 15874 props = props.concat( vProps ); 15875 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 15876 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 15877 } 15878 15879 // Horizontal props scaling 15880 if ( factor.from.x !== factor.to.x ) { 15881 props = props.concat( hProps ); 15882 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 15883 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 15884 } 15885 } 15886 15887 // Scale the content 15888 if ( scale === "content" || scale === "both" ) { 15889 15890 // Vertical props scaling 15891 if ( factor.from.y !== factor.to.y ) { 15892 props = props.concat( cProps ).concat( props2 ); 15893 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 15894 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 15895 } 15896 } 15897 15898 $.effects.save( el, props ); 15899 el.show(); 15900 $.effects.createWrapper( el ); 15901 el.css( "overflow", "hidden" ).css( el.from ); 15902 15903 // Adjust 15904 if (origin) { // Calculate baseline shifts 15905 baseline = $.effects.getBaseline( origin, original ); 15906 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 15907 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 15908 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 15909 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 15910 } 15911 el.css( el.from ); // set top & left 15912 15913 // Animate 15914 if ( scale === "content" || scale === "both" ) { // Scale the children 15915 15916 // Add margins/font-size 15917 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 15918 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 15919 props2 = props0.concat(vProps).concat(hProps); 15920 15921 el.find( "*[width]" ).each( function() { 15922 var child = $( this ), 15923 c_original = { 15924 height: child.height(), 15925 width: child.width(), 15926 outerHeight: child.outerHeight(), 15927 outerWidth: child.outerWidth() 15928 }; 15929 if (restore) { 15930 $.effects.save(child, props2); 15931 } 15932 15933 child.from = { 15934 height: c_original.height * factor.from.y, 15935 width: c_original.width * factor.from.x, 15936 outerHeight: c_original.outerHeight * factor.from.y, 15937 outerWidth: c_original.outerWidth * factor.from.x 15938 }; 15939 child.to = { 15940 height: c_original.height * factor.to.y, 15941 width: c_original.width * factor.to.x, 15942 outerHeight: c_original.height * factor.to.y, 15943 outerWidth: c_original.width * factor.to.x 15944 }; 15945 15946 // Vertical props scaling 15947 if ( factor.from.y !== factor.to.y ) { 15948 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 15949 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 15950 } 15951 15952 // Horizontal props scaling 15953 if ( factor.from.x !== factor.to.x ) { 15954 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 15955 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 15956 } 15957 15958 // Animate children 15959 child.css( child.from ); 15960 child.animate( child.to, o.duration, o.easing, function() { 15961 15962 // Restore children 15963 if ( restore ) { 15964 $.effects.restore( child, props2 ); 15965 } 15966 }); 15967 }); 15968 } 15969 15970 // Animate 15971 el.animate( el.to, { 15972 queue: false, 15973 duration: o.duration, 15974 easing: o.easing, 15975 complete: function() { 15976 if ( el.to.opacity === 0 ) { 15977 el.css( "opacity", el.from.opacity ); 15978 } 15979 if ( mode === "hide" ) { 15980 el.hide(); 15981 } 15982 $.effects.restore( el, props ); 15983 if ( !restore ) { 15984 15985 // we need to calculate our new positioning based on the scaling 15986 if ( position === "static" ) { 15987 el.css({ 15988 position: "relative", 15989 top: el.to.top, 15990 left: el.to.left 15991 }); 15992 } else { 15993 $.each([ "top", "left" ], function( idx, pos ) { 15994 el.css( pos, function( _, str ) { 15995 var val = parseInt( str, 10 ), 15996 toRef = idx ? el.to.left : el.to.top; 15997 15998 // if original was "auto", recalculate the new value from wrapper 15999 if ( str === "auto" ) { 16000 return toRef + "px"; 16001 } 16002 16003 return val + toRef + "px"; 16004 }); 16005 }); 16006 } 16007 } 16008 16009 $.effects.removeWrapper( el ); 16010 done(); 16011 } 16012 }); 16013 16014}; 16015 16016 16017/*! 16018 * jQuery UI Effects Scale 1.11.1 16019 * http://jqueryui.com 16020 * 16021 * Copyright 2014 jQuery Foundation and other contributors 16022 * Released under the MIT license. 16023 * http://jquery.org/license 16024 * 16025 * http://api.jqueryui.com/scale-effect/ 16026 */ 16027 16028 16029var effectScale = $.effects.effect.scale = function( o, done ) { 16030 16031 // Create element 16032 var el = $( this ), 16033 options = $.extend( true, {}, o ), 16034 mode = $.effects.setMode( el, o.mode || "effect" ), 16035 percent = parseInt( o.percent, 10 ) || 16036 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 16037 direction = o.direction || "both", 16038 origin = o.origin, 16039 original = { 16040 height: el.height(), 16041 width: el.width(), 16042 outerHeight: el.outerHeight(), 16043 outerWidth: el.outerWidth() 16044 }, 16045 factor = { 16046 y: direction !== "horizontal" ? (percent / 100) : 1, 16047 x: direction !== "vertical" ? (percent / 100) : 1 16048 }; 16049 16050 // We are going to pass this effect to the size effect: 16051 options.effect = "size"; 16052 options.queue = false; 16053 options.complete = done; 16054 16055 // Set default origin and restore for show/hide 16056 if ( mode !== "effect" ) { 16057 options.origin = origin || [ "middle", "center" ]; 16058 options.restore = true; 16059 } 16060 16061 options.from = o.from || ( mode === "show" ? { 16062 height: 0, 16063 width: 0, 16064 outerHeight: 0, 16065 outerWidth: 0 16066 } : original ); 16067 options.to = { 16068 height: original.height * factor.y, 16069 width: original.width * factor.x, 16070 outerHeight: original.outerHeight * factor.y, 16071 outerWidth: original.outerWidth * factor.x 16072 }; 16073 16074 // Fade option to support puff 16075 if ( options.fade ) { 16076 if ( mode === "show" ) { 16077 options.from.opacity = 0; 16078 options.to.opacity = 1; 16079 } 16080 if ( mode === "hide" ) { 16081 options.from.opacity = 1; 16082 options.to.opacity = 0; 16083 } 16084 } 16085 16086 // Animate 16087 el.effect( options ); 16088 16089}; 16090 16091 16092/*! 16093 * jQuery UI Effects Puff 1.11.1 16094 * http://jqueryui.com 16095 * 16096 * Copyright 2014 jQuery Foundation and other contributors 16097 * Released under the MIT license. 16098 * http://jquery.org/license 16099 * 16100 * http://api.jqueryui.com/puff-effect/ 16101 */ 16102 16103 16104var effectPuff = $.effects.effect.puff = function( o, done ) { 16105 var elem = $( this ), 16106 mode = $.effects.setMode( elem, o.mode || "hide" ), 16107 hide = mode === "hide", 16108 percent = parseInt( o.percent, 10 ) || 150, 16109 factor = percent / 100, 16110 original = { 16111 height: elem.height(), 16112 width: elem.width(), 16113 outerHeight: elem.outerHeight(), 16114 outerWidth: elem.outerWidth() 16115 }; 16116 16117 $.extend( o, { 16118 effect: "scale", 16119 queue: false, 16120 fade: true, 16121 mode: mode, 16122 complete: done, 16123 percent: hide ? percent : 100, 16124 from: hide ? 16125 original : 16126 { 16127 height: original.height * factor, 16128 width: original.width * factor, 16129 outerHeight: original.outerHeight * factor, 16130 outerWidth: original.outerWidth * factor 16131 } 16132 }); 16133 16134 elem.effect( o ); 16135}; 16136 16137 16138/*! 16139 * jQuery UI Effects Pulsate 1.11.1 16140 * http://jqueryui.com 16141 * 16142 * Copyright 2014 jQuery Foundation and other contributors 16143 * Released under the MIT license. 16144 * http://jquery.org/license 16145 * 16146 * http://api.jqueryui.com/pulsate-effect/ 16147 */ 16148 16149 16150var effectPulsate = $.effects.effect.pulsate = function( o, done ) { 16151 var elem = $( this ), 16152 mode = $.effects.setMode( elem, o.mode || "show" ), 16153 show = mode === "show", 16154 hide = mode === "hide", 16155 showhide = ( show || mode === "hide" ), 16156 16157 // showing or hiding leaves of the "last" animation 16158 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 16159 duration = o.duration / anims, 16160 animateTo = 0, 16161 queue = elem.queue(), 16162 queuelen = queue.length, 16163 i; 16164 16165 if ( show || !elem.is(":visible")) { 16166 elem.css( "opacity", 0 ).show(); 16167 animateTo = 1; 16168 } 16169 16170 // anims - 1 opacity "toggles" 16171 for ( i = 1; i < anims; i++ ) { 16172 elem.animate({ 16173 opacity: animateTo 16174 }, duration, o.easing ); 16175 animateTo = 1 - animateTo; 16176 } 16177 16178 elem.animate({ 16179 opacity: animateTo 16180 }, duration, o.easing); 16181 16182 elem.queue(function() { 16183 if ( hide ) { 16184 elem.hide(); 16185 } 16186 done(); 16187 }); 16188 16189 // We just queued up "anims" animations, we need to put them next in the queue 16190 if ( queuelen > 1 ) { 16191 queue.splice.apply( queue, 16192 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 16193 } 16194 elem.dequeue(); 16195}; 16196 16197 16198/*! 16199 * jQuery UI Effects Shake 1.11.1 16200 * http://jqueryui.com 16201 * 16202 * Copyright 2014 jQuery Foundation and other contributors 16203 * Released under the MIT license. 16204 * http://jquery.org/license 16205 * 16206 * http://api.jqueryui.com/shake-effect/ 16207 */ 16208 16209 16210var effectShake = $.effects.effect.shake = function( o, done ) { 16211 16212 var el = $( this ), 16213 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 16214 mode = $.effects.setMode( el, o.mode || "effect" ), 16215 direction = o.direction || "left", 16216 distance = o.distance || 20, 16217 times = o.times || 3, 16218 anims = times * 2 + 1, 16219 speed = Math.round( o.duration / anims ), 16220 ref = (direction === "up" || direction === "down") ? "top" : "left", 16221 positiveMotion = (direction === "up" || direction === "left"), 16222 animation = {}, 16223 animation1 = {}, 16224 animation2 = {}, 16225 i, 16226 16227 // we will need to re-assemble the queue to stack our animations in place 16228 queue = el.queue(), 16229 queuelen = queue.length; 16230 16231 $.effects.save( el, props ); 16232 el.show(); 16233 $.effects.createWrapper( el ); 16234 16235 // Animation 16236 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 16237 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 16238 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 16239 16240 // Animate 16241 el.animate( animation, speed, o.easing ); 16242 16243 // Shakes 16244 for ( i = 1; i < times; i++ ) { 16245 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 16246 } 16247 el 16248 .animate( animation1, speed, o.easing ) 16249 .animate( animation, speed / 2, o.easing ) 16250 .queue(function() { 16251 if ( mode === "hide" ) { 16252 el.hide(); 16253 } 16254 $.effects.restore( el, props ); 16255 $.effects.removeWrapper( el ); 16256 done(); 16257 }); 16258 16259 // inject all the animations we just queued to be first in line (after "inprogress") 16260 if ( queuelen > 1) { 16261 queue.splice.apply( queue, 16262 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 16263 } 16264 el.dequeue(); 16265 16266}; 16267 16268 16269/*! 16270 * jQuery UI Effects Slide 1.11.1 16271 * http://jqueryui.com 16272 * 16273 * Copyright 2014 jQuery Foundation and other contributors 16274 * Released under the MIT license. 16275 * http://jquery.org/license 16276 * 16277 * http://api.jqueryui.com/slide-effect/ 16278 */ 16279 16280 16281var effectSlide = $.effects.effect.slide = function( o, done ) { 16282 16283 // Create element 16284 var el = $( this ), 16285 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 16286 mode = $.effects.setMode( el, o.mode || "show" ), 16287 show = mode === "show", 16288 direction = o.direction || "left", 16289 ref = (direction === "up" || direction === "down") ? "top" : "left", 16290 positiveMotion = (direction === "up" || direction === "left"), 16291 distance, 16292 animation = {}; 16293 16294 // Adjust 16295 $.effects.save( el, props ); 16296 el.show(); 16297 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 16298 16299 $.effects.createWrapper( el ).css({ 16300 overflow: "hidden" 16301 }); 16302 16303 if ( show ) { 16304 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 16305 } 16306 16307 // Animation 16308 animation[ ref ] = ( show ? 16309 ( positiveMotion ? "+=" : "-=") : 16310 ( positiveMotion ? "-=" : "+=")) + 16311 distance; 16312 16313 // Animate 16314 el.animate( animation, { 16315 queue: false, 16316 duration: o.duration, 16317 easing: o.easing, 16318 complete: function() { 16319 if ( mode === "hide" ) { 16320 el.hide(); 16321 } 16322 $.effects.restore( el, props ); 16323 $.effects.removeWrapper( el ); 16324 done(); 16325 } 16326 }); 16327}; 16328 16329 16330/*! 16331 * jQuery UI Effects Transfer 1.11.1 16332 * http://jqueryui.com 16333 * 16334 * Copyright 2014 jQuery Foundation and other contributors 16335 * Released under the MIT license. 16336 * http://jquery.org/license 16337 * 16338 * http://api.jqueryui.com/transfer-effect/ 16339 */ 16340 16341 16342var effectTransfer = $.effects.effect.transfer = function( o, done ) { 16343 var elem = $( this ), 16344 target = $( o.to ), 16345 targetFixed = target.css( "position" ) === "fixed", 16346 body = $("body"), 16347 fixTop = targetFixed ? body.scrollTop() : 0, 16348 fixLeft = targetFixed ? body.scrollLeft() : 0, 16349 endPosition = target.offset(), 16350 animation = { 16351 top: endPosition.top - fixTop, 16352 left: endPosition.left - fixLeft, 16353 height: target.innerHeight(), 16354 width: target.innerWidth() 16355 }, 16356 startPosition = elem.offset(), 16357 transfer = $( "<div class='ui-effects-transfer'></div>" ) 16358 .appendTo( document.body ) 16359 .addClass( o.className ) 16360 .css({ 16361 top: startPosition.top - fixTop, 16362 left: startPosition.left - fixLeft, 16363 height: elem.innerHeight(), 16364 width: elem.innerWidth(), 16365 position: targetFixed ? "fixed" : "absolute" 16366 }) 16367 .animate( animation, o.duration, o.easing, function() { 16368 transfer.remove(); 16369 done(); 16370 }); 16371}; 16372 16373
16374 16375}));
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.