vendor: 5,834 bytes, lines 1-198
1/*! jQuery UI - v1.10.4 - 2017-05-07 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-drop.js, jquery.ui.effect-fade.js, jquery.ui.effect-highlight.js, jquery.ui.effect-slide.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// $.ui might exist from components with no dependencies, e.g., $.ui.position 12$.ui = $.ui || {}; 13 14$.extend( $.ui, { 15 version: "1.10.4", 16 17 keyCode: { 18 BACKSPACE: 8, 19 COMMA: 188, 20 DELETE: 46, 21 DOWN: 40, 22 END: 35, 23 ENTER: 13, 24 ESCAPE: 27, 25 HOME: 36, 26 LEFT: 37, 27 NUMPAD_ADD: 107, 28 NUMPAD_DECIMAL: 110, 29 NUMPAD_DIVIDE: 111, 30 NUMPAD_ENTER: 108, 31 NUMPAD_MULTIPLY: 106, 32 NUMPAD_SUBTRACT: 109, 33 PAGE_DOWN: 34, 34 PAGE_UP: 33, 35 PERIOD: 190, 36 RIGHT: 39, 37 SPACE: 32, 38 TAB: 9, 39 UP: 38 40 } 41}); 42 43// plugins 44$.fn.extend({ 45 focus: (function( orig ) { 46 return function( delay, fn ) { 47 return typeof delay === "number" ? 48 this.each(function() { 49 var elem = this; 50 setTimeout(function() { 51 $( elem ).focus(); 52 if ( fn ) { 53 fn.call( elem ); 54 } 55 }, delay ); 56 }) : 57 orig.apply( this, arguments ); 58 }; 59 })( $.fn.focus ), 60 61 scrollParent: function() { 62 var scrollParent; 63 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 64 scrollParent = this.parents().filter(function() { 65 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 66 }).eq(0); 67 } else { 68 scrollParent = this.parents().filter(function() { 69 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } 72 73 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 74 }, 75 76 zIndex: function( zIndex ) { 77 if ( zIndex !== undefined ) { 78 return this.css( "zIndex", zIndex ); 79 } 80 81 if ( this.length ) { 82 var elem = $( this[ 0 ] ), position, value; 83 while ( elem.length && elem[ 0 ] !== document ) { 84 // Ignore z-index if position is set to a value where z-index is ignored by the browser 85 // This makes behavior of this function consistent across browsers 86 // WebKit always returns auto if the element is positioned 87 position = elem.css( "position" ); 88 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 89 // IE returns 0 when zIndex is not specified 90 // other browsers return a string 91 // we ignore the case of nested elements with an explicit value of 0 92 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 93 value = parseInt( elem.css( "zIndex" ), 10 ); 94 if ( !isNaN( value ) && value !== 0 ) { 95 return value; 96 } 97 } 98 elem = elem.parent(); 99 } 100 } 101 102 return 0; 103 }, 104 105 uniqueId: function() { 106 return this.each(function() { 107 if ( !this.id ) { 108 this.id = "ui-id-" + (++uuid); 109 } 110 }); 111 }, 112 113 removeUniqueId: function() { 114 return this.each(function() { 115 if ( runiqueId.test( this.id ) ) { 116 $( this ).removeAttr( "id" ); 117 } 118 }); 119 } 120}); 121 122// selectors 123function focusable( element, isTabIndexNotNaN ) { 124 var map, mapName, img, 125 nodeName = element.nodeName.toLowerCase(); 126 if ( "area" === nodeName ) { 127 map = element.parentNode; 128 mapName = map.name; 129 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 130 return false; 131 } 132 img = $( "img[usemap=#" + mapName + "]" )[0]; 133 return !!img && visible( img ); 134 } 135 return ( /input|select|textarea|button|object/.test( nodeName ) ? 136 !element.disabled : 137 "a" === nodeName ? 138 element.href || isTabIndexNotNaN : 139 isTabIndexNotNaN) && 140 // the element and all of its ancestors must be visible 141 visible( element ); 142} 143 144function visible( element ) { 145 return $.expr.filters.visible( element ) && 146 !$( element ).parents().addBack().filter(function() { 147 return $.css( this, "visibility" ) === "hidden"; 148 }).length; 149} 150 151$.extend( $.expr[ ":" ], { 152 data: $.expr.createPseudo ? 153 $.expr.createPseudo(function( dataName ) { 154 return function( elem ) { 155 return !!$.data( elem, dataName ); 156 }; 157 }) : 158 // support: jQuery <1.8 159 function( elem, i, match ) { 160 return !!$.data( elem, match[ 3 ] ); 161 }, 162 163 focusable: function( element ) { 164 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 165 }, 166 167 tabbable: function( element ) { 168 var tabIndex = $.attr( element, "tabindex" ), 169 isTabIndexNaN = isNaN( tabIndex ); 170 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 171 } 172}); 173 174// support: jQuery <1.8 175if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 176 $.each( [ "Width", "Height" ], function( i, name ) { 177 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 178 type = name.toLowerCase(), 179 orig = { 180 innerWidth: $.fn.innerWidth, 181 innerHeight: $.fn.innerHeight, 182 outerWidth: $.fn.outerWidth, 183 outerHeight: $.fn.outerHeight 184 }; 185 186 function reduce( elem, size, border, margin ) { 187 $.each( side, function() { 188 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 189 if ( border ) { 190 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 191 } 192 if ( margin ) { 193 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 194 } 195 }); 196 return size; 197 } 198
vendor: 5,527 bytes, lines 199-400
199 $.fn[ "inner" + name ] = function( size ) { 200 if ( size === undefined ) { 201 return orig[ "inner" + name ].call( this ); 202 } 203 204 return this.each(function() { 205 $( this ).css( type, reduce( this, size ) + "px" ); 206 }); 207 }; 208 209 $.fn[ "outer" + name] = function( size, margin ) { 210 if ( typeof size !== "number" ) { 211 return orig[ "outer" + name ].call( this, size ); 212 } 213 214 return this.each(function() { 215 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 216 }); 217 }; 218 }); 219} 220 221// support: jQuery <1.8 222if ( !$.fn.addBack ) { 223 $.fn.addBack = function( selector ) { 224 return this.add( selector == null ? 225 this.prevObject : this.prevObject.filter( selector ) 226 ); 227 }; 228} 229 230// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 231if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 232 $.fn.removeData = (function( removeData ) { 233 return function( key ) { 234 if ( arguments.length ) { 235 return removeData.call( this, $.camelCase( key ) ); 236 } else { 237 return removeData.call( this ); 238 } 239 }; 240 })( $.fn.removeData ); 241} 242 243 244 245 246 247// deprecated 248$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 249 250$.support.selectstart = "onselectstart" in document.createElement( "div" ); 251$.fn.extend({ 252 disableSelection: function() { 253 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 254 ".ui-disableSelection", function( event ) { 255 event.preventDefault(); 256 }); 257 }, 258 259 enableSelection: function() { 260 return this.unbind( ".ui-disableSelection" ); 261 } 262}); 263 264$.extend( $.ui, { 265 // $.ui.plugin is deprecated. Use $.widget() extensions instead. 266 plugin: { 267 add: function( module, option, set ) { 268 var i, 269 proto = $.ui[ module ].prototype; 270 for ( i in set ) { 271 proto.plugins[ i ] = proto.plugins[ i ] || []; 272 proto.plugins[ i ].push( [ option, set[ i ] ] ); 273 } 274 }, 275 call: function( instance, name, args ) { 276 var i, 277 set = instance.plugins[ name ]; 278 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 279 return; 280 } 281 282 for ( i = 0; i < set.length; i++ ) { 283 if ( instance.options[ set[ i ][ 0 ] ] ) { 284 set[ i ][ 1 ].apply( instance.element, args ); 285 } 286 } 287 } 288 }, 289 290 // only used by resizable 291 hasScroll: function( el, a ) { 292 293 //If overflow is hidden, the element might have extra content, but the user wants to hide it 294 if ( $( el ).css( "overflow" ) === "hidden") { 295 return false; 296 } 297 298 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 299 has = false; 300 301 if ( el[ scroll ] > 0 ) { 302 return true; 303 } 304 305 // TODO: determine which cases actually cause this to happen 306 // if the element doesn't have the scroll set, see if it's possible to 307 // set the scroll 308 el[ scroll ] = 1; 309 has = ( el[ scroll ] > 0 ); 310 el[ scroll ] = 0; 311 return has; 312 } 313}); 314 315})( jQuery ); 316(function( $, undefined ) { 317 318var uuid = 0, 319 slice = Array.prototype.slice, 320 _cleanData = $.cleanData; 321$.cleanData = function( elems ) { 322 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 323 try { 324 $( elem ).triggerHandler( "remove" ); 325 // http://bugs.jquery.com/ticket/8235 326 } catch( e ) {} 327 } 328 _cleanData( elems ); 329}; 330 331$.widget = function( name, base, prototype ) { 332 var fullName, existingConstructor, constructor, basePrototype, 333 // proxiedPrototype allows the provided prototype to remain unmodified 334 // so that it can be used as a mixin for multiple widgets (#8876) 335 proxiedPrototype = {}, 336 namespace = name.split( "." )[ 0 ]; 337 338 name = name.split( "." )[ 1 ]; 339 fullName = namespace + "-" + name; 340 341 if ( !prototype ) { 342 prototype = base; 343 base = $.Widget; 344 } 345 346 // create selector for plugin 347 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 348 return !!$.data( elem, fullName ); 349 }; 350 351 $[ namespace ] = $[ namespace ] || {}; 352 existingConstructor = $[ namespace ][ name ]; 353 constructor = $[ namespace ][ name ] = function( options, element ) { 354 // allow instantiation without "new" keyword 355 if ( !this._createWidget ) { 356 return new constructor( options, element ); 357 } 358 359 // allow instantiation without initializing for simple inheritance 360 // must use "new" keyword (the code above always passes args) 361 if ( arguments.length ) { 362 this._createWidget( options, element ); 363 } 364 }; 365 // extend with the existing constructor to carry over any static properties 366 $.extend( constructor, existingConstructor, { 367 version: prototype.version, 368 // copy the object used to create the prototype in case we need to 369 // redefine the widget later 370 _proto: $.extend( {}, prototype ), 371 // track widgets that inherit from this widget in case this widget is 372 // redefined after a widget inherits from it 373 _childConstructors: [] 374 }); 375 376 basePrototype = new base(); 377 // we need to make the options hash a property directly on the new instance 378 // otherwise we'll modify the options hash on the prototype that we're 379 // inheriting from 380 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 381 $.each( prototype, function( prop, value ) { 382 if ( !$.isFunction( value ) ) { 383 proxiedPrototype[ prop ] = value; 384 return; 385 } 386 proxiedPrototype[ prop ] = (function() { 387 var _super = function() { 388 return base.prototype[ prop ].apply( this, arguments ); 389 }, 390 _superApply = function( args ) { 391 return base.prototype[ prop ].apply( this, args ); 392 }; 393 return function() { 394 var __super = this._super, 395 __superApply = this._superApply, 396 returnValue; 397 398 this._super = _super; 399 this._superApply = _superApply; 400
vendor: 11,929 bytes, lines 401-812
401 returnValue = value.apply( this, arguments ); 402 403 this._super = __super; 404 this._superApply = __superApply; 405 406 return returnValue; 407 }; 408 })(); 409 }); 410 constructor.prototype = $.widget.extend( basePrototype, { 411 // TODO: remove support for widgetEventPrefix 412 // always use the name + a colon as the prefix, e.g., draggable:start 413 // don't prefix for widgets that aren't DOM-based 414 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name 415 }, proxiedPrototype, { 416 constructor: constructor, 417 namespace: namespace, 418 widgetName: name, 419 widgetFullName: fullName 420 }); 421 422 // If this widget is being redefined then we need to find all widgets that 423 // are inheriting from it and redefine all of them so that they inherit from 424 // the new version of this widget. We're essentially trying to replace one 425 // level in the prototype chain. 426 if ( existingConstructor ) { 427 $.each( existingConstructor._childConstructors, function( i, child ) { 428 var childPrototype = child.prototype; 429 430 // redefine the child widget using the same prototype that was 431 // originally used, but inherit from the new version of the base 432 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 433 }); 434 // remove the list of existing child constructors from the old constructor 435 // so the old child constructors can be garbage collected 436 delete existingConstructor._childConstructors; 437 } else { 438 base._childConstructors.push( constructor ); 439 } 440 441 $.widget.bridge( name, constructor ); 442}; 443 444$.widget.extend = function( target ) { 445 var input = slice.call( arguments, 1 ), 446 inputIndex = 0, 447 inputLength = input.length, 448 key, 449 value; 450 for ( ; inputIndex < inputLength; inputIndex++ ) { 451 for ( key in input[ inputIndex ] ) { 452 value = input[ inputIndex ][ key ]; 453 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 454 // Clone objects 455 if ( $.isPlainObject( value ) ) { 456 target[ key ] = $.isPlainObject( target[ key ] ) ? 457 $.widget.extend( {}, target[ key ], value ) : 458 // Don't extend strings, arrays, etc. with objects 459 $.widget.extend( {}, value ); 460 // Copy everything else by reference 461 } else { 462 target[ key ] = value; 463 } 464 } 465 } 466 } 467 return target; 468}; 469 470$.widget.bridge = function( name, object ) { 471 var fullName = object.prototype.widgetFullName || name; 472 $.fn[ name ] = function( options ) { 473 var isMethodCall = typeof options === "string", 474 args = slice.call( arguments, 1 ), 475 returnValue = this; 476 477 // allow multiple hashes to be passed on init 478 options = !isMethodCall && args.length ? 479 $.widget.extend.apply( null, [ options ].concat(args) ) : 480 options; 481 482 if ( isMethodCall ) { 483 this.each(function() { 484 var methodValue, 485 instance = $.data( this, fullName ); 486 if ( !instance ) { 487 return $.error( "cannot call methods on " + name + " prior to initialization; " + 488 "attempted to call method '" + options + "'" ); 489 } 490 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 491 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 492 } 493 methodValue = instance[ options ].apply( instance, args ); 494 if ( methodValue !== instance && methodValue !== undefined ) { 495 returnValue = methodValue && methodValue.jquery ? 496 returnValue.pushStack( methodValue.get() ) : 497 methodValue; 498 return false; 499 } 500 }); 501 } else { 502 this.each(function() { 503 var instance = $.data( this, fullName ); 504 if ( instance ) { 505 instance.option( options || {} )._init(); 506 } else { 507 $.data( this, fullName, new object( options, this ) ); 508 } 509 }); 510 } 511 512 return returnValue; 513 }; 514}; 515 516$.Widget = function( /* options, element */ ) {}; 517$.Widget._childConstructors = []; 518 519$.Widget.prototype = { 520 widgetName: "widget", 521 widgetEventPrefix: "", 522 defaultElement: "<div>", 523 options: { 524 disabled: false, 525 526 // callbacks 527 create: null 528 }, 529 _createWidget: function( options, element ) { 530 element = $( element || this.defaultElement || this )[ 0 ]; 531 this.element = $( element ); 532 this.uuid = uuid++; 533 this.eventNamespace = "." + this.widgetName + this.uuid; 534 this.options = $.widget.extend( {}, 535 this.options, 536 this._getCreateOptions(), 537 options ); 538 539 this.bindings = $(); 540 this.hoverable = $(); 541 this.focusable = $(); 542 543 if ( element !== this ) { 544 $.data( element, this.widgetFullName, this ); 545 this._on( true, this.element, { 546 remove: function( event ) { 547 if ( event.target === element ) { 548 this.destroy(); 549 } 550 } 551 }); 552 this.document = $( element.style ? 553 // element within the document 554 element.ownerDocument : 555 // element is window or document 556 element.document || element ); 557 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 558 } 559 560 this._create(); 561 this._trigger( "create", null, this._getCreateEventData() ); 562 this._init(); 563 }, 564 _getCreateOptions: $.noop, 565 _getCreateEventData: $.noop, 566 _create: $.noop, 567 _init: $.noop, 568 569 destroy: function() { 570 this._destroy(); 571 // we can probably remove the unbind calls in 2.0 572 // all event bindings should go through this._on() 573 this.element 574 .unbind( this.eventNamespace ) 575 // 1.9 BC for #7810 576 // TODO remove dual storage 577 .removeData( this.widgetName ) 578 .removeData( this.widgetFullName ) 579 // support: jquery <1.6.3 580 // http://bugs.jquery.com/ticket/9413 581 .removeData( $.camelCase( this.widgetFullName ) ); 582 this.widget() 583 .unbind( this.eventNamespace ) 584 .removeAttr( "aria-disabled" ) 585 .removeClass( 586 this.widgetFullName + "-disabled " + 587 "ui-state-disabled" ); 588 589 // clean up events and states 590 this.bindings.unbind( this.eventNamespace ); 591 this.hoverable.removeClass( "ui-state-hover" ); 592 this.focusable.removeClass( "ui-state-focus" ); 593 }, 594 _destroy: $.noop, 595 596 widget: function() { 597 return this.element; 598 }, 599 600 option: function( key, value ) { 601 var options = key, 602 parts, 603 curOption, 604 i; 605 606 if ( arguments.length === 0 ) { 607 // don't return a reference to the internal hash 608 return $.widget.extend( {}, this.options ); 609 } 610 611 if ( typeof key === "string" ) { 612 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 613 options = {}; 614 parts = key.split( "." ); 615 key = parts.shift(); 616 if ( parts.length ) { 617 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 618 for ( i = 0; i < parts.length - 1; i++ ) { 619 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 620 curOption = curOption[ parts[ i ] ]; 621 } 622 key = parts.pop(); 623 if ( arguments.length === 1 ) { 624 return curOption[ key ] === undefined ? null : curOption[ key ]; 625 } 626 curOption[ key ] = value; 627 } else { 628 if ( arguments.length === 1 ) { 629 return this.options[ key ] === undefined ? null : this.options[ key ]; 630 } 631 options[ key ] = value; 632 } 633 } 634 635 this._setOptions( options ); 636 637 return this; 638 }, 639 _setOptions: function( options ) { 640 var key; 641 642 for ( key in options ) { 643 this._setOption( key, options[ key ] ); 644 } 645 646 return this; 647 }, 648 _setOption: function( key, value ) { 649 this.options[ key ] = value; 650 651 if ( key === "disabled" ) { 652 this.widget() 653 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 654 .attr( "aria-disabled", value ); 655 this.hoverable.removeClass( "ui-state-hover" ); 656 this.focusable.removeClass( "ui-state-focus" ); 657 } 658 659 return this; 660 }, 661 662 enable: function() { 663 return this._setOption( "disabled", false ); 664 }, 665 disable: function() { 666 return this._setOption( "disabled", true ); 667 }, 668 669 _on: function( suppressDisabledCheck, element, handlers ) { 670 var delegateElement, 671 instance = this; 672 673 // no suppressDisabledCheck flag, shuffle arguments 674 if ( typeof suppressDisabledCheck !== "boolean" ) { 675 handlers = element; 676 element = suppressDisabledCheck; 677 suppressDisabledCheck = false; 678 } 679 680 // no element argument, shuffle and use this.element 681 if ( !handlers ) { 682 handlers = element; 683 element = this.element; 684 delegateElement = this.widget(); 685 } else { 686 // accept selectors, DOM elements 687 element = delegateElement = $( element ); 688 this.bindings = this.bindings.add( element ); 689 } 690 691 $.each( handlers, function( event, handler ) { 692 function handlerProxy() { 693 // allow widgets to customize the disabled handling 694 // - disabled as an array instead of boolean 695 // - disabled class as method for disabling individual parts 696 if ( !suppressDisabledCheck && 697 ( instance.options.disabled === true || 698 $( this ).hasClass( "ui-state-disabled" ) ) ) { 699 return; 700 } 701 return ( typeof handler === "string" ? instance[ handler ] : handler ) 702 .apply( instance, arguments ); 703 } 704 705 // copy the guid so direct unbinding works 706 if ( typeof handler !== "string" ) { 707 handlerProxy.guid = handler.guid = 708 handler.guid || handlerProxy.guid || $.guid++; 709 } 710 711 var match = event.match( /^(\w+)\s*(.*)$/ ), 712 eventName = match[1] + instance.eventNamespace, 713 selector = match[2]; 714 if ( selector ) { 715 delegateElement.delegate( selector, eventName, handlerProxy ); 716 } else { 717 element.bind( eventName, handlerProxy ); 718 } 719 }); 720 }, 721 722 _off: function( element, eventName ) { 723 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 724 element.unbind( eventName ).undelegate( eventName ); 725 }, 726 727 _delay: function( handler, delay ) { 728 function handlerProxy() { 729 return ( typeof handler === "string" ? instance[ handler ] : handler ) 730 .apply( instance, arguments ); 731 } 732 var instance = this; 733 return setTimeout( handlerProxy, delay || 0 ); 734 }, 735 736 _hoverable: function( element ) { 737 this.hoverable = this.hoverable.add( element ); 738 this._on( element, { 739 mouseenter: function( event ) { 740 $( event.currentTarget ).addClass( "ui-state-hover" ); 741 }, 742 mouseleave: function( event ) { 743 $( event.currentTarget ).removeClass( "ui-state-hover" ); 744 } 745 }); 746 }, 747 748 _focusable: function( element ) { 749 this.focusable = this.focusable.add( element ); 750 this._on( element, { 751 focusin: function( event ) { 752 $( event.currentTarget ).addClass( "ui-state-focus" ); 753 }, 754 focusout: function( event ) { 755 $( event.currentTarget ).removeClass( "ui-state-focus" ); 756 } 757 }); 758 }, 759 760 _trigger: function( type, event, data ) { 761 var prop, orig, 762 callback = this.options[ type ]; 763 764 data = data || {}; 765 event = $.Event( event ); 766 event.type = ( type === this.widgetEventPrefix ? 767 type : 768 this.widgetEventPrefix + type ).toLowerCase(); 769 // the original event may come from any element 770 // so we need to reset the target on the new event 771 event.target = this.element[ 0 ]; 772 773 // copy original event properties over to the new event 774 orig = event.originalEvent; 775 if ( orig ) { 776 for ( prop in orig ) { 777 if ( !( prop in event ) ) { 778 event[ prop ] = orig[ prop ]; 779 } 780 } 781 } 782 783 this.element.trigger( event, data ); 784 return !( $.isFunction( callback ) && 785 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 786 event.isDefaultPrevented() ); 787 } 788}; 789 790$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 791 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 792 if ( typeof options === "string" ) { 793 options = { effect: options }; 794 } 795 var hasOptions, 796 effectName = !options ? 797 method : 798 options === true || typeof options === "number" ? 799 defaultEffect : 800 options.effect || defaultEffect; 801 options = options || {}; 802 if ( typeof options === "number" ) { 803 options = { duration: options }; 804 } 805 hasOptions = !$.isEmptyObject( options ); 806 options.complete = callback; 807 if ( options.delay ) { 808 element.delay( options.delay ); 809 } 810 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 811 element[ method ]( options ); 812 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 113,433 bytes, lines 813-4609
813 element[ effectName ]( options.duration, options.easing, callback ); 814 } else { 815 element.queue(function( next ) { 816 $( this )[ method ](); 817 if ( callback ) { 818 callback.call( element[ 0 ] ); 819 } 820 next(); 821 }); 822 } 823 }; 824}); 825 826})( jQuery ); 827(function( $, undefined ) { 828 829var mouseHandled = false; 830$( document ).mouseup( function() { 831 mouseHandled = false; 832}); 833 834$.widget("ui.mouse", { 835 version: "1.10.4", 836 options: { 837 cancel: "input,textarea,button,select,option", 838 distance: 1, 839 delay: 0 840 }, 841 _mouseInit: function() { 842 var that = this; 843 844 this.element 845 .bind("mousedown."+this.widgetName, function(event) { 846 return that._mouseDown(event); 847 }) 848 .bind("click."+this.widgetName, function(event) { 849 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 850 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 851 event.stopImmediatePropagation(); 852 return false; 853 } 854 }); 855 856 this.started = false; 857 }, 858 859 // TODO: make sure destroying one instance of mouse doesn't mess with 860 // other instances of mouse 861 _mouseDestroy: function() { 862 this.element.unbind("."+this.widgetName); 863 if ( this._mouseMoveDelegate ) { 864 $(document) 865 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 866 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 867 } 868 }, 869 870 _mouseDown: function(event) { 871 // don't let more than one widget handle mouseStart 872 if( mouseHandled ) { return; } 873 874 // we may have missed mouseup (out of window) 875 (this._mouseStarted && this._mouseUp(event)); 876 877 this._mouseDownEvent = event; 878 879 var that = this, 880 btnIsLeft = (event.which === 1), 881 // event.target.nodeName works around a bug in IE 8 with 882 // disabled inputs (#7620) 883 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 884 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 885 return true; 886 } 887 888 this.mouseDelayMet = !this.options.delay; 889 if (!this.mouseDelayMet) { 890 this._mouseDelayTimer = setTimeout(function() { 891 that.mouseDelayMet = true; 892 }, this.options.delay); 893 } 894 895 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 896 this._mouseStarted = (this._mouseStart(event) !== false); 897 if (!this._mouseStarted) { 898 event.preventDefault(); 899 return true; 900 } 901 } 902 903 // Click event may never have fired (Gecko & Opera) 904 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 905 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 906 } 907 908 // these delegates are required to keep context 909 this._mouseMoveDelegate = function(event) { 910 return that._mouseMove(event); 911 }; 912 this._mouseUpDelegate = function(event) { 913 return that._mouseUp(event); 914 }; 915 $(document) 916 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 917 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 918 919 event.preventDefault(); 920 921 mouseHandled = true; 922 return true; 923 }, 924 925 _mouseMove: function(event) { 926 // IE mouseup check - mouseup happened when mouse was out of window 927 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 928 return this._mouseUp(event); 929 } 930 931 if (this._mouseStarted) { 932 this._mouseDrag(event); 933 return event.preventDefault(); 934 } 935 936 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 937 this._mouseStarted = 938 (this._mouseStart(this._mouseDownEvent, event) !== false); 939 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 940 } 941 942 return !this._mouseStarted; 943 }, 944 945 _mouseUp: function(event) { 946 $(document) 947 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 948 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 949 950 if (this._mouseStarted) { 951 this._mouseStarted = false; 952 953 if (event.target === this._mouseDownEvent.target) { 954 $.data(event.target, this.widgetName + ".preventClickEvent", true); 955 } 956 957 this._mouseStop(event); 958 } 959 960 return false; 961 }, 962 963 _mouseDistanceMet: function(event) { 964 return (Math.max( 965 Math.abs(this._mouseDownEvent.pageX - event.pageX), 966 Math.abs(this._mouseDownEvent.pageY - event.pageY) 967 ) >= this.options.distance 968 ); 969 }, 970 971 _mouseDelayMet: function(/* event */) { 972 return this.mouseDelayMet; 973 }, 974 975 // These are placeholder methods, to be overriden by extending plugin 976 _mouseStart: function(/* event */) {}, 977 _mouseDrag: function(/* event */) {}, 978 _mouseStop: function(/* event */) {}, 979 _mouseCapture: function(/* event */) { return true; } 980}); 981 982})(jQuery); 983(function( $, undefined ) { 984 985$.ui = $.ui || {}; 986 987var cachedScrollbarWidth, 988 max = Math.max, 989 abs = Math.abs, 990 round = Math.round, 991 rhorizontal = /left|center|right/, 992 rvertical = /top|center|bottom/, 993 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 994 rposition = /^\w+/, 995 rpercent = /%$/, 996 _position = $.fn.position; 997 998function getOffsets( offsets, width, height ) { 999 return [ 1000 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1001 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1002 ]; 1003} 1004 1005function parseCss( element, property ) { 1006 return parseInt( $.css( element, property ), 10 ) || 0; 1007} 1008 1009function getDimensions( elem ) { 1010 var raw = elem[0]; 1011 if ( raw.nodeType === 9 ) { 1012 return { 1013 width: elem.width(), 1014 height: elem.height(), 1015 offset: { top: 0, left: 0 } 1016 }; 1017 } 1018 if ( $.isWindow( raw ) ) { 1019 return { 1020 width: elem.width(), 1021 height: elem.height(), 1022 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1023 }; 1024 } 1025 if ( raw.preventDefault ) { 1026 return { 1027 width: 0, 1028 height: 0, 1029 offset: { top: raw.pageY, left: raw.pageX } 1030 }; 1031 } 1032 return { 1033 width: elem.outerWidth(), 1034 height: elem.outerHeight(), 1035 offset: elem.offset() 1036 }; 1037} 1038 1039$.position = { 1040 scrollbarWidth: function() { 1041 if ( cachedScrollbarWidth !== undefined ) { 1042 return cachedScrollbarWidth; 1043 } 1044 var w1, w2, 1045 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1046 innerDiv = div.children()[0]; 1047 1048 $( "body" ).append( div ); 1049 w1 = innerDiv.offsetWidth; 1050 div.css( "overflow", "scroll" ); 1051 1052 w2 = innerDiv.offsetWidth; 1053 1054 if ( w1 === w2 ) { 1055 w2 = div[0].clientWidth; 1056 } 1057 1058 div.remove(); 1059 1060 return (cachedScrollbarWidth = w1 - w2); 1061 }, 1062 getScrollInfo: function( within ) { 1063 var overflowX = within.isWindow || within.isDocument ? "" : 1064 within.element.css( "overflow-x" ), 1065 overflowY = within.isWindow || within.isDocument ? "" : 1066 within.element.css( "overflow-y" ), 1067 hasOverflowX = overflowX === "scroll" || 1068 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1069 hasOverflowY = overflowY === "scroll" || 1070 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1071 return { 1072 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1073 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1074 }; 1075 }, 1076 getWithinInfo: function( element ) { 1077 var withinElement = $( element || window ), 1078 isWindow = $.isWindow( withinElement[0] ), 1079 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1080 return { 1081 element: withinElement, 1082 isWindow: isWindow, 1083 isDocument: isDocument, 1084 offset: withinElement.offset() || { left: 0, top: 0 }, 1085 scrollLeft: withinElement.scrollLeft(), 1086 scrollTop: withinElement.scrollTop(), 1087 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1088 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1089 }; 1090 } 1091}; 1092 1093$.fn.position = function( options ) { 1094 if ( !options || !options.of ) { 1095 return _position.apply( this, arguments ); 1096 } 1097 1098 // make a copy, we don't want to modify arguments 1099 options = $.extend( {}, options ); 1100 1101 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1102 target = $( options.of ), 1103 within = $.position.getWithinInfo( options.within ), 1104 scrollInfo = $.position.getScrollInfo( within ), 1105 collision = ( options.collision || "flip" ).split( " " ), 1106 offsets = {}; 1107 1108 dimensions = getDimensions( target ); 1109 if ( target[0].preventDefault ) { 1110 // force left top to allow flipping 1111 options.at = "left top"; 1112 } 1113 targetWidth = dimensions.width; 1114 targetHeight = dimensions.height; 1115 targetOffset = dimensions.offset; 1116 // clone to reuse original targetOffset later 1117 basePosition = $.extend( {}, targetOffset ); 1118 1119 // force my and at to have valid horizontal and vertical positions 1120 // if a value is missing or invalid, it will be converted to center 1121 $.each( [ "my", "at" ], function() { 1122 var pos = ( options[ this ] || "" ).split( " " ), 1123 horizontalOffset, 1124 verticalOffset; 1125 1126 if ( pos.length === 1) { 1127 pos = rhorizontal.test( pos[ 0 ] ) ? 1128 pos.concat( [ "center" ] ) : 1129 rvertical.test( pos[ 0 ] ) ? 1130 [ "center" ].concat( pos ) : 1131 [ "center", "center" ]; 1132 } 1133 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1134 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1135 1136 // calculate offsets 1137 horizontalOffset = roffset.exec( pos[ 0 ] ); 1138 verticalOffset = roffset.exec( pos[ 1 ] ); 1139 offsets[ this ] = [ 1140 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1141 verticalOffset ? verticalOffset[ 0 ] : 0 1142 ]; 1143 1144 // reduce to just the positions without the offsets 1145 options[ this ] = [ 1146 rposition.exec( pos[ 0 ] )[ 0 ], 1147 rposition.exec( pos[ 1 ] )[ 0 ] 1148 ]; 1149 }); 1150 1151 // normalize collision option 1152 if ( collision.length === 1 ) { 1153 collision[ 1 ] = collision[ 0 ]; 1154 } 1155 1156 if ( options.at[ 0 ] === "right" ) { 1157 basePosition.left += targetWidth; 1158 } else if ( options.at[ 0 ] === "center" ) { 1159 basePosition.left += targetWidth / 2; 1160 } 1161 1162 if ( options.at[ 1 ] === "bottom" ) { 1163 basePosition.top += targetHeight; 1164 } else if ( options.at[ 1 ] === "center" ) { 1165 basePosition.top += targetHeight / 2; 1166 } 1167 1168 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1169 basePosition.left += atOffset[ 0 ]; 1170 basePosition.top += atOffset[ 1 ]; 1171 1172 return this.each(function() { 1173 var collisionPosition, using, 1174 elem = $( this ), 1175 elemWidth = elem.outerWidth(), 1176 elemHeight = elem.outerHeight(), 1177 marginLeft = parseCss( this, "marginLeft" ), 1178 marginTop = parseCss( this, "marginTop" ), 1179 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1180 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1181 position = $.extend( {}, basePosition ), 1182 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1183 1184 if ( options.my[ 0 ] === "right" ) { 1185 position.left -= elemWidth; 1186 } else if ( options.my[ 0 ] === "center" ) { 1187 position.left -= elemWidth / 2; 1188 } 1189 1190 if ( options.my[ 1 ] === "bottom" ) { 1191 position.top -= elemHeight; 1192 } else if ( options.my[ 1 ] === "center" ) { 1193 position.top -= elemHeight / 2; 1194 } 1195 1196 position.left += myOffset[ 0 ]; 1197 position.top += myOffset[ 1 ]; 1198 1199 // if the browser doesn't support fractions, then round for consistent results 1200 if ( !$.support.offsetFractions ) { 1201 position.left = round( position.left ); 1202 position.top = round( position.top ); 1203 } 1204 1205 collisionPosition = { 1206 marginLeft: marginLeft, 1207 marginTop: marginTop 1208 }; 1209 1210 $.each( [ "left", "top" ], function( i, dir ) { 1211 if ( $.ui.position[ collision[ i ] ] ) { 1212 $.ui.position[ collision[ i ] ][ dir ]( position, { 1213 targetWidth: targetWidth, 1214 targetHeight: targetHeight, 1215 elemWidth: elemWidth, 1216 elemHeight: elemHeight, 1217 collisionPosition: collisionPosition, 1218 collisionWidth: collisionWidth, 1219 collisionHeight: collisionHeight, 1220 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1221 my: options.my, 1222 at: options.at, 1223 within: within, 1224 elem : elem 1225 }); 1226 } 1227 }); 1228 1229 if ( options.using ) { 1230 // adds feedback as second argument to using callback, if present 1231 using = function( props ) { 1232 var left = targetOffset.left - position.left, 1233 right = left + targetWidth - elemWidth, 1234 top = targetOffset.top - position.top, 1235 bottom = top + targetHeight - elemHeight, 1236 feedback = { 1237 target: { 1238 element: target, 1239 left: targetOffset.left, 1240 top: targetOffset.top, 1241 width: targetWidth, 1242 height: targetHeight 1243 }, 1244 element: { 1245 element: elem, 1246 left: position.left, 1247 top: position.top, 1248 width: elemWidth, 1249 height: elemHeight 1250 }, 1251 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1252 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1253 }; 1254 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1255 feedback.horizontal = "center"; 1256 } 1257 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1258 feedback.vertical = "middle"; 1259 } 1260 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1261 feedback.important = "horizontal"; 1262 } else { 1263 feedback.important = "vertical"; 1264 } 1265 options.using.call( this, props, feedback ); 1266 }; 1267 } 1268 1269 elem.offset( $.extend( position, { using: using } ) ); 1270 }); 1271}; 1272 1273$.ui.position = { 1274 fit: { 1275 left: function( position, data ) { 1276 var within = data.within, 1277 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1278 outerWidth = within.width, 1279 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1280 overLeft = withinOffset - collisionPosLeft, 1281 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1282 newOverRight; 1283 1284 // element is wider than within 1285 if ( data.collisionWidth > outerWidth ) { 1286 // element is initially over the left side of within 1287 if ( overLeft > 0 && overRight <= 0 ) { 1288 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1289 position.left += overLeft - newOverRight; 1290 // element is initially over right side of within 1291 } else if ( overRight > 0 && overLeft <= 0 ) { 1292 position.left = withinOffset; 1293 // element is initially over both left and right sides of within 1294 } else { 1295 if ( overLeft > overRight ) { 1296 position.left = withinOffset + outerWidth - data.collisionWidth; 1297 } else { 1298 position.left = withinOffset; 1299 } 1300 } 1301 // too far left -> align with left edge 1302 } else if ( overLeft > 0 ) { 1303 position.left += overLeft; 1304 // too far right -> align with right edge 1305 } else if ( overRight > 0 ) { 1306 position.left -= overRight; 1307 // adjust based on position and margin 1308 } else { 1309 position.left = max( position.left - collisionPosLeft, position.left ); 1310 } 1311 }, 1312 top: function( position, data ) { 1313 var within = data.within, 1314 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1315 outerHeight = data.within.height, 1316 collisionPosTop = position.top - data.collisionPosition.marginTop, 1317 overTop = withinOffset - collisionPosTop, 1318 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1319 newOverBottom; 1320 1321 // element is taller than within 1322 if ( data.collisionHeight > outerHeight ) { 1323 // element is initially over the top of within 1324 if ( overTop > 0 && overBottom <= 0 ) { 1325 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1326 position.top += overTop - newOverBottom; 1327 // element is initially over bottom of within 1328 } else if ( overBottom > 0 && overTop <= 0 ) { 1329 position.top = withinOffset; 1330 // element is initially over both top and bottom of within 1331 } else { 1332 if ( overTop > overBottom ) { 1333 position.top = withinOffset + outerHeight - data.collisionHeight; 1334 } else { 1335 position.top = withinOffset; 1336 } 1337 } 1338 // too far up -> align with top 1339 } else if ( overTop > 0 ) { 1340 position.top += overTop; 1341 // too far down -> align with bottom edge 1342 } else if ( overBottom > 0 ) { 1343 position.top -= overBottom; 1344 // adjust based on position and margin 1345 } else { 1346 position.top = max( position.top - collisionPosTop, position.top ); 1347 } 1348 } 1349 }, 1350 flip: { 1351 left: function( position, data ) { 1352 var within = data.within, 1353 withinOffset = within.offset.left + within.scrollLeft, 1354 outerWidth = within.width, 1355 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1356 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1357 overLeft = collisionPosLeft - offsetLeft, 1358 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1359 myOffset = data.my[ 0 ] === "left" ? 1360 -data.elemWidth : 1361 data.my[ 0 ] === "right" ? 1362 data.elemWidth : 1363 0, 1364 atOffset = data.at[ 0 ] === "left" ? 1365 data.targetWidth : 1366 data.at[ 0 ] === "right" ? 1367 -data.targetWidth : 1368 0, 1369 offset = -2 * data.offset[ 0 ], 1370 newOverRight, 1371 newOverLeft; 1372 1373 if ( overLeft < 0 ) { 1374 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1375 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1376 position.left += myOffset + atOffset + offset; 1377 } 1378 } 1379 else if ( overRight > 0 ) { 1380 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1381 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1382 position.left += myOffset + atOffset + offset; 1383 } 1384 } 1385 }, 1386 top: function( position, data ) { 1387 var within = data.within, 1388 withinOffset = within.offset.top + within.scrollTop, 1389 outerHeight = within.height, 1390 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1391 collisionPosTop = position.top - data.collisionPosition.marginTop, 1392 overTop = collisionPosTop - offsetTop, 1393 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1394 top = data.my[ 1 ] === "top", 1395 myOffset = top ? 1396 -data.elemHeight : 1397 data.my[ 1 ] === "bottom" ? 1398 data.elemHeight : 1399 0, 1400 atOffset = data.at[ 1 ] === "top" ? 1401 data.targetHeight : 1402 data.at[ 1 ] === "bottom" ? 1403 -data.targetHeight : 1404 0, 1405 offset = -2 * data.offset[ 1 ], 1406 newOverTop, 1407 newOverBottom; 1408 if ( overTop < 0 ) { 1409 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1410 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1411 position.top += myOffset + atOffset + offset; 1412 } 1413 } 1414 else if ( overBottom > 0 ) { 1415 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1416 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1417 position.top += myOffset + atOffset + offset; 1418 } 1419 } 1420 } 1421 }, 1422 flipfit: { 1423 left: function() { 1424 $.ui.position.flip.left.apply( this, arguments ); 1425 $.ui.position.fit.left.apply( this, arguments ); 1426 }, 1427 top: function() { 1428 $.ui.position.flip.top.apply( this, arguments ); 1429 $.ui.position.fit.top.apply( this, arguments ); 1430 } 1431 } 1432}; 1433 1434// fraction support test 1435(function () { 1436 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1437 body = document.getElementsByTagName( "body" )[ 0 ], 1438 div = document.createElement( "div" ); 1439 1440 //Create a "fake body" for testing based on method used in jQuery.support 1441 testElement = document.createElement( body ? "div" : "body" ); 1442 testElementStyle = { 1443 visibility: "hidden", 1444 width: 0, 1445 height: 0, 1446 border: 0, 1447 margin: 0, 1448 background: "none" 1449 }; 1450 if ( body ) { 1451 $.extend( testElementStyle, { 1452 position: "absolute", 1453 left: "-1000px", 1454 top: "-1000px" 1455 }); 1456 } 1457 for ( i in testElementStyle ) { 1458 testElement.style[ i ] = testElementStyle[ i ]; 1459 } 1460 testElement.appendChild( div ); 1461 testElementParent = body || document.documentElement; 1462 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1463 1464 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1465 1466 offsetLeft = $( div ).offset().left; 1467 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1468 1469 testElement.innerHTML = ""; 1470 testElementParent.removeChild( testElement ); 1471})(); 1472 1473}( jQuery ) ); 1474(function( $, undefined ) { 1475 1476$.widget("ui.draggable", $.ui.mouse, { 1477 version: "1.10.4", 1478 widgetEventPrefix: "drag", 1479 options: { 1480 addClasses: true, 1481 appendTo: "parent", 1482 axis: false, 1483 connectToSortable: false, 1484 containment: false, 1485 cursor: "auto", 1486 cursorAt: false, 1487 grid: false, 1488 handle: false, 1489 helper: "original", 1490 iframeFix: false, 1491 opacity: false, 1492 refreshPositions: false, 1493 revert: false, 1494 revertDuration: 500, 1495 scope: "default", 1496 scroll: true, 1497 scrollSensitivity: 20, 1498 scrollSpeed: 20, 1499 snap: false, 1500 snapMode: "both", 1501 snapTolerance: 20, 1502 stack: false, 1503 zIndex: false, 1504 1505 // callbacks 1506 drag: null, 1507 start: null, 1508 stop: null 1509 }, 1510 _create: function() { 1511 1512 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1513 this.element[0].style.position = "relative"; 1514 } 1515 if (this.options.addClasses){ 1516 this.element.addClass("ui-draggable"); 1517 } 1518 if (this.options.disabled){ 1519 this.element.addClass("ui-draggable-disabled"); 1520 } 1521 1522 this._mouseInit(); 1523 1524 }, 1525 1526 _destroy: function() { 1527 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1528 this._mouseDestroy(); 1529 }, 1530 1531 _mouseCapture: function(event) { 1532 1533 var o = this.options; 1534 1535 // among others, prevent a drag on a resizable-handle 1536 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1537 return false; 1538 } 1539 1540 //Quit if we're not on a valid handle 1541 this.handle = this._getHandle(event); 1542 if (!this.handle) { 1543 return false; 1544 } 1545 1546 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1547 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1548 .css({ 1549 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1550 position: "absolute", opacity: "0.001", zIndex: 1000 1551 }) 1552 .css($(this).offset()) 1553 .appendTo("body"); 1554 }); 1555 1556 return true; 1557 1558 }, 1559 1560 _mouseStart: function(event) { 1561 1562 var o = this.options; 1563 1564 //Create and append the visible helper 1565 this.helper = this._createHelper(event); 1566 1567 this.helper.addClass("ui-draggable-dragging"); 1568 1569 //Cache the helper size 1570 this._cacheHelperProportions(); 1571 1572 //If ddmanager is used for droppables, set the global draggable 1573 if($.ui.ddmanager) { 1574 $.ui.ddmanager.current = this; 1575 } 1576 1577 /* 1578 * - Position generation - 1579 * This block generates everything position related - it's the core of draggables. 1580 */ 1581 1582 //Cache the margins of the original element 1583 this._cacheMargins(); 1584 1585 //Store the helper's css position 1586 this.cssPosition = this.helper.css( "position" ); 1587 this.scrollParent = this.helper.scrollParent(); 1588 this.offsetParent = this.helper.offsetParent(); 1589 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 1590 1591 //The element's absolute position on the page minus margins 1592 this.offset = this.positionAbs = this.element.offset(); 1593 this.offset = { 1594 top: this.offset.top - this.margins.top, 1595 left: this.offset.left - this.margins.left 1596 }; 1597 1598 //Reset scroll cache 1599 this.offset.scroll = false; 1600 1601 $.extend(this.offset, { 1602 click: { //Where the click happened, relative to the element 1603 left: event.pageX - this.offset.left, 1604 top: event.pageY - this.offset.top 1605 }, 1606 parent: this._getParentOffset(), 1607 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1608 }); 1609 1610 //Generate the original position 1611 this.originalPosition = this.position = this._generatePosition(event); 1612 this.originalPageX = event.pageX; 1613 this.originalPageY = event.pageY; 1614 1615 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1616 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1617 1618 //Set a containment if given in the options 1619 this._setContainment(); 1620 1621 //Trigger event + callbacks 1622 if(this._trigger("start", event) === false) { 1623 this._clear(); 1624 return false; 1625 } 1626 1627 //Recache the helper size 1628 this._cacheHelperProportions(); 1629 1630 //Prepare the droppable offsets 1631 if ($.ui.ddmanager && !o.dropBehaviour) { 1632 $.ui.ddmanager.prepareOffsets(this, event); 1633 } 1634 1635 1636 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1637 1638 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1639 if ( $.ui.ddmanager ) { 1640 $.ui.ddmanager.dragStart(this, event); 1641 } 1642 1643 return true; 1644 }, 1645 1646 _mouseDrag: function(event, noPropagation) { 1647 // reset any necessary cached properties (see #5009) 1648 if ( this.offsetParentCssPosition === "fixed" ) { 1649 this.offset.parent = this._getParentOffset(); 1650 } 1651 1652 //Compute the helpers position 1653 this.position = this._generatePosition(event); 1654 this.positionAbs = this._convertPositionTo("absolute"); 1655 1656 //Call plugins and callbacks and use the resulting position if something is returned 1657 if (!noPropagation) { 1658 var ui = this._uiHash(); 1659 if(this._trigger("drag", event, ui) === false) { 1660 this._mouseUp({}); 1661 return false; 1662 } 1663 this.position = ui.position; 1664 } 1665 1666 if(!this.options.axis || this.options.axis !== "y") { 1667 this.helper[0].style.left = this.position.left+"px"; 1668 } 1669 if(!this.options.axis || this.options.axis !== "x") { 1670 this.helper[0].style.top = this.position.top+"px"; 1671 } 1672 if($.ui.ddmanager) { 1673 $.ui.ddmanager.drag(this, event); 1674 } 1675 1676 return false; 1677 }, 1678 1679 _mouseStop: function(event) { 1680 1681 //If we are using droppables, inform the manager about the drop 1682 var that = this, 1683 dropped = false; 1684 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1685 dropped = $.ui.ddmanager.drop(this, event); 1686 } 1687 1688 //if a drop comes from outside (a sortable) 1689 if(this.dropped) { 1690 dropped = this.dropped; 1691 this.dropped = false; 1692 } 1693 1694 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1695 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { 1696 return false; 1697 } 1698 1699 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))) { 1700 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1701 if(that._trigger("stop", event) !== false) { 1702 that._clear(); 1703 } 1704 }); 1705 } else { 1706 if(this._trigger("stop", event) !== false) { 1707 this._clear(); 1708 } 1709 } 1710 1711 return false; 1712 }, 1713 1714 _mouseUp: function(event) { 1715 //Remove frame helpers 1716 $("div.ui-draggable-iframeFix").each(function() { 1717 this.parentNode.removeChild(this); 1718 }); 1719 1720 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1721 if( $.ui.ddmanager ) { 1722 $.ui.ddmanager.dragStop(this, event); 1723 } 1724 1725 return $.ui.mouse.prototype._mouseUp.call(this, event); 1726 }, 1727 1728 cancel: function() { 1729 1730 if(this.helper.is(".ui-draggable-dragging")) { 1731 this._mouseUp({}); 1732 } else { 1733 this._clear(); 1734 } 1735 1736 return this; 1737 1738 }, 1739 1740 _getHandle: function(event) { 1741 return this.options.handle ? 1742 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1743 true; 1744 }, 1745 1746 _createHelper: function(event) { 1747 1748 var o = this.options, 1749 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1750 1751 if(!helper.parents("body").length) { 1752 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1753 } 1754 1755 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1756 helper.css("position", "absolute"); 1757 } 1758 1759 return helper; 1760 1761 }, 1762 1763 _adjustOffsetFromHelper: function(obj) { 1764 if (typeof obj === "string") { 1765 obj = obj.split(" "); 1766 } 1767 if ($.isArray(obj)) { 1768 obj = {left: +obj[0], top: +obj[1] || 0}; 1769 } 1770 if ("left" in obj) { 1771 this.offset.click.left = obj.left + this.margins.left; 1772 } 1773 if ("right" in obj) { 1774 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1775 } 1776 if ("top" in obj) { 1777 this.offset.click.top = obj.top + this.margins.top; 1778 } 1779 if ("bottom" in obj) { 1780 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1781 } 1782 }, 1783 1784 _getParentOffset: function() { 1785 1786 //Get the offsetParent and cache its position 1787 var po = this.offsetParent.offset(); 1788 1789 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1790 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1791 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1792 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1793 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1794 po.left += this.scrollParent.scrollLeft(); 1795 po.top += this.scrollParent.scrollTop(); 1796 } 1797 1798 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1799 //Ugly IE fix 1800 if((this.offsetParent[0] === document.body) || 1801 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1802 po = { top: 0, left: 0 }; 1803 } 1804 1805 return { 1806 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 1807 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1808 }; 1809 1810 }, 1811 1812 _getRelativeOffset: function() { 1813 1814 if(this.cssPosition === "relative") { 1815 var p = this.element.position(); 1816 return { 1817 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1818 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1819 }; 1820 } else { 1821 return { top: 0, left: 0 }; 1822 } 1823 1824 }, 1825 1826 _cacheMargins: function() { 1827 this.margins = { 1828 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1829 top: (parseInt(this.element.css("marginTop"),10) || 0), 1830 right: (parseInt(this.element.css("marginRight"),10) || 0), 1831 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1832 }; 1833 }, 1834 1835 _cacheHelperProportions: function() { 1836 this.helperProportions = { 1837 width: this.helper.outerWidth(), 1838 height: this.helper.outerHeight() 1839 }; 1840 }, 1841 1842 _setContainment: function() { 1843 1844 var over, c, ce, 1845 o = this.options; 1846 1847 if ( !o.containment ) { 1848 this.containment = null; 1849 return; 1850 } 1851 1852 if ( o.containment === "window" ) { 1853 this.containment = [ 1854 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1855 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1856 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 1857 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1858 ]; 1859 return; 1860 } 1861 1862 if ( o.containment === "document") { 1863 this.containment = [ 1864 0, 1865 0, 1866 $( document ).width() - this.helperProportions.width - this.margins.left, 1867 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1868 ]; 1869 return; 1870 } 1871 1872 if ( o.containment.constructor === Array ) { 1873 this.containment = o.containment; 1874 return; 1875 } 1876 1877 if ( o.containment === "parent" ) { 1878 o.containment = this.helper[ 0 ].parentNode; 1879 } 1880 1881 c = $( o.containment ); 1882 ce = c[ 0 ]; 1883 1884 if( !ce ) { 1885 return; 1886 } 1887 1888 over = c.css( "overflow" ) !== "hidden"; 1889 1890 this.containment = [ 1891 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 1892 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , 1893 ( 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, 1894 ( 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 1895 ]; 1896 this.relative_container = c; 1897 }, 1898 1899 _convertPositionTo: function(d, pos) { 1900 1901 if(!pos) { 1902 pos = this.position; 1903 } 1904 1905 var mod = d === "absolute" ? 1 : -1, 1906 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; 1907 1908 //Cache the scroll 1909 if (!this.offset.scroll) { 1910 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1911 } 1912 1913 return { 1914 top: ( 1915 pos.top + // The absolute mouse position 1916 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1917 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1918 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) 1919 ), 1920 left: ( 1921 pos.left + // The absolute mouse position 1922 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1923 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1924 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) 1925 ) 1926 }; 1927 1928 }, 1929 1930 _generatePosition: function(event) { 1931 1932 var containment, co, top, left, 1933 o = this.options, 1934 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, 1935 pageX = event.pageX, 1936 pageY = event.pageY; 1937 1938 //Cache the scroll 1939 if (!this.offset.scroll) { 1940 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1941 } 1942 1943 /* 1944 * - Position constraining - 1945 * Constrain the position to a mix of grid, containment. 1946 */ 1947 1948 // If we are not dragging yet, we won't check for options 1949 if ( this.originalPosition ) { 1950 if ( this.containment ) { 1951 if ( this.relative_container ){ 1952 co = this.relative_container.offset(); 1953 containment = [ 1954 this.containment[ 0 ] + co.left, 1955 this.containment[ 1 ] + co.top, 1956 this.containment[ 2 ] + co.left, 1957 this.containment[ 3 ] + co.top 1958 ]; 1959 } 1960 else { 1961 containment = this.containment; 1962 } 1963 1964 if(event.pageX - this.offset.click.left < containment[0]) { 1965 pageX = containment[0] + this.offset.click.left; 1966 } 1967 if(event.pageY - this.offset.click.top < containment[1]) { 1968 pageY = containment[1] + this.offset.click.top; 1969 } 1970 if(event.pageX - this.offset.click.left > containment[2]) { 1971 pageX = containment[2] + this.offset.click.left; 1972 } 1973 if(event.pageY - this.offset.click.top > containment[3]) { 1974 pageY = containment[3] + this.offset.click.top; 1975 } 1976 } 1977 1978 if(o.grid) { 1979 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1980 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1981 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; 1982 1983 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1984 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; 1985 } 1986 1987 } 1988 1989 return { 1990 top: ( 1991 pageY - // The absolute mouse position 1992 this.offset.click.top - // Click offset (relative to the element) 1993 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1994 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1995 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) 1996 ), 1997 left: ( 1998 pageX - // The absolute mouse position 1999 this.offset.click.left - // Click offset (relative to the element) 2000 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 2001 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 2002 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) 2003 ) 2004 }; 2005 2006 }, 2007 2008 _clear: function() { 2009 this.helper.removeClass("ui-draggable-dragging"); 2010 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 2011 this.helper.remove(); 2012 } 2013 this.helper = null; 2014 this.cancelHelperRemoval = false; 2015 }, 2016 2017 // From now on bulk stuff - mainly helpers 2018 2019 _trigger: function(type, event, ui) { 2020 ui = ui || this._uiHash(); 2021 $.ui.plugin.call(this, type, [event, ui]); 2022 //The absolute position has to be recalculated after plugins 2023 if(type === "drag") { 2024 this.positionAbs = this._convertPositionTo("absolute"); 2025 } 2026 return $.Widget.prototype._trigger.call(this, type, event, ui); 2027 }, 2028 2029 plugins: {}, 2030 2031 _uiHash: function() { 2032 return { 2033 helper: this.helper, 2034 position: this.position, 2035 originalPosition: this.originalPosition, 2036 offset: this.positionAbs 2037 }; 2038 } 2039 2040}); 2041 2042$.ui.plugin.add("draggable", "connectToSortable", { 2043 start: function(event, ui) { 2044 2045 var inst = $(this).data("ui-draggable"), o = inst.options, 2046 uiSortable = $.extend({}, ui, { item: inst.element }); 2047 inst.sortables = []; 2048 $(o.connectToSortable).each(function() { 2049 var sortable = $.data(this, "ui-sortable"); 2050 if (sortable && !sortable.options.disabled) { 2051 inst.sortables.push({ 2052 instance: sortable, 2053 shouldRevert: sortable.options.revert 2054 }); 2055 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). 2056 sortable._trigger("activate", event, uiSortable); 2057 } 2058 }); 2059 2060 }, 2061 stop: function(event, ui) { 2062 2063 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2064 var inst = $(this).data("ui-draggable"), 2065 uiSortable = $.extend({}, ui, { item: inst.element }); 2066 2067 $.each(inst.sortables, function() { 2068 if(this.instance.isOver) { 2069 2070 this.instance.isOver = 0; 2071 2072 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2073 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2074 2075 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 2076 if(this.shouldRevert) { 2077 this.instance.options.revert = this.shouldRevert; 2078 } 2079 2080 //Trigger the stop of the sortable 2081 this.instance._mouseStop(event); 2082 2083 this.instance.options.helper = this.instance.options._helper; 2084 2085 //If the helper has been the original item, restore properties in the sortable 2086 if(inst.options.helper === "original") { 2087 this.instance.currentItem.css({ top: "auto", left: "auto" }); 2088 } 2089 2090 } else { 2091 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2092 this.instance._trigger("deactivate", event, uiSortable); 2093 } 2094 2095 }); 2096 2097 }, 2098 drag: function(event, ui) { 2099 2100 var inst = $(this).data("ui-draggable"), that = this; 2101 2102 $.each(inst.sortables, function() { 2103 2104 var innermostIntersecting = false, 2105 thisSortable = this; 2106 2107 //Copy over some variables to allow calling the sortable's native _intersectsWith 2108 this.instance.positionAbs = inst.positionAbs; 2109 this.instance.helperProportions = inst.helperProportions; 2110 this.instance.offset.click = inst.offset.click; 2111 2112 if(this.instance._intersectsWith(this.instance.containerCache)) { 2113 innermostIntersecting = true; 2114 $.each(inst.sortables, function () { 2115 this.instance.positionAbs = inst.positionAbs; 2116 this.instance.helperProportions = inst.helperProportions; 2117 this.instance.offset.click = inst.offset.click; 2118 if (this !== thisSortable && 2119 this.instance._intersectsWith(this.instance.containerCache) && 2120 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 2121 ) { 2122 innermostIntersecting = false; 2123 } 2124 return innermostIntersecting; 2125 }); 2126 } 2127 2128 2129 if(innermostIntersecting) { 2130 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 2131 if(!this.instance.isOver) { 2132 2133 this.instance.isOver = 1; 2134 //Now we fake the start of dragging for the sortable instance, 2135 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 2136 //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) 2137 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 2138 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 2139 this.instance.options.helper = function() { return ui.helper[0]; }; 2140 2141 event.target = this.instance.currentItem[0]; 2142 this.instance._mouseCapture(event, true); 2143 this.instance._mouseStart(event, true, true); 2144 2145 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 2146 this.instance.offset.click.top = inst.offset.click.top; 2147 this.instance.offset.click.left = inst.offset.click.left; 2148 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 2149 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 2150 2151 inst._trigger("toSortable", event); 2152 inst.dropped = this.instance.element; //draggable revert needs that 2153 //hack so receive/update callbacks work (mostly) 2154 inst.currentItem = inst.element; 2155 this.instance.fromOutside = inst; 2156 2157 } 2158 2159 //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 2160 if(this.instance.currentItem) { 2161 this.instance._mouseDrag(event); 2162 } 2163 2164 } else { 2165 2166 //If it doesn't intersect with the sortable, and it intersected before, 2167 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2168 if(this.instance.isOver) { 2169 2170 this.instance.isOver = 0; 2171 this.instance.cancelHelperRemoval = true; 2172 2173 //Prevent reverting on this forced stop 2174 this.instance.options.revert = false; 2175 2176 // The out event needs to be triggered independently 2177 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 2178 2179 this.instance._mouseStop(event, true); 2180 this.instance.options.helper = this.instance.options._helper; 2181 2182 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2183 this.instance.currentItem.remove(); 2184 if(this.instance.placeholder) { 2185 this.instance.placeholder.remove(); 2186 } 2187 2188 inst._trigger("fromSortable", event); 2189 inst.dropped = false; //draggable revert needs that 2190 } 2191 2192 } 2193 2194 }); 2195 2196 } 2197}); 2198 2199$.ui.plugin.add("draggable", "cursor", { 2200 start: function() { 2201 var t = $("body"), o = $(this).data("ui-draggable").options; 2202 if (t.css("cursor")) { 2203 o._cursor = t.css("cursor"); 2204 } 2205 t.css("cursor", o.cursor); 2206 }, 2207 stop: function() { 2208 var o = $(this).data("ui-draggable").options; 2209 if (o._cursor) { 2210 $("body").css("cursor", o._cursor); 2211 } 2212 } 2213}); 2214 2215$.ui.plugin.add("draggable", "opacity", { 2216 start: function(event, ui) { 2217 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2218 if(t.css("opacity")) { 2219 o._opacity = t.css("opacity"); 2220 } 2221 t.css("opacity", o.opacity); 2222 }, 2223 stop: function(event, ui) { 2224 var o = $(this).data("ui-draggable").options; 2225 if(o._opacity) { 2226 $(ui.helper).css("opacity", o._opacity); 2227 } 2228 } 2229}); 2230 2231$.ui.plugin.add("draggable", "scroll", { 2232 start: function() { 2233 var i = $(this).data("ui-draggable"); 2234 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2235 i.overflowOffset = i.scrollParent.offset(); 2236 } 2237 }, 2238 drag: function( event ) { 2239 2240 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 2241 2242 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2243 2244 if(!o.axis || o.axis !== "x") { 2245 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 2246 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 2247 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 2248 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 2249 } 2250 } 2251 2252 if(!o.axis || o.axis !== "y") { 2253 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 2254 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 2255 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 2256 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 2257 } 2258 } 2259 2260 } else { 2261 2262 if(!o.axis || o.axis !== "x") { 2263 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 2264 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2265 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 2266 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2267 } 2268 } 2269 2270 if(!o.axis || o.axis !== "y") { 2271 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 2272 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2273 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 2274 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2275 } 2276 } 2277 2278 } 2279 2280 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 2281 $.ui.ddmanager.prepareOffsets(i, event); 2282 } 2283 2284 } 2285}); 2286 2287$.ui.plugin.add("draggable", "snap", { 2288 start: function() { 2289 2290 var i = $(this).data("ui-draggable"), 2291 o = i.options; 2292 2293 i.snapElements = []; 2294 2295 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 2296 var $t = $(this), 2297 $o = $t.offset(); 2298 if(this !== i.element[0]) { 2299 i.snapElements.push({ 2300 item: this, 2301 width: $t.outerWidth(), height: $t.outerHeight(), 2302 top: $o.top, left: $o.left 2303 }); 2304 } 2305 }); 2306 2307 }, 2308 drag: function(event, ui) { 2309 2310 var ts, bs, ls, rs, l, r, t, b, i, first, 2311 inst = $(this).data("ui-draggable"), 2312 o = inst.options, 2313 d = o.snapTolerance, 2314 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2315 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2316 2317 for (i = inst.snapElements.length - 1; i >= 0; i--){ 2318 2319 l = inst.snapElements[i].left; 2320 r = l + inst.snapElements[i].width; 2321 t = inst.snapElements[i].top; 2322 b = t + inst.snapElements[i].height; 2323 2324 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 2325 if(inst.snapElements[i].snapping) { 2326 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2327 } 2328 inst.snapElements[i].snapping = false; 2329 continue; 2330 } 2331 2332 if(o.snapMode !== "inner") { 2333 ts = Math.abs(t - y2) <= d; 2334 bs = Math.abs(b - y1) <= d; 2335 ls = Math.abs(l - x2) <= d; 2336 rs = Math.abs(r - x1) <= d; 2337 if(ts) { 2338 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2339 } 2340 if(bs) { 2341 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2342 } 2343 if(ls) { 2344 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2345 } 2346 if(rs) { 2347 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2348 } 2349 } 2350 2351 first = (ts || bs || ls || rs); 2352 2353 if(o.snapMode !== "outer") { 2354 ts = Math.abs(t - y1) <= d; 2355 bs = Math.abs(b - y2) <= d; 2356 ls = Math.abs(l - x1) <= d; 2357 rs = Math.abs(r - x2) <= d; 2358 if(ts) { 2359 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2360 } 2361 if(bs) { 2362 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2363 } 2364 if(ls) { 2365 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2366 } 2367 if(rs) { 2368 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2369 } 2370 } 2371 2372 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 2373 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2374 } 2375 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2376 2377 } 2378 2379 } 2380}); 2381 2382$.ui.plugin.add("draggable", "stack", { 2383 start: function() { 2384 var min, 2385 o = this.data("ui-draggable").options, 2386 group = $.makeArray($(o.stack)).sort(function(a,b) { 2387 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 2388 }); 2389 2390 if (!group.length) { return; } 2391 2392 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 2393 $(group).each(function(i) { 2394 $(this).css("zIndex", min + i); 2395 }); 2396 this.css("zIndex", (min + group.length)); 2397 } 2398}); 2399 2400$.ui.plugin.add("draggable", "zIndex", { 2401 start: function(event, ui) { 2402 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2403 if(t.css("zIndex")) { 2404 o._zIndex = t.css("zIndex"); 2405 } 2406 t.css("zIndex", o.zIndex); 2407 }, 2408 stop: function(event, ui) { 2409 var o = $(this).data("ui-draggable").options; 2410 if(o._zIndex) { 2411 $(ui.helper).css("zIndex", o._zIndex); 2412 } 2413 } 2414}); 2415 2416})(jQuery); 2417(function( $, undefined ) { 2418 2419function isOverAxis( x, reference, size ) { 2420 return ( x > reference ) && ( x < ( reference + size ) ); 2421} 2422 2423$.widget("ui.droppable", { 2424 version: "1.10.4", 2425 widgetEventPrefix: "drop", 2426 options: { 2427 accept: "*", 2428 activeClass: false, 2429 addClasses: true, 2430 greedy: false, 2431 hoverClass: false, 2432 scope: "default", 2433 tolerance: "intersect", 2434 2435 // callbacks 2436 activate: null, 2437 deactivate: null, 2438 drop: null, 2439 out: null, 2440 over: null 2441 }, 2442 _create: function() { 2443 2444 var proportions, 2445 o = this.options, 2446 accept = o.accept; 2447 2448 this.isover = false; 2449 this.isout = true; 2450 2451 this.accept = $.isFunction(accept) ? accept : function(d) { 2452 return d.is(accept); 2453 }; 2454 2455 this.proportions = function( /* valueToWrite */ ) { 2456 if ( arguments.length ) { 2457 // Store the droppable's proportions 2458 proportions = arguments[ 0 ]; 2459 } else { 2460 // Retrieve or derive the droppable's proportions 2461 return proportions ? 2462 proportions : 2463 proportions = { 2464 width: this.element[ 0 ].offsetWidth, 2465 height: this.element[ 0 ].offsetHeight 2466 }; 2467 } 2468 }; 2469 2470 // Add the reference and positions to the manager 2471 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 2472 $.ui.ddmanager.droppables[o.scope].push(this); 2473 2474 (o.addClasses && this.element.addClass("ui-droppable")); 2475 2476 }, 2477 2478 _destroy: function() { 2479 var i = 0, 2480 drop = $.ui.ddmanager.droppables[this.options.scope]; 2481 2482 for ( ; i < drop.length; i++ ) { 2483 if ( drop[i] === this ) { 2484 drop.splice(i, 1); 2485 } 2486 } 2487 2488 this.element.removeClass("ui-droppable ui-droppable-disabled"); 2489 }, 2490 2491 _setOption: function(key, value) { 2492 2493 if(key === "accept") { 2494 this.accept = $.isFunction(value) ? value : function(d) { 2495 return d.is(value); 2496 }; 2497 } 2498 $.Widget.prototype._setOption.apply(this, arguments); 2499 }, 2500 2501 _activate: function(event) { 2502 var draggable = $.ui.ddmanager.current; 2503 if(this.options.activeClass) { 2504 this.element.addClass(this.options.activeClass); 2505 } 2506 if(draggable){ 2507 this._trigger("activate", event, this.ui(draggable)); 2508 } 2509 }, 2510 2511 _deactivate: function(event) { 2512 var draggable = $.ui.ddmanager.current; 2513 if(this.options.activeClass) { 2514 this.element.removeClass(this.options.activeClass); 2515 } 2516 if(draggable){ 2517 this._trigger("deactivate", event, this.ui(draggable)); 2518 } 2519 }, 2520 2521 _over: function(event) { 2522 2523 var draggable = $.ui.ddmanager.current; 2524 2525 // Bail if draggable and droppable are same element 2526 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2527 return; 2528 } 2529 2530 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2531 if(this.options.hoverClass) { 2532 this.element.addClass(this.options.hoverClass); 2533 } 2534 this._trigger("over", event, this.ui(draggable)); 2535 } 2536 2537 }, 2538 2539 _out: function(event) { 2540 2541 var draggable = $.ui.ddmanager.current; 2542 2543 // Bail if draggable and droppable are same element 2544 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2545 return; 2546 } 2547 2548 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2549 if(this.options.hoverClass) { 2550 this.element.removeClass(this.options.hoverClass); 2551 } 2552 this._trigger("out", event, this.ui(draggable)); 2553 } 2554 2555 }, 2556 2557 _drop: function(event,custom) { 2558 2559 var draggable = custom || $.ui.ddmanager.current, 2560 childrenIntersection = false; 2561 2562 // Bail if draggable and droppable are same element 2563 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2564 return false; 2565 } 2566 2567 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2568 var inst = $.data(this, "ui-droppable"); 2569 if( 2570 inst.options.greedy && 2571 !inst.options.disabled && 2572 inst.options.scope === draggable.options.scope && 2573 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2574 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2575 ) { childrenIntersection = true; return false; } 2576 }); 2577 if(childrenIntersection) { 2578 return false; 2579 } 2580 2581 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2582 if(this.options.activeClass) { 2583 this.element.removeClass(this.options.activeClass); 2584 } 2585 if(this.options.hoverClass) { 2586 this.element.removeClass(this.options.hoverClass); 2587 } 2588 this._trigger("drop", event, this.ui(draggable)); 2589 return this.element; 2590 } 2591 2592 return false; 2593 2594 }, 2595 2596 ui: function(c) { 2597 return { 2598 draggable: (c.currentItem || c.element), 2599 helper: c.helper, 2600 position: c.position, 2601 offset: c.positionAbs 2602 }; 2603 } 2604 2605}); 2606 2607$.ui.intersect = function(draggable, droppable, toleranceMode) { 2608 2609 if (!droppable.offset) { 2610 return false; 2611 } 2612 2613 var draggableLeft, draggableTop, 2614 x1 = (draggable.positionAbs || draggable.position.absolute).left, 2615 y1 = (draggable.positionAbs || draggable.position.absolute).top, 2616 x2 = x1 + draggable.helperProportions.width, 2617 y2 = y1 + draggable.helperProportions.height, 2618 l = droppable.offset.left, 2619 t = droppable.offset.top, 2620 r = l + droppable.proportions().width, 2621 b = t + droppable.proportions().height; 2622 2623 switch (toleranceMode) { 2624 case "fit": 2625 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2626 case "intersect": 2627 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2628 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2629 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2630 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2631 case "pointer": 2632 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2633 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2634 return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width ); 2635 case "touch": 2636 return ( 2637 (y1 >= t && y1 <= b) || // Top edge touching 2638 (y2 >= t && y2 <= b) || // Bottom edge touching 2639 (y1 < t && y2 > b) // Surrounded vertically 2640 ) && ( 2641 (x1 >= l && x1 <= r) || // Left edge touching 2642 (x2 >= l && x2 <= r) || // Right edge touching 2643 (x1 < l && x2 > r) // Surrounded horizontally 2644 ); 2645 default: 2646 return false; 2647 } 2648 2649}; 2650 2651/* 2652 This manager tracks offsets of draggables and droppables 2653*/ 2654$.ui.ddmanager = { 2655 current: null, 2656 droppables: { "default": [] }, 2657 prepareOffsets: function(t, event) { 2658 2659 var i, j, 2660 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2661 type = event ? event.type : null, // workaround for #2317 2662 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2663 2664 droppablesLoop: for (i = 0; i < m.length; i++) { 2665 2666 //No disabled and non-accepted 2667 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2668 continue; 2669 } 2670 2671 // Filter out elements in the current dragged item 2672 for (j=0; j < list.length; j++) { 2673 if(list[j] === m[i].element[0]) { 2674 m[i].proportions().height = 0; 2675 continue droppablesLoop; 2676 } 2677 } 2678 2679 m[i].visible = m[i].element.css("display") !== "none"; 2680 if(!m[i].visible) { 2681 continue; 2682 } 2683 2684 //Activate the droppable if used directly from draggables 2685 if(type === "mousedown") { 2686 m[i]._activate.call(m[i], event); 2687 } 2688 2689 m[ i ].offset = m[ i ].element.offset(); 2690 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 2691 2692 } 2693 2694 }, 2695 drop: function(draggable, event) { 2696 2697 var dropped = false; 2698 // Create a copy of the droppables in case the list changes during the drop (#9116) 2699 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2700 2701 if(!this.options) { 2702 return; 2703 } 2704 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2705 dropped = this._drop.call(this, event) || dropped; 2706 } 2707 2708 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2709 this.isout = true; 2710 this.isover = false; 2711 this._deactivate.call(this, event); 2712 } 2713 2714 }); 2715 return dropped; 2716 2717 }, 2718 dragStart: function( draggable, event ) { 2719 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2720 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2721 if( !draggable.options.refreshPositions ) { 2722 $.ui.ddmanager.prepareOffsets( draggable, event ); 2723 } 2724 }); 2725 }, 2726 drag: function(draggable, event) { 2727 2728 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2729 if(draggable.options.refreshPositions) { 2730 $.ui.ddmanager.prepareOffsets(draggable, event); 2731 } 2732 2733 //Run through all droppables and check their positions based on specific tolerance options 2734 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2735 2736 if(this.options.disabled || this.greedyChild || !this.visible) { 2737 return; 2738 } 2739 2740 var parentInstance, scope, parent, 2741 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2742 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2743 if(!c) { 2744 return; 2745 } 2746 2747 if (this.options.greedy) { 2748 // find droppable parents with same scope 2749 scope = this.options.scope; 2750 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2751 return $.data(this, "ui-droppable").options.scope === scope; 2752 }); 2753 2754 if (parent.length) { 2755 parentInstance = $.data(parent[0], "ui-droppable"); 2756 parentInstance.greedyChild = (c === "isover"); 2757 } 2758 } 2759 2760 // we just moved into a greedy child 2761 if (parentInstance && c === "isover") { 2762 parentInstance.isover = false; 2763 parentInstance.isout = true; 2764 parentInstance._out.call(parentInstance, event); 2765 } 2766 2767 this[c] = true; 2768 this[c === "isout" ? "isover" : "isout"] = false; 2769 this[c === "isover" ? "_over" : "_out"].call(this, event); 2770 2771 // we just moved out of a greedy child 2772 if (parentInstance && c === "isout") { 2773 parentInstance.isout = false; 2774 parentInstance.isover = true; 2775 parentInstance._over.call(parentInstance, event); 2776 } 2777 }); 2778 2779 }, 2780 dragStop: function( draggable, event ) { 2781 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2782 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2783 if( !draggable.options.refreshPositions ) { 2784 $.ui.ddmanager.prepareOffsets( draggable, event ); 2785 } 2786 } 2787}; 2788 2789})(jQuery); 2790(function( $, undefined ) { 2791 2792function num(v) { 2793 return parseInt(v, 10) || 0; 2794} 2795 2796function isNumber(value) { 2797 return !isNaN(parseInt(value, 10)); 2798} 2799 2800$.widget("ui.resizable", $.ui.mouse, { 2801 version: "1.10.4", 2802 widgetEventPrefix: "resize", 2803 options: { 2804 alsoResize: false, 2805 animate: false, 2806 animateDuration: "slow", 2807 animateEasing: "swing", 2808 aspectRatio: false, 2809 autoHide: false, 2810 containment: false, 2811 ghost: false, 2812 grid: false, 2813 handles: "e,s,se", 2814 helper: false, 2815 maxHeight: null, 2816 maxWidth: null, 2817 minHeight: 10, 2818 minWidth: 10, 2819 // See #7960 2820 zIndex: 90, 2821 2822 // callbacks 2823 resize: null, 2824 start: null, 2825 stop: null 2826 }, 2827 _create: function() { 2828 2829 var n, i, handle, axis, hname, 2830 that = this, 2831 o = this.options; 2832 this.element.addClass("ui-resizable"); 2833 2834 $.extend(this, { 2835 _aspectRatio: !!(o.aspectRatio), 2836 aspectRatio: o.aspectRatio, 2837 originalElement: this.element, 2838 _proportionallyResizeElements: [], 2839 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2840 }); 2841 2842 //Wrap the element if it cannot hold child nodes 2843 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2844 2845 //Create a wrapper element and set the wrapper to the new current internal element 2846 this.element.wrap( 2847 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2848 position: this.element.css("position"), 2849 width: this.element.outerWidth(), 2850 height: this.element.outerHeight(), 2851 top: this.element.css("top"), 2852 left: this.element.css("left") 2853 }) 2854 ); 2855 2856 //Overwrite the original this.element 2857 this.element = this.element.parent().data( 2858 "ui-resizable", this.element.data("ui-resizable") 2859 ); 2860 2861 this.elementIsWrapper = true; 2862 2863 //Move margins to the wrapper 2864 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2865 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2866 2867 //Prevent Safari textarea resize 2868 this.originalResizeStyle = this.originalElement.css("resize"); 2869 this.originalElement.css("resize", "none"); 2870 2871 //Push the actual element to our proportionallyResize internal array 2872 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2873 2874 // avoid IE jump (hard set the margin) 2875 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2876 2877 // fix handlers offset 2878 this._proportionallyResize(); 2879 2880 } 2881 2882 this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); 2883 if(this.handles.constructor === String) { 2884 2885 if ( this.handles === "all") { 2886 this.handles = "n,e,s,w,se,sw,ne,nw"; 2887 } 2888 2889 n = this.handles.split(","); 2890 this.handles = {}; 2891 2892 for(i = 0; i < n.length; i++) { 2893 2894 handle = $.trim(n[i]); 2895 hname = "ui-resizable-"+handle; 2896 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2897 2898 // Apply zIndex to all handles - see #7960 2899 axis.css({ zIndex: o.zIndex }); 2900 2901 //TODO : What's going on here? 2902 if ("se" === handle) { 2903 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2904 } 2905 2906 //Insert into internal handles object and append to element 2907 this.handles[handle] = ".ui-resizable-"+handle; 2908 this.element.append(axis); 2909 } 2910 2911 } 2912 2913 this._renderAxis = function(target) { 2914 2915 var i, axis, padPos, padWrapper; 2916 2917 target = target || this.element; 2918 2919 for(i in this.handles) { 2920 2921 if(this.handles[i].constructor === String) { 2922 this.handles[i] = $(this.handles[i], this.element).show(); 2923 } 2924 2925 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2926 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2927 2928 axis = $(this.handles[i], this.element); 2929 2930 //Checking the correct pad and border 2931 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2932 2933 //The padding type i have to apply... 2934 padPos = [ "padding", 2935 /ne|nw|n/.test(i) ? "Top" : 2936 /se|sw|s/.test(i) ? "Bottom" : 2937 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2938 2939 target.css(padPos, padWrapper); 2940 2941 this._proportionallyResize(); 2942 2943 } 2944 2945 //TODO: What's that good for? There's not anything to be executed left 2946 if(!$(this.handles[i]).length) { 2947 continue; 2948 } 2949 } 2950 }; 2951 2952 //TODO: make renderAxis a prototype function 2953 this._renderAxis(this.element); 2954 2955 this._handles = $(".ui-resizable-handle", this.element) 2956 .disableSelection(); 2957 2958 //Matching axis name 2959 this._handles.mouseover(function() { 2960 if (!that.resizing) { 2961 if (this.className) { 2962 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2963 } 2964 //Axis, default = se 2965 that.axis = axis && axis[1] ? axis[1] : "se"; 2966 } 2967 }); 2968 2969 //If we want to auto hide the elements 2970 if (o.autoHide) { 2971 this._handles.hide(); 2972 $(this.element) 2973 .addClass("ui-resizable-autohide") 2974 .mouseenter(function() { 2975 if (o.disabled) { 2976 return; 2977 } 2978 $(this).removeClass("ui-resizable-autohide"); 2979 that._handles.show(); 2980 }) 2981 .mouseleave(function(){ 2982 if (o.disabled) { 2983 return; 2984 } 2985 if (!that.resizing) { 2986 $(this).addClass("ui-resizable-autohide"); 2987 that._handles.hide(); 2988 } 2989 }); 2990 } 2991 2992 //Initialize the mouse interaction 2993 this._mouseInit(); 2994 2995 }, 2996 2997 _destroy: function() { 2998 2999 this._mouseDestroy(); 3000 3001 var wrapper, 3002 _destroy = function(exp) { 3003 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 3004 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 3005 }; 3006 3007 //TODO: Unwrap at same DOM position 3008 if (this.elementIsWrapper) { 3009 _destroy(this.element); 3010 wrapper = this.element; 3011 this.originalElement.css({ 3012 position: wrapper.css("position"), 3013 width: wrapper.outerWidth(), 3014 height: wrapper.outerHeight(), 3015 top: wrapper.css("top"), 3016 left: wrapper.css("left") 3017 }).insertAfter( wrapper ); 3018 wrapper.remove(); 3019 } 3020 3021 this.originalElement.css("resize", this.originalResizeStyle); 3022 _destroy(this.originalElement); 3023 3024 return this; 3025 }, 3026 3027 _mouseCapture: function(event) { 3028 var i, handle, 3029 capture = false; 3030 3031 for (i in this.handles) { 3032 handle = $(this.handles[i])[0]; 3033 if (handle === event.target || $.contains(handle, event.target)) { 3034 capture = true; 3035 } 3036 } 3037 3038 return !this.options.disabled && capture; 3039 }, 3040 3041 _mouseStart: function(event) { 3042 3043 var curleft, curtop, cursor, 3044 o = this.options, 3045 iniPos = this.element.position(), 3046 el = this.element; 3047 3048 this.resizing = true; 3049 3050 // bugfix for http://dev.jquery.com/ticket/1749 3051 if ( (/absolute/).test( el.css("position") ) ) { 3052 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 3053 } else if (el.is(".ui-draggable")) { 3054 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 3055 } 3056 3057 this._renderProxy(); 3058 3059 curleft = num(this.helper.css("left")); 3060 curtop = num(this.helper.css("top")); 3061 3062 if (o.containment) { 3063 curleft += $(o.containment).scrollLeft() || 0; 3064 curtop += $(o.containment).scrollTop() || 0; 3065 } 3066 3067 //Store needed variables 3068 this.offset = this.helper.offset(); 3069 this.position = { left: curleft, top: curtop }; 3070 this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() }; 3071 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 3072 this.originalPosition = { left: curleft, top: curtop }; 3073 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 3074 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 3075 3076 //Aspect Ratio 3077 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 3078 3079 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 3080 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 3081 3082 el.addClass("ui-resizable-resizing"); 3083 this._propagate("start", event); 3084 return true; 3085 }, 3086 3087 _mouseDrag: function(event) { 3088 3089 //Increase performance, avoid regex 3090 var data, 3091 el = this.helper, props = {}, 3092 smp = this.originalMousePosition, 3093 a = this.axis, 3094 prevTop = this.position.top, 3095 prevLeft = this.position.left, 3096 prevWidth = this.size.width, 3097 prevHeight = this.size.height, 3098 dx = (event.pageX-smp.left)||0, 3099 dy = (event.pageY-smp.top)||0, 3100 trigger = this._change[a]; 3101 3102 if (!trigger) { 3103 return false; 3104 } 3105 3106 // Calculate the attrs that will be change 3107 data = trigger.apply(this, [event, dx, dy]); 3108 3109 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 3110 this._updateVirtualBoundaries(event.shiftKey); 3111 if (this._aspectRatio || event.shiftKey) { 3112 data = this._updateRatio(data, event); 3113 } 3114 3115 data = this._respectSize(data, event); 3116 3117 this._updateCache(data); 3118 3119 // plugins callbacks need to be called first 3120 this._propagate("resize", event); 3121 3122 if (this.position.top !== prevTop) { 3123 props.top = this.position.top + "px"; 3124 } 3125 if (this.position.left !== prevLeft) { 3126 props.left = this.position.left + "px"; 3127 } 3128 if (this.size.width !== prevWidth) { 3129 props.width = this.size.width + "px"; 3130 } 3131 if (this.size.height !== prevHeight) { 3132 props.height = this.size.height + "px"; 3133 } 3134 el.css(props); 3135 3136 if (!this._helper && this._proportionallyResizeElements.length) { 3137 this._proportionallyResize(); 3138 } 3139 3140 // Call the user callback if the element was resized 3141 if ( ! $.isEmptyObject(props) ) { 3142 this._trigger("resize", event, this.ui()); 3143 } 3144 3145 return false; 3146 }, 3147 3148 _mouseStop: function(event) { 3149 3150 this.resizing = false; 3151 var pr, ista, soffseth, soffsetw, s, left, top, 3152 o = this.options, that = this; 3153 3154 if(this._helper) { 3155 3156 pr = this._proportionallyResizeElements; 3157 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 3158 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 3159 soffsetw = ista ? 0 : that.sizeDiff.width; 3160 3161 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 3162 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 3163 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3164 3165 if (!o.animate) { 3166 this.element.css($.extend(s, { top: top, left: left })); 3167 } 3168 3169 that.helper.height(that.size.height); 3170 that.helper.width(that.size.width); 3171 3172 if (this._helper && !o.animate) { 3173 this._proportionallyResize(); 3174 } 3175 } 3176 3177 $("body").css("cursor", "auto"); 3178 3179 this.element.removeClass("ui-resizable-resizing"); 3180 3181 this._propagate("stop", event); 3182 3183 if (this._helper) { 3184 this.helper.remove(); 3185 } 3186 3187 return false; 3188 3189 }, 3190 3191 _updateVirtualBoundaries: function(forceAspectRatio) { 3192 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 3193 o = this.options; 3194 3195 b = { 3196 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 3197 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 3198 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 3199 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 3200 }; 3201 3202 if(this._aspectRatio || forceAspectRatio) { 3203 // We want to create an enclosing box whose aspect ration is the requested one 3204 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 3205 pMinWidth = b.minHeight * this.aspectRatio; 3206 pMinHeight = b.minWidth / this.aspectRatio; 3207 pMaxWidth = b.maxHeight * this.aspectRatio; 3208 pMaxHeight = b.maxWidth / this.aspectRatio; 3209 3210 if(pMinWidth > b.minWidth) { 3211 b.minWidth = pMinWidth; 3212 } 3213 if(pMinHeight > b.minHeight) { 3214 b.minHeight = pMinHeight; 3215 } 3216 if(pMaxWidth < b.maxWidth) { 3217 b.maxWidth = pMaxWidth; 3218 } 3219 if(pMaxHeight < b.maxHeight) { 3220 b.maxHeight = pMaxHeight; 3221 } 3222 } 3223 this._vBoundaries = b; 3224 }, 3225 3226 _updateCache: function(data) { 3227 this.offset = this.helper.offset(); 3228 if (isNumber(data.left)) { 3229 this.position.left = data.left; 3230 } 3231 if (isNumber(data.top)) { 3232 this.position.top = data.top; 3233 } 3234 if (isNumber(data.height)) { 3235 this.size.height = data.height; 3236 } 3237 if (isNumber(data.width)) { 3238 this.size.width = data.width; 3239 } 3240 }, 3241 3242 _updateRatio: function( data ) { 3243 3244 var cpos = this.position, 3245 csize = this.size, 3246 a = this.axis; 3247 3248 if (isNumber(data.height)) { 3249 data.width = (data.height * this.aspectRatio); 3250 } else if (isNumber(data.width)) { 3251 data.height = (data.width / this.aspectRatio); 3252 } 3253 3254 if (a === "sw") { 3255 data.left = cpos.left + (csize.width - data.width); 3256 data.top = null; 3257 } 3258 if (a === "nw") { 3259 data.top = cpos.top + (csize.height - data.height); 3260 data.left = cpos.left + (csize.width - data.width); 3261 } 3262 3263 return data; 3264 }, 3265 3266 _respectSize: function( data ) { 3267 3268 var o = this._vBoundaries, 3269 a = this.axis, 3270 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3271 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 3272 dw = this.originalPosition.left + this.originalSize.width, 3273 dh = this.position.top + this.size.height, 3274 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3275 if (isminw) { 3276 data.width = o.minWidth; 3277 } 3278 if (isminh) { 3279 data.height = o.minHeight; 3280 } 3281 if (ismaxw) { 3282 data.width = o.maxWidth; 3283 } 3284 if (ismaxh) { 3285 data.height = o.maxHeight; 3286 } 3287 3288 if (isminw && cw) { 3289 data.left = dw - o.minWidth; 3290 } 3291 if (ismaxw && cw) { 3292 data.left = dw - o.maxWidth; 3293 } 3294 if (isminh && ch) { 3295 data.top = dh - o.minHeight; 3296 } 3297 if (ismaxh && ch) { 3298 data.top = dh - o.maxHeight; 3299 } 3300 3301 // fixing jump error on top/left - bug #2330 3302 if (!data.width && !data.height && !data.left && data.top) { 3303 data.top = null; 3304 } else if (!data.width && !data.height && !data.top && data.left) { 3305 data.left = null; 3306 } 3307 3308 return data; 3309 }, 3310 3311 _proportionallyResize: function() { 3312 3313 if (!this._proportionallyResizeElements.length) { 3314 return; 3315 } 3316 3317 var i, j, borders, paddings, prel, 3318 element = this.helper || this.element; 3319 3320 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 3321 3322 prel = this._proportionallyResizeElements[i]; 3323 3324 if (!this.borderDif) { 3325 this.borderDif = []; 3326 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 3327 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 3328 3329 for ( j = 0; j < borders.length; j++ ) { 3330 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 3331 } 3332 } 3333 3334 prel.css({ 3335 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 3336 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 3337 }); 3338 3339 } 3340 3341 }, 3342 3343 _renderProxy: function() { 3344 3345 var el = this.element, o = this.options; 3346 this.elementOffset = el.offset(); 3347 3348 if(this._helper) { 3349 3350 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 3351 3352 this.helper.addClass(this._helper).css({ 3353 width: this.element.outerWidth() - 1, 3354 height: this.element.outerHeight() - 1, 3355 position: "absolute", 3356 left: this.elementOffset.left +"px", 3357 top: this.elementOffset.top +"px", 3358 zIndex: ++o.zIndex //TODO: Don't modify option 3359 }); 3360 3361 this.helper 3362 .appendTo("body") 3363 .disableSelection(); 3364 3365 } else { 3366 this.helper = this.element; 3367 } 3368 3369 }, 3370 3371 _change: { 3372 e: function(event, dx) { 3373 return { width: this.originalSize.width + dx }; 3374 }, 3375 w: function(event, dx) { 3376 var cs = this.originalSize, sp = this.originalPosition; 3377 return { left: sp.left + dx, width: cs.width - dx }; 3378 }, 3379 n: function(event, dx, dy) { 3380 var cs = this.originalSize, sp = this.originalPosition; 3381 return { top: sp.top + dy, height: cs.height - dy }; 3382 }, 3383 s: function(event, dx, dy) { 3384 return { height: this.originalSize.height + dy }; 3385 }, 3386 se: function(event, dx, dy) { 3387 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3388 }, 3389 sw: function(event, dx, dy) { 3390 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3391 }, 3392 ne: function(event, dx, dy) { 3393 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3394 }, 3395 nw: function(event, dx, dy) { 3396 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3397 } 3398 }, 3399 3400 _propagate: function(n, event) { 3401 $.ui.plugin.call(this, n, [event, this.ui()]); 3402 (n !== "resize" && this._trigger(n, event, this.ui())); 3403 }, 3404 3405 plugins: {}, 3406 3407 ui: function() { 3408 return { 3409 originalElement: this.originalElement, 3410 element: this.element, 3411 helper: this.helper, 3412 position: this.position, 3413 size: this.size, 3414 originalSize: this.originalSize, 3415 originalPosition: this.originalPosition 3416 }; 3417 } 3418 3419}); 3420 3421/* 3422 * Resizable Extensions 3423 */ 3424 3425$.ui.plugin.add("resizable", "animate", { 3426 3427 stop: function( event ) { 3428 var that = $(this).data("ui-resizable"), 3429 o = that.options, 3430 pr = that._proportionallyResizeElements, 3431 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3432 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 3433 soffsetw = ista ? 0 : that.sizeDiff.width, 3434 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3435 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 3436 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3437 3438 that.element.animate( 3439 $.extend(style, top && left ? { top: top, left: left } : {}), { 3440 duration: o.animateDuration, 3441 easing: o.animateEasing, 3442 step: function() { 3443 3444 var data = { 3445 width: parseInt(that.element.css("width"), 10), 3446 height: parseInt(that.element.css("height"), 10), 3447 top: parseInt(that.element.css("top"), 10), 3448 left: parseInt(that.element.css("left"), 10) 3449 }; 3450 3451 if (pr && pr.length) { 3452 $(pr[0]).css({ width: data.width, height: data.height }); 3453 } 3454 3455 // propagating resize, and updating values for each animation step 3456 that._updateCache(data); 3457 that._propagate("resize", event); 3458 3459 } 3460 } 3461 ); 3462 } 3463 3464}); 3465 3466$.ui.plugin.add("resizable", "containment", { 3467 3468 start: function() { 3469 var element, p, co, ch, cw, width, height, 3470 that = $(this).data("ui-resizable"), 3471 o = that.options, 3472 el = that.element, 3473 oc = o.containment, 3474 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 3475 3476 if (!ce) { 3477 return; 3478 } 3479 3480 that.containerElement = $(ce); 3481 3482 if (/document/.test(oc) || oc === document) { 3483 that.containerOffset = { left: 0, top: 0 }; 3484 that.containerPosition = { left: 0, top: 0 }; 3485 3486 that.parentData = { 3487 element: $(document), left: 0, top: 0, 3488 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 3489 }; 3490 } 3491 3492 // i'm a node, so compute top, left, right, bottom 3493 else { 3494 element = $(ce); 3495 p = []; 3496 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 3497 3498 that.containerOffset = element.offset(); 3499 that.containerPosition = element.position(); 3500 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 3501 3502 co = that.containerOffset; 3503 ch = that.containerSize.height; 3504 cw = that.containerSize.width; 3505 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 3506 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3507 3508 that.parentData = { 3509 element: ce, left: co.left, top: co.top, width: width, height: height 3510 }; 3511 } 3512 }, 3513 3514 resize: function( event ) { 3515 var woset, hoset, isParent, isOffsetRelative, 3516 that = $(this).data("ui-resizable"), 3517 o = that.options, 3518 co = that.containerOffset, cp = that.position, 3519 pRatio = that._aspectRatio || event.shiftKey, 3520 cop = { top:0, left:0 }, ce = that.containerElement; 3521 3522 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3523 cop = co; 3524 } 3525 3526 if (cp.left < (that._helper ? co.left : 0)) { 3527 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3528 if (pRatio) { 3529 that.size.height = that.size.width / that.aspectRatio; 3530 } 3531 that.position.left = o.helper ? co.left : 0; 3532 } 3533 3534 if (cp.top < (that._helper ? co.top : 0)) { 3535 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3536 if (pRatio) { 3537 that.size.width = that.size.height * that.aspectRatio; 3538 } 3539 that.position.top = that._helper ? co.top : 0; 3540 } 3541 3542 that.offset.left = that.parentData.left+that.position.left; 3543 that.offset.top = that.parentData.top+that.position.top; 3544 3545 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3546 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3547 3548 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3549 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3550 3551 if ( isParent && isOffsetRelative ) { 3552 woset -= Math.abs( that.parentData.left ); 3553 } 3554 3555 if (woset + that.size.width >= that.parentData.width) { 3556 that.size.width = that.parentData.width - woset; 3557 if (pRatio) { 3558 that.size.height = that.size.width / that.aspectRatio; 3559 } 3560 } 3561 3562 if (hoset + that.size.height >= that.parentData.height) { 3563 that.size.height = that.parentData.height - hoset; 3564 if (pRatio) { 3565 that.size.width = that.size.height * that.aspectRatio; 3566 } 3567 } 3568 }, 3569 3570 stop: function(){ 3571 var that = $(this).data("ui-resizable"), 3572 o = that.options, 3573 co = that.containerOffset, 3574 cop = that.containerPosition, 3575 ce = that.containerElement, 3576 helper = $(that.helper), 3577 ho = helper.offset(), 3578 w = helper.outerWidth() - that.sizeDiff.width, 3579 h = helper.outerHeight() - that.sizeDiff.height; 3580 3581 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3582 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3583 } 3584 3585 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3586 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3587 } 3588 3589 } 3590}); 3591 3592$.ui.plugin.add("resizable", "alsoResize", { 3593 3594 start: function () { 3595 var that = $(this).data("ui-resizable"), 3596 o = that.options, 3597 _store = function (exp) { 3598 $(exp).each(function() { 3599 var el = $(this); 3600 el.data("ui-resizable-alsoresize", { 3601 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3602 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3603 }); 3604 }); 3605 }; 3606 3607 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3608 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3609 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3610 }else{ 3611 _store(o.alsoResize); 3612 } 3613 }, 3614 3615 resize: function (event, ui) { 3616 var that = $(this).data("ui-resizable"), 3617 o = that.options, 3618 os = that.originalSize, 3619 op = that.originalPosition, 3620 delta = { 3621 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3622 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3623 }, 3624 3625 _alsoResize = function (exp, c) { 3626 $(exp).each(function() { 3627 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3628 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3629 3630 $.each(css, function (i, prop) { 3631 var sum = (start[prop]||0) + (delta[prop]||0); 3632 if (sum && sum >= 0) { 3633 style[prop] = sum || null; 3634 } 3635 }); 3636 3637 el.css(style); 3638 }); 3639 }; 3640 3641 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3642 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3643 }else{ 3644 _alsoResize(o.alsoResize); 3645 } 3646 }, 3647 3648 stop: function () { 3649 $(this).removeData("resizable-alsoresize"); 3650 } 3651}); 3652 3653$.ui.plugin.add("resizable", "ghost", { 3654 3655 start: function() { 3656 3657 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3658 3659 that.ghost = that.originalElement.clone(); 3660 that.ghost 3661 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3662 .addClass("ui-resizable-ghost") 3663 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3664 3665 that.ghost.appendTo(that.helper); 3666 3667 }, 3668 3669 resize: function(){ 3670 var that = $(this).data("ui-resizable"); 3671 if (that.ghost) { 3672 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3673 } 3674 }, 3675 3676 stop: function() { 3677 var that = $(this).data("ui-resizable"); 3678 if (that.ghost && that.helper) { 3679 that.helper.get(0).removeChild(that.ghost.get(0)); 3680 } 3681 } 3682 3683}); 3684 3685$.ui.plugin.add("resizable", "grid", { 3686 3687 resize: function() { 3688 var that = $(this).data("ui-resizable"), 3689 o = that.options, 3690 cs = that.size, 3691 os = that.originalSize, 3692 op = that.originalPosition, 3693 a = that.axis, 3694 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3695 gridX = (grid[0]||1), 3696 gridY = (grid[1]||1), 3697 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3698 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3699 newWidth = os.width + ox, 3700 newHeight = os.height + oy, 3701 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3702 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3703 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3704 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3705 3706 o.grid = grid; 3707 3708 if (isMinWidth) { 3709 newWidth = newWidth + gridX; 3710 } 3711 if (isMinHeight) { 3712 newHeight = newHeight + gridY; 3713 } 3714 if (isMaxWidth) { 3715 newWidth = newWidth - gridX; 3716 } 3717 if (isMaxHeight) { 3718 newHeight = newHeight - gridY; 3719 } 3720 3721 if (/^(se|s|e)$/.test(a)) { 3722 that.size.width = newWidth; 3723 that.size.height = newHeight; 3724 } else if (/^(ne)$/.test(a)) { 3725 that.size.width = newWidth; 3726 that.size.height = newHeight; 3727 that.position.top = op.top - oy; 3728 } else if (/^(sw)$/.test(a)) { 3729 that.size.width = newWidth; 3730 that.size.height = newHeight; 3731 that.position.left = op.left - ox; 3732 } else { 3733 if ( newHeight - gridY > 0 ) { 3734 that.size.height = newHeight; 3735 that.position.top = op.top - oy; 3736 } else { 3737 that.size.height = gridY; 3738 that.position.top = op.top + os.height - gridY; 3739 } 3740 if ( newWidth - gridX > 0 ) { 3741 that.size.width = newWidth; 3742 that.position.left = op.left - ox; 3743 } else { 3744 that.size.width = gridX; 3745 that.position.left = op.left + os.width - gridX; 3746 } 3747 } 3748 } 3749 3750}); 3751 3752})(jQuery); 3753(function( $, undefined ) { 3754 3755$.widget("ui.selectable", $.ui.mouse, { 3756 version: "1.10.4", 3757 options: { 3758 appendTo: "body", 3759 autoRefresh: true, 3760 distance: 0, 3761 filter: "*", 3762 tolerance: "touch", 3763 3764 // callbacks 3765 selected: null, 3766 selecting: null, 3767 start: null, 3768 stop: null, 3769 unselected: null, 3770 unselecting: null 3771 }, 3772 _create: function() { 3773 var selectees, 3774 that = this; 3775 3776 this.element.addClass("ui-selectable"); 3777 3778 this.dragged = false; 3779 3780 // cache selectee children based on filter 3781 this.refresh = function() { 3782 selectees = $(that.options.filter, that.element[0]); 3783 selectees.addClass("ui-selectee"); 3784 selectees.each(function() { 3785 var $this = $(this), 3786 pos = $this.offset(); 3787 $.data(this, "selectable-item", { 3788 element: this, 3789 $element: $this, 3790 left: pos.left, 3791 top: pos.top, 3792 right: pos.left + $this.outerWidth(), 3793 bottom: pos.top + $this.outerHeight(), 3794 startselected: false, 3795 selected: $this.hasClass("ui-selected"), 3796 selecting: $this.hasClass("ui-selecting"), 3797 unselecting: $this.hasClass("ui-unselecting") 3798 }); 3799 }); 3800 }; 3801 this.refresh(); 3802 3803 this.selectees = selectees.addClass("ui-selectee"); 3804 3805 this._mouseInit(); 3806 3807 this.helper = $("<div class='ui-selectable-helper'></div>"); 3808 }, 3809 3810 _destroy: function() { 3811 this.selectees 3812 .removeClass("ui-selectee") 3813 .removeData("selectable-item"); 3814 this.element 3815 .removeClass("ui-selectable ui-selectable-disabled"); 3816 this._mouseDestroy(); 3817 }, 3818 3819 _mouseStart: function(event) { 3820 var that = this, 3821 options = this.options; 3822 3823 this.opos = [event.pageX, event.pageY]; 3824 3825 if (this.options.disabled) { 3826 return; 3827 } 3828 3829 this.selectees = $(options.filter, this.element[0]); 3830 3831 this._trigger("start", event); 3832 3833 $(options.appendTo).append(this.helper); 3834 // position helper (lasso) 3835 this.helper.css({ 3836 "left": event.pageX, 3837 "top": event.pageY, 3838 "width": 0, 3839 "height": 0 3840 }); 3841 3842 if (options.autoRefresh) { 3843 this.refresh(); 3844 } 3845 3846 this.selectees.filter(".ui-selected").each(function() { 3847 var selectee = $.data(this, "selectable-item"); 3848 selectee.startselected = true; 3849 if (!event.metaKey && !event.ctrlKey) { 3850 selectee.$element.removeClass("ui-selected"); 3851 selectee.selected = false; 3852 selectee.$element.addClass("ui-unselecting"); 3853 selectee.unselecting = true; 3854 // selectable UNSELECTING callback 3855 that._trigger("unselecting", event, { 3856 unselecting: selectee.element 3857 }); 3858 } 3859 }); 3860 3861 $(event.target).parents().addBack().each(function() { 3862 var doSelect, 3863 selectee = $.data(this, "selectable-item"); 3864 if (selectee) { 3865 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3866 selectee.$element 3867 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3868 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3869 selectee.unselecting = !doSelect; 3870 selectee.selecting = doSelect; 3871 selectee.selected = doSelect; 3872 // selectable (UN)SELECTING callback 3873 if (doSelect) { 3874 that._trigger("selecting", event, { 3875 selecting: selectee.element 3876 }); 3877 } else { 3878 that._trigger("unselecting", event, { 3879 unselecting: selectee.element 3880 }); 3881 } 3882 return false; 3883 } 3884 }); 3885 3886 }, 3887 3888 _mouseDrag: function(event) { 3889 3890 this.dragged = true; 3891 3892 if (this.options.disabled) { 3893 return; 3894 } 3895 3896 var tmp, 3897 that = this, 3898 options = this.options, 3899 x1 = this.opos[0], 3900 y1 = this.opos[1], 3901 x2 = event.pageX, 3902 y2 = event.pageY; 3903 3904 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3905 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3906 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3907 3908 this.selectees.each(function() { 3909 var selectee = $.data(this, "selectable-item"), 3910 hit = false; 3911 3912 //prevent helper from being selected if appendTo: selectable 3913 if (!selectee || selectee.element === that.element[0]) { 3914 return; 3915 } 3916 3917 if (options.tolerance === "touch") { 3918 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3919 } else if (options.tolerance === "fit") { 3920 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3921 } 3922 3923 if (hit) { 3924 // SELECT 3925 if (selectee.selected) { 3926 selectee.$element.removeClass("ui-selected"); 3927 selectee.selected = false; 3928 } 3929 if (selectee.unselecting) { 3930 selectee.$element.removeClass("ui-unselecting"); 3931 selectee.unselecting = false; 3932 } 3933 if (!selectee.selecting) { 3934 selectee.$element.addClass("ui-selecting"); 3935 selectee.selecting = true; 3936 // selectable SELECTING callback 3937 that._trigger("selecting", event, { 3938 selecting: selectee.element 3939 }); 3940 } 3941 } else { 3942 // UNSELECT 3943 if (selectee.selecting) { 3944 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3945 selectee.$element.removeClass("ui-selecting"); 3946 selectee.selecting = false; 3947 selectee.$element.addClass("ui-selected"); 3948 selectee.selected = true; 3949 } else { 3950 selectee.$element.removeClass("ui-selecting"); 3951 selectee.selecting = false; 3952 if (selectee.startselected) { 3953 selectee.$element.addClass("ui-unselecting"); 3954 selectee.unselecting = true; 3955 } 3956 // selectable UNSELECTING callback 3957 that._trigger("unselecting", event, { 3958 unselecting: selectee.element 3959 }); 3960 } 3961 } 3962 if (selectee.selected) { 3963 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3964 selectee.$element.removeClass("ui-selected"); 3965 selectee.selected = false; 3966 3967 selectee.$element.addClass("ui-unselecting"); 3968 selectee.unselecting = true; 3969 // selectable UNSELECTING callback 3970 that._trigger("unselecting", event, { 3971 unselecting: selectee.element 3972 }); 3973 } 3974 } 3975 } 3976 }); 3977 3978 return false; 3979 }, 3980 3981 _mouseStop: function(event) { 3982 var that = this; 3983 3984 this.dragged = false; 3985 3986 $(".ui-unselecting", this.element[0]).each(function() { 3987 var selectee = $.data(this, "selectable-item"); 3988 selectee.$element.removeClass("ui-unselecting"); 3989 selectee.unselecting = false; 3990 selectee.startselected = false; 3991 that._trigger("unselected", event, { 3992 unselected: selectee.element 3993 }); 3994 }); 3995 $(".ui-selecting", this.element[0]).each(function() { 3996 var selectee = $.data(this, "selectable-item"); 3997 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3998 selectee.selecting = false; 3999 selectee.selected = true; 4000 selectee.startselected = true; 4001 that._trigger("selected", event, { 4002 selected: selectee.element 4003 }); 4004 }); 4005 this._trigger("stop", event); 4006 4007 this.helper.remove(); 4008 4009 return false; 4010 } 4011 4012}); 4013 4014})(jQuery); 4015(function( $, undefined ) { 4016 4017function isOverAxis( x, reference, size ) { 4018 return ( x > reference ) && ( x < ( reference + size ) ); 4019} 4020 4021function isFloating(item) { 4022 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 4023} 4024 4025$.widget("ui.sortable", $.ui.mouse, { 4026 version: "1.10.4", 4027 widgetEventPrefix: "sort", 4028 ready: false, 4029 options: { 4030 appendTo: "parent", 4031 axis: false, 4032 connectWith: false, 4033 containment: false, 4034 cursor: "auto", 4035 cursorAt: false, 4036 dropOnEmpty: true, 4037 forcePlaceholderSize: false, 4038 forceHelperSize: false, 4039 grid: false, 4040 handle: false, 4041 helper: "original", 4042 items: "> *", 4043 opacity: false, 4044 placeholder: false, 4045 revert: false, 4046 scroll: true, 4047 scrollSensitivity: 20, 4048 scrollSpeed: 20, 4049 scope: "default", 4050 tolerance: "intersect", 4051 zIndex: 1000, 4052 4053 // callbacks 4054 activate: null, 4055 beforeStop: null, 4056 change: null, 4057 deactivate: null, 4058 out: null, 4059 over: null, 4060 receive: null, 4061 remove: null, 4062 sort: null, 4063 start: null, 4064 stop: null, 4065 update: null 4066 }, 4067 _create: function() { 4068 4069 var o = this.options; 4070 this.containerCache = {}; 4071 this.element.addClass("ui-sortable"); 4072 4073 //Get the items 4074 this.refresh(); 4075 4076 //Let's determine if the items are being displayed horizontally 4077 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 4078 4079 //Let's determine the parent's offset 4080 this.offset = this.element.offset(); 4081 4082 //Initialize mouse events for interaction 4083 this._mouseInit(); 4084 4085 //We're ready to go 4086 this.ready = true; 4087 4088 }, 4089 4090 _destroy: function() { 4091 this.element 4092 .removeClass("ui-sortable ui-sortable-disabled"); 4093 this._mouseDestroy(); 4094 4095 for ( var i = this.items.length - 1; i >= 0; i-- ) { 4096 this.items[i].item.removeData(this.widgetName + "-item"); 4097 } 4098 4099 return this; 4100 }, 4101 4102 _setOption: function(key, value){ 4103 if ( key === "disabled" ) { 4104 this.options[ key ] = value; 4105 4106 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 4107 } else { 4108 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 4109 $.Widget.prototype._setOption.apply(this, arguments); 4110 } 4111 }, 4112 4113 _mouseCapture: function(event, overrideHandle) { 4114 var currentItem = null, 4115 validHandle = false, 4116 that = this; 4117 4118 if (this.reverting) { 4119 return false; 4120 } 4121 4122 if(this.options.disabled || this.options.type === "static") { 4123 return false; 4124 } 4125 4126 //We have to refresh the items data once first 4127 this._refreshItems(event); 4128 4129 //Find out if the clicked node (or one of its parents) is a actual item in this.items 4130 $(event.target).parents().each(function() { 4131 if($.data(this, that.widgetName + "-item") === that) { 4132 currentItem = $(this); 4133 return false; 4134 } 4135 }); 4136 if($.data(event.target, that.widgetName + "-item") === that) { 4137 currentItem = $(event.target); 4138 } 4139 4140 if(!currentItem) { 4141 return false; 4142 } 4143 if(this.options.handle && !overrideHandle) { 4144 $(this.options.handle, currentItem).find("*").addBack().each(function() { 4145 if(this === event.target) { 4146 validHandle = true; 4147 } 4148 }); 4149 if(!validHandle) { 4150 return false; 4151 } 4152 } 4153 4154 this.currentItem = currentItem; 4155 this._removeCurrentsFromItems(); 4156 return true; 4157 4158 }, 4159 4160 _mouseStart: function(event, overrideHandle, noActivation) { 4161 4162 var i, body, 4163 o = this.options; 4164 4165 this.currentContainer = this; 4166 4167 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 4168 this.refreshPositions(); 4169 4170 //Create and append the visible helper 4171 this.helper = this._createHelper(event); 4172 4173 //Cache the helper size 4174 this._cacheHelperProportions(); 4175 4176 /* 4177 * - Position generation - 4178 * This block generates everything position related - it's the core of draggables. 4179 */ 4180 4181 //Cache the margins of the original element 4182 this._cacheMargins(); 4183 4184 //Get the next scrolling parent 4185 this.scrollParent = this.helper.scrollParent(); 4186 4187 //The element's absolute position on the page minus margins 4188 this.offset = this.currentItem.offset(); 4189 this.offset = { 4190 top: this.offset.top - this.margins.top, 4191 left: this.offset.left - this.margins.left 4192 }; 4193 4194 $.extend(this.offset, { 4195 click: { //Where the click happened, relative to the element 4196 left: event.pageX - this.offset.left, 4197 top: event.pageY - this.offset.top 4198 }, 4199 parent: this._getParentOffset(), 4200 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 4201 }); 4202 4203 // Only after we got the offset, we can change the helper's position to absolute 4204 // TODO: Still need to figure out a way to make relative sorting possible 4205 this.helper.css("position", "absolute"); 4206 this.cssPosition = this.helper.css("position"); 4207 4208 //Generate the original position 4209 this.originalPosition = this._generatePosition(event); 4210 this.originalPageX = event.pageX; 4211 this.originalPageY = event.pageY; 4212 4213 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 4214 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 4215 4216 //Cache the former DOM position 4217 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 4218 4219 //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 4220 if(this.helper[0] !== this.currentItem[0]) { 4221 this.currentItem.hide(); 4222 } 4223 4224 //Create the placeholder 4225 this._createPlaceholder(); 4226 4227 //Set a containment if given in the options 4228 if(o.containment) { 4229 this._setContainment(); 4230 } 4231 4232 if( o.cursor && o.cursor !== "auto" ) { // cursor option 4233 body = this.document.find( "body" ); 4234 4235 // support: IE 4236 this.storedCursor = body.css( "cursor" ); 4237 body.css( "cursor", o.cursor ); 4238 4239 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 4240 } 4241 4242 if(o.opacity) { // opacity option 4243 if (this.helper.css("opacity")) { 4244 this._storedOpacity = this.helper.css("opacity"); 4245 } 4246 this.helper.css("opacity", o.opacity); 4247 } 4248 4249 if(o.zIndex) { // zIndex option 4250 if (this.helper.css("zIndex")) { 4251 this._storedZIndex = this.helper.css("zIndex"); 4252 } 4253 this.helper.css("zIndex", o.zIndex); 4254 } 4255 4256 //Prepare scrolling 4257 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4258 this.overflowOffset = this.scrollParent.offset(); 4259 } 4260 4261 //Call callbacks 4262 this._trigger("start", event, this._uiHash()); 4263 4264 //Recache the helper size 4265 if(!this._preserveHelperProportions) { 4266 this._cacheHelperProportions(); 4267 } 4268 4269 4270 //Post "activate" events to possible containers 4271 if( !noActivation ) { 4272 for ( i = this.containers.length - 1; i >= 0; i-- ) { 4273 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 4274 } 4275 } 4276 4277 //Prepare possible droppables 4278 if($.ui.ddmanager) { 4279 $.ui.ddmanager.current = this; 4280 } 4281 4282 if ($.ui.ddmanager && !o.dropBehaviour) { 4283 $.ui.ddmanager.prepareOffsets(this, event); 4284 } 4285 4286 this.dragging = true; 4287 4288 this.helper.addClass("ui-sortable-helper"); 4289 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 4290 return true; 4291 4292 }, 4293 4294 _mouseDrag: function(event) { 4295 var i, item, itemElement, intersection, 4296 o = this.options, 4297 scrolled = false; 4298 4299 //Compute the helpers position 4300 this.position = this._generatePosition(event); 4301 this.positionAbs = this._convertPositionTo("absolute"); 4302 4303 if (!this.lastPositionAbs) { 4304 this.lastPositionAbs = this.positionAbs; 4305 } 4306 4307 //Do scrolling 4308 if(this.options.scroll) { 4309 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4310 4311 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 4312 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 4313 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 4314 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 4315 } 4316 4317 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 4318 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 4319 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 4320 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 4321 } 4322 4323 } else { 4324 4325 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 4326 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4327 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 4328 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4329 } 4330 4331 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 4332 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4333 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 4334 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4335 } 4336 4337 } 4338 4339 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 4340 $.ui.ddmanager.prepareOffsets(this, event); 4341 } 4342 } 4343 4344 //Regenerate the absolute position used for position checks 4345 this.positionAbs = this._convertPositionTo("absolute"); 4346 4347 //Set the helper position 4348 if(!this.options.axis || this.options.axis !== "y") { 4349 this.helper[0].style.left = this.position.left+"px"; 4350 } 4351 if(!this.options.axis || this.options.axis !== "x") { 4352 this.helper[0].style.top = this.position.top+"px"; 4353 } 4354 4355 //Rearrange 4356 for (i = this.items.length - 1; i >= 0; i--) { 4357 4358 //Cache variables and intersection, continue if no intersection 4359 item = this.items[i]; 4360 itemElement = item.item[0]; 4361 intersection = this._intersectsWithPointer(item); 4362 if (!intersection) { 4363 continue; 4364 } 4365 4366 // Only put the placeholder inside the current Container, skip all 4367 // items from other containers. This works because when moving 4368 // an item from one container to another the 4369 // currentContainer is switched before the placeholder is moved. 4370 // 4371 // Without this, moving items in "sub-sortables" can cause 4372 // the placeholder to jitter beetween the outer and inner container. 4373 if (item.instance !== this.currentContainer) { 4374 continue; 4375 } 4376 4377 // cannot intersect with itself 4378 // no useless actions that have been done before 4379 // no action if the item moved is the parent of the item checked 4380 if (itemElement !== this.currentItem[0] && 4381 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 4382 !$.contains(this.placeholder[0], itemElement) && 4383 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 4384 ) { 4385 4386 this.direction = intersection === 1 ? "down" : "up"; 4387 4388 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 4389 this._rearrange(event, item); 4390 } else { 4391 break; 4392 } 4393 4394 this._trigger("change", event, this._uiHash()); 4395 break; 4396 } 4397 } 4398 4399 //Post events to containers 4400 this._contactContainers(event); 4401 4402 //Interconnect with droppables 4403 if($.ui.ddmanager) { 4404 $.ui.ddmanager.drag(this, event); 4405 } 4406 4407 //Call callbacks 4408 this._trigger("sort", event, this._uiHash()); 4409 4410 this.lastPositionAbs = this.positionAbs; 4411 return false; 4412 4413 }, 4414 4415 _mouseStop: function(event, noPropagation) { 4416 4417 if(!event) { 4418 return; 4419 } 4420 4421 //If we are using droppables, inform the manager about the drop 4422 if ($.ui.ddmanager && !this.options.dropBehaviour) { 4423 $.ui.ddmanager.drop(this, event); 4424 } 4425 4426 if(this.options.revert) { 4427 var that = this, 4428 cur = this.placeholder.offset(), 4429 axis = this.options.axis, 4430 animation = {}; 4431 4432 if ( !axis || axis === "x" ) { 4433 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 4434 } 4435 if ( !axis || axis === "y" ) { 4436 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 4437 } 4438 this.reverting = true; 4439 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 4440 that._clear(event); 4441 }); 4442 } else { 4443 this._clear(event, noPropagation); 4444 } 4445 4446 return false; 4447 4448 }, 4449 4450 cancel: function() { 4451 4452 if(this.dragging) { 4453 4454 this._mouseUp({ target: null }); 4455 4456 if(this.options.helper === "original") { 4457 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4458 } else { 4459 this.currentItem.show(); 4460 } 4461 4462 //Post deactivating events to containers 4463 for (var i = this.containers.length - 1; i >= 0; i--){ 4464 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4465 if(this.containers[i].containerCache.over) { 4466 this.containers[i]._trigger("out", null, this._uiHash(this)); 4467 this.containers[i].containerCache.over = 0; 4468 } 4469 } 4470 4471 } 4472 4473 if (this.placeholder) { 4474 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4475 if(this.placeholder[0].parentNode) { 4476 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4477 } 4478 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 4479 this.helper.remove(); 4480 } 4481 4482 $.extend(this, { 4483 helper: null, 4484 dragging: false, 4485 reverting: false, 4486 _noFinalSort: null 4487 }); 4488 4489 if(this.domPosition.prev) { 4490 $(this.domPosition.prev).after(this.currentItem); 4491 } else { 4492 $(this.domPosition.parent).prepend(this.currentItem); 4493 } 4494 } 4495 4496 return this; 4497 4498 }, 4499 4500 serialize: function(o) { 4501 4502 var items = this._getItemsAsjQuery(o && o.connected), 4503 str = []; 4504 o = o || {}; 4505 4506 $(items).each(function() { 4507 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 4508 if (res) { 4509 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4510 } 4511 }); 4512 4513 if(!str.length && o.key) { 4514 str.push(o.key + "="); 4515 } 4516 4517 return str.join("&"); 4518 4519 }, 4520 4521 toArray: function(o) { 4522 4523 var items = this._getItemsAsjQuery(o && o.connected), 4524 ret = []; 4525 4526 o = o || {}; 4527 4528 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4529 return ret; 4530 4531 }, 4532 4533 /* Be careful with the following core functions */ 4534 _intersectsWith: function(item) { 4535 4536 var x1 = this.positionAbs.left, 4537 x2 = x1 + this.helperProportions.width, 4538 y1 = this.positionAbs.top, 4539 y2 = y1 + this.helperProportions.height, 4540 l = item.left, 4541 r = l + item.width, 4542 t = item.top, 4543 b = t + item.height, 4544 dyClick = this.offset.click.top, 4545 dxClick = this.offset.click.left, 4546 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 4547 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 4548 isOverElement = isOverElementHeight && isOverElementWidth; 4549 4550 if ( this.options.tolerance === "pointer" || 4551 this.options.forcePointerForContainers || 4552 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4553 ) { 4554 return isOverElement; 4555 } else { 4556 4557 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4558 x2 - (this.helperProportions.width / 2) < r && // Left Half 4559 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4560 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4561 4562 } 4563 }, 4564 4565 _intersectsWithPointer: function(item) { 4566 4567 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4568 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4569 isOverElement = isOverElementHeight && isOverElementWidth, 4570 verticalDirection = this._getDragVerticalDirection(), 4571 horizontalDirection = this._getDragHorizontalDirection(); 4572 4573 if (!isOverElement) { 4574 return false; 4575 } 4576 4577 return this.floating ? 4578 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4579 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4580 4581 }, 4582 4583 _intersectsWithSides: function(item) { 4584 4585 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4586 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4587 verticalDirection = this._getDragVerticalDirection(), 4588 horizontalDirection = this._getDragHorizontalDirection(); 4589 4590 if (this.floating && horizontalDirection) { 4591 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4592 } else { 4593 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4594 } 4595 4596 }, 4597 4598 _getDragVerticalDirection: function() { 4599 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4600 return delta !== 0 && (delta > 0 ? "down" : "up"); 4601 }, 4602 4603 _getDragHorizontalDirection: function() { 4604 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4605 return delta !== 0 && (delta > 0 ? "right" : "left"); 4606 }, 4607 4608 refresh: function(event) { 4609 this._refreshItems(event
vendor: 4,154 bytes, lines 4609-4745
4609); 4610 this.refreshPositions(); 4611 return this; 4612 }, 4613 4614 _connectWith: function() { 4615 var options = this.options; 4616 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4617 }, 4618 4619 _getItemsAsjQuery: function(connected) { 4620 4621 var i, j, cur, inst, 4622 items = [], 4623 queries = [], 4624 connectWith = this._connectWith(); 4625 4626 if(connectWith && connected) { 4627 for (i = connectWith.length - 1; i >= 0; i--){ 4628 cur = $(connectWith[i]); 4629 for ( j = cur.length - 1; j >= 0; j--){ 4630 inst = $.data(cur[j], this.widgetFullName); 4631 if(inst && inst !== this && !inst.options.disabled) { 4632 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]); 4633 } 4634 } 4635 } 4636 } 4637 4638 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]); 4639 4640 function addItems() { 4641 items.push( this ); 4642 } 4643 for (i = queries.length - 1; i >= 0; i--){ 4644 queries[i][0].each( addItems ); 4645 } 4646 4647 return $(items); 4648 4649 }, 4650 4651 _removeCurrentsFromItems: function() { 4652 4653 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4654 4655 this.items = $.grep(this.items, function (item) { 4656 for (var j=0; j < list.length; j++) { 4657 if(list[j] === item.item[0]) { 4658 return false; 4659 } 4660 } 4661 return true; 4662 }); 4663 4664 }, 4665 4666 _refreshItems: function(event) { 4667 4668 this.items = []; 4669 this.containers = [this]; 4670 4671 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4672 items = this.items, 4673 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4674 connectWith = this._connectWith(); 4675 4676 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4677 for (i = connectWith.length - 1; i >= 0; i--){ 4678 cur = $(connectWith[i]); 4679 for (j = cur.length - 1; j >= 0; j--){ 4680 inst = $.data(cur[j], this.widgetFullName); 4681 if(inst && inst !== this && !inst.options.disabled) { 4682 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4683 this.containers.push(inst); 4684 } 4685 } 4686 } 4687 } 4688 4689 for (i = queries.length - 1; i >= 0; i--) { 4690 targetData = queries[i][1]; 4691 _queries = queries[i][0]; 4692 4693 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4694 item = $(_queries[j]); 4695 4696 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4697 4698 items.push({ 4699 item: item, 4700 instance: targetData, 4701 width: 0, height: 0, 4702 left: 0, top: 0 4703 }); 4704 } 4705 } 4706 4707 }, 4708 4709 refreshPositions: function(fast) { 4710 4711 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4712 if(this.offsetParent && this.helper) { 4713 this.offset.parent = this._getParentOffset(); 4714 } 4715 4716 var i, item, t, p; 4717 4718 for (i = this.items.length - 1; i >= 0; i--){ 4719 item = this.items[i]; 4720 4721 //We ignore calculating positions of all connected containers when we're not over them 4722 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4723 continue; 4724 } 4725 4726 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4727 4728 if (!fast) { 4729 item.width = t.outerWidth(); 4730 item.height = t.outerHeight(); 4731 } 4732 4733 p = t.offset(); 4734 item.left = p.left; 4735 item.top = p.top; 4736 } 4737 4738 if(this.options.custom && this.options.custom.refreshContainers) { 4739 this.options.custom.refreshContainers.call(this); 4740 } else { 4741 for (i = this.containers.length - 1; i >= 0; i--){ 4742 p = this.containers[i].element.offset(); 4743 this.containers[i].containerCache.left = p.left; 4744 this.containers[i].containerCache.top = p.top; 4745 this.containers[i].containerCache.width
vendor: 1,591 bytes, lines 4745-4792
4745 = this.containers[i].element.outerWidth(); 4746 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4747 } 4748 } 4749 4750 return this; 4751 }, 4752 4753 _createPlaceholder: function(that) { 4754 that = that || this; 4755 var className, 4756 o = that.options; 4757 4758 if(!o.placeholder || o.placeholder.constructor === String) { 4759 className = o.placeholder; 4760 o.placeholder = { 4761 element: function() { 4762 4763 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4764 element = $( "<" + nodeName + ">", that.document[0] ) 4765 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4766 .removeClass("ui-sortable-helper"); 4767 4768 if ( nodeName === "tr" ) { 4769 that.currentItem.children().each(function() { 4770 $( "<td> </td>", that.document[0] ) 4771 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 4772 .appendTo( element ); 4773 }); 4774 } else if ( nodeName === "img" ) { 4775 element.attr( "src", that.currentItem.attr( "src" ) ); 4776 } 4777 4778 if ( !className ) { 4779 element.css( "visibility", "hidden" ); 4780 } 4781 4782 return element; 4783 }, 4784 update: function(container, p) { 4785 4786 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4787 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4788 if(className && !o.forcePlaceholderSize) { 4789 return; 4790 } 4791 4792 //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
4793 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4794 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4795 } 4796 }; 4797 } 4798 4799 //Create the placeholder 4800 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4801 4802 //Append it after the actual current item 4803 that.currentItem.after(that.placeholder); 4804 4805 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4806 o.placeholder.update(that, that.placeholder); 4807 4808 }, 4809 4810 _contactContainers: function(event) { 4811 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4812 innermostContainer = null, 4813 innermostIndex = null; 4814 4815 // get innermost container that intersects with item 4816 for (i = this.containers.length - 1; i >= 0; i--) { 4817 4818 // never consider a container that's located within the item itself 4819 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4820 continue; 4821 } 4822 4823 if(this._intersectsWith(this.containers[i].containerCache)) { 4824 4825 // if we've already found a container and it's more "inner" than this, then continue 4826 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4827 continue; 4828 } 4829 4830 innermostContainer = this.containers[i]; 4831 innermostIndex = i; 4832 4833 } else { 4834 // container doesn't intersect. trigger "out" event if necessary 4835 if(this.containers[i].containerCache.over) { 4836 this.containers[i]._trigger("out", event, this._uiHash(this)); 4837 this.containers[i].containerCache.over = 0; 4838 } 4839 } 4840 4841 } 4842 4843 // if no intersecting containers found, return 4844 if(!innermostContainer) { 4845 return; 4846 } 4847 4848 // move the item into the container if it's not there already 4849 if(this.containers.length === 1) { 4850 if (!this.containers[innermostIndex].containerCache.over) { 4851 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4852 this.containers[innermostIndex].containerCache.over = 1; 4853 } 4854 } else { 4855 4856 //When entering a new container, we will find the item with the least distance and append our item near it 4857 dist = 10000; 4858 itemWithLeastDistance = null; 4859 floating = innermostContainer.floating || isFloating(this.currentItem); 4860 posProperty = floating ? "left" : "top"; 4861 sizeProperty = floating ? "width" : "height"; 4862 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4863 for (j = this.items.length - 1; j >= 0; j--) { 4864 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4865 continue; 4866 } 4867 if(this.items[j].item[0] === this.currentItem[0]) { 4868 continue; 4869 } 4870 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 4871 continue; 4872 } 4873 cur = this.items[j].item.offset()[posProperty]; 4874 nearBottom = false; 4875 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4876 nearBottom = true; 4877 cur += this.items[j][sizeProperty]; 4878 } 4879 4880 if(Math.abs(cur - base) < dist) { 4881 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j
vendor: 15,870 bytes, lines 4881-5287
4881]; 4882 this.direction = nearBottom ? "up": "down"; 4883 } 4884 } 4885 4886 //Check if dropOnEmpty is enabled 4887 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4888 return; 4889 } 4890 4891 if(this.currentContainer === this.containers[innermostIndex]) { 4892 return; 4893 } 4894 4895 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4896 this._trigger("change", event, this._uiHash()); 4897 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4898 this.currentContainer = this.containers[innermostIndex]; 4899 4900 //Update the placeholder 4901 this.options.placeholder.update(this.currentContainer, this.placeholder); 4902 4903 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4904 this.containers[innermostIndex].containerCache.over = 1; 4905 } 4906 4907 4908 }, 4909 4910 _createHelper: function(event) { 4911 4912 var o = this.options, 4913 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4914 4915 //Add the helper to the DOM if that didn't happen already 4916 if(!helper.parents("body").length) { 4917 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4918 } 4919 4920 if(helper[0] === this.currentItem[0]) { 4921 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") }; 4922 } 4923 4924 if(!helper[0].style.width || o.forceHelperSize) { 4925 helper.width(this.currentItem.width()); 4926 } 4927 if(!helper[0].style.height || o.forceHelperSize) { 4928 helper.height(this.currentItem.height()); 4929 } 4930 4931 return helper; 4932 4933 }, 4934 4935 _adjustOffsetFromHelper: function(obj) { 4936 if (typeof obj === "string") { 4937 obj = obj.split(" "); 4938 } 4939 if ($.isArray(obj)) { 4940 obj = {left: +obj[0], top: +obj[1] || 0}; 4941 } 4942 if ("left" in obj) { 4943 this.offset.click.left = obj.left + this.margins.left; 4944 } 4945 if ("right" in obj) { 4946 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4947 } 4948 if ("top" in obj) { 4949 this.offset.click.top = obj.top + this.margins.top; 4950 } 4951 if ("bottom" in obj) { 4952 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4953 } 4954 }, 4955 4956 _getParentOffset: function() { 4957 4958 4959 //Get the offsetParent and cache its position 4960 this.offsetParent = this.helper.offsetParent(); 4961 var po = this.offsetParent.offset(); 4962 4963 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4964 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4965 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4966 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4967 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4968 po.left += this.scrollParent.scrollLeft(); 4969 po.top += this.scrollParent.scrollTop(); 4970 } 4971 4972 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4973 // with an ugly IE fix 4974 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4975 po = { top: 0, left: 0 }; 4976 } 4977 4978 return { 4979 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4980 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4981 }; 4982 4983 }, 4984 4985 _getRelativeOffset: function() { 4986 4987 if(this.cssPosition === "relative") { 4988 var p = this.currentItem.position(); 4989 return { 4990 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4991 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4992 }; 4993 } else { 4994 return { top: 0, left: 0 }; 4995 } 4996 4997 }, 4998 4999 _cacheMargins: function() { 5000 this.margins = { 5001 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 5002 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 5003 }; 5004 }, 5005 5006 _cacheHelperProportions: function() { 5007 this.helperProportions = { 5008 width: this.helper.outerWidth(), 5009 height: this.helper.outerHeight() 5010 }; 5011 }, 5012 5013 _setContainment: function() { 5014 5015 var ce, co, over, 5016 o = this.options; 5017 if(o.containment === "parent") { 5018 o.containment = this.helper[0].parentNode; 5019 } 5020 if(o.containment === "document" || o.containment === "window") { 5021 this.containment = [ 5022 0 - this.offset.relative.left - this.offset.parent.left, 5023 0 - this.offset.relative.top - this.offset.parent.top, 5024 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 5025 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 5026 ]; 5027 } 5028 5029 if(!(/^(document|window|parent)$/).test(o.containment)) { 5030 ce = $(o.containment)[0]; 5031 co = $(o.containment).offset(); 5032 over = ($(ce).css("overflow") !== "hidden"); 5033 5034 this.containment = [ 5035 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 5036 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 5037 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, 5038 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 5039 ]; 5040 } 5041 5042 }, 5043 5044 _convertPositionTo: function(d, pos) { 5045 5046 if(!pos) { 5047 pos = this.position; 5048 } 5049 var mod = d === "absolute" ? 1 : -1, 5050 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 5051 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 5052 5053 return { 5054 top: ( 5055 pos.top + // The absolute mouse position 5056 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5057 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 5058 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 5059 ), 5060 left: ( 5061 pos.left + // The absolute mouse position 5062 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5063 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 5064 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 5065 ) 5066 }; 5067 5068 }, 5069 5070 _generatePosition: function(event) { 5071 5072 var top, left, 5073 o = this.options, 5074 pageX = event.pageX, 5075 pageY = event.pageY, 5076 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); 5077 5078 // This is another very weird special case that only happens for relative elements: 5079 // 1. If the css position is relative 5080 // 2. and the scroll parent is the document or similar to the offset parent 5081 // we have to refresh the relative offset during the scroll so there are no jumps 5082 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 5083 this.offset.relative = this._getRelativeOffset(); 5084 } 5085 5086 /* 5087 * - Position constraining - 5088 * Constrain the position to a mix of grid, containment. 5089 */ 5090 5091 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 5092 5093 if(this.containment) { 5094 if(event.pageX - this.offset.click.left < this.containment[0]) { 5095 pageX = this.containment[0] + this.offset.click.left; 5096 } 5097 if(event.pageY - this.offset.click.top < this.containment[1]) { 5098 pageY = this.containment[1] + this.offset.click.top; 5099 } 5100 if(event.pageX - this.offset.click.left > this.containment[2]) { 5101 pageX = this.containment[2] + this.offset.click.left; 5102 } 5103 if(event.pageY - this.offset.click.top > this.containment[3]) { 5104 pageY = this.containment[3] + this.offset.click.top; 5105 } 5106 } 5107 5108 if(o.grid) { 5109 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 5110 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; 5111 5112 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 5113 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; 5114 } 5115 5116 } 5117 5118 return { 5119 top: ( 5120 pageY - // The absolute mouse position 5121 this.offset.click.top - // Click offset (relative to the element) 5122 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 5123 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 5124 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 5125 ), 5126 left: ( 5127 pageX - // The absolute mouse position 5128 this.offset.click.left - // Click offset (relative to the element) 5129 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 5130 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 5131 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 5132 ) 5133 }; 5134 5135 }, 5136 5137 _rearrange: function(event, i, a, hardRefresh) { 5138 5139 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)); 5140 5141 //Various things done here to improve the performance: 5142 // 1. we create a setTimeout, that calls refreshPositions 5143 // 2. on the instance, we have a counter variable, that get's higher after every append 5144 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 5145 // 4. this lets only the last addition to the timeout stack through 5146 this.counter = this.counter ? ++this.counter : 1; 5147 var counter = this.counter; 5148 5149 this._delay(function() { 5150 if(counter === this.counter) { 5151 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 5152 } 5153 }); 5154 5155 }, 5156 5157 _clear: function(event, noPropagation) { 5158 5159 this.reverting = false; 5160 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 5161 // everything else normalized again 5162 var i, 5163 delayedTriggers = []; 5164 5165 // We first have to update the dom position of the actual currentItem 5166 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 5167 if(!this._noFinalSort && this.currentItem.parent().length) { 5168 this.placeholder.before(this.currentItem); 5169 } 5170 this._noFinalSort = null; 5171 5172 if(this.helper[0] === this.currentItem[0]) { 5173 for(i in this._storedCSS) { 5174 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 5175 this._storedCSS[i] = ""; 5176 } 5177 } 5178 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 5179 } else { 5180 this.currentItem.show(); 5181 } 5182 5183 if(this.fromOutside && !noPropagation) { 5184 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 5185 } 5186 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 5187 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 5188 } 5189 5190 // Check if the items Container has Changed and trigger appropriate 5191 // events. 5192 if (this !== this.currentContainer) { 5193 if(!noPropagation) { 5194 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 5195 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5196 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5197 } 5198 } 5199 5200 5201 //Post events to containers 5202 function delayEvent( type, instance, container ) { 5203 return function( event ) { 5204 container._trigger( type, event, instance._uiHash( instance ) ); 5205 }; 5206 } 5207 for (i = this.containers.length - 1; i >= 0; i--){ 5208 if (!noPropagation) { 5209 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 5210 } 5211 if(this.containers[i].containerCache.over) { 5212 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 5213 this.containers[i].containerCache.over = 0; 5214 } 5215 } 5216 5217 //Do what was originally in plugins 5218 if ( this.storedCursor ) { 5219 this.document.find( "body" ).css( "cursor", this.storedCursor ); 5220 this.storedStylesheet.remove(); 5221 } 5222 if(this._storedOpacity) { 5223 this.helper.css("opacity", this._storedOpacity); 5224 } 5225 if(this._storedZIndex) { 5226 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 5227 } 5228 5229 this.dragging = false; 5230 if(this.cancelHelperRemoval) { 5231 if(!noPropagation) { 5232 this._trigger("beforeStop", event, this._uiHash()); 5233 for (i=0; i < delayedTriggers.length; i++) { 5234 delayedTriggers[i].call(this, event); 5235 } //Trigger all delayed events 5236 this._trigger("stop", event, this._uiHash()); 5237 } 5238 5239 this.fromOutside = false; 5240 return false; 5241 } 5242 5243 if(!noPropagation) { 5244 this._trigger("beforeStop", event, this._uiHash()); 5245 } 5246 5247 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 5248 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 5249 5250 if(this.helper[0] !== this.currentItem[0]) { 5251 this.helper.remove(); 5252 } 5253 this.helper = null; 5254 5255 if(!noPropagation) { 5256 for (i=0; i < delayedTriggers.length; i++) { 5257 delayedTriggers[i].call(this, event); 5258 } //Trigger all delayed events 5259 this._trigger("stop", event, this._uiHash()); 5260 } 5261 5262 this.fromOutside = false; 5263 return true; 5264 5265 }, 5266 5267 _trigger: function() { 5268 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 5269 this.cancel(); 5270 } 5271 }, 5272 5273 _uiHash: function(_inst) { 5274 var inst = _inst || this; 5275 return { 5276 helper: inst.helper, 5277 placeholder: inst.placeholder || $([]), 5278 position: inst.position, 5279 originalPosition: inst.originalPosition, 5280 offset: inst.positionAbs, 5281 item: inst.currentItem, 5282 sender: _inst ? _inst.element : null 5283 }; 5284 } 5285 5286}); 5287
vendor: 38,719 bytes, lines 5288-6728
5288})(jQuery); 5289(function( $, undefined ) { 5290 5291var uid = 0, 5292 hideProps = {}, 5293 showProps = {}; 5294 5295hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5296 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5297showProps.height = showProps.paddingTop = showProps.paddingBottom = 5298 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5299 5300$.widget( "ui.accordion", { 5301 version: "1.10.4", 5302 options: { 5303 active: 0, 5304 animate: {}, 5305 collapsible: false, 5306 event: "click", 5307 header: "> li > :first-child,> :not(li):even", 5308 heightStyle: "auto", 5309 icons: { 5310 activeHeader: "ui-icon-triangle-1-s", 5311 header: "ui-icon-triangle-1-e" 5312 }, 5313 5314 // callbacks 5315 activate: null, 5316 beforeActivate: null 5317 }, 5318 5319 _create: function() { 5320 var options = this.options; 5321 this.prevShow = this.prevHide = $(); 5322 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 5323 // ARIA 5324 .attr( "role", "tablist" ); 5325 5326 // don't allow collapsible: false and active: false / null 5327 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5328 options.active = 0; 5329 } 5330 5331 this._processPanels(); 5332 // handle negative values 5333 if ( options.active < 0 ) { 5334 options.active += this.headers.length; 5335 } 5336 this._refresh(); 5337 }, 5338 5339 _getCreateEventData: function() { 5340 return { 5341 header: this.active, 5342 panel: !this.active.length ? $() : this.active.next(), 5343 content: !this.active.length ? $() : this.active.next() 5344 }; 5345 }, 5346 5347 _createIcons: function() { 5348 var icons = this.options.icons; 5349 if ( icons ) { 5350 $( "<span>" ) 5351 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5352 .prependTo( this.headers ); 5353 this.active.children( ".ui-accordion-header-icon" ) 5354 .removeClass( icons.header ) 5355 .addClass( icons.activeHeader ); 5356 this.headers.addClass( "ui-accordion-icons" ); 5357 } 5358 }, 5359 5360 _destroyIcons: function() { 5361 this.headers 5362 .removeClass( "ui-accordion-icons" ) 5363 .children( ".ui-accordion-header-icon" ) 5364 .remove(); 5365 }, 5366 5367 _destroy: function() { 5368 var contents; 5369 5370 // clean up main element 5371 this.element 5372 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5373 .removeAttr( "role" ); 5374 5375 // clean up headers 5376 this.headers 5377 .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 5378 .removeAttr( "role" ) 5379 .removeAttr( "aria-expanded" ) 5380 .removeAttr( "aria-selected" ) 5381 .removeAttr( "aria-controls" ) 5382 .removeAttr( "tabIndex" ) 5383 .each(function() { 5384 if ( /^ui-accordion/.test( this.id ) ) { 5385 this.removeAttribute( "id" ); 5386 } 5387 }); 5388 this._destroyIcons(); 5389 5390 // clean up content panels 5391 contents = this.headers.next() 5392 .css( "display", "" ) 5393 .removeAttr( "role" ) 5394 .removeAttr( "aria-hidden" ) 5395 .removeAttr( "aria-labelledby" ) 5396 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5397 .each(function() { 5398 if ( /^ui-accordion/.test( this.id ) ) { 5399 this.removeAttribute( "id" ); 5400 } 5401 }); 5402 if ( this.options.heightStyle !== "content" ) { 5403 contents.css( "height", "" ); 5404 } 5405 }, 5406 5407 _setOption: function( key, value ) { 5408 if ( key === "active" ) { 5409 // _activate() will handle invalid values and update this.options 5410 this._activate( value ); 5411 return; 5412 } 5413 5414 if ( key === "event" ) { 5415 if ( this.options.event ) { 5416 this._off( this.headers, this.options.event ); 5417 } 5418 this._setupEvents( value ); 5419 } 5420 5421 this._super( key, value ); 5422 5423 // setting collapsible: false while collapsed; open first panel 5424 if ( key === "collapsible" && !value && this.options.active === false ) { 5425 this._activate( 0 ); 5426 } 5427 5428 if ( key === "icons" ) { 5429 this._destroyIcons(); 5430 if ( value ) { 5431 this._createIcons(); 5432 } 5433 } 5434 5435 // #5332 - opacity doesn't cascade to positioned elements in IE 5436 // so we need to add the disabled class to the headers and panels 5437 if ( key === "disabled" ) { 5438 this.headers.add( this.headers.next() ) 5439 .toggleClass( "ui-state-disabled", !!value ); 5440 } 5441 }, 5442 5443 _keydown: function( event ) { 5444 if ( event.altKey || event.ctrlKey ) { 5445 return; 5446 } 5447 5448 var keyCode = $.ui.keyCode, 5449 length = this.headers.length, 5450 currentIndex = this.headers.index( event.target ), 5451 toFocus = false; 5452 5453 switch ( event.keyCode ) { 5454 case keyCode.RIGHT: 5455 case keyCode.DOWN: 5456 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5457 break; 5458 case keyCode.LEFT: 5459 case keyCode.UP: 5460 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5461 break; 5462 case keyCode.SPACE: 5463 case keyCode.ENTER: 5464 this._eventHandler( event ); 5465 break; 5466 case keyCode.HOME: 5467 toFocus = this.headers[ 0 ]; 5468 break; 5469 case keyCode.END: 5470 toFocus = this.headers[ length - 1 ]; 5471 break; 5472 } 5473 5474 if ( toFocus ) { 5475 $( event.target ).attr( "tabIndex", -1 ); 5476 $( toFocus ).attr( "tabIndex", 0 ); 5477 toFocus.focus(); 5478 event.preventDefault(); 5479 } 5480 }, 5481 5482 _panelKeyDown : function( event ) { 5483 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5484 $( event.currentTarget ).prev().focus(); 5485 } 5486 }, 5487 5488 refresh: function() { 5489 var options = this.options; 5490 this._processPanels(); 5491 5492 // was collapsed or no panel 5493 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 5494 options.active = false; 5495 this.active = $(); 5496 // active false only when collapsible is true 5497 } else if ( options.active === false ) { 5498 this._activate( 0 ); 5499 // was active, but active panel is gone 5500 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5501 // all remaining panel are disabled 5502 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 5503 options.active = false; 5504 this.active = $(); 5505 // activate previous panel 5506 } else { 5507 this._activate( Math.max( 0, options.active - 1 ) ); 5508 } 5509 // was active, active panel still exists 5510 } else { 5511 // make sure active index is correct 5512 options.active = this.headers.index( this.active ); 5513 } 5514 5515 this._destroyIcons(); 5516 5517 this._refresh(); 5518 }, 5519 5520 _processPanels: function() { 5521 this.headers = this.element.find( this.options.header ) 5522 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 5523 5524 this.headers.next() 5525 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 5526 .filter(":not(.ui-accordion-content-active)") 5527 .hide(); 5528 }, 5529 5530 _refresh: function() { 5531 var maxHeight, 5532 options = this.options, 5533 heightStyle = options.heightStyle, 5534 parent = this.element.parent(), 5535 accordionId = this.accordionId = "ui-accordion-" + 5536 (this.element.attr( "id" ) || ++uid); 5537 5538 this.active = this._findActive( options.active ) 5539 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 5540 .removeClass( "ui-corner-all" ); 5541 this.active.next() 5542 .addClass( "ui-accordion-content-active" ) 5543 .show(); 5544 5545 this.headers 5546 .attr( "role", "tab" ) 5547 .each(function( i ) { 5548 var header = $( this ), 5549 headerId = header.attr( "id" ), 5550 panel = header.next(), 5551 panelId = panel.attr( "id" ); 5552 if ( !headerId ) { 5553 headerId = accordionId + "-header-" + i; 5554 header.attr( "id", headerId ); 5555 } 5556 if ( !panelId ) { 5557 panelId = accordionId + "-panel-" + i; 5558 panel.attr( "id", panelId ); 5559 } 5560 header.attr( "aria-controls", panelId ); 5561 panel.attr( "aria-labelledby", headerId ); 5562 }) 5563 .next() 5564 .attr( "role", "tabpanel" ); 5565 5566 this.headers 5567 .not( this.active ) 5568 .attr({ 5569 "aria-selected": "false", 5570 "aria-expanded": "false", 5571 tabIndex: -1 5572 }) 5573 .next() 5574 .attr({ 5575 "aria-hidden": "true" 5576 }) 5577 .hide(); 5578 5579 // make sure at least one header is in the tab order 5580 if ( !this.active.length ) { 5581 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5582 } else { 5583 this.active.attr({ 5584 "aria-selected": "true", 5585 "aria-expanded": "true", 5586 tabIndex: 0 5587 }) 5588 .next() 5589 .attr({ 5590 "aria-hidden": "false" 5591 }); 5592 } 5593 5594 this._createIcons(); 5595 5596 this._setupEvents( options.event ); 5597 5598 if ( heightStyle === "fill" ) { 5599 maxHeight = parent.height(); 5600 this.element.siblings( ":visible" ).each(function() { 5601 var elem = $( this ), 5602 position = elem.css( "position" ); 5603 5604 if ( position === "absolute" || position === "fixed" ) { 5605 return; 5606 } 5607 maxHeight -= elem.outerHeight( true ); 5608 }); 5609 5610 this.headers.each(function() { 5611 maxHeight -= $( this ).outerHeight( true ); 5612 }); 5613 5614 this.headers.next() 5615 .each(function() { 5616 $( this ).height( Math.max( 0, maxHeight - 5617 $( this ).innerHeight() + $( this ).height() ) ); 5618 }) 5619 .css( "overflow", "auto" ); 5620 } else if ( heightStyle === "auto" ) { 5621 maxHeight = 0; 5622 this.headers.next() 5623 .each(function() { 5624 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5625 }) 5626 .height( maxHeight ); 5627 } 5628 }, 5629 5630 _activate: function( index ) { 5631 var active = this._findActive( index )[ 0 ]; 5632 5633 // trying to activate the already active panel 5634 if ( active === this.active[ 0 ] ) { 5635 return; 5636 } 5637 5638 // trying to collapse, simulate a click on the currently active header 5639 active = active || this.active[ 0 ]; 5640 5641 this._eventHandler({ 5642 target: active, 5643 currentTarget: active, 5644 preventDefault: $.noop 5645 }); 5646 }, 5647 5648 _findActive: function( selector ) { 5649 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5650 }, 5651 5652 _setupEvents: function( event ) { 5653 var events = { 5654 keydown: "_keydown" 5655 }; 5656 if ( event ) { 5657 $.each( event.split(" "), function( index, eventName ) { 5658 events[ eventName ] = "_eventHandler"; 5659 }); 5660 } 5661 5662 this._off( this.headers.add( this.headers.next() ) ); 5663 this._on( this.headers, events ); 5664 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 5665 this._hoverable( this.headers ); 5666 this._focusable( this.headers ); 5667 }, 5668 5669 _eventHandler: function( event ) { 5670 var options = this.options, 5671 active = this.active, 5672 clicked = $( event.currentTarget ), 5673 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5674 collapsing = clickedIsActive && options.collapsible, 5675 toShow = collapsing ? $() : clicked.next(), 5676 toHide = active.next(), 5677 eventData = { 5678 oldHeader: active, 5679 oldPanel: toHide, 5680 newHeader: collapsing ? $() : clicked, 5681 newPanel: toShow 5682 }; 5683 5684 event.preventDefault(); 5685 5686 if ( 5687 // click on active header, but not collapsible 5688 ( clickedIsActive && !options.collapsible ) || 5689 // allow canceling activation 5690 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5691 return; 5692 } 5693 5694 options.active = collapsing ? false : this.headers.index( clicked ); 5695 5696 // when the call to ._toggle() comes after the class changes 5697 // it causes a very odd bug in IE 8 (see #6720) 5698 this.active = clickedIsActive ? $() : clicked; 5699 this._toggle( eventData ); 5700 5701 // switch classes 5702 // corner classes on the previously active header stay after the animation 5703 active.removeClass( "ui-accordion-header-active ui-state-active" ); 5704 if ( options.icons ) { 5705 active.children( ".ui-accordion-header-icon" ) 5706 .removeClass( options.icons.activeHeader ) 5707 .addClass( options.icons.header ); 5708 } 5709 5710 if ( !clickedIsActive ) { 5711 clicked 5712 .removeClass( "ui-corner-all" ) 5713 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 5714 if ( options.icons ) { 5715 clicked.children( ".ui-accordion-header-icon" ) 5716 .removeClass( options.icons.header ) 5717 .addClass( options.icons.activeHeader ); 5718 } 5719 5720 clicked 5721 .next() 5722 .addClass( "ui-accordion-content-active" ); 5723 } 5724 }, 5725 5726 _toggle: function( data ) { 5727 var toShow = data.newPanel, 5728 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5729 5730 // handle activating a panel during the animation for another activation 5731 this.prevShow.add( this.prevHide ).stop( true, true ); 5732 this.prevShow = toShow; 5733 this.prevHide = toHide; 5734 5735 if ( this.options.animate ) { 5736 this._animate( toShow, toHide, data ); 5737 } else { 5738 toHide.hide(); 5739 toShow.show(); 5740 this._toggleComplete( data ); 5741 } 5742 5743 toHide.attr({ 5744 "aria-hidden": "true" 5745 }); 5746 toHide.prev().attr( "aria-selected", "false" ); 5747 // if we're switching panels, remove the old header from the tab order 5748 // if we're opening from collapsed state, remove the previous header from the tab order 5749 // if we're collapsing, then keep the collapsing header in the tab order 5750 if ( toShow.length && toHide.length ) { 5751 toHide.prev().attr({ 5752 "tabIndex": -1, 5753 "aria-expanded": "false" 5754 }); 5755 } else if ( toShow.length ) { 5756 this.headers.filter(function() { 5757 return $( this ).attr( "tabIndex" ) === 0; 5758 }) 5759 .attr( "tabIndex", -1 ); 5760 } 5761 5762 toShow 5763 .attr( "aria-hidden", "false" ) 5764 .prev() 5765 .attr({ 5766 "aria-selected": "true", 5767 tabIndex: 0, 5768 "aria-expanded": "true" 5769 }); 5770 }, 5771 5772 _animate: function( toShow, toHide, data ) { 5773 var total, easing, duration, 5774 that = this, 5775 adjust = 0, 5776 down = toShow.length && 5777 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5778 animate = this.options.animate || {}, 5779 options = down && animate.down || animate, 5780 complete = function() { 5781 that._toggleComplete( data ); 5782 }; 5783 5784 if ( typeof options === "number" ) { 5785 duration = options; 5786 } 5787 if ( typeof options === "string" ) { 5788 easing = options; 5789 } 5790 // fall back from options to animation in case of partial down settings 5791 easing = easing || options.easing || animate.easing; 5792 duration = duration || options.duration || animate.duration; 5793 5794 if ( !toHide.length ) { 5795 return toShow.animate( showProps, duration, easing, complete ); 5796 } 5797 if ( !toShow.length ) { 5798 return toHide.animate( hideProps, duration, easing, complete ); 5799 } 5800 5801 total = toShow.show().outerHeight(); 5802 toHide.animate( hideProps, { 5803 duration: duration, 5804 easing: easing, 5805 step: function( now, fx ) { 5806 fx.now = Math.round( now ); 5807 } 5808 }); 5809 toShow 5810 .hide() 5811 .animate( showProps, { 5812 duration: duration, 5813 easing: easing, 5814 complete: complete, 5815 step: function( now, fx ) { 5816 fx.now = Math.round( now ); 5817 if ( fx.prop !== "height" ) { 5818 adjust += fx.now; 5819 } else if ( that.options.heightStyle !== "content" ) { 5820 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 5821 adjust = 0; 5822 } 5823 } 5824 }); 5825 }, 5826 5827 _toggleComplete: function( data ) { 5828 var toHide = data.oldPanel; 5829 5830 toHide 5831 .removeClass( "ui-accordion-content-active" ) 5832 .prev() 5833 .removeClass( "ui-corner-top" ) 5834 .addClass( "ui-corner-all" ); 5835 5836 // Work around for rendering bug in IE (#5421) 5837 if ( toHide.length ) { 5838 toHide.parent()[0].className = toHide.parent()[0].className; 5839 } 5840 this._trigger( "activate", null, data ); 5841 } 5842}); 5843 5844})( jQuery ); 5845(function( $, undefined ) { 5846 5847$.widget( "ui.autocomplete", { 5848 version: "1.10.4", 5849 defaultElement: "<input>", 5850 options: { 5851 appendTo: null, 5852 autoFocus: false, 5853 delay: 300, 5854 minLength: 1, 5855 position: { 5856 my: "left top", 5857 at: "left bottom", 5858 collision: "none" 5859 }, 5860 source: null, 5861 5862 // callbacks 5863 change: null, 5864 close: null, 5865 focus: null, 5866 open: null, 5867 response: null, 5868 search: null, 5869 select: null 5870 }, 5871 5872 requestIndex: 0, 5873 pending: 0, 5874 5875 _create: function() { 5876 // Some browsers only repeat keydown events, not keypress events, 5877 // so we use the suppressKeyPress flag to determine if we've already 5878 // handled the keydown event. #7269 5879 // Unfortunately the code for & in keypress is the same as the up arrow, 5880 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 5881 // events when we know the keydown event was used to modify the 5882 // search term. #7799 5883 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 5884 nodeName = this.element[0].nodeName.toLowerCase(), 5885 isTextarea = nodeName === "textarea", 5886 isInput = nodeName === "input"; 5887 5888 this.isMultiLine = 5889 // Textareas are always multi-line 5890 isTextarea ? true : 5891 // Inputs are always single-line, even if inside a contentEditable element 5892 // IE also treats inputs as contentEditable 5893 isInput ? false : 5894 // All other element types are determined by whether or not they're contentEditable 5895 this.element.prop( "isContentEditable" ); 5896 5897 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 5898 this.isNewMenu = true; 5899 5900 this.element 5901 .addClass( "ui-autocomplete-input" ) 5902 .attr( "autocomplete", "off" ); 5903 5904 this._on( this.element, { 5905 keydown: function( event ) { 5906 if ( this.element.prop( "readOnly" ) ) { 5907 suppressKeyPress = true; 5908 suppressInput = true; 5909 suppressKeyPressRepeat = true; 5910 return; 5911 } 5912 5913 suppressKeyPress = false; 5914 suppressInput = false; 5915 suppressKeyPressRepeat = false; 5916 var keyCode = $.ui.keyCode; 5917 switch( event.keyCode ) { 5918 case keyCode.PAGE_UP: 5919 suppressKeyPress = true; 5920 this._move( "previousPage", event ); 5921 break; 5922 case keyCode.PAGE_DOWN: 5923 suppressKeyPress = true; 5924 this._move( "nextPage", event ); 5925 break; 5926 case keyCode.UP: 5927 suppressKeyPress = true; 5928 this._keyEvent( "previous", event ); 5929 break; 5930 case keyCode.DOWN: 5931 suppressKeyPress = true; 5932 this._keyEvent( "next", event ); 5933 break; 5934 case keyCode.ENTER: 5935 case keyCode.NUMPAD_ENTER: 5936 // when menu is open and has focus 5937 if ( this.menu.active ) { 5938 // #6055 - Opera still allows the keypress to occur 5939 // which causes forms to submit 5940 suppressKeyPress = true; 5941 event.preventDefault(); 5942 this.menu.select( event ); 5943 } 5944 break; 5945 case keyCode.TAB: 5946 if ( this.menu.active ) { 5947 this.menu.select( event ); 5948 } 5949 break; 5950 case keyCode.ESCAPE: 5951 if ( this.menu.element.is( ":visible" ) ) { 5952 this._value( this.term ); 5953 this.close( event ); 5954 // Different browsers have different default behavior for escape 5955 // Single press can mean undo or clear 5956 // Double press in IE means clear the whole form 5957 event.preventDefault(); 5958 } 5959 break; 5960 default: 5961 suppressKeyPressRepeat = true; 5962 // search timeout should be triggered before the input value is changed 5963 this._searchTimeout( event ); 5964 break; 5965 } 5966 }, 5967 keypress: function( event ) { 5968 if ( suppressKeyPress ) { 5969 suppressKeyPress = false; 5970 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 5971 event.preventDefault(); 5972 } 5973 return; 5974 } 5975 if ( suppressKeyPressRepeat ) { 5976 return; 5977 } 5978 5979 // replicate some key handlers to allow them to repeat in Firefox and Opera 5980 var keyCode = $.ui.keyCode; 5981 switch( event.keyCode ) { 5982 case keyCode.PAGE_UP: 5983 this._move( "previousPage", event ); 5984 break; 5985 case keyCode.PAGE_DOWN: 5986 this._move( "nextPage", event ); 5987 break; 5988 case keyCode.UP: 5989 this._keyEvent( "previous", event ); 5990 break; 5991 case keyCode.DOWN: 5992 this._keyEvent( "next", event ); 5993 break; 5994 } 5995 }, 5996 input: function( event ) { 5997 if ( suppressInput ) { 5998 suppressInput = false; 5999 event.preventDefault(); 6000 return; 6001 } 6002 this._searchTimeout( event ); 6003 }, 6004 focus: function() { 6005 this.selectedItem = null; 6006 this.previous = this._value(); 6007 }, 6008 blur: function( event ) { 6009 if ( this.cancelBlur ) { 6010 delete this.cancelBlur; 6011 return; 6012 } 6013 6014 clearTimeout( this.searching ); 6015 this.close( event ); 6016 this._change( event ); 6017 } 6018 }); 6019 6020 this._initSource(); 6021 this.menu = $( "<ul>" ) 6022 .addClass( "ui-autocomplete ui-front" ) 6023 .appendTo( this._appendTo() ) 6024 .menu({ 6025 // disable ARIA support, the live region takes care of that 6026 role: null 6027 }) 6028 .hide() 6029 .data( "ui-menu" ); 6030 6031 this._on( this.menu.element, { 6032 mousedown: function( event ) { 6033 // prevent moving focus out of the text field 6034 event.preventDefault(); 6035 6036 // IE doesn't prevent moving focus even with event.preventDefault() 6037 // so we set a flag to know when we should ignore the blur event 6038 this.cancelBlur = true; 6039 this._delay(function() { 6040 delete this.cancelBlur; 6041 }); 6042 6043 // clicking on the scrollbar causes focus to shift to the body 6044 // but we can't detect a mouseup or a click immediately afterward 6045 // so we have to track the next mousedown and close the menu if 6046 // the user clicks somewhere outside of the autocomplete 6047 var menuElement = this.menu.element[ 0 ]; 6048 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6049 this._delay(function() { 6050 var that = this; 6051 this.document.one( "mousedown", function( event ) { 6052 if ( event.target !== that.element[ 0 ] && 6053 event.target !== menuElement && 6054 !$.contains( menuElement, event.target ) ) { 6055 that.close(); 6056 } 6057 }); 6058 }); 6059 } 6060 }, 6061 menufocus: function( event, ui ) { 6062 // support: Firefox 6063 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6064 if ( this.isNewMenu ) { 6065 this.isNewMenu = false; 6066 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6067 this.menu.blur(); 6068 6069 this.document.one( "mousemove", function() { 6070 $( event.target ).trigger( event.originalEvent ); 6071 }); 6072 6073 return; 6074 } 6075 } 6076 6077 var item = ui.item.data( "ui-autocomplete-item" ); 6078 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6079 // use value to match what will end up in the input, if it was a key event 6080 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6081 this._value( item.value ); 6082 } 6083 } else { 6084 // Normally the input is populated with the item's value as the 6085 // menu is navigated, causing screen readers to notice a change and 6086 // announce the item. Since the focus event was canceled, this doesn't 6087 // happen, so we update the live region so that screen readers can 6088 // still notice the change and announce it. 6089 this.liveRegion.text( item.value ); 6090 } 6091 }, 6092 menuselect: function( event, ui ) { 6093 var item = ui.item.data( "ui-autocomplete-item" ), 6094 previous = this.previous; 6095 6096 // only trigger when focus was lost (click on menu) 6097 if ( this.element[0] !== this.document[0].activeElement ) { 6098 this.element.focus(); 6099 this.previous = previous; 6100 // #6109 - IE triggers two focus events and the second 6101 // is asynchronous, so we need to reset the previous 6102 // term synchronously and asynchronously :-( 6103 this._delay(function() { 6104 this.previous = previous; 6105 this.selectedItem = item; 6106 }); 6107 } 6108 6109 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6110 this._value( item.value ); 6111 } 6112 // reset the term after the select event 6113 // this allows custom select handling to work properly 6114 this.term = this._value(); 6115 6116 this.close( event ); 6117 this.selectedItem = item; 6118 } 6119 }); 6120 6121 this.liveRegion = $( "<span>", { 6122 role: "status", 6123 "aria-live": "polite" 6124 }) 6125 .addClass( "ui-helper-hidden-accessible" ) 6126 .insertBefore( this.element ); 6127 6128 // turning off autocomplete prevents the browser from remembering the 6129 // value when navigating through history, so we re-enable autocomplete 6130 // if the page is unloaded before the widget is destroyed. #7790 6131 this._on( this.window, { 6132 beforeunload: function() { 6133 this.element.removeAttr( "autocomplete" ); 6134 } 6135 }); 6136 }, 6137 6138 _destroy: function() { 6139 clearTimeout( this.searching ); 6140 this.element 6141 .removeClass( "ui-autocomplete-input" ) 6142 .removeAttr( "autocomplete" ); 6143 this.menu.element.remove(); 6144 this.liveRegion.remove(); 6145 }, 6146 6147 _setOption: function( key, value ) { 6148 this._super( key, value ); 6149 if ( key === "source" ) { 6150 this._initSource(); 6151 } 6152 if ( key === "appendTo" ) { 6153 this.menu.element.appendTo( this._appendTo() ); 6154 } 6155 if ( key === "disabled" && value && this.xhr ) { 6156 this.xhr.abort(); 6157 } 6158 }, 6159 6160 _appendTo: function() { 6161 var element = this.options.appendTo; 6162 6163 if ( element ) { 6164 element = element.jquery || element.nodeType ? 6165 $( element ) : 6166 this.document.find( element ).eq( 0 ); 6167 } 6168 6169 if ( !element ) { 6170 element = this.element.closest( ".ui-front" ); 6171 } 6172 6173 if ( !element.length ) { 6174 element = this.document[0].body; 6175 } 6176 6177 return element; 6178 }, 6179 6180 _initSource: function() { 6181 var array, url, 6182 that = this; 6183 if ( $.isArray(this.options.source) ) { 6184 array = this.options.source; 6185 this.source = function( request, response ) { 6186 response( $.ui.autocomplete.filter( array, request.term ) ); 6187 }; 6188 } else if ( typeof this.options.source === "string" ) { 6189 url = this.options.source; 6190 this.source = function( request, response ) { 6191 if ( that.xhr ) { 6192 that.xhr.abort(); 6193 } 6194 that.xhr = $.ajax({ 6195 url: url, 6196 data: request, 6197 dataType: "json", 6198 success: function( data ) { 6199 response( data ); 6200 }, 6201 error: function() { 6202 response( [] ); 6203 } 6204 }); 6205 }; 6206 } else { 6207 this.source = this.options.source; 6208 } 6209 }, 6210 6211 _searchTimeout: function( event ) { 6212 clearTimeout( this.searching ); 6213 this.searching = this._delay(function() { 6214 // only search if the value has changed 6215 if ( this.term !== this._value() ) { 6216 this.selectedItem = null; 6217 this.search( null, event ); 6218 } 6219 }, this.options.delay ); 6220 }, 6221 6222 search: function( value, event ) { 6223 value = value != null ? value : this._value(); 6224 6225 // always save the actual value, not the one passed as an argument 6226 this.term = this._value(); 6227 6228 if ( value.length < this.options.minLength ) { 6229 return this.close( event ); 6230 } 6231 6232 if ( this._trigger( "search", event ) === false ) { 6233 return; 6234 } 6235 6236 return this._search( value ); 6237 }, 6238 6239 _search: function( value ) { 6240 this.pending++; 6241 this.element.addClass( "ui-autocomplete-loading" ); 6242 this.cancelSearch = false; 6243 6244 this.source( { term: value }, this._response() ); 6245 }, 6246 6247 _response: function() { 6248 var index = ++this.requestIndex; 6249 6250 return $.proxy(function( content ) { 6251 if ( index === this.requestIndex ) { 6252 this.__response( content ); 6253 } 6254 6255 this.pending--; 6256 if ( !this.pending ) { 6257 this.element.removeClass( "ui-autocomplete-loading" ); 6258 } 6259 }, this ); 6260 }, 6261 6262 __response: function( content ) { 6263 if ( content ) { 6264 content = this._normalize( content ); 6265 } 6266 this._trigger( "response", null, { content: content } ); 6267 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6268 this._suggest( content ); 6269 this._trigger( "open" ); 6270 } else { 6271 // use ._close() instead of .close() so we don't cancel future searches 6272 this._close(); 6273 } 6274 }, 6275 6276 close: function( event ) { 6277 this.cancelSearch = true; 6278 this._close( event ); 6279 }, 6280 6281 _close: function( event ) { 6282 if ( this.menu.element.is( ":visible" ) ) { 6283 this.menu.element.hide(); 6284 this.menu.blur(); 6285 this.isNewMenu = true; 6286 this._trigger( "close", event ); 6287 } 6288 }, 6289 6290 _change: function( event ) { 6291 if ( this.previous !== this._value() ) { 6292 this._trigger( "change", event, { item: this.selectedItem } ); 6293 } 6294 }, 6295 6296 _normalize: function( items ) { 6297 // assume all items have the right format when the first item is complete 6298 if ( items.length && items[0].label && items[0].value ) { 6299 return items; 6300 } 6301 return $.map( items, function( item ) { 6302 if ( typeof item === "string" ) { 6303 return { 6304 label: item, 6305 value: item 6306 }; 6307 } 6308 return $.extend({ 6309 label: item.label || item.value, 6310 value: item.value || item.label 6311 }, item ); 6312 }); 6313 }, 6314 6315 _suggest: function( items ) { 6316 var ul = this.menu.element.empty(); 6317 this._renderMenu( ul, items ); 6318 this.isNewMenu = true; 6319 this.menu.refresh(); 6320 6321 // size and position menu 6322 ul.show(); 6323 this._resizeMenu(); 6324 ul.position( $.extend({ 6325 of: this.element 6326 }, this.options.position )); 6327 6328 if ( this.options.autoFocus ) { 6329 this.menu.next(); 6330 } 6331 }, 6332 6333 _resizeMenu: function() { 6334 var ul = this.menu.element; 6335 ul.outerWidth( Math.max( 6336 // Firefox wraps long text (possibly a rounding bug) 6337 // so we add 1px to avoid the wrapping (#7513) 6338 ul.width( "" ).outerWidth() + 1, 6339 this.element.outerWidth() 6340 ) ); 6341 }, 6342 6343 _renderMenu: function( ul, items ) { 6344 var that = this; 6345 $.each( items, function( index, item ) { 6346 that._renderItemData( ul, item ); 6347 }); 6348 }, 6349 6350 _renderItemData: function( ul, item ) { 6351 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6352 }, 6353 6354 _renderItem: function( ul, item ) { 6355 return $( "<li>" ) 6356 .append( $( "<a>" ).text( item.label ) ) 6357 .appendTo( ul ); 6358 }, 6359 6360 _move: function( direction, event ) { 6361 if ( !this.menu.element.is( ":visible" ) ) { 6362 this.search( null, event ); 6363 return; 6364 } 6365 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6366 this.menu.isLastItem() && /^next/.test( direction ) ) { 6367 this._value( this.term ); 6368 this.menu.blur(); 6369 return; 6370 } 6371 this.menu[ direction ]( event ); 6372 }, 6373 6374 widget: function() { 6375 return this.menu.element; 6376 }, 6377 6378 _value: function() { 6379 return this.valueMethod.apply( this.element, arguments ); 6380 }, 6381 6382 _keyEvent: function( keyEvent, event ) { 6383 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6384 this._move( keyEvent, event ); 6385 6386 // prevents moving cursor to beginning/end of the text field in some browsers 6387 event.preventDefault(); 6388 } 6389 } 6390}); 6391 6392$.extend( $.ui.autocomplete, { 6393 escapeRegex: function( value ) { 6394 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6395 }, 6396 filter: function(array, term) { 6397 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 6398 return $.grep( array, function(value) { 6399 return matcher.test( value.label || value.value || value ); 6400 }); 6401 } 6402}); 6403 6404 6405// live region extension, adding a `messages` option 6406// NOTE: This is an experimental API. We are still investigating 6407// a full solution for string manipulation and internationalization. 6408$.widget( "ui.autocomplete", $.ui.autocomplete, { 6409 options: { 6410 messages: { 6411 noResults: "No search results.", 6412 results: function( amount ) { 6413 return amount + ( amount > 1 ? " results are" : " result is" ) + 6414 " available, use up and down arrow keys to navigate."; 6415 } 6416 } 6417 }, 6418 6419 __response: function( content ) { 6420 var message; 6421 this._superApply( arguments ); 6422 if ( this.options.disabled || this.cancelSearch ) { 6423 return; 6424 } 6425 if ( content && content.length ) { 6426 message = this.options.messages.results( content.length ); 6427 } else { 6428 message = this.options.messages.noResults; 6429 } 6430 this.liveRegion.text( message ); 6431 } 6432}); 6433 6434}( jQuery )); 6435(function( $, undefined ) { 6436 6437var lastActive, 6438 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6439 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", 6440 formResetHandler = function() { 6441 var form = $( this ); 6442 setTimeout(function() { 6443 form.find( ":ui-button" ).button( "refresh" ); 6444 }, 1 ); 6445 }, 6446 radioGroup = function( radio ) { 6447 var name = radio.name, 6448 form = radio.form, 6449 radios = $( [] ); 6450 if ( name ) { 6451 name = name.replace( /'/g, "\\'" ); 6452 if ( form ) { 6453 radios = $( form ).find( "[name='" + name + "']" ); 6454 } else { 6455 radios = $( "[name='" + name + "']", radio.ownerDocument ) 6456 .filter(function() { 6457 return !this.form; 6458 }); 6459 } 6460 } 6461 return radios; 6462 }; 6463 6464$.widget( "ui.button", { 6465 version: "1.10.4", 6466 defaultElement: "<button>", 6467 options: { 6468 disabled: null, 6469 text: true, 6470 label: null, 6471 icons: { 6472 primary: null, 6473 secondary: null 6474 } 6475 }, 6476 _create: function() { 6477 this.element.closest( "form" ) 6478 .unbind( "reset" + this.eventNamespace ) 6479 .bind( "reset" + this.eventNamespace, formResetHandler ); 6480 6481 if ( typeof this.options.disabled !== "boolean" ) { 6482 this.options.disabled = !!this.element.prop( "disabled" ); 6483 } else { 6484 this.element.prop( "disabled", this.options.disabled ); 6485 } 6486 6487 this._determineButtonType(); 6488 this.hasTitle = !!this.buttonElement.attr( "title" ); 6489 6490 var that = this, 6491 options = this.options, 6492 toggleButton = this.type === "checkbox" || this.type === "radio", 6493 activeClass = !toggleButton ? "ui-state-active" : ""; 6494 6495 if ( options.label === null ) { 6496 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6497 } 6498 6499 this._hoverable( this.buttonElement ); 6500 6501 this.buttonElement 6502 .addClass( baseClasses ) 6503 .attr( "role", "button" ) 6504 .bind( "mouseenter" + this.eventNamespace, function() { 6505 if ( options.disabled ) { 6506 return; 6507 } 6508 if ( this === lastActive ) { 6509 $( this ).addClass( "ui-state-active" ); 6510 } 6511 }) 6512 .bind( "mouseleave" + this.eventNamespace, function() { 6513 if ( options.disabled ) { 6514 return; 6515 } 6516 $( this ).removeClass( activeClass ); 6517 }) 6518 .bind( "click" + this.eventNamespace, function( event ) { 6519 if ( options.disabled ) { 6520 event.preventDefault(); 6521 event.stopImmediatePropagation(); 6522 } 6523 }); 6524 6525 // Can't use _focusable() because the element that receives focus 6526 // and the element that gets the ui-state-focus class are different 6527 this._on({ 6528 focus: function() { 6529 this.buttonElement.addClass( "ui-state-focus" ); 6530 }, 6531 blur: function() { 6532 this.buttonElement.removeClass( "ui-state-focus" ); 6533 } 6534 }); 6535 6536 if ( toggleButton ) { 6537 this.element.bind( "change" + this.eventNamespace, function() { 6538 that.refresh(); 6539 }); 6540 } 6541 6542 if ( this.type === "checkbox" ) { 6543 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6544 if ( options.disabled ) { 6545 return false; 6546 } 6547 }); 6548 } else if ( this.type === "radio" ) { 6549 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6550 if ( options.disabled ) { 6551 return false; 6552 } 6553 $( this ).addClass( "ui-state-active" ); 6554 that.buttonElement.attr( "aria-pressed", "true" ); 6555 6556 var radio = that.element[ 0 ]; 6557 radioGroup( radio ) 6558 .not( radio ) 6559 .map(function() { 6560 return $( this ).button( "widget" )[ 0 ]; 6561 }) 6562 .removeClass( "ui-state-active" ) 6563 .attr( "aria-pressed", "false" ); 6564 }); 6565 } else { 6566 this.buttonElement 6567 .bind( "mousedown" + this.eventNamespace, function() { 6568 if ( options.disabled ) { 6569 return false; 6570 } 6571 $( this ).addClass( "ui-state-active" ); 6572 lastActive = this; 6573 that.document.one( "mouseup", function() { 6574 lastActive = null; 6575 }); 6576 }) 6577 .bind( "mouseup" + this.eventNamespace, function() { 6578 if ( options.disabled ) { 6579 return false; 6580 } 6581 $( this ).removeClass( "ui-state-active" ); 6582 }) 6583 .bind( "keydown" + this.eventNamespace, function(event) { 6584 if ( options.disabled ) { 6585 return false; 6586 } 6587 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 6588 $( this ).addClass( "ui-state-active" ); 6589 } 6590 }) 6591 // see #8559, we bind to blur here in case the button element loses 6592 // focus between keydown and keyup, it would be left in an "active" state 6593 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 6594 $( this ).removeClass( "ui-state-active" ); 6595 }); 6596 6597 if ( this.buttonElement.is("a") ) { 6598 this.buttonElement.keyup(function(event) { 6599 if ( event.keyCode === $.ui.keyCode.SPACE ) { 6600 // TODO pass through original event correctly (just as 2nd argument doesn't work) 6601 $( this ).click(); 6602 } 6603 }); 6604 } 6605 } 6606 6607 // TODO: pull out $.Widget's handling for the disabled option into 6608 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 6609 // be overridden by individual plugins 6610 this._setOption( "disabled", options.disabled ); 6611 this._resetButton(); 6612 }, 6613 6614 _determineButtonType: function() { 6615 var ancestor, labelSelector, checked; 6616 6617 if ( this.element.is("[type=checkbox]") ) { 6618 this.type = "checkbox"; 6619 } else if ( this.element.is("[type=radio]") ) { 6620 this.type = "radio"; 6621 } else if ( this.element.is("input") ) { 6622 this.type = "input"; 6623 } else { 6624 this.type = "button"; 6625 } 6626 6627 if ( this.type === "checkbox" || this.type === "radio" ) { 6628 // we don't search against the document in case the element 6629 // is disconnected from the DOM 6630 ancestor = this.element.parents().last(); 6631 labelSelector = "label[for='" + this.element.attr("id") + "']"; 6632 this.buttonElement = ancestor.find( labelSelector ); 6633 if ( !this.buttonElement.length ) { 6634 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 6635 this.buttonElement = ancestor.filter( labelSelector ); 6636 if ( !this.buttonElement.length ) { 6637 this.buttonElement = ancestor.find( labelSelector ); 6638 } 6639 } 6640 this.element.addClass( "ui-helper-hidden-accessible" ); 6641 6642 checked = this.element.is( ":checked" ); 6643 if ( checked ) { 6644 this.buttonElement.addClass( "ui-state-active" ); 6645 } 6646 this.buttonElement.prop( "aria-pressed", checked ); 6647 } else { 6648 this.buttonElement = this.element; 6649 } 6650 }, 6651 6652 widget: function() { 6653 return this.buttonElement; 6654 }, 6655 6656 _destroy: function() { 6657 this.element 6658 .removeClass( "ui-helper-hidden-accessible" ); 6659 this.buttonElement 6660 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 6661 .removeAttr( "role" ) 6662 .removeAttr( "aria-pressed" ) 6663 .html( this.buttonElement.find(".ui-button-text").html() ); 6664 6665 if ( !this.hasTitle ) { 6666 this.buttonElement.removeAttr( "title" ); 6667 } 6668 }, 6669 6670 _setOption: function( key, value ) { 6671 this._super( key, value ); 6672 if ( key === "disabled" ) { 6673 this.element.prop( "disabled", !!value ); 6674 if ( value ) { 6675 this.buttonElement.removeClass( "ui-state-focus" ); 6676 } 6677 return; 6678 } 6679 this._resetButton(); 6680 }, 6681 6682 refresh: function() { 6683 //See #8237 & #8828 6684 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 6685 6686 if ( isDisabled !== this.options.disabled ) { 6687 this._setOption( "disabled", isDisabled ); 6688 } 6689 if ( this.type === "radio" ) { 6690 radioGroup( this.element[0] ).each(function() { 6691 if ( $( this ).is( ":checked" ) ) { 6692 $( this ).button( "widget" ) 6693 .addClass( "ui-state-active" ) 6694 .attr( "aria-pressed", "true" ); 6695 } else { 6696 $( this ).button( "widget" ) 6697 .removeClass( "ui-state-active" ) 6698 .attr( "aria-pressed", "false" ); 6699 } 6700 }); 6701 } else if ( this.type === "checkbox" ) { 6702 if ( this.element.is( ":checked" ) ) { 6703 this.buttonElement 6704 .addClass( "ui-state-active" ) 6705 .attr( "aria-pressed", "true" ); 6706 } else { 6707 this.buttonElement 6708 .removeClass( "ui-state-active" ) 6709 .attr( "aria-pressed", "false" ); 6710 } 6711 } 6712 }, 6713 6714 _resetButton: function() { 6715 if ( this.type === "input" ) { 6716 if ( this.options.label ) { 6717 this.element.val( this.options.label ); 6718 } 6719 return; 6720 } 6721 var buttonElement = this.buttonElement.removeClass( typeClasses ), 6722 buttonText = $( "<span></span>", this.document[0] ) 6723 .addClass( "ui-button-text" ) 6724 .html( this.options.label ) 6725 .appendTo( buttonElement.empty() ) 6726 .text(), 6727 icons = this.options.icons, 6728 multipleIcons = icons.primary && icons.secondary,
vendor: 4,940 bytes, lines 6729-6858
6729 buttonClasses = []; 6730 6731 if ( icons.primary || icons.secondary ) { 6732 if ( this.options.text ) { 6733 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 6734 } 6735 6736 if ( icons.primary ) { 6737 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 6738 } 6739 6740 if ( icons.secondary ) { 6741 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 6742 } 6743 6744 if ( !this.options.text ) { 6745 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 6746 6747 if ( !this.hasTitle ) { 6748 buttonElement.attr( "title", $.trim( buttonText ) ); 6749 } 6750 } 6751 } else { 6752 buttonClasses.push( "ui-button-text-only" ); 6753 } 6754 buttonElement.addClass( buttonClasses.join( " " ) ); 6755 } 6756}); 6757 6758$.widget( "ui.buttonset", { 6759 version: "1.10.4", 6760 options: { 6761 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 6762 }, 6763 6764 _create: function() { 6765 this.element.addClass( "ui-buttonset" ); 6766 }, 6767 6768 _init: function() { 6769 this.refresh(); 6770 }, 6771 6772 _setOption: function( key, value ) { 6773 if ( key === "disabled" ) { 6774 this.buttons.button( "option", key, value ); 6775 } 6776 6777 this._super( key, value ); 6778 }, 6779 6780 refresh: function() { 6781 var rtl = this.element.css( "direction" ) === "rtl"; 6782 6783 this.buttons = this.element.find( this.options.items ) 6784 .filter( ":ui-button" ) 6785 .button( "refresh" ) 6786 .end() 6787 .not( ":ui-button" ) 6788 .button() 6789 .end() 6790 .map(function() { 6791 return $( this ).button( "widget" )[ 0 ]; 6792 }) 6793 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 6794 .filter( ":first" ) 6795 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 6796 .end() 6797 .filter( ":last" ) 6798 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 6799 .end() 6800 .end(); 6801 }, 6802 6803 _destroy: function() { 6804 this.element.removeClass( "ui-buttonset" ); 6805 this.buttons 6806 .map(function() { 6807 return $( this ).button( "widget" )[ 0 ]; 6808 }) 6809 .removeClass( "ui-corner-left ui-corner-right" ) 6810 .end() 6811 .button( "destroy" ); 6812 } 6813}); 6814 6815}( jQuery ) ); 6816(function( $, undefined ) { 6817 6818$.extend($.ui, { datepicker: { version: "1.10.4" } }); 6819 6820var PROP_NAME = "datepicker", 6821 instActive; 6822 6823/* Date picker manager. 6824 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 6825 Settings for (groups of) date pickers are maintained in an instance object, 6826 allowing multiple different settings on the same page. */ 6827 6828function Datepicker() { 6829 this._curInst = null; // The current instance in use 6830 this._keyEvent = false; // If the last event was a key event 6831 this._disabledInputs = []; // List of date picker inputs that have been disabled 6832 this._datepickerShowing = false; // True if the popup picker is showing , false if not 6833 this._inDialog = false; // True if showing within a "dialog", false if not 6834 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 6835 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 6836 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 6837 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 6838 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 6839 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 6840 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 6841 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 6842 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 6843 this.regional = []; // Available regional settings, indexed by language code 6844 this.regional[""] = { // Default regional settings 6845 closeText: "ë«ê¸°", // Display text for close link 6846 prevText: "ì´ì ", // Display text for previous month link 6847 nextText: "ë¤ì", // Display text for next month link 6848 currentText: "ì¤ë", // Display text for current month link 6849 monthNames: ['1ì','2ì','3ì','4ì','5ì','6ì','7ì','8ì','9ì','10ì','11ì','12ì'], // Names of months for drop-down and formatting 6850 monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], // For formatting 6851 dayNames: ['ì¼1','ì','í','ì','목','ê¸','í '], // For formatting 6852 dayNamesShort: ['ì¼','ì','í','ì','목','ê¸','í '], // For formatting 6853 dayNamesMin: ['ì¼','ì','í','ì','목','ê¸','í '], // Column headings for days starting at Sunday 6854 weekHeader: "Wk", // Column header for week of the year 6855 dateFormat: "yy-mm-dd", // See format options on parseDate 6856 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 6857 isRTL: false, // True if right-to-left language, false if left-to-right 6858 showMonthAfterYear: tru
vendor: 73,206 bytes, lines 6858-8837
6858e, // True if the year select precedes month, false for month then year 6859 yearSuffix: "" // Additional text to append to the year in the month headers 6860 }; 6861 this._defaults = { // Global defaults for all the date picker instances 6862 showOn: "focus", // "focus" for popup on focus, 6863 // "button" for trigger button, or "both" for either 6864 showAnim: "fadeIn", // Name of jQuery animation for popup 6865 showOptions: {}, // Options for enhanced animations 6866 defaultDate: null, // Used when field is blank: actual date, 6867 // +/-number for offset from today, null for today 6868 appendText: "", // Display text following the input box, e.g. showing the format 6869 buttonText: "...", // Text for trigger button 6870 buttonImage: "", // URL for trigger button image 6871 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 6872 hideIfNoPrevNext: false, // True to hide next/previous month links 6873 // if not applicable, false to just disable them 6874 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 6875 gotoCurrent: false, // True if today link goes back to current selection instead 6876 changeMonth: false, // True if month can be selected directly, false if only prev/next 6877 changeYear: false, // True if year can be selected directly, false if only prev/next 6878 yearRange: "c-10:c+10", // Range of years to display in drop-down, 6879 // either relative to today's year (-nn:+nn), relative to currently displayed year 6880 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 6881 showOtherMonths: false, // True to show dates in other months, false to leave blank 6882 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 6883 showWeek: false, // True to show week of the year, false to not show it 6884 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 6885 // takes a Date and returns the number of the week for it 6886 shortYearCutoff: "+10", // Short year values < this are in the current century, 6887 // > this are in the previous century, 6888 // string value starting with "+" for current year + value 6889 minDate: null, // The earliest selectable date, or null for no limit 6890 maxDate: null, // The latest selectable date, or null for no limit 6891 duration: "fast", // Duration of display/closure 6892 beforeShowDay: null, // Function that takes a date and returns an array with 6893 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 6894 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 6895 beforeShow: null, // Function that takes an input field and 6896 // returns a set of custom settings for the date picker 6897 onSelect: null, // Define a callback function when a date is selected 6898 onChangeMonthYear: null, // Define a callback function when the month or year is changed 6899 onClose: null, // Define a callback function when the datepicker is closed 6900 numberOfMonths: 1, // Number of months to show at a time 6901 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 6902 stepMonths: 1, // Number of months to step back/forward 6903 stepBigMonths: 12, // Number of months to step back/forward for the big links 6904 altField: "", // Selector for an alternate field to store selected dates into 6905 altFormat: "", // The date format to use for the alternate field 6906 constrainInput: true, // The input is constrained by the current date format 6907 showButtonPanel: false, // True to show button panel, false to not show it 6908 autoSize: false, // True to size the input for the date format, false to leave as is 6909 disabled: false // The initial disabled state 6910 }; 6911 $.extend(this._defaults, this.regional[""]); 6912 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 6913} 6914 6915$.extend(Datepicker.prototype, { 6916 /* Class name added to elements to indicate already configured with a date picker. */ 6917 markerClassName: "hasDatepicker", 6918 6919 //Keep track of the maximum number of rows displayed (see #7043) 6920 maxRows: 4, 6921 6922 // TODO rename to "widget" when switching to widget factory 6923 _widgetDatepicker: function() { 6924 return this.dpDiv; 6925 }, 6926 6927 /* Override the default settings for all instances of the date picker. 6928 * @param settings object - the new settings to use as defaults (anonymous object) 6929 * @return the manager object 6930 */ 6931 setDefaults: function(settings) { 6932 extendRemove(this._defaults, settings || {}); 6933 return this; 6934 }, 6935 6936 /* Attach the date picker to a jQuery selection. 6937 * @param target element - the target input field or division or span 6938 * @param settings object - the new settings to use for this date picker instance (anonymous) 6939 */ 6940 _attachDatepicker: function(target, settings) { 6941 var nodeName, inline, inst; 6942 nodeName = target.nodeName.toLowerCase(); 6943 inline = (nodeName === "div" || nodeName === "span"); 6944 if (!target.id) { 6945 this.uuid += 1; 6946 target.id = "dp" + this.uuid; 6947 } 6948 inst = this._newInst($(target), inline); 6949 inst.settings = $.extend({}, settings || {}); 6950 if (nodeName === "input") { 6951 this._connectDatepicker(target, inst); 6952 } else if (inline) { 6953 this._inlineDatepicker(target, inst); 6954 } 6955 }, 6956 6957 /* Create a new instance object. */ 6958 _newInst: function(target, inline) { 6959 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 6960 return {id: id, input: target, // associated target 6961 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 6962 drawMonth: 0, drawYear: 0, // month being drawn 6963 inline: inline, // is datepicker inline or not 6964 dpDiv: (!inline ? this.dpDiv : // presentation div 6965 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 6966 }, 6967 6968 /* Attach the date picker to an input field. */ 6969 _connectDatepicker: function(target, inst) { 6970 var input = $(target); 6971 inst.append = $([]); 6972 inst.trigger = $([]); 6973 if (input.hasClass(this.markerClassName)) { 6974 return; 6975 } 6976 this._attachments(input, inst); 6977 input.addClass(this.markerClassName).keydown(this._doKeyDown). 6978 keypress(this._doKeyPress).keyup(this._doKeyUp); 6979 this._autoSize(inst); 6980 $.data(target, PROP_NAME, inst); 6981 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 6982 if( inst.settings.disabled ) { 6983 this._disableDatepicker( target ); 6984 } 6985 }, 6986 6987 /* Make attachments based on settings. */ 6988 _attachments: function(input, inst) { 6989 var showOn, buttonText, buttonImage, 6990 appendText = this._get(inst, "appendText"), 6991 isRTL = this._get(inst, "isRTL"); 6992 6993 if (inst.append) { 6994 inst.append.remove(); 6995 } 6996 if (appendText) { 6997 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 6998 input[isRTL ? "before" : "after"](inst.append); 6999 } 7000 7001 input.unbind("focus", this._showDatepicker); 7002 7003 if (inst.trigger) { 7004 inst.trigger.remove(); 7005 } 7006 7007 showOn = this._get(inst, "showOn"); 7008 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7009 input.focus(this._showDatepicker); 7010 } 7011 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7012 buttonText = this._get(inst, "buttonText"); 7013 buttonImage = this._get(inst, "buttonImage"); 7014 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7015 $("<img/>").addClass(this._triggerClass). 7016 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7017 $("<button type='button'></button>").addClass(this._triggerClass). 7018 html(!buttonImage ? buttonText : $("<img/>").attr( 7019 { src:buttonImage, alt:buttonText, title:buttonText }))); 7020 input[isRTL ? "before" : "after"](inst.trigger); 7021 inst.trigger.click(function() { 7022 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7023 $.datepicker._hideDatepicker(); 7024 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7025 $.datepicker._hideDatepicker(); 7026 $.datepicker._showDatepicker(input[0]); 7027 } else { 7028 $.datepicker._showDatepicker(input[0]); 7029 } 7030 return false; 7031 }); 7032 } 7033 }, 7034 7035 /* Apply the maximum length for the date format. */ 7036 _autoSize: function(inst) { 7037 if (this._get(inst, "autoSize") && !inst.inline) { 7038 var findMax, max, maxI, i, 7039 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7040 dateFormat = this._get(inst, "dateFormat"); 7041 7042 if (dateFormat.match(/[DM]/)) { 7043 findMax = function(names) { 7044 max = 0; 7045 maxI = 0; 7046 for (i = 0; i < names.length; i++) { 7047 if (names[i].length > max) { 7048 max = names[i].length; 7049 maxI = i; 7050 } 7051 } 7052 return maxI; 7053 }; 7054 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7055 "monthNames" : "monthNamesShort")))); 7056 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7057 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7058 } 7059 inst.input.attr("size", this._formatDate(inst, date).length); 7060 } 7061 }, 7062 7063 /* Attach an inline date picker to a div. */ 7064 _inlineDatepicker: function(target, inst) { 7065 var divSpan = $(target); 7066 if (divSpan.hasClass(this.markerClassName)) { 7067 return; 7068 } 7069 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7070 $.data(target, PROP_NAME, inst); 7071 this._setDate(inst, this._getDefaultDate(inst), true); 7072 this._updateDatepicker(inst); 7073 this._updateAlternate(inst); 7074 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7075 if( inst.settings.disabled ) { 7076 this._disableDatepicker( target ); 7077 } 7078 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7079 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7080 inst.dpDiv.css( "display", "block" ); 7081 }, 7082 7083 /* Pop-up the date picker in a "dialog" box. 7084 * @param input element - ignored 7085 * @param date string or Date - the initial date to display 7086 * @param onSelect function - the function to call when a date is selected 7087 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7088 * @param pos int[2] - coordinates for the dialog's position within the screen or 7089 * event - with x/y coordinates or 7090 * leave empty for default (screen centre) 7091 * @return the manager object 7092 */ 7093 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7094 var id, browserWidth, browserHeight, scrollX, scrollY, 7095 inst = this._dialogInst; // internal instance 7096 7097 if (!inst) { 7098 this.uuid += 1; 7099 id = "dp" + this.uuid; 7100 this._dialogInput = $("<input type='text' id='" + id + 7101 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7102 this._dialogInput.keydown(this._doKeyDown); 7103 $("body").append(this._dialogInput); 7104 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7105 inst.settings = {}; 7106 $.data(this._dialogInput[0], PROP_NAME, inst); 7107 } 7108 extendRemove(inst.settings, settings || {}); 7109 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7110 this._dialogInput.val(date); 7111 7112 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7113 if (!this._pos) { 7114 browserWidth = document.documentElement.clientWidth; 7115 browserHeight = document.documentElement.clientHeight; 7116 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7117 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7118 this._pos = // should use actual width/height below 7119 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7120 } 7121 7122 // move input on screen for focus, but hidden behind dialog 7123 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7124 inst.settings.onSelect = onSelect; 7125 this._inDialog = true; 7126 this.dpDiv.addClass(this._dialogClass); 7127 this._showDatepicker(this._dialogInput[0]); 7128 if ($.blockUI) { 7129 $.blockUI(this.dpDiv); 7130 } 7131 $.data(this._dialogInput[0], PROP_NAME, inst); 7132 return this; 7133 }, 7134 7135 /* Detach a datepicker from its control. 7136 * @param target element - the target input field or division or span 7137 */ 7138 _destroyDatepicker: function(target) { 7139 var nodeName, 7140 $target = $(target), 7141 inst = $.data(target, PROP_NAME); 7142 7143 if (!$target.hasClass(this.markerClassName)) { 7144 return; 7145 } 7146 7147 nodeName = target.nodeName.toLowerCase(); 7148 $.removeData(target, PROP_NAME); 7149 if (nodeName === "input") { 7150 inst.append.remove(); 7151 inst.trigger.remove(); 7152 $target.removeClass(this.markerClassName). 7153 unbind("focus", this._showDatepicker). 7154 unbind("keydown", this._doKeyDown). 7155 unbind("keypress", this._doKeyPress). 7156 unbind("keyup", this._doKeyUp); 7157 } else if (nodeName === "div" || nodeName === "span") { 7158 $target.removeClass(this.markerClassName).empty(); 7159 } 7160 }, 7161 7162 /* Enable the date picker to a jQuery selection. 7163 * @param target element - the target input field or division or span 7164 */ 7165 _enableDatepicker: function(target) { 7166 var nodeName, inline, 7167 $target = $(target), 7168 inst = $.data(target, PROP_NAME); 7169 7170 if (!$target.hasClass(this.markerClassName)) { 7171 return; 7172 } 7173 7174 nodeName = target.nodeName.toLowerCase(); 7175 if (nodeName === "input") { 7176 target.disabled = false; 7177 inst.trigger.filter("button"). 7178 each(function() { this.disabled = false; }).end(). 7179 filter("img").css({opacity: "1.0", cursor: ""}); 7180 } else if (nodeName === "div" || nodeName === "span") { 7181 inline = $target.children("." + this._inlineClass); 7182 inline.children().removeClass("ui-state-disabled"); 7183 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7184 prop("disabled", false); 7185 } 7186 this._disabledInputs = $.map(this._disabledInputs, 7187 function(value) { return (value === target ? null : value); }); // delete entry 7188 }, 7189 7190 /* Disable the date picker to a jQuery selection. 7191 * @param target element - the target input field or division or span 7192 */ 7193 _disableDatepicker: function(target) { 7194 var nodeName, inline, 7195 $target = $(target), 7196 inst = $.data(target, PROP_NAME); 7197 7198 if (!$target.hasClass(this.markerClassName)) { 7199 return; 7200 } 7201 7202 nodeName = target.nodeName.toLowerCase(); 7203 if (nodeName === "input") { 7204 target.disabled = true; 7205 inst.trigger.filter("button"). 7206 each(function() { this.disabled = true; }).end(). 7207 filter("img").css({opacity: "0.5", cursor: "default"}); 7208 } else if (nodeName === "div" || nodeName === "span") { 7209 inline = $target.children("." + this._inlineClass); 7210 inline.children().addClass("ui-state-disabled"); 7211 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7212 prop("disabled", true); 7213 } 7214 this._disabledInputs = $.map(this._disabledInputs, 7215 function(value) { return (value === target ? null : value); }); // delete entry 7216 this._disabledInputs[this._disabledInputs.length] = target; 7217 }, 7218 7219 /* Is the first field in a jQuery collection disabled as a datepicker? 7220 * @param target element - the target input field or division or span 7221 * @return boolean - true if disabled, false if enabled 7222 */ 7223 _isDisabledDatepicker: function(target) { 7224 if (!target) { 7225 return false; 7226 } 7227 for (var i = 0; i < this._disabledInputs.length; i++) { 7228 if (this._disabledInputs[i] === target) { 7229 return true; 7230 } 7231 } 7232 return false; 7233 }, 7234 7235 /* Retrieve the instance data for the target control. 7236 * @param target element - the target input field or division or span 7237 * @return object - the associated instance data 7238 * @throws error if a jQuery problem getting data 7239 */ 7240 _getInst: function(target) { 7241 try { 7242 return $.data(target, PROP_NAME); 7243 } 7244 catch (err) { 7245 throw "Missing instance data for this datepicker"; 7246 } 7247 }, 7248 7249 /* Update or retrieve the settings for a date picker attached to an input field or division. 7250 * @param target element - the target input field or division or span 7251 * @param name object - the new settings to update or 7252 * string - the name of the setting to change or retrieve, 7253 * when retrieving also "all" for all instance settings or 7254 * "defaults" for all global defaults 7255 * @param value any - the new value for the setting 7256 * (omit if above is an object or to retrieve a value) 7257 */ 7258 _optionDatepicker: function(target, name, value) { 7259 var settings, date, minDate, maxDate, 7260 inst = this._getInst(target); 7261 7262 if (arguments.length === 2 && typeof name === "string") { 7263 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 7264 (inst ? (name === "all" ? $.extend({}, inst.settings) : 7265 this._get(inst, name)) : null)); 7266 } 7267 7268 settings = name || {}; 7269 if (typeof name === "string") { 7270 settings = {}; 7271 settings[name] = value; 7272 } 7273 7274 if (inst) { 7275 if (this._curInst === inst) { 7276 this._hideDatepicker(); 7277 } 7278 7279 date = this._getDateDatepicker(target, true); 7280 minDate = this._getMinMaxDate(inst, "min"); 7281 maxDate = this._getMinMaxDate(inst, "max"); 7282 extendRemove(inst.settings, settings); 7283 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7284 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 7285 inst.settings.minDate = this._formatDate(inst, minDate); 7286 } 7287 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 7288 inst.settings.maxDate = this._formatDate(inst, maxDate); 7289 } 7290 if ( "disabled" in settings ) { 7291 if ( settings.disabled ) { 7292 this._disableDatepicker(target); 7293 } else { 7294 this._enableDatepicker(target); 7295 } 7296 } 7297 this._attachments($(target), inst); 7298 this._autoSize(inst); 7299 this._setDate(inst, date); 7300 this._updateAlternate(inst); 7301 this._updateDatepicker(inst); 7302 } 7303 }, 7304 7305 // change method deprecated 7306 _changeDatepicker: function(target, name, value) { 7307 this._optionDatepicker(target, name, value); 7308 }, 7309 7310 /* Redraw the date picker attached to an input field or division. 7311 * @param target element - the target input field or division or span 7312 */ 7313 _refreshDatepicker: function(target) { 7314 var inst = this._getInst(target); 7315 if (inst) { 7316 this._updateDatepicker(inst); 7317 } 7318 }, 7319 7320 /* Set the dates for a jQuery selection. 7321 * @param target element - the target input field or division or span 7322 * @param date Date - the new date 7323 */ 7324 _setDateDatepicker: function(target, date) { 7325 var inst = this._getInst(target); 7326 if (inst) { 7327 this._setDate(inst, date); 7328 this._updateDatepicker(inst); 7329 this._updateAlternate(inst); 7330 } 7331 }, 7332 7333 /* Get the date(s) for the first entry in a jQuery selection. 7334 * @param target element - the target input field or division or span 7335 * @param noDefault boolean - true if no default date is to be used 7336 * @return Date - the current date 7337 */ 7338 _getDateDatepicker: function(target, noDefault) { 7339 var inst = this._getInst(target); 7340 if (inst && !inst.inline) { 7341 this._setDateFromField(inst, noDefault); 7342 } 7343 return (inst ? this._getDate(inst) : null); 7344 }, 7345 7346 /* Handle keystrokes. */ 7347 _doKeyDown: function(event) { 7348 var onSelect, dateStr, sel, 7349 inst = $.datepicker._getInst(event.target), 7350 handled = true, 7351 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 7352 7353 inst._keyEvent = true; 7354 if ($.datepicker._datepickerShowing) { 7355 switch (event.keyCode) { 7356 case 9: $.datepicker._hideDatepicker(); 7357 handled = false; 7358 break; // hide on tab out 7359 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 7360 $.datepicker._currentClass + ")", inst.dpDiv); 7361 if (sel[0]) { 7362 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 7363 } 7364 7365 onSelect = $.datepicker._get(inst, "onSelect"); 7366 if (onSelect) { 7367 dateStr = $.datepicker._formatDate(inst); 7368 7369 // trigger custom callback 7370 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 7371 } else { 7372 $.datepicker._hideDatepicker(); 7373 } 7374 7375 return false; // don't submit the form 7376 case 27: $.datepicker._hideDatepicker(); 7377 break; // hide on escape 7378 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7379 -$.datepicker._get(inst, "stepBigMonths") : 7380 -$.datepicker._get(inst, "stepMonths")), "M"); 7381 break; // previous month/year on page up/+ ctrl 7382 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7383 +$.datepicker._get(inst, "stepBigMonths") : 7384 +$.datepicker._get(inst, "stepMonths")), "M"); 7385 break; // next month/year on page down/+ ctrl 7386 case 35: if (event.ctrlKey || event.metaKey) { 7387 $.datepicker._clearDate(event.target); 7388 } 7389 handled = event.ctrlKey || event.metaKey; 7390 break; // clear on ctrl or command +end 7391 case 36: if (event.ctrlKey || event.metaKey) { 7392 $.datepicker._gotoToday(event.target); 7393 } 7394 handled = event.ctrlKey || event.metaKey; 7395 break; // current on ctrl or command +home 7396 case 37: if (event.ctrlKey || event.metaKey) { 7397 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 7398 } 7399 handled = event.ctrlKey || event.metaKey; 7400 // -1 day on ctrl or command +left 7401 if (event.originalEvent.altKey) { 7402 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7403 -$.datepicker._get(inst, "stepBigMonths") : 7404 -$.datepicker._get(inst, "stepMonths")), "M"); 7405 } 7406 // next month/year on alt +left on Mac 7407 break; 7408 case 38: if (event.ctrlKey || event.metaKey) { 7409 $.datepicker._adjustDate(event.target, -7, "D"); 7410 } 7411 handled = event.ctrlKey || event.metaKey; 7412 break; // -1 week on ctrl or command +up 7413 case 39: if (event.ctrlKey || event.metaKey) { 7414 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 7415 } 7416 handled = event.ctrlKey || event.metaKey; 7417 // +1 day on ctrl or command +right 7418 if (event.originalEvent.altKey) { 7419 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7420 +$.datepicker._get(inst, "stepBigMonths") : 7421 +$.datepicker._get(inst, "stepMonths")), "M"); 7422 } 7423 // next month/year on alt +right 7424 break; 7425 case 40: if (event.ctrlKey || event.metaKey) { 7426 $.datepicker._adjustDate(event.target, +7, "D"); 7427 } 7428 handled = event.ctrlKey || event.metaKey; 7429 break; // +1 week on ctrl or command +down 7430 default: handled = false; 7431 } 7432 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 7433 $.datepicker._showDatepicker(this); 7434 } else { 7435 handled = false; 7436 } 7437 7438 if (handled) { 7439 event.preventDefault(); 7440 event.stopPropagation(); 7441 } 7442 }, 7443 7444 /* Filter entered characters - based on date format. */ 7445 _doKeyPress: function(event) { 7446 var chars, chr, 7447 inst = $.datepicker._getInst(event.target); 7448 7449 if ($.datepicker._get(inst, "constrainInput")) { 7450 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 7451 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 7452 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 7453 } 7454 }, 7455 7456 /* Synchronise manual entry and field/alternate field. */ 7457 _doKeyUp: function(event) { 7458 var date, 7459 inst = $.datepicker._getInst(event.target); 7460 7461 if (inst.input.val() !== inst.lastVal) { 7462 try { 7463 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 7464 (inst.input ? inst.input.val() : null), 7465 $.datepicker._getFormatConfig(inst)); 7466 7467 if (date) { // only if valid 7468 $.datepicker._setDateFromField(inst); 7469 $.datepicker._updateAlternate(inst); 7470 $.datepicker._updateDatepicker(inst); 7471 } 7472 } 7473 catch (err) { 7474 } 7475 } 7476 return true; 7477 }, 7478 7479 /* Pop-up the date picker for a given input field. 7480 * If false returned from beforeShow event handler do not show. 7481 * @param input element - the input field attached to the date picker or 7482 * event - if triggered by focus 7483 */ 7484 _showDatepicker: function(input) { 7485 input = input.target || input; 7486 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 7487 input = $("input", input.parentNode)[0]; 7488 } 7489 7490 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 7491 return; 7492 } 7493 7494 var inst, beforeShow, beforeShowSettings, isFixed, 7495 offset, showAnim, duration; 7496 7497 inst = $.datepicker._getInst(input); 7498 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 7499 $.datepicker._curInst.dpDiv.stop(true, true); 7500 if ( inst && $.datepicker._datepickerShowing ) { 7501 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 7502 } 7503 } 7504 7505 beforeShow = $.datepicker._get(inst, "beforeShow"); 7506 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7507 if(beforeShowSettings === false){ 7508 return; 7509 } 7510 extendRemove(inst.settings, beforeShowSettings); 7511 7512 inst.lastVal = null; 7513 $.datepicker._lastInput = input; 7514 $.datepicker._setDateFromField(inst); 7515 7516 if ($.datepicker._inDialog) { // hide cursor 7517 input.value = ""; 7518 } 7519 if (!$.datepicker._pos) { // position below input 7520 $.datepicker._pos = $.datepicker._findPos(input); 7521 $.datepicker._pos[1] += input.offsetHeight; // add the height 7522 } 7523 7524 isFixed = false; 7525 $(input).parents().each(function() { 7526 isFixed |= $(this).css("position") === "fixed"; 7527 return !isFixed; 7528 }); 7529 7530 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 7531 $.datepicker._pos = null; 7532 //to avoid flashes on Firefox 7533 inst.dpDiv.empty(); 7534 // determine sizing offscreen 7535 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 7536 $.datepicker._updateDatepicker(inst); 7537 // fix width for dynamic number of date pickers 7538 // and adjust position before showing 7539 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7540 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 7541 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 7542 left: offset.left + "px", top: offset.top + "px"}); 7543 7544 if (!inst.inline) { 7545 showAnim = $.datepicker._get(inst, "showAnim"); 7546 duration = $.datepicker._get(inst, "duration"); 7547 inst.dpDiv.zIndex($(input).zIndex()+1); 7548 $.datepicker._datepickerShowing = true; 7549 7550 if ( $.effects && $.effects.effect[ showAnim ] ) { 7551 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 7552 } else { 7553 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 7554 } 7555 7556 if ( $.datepicker._shouldFocusInput( inst ) ) { 7557 inst.input.focus(); 7558 } 7559 7560 $.datepicker._curInst = inst; 7561 } 7562 }, 7563 7564 /* Generate the date picker content. */ 7565 _updateDatepicker: function(inst) { 7566 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 7567 instActive = inst; // for delegate hover events 7568 inst.dpDiv.empty().append(this._generateHTML(inst)); 7569 this._attachHandlers(inst); 7570 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 7571 7572 var origyearshtml, 7573 numMonths = this._getNumberOfMonths(inst), 7574 cols = numMonths[1], 7575 width = 17; 7576 7577 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 7578 if (cols > 1) { 7579 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 7580 } 7581 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 7582 "Class"]("ui-datepicker-multi"); 7583 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 7584 "Class"]("ui-datepicker-rtl"); 7585 7586 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 7587 inst.input.focus(); 7588 } 7589 7590 // deffered render of the years select (to avoid flashes on Firefox) 7591 if( inst.yearshtml ){ 7592 origyearshtml = inst.yearshtml; 7593 setTimeout(function(){ 7594 //assure that inst.yearshtml didn't change. 7595 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 7596 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 7597 } 7598 origyearshtml = inst.yearshtml = null; 7599 }, 0); 7600 } 7601 }, 7602 7603 // #6694 - don't focus the input if it's already focused 7604 // this breaks the change event in IE 7605 // Support: IE and jQuery <1.9 7606 _shouldFocusInput: function( inst ) { 7607 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 7608 }, 7609 7610 /* Check positioning to remain on screen. */ 7611 _checkOffset: function(inst, offset, isFixed) { 7612 var dpWidth = inst.dpDiv.outerWidth(), 7613 dpHeight = inst.dpDiv.outerHeight(), 7614 inputWidth = inst.input ? inst.input.outerWidth() : 0, 7615 inputHeight = inst.input ? inst.input.outerHeight() : 0, 7616 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 7617 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 7618 7619 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 7620 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 7621 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 7622 7623 // now check if datepicker is showing outside window viewport - move to a better place if so. 7624 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 7625 Math.abs(offset.left + dpWidth - viewWidth) : 0); 7626 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 7627 Math.abs(dpHeight + inputHeight) : 0); 7628 7629 return offset; 7630 }, 7631 7632 /* Find an object's position on the screen. */ 7633 _findPos: function(obj) { 7634 var position, 7635 inst = this._getInst(obj), 7636 isRTL = this._get(inst, "isRTL"); 7637 7638 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 7639 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 7640 } 7641 7642 position = $(obj).offset(); 7643 return [position.left, position.top]; 7644 }, 7645 7646 /* Hide the date picker from view. 7647 * @param input element - the input field attached to the date picker 7648 */ 7649 _hideDatepicker: function(input) { 7650 var showAnim, duration, postProcess, onClose, 7651 inst = this._curInst; 7652 7653 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 7654 return; 7655 } 7656 7657 if (this._datepickerShowing) { 7658 showAnim = this._get(inst, "showAnim"); 7659 duration = this._get(inst, "duration"); 7660 postProcess = function() { 7661 $.datepicker._tidyDialog(inst); 7662 }; 7663 7664 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7665 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 7666 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 7667 } else { 7668 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 7669 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 7670 } 7671 7672 if (!showAnim) { 7673 postProcess(); 7674 } 7675 this._datepickerShowing = false; 7676 7677 onClose = this._get(inst, "onClose"); 7678 if (onClose) { 7679 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 7680 } 7681 7682 this._lastInput = null; 7683 if (this._inDialog) { 7684 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 7685 if ($.blockUI) { 7686 $.unblockUI(); 7687 $("body").append(this.dpDiv); 7688 } 7689 } 7690 this._inDialog = false; 7691 } 7692 }, 7693 7694 /* Tidy up after a dialog display. */ 7695 _tidyDialog: function(inst) { 7696 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 7697 }, 7698 7699 /* Close date picker if clicked elsewhere. */ 7700 _checkExternalClick: function(event) { 7701 if (!$.datepicker._curInst) { 7702 return; 7703 } 7704 7705 var $target = $(event.target), 7706 inst = $.datepicker._getInst($target[0]); 7707 7708 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 7709 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 7710 !$target.hasClass($.datepicker.markerClassName) && 7711 !$target.closest("." + $.datepicker._triggerClass).length && 7712 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 7713 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 7714 $.datepicker._hideDatepicker(); 7715 } 7716 }, 7717 7718 /* Adjust one of the date sub-fields. */ 7719 _adjustDate: function(id, offset, period) { 7720 var target = $(id), 7721 inst = this._getInst(target[0]); 7722 7723 if (this._isDisabledDatepicker(target[0])) { 7724 return; 7725 } 7726 this._adjustInstDate(inst, offset + 7727 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 7728 period); 7729 this._updateDatepicker(inst); 7730 }, 7731 7732 /* Action for current link. */ 7733 _gotoToday: function(id) { 7734 var date, 7735 target = $(id), 7736 inst = this._getInst(target[0]); 7737 7738 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 7739 inst.selectedDay = inst.currentDay; 7740 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 7741 inst.drawYear = inst.selectedYear = inst.currentYear; 7742 } else { 7743 date = new Date(); 7744 inst.selectedDay = date.getDate(); 7745 inst.drawMonth = inst.selectedMonth = date.getMonth(); 7746 inst.drawYear = inst.selectedYear = date.getFullYear(); 7747 } 7748 this._notifyChange(inst); 7749 this._adjustDate(target); 7750 }, 7751 7752 /* Action for selecting a new month/year. */ 7753 _selectMonthYear: function(id, select, period) { 7754 var target = $(id), 7755 inst = this._getInst(target[0]); 7756 7757 inst["selected" + (period === "M" ? "Month" : "Year")] = 7758 inst["draw" + (period === "M" ? "Month" : "Year")] = 7759 parseInt(select.options[select.selectedIndex].value,10); 7760 7761 this._notifyChange(inst); 7762 this._adjustDate(target); 7763 }, 7764 7765 /* Action for selecting a day. */ 7766 _selectDay: function(id, month, year, td) { 7767 var inst, 7768 target = $(id); 7769 7770 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 7771 return; 7772 } 7773 7774 inst = this._getInst(target[0]); 7775 inst.selectedDay = inst.currentDay = $("a", td).html(); 7776 inst.selectedMonth = inst.currentMonth = month; 7777 inst.selectedYear = inst.currentYear = year; 7778 this._selectDate(id, this._formatDate(inst, 7779 inst.currentDay, inst.currentMonth, inst.currentYear)); 7780 }, 7781 7782 /* Erase the input field and hide the date picker. */ 7783 _clearDate: function(id) { 7784 var target = $(id); 7785 this._selectDate(target, ""); 7786 }, 7787 7788 /* Update the input field with the selected date. */ 7789 _selectDate: function(id, dateStr) { 7790 var onSelect, 7791 target = $(id), 7792 inst = this._getInst(target[0]); 7793 7794 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 7795 if (inst.input) { 7796 inst.input.val(dateStr); 7797 } 7798 this._updateAlternate(inst); 7799 7800 onSelect = this._get(inst, "onSelect"); 7801 if (onSelect) { 7802 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 7803 } else if (inst.input) { 7804 inst.input.trigger("change"); // fire the change event 7805 } 7806 7807 if (inst.inline){ 7808 this._updateDatepicker(inst); 7809 } else { 7810 this._hideDatepicker(); 7811 this._lastInput = inst.input[0]; 7812 if (typeof(inst.input[0]) !== "object") { 7813 inst.input.focus(); // restore focus 7814 } 7815 this._lastInput = null; 7816 } 7817 }, 7818 7819 /* Update any alternate field to synchronise with the main field. */ 7820 _updateAlternate: function(inst) { 7821 var altFormat, date, dateStr, 7822 altField = this._get(inst, "altField"); 7823 7824 if (altField) { // update alternate field too 7825 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 7826 date = this._getDate(inst); 7827 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 7828 $(altField).each(function() { $(this).val(dateStr); }); 7829 } 7830 }, 7831 7832 /* Set as beforeShowDay function to prevent selection of weekends. 7833 * @param date Date - the date to customise 7834 * @return [boolean, string] - is this date selectable?, what is its CSS class? 7835 */ 7836 noWeekends: function(date) { 7837 var day = date.getDay(); 7838 return [(day > 0 && day < 6), ""]; 7839 }, 7840 7841 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 7842 * @param date Date - the date to get the week for 7843 * @return number - the number of the week within the year that contains this date 7844 */ 7845 iso8601Week: function(date) { 7846 var time, 7847 checkDate = new Date(date.getTime()); 7848 7849 // Find Thursday of this week starting on Monday 7850 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 7851 7852 time = checkDate.getTime(); 7853 checkDate.setMonth(0); // Compare with Jan 1 7854 checkDate.setDate(1); 7855 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 7856 }, 7857 7858 /* Parse a string value into a date object. 7859 * See formatDate below for the possible formats. 7860 * 7861 * @param format string - the expected format of the date 7862 * @param value string - the date in the above format 7863 * @param settings Object - attributes include: 7864 * shortYearCutoff number - the cutoff year for determining the century (optional) 7865 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 7866 * dayNames string[7] - names of the days from Sunday (optional) 7867 * monthNamesShort string[12] - abbreviated names of the months (optional) 7868 * monthNames string[12] - names of the months (optional) 7869 * @return Date - the extracted date value or null if value is blank 7870 */ 7871 parseDate: function (format, value, settings) { 7872 if (format == null || value == null) { 7873 throw "Invalid arguments"; 7874 } 7875 7876 value = (typeof value === "object" ? value.toString() : value + ""); 7877 if (value === "") { 7878 return null; 7879 } 7880 7881 var iFormat, dim, extra, 7882 iValue = 0, 7883 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 7884 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 7885 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 7886 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 7887 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 7888 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 7889 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 7890 year = -1, 7891 month = -1, 7892 day = -1, 7893 doy = -1, 7894 literal = false, 7895 date, 7896 // Check whether a format character is doubled 7897 lookAhead = function(match) { 7898 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 7899 if (matches) { 7900 iFormat++; 7901 } 7902 return matches; 7903 }, 7904 // Extract a number from the string value 7905 getNumber = function(match) { 7906 var isDoubled = lookAhead(match), 7907 size = (match === "@" ? 14 : (match === "!" ? 20 : 7908 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 7909 digits = new RegExp("^\\d{1," + size + "}"), 7910 num = value.substring(iValue).match(digits); 7911 if (!num) { 7912 throw "Missing number at position " + iValue; 7913 } 7914 iValue += num[0].length; 7915 return parseInt(num[0], 10); 7916 }, 7917 // Extract a name from the string value and convert to an index 7918 getName = function(match, shortNames, longNames) { 7919 var index = -1, 7920 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 7921 return [ [k, v] ]; 7922 }).sort(function (a, b) { 7923 return -(a[1].length - b[1].length); 7924 }); 7925 7926 $.each(names, function (i, pair) { 7927 var name = pair[1]; 7928 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 7929 index = pair[0]; 7930 iValue += name.length; 7931 return false; 7932 } 7933 }); 7934 if (index !== -1) { 7935 return index + 1; 7936 } else { 7937 throw "Unknown name at position " + iValue; 7938 } 7939 }, 7940 // Confirm that a literal character matches the string value 7941 checkLiteral = function() { 7942 if (value.charAt(iValue) !== format.charAt(iFormat)) { 7943 throw "Unexpected literal at position " + iValue; 7944 } 7945 iValue++; 7946 }; 7947 7948 for (iFormat = 0; iFormat < format.length; iFormat++) { 7949 if (literal) { 7950 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 7951 literal = false; 7952 } else { 7953 checkLiteral(); 7954 } 7955 } else { 7956 switch (format.charAt(iFormat)) { 7957 case "d": 7958 day = getNumber("d"); 7959 break; 7960 case "D": 7961 getName("D", dayNamesShort, dayNames); 7962 break; 7963 case "o": 7964 doy = getNumber("o"); 7965 break; 7966 case "m": 7967 month = getNumber("m"); 7968 break; 7969 case "M": 7970 month = getName("M", monthNamesShort, monthNames); 7971 break; 7972 case "y": 7973 year = getNumber("y"); 7974 break; 7975 case "@": 7976 date = new Date(getNumber("@")); 7977 year = date.getFullYear(); 7978 month = date.getMonth() + 1; 7979 day = date.getDate(); 7980 break; 7981 case "!": 7982 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 7983 year = date.getFullYear(); 7984 month = date.getMonth() + 1; 7985 day = date.getDate(); 7986 break; 7987 case "'": 7988 if (lookAhead("'")){ 7989 checkLiteral(); 7990 } else { 7991 literal = true; 7992 } 7993 break; 7994 default: 7995 checkLiteral(); 7996 } 7997 } 7998 } 7999 8000 if (iValue < value.length){ 8001 extra = value.substr(iValue); 8002 if (!/^\s+/.test(extra)) { 8003 throw "Extra/unparsed characters found in date: " + extra; 8004 } 8005 } 8006 8007 if (year === -1) { 8008 year = new Date().getFullYear(); 8009 } else if (year < 100) { 8010 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8011 (year <= shortYearCutoff ? 0 : -100); 8012 } 8013 8014 if (doy > -1) { 8015 month = 1; 8016 day = doy; 8017 do { 8018 dim = this._getDaysInMonth(year, month - 1); 8019 if (day <= dim) { 8020 break; 8021 } 8022 month++; 8023 day -= dim; 8024 } while (true); 8025 } 8026 8027 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8028 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8029 throw "Invalid date"; // E.g. 31/02/00 8030 } 8031 return date; 8032 }, 8033 8034 /* Standard date formats. */ 8035 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8036 COOKIE: "D, dd M yy", 8037 ISO_8601: "yy-mm-dd", 8038 RFC_822: "D, d M y", 8039 RFC_850: "DD, dd-M-y", 8040 RFC_1036: "D, d M y", 8041 RFC_1123: "D, d M yy", 8042 RFC_2822: "D, d M yy", 8043 RSS: "D, d M y", // RFC 822 8044 TICKS: "!", 8045 TIMESTAMP: "@", 8046 W3C: "yy-mm-dd", // ISO 8601 8047 8048 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8049 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8050 8051 /* Format a date object into a string value. 8052 * The format can be combinations of the following: 8053 * d - day of month (no leading zero) 8054 * dd - day of month (two digit) 8055 * o - day of year (no leading zeros) 8056 * oo - day of year (three digit) 8057 * D - day name short 8058 * DD - day name long 8059 * m - month of year (no leading zero) 8060 * mm - month of year (two digit) 8061 * M - month name short 8062 * MM - month name long 8063 * y - year (two digit) 8064 * yy - year (four digit) 8065 * @ - Unix timestamp (ms since 01/01/1970) 8066 * ! - Windows ticks (100ns since 01/01/0001) 8067 * "..." - literal text 8068 * '' - single quote 8069 * 8070 * @param format string - the desired format of the date 8071 * @param date Date - the date value to format 8072 * @param settings Object - attributes include: 8073 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8074 * dayNames string[7] - names of the days from Sunday (optional) 8075 * monthNamesShort string[12] - abbreviated names of the months (optional) 8076 * monthNames string[12] - names of the months (optional) 8077 * @return string - the date in the above format 8078 */ 8079 formatDate: function (format, date, settings) { 8080 if (!date) { 8081 return ""; 8082 } 8083 8084 var iFormat, 8085 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8086 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8087 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8088 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8089 // Check whether a format character is doubled 8090 lookAhead = function(match) { 8091 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8092 if (matches) { 8093 iFormat++; 8094 } 8095 return matches; 8096 }, 8097 // Format a number, with leading zero if necessary 8098 formatNumber = function(match, value, len) { 8099 var num = "" + value; 8100 if (lookAhead(match)) { 8101 while (num.length < len) { 8102 num = "0" + num; 8103 } 8104 } 8105 return num; 8106 }, 8107 // Format a name, short or long as requested 8108 formatName = function(match, value, shortNames, longNames) { 8109 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8110 }, 8111 output = "", 8112 literal = false; 8113 8114 if (date) { 8115 for (iFormat = 0; iFormat < format.length; iFormat++) { 8116 if (literal) { 8117 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8118 literal = false; 8119 } else { 8120 output += format.charAt(iFormat); 8121 } 8122 } else { 8123 switch (format.charAt(iFormat)) { 8124 case "d": 8125 output += formatNumber("d", date.getDate(), 2); 8126 break; 8127 case "D": 8128 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8129 break; 8130 case "o": 8131 output += formatNumber("o", 8132 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8133 break; 8134 case "m": 8135 output += formatNumber("m", date.getMonth() + 1, 2); 8136 break; 8137 case "M": 8138 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8139 break; 8140 case "y": 8141 output += (lookAhead("y") ? date.getFullYear() : 8142 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8143 break; 8144 case "@": 8145 output += date.getTime(); 8146 break; 8147 case "!": 8148 output += date.getTime() * 10000 + this._ticksTo1970; 8149 break; 8150 case "'": 8151 if (lookAhead("'")) { 8152 output += "'"; 8153 } else { 8154 literal = true; 8155 } 8156 break; 8157 default: 8158 output += format.charAt(iFormat); 8159 } 8160 } 8161 } 8162 } 8163 return output; 8164 }, 8165 8166 /* Extract all possible characters from the date format. */ 8167 _possibleChars: function (format) { 8168 var iFormat, 8169 chars = "", 8170 literal = false, 8171 // Check whether a format character is doubled 8172 lookAhead = function(match) { 8173 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8174 if (matches) { 8175 iFormat++; 8176 } 8177 return matches; 8178 }; 8179 8180 for (iFormat = 0; iFormat < format.length; iFormat++) { 8181 if (literal) { 8182 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8183 literal = false; 8184 } else { 8185 chars += format.charAt(iFormat); 8186 } 8187 } else { 8188 switch (format.charAt(iFormat)) { 8189 case "d": case "m": case "y": case "@": 8190 chars += "0123456789"; 8191 break; 8192 case "D": case "M": 8193 return null; // Accept anything 8194 case "'": 8195 if (lookAhead("'")) { 8196 chars += "'"; 8197 } else { 8198 literal = true; 8199 } 8200 break; 8201 default: 8202 chars += format.charAt(iFormat); 8203 } 8204 } 8205 } 8206 return chars; 8207 }, 8208 8209 /* Get a setting value, defaulting if necessary. */ 8210 _get: function(inst, name) { 8211 return inst.settings[name] !== undefined ? 8212 inst.settings[name] : this._defaults[name]; 8213 }, 8214 8215 /* Parse existing date and initialise date picker. */ 8216 _setDateFromField: function(inst, noDefault) { 8217 if (inst.input.val() === inst.lastVal) { 8218 return; 8219 } 8220 8221 var dateFormat = this._get(inst, "dateFormat"), 8222 dates = inst.lastVal = inst.input ? inst.input.val() : null, 8223 defaultDate = this._getDefaultDate(inst), 8224 date = defaultDate, 8225 settings = this._getFormatConfig(inst); 8226 8227 try { 8228 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8229 } catch (event) { 8230 dates = (noDefault ? "" : dates); 8231 } 8232 inst.selectedDay = date.getDate(); 8233 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8234 inst.drawYear = inst.selectedYear = date.getFullYear(); 8235 inst.currentDay = (dates ? date.getDate() : 0); 8236 inst.currentMonth = (dates ? date.getMonth() : 0); 8237 inst.currentYear = (dates ? date.getFullYear() : 0); 8238 this._adjustInstDate(inst); 8239 }, 8240 8241 /* Retrieve the default date shown on opening. */ 8242 _getDefaultDate: function(inst) { 8243 return this._restrictMinMax(inst, 8244 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 8245 }, 8246 8247 /* A date may be specified as an exact value or a relative one. */ 8248 _determineDate: function(inst, date, defaultDate) { 8249 var offsetNumeric = function(offset) { 8250 var date = new Date(); 8251 date.setDate(date.getDate() + offset); 8252 return date; 8253 }, 8254 offsetString = function(offset) { 8255 try { 8256 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8257 offset, $.datepicker._getFormatConfig(inst)); 8258 } 8259 catch (e) { 8260 // Ignore 8261 } 8262 8263 var date = (offset.toLowerCase().match(/^c/) ? 8264 $.datepicker._getDate(inst) : null) || new Date(), 8265 year = date.getFullYear(), 8266 month = date.getMonth(), 8267 day = date.getDate(), 8268 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 8269 matches = pattern.exec(offset); 8270 8271 while (matches) { 8272 switch (matches[2] || "d") { 8273 case "d" : case "D" : 8274 day += parseInt(matches[1],10); break; 8275 case "w" : case "W" : 8276 day += parseInt(matches[1],10) * 7; break; 8277 case "m" : case "M" : 8278 month += parseInt(matches[1],10); 8279 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8280 break; 8281 case "y": case "Y" : 8282 year += parseInt(matches[1],10); 8283 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8284 break; 8285 } 8286 matches = pattern.exec(offset); 8287 } 8288 return new Date(year, month, day); 8289 }, 8290 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 8291 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 8292 8293 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 8294 if (newDate) { 8295 newDate.setHours(0); 8296 newDate.setMinutes(0); 8297 newDate.setSeconds(0); 8298 newDate.setMilliseconds(0); 8299 } 8300 return this._daylightSavingAdjust(newDate); 8301 }, 8302 8303 /* Handle switch to/from daylight saving. 8304 * Hours may be non-zero on daylight saving cut-over: 8305 * > 12 when midnight changeover, but then cannot generate 8306 * midnight datetime, so jump to 1AM, otherwise reset. 8307 * @param date (Date) the date to check 8308 * @return (Date) the corrected date 8309 */ 8310 _daylightSavingAdjust: function(date) { 8311 if (!date) { 8312 return null; 8313 } 8314 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 8315 return date; 8316 }, 8317 8318 /* Set the date(s) directly. */ 8319 _setDate: function(inst, date, noChange) { 8320 var clear = !date, 8321 origMonth = inst.selectedMonth, 8322 origYear = inst.selectedYear, 8323 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 8324 8325 inst.selectedDay = inst.currentDay = newDate.getDate(); 8326 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8327 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8328 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 8329 this._notifyChange(inst); 8330 } 8331 this._adjustInstDate(inst); 8332 if (inst.input) { 8333 inst.input.val(clear ? "" : this._formatDate(inst)); 8334 } 8335 }, 8336 8337 /* Retrieve the date(s) directly. */ 8338 _getDate: function(inst) { 8339 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 8340 this._daylightSavingAdjust(new Date( 8341 inst.currentYear, inst.currentMonth, inst.currentDay))); 8342 return startDate; 8343 }, 8344 8345 /* Attach the onxxx handlers. These are declared statically so 8346 * they work with static code transformers like Caja. 8347 */ 8348 _attachHandlers: function(inst) { 8349 var stepMonths = this._get(inst, "stepMonths"), 8350 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 8351 inst.dpDiv.find("[data-handler]").map(function () { 8352 var handler = { 8353 prev: function () { 8354 $.datepicker._adjustDate(id, -stepMonths, "M"); 8355 }, 8356 next: function () { 8357 $.datepicker._adjustDate(id, +stepMonths, "M"); 8358 }, 8359 hide: function () { 8360 $.datepicker._hideDatepicker(); 8361 }, 8362 today: function () { 8363 $.datepicker._gotoToday(id); 8364 }, 8365 selectDay: function () { 8366 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 8367 return false; 8368 }, 8369 selectMonth: function () { 8370 $.datepicker._selectMonthYear(id, this, "M"); 8371 return false; 8372 }, 8373 selectYear: function () { 8374 $.datepicker._selectMonthYear(id, this, "Y"); 8375 return false; 8376 } 8377 }; 8378 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 8379 }); 8380 }, 8381 8382 /* Generate the HTML for the current state of the date picker. */ 8383 _generateHTML: function(inst) { 8384 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 8385 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 8386 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 8387 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 8388 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 8389 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 8390 tempDate = new Date(), 8391 today = this._daylightSavingAdjust( 8392 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 8393 isRTL = this._get(inst, "isRTL"), 8394 showButtonPanel = this._get(inst, "showButtonPanel"), 8395 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 8396 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 8397 numMonths = this._getNumberOfMonths(inst), 8398 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 8399 stepMonths = this._get(inst, "stepMonths"), 8400 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 8401 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 8402 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 8403 minDate = this._getMinMaxDate(inst, "min"), 8404 maxDate = this._getMinMaxDate(inst, "max"), 8405 drawMonth = inst.drawMonth - showCurrentAtPos, 8406 drawYear = inst.drawYear; 8407 8408 if (drawMonth < 0) { 8409 drawMonth += 12; 8410 drawYear--; 8411 } 8412 if (maxDate) { 8413 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 8414 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 8415 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 8416 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 8417 drawMonth--; 8418 if (drawMonth < 0) { 8419 drawMonth = 11; 8420 drawYear--; 8421 } 8422 } 8423 } 8424 inst.drawMonth = drawMonth; 8425 inst.drawYear = drawYear; 8426 8427 prevText = this._get(inst, "prevText"); 8428 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 8429 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 8430 this._getFormatConfig(inst))); 8431 8432 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 8433 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 8434 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 8435 (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>")); 8436 8437 nextText = this._get(inst, "nextText"); 8438 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 8439 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 8440 this._getFormatConfig(inst))); 8441 8442 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 8443 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 8444 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 8445 (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>")); 8446 8447 currentText = this._get(inst, "currentText"); 8448 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 8449 currentText = (!navigationAsDateFormat ? currentText : 8450 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 8451 8452 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'>" + 8453 this._get(inst, "closeText") + "</button>" : ""); 8454 8455 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 8456 (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'" + 8457 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 8458 8459 firstDay = parseInt(this._get(inst, "firstDay"),10); 8460 firstDay = (isNaN(firstDay) ? 0 : firstDay); 8461 8462 showWeek = this._get(inst, "showWeek"); 8463 dayNames = this._get(inst, "dayNames"); 8464 dayNamesMin = this._get(inst, "dayNamesMin"); 8465 monthNames = this._get(inst, "monthNames"); 8466 monthNamesShort = this._get(inst, "monthNamesShort"); 8467 beforeShowDay = this._get(inst, "beforeShowDay"); 8468 showOtherMonths = this._get(inst, "showOtherMonths"); 8469 selectOtherMonths = this._get(inst, "selectOtherMonths"); 8470 defaultDate = this._getDefaultDate(inst); 8471 html = ""; 8472 dow; 8473 for (row = 0; row < numMonths[0]; row++) { 8474 group = ""; 8475 this.maxRows = 4; 8476 for (col = 0; col < numMonths[1]; col++) { 8477 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 8478 cornerClass = " ui-corner-all"; 8479 calender = ""; 8480 if (isMultiMonth) { 8481 calender += "<div class='ui-datepicker-group"; 8482 if (numMonths[1] > 1) { 8483 switch (col) { 8484 case 0: calender += " ui-datepicker-group-first"; 8485 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 8486 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 8487 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 8488 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 8489 } 8490 } 8491 calender += "'>"; 8492 } 8493 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 8494 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 8495 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 8496 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 8497 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 8498 "</div><table class='ui-datepicker-calendar'><thead>" + 8499 "<tr>"; 8500 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 8501 for (dow = 0; dow < 7; dow++) { // days of the week 8502 day = (dow + firstDay) % 7; 8503 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 8504 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 8505 } 8506 calender += thead + "</tr></thead><tbody>"; 8507 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 8508 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 8509 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 8510 } 8511 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 8512 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 8513 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 8514 this.maxRows = numRows; 8515 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8516 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 8517 calender += "<tr>"; 8518 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 8519 this._get(inst, "calculateWeek")(printDate) + "</td>"); 8520 for (dow = 0; dow < 7; dow++) { // create date picker days 8521 daySettings = (beforeShowDay ? 8522 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 8523 otherMonth = (printDate.getMonth() !== drawMonth); 8524 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 8525 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 8526 tbody += "<td class='" + 8527 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 8528 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 8529 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 8530 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 8531 // or defaultDate is current printedDate and defaultDate is selectedDate 8532 " " + this._dayOverClass : "") + // highlight selected day 8533 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 8534 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 8535 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 8536 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 8537 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 8538 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 8539 (otherMonth && !showOtherMonths ? " " : // display for other months 8540 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 8541 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 8542 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 8543 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 8544 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 8545 printDate.setDate(printDate.getDate() + 1); 8546 printDate = this._daylightSavingAdjust(printDate); 8547 } 8548 calender += tbody + "</tr>"; 8549 } 8550 drawMonth++; 8551 if (drawMonth > 11) { 8552 drawMonth = 0; 8553 drawYear++; 8554 } 8555 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 8556 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 8557 group += calender; 8558 } 8559 html += group; 8560 } 8561 html += buttonPanel; 8562 inst._keyEvent = false; 8563 return html; 8564 }, 8565 8566 /* Generate the month and year header. */ 8567 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 8568 secondary, monthNames, monthNamesShort) { 8569 8570 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 8571 changeMonth = this._get(inst, "changeMonth"), 8572 changeYear = this._get(inst, "changeYear"), 8573 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 8574 html = "<div class='ui-datepicker-title'>", 8575 monthHtml = ""; 8576 8577 // month selection 8578 if (secondary || !changeMonth) { 8579 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 8580 } else { 8581 inMinYear = (minDate && minDate.getFullYear() === drawYear); 8582 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 8583 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 8584 for ( month = 0; month < 12; month++) { 8585 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 8586 monthHtml += "<option value='" + month + "'" + 8587 (month === drawMonth ? " selected='selected'" : "") + 8588 ">" + monthNamesShort[month] + "</option>"; 8589 } 8590 } 8591 monthHtml += "</select>"; 8592 } 8593 8594 if (!showMonthAfterYear) { 8595 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 8596 } 8597 8598 // year selection 8599 if ( !inst.yearshtml ) { 8600 inst.yearshtml = ""; 8601 if (secondary || !changeYear) { 8602 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 8603 } else { 8604 // determine range of years to display 8605 years = this._get(inst, "yearRange").split(":"); 8606 thisYear = new Date().getFullYear(); 8607 determineYear = function(value) { 8608 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8609 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 8610 parseInt(value, 10))); 8611 return (isNaN(year) ? thisYear : year); 8612 }; 8613 year = determineYear(years[0]); 8614 endYear = Math.max(year, determineYear(years[1] || "")); 8615 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8616 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8617 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 8618 for (; year <= endYear; year++) { 8619 inst.yearshtml += "<option value='" + year + "'" + 8620 (year === drawYear ? " selected='selected'" : "") + 8621 ">" + year + "</option>"; 8622 } 8623 inst.yearshtml += "</select>"; 8624 8625 html += inst.yearshtml; 8626 inst.yearshtml = null; 8627 } 8628 } 8629 8630 html += this._get(inst, "yearSuffix"); 8631 if (showMonthAfterYear) { 8632 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 8633 } 8634 html += "</div>"; // Close datepicker_header 8635 return html; 8636 }, 8637 8638 /* Adjust one of the date sub-fields. */ 8639 _adjustInstDate: function(inst, offset, period) { 8640 var year = inst.drawYear + (period === "Y" ? offset : 0), 8641 month = inst.drawMonth + (period === "M" ? offset : 0), 8642 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 8643 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 8644 8645 inst.selectedDay = date.getDate(); 8646 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8647 inst.drawYear = inst.selectedYear = date.getFullYear(); 8648 if (period === "M" || period === "Y") { 8649 this._notifyChange(inst); 8650 } 8651 }, 8652 8653 /* Ensure a date is within any min/max bounds. */ 8654 _restrictMinMax: function(inst, date) { 8655 var minDate = this._getMinMaxDate(inst, "min"), 8656 maxDate = this._getMinMaxDate(inst, "max"), 8657 newDate = (minDate && date < minDate ? minDate : date); 8658 return (maxDate && newDate > maxDate ? maxDate : newDate); 8659 }, 8660 8661 /* Notify change of month/year. */ 8662 _notifyChange: function(inst) { 8663 var onChange = this._get(inst, "onChangeMonthYear"); 8664 if (onChange) { 8665 onChange.apply((inst.input ? inst.input[0] : null), 8666 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8667 } 8668 }, 8669 8670 /* Determine the number of months to show. */ 8671 _getNumberOfMonths: function(inst) { 8672 var numMonths = this._get(inst, "numberOfMonths"); 8673 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 8674 }, 8675 8676 /* Determine the current maximum date - ensure no time components are set. */ 8677 _getMinMaxDate: function(inst, minMax) { 8678 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 8679 }, 8680 8681 /* Find the number of days in a given month. */ 8682 _getDaysInMonth: function(year, month) { 8683 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8684 }, 8685 8686 /* Find the day of the week of the first of a month. */ 8687 _getFirstDayOfMonth: function(year, month) { 8688 return new Date(year, month, 1).getDay(); 8689 }, 8690 8691 /* Determines if we should allow a "next/prev" month display change. */ 8692 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 8693 var numMonths = this._getNumberOfMonths(inst), 8694 date = this._daylightSavingAdjust(new Date(curYear, 8695 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8696 8697 if (offset < 0) { 8698 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8699 } 8700 return this._isInRange(inst, date); 8701 }, 8702 8703 /* Is the given date in the accepted range? */ 8704 _isInRange: function(inst, date) { 8705 var yearSplit, currentYear, 8706 minDate = this._getMinMaxDate(inst, "min"), 8707 maxDate = this._getMinMaxDate(inst, "max"), 8708 minYear = null, 8709 maxYear = null, 8710 years = this._get(inst, "yearRange"); 8711 if (years){ 8712 yearSplit = years.split(":"); 8713 currentYear = new Date().getFullYear(); 8714 minYear = parseInt(yearSplit[0], 10); 8715 maxYear = parseInt(yearSplit[1], 10); 8716 if ( yearSplit[0].match(/[+\-].*/) ) { 8717 minYear += currentYear; 8718 } 8719 if ( yearSplit[1].match(/[+\-].*/) ) { 8720 maxYear += currentYear; 8721 } 8722 } 8723 8724 return ((!minDate || date.getTime() >= minDate.getTime()) && 8725 (!maxDate || date.getTime() <= maxDate.getTime()) && 8726 (!minYear || date.getFullYear() >= minYear) && 8727 (!maxYear || date.getFullYear() <= maxYear)); 8728 }, 8729 8730 /* Provide the configuration settings for formatting/parsing. */ 8731 _getFormatConfig: function(inst) { 8732 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 8733 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 8734 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8735 return {shortYearCutoff: shortYearCutoff, 8736 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 8737 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 8738 }, 8739 8740 /* Format the given date for display. */ 8741 _formatDate: function(inst, day, month, year) { 8742 if (!day) { 8743 inst.currentDay = inst.selectedDay; 8744 inst.currentMonth = inst.selectedMonth; 8745 inst.currentYear = inst.selectedYear; 8746 } 8747 var date = (day ? (typeof day === "object" ? day : 8748 this._daylightSavingAdjust(new Date(year, month, day))) : 8749 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8750 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 8751 } 8752}); 8753 8754/* 8755 * Bind hover events for datepicker elements. 8756 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8757 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8758 */ 8759function bindHover(dpDiv) { 8760 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 8761 return dpDiv.delegate(selector, "mouseout", function() { 8762 $(this).removeClass("ui-state-hover"); 8763 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 8764 $(this).removeClass("ui-datepicker-prev-hover"); 8765 } 8766 if (this.className.indexOf("ui-datepicker-next") !== -1) { 8767 $(this).removeClass("ui-datepicker-next-hover"); 8768 } 8769 }) 8770 .delegate(selector, "mouseover", function(){ 8771 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 8772 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 8773 $(this).addClass("ui-state-hover"); 8774 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 8775 $(this).addClass("ui-datepicker-prev-hover"); 8776 } 8777 if (this.className.indexOf("ui-datepicker-next") !== -1) { 8778 $(this).addClass("ui-datepicker-next-hover"); 8779 } 8780 } 8781 }); 8782} 8783 8784/* jQuery extend now ignores nulls! */ 8785function extendRemove(target, props) { 8786 $.extend(target, props); 8787 for (var name in props) { 8788 if (props[name] == null) { 8789 target[name] = props[name]; 8790 } 8791 } 8792 return target; 8793} 8794 8795/* Invoke the datepicker functionality. 8796 @param options string - a command, optionally followed by additional parameters or 8797 Object - settings for attaching new datepicker functionality 8798 @return jQuery object */ 8799$.fn.datepicker = function(options){ 8800 8801 /* Verify an empty collection wasn't passed - Fixes #6976 */ 8802 if ( !this.length ) { 8803 return this; 8804 } 8805 8806 /* Initialise the date picker. */ 8807 if (!$.datepicker.initialized) { 8808 $(document).mousedown($.datepicker._checkExternalClick); 8809 $.datepicker.initialized = true; 8810 } 8811 8812 /* Append datepicker main container to body if not exist. */ 8813 if ($("#"+$.datepicker._mainDivId).length === 0) { 8814 $("body").append($.datepicker.dpDiv); 8815 } 8816 8817 var otherArgs = Array.prototype.slice.call(arguments, 1); 8818 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 8819 return $.datepicker["_" + options + "Datepicker"]. 8820 apply($.datepicker, [this[0]].concat(otherArgs)); 8821 } 8822 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 8823 return $.datepicker["_" + options + "Datepicker"]. 8824 apply($.datepicker, [this[0]].concat(otherArgs)); 8825 } 8826 return this.each(function() { 8827 typeof options === "string" ? 8828 $.datepicker["_" + options + "Datepicker"]. 8829 apply($.datepicker, [this].concat(otherArgs)) : 8830 $.datepicker._attachDatepicker(this, options); 8831 }); 8832}; 8833 8834$.datepicker = new Datepicker(); // singleton instance 8835$.datepicker.initialized = false; 8836$.datepicker.uuid = new Date().getTime(); 8837$.datepicker.version = "1.10.
vendor: 18,167 bytes, lines 8837-9564
88374"; 8838 8839})(jQuery); 8840(function( $, undefined ) { 8841 8842var sizeRelatedOptions = { 8843 buttons: true, 8844 height: true, 8845 maxHeight: true, 8846 maxWidth: true, 8847 minHeight: true, 8848 minWidth: true, 8849 width: true 8850 }, 8851 resizableRelatedOptions = { 8852 maxHeight: true, 8853 maxWidth: true, 8854 minHeight: true, 8855 minWidth: true 8856 }; 8857 8858$.widget( "ui.dialog", { 8859 version: "1.10.4", 8860 options: { 8861 appendTo: "body", 8862 autoOpen: true, 8863 buttons: [], 8864 closeOnEscape: true, 8865 closeText: "close", 8866 dialogClass: "", 8867 draggable: true, 8868 hide: null, 8869 height: "auto", 8870 maxHeight: null, 8871 maxWidth: null, 8872 minHeight: 150, 8873 minWidth: 150, 8874 modal: false, 8875 position: { 8876 my: "center", 8877 at: "center", 8878 of: window, 8879 collision: "fit", 8880 // Ensure the titlebar is always visible 8881 using: function( pos ) { 8882 var topOffset = $( this ).css( pos ).offset().top; 8883 if ( topOffset < 0 ) { 8884 $( this ).css( "top", pos.top - topOffset ); 8885 } 8886 } 8887 }, 8888 resizable: true, 8889 show: null, 8890 title: null, 8891 width: 300, 8892 8893 // callbacks 8894 beforeClose: null, 8895 close: null, 8896 drag: null, 8897 dragStart: null, 8898 dragStop: null, 8899 focus: null, 8900 open: null, 8901 resize: null, 8902 resizeStart: null, 8903 resizeStop: null 8904 }, 8905 8906 _create: function() { 8907 this.originalCss = { 8908 display: this.element[0].style.display, 8909 width: this.element[0].style.width, 8910 minHeight: this.element[0].style.minHeight, 8911 maxHeight: this.element[0].style.maxHeight, 8912 height: this.element[0].style.height 8913 }; 8914 this.originalPosition = { 8915 parent: this.element.parent(), 8916 index: this.element.parent().children().index( this.element ) 8917 }; 8918 this.originalTitle = this.element.attr("title"); 8919 this.options.title = this.options.title || this.originalTitle; 8920 8921 this._createWrapper(); 8922 8923 this.element 8924 .show() 8925 .removeAttr("title") 8926 .addClass("ui-dialog-content ui-widget-content") 8927 .appendTo( this.uiDialog ); 8928 8929 this._createTitlebar(); 8930 this._createButtonPane(); 8931 8932 if ( this.options.draggable && $.fn.draggable ) { 8933 this._makeDraggable(); 8934 } 8935 if ( this.options.resizable && $.fn.resizable ) { 8936 this._makeResizable(); 8937 } 8938 8939 this._isOpen = false; 8940 }, 8941 8942 _init: function() { 8943 if ( this.options.autoOpen ) { 8944 this.open(); 8945 } 8946 }, 8947 8948 _appendTo: function() { 8949 var element = this.options.appendTo; 8950 if ( element && (element.jquery || element.nodeType) ) { 8951 return $( element ); 8952 } 8953 return this.document.find( element || "body" ).eq( 0 ); 8954 }, 8955 8956 _destroy: function() { 8957 var next, 8958 originalPosition = this.originalPosition; 8959 8960 this._destroyOverlay(); 8961 8962 this.element 8963 .removeUniqueId() 8964 .removeClass("ui-dialog-content ui-widget-content") 8965 .css( this.originalCss ) 8966 // Without detaching first, the following becomes really slow 8967 .detach(); 8968 8969 this.uiDialog.stop( true, true ).remove(); 8970 8971 if ( this.originalTitle ) { 8972 this.element.attr( "title", this.originalTitle ); 8973 } 8974 8975 next = originalPosition.parent.children().eq( originalPosition.index ); 8976 // Don't try to place the dialog next to itself (#8613) 8977 if ( next.length && next[0] !== this.element[0] ) { 8978 next.before( this.element ); 8979 } else { 8980 originalPosition.parent.append( this.element ); 8981 } 8982 }, 8983 8984 widget: function() { 8985 return this.uiDialog; 8986 }, 8987 8988 disable: $.noop, 8989 enable: $.noop, 8990 8991 close: function( event ) { 8992 var activeElement, 8993 that = this; 8994 8995 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 8996 return; 8997 } 8998 8999 this._isOpen = false; 9000 this._destroyOverlay(); 9001 9002 if ( !this.opener.filter(":focusable").focus().length ) { 9003 9004 // support: IE9 9005 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 9006 try { 9007 activeElement = this.document[ 0 ].activeElement; 9008 9009 // Support: IE9, IE10 9010 // If the <body> is blurred, IE will switch windows, see #4520 9011 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 9012 9013 // Hiding a focused element doesn't trigger blur in WebKit 9014 // so in case we have nothing to focus on, explicitly blur the active element 9015 // https://bugs.webkit.org/show_bug.cgi?id=47182 9016 $( activeElement ).blur(); 9017 } 9018 } catch ( error ) {} 9019 } 9020 9021 this._hide( this.uiDialog, this.options.hide, function() { 9022 that._trigger( "close", event ); 9023 }); 9024 }, 9025 9026 isOpen: function() { 9027 return this._isOpen; 9028 }, 9029 9030 moveToTop: function() { 9031 this._moveToTop(); 9032 }, 9033 9034 _moveToTop: function( event, silent ) { 9035 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9036 if ( moved && !silent ) { 9037 this._trigger( "focus", event ); 9038 } 9039 return moved; 9040 }, 9041 9042 open: function() { 9043 var that = this; 9044 if ( this._isOpen ) { 9045 if ( this._moveToTop() ) { 9046 this._focusTabbable(); 9047 } 9048 return; 9049 } 9050 9051 this._isOpen = true; 9052 this.opener = $( this.document[0].activeElement ); 9053 9054 this._size(); 9055 this._position(); 9056 this._createOverlay(); 9057 this._moveToTop( null, true ); 9058 this._show( this.uiDialog, this.options.show, function() { 9059 that._focusTabbable(); 9060 that._trigger("focus"); 9061 }); 9062 9063 this._trigger("open"); 9064 }, 9065 9066 _focusTabbable: function() { 9067 // Set focus to the first match: 9068 // 1. First element inside the dialog matching [autofocus] 9069 // 2. Tabbable element inside the content element 9070 // 3. Tabbable element inside the buttonpane 9071 // 4. The close button 9072 // 5. The dialog itself 9073 var hasFocus = this.element.find("[autofocus]"); 9074 if ( !hasFocus.length ) { 9075 hasFocus = this.element.find(":tabbable"); 9076 } 9077 if ( !hasFocus.length ) { 9078 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9079 } 9080 if ( !hasFocus.length ) { 9081 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9082 } 9083 if ( !hasFocus.length ) { 9084 hasFocus = this.uiDialog; 9085 } 9086 hasFocus.eq( 0 ).focus(); 9087 }, 9088 9089 _keepFocus: function( event ) { 9090 function checkFocus() { 9091 var activeElement = this.document[0].activeElement, 9092 isActive = this.uiDialog[0] === activeElement || 9093 $.contains( this.uiDialog[0], activeElement ); 9094 if ( !isActive ) { 9095 this._focusTabbable(); 9096 } 9097 } 9098 event.preventDefault(); 9099 checkFocus.call( this ); 9100 // support: IE 9101 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9102 // so we check again later 9103 this._delay( checkFocus ); 9104 }, 9105 9106 _createWrapper: function() { 9107 this.uiDialog = $("<div>") 9108 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9109 this.options.dialogClass ) 9110 .hide() 9111 .attr({ 9112 // Setting tabIndex makes the div focusable 9113 tabIndex: -1, 9114 role: "dialog" 9115 }) 9116 .appendTo( this._appendTo() ); 9117 9118 this._on( this.uiDialog, { 9119 keydown: function( event ) { 9120 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9121 event.keyCode === $.ui.keyCode.ESCAPE ) { 9122 event.preventDefault(); 9123 this.close( event ); 9124 return; 9125 } 9126 9127 // prevent tabbing out of dialogs 9128 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9129 return; 9130 } 9131 var tabbables = this.uiDialog.find(":tabbable"), 9132 first = tabbables.filter(":first"), 9133 last = tabbables.filter(":last"); 9134 9135 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9136 first.focus( 1 ); 9137 event.preventDefault(); 9138 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9139 last.focus( 1 ); 9140 event.preventDefault(); 9141 } 9142 }, 9143 mousedown: function( event ) { 9144 if ( this._moveToTop( event ) ) { 9145 this._focusTabbable(); 9146 } 9147 } 9148 }); 9149 9150 // We assume that any existing aria-describedby attribute means 9151 // that the dialog content is marked up properly 9152 // otherwise we brute force the content as the description 9153 if ( !this.element.find("[aria-describedby]").length ) { 9154 this.uiDialog.attr({ 9155 "aria-describedby": this.element.uniqueId().attr("id") 9156 }); 9157 } 9158 }, 9159 9160 _createTitlebar: function() { 9161 var uiDialogTitle; 9162 9163 this.uiDialogTitlebar = $("<div>") 9164 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9165 .prependTo( this.uiDialog ); 9166 this._on( this.uiDialogTitlebar, { 9167 mousedown: function( event ) { 9168 // Don't prevent click on close button (#8838) 9169 // Focusing a dialog that is partially scrolled out of view 9170 // causes the browser to scroll it into view, preventing the click event 9171 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9172 // Dialog isn't getting focus when dragging (#8063) 9173 this.uiDialog.focus(); 9174 } 9175 } 9176 }); 9177 9178 // support: IE 9179 // Use type="button" to prevent enter keypresses in textboxes from closing the 9180 // dialog in IE (#9312) 9181 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 9182 .button({ 9183 label: this.options.closeText, 9184 icons: { 9185 primary: "ui-icon-closethick" 9186 }, 9187 text: false 9188 }) 9189 .addClass("ui-dialog-titlebar-close") 9190 .appendTo( this.uiDialogTitlebar ); 9191 this._on( this.uiDialogTitlebarClose, { 9192 click: function( event ) { 9193 event.preventDefault(); 9194 this.close( event ); 9195 } 9196 }); 9197 9198 uiDialogTitle = $("<span>") 9199 .uniqueId() 9200 .addClass("ui-dialog-title") 9201 .prependTo( this.uiDialogTitlebar ); 9202 this._title( uiDialogTitle ); 9203 9204 this.uiDialog.attr({ 9205 "aria-labelledby": uiDialogTitle.attr("id") 9206 }); 9207 }, 9208 9209 _title: function( title ) { 9210 if ( !this.options.title ) { 9211 title.html(" "); 9212 } 9213 title.text( this.options.title ); 9214 }, 9215 9216 _createButtonPane: function() { 9217 this.uiDialogButtonPane = $("<div>") 9218 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9219 9220 this.uiButtonSet = $("<div>") 9221 .addClass("ui-dialog-buttonset") 9222 .appendTo( this.uiDialogButtonPane ); 9223 9224 this._createButtons(); 9225 }, 9226 9227 _createButtons: function() { 9228 var that = this, 9229 buttons = this.options.buttons; 9230 9231 // if we already have a button pane, remove it 9232 this.uiDialogButtonPane.remove(); 9233 this.uiButtonSet.empty(); 9234 9235 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 9236 this.uiDialog.removeClass("ui-dialog-buttons"); 9237 return; 9238 } 9239 9240 $.each( buttons, function( name, props ) { 9241 var click, buttonOptions; 9242 props = $.isFunction( props ) ? 9243 { click: props, text: name } : 9244 props; 9245 // Default to a non-submitting button 9246 props = $.extend( { type: "button" }, props ); 9247 // Change the context for the click callback to be the main element 9248 click = props.click; 9249 props.click = function() { 9250 click.apply( that.element[0], arguments ); 9251 }; 9252 buttonOptions = { 9253 icons: props.icons, 9254 text: props.showText 9255 }; 9256 delete props.icons; 9257 delete props.showText; 9258 $( "<button></button>", props ) 9259 .button( buttonOptions ) 9260 .appendTo( that.uiButtonSet ); 9261 }); 9262 this.uiDialog.addClass("ui-dialog-buttons"); 9263 this.uiDialogButtonPane.appendTo( this.uiDialog ); 9264 }, 9265 9266 _makeDraggable: function() { 9267 var that = this, 9268 options = this.options; 9269 9270 function filteredUi( ui ) { 9271 return { 9272 position: ui.position, 9273 offset: ui.offset 9274 }; 9275 } 9276 9277 this.uiDialog.draggable({ 9278 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 9279 handle: ".ui-dialog-titlebar", 9280 containment: "document", 9281 start: function( event, ui ) { 9282 $( this ).addClass("ui-dialog-dragging"); 9283 that._blockFrames(); 9284 that._trigger( "dragStart", event, filteredUi( ui ) ); 9285 }, 9286 drag: function( event, ui ) { 9287 that._trigger( "drag", event, filteredUi( ui ) ); 9288 }, 9289 stop: function( event, ui ) { 9290 options.position = [ 9291 ui.position.left - that.document.scrollLeft(), 9292 ui.position.top - that.document.scrollTop() 9293 ]; 9294 $( this ).removeClass("ui-dialog-dragging"); 9295 that._unblockFrames(); 9296 that._trigger( "dragStop", event, filteredUi( ui ) ); 9297 } 9298 }); 9299 }, 9300 9301 _makeResizable: function() { 9302 var that = this, 9303 options = this.options, 9304 handles = options.resizable, 9305 // .ui-resizable has position: relative defined in the stylesheet 9306 // but dialogs have to use absolute or fixed positioning 9307 position = this.uiDialog.css("position"), 9308 resizeHandles = typeof handles === "string" ? 9309 handles : 9310 "n,e,s,w,se,sw,ne,nw"; 9311 9312 function filteredUi( ui ) { 9313 return { 9314 originalPosition: ui.originalPosition, 9315 originalSize: ui.originalSize, 9316 position: ui.position, 9317 size: ui.size 9318 }; 9319 } 9320 9321 this.uiDialog.resizable({ 9322 cancel: ".ui-dialog-content", 9323 containment: "document", 9324 alsoResize: this.element, 9325 maxWidth: options.maxWidth, 9326 maxHeight: options.maxHeight, 9327 minWidth: options.minWidth, 9328 minHeight: this._minHeight(), 9329 handles: resizeHandles, 9330 start: function( event, ui ) { 9331 $( this ).addClass("ui-dialog-resizing"); 9332 that._blockFrames(); 9333 that._trigger( "resizeStart", event, filteredUi( ui ) ); 9334 }, 9335 resize: function( event, ui ) { 9336 that._trigger( "resize", event, filteredUi( ui ) ); 9337 }, 9338 stop: function( event, ui ) { 9339 options.height = $( this ).height(); 9340 options.width = $( this ).width(); 9341 $( this ).removeClass("ui-dialog-resizing"); 9342 that._unblockFrames(); 9343 that._trigger( "resizeStop", event, filteredUi( ui ) ); 9344 } 9345 }) 9346 .css( "position", position ); 9347 }, 9348 9349 _minHeight: function() { 9350 var options = this.options; 9351 9352 return options.height === "auto" ? 9353 options.minHeight : 9354 Math.min( options.minHeight, options.height ); 9355 }, 9356 9357 _position: function() { 9358 // Need to show the dialog to get the actual offset in the position plugin 9359 var isVisible = this.uiDialog.is(":visible"); 9360 if ( !isVisible ) { 9361 this.uiDialog.show(); 9362 } 9363 this.uiDialog.position( this.options.position ); 9364 if ( !isVisible ) { 9365 this.uiDialog.hide(); 9366 } 9367 }, 9368 9369 _setOptions: function( options ) { 9370 var that = this, 9371 resize = false, 9372 resizableOptions = {}; 9373 9374 $.each( options, function( key, value ) { 9375 that._setOption( key, value ); 9376 9377 if ( key in sizeRelatedOptions ) { 9378 resize = true; 9379 } 9380 if ( key in resizableRelatedOptions ) { 9381 resizableOptions[ key ] = value; 9382 } 9383 }); 9384 9385 if ( resize ) { 9386 this._size(); 9387 this._position(); 9388 } 9389 if ( this.uiDialog.is(":data(ui-resizable)") ) { 9390 this.uiDialog.resizable( "option", resizableOptions ); 9391 } 9392 }, 9393 9394 _setOption: function( key, value ) { 9395 var isDraggable, isResizable, 9396 uiDialog = this.uiDialog; 9397 9398 if ( key === "dialogClass" ) { 9399 uiDialog 9400 .removeClass( this.options.dialogClass ) 9401 .addClass( value ); 9402 } 9403 9404 if ( key === "disabled" ) { 9405 return; 9406 } 9407 9408 this._super( key, value ); 9409 9410 if ( key === "appendTo" ) { 9411 this.uiDialog.appendTo( this._appendTo() ); 9412 } 9413 9414 if ( key === "buttons" ) { 9415 this._createButtons(); 9416 } 9417 9418 if ( key === "closeText" ) { 9419 this.uiDialogTitlebarClose.button({ 9420 // Ensure that we always pass a string 9421 label: "" + value 9422 }); 9423 } 9424 9425 if ( key === "draggable" ) { 9426 isDraggable = uiDialog.is(":data(ui-draggable)"); 9427 if ( isDraggable && !value ) { 9428 uiDialog.draggable("destroy"); 9429 } 9430 9431 if ( !isDraggable && value ) { 9432 this._makeDraggable(); 9433 } 9434 } 9435 9436 if ( key === "position" ) { 9437 this._position(); 9438 } 9439 9440 if ( key === "resizable" ) { 9441 // currently resizable, becoming non-resizable 9442 isResizable = uiDialog.is(":data(ui-resizable)"); 9443 if ( isResizable && !value ) { 9444 uiDialog.resizable("destroy"); 9445 } 9446 9447 // currently resizable, changing handles 9448 if ( isResizable && typeof value === "string" ) { 9449 uiDialog.resizable( "option", "handles", value ); 9450 } 9451 9452 // currently non-resizable, becoming resizable 9453 if ( !isResizable && value !== false ) { 9454 this._makeResizable(); 9455 } 9456 } 9457 9458 if ( key === "title" ) { 9459 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 9460 } 9461 }, 9462 9463 _size: function() { 9464 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9465 // divs will both have width and height set, so we need to reset them 9466 var nonContentHeight, minContentHeight, maxContentHeight, 9467 options = this.options; 9468 9469 // Reset content sizing 9470 this.element.show().css({ 9471 width: "auto", 9472 minHeight: 0, 9473 maxHeight: "none", 9474 height: 0 9475 }); 9476 9477 if ( options.minWidth > options.width ) { 9478 options.width = options.minWidth; 9479 } 9480 9481 // reset wrapper sizing 9482 // determine the height of all the non-content elements 9483 nonContentHeight = this.uiDialog.css({ 9484 height: "auto", 9485 width: options.width 9486 }) 9487 .outerHeight(); 9488 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 9489 maxContentHeight = typeof options.maxHeight === "number" ? 9490 Math.max( 0, options.maxHeight - nonContentHeight ) : 9491 "none"; 9492 9493 if ( options.height === "auto" ) { 9494 this.element.css({ 9495 minHeight: minContentHeight, 9496 maxHeight: maxContentHeight, 9497 height: "auto" 9498 }); 9499 } else { 9500 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 9501 } 9502 9503 if (this.uiDialog.is(":data(ui-resizable)") ) { 9504 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 9505 } 9506 }, 9507 9508 _blockFrames: function() { 9509 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 9510 var iframe = $( this ); 9511 9512 return $( "<div>" ) 9513 .css({ 9514 position: "absolute", 9515 width: iframe.outerWidth(), 9516 height: iframe.outerHeight() 9517 }) 9518 .appendTo( iframe.parent() ) 9519 .offset( iframe.offset() )[0]; 9520 }); 9521 }, 9522 9523 _unblockFrames: function() { 9524 if ( this.iframeBlocks ) { 9525 this.iframeBlocks.remove(); 9526 delete this.iframeBlocks; 9527 } 9528 }, 9529 9530 _allowInteraction: function( event ) { 9531 if ( $( event.target ).closest(".ui-dialog").length ) { 9532 return true; 9533 } 9534 9535 // TODO: Remove hack when datepicker implements 9536 // the .ui-front logic (#8989) 9537 return !!$( event.target ).closest(".ui-datepicker").length; 9538 }, 9539 9540 _createOverlay: function() { 9541 if ( !this.options.modal ) { 9542 return; 9543 } 9544 9545 var that = this, 9546 widgetFullName = this.widgetFullName; 9547 if ( !$.ui.dialog.overlayInstances ) { 9548 // Prevent use of anchors and inputs. 9549 // We use a delay in case the overlay is created from an 9550 // event that we're going to be cancelling. (#2804) 9551 this._delay(function() { 9552 // Handle .dialog().dialog("close") (#4065) 9553 if ( $.ui.dialog.overlayInstances ) { 9554 this.document.bind( "focusin.dialog", function( event ) { 9555 if ( !that._allowInteraction( event ) ) { 9556 event.preventDefault(); 9557 $(".ui-dialog:visible:last .ui-dialog-content") 9558 .data( widgetFullName )._focusTabbable(); 9559 } 9560 }); 9561 } 9562 }); 9563 } 9564
9565 this.overlay = $("<div>") 9566 .addClass("ui-widget-overlay ui-front") 9567 .appendTo( this._appendTo() ); 9568 this._on( this.overlay, { 9569 mousedown: "_keepFocus" 9570 }); 9571 $.ui.dialog.overlayInstances++; 9572 }, 9573 9574 _destroyOverlay: function() { 9575 if ( !this.options.modal ) { 9576 return; 9577 } 9578 9579 if ( this.overlay ) { 9580 $.ui.dialog.overlayInstances--; 9581 9582 if ( !$.ui.dialog.overlayInstances ) { 9583 this.document.unbind( "focusin.dialog" ); 9584 } 9585 this.overlay.remove(); 9586 this.overlay = null; 9587 } 9588 } 9589}); 9590 9591$.ui.dialog.overlayInstances = 0; 9592 9593// DEPRECATED 9594if ( $.uiBackCompat !== false ) { 9595 // position option with array notation 9596 // just override with old implementation 9597 $.widget( "ui.dialog", $.ui.dialog, { 9598 _position: function() { 9599 var position = this.options.position, 9600 myAt = [], 9601 offset = [ 0, 0 ], 9602 isVisible; 9603 9604 if ( position ) { 9605 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 9606 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 9607 if ( myAt.length === 1 ) { 9608 myAt[1] = myAt[0]; 9609 } 9610 9611 $.each( [ "left", "top" ], function( i, offsetPosition ) { 9612 if ( +myAt[ i ] === myAt[ i ] ) { 9613 offset[ i ] = myAt[ i ]; 9614 myAt[ i ] = offsetPosition; 9615 } 9616 }); 9617 9618 position = { 9619 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 9620 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 9621 at: myAt.join(" ") 9622 }; 9623 } 9624 9625 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 9626 } else { 9627 position = $.ui.dialog.prototype.options.position; 9628 } 9629 9630 // need to show the dialog to get the actual offset in the position plugin 9631 isVisible = this.uiDialog.is(":visible"); 9632 if ( !isVisible ) { 9633 this.uiDialog.show(); 9634 } 9635 this.uiDialog.position( position ); 9636 if ( !isVisible ) { 9637 this.uiDialog.hide(); 9638 } 9639 } 9640 }); 9641} 9642 9643}( jQuery ) ); 9644(function( $, undefined ) { 9645 9646$.widget( "ui.menu", { 9647 version: "1.10.4", 9648 defaultElement: "<ul>", 9649 delay: 300, 9650 options: { 9651 icons: { 9652 submenu: "ui-icon-carat-1-e" 9653 }, 9654 menus: "ul", 9655 position: { 9656 my: "left top", 9657 at: "right top" 9658 }, 9659 role: "menu", 9660 9661 // callbacks 9662 blur: null, 9663 focus: null, 9664 select: null 9665 }, 9666 9667 _create: function() { 9668 this.activeMenu = this.element; 9669 // flag used to prevent firing of the click handler 9670 // as the event bubbles up through nested menus 9671 this.mouseHandled = false; 9672 this.element 9673 .uniqueId() 9674 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9675 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 9676 .attr({ 9677 role: this.options.role, 9678 tabIndex: 0 9679 }) 9680 // need to catch all clicks on disabled menu 9681 // not possible through _on 9682 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 9683 if ( this.options.disabled ) { 9684 event.preventDefault(); 9685 } 9686 }, this )); 9687 9688 if ( this.options.disabled ) { 9689 this.element 9690 .addClass( "ui-state-disabled" ) 9691 .attr( "aria-disabled", "true" ); 9692 } 9693 9694 this._on({ 9695 // Prevent focus from sticking to links inside menu after clicking 9696 // them (focus should always stay on UL during navigation). 9697 "mousedown .ui-menu-item > a": function( event ) { 9698 event.preventDefault(); 9699 }, 9700 "click .ui-state-disabled > a": function( event ) { 9701 event.preventDefault(); 9702 }, 9703 "click .ui-menu-item:has(a)": function( event ) { 9704 var target = $( event.target ).closest( ".ui-menu-item" ); 9705 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 9706 this.select( event ); 9707 9708 // Only set the mouseHandled flag if the event will bubble, see #9469. 9709 if ( !event.isPropagationStopped() ) { 9710 this.mouseHandled = true; 9711 } 9712 9713 // Open submenu on click 9714 if ( target.has( ".ui-menu" ).length ) { 9715 this.expand( event ); 9716 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 9717 9718 // Redirect focus to the menu 9719 this.element.trigger( "focus", [ true ] ); 9720 9721 // If the active item is on the top level, let it stay active. 9722 // Otherwise, blur the active item since it is no longer visible. 9723 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 9724 clearTimeout( this.timer ); 9725 } 9726 } 9727 } 9728 }, 9729 "mouseenter .ui-menu-item": function( event ) { 9730 var target = $( event.currentTarget ); 9731 // Remove ui-state-active class from siblings of the newly focused menu item 9732 // to avoid a jump caused by adjacent elements both having a class with a border 9733 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 9734 this.focus( event, target ); 9735 }, 9736 mouseleave: "collapseAll", 9737 "mouseleave .ui-menu": "collapseAll", 9738 focus: function( event, keepActiveItem ) { 9739 // If there's already an active item, keep it active 9740 // If not, activate the first item 9741 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 9742 9743 if ( !keepActiveItem ) { 9744 this.focus( event, item ); 9745 } 9746 }, 9747 blur: function( event ) { 9748 this._delay(function() { 9749 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 9750 this.collapseAll( event ); 9751 } 9752 }); 9753 }, 9754 keydown: "_keydown" 9755 }); 9756 9757 this.refresh(); 9758
vendor: 113,707 bytes, lines 9759-14187
9759 // Clicks outside of a menu collapse any open menus 9760 this._on( this.document, { 9761 click: function( event ) { 9762 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 9763 this.collapseAll( event ); 9764 } 9765 9766 // Reset the mouseHandled flag 9767 this.mouseHandled = false; 9768 } 9769 }); 9770 }, 9771 9772 _destroy: function() { 9773 // Destroy (sub)menus 9774 this.element 9775 .removeAttr( "aria-activedescendant" ) 9776 .find( ".ui-menu" ).addBack() 9777 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 9778 .removeAttr( "role" ) 9779 .removeAttr( "tabIndex" ) 9780 .removeAttr( "aria-labelledby" ) 9781 .removeAttr( "aria-expanded" ) 9782 .removeAttr( "aria-hidden" ) 9783 .removeAttr( "aria-disabled" ) 9784 .removeUniqueId() 9785 .show(); 9786 9787 // Destroy menu items 9788 this.element.find( ".ui-menu-item" ) 9789 .removeClass( "ui-menu-item" ) 9790 .removeAttr( "role" ) 9791 .removeAttr( "aria-disabled" ) 9792 .children( "a" ) 9793 .removeUniqueId() 9794 .removeClass( "ui-corner-all ui-state-hover" ) 9795 .removeAttr( "tabIndex" ) 9796 .removeAttr( "role" ) 9797 .removeAttr( "aria-haspopup" ) 9798 .children().each( function() { 9799 var elem = $( this ); 9800 if ( elem.data( "ui-menu-submenu-carat" ) ) { 9801 elem.remove(); 9802 } 9803 }); 9804 9805 // Destroy menu dividers 9806 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 9807 }, 9808 9809 _keydown: function( event ) { 9810 var match, prev, character, skip, regex, 9811 preventDefault = true; 9812 9813 function escape( value ) { 9814 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 9815 } 9816 9817 switch ( event.keyCode ) { 9818 case $.ui.keyCode.PAGE_UP: 9819 this.previousPage( event ); 9820 break; 9821 case $.ui.keyCode.PAGE_DOWN: 9822 this.nextPage( event ); 9823 break; 9824 case $.ui.keyCode.HOME: 9825 this._move( "first", "first", event ); 9826 break; 9827 case $.ui.keyCode.END: 9828 this._move( "last", "last", event ); 9829 break; 9830 case $.ui.keyCode.UP: 9831 this.previous( event ); 9832 break; 9833 case $.ui.keyCode.DOWN: 9834 this.next( event ); 9835 break; 9836 case $.ui.keyCode.LEFT: 9837 this.collapse( event ); 9838 break; 9839 case $.ui.keyCode.RIGHT: 9840 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 9841 this.expand( event ); 9842 } 9843 break; 9844 case $.ui.keyCode.ENTER: 9845 case $.ui.keyCode.SPACE: 9846 this._activate( event ); 9847 break; 9848 case $.ui.keyCode.ESCAPE: 9849 this.collapse( event ); 9850 break; 9851 default: 9852 preventDefault = false; 9853 prev = this.previousFilter || ""; 9854 character = String.fromCharCode( event.keyCode ); 9855 skip = false; 9856 9857 clearTimeout( this.filterTimer ); 9858 9859 if ( character === prev ) { 9860 skip = true; 9861 } else { 9862 character = prev + character; 9863 } 9864 9865 regex = new RegExp( "^" + escape( character ), "i" ); 9866 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9867 return regex.test( $( this ).children( "a" ).text() ); 9868 }); 9869 match = skip && match.index( this.active.next() ) !== -1 ? 9870 this.active.nextAll( ".ui-menu-item" ) : 9871 match; 9872 9873 // If no matches on the current filter, reset to the last character pressed 9874 // to move down the menu to the first item that starts with that character 9875 if ( !match.length ) { 9876 character = String.fromCharCode( event.keyCode ); 9877 regex = new RegExp( "^" + escape( character ), "i" ); 9878 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9879 return regex.test( $( this ).children( "a" ).text() ); 9880 }); 9881 } 9882 9883 if ( match.length ) { 9884 this.focus( event, match ); 9885 if ( match.length > 1 ) { 9886 this.previousFilter = character; 9887 this.filterTimer = this._delay(function() { 9888 delete this.previousFilter; 9889 }, 1000 ); 9890 } else { 9891 delete this.previousFilter; 9892 } 9893 } else { 9894 delete this.previousFilter; 9895 } 9896 } 9897 9898 if ( preventDefault ) { 9899 event.preventDefault(); 9900 } 9901 }, 9902 9903 _activate: function( event ) { 9904 if ( !this.active.is( ".ui-state-disabled" ) ) { 9905 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 9906 this.expand( event ); 9907 } else { 9908 this.select( event ); 9909 } 9910 } 9911 }, 9912 9913 refresh: function() { 9914 var menus, 9915 icon = this.options.icons.submenu, 9916 submenus = this.element.find( this.options.menus ); 9917 9918 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 9919 9920 // Initialize nested menus 9921 submenus.filter( ":not(.ui-menu)" ) 9922 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9923 .hide() 9924 .attr({ 9925 role: this.options.role, 9926 "aria-hidden": "true", 9927 "aria-expanded": "false" 9928 }) 9929 .each(function() { 9930 var menu = $( this ), 9931 item = menu.prev( "a" ), 9932 submenuCarat = $( "<span>" ) 9933 .addClass( "ui-menu-icon ui-icon " + icon ) 9934 .data( "ui-menu-submenu-carat", true ); 9935 9936 item 9937 .attr( "aria-haspopup", "true" ) 9938 .prepend( submenuCarat ); 9939 menu.attr( "aria-labelledby", item.attr( "id" ) ); 9940 }); 9941 9942 menus = submenus.add( this.element ); 9943 9944 // Don't refresh list items that are already adapted 9945 menus.children( ":not(.ui-menu-item):has(a)" ) 9946 .addClass( "ui-menu-item" ) 9947 .attr( "role", "presentation" ) 9948 .children( "a" ) 9949 .uniqueId() 9950 .addClass( "ui-corner-all" ) 9951 .attr({ 9952 tabIndex: -1, 9953 role: this._itemRole() 9954 }); 9955 9956 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 9957 menus.children( ":not(.ui-menu-item)" ).each(function() { 9958 var item = $( this ); 9959 // hyphen, em dash, en dash 9960 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 9961 item.addClass( "ui-widget-content ui-menu-divider" ); 9962 } 9963 }); 9964 9965 // Add aria-disabled attribute to any disabled menu item 9966 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 9967 9968 // If the active item has been removed, blur the menu 9969 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 9970 this.blur(); 9971 } 9972 }, 9973 9974 _itemRole: function() { 9975 return { 9976 menu: "menuitem", 9977 listbox: "option" 9978 }[ this.options.role ]; 9979 }, 9980 9981 _setOption: function( key, value ) { 9982 if ( key === "icons" ) { 9983 this.element.find( ".ui-menu-icon" ) 9984 .removeClass( this.options.icons.submenu ) 9985 .addClass( value.submenu ); 9986 } 9987 this._super( key, value ); 9988 }, 9989 9990 focus: function( event, item ) { 9991 var nested, focused; 9992 this.blur( event, event && event.type === "focus" ); 9993 9994 this._scrollIntoView( item ); 9995 9996 this.active = item.first(); 9997 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 9998 // Only update aria-activedescendant if there's a role 9999 // otherwise we assume focus is managed elsewhere 10000 if ( this.options.role ) { 10001 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 10002 } 10003 10004 // Highlight active parent menu item, if any 10005 this.active 10006 .parent() 10007 .closest( ".ui-menu-item" ) 10008 .children( "a:first" ) 10009 .addClass( "ui-state-active" ); 10010 10011 if ( event && event.type === "keydown" ) { 10012 this._close(); 10013 } else { 10014 this.timer = this._delay(function() { 10015 this._close(); 10016 }, this.delay ); 10017 } 10018 10019 nested = item.children( ".ui-menu" ); 10020 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 10021 this._startOpening(nested); 10022 } 10023 this.activeMenu = item.parent(); 10024 10025 this._trigger( "focus", event, { item: item } ); 10026 }, 10027 10028 _scrollIntoView: function( item ) { 10029 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 10030 if ( this._hasScroll() ) { 10031 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 10032 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 10033 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 10034 scroll = this.activeMenu.scrollTop(); 10035 elementHeight = this.activeMenu.height(); 10036 itemHeight = item.height(); 10037 10038 if ( offset < 0 ) { 10039 this.activeMenu.scrollTop( scroll + offset ); 10040 } else if ( offset + itemHeight > elementHeight ) { 10041 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 10042 } 10043 } 10044 }, 10045 10046 blur: function( event, fromFocus ) { 10047 if ( !fromFocus ) { 10048 clearTimeout( this.timer ); 10049 } 10050 10051 if ( !this.active ) { 10052 return; 10053 } 10054 10055 this.active.children( "a" ).removeClass( "ui-state-focus" ); 10056 this.active = null; 10057 10058 this._trigger( "blur", event, { item: this.active } ); 10059 }, 10060 10061 _startOpening: function( submenu ) { 10062 clearTimeout( this.timer ); 10063 10064 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 10065 // shift in the submenu position when mousing over the carat icon 10066 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 10067 return; 10068 } 10069 10070 this.timer = this._delay(function() { 10071 this._close(); 10072 this._open( submenu ); 10073 }, this.delay ); 10074 }, 10075 10076 _open: function( submenu ) { 10077 var position = $.extend({ 10078 of: this.active 10079 }, this.options.position ); 10080 10081 clearTimeout( this.timer ); 10082 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 10083 .hide() 10084 .attr( "aria-hidden", "true" ); 10085 10086 submenu 10087 .show() 10088 .removeAttr( "aria-hidden" ) 10089 .attr( "aria-expanded", "true" ) 10090 .position( position ); 10091 }, 10092 10093 collapseAll: function( event, all ) { 10094 clearTimeout( this.timer ); 10095 this.timer = this._delay(function() { 10096 // If we were passed an event, look for the submenu that contains the event 10097 var currentMenu = all ? this.element : 10098 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 10099 10100 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 10101 if ( !currentMenu.length ) { 10102 currentMenu = this.element; 10103 } 10104 10105 this._close( currentMenu ); 10106 10107 this.blur( event ); 10108 this.activeMenu = currentMenu; 10109 }, this.delay ); 10110 }, 10111 10112 // With no arguments, closes the currently active menu - if nothing is active 10113 // it closes all menus. If passed an argument, it will search for menus BELOW 10114 _close: function( startMenu ) { 10115 if ( !startMenu ) { 10116 startMenu = this.active ? this.active.parent() : this.element; 10117 } 10118 10119 startMenu 10120 .find( ".ui-menu" ) 10121 .hide() 10122 .attr( "aria-hidden", "true" ) 10123 .attr( "aria-expanded", "false" ) 10124 .end() 10125 .find( "a.ui-state-active" ) 10126 .removeClass( "ui-state-active" ); 10127 }, 10128 10129 collapse: function( event ) { 10130 var newItem = this.active && 10131 this.active.parent().closest( ".ui-menu-item", this.element ); 10132 if ( newItem && newItem.length ) { 10133 this._close(); 10134 this.focus( event, newItem ); 10135 } 10136 }, 10137 10138 expand: function( event ) { 10139 var newItem = this.active && 10140 this.active 10141 .children( ".ui-menu " ) 10142 .children( ".ui-menu-item" ) 10143 .first(); 10144 10145 if ( newItem && newItem.length ) { 10146 this._open( newItem.parent() ); 10147 10148 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 10149 this._delay(function() { 10150 this.focus( event, newItem ); 10151 }); 10152 } 10153 }, 10154 10155 next: function( event ) { 10156 this._move( "next", "first", event ); 10157 }, 10158 10159 previous: function( event ) { 10160 this._move( "prev", "last", event ); 10161 }, 10162 10163 isFirstItem: function() { 10164 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 10165 }, 10166 10167 isLastItem: function() { 10168 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 10169 }, 10170 10171 _move: function( direction, filter, event ) { 10172 var next; 10173 if ( this.active ) { 10174 if ( direction === "first" || direction === "last" ) { 10175 next = this.active 10176 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 10177 .eq( -1 ); 10178 } else { 10179 next = this.active 10180 [ direction + "All" ]( ".ui-menu-item" ) 10181 .eq( 0 ); 10182 } 10183 } 10184 if ( !next || !next.length || !this.active ) { 10185 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 10186 } 10187 10188 this.focus( event, next ); 10189 }, 10190 10191 nextPage: function( event ) { 10192 var item, base, height; 10193 10194 if ( !this.active ) { 10195 this.next( event ); 10196 return; 10197 } 10198 if ( this.isLastItem() ) { 10199 return; 10200 } 10201 if ( this._hasScroll() ) { 10202 base = this.active.offset().top; 10203 height = this.element.height(); 10204 this.active.nextAll( ".ui-menu-item" ).each(function() { 10205 item = $( this ); 10206 return item.offset().top - base - height < 0; 10207 }); 10208 10209 this.focus( event, item ); 10210 } else { 10211 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 10212 [ !this.active ? "first" : "last" ]() ); 10213 } 10214 }, 10215 10216 previousPage: function( event ) { 10217 var item, base, height; 10218 if ( !this.active ) { 10219 this.next( event ); 10220 return; 10221 } 10222 if ( this.isFirstItem() ) { 10223 return; 10224 } 10225 if ( this._hasScroll() ) { 10226 base = this.active.offset().top; 10227 height = this.element.height(); 10228 this.active.prevAll( ".ui-menu-item" ).each(function() { 10229 item = $( this ); 10230 return item.offset().top - base + height > 0; 10231 }); 10232 10233 this.focus( event, item ); 10234 } else { 10235 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 10236 } 10237 }, 10238 10239 _hasScroll: function() { 10240 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 10241 }, 10242 10243 select: function( event ) { 10244 // TODO: It should never be possible to not have an active item at this 10245 // point, but the tests don't trigger mouseenter before click. 10246 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 10247 var ui = { item: this.active }; 10248 if ( !this.active.has( ".ui-menu" ).length ) { 10249 this.collapseAll( event, true ); 10250 } 10251 this._trigger( "select", event, ui ); 10252 } 10253}); 10254 10255}( jQuery )); 10256(function( $, undefined ) { 10257 10258$.widget( "ui.progressbar", { 10259 version: "1.10.4", 10260 options: { 10261 max: 100, 10262 value: 0, 10263 10264 change: null, 10265 complete: null 10266 }, 10267 10268 min: 0, 10269 10270 _create: function() { 10271 // Constrain initial value 10272 this.oldValue = this.options.value = this._constrainedValue(); 10273 10274 this.element 10275 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10276 .attr({ 10277 // Only set static values, aria-valuenow and aria-valuemax are 10278 // set inside _refreshValue() 10279 role: "progressbar", 10280 "aria-valuemin": this.min 10281 }); 10282 10283 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10284 .appendTo( this.element ); 10285 10286 this._refreshValue(); 10287 }, 10288 10289 _destroy: function() { 10290 this.element 10291 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10292 .removeAttr( "role" ) 10293 .removeAttr( "aria-valuemin" ) 10294 .removeAttr( "aria-valuemax" ) 10295 .removeAttr( "aria-valuenow" ); 10296 10297 this.valueDiv.remove(); 10298 }, 10299 10300 value: function( newValue ) { 10301 if ( newValue === undefined ) { 10302 return this.options.value; 10303 } 10304 10305 this.options.value = this._constrainedValue( newValue ); 10306 this._refreshValue(); 10307 }, 10308 10309 _constrainedValue: function( newValue ) { 10310 if ( newValue === undefined ) { 10311 newValue = this.options.value; 10312 } 10313 10314 this.indeterminate = newValue === false; 10315 10316 // sanitize value 10317 if ( typeof newValue !== "number" ) { 10318 newValue = 0; 10319 } 10320 10321 return this.indeterminate ? false : 10322 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10323 }, 10324 10325 _setOptions: function( options ) { 10326 // Ensure "value" option is set after other values (like max) 10327 var value = options.value; 10328 delete options.value; 10329 10330 this._super( options ); 10331 10332 this.options.value = this._constrainedValue( value ); 10333 this._refreshValue(); 10334 }, 10335 10336 _setOption: function( key, value ) { 10337 if ( key === "max" ) { 10338 // Don't allow a max less than min 10339 value = Math.max( this.min, value ); 10340 } 10341 10342 this._super( key, value ); 10343 }, 10344 10345 _percentage: function() { 10346 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 10347 }, 10348 10349 _refreshValue: function() { 10350 var value = this.options.value, 10351 percentage = this._percentage(); 10352 10353 this.valueDiv 10354 .toggle( this.indeterminate || value > this.min ) 10355 .toggleClass( "ui-corner-right", value === this.options.max ) 10356 .width( percentage.toFixed(0) + "%" ); 10357 10358 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 10359 10360 if ( this.indeterminate ) { 10361 this.element.removeAttr( "aria-valuenow" ); 10362 if ( !this.overlayDiv ) { 10363 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 10364 } 10365 } else { 10366 this.element.attr({ 10367 "aria-valuemax": this.options.max, 10368 "aria-valuenow": value 10369 }); 10370 if ( this.overlayDiv ) { 10371 this.overlayDiv.remove(); 10372 this.overlayDiv = null; 10373 } 10374 } 10375 10376 if ( this.oldValue !== value ) { 10377 this.oldValue = value; 10378 this._trigger( "change" ); 10379 } 10380 if ( value === this.options.max ) { 10381 this._trigger( "complete" ); 10382 } 10383 } 10384}); 10385 10386})( jQuery ); 10387(function( $, undefined ) { 10388 10389// number of pages in a slider 10390// (how many times can you page up/down to go through the whole range) 10391var numPages = 5; 10392 10393$.widget( "ui.slider", $.ui.mouse, { 10394 version: "1.10.4", 10395 widgetEventPrefix: "slide", 10396 10397 options: { 10398 animate: false, 10399 distance: 0, 10400 max: 100, 10401 min: 0, 10402 orientation: "horizontal", 10403 range: false, 10404 step: 1, 10405 value: 0, 10406 values: null, 10407 10408 // callbacks 10409 change: null, 10410 slide: null, 10411 start: null, 10412 stop: null 10413 }, 10414 10415 _create: function() { 10416 this._keySliding = false; 10417 this._mouseSliding = false; 10418 this._animateOff = true; 10419 this._handleIndex = null; 10420 this._detectOrientation(); 10421 this._mouseInit(); 10422 10423 this.element 10424 .addClass( "ui-slider" + 10425 " ui-slider-" + this.orientation + 10426 " ui-widget" + 10427 " ui-widget-content" + 10428 " ui-corner-all"); 10429 10430 this._refresh(); 10431 this._setOption( "disabled", this.options.disabled ); 10432 10433 this._animateOff = false; 10434 }, 10435 10436 _refresh: function() { 10437 this._createRange(); 10438 this._createHandles(); 10439 this._setupEvents(); 10440 this._refreshValue(); 10441 }, 10442 10443 _createHandles: function() { 10444 var i, handleCount, 10445 options = this.options, 10446 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 10447 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 10448 handles = []; 10449 10450 handleCount = ( options.values && options.values.length ) || 1; 10451 10452 if ( existingHandles.length > handleCount ) { 10453 existingHandles.slice( handleCount ).remove(); 10454 existingHandles = existingHandles.slice( 0, handleCount ); 10455 } 10456 10457 for ( i = existingHandles.length; i < handleCount; i++ ) { 10458 handles.push( handle ); 10459 } 10460 10461 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 10462 10463 this.handle = this.handles.eq( 0 ); 10464 10465 this.handles.each(function( i ) { 10466 $( this ).data( "ui-slider-handle-index", i ); 10467 }); 10468 }, 10469 10470 _createRange: function() { 10471 var options = this.options, 10472 classes = ""; 10473 10474 if ( options.range ) { 10475 if ( options.range === true ) { 10476 if ( !options.values ) { 10477 options.values = [ this._valueMin(), this._valueMin() ]; 10478 } else if ( options.values.length && options.values.length !== 2 ) { 10479 options.values = [ options.values[0], options.values[0] ]; 10480 } else if ( $.isArray( options.values ) ) { 10481 options.values = options.values.slice(0); 10482 } 10483 } 10484 10485 if ( !this.range || !this.range.length ) { 10486 this.range = $( "<div></div>" ) 10487 .appendTo( this.element ); 10488 10489 classes = "ui-slider-range" + 10490 // note: this isn't the most fittingly semantic framework class for this element, 10491 // but worked best visually with a variety of themes 10492 " ui-widget-header ui-corner-all"; 10493 } else { 10494 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 10495 // Handle range switching from true to min/max 10496 .css({ 10497 "left": "", 10498 "bottom": "" 10499 }); 10500 } 10501 10502 this.range.addClass( classes + 10503 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 10504 } else { 10505 if ( this.range ) { 10506 this.range.remove(); 10507 } 10508 this.range = null; 10509 } 10510 }, 10511 10512 _setupEvents: function() { 10513 var elements = this.handles.add( this.range ).filter( "a" ); 10514 this._off( elements ); 10515 this._on( elements, this._handleEvents ); 10516 this._hoverable( elements ); 10517 this._focusable( elements ); 10518 }, 10519 10520 _destroy: function() { 10521 this.handles.remove(); 10522 if ( this.range ) { 10523 this.range.remove(); 10524 } 10525 10526 this.element 10527 .removeClass( "ui-slider" + 10528 " ui-slider-horizontal" + 10529 " ui-slider-vertical" + 10530 " ui-widget" + 10531 " ui-widget-content" + 10532 " ui-corner-all" ); 10533 10534 this._mouseDestroy(); 10535 }, 10536 10537 _mouseCapture: function( event ) { 10538 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 10539 that = this, 10540 o = this.options; 10541 10542 if ( o.disabled ) { 10543 return false; 10544 } 10545 10546 this.elementSize = { 10547 width: this.element.outerWidth(), 10548 height: this.element.outerHeight() 10549 }; 10550 this.elementOffset = this.element.offset(); 10551 10552 position = { x: event.pageX, y: event.pageY }; 10553 normValue = this._normValueFromMouse( position ); 10554 distance = this._valueMax() - this._valueMin() + 1; 10555 this.handles.each(function( i ) { 10556 var thisDistance = Math.abs( normValue - that.values(i) ); 10557 if (( distance > thisDistance ) || 10558 ( distance === thisDistance && 10559 (i === that._lastChangedValue || that.values(i) === o.min ))) { 10560 distance = thisDistance; 10561 closestHandle = $( this ); 10562 index = i; 10563 } 10564 }); 10565 10566 allowed = this._start( event, index ); 10567 if ( allowed === false ) { 10568 return false; 10569 } 10570 this._mouseSliding = true; 10571 10572 this._handleIndex = index; 10573 10574 closestHandle 10575 .addClass( "ui-state-active" ) 10576 .focus(); 10577 10578 offset = closestHandle.offset(); 10579 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 10580 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 10581 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 10582 top: event.pageY - offset.top - 10583 ( closestHandle.height() / 2 ) - 10584 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 10585 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 10586 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 10587 }; 10588 10589 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 10590 this._slide( event, index, normValue ); 10591 } 10592 this._animateOff = true; 10593 return true; 10594 }, 10595 10596 _mouseStart: function() { 10597 return true; 10598 }, 10599 10600 _mouseDrag: function( event ) { 10601 var position = { x: event.pageX, y: event.pageY }, 10602 normValue = this._normValueFromMouse( position ); 10603 10604 this._slide( event, this._handleIndex, normValue ); 10605 10606 return false; 10607 }, 10608 10609 _mouseStop: function( event ) { 10610 this.handles.removeClass( "ui-state-active" ); 10611 this._mouseSliding = false; 10612 10613 this._stop( event, this._handleIndex ); 10614 this._change( event, this._handleIndex ); 10615 10616 this._handleIndex = null; 10617 this._clickOffset = null; 10618 this._animateOff = false; 10619 10620 return false; 10621 }, 10622 10623 _detectOrientation: function() { 10624 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 10625 }, 10626 10627 _normValueFromMouse: function( position ) { 10628 var pixelTotal, 10629 pixelMouse, 10630 percentMouse, 10631 valueTotal, 10632 valueMouse; 10633 10634 if ( this.orientation === "horizontal" ) { 10635 pixelTotal = this.elementSize.width; 10636 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 10637 } else { 10638 pixelTotal = this.elementSize.height; 10639 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 10640 } 10641 10642 percentMouse = ( pixelMouse / pixelTotal ); 10643 if ( percentMouse > 1 ) { 10644 percentMouse = 1; 10645 } 10646 if ( percentMouse < 0 ) { 10647 percentMouse = 0; 10648 } 10649 if ( this.orientation === "vertical" ) { 10650 percentMouse = 1 - percentMouse; 10651 } 10652 10653 valueTotal = this._valueMax() - this._valueMin(); 10654 valueMouse = this._valueMin() + percentMouse * valueTotal; 10655 10656 return this._trimAlignValue( valueMouse ); 10657 }, 10658 10659 _start: function( event, index ) { 10660 var uiHash = { 10661 handle: this.handles[ index ], 10662 value: this.value() 10663 }; 10664 if ( this.options.values && this.options.values.length ) { 10665 uiHash.value = this.values( index ); 10666 uiHash.values = this.values(); 10667 } 10668 return this._trigger( "start", event, uiHash ); 10669 }, 10670 10671 _slide: function( event, index, newVal ) { 10672 var otherVal, 10673 newValues, 10674 allowed; 10675 10676 if ( this.options.values && this.options.values.length ) { 10677 otherVal = this.values( index ? 0 : 1 ); 10678 10679 if ( ( this.options.values.length === 2 && this.options.range === true ) && 10680 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 10681 ) { 10682 newVal = otherVal; 10683 } 10684 10685 if ( newVal !== this.values( index ) ) { 10686 newValues = this.values(); 10687 newValues[ index ] = newVal; 10688 // A slide can be canceled by returning false from the slide callback 10689 allowed = this._trigger( "slide", event, { 10690 handle: this.handles[ index ], 10691 value: newVal, 10692 values: newValues 10693 } ); 10694 otherVal = this.values( index ? 0 : 1 ); 10695 if ( allowed !== false ) { 10696 this.values( index, newVal ); 10697 } 10698 } 10699 } else { 10700 if ( newVal !== this.value() ) { 10701 // A slide can be canceled by returning false from the slide callback 10702 allowed = this._trigger( "slide", event, { 10703 handle: this.handles[ index ], 10704 value: newVal 10705 } ); 10706 if ( allowed !== false ) { 10707 this.value( newVal ); 10708 } 10709 } 10710 } 10711 }, 10712 10713 _stop: function( event, index ) { 10714 var uiHash = { 10715 handle: this.handles[ index ], 10716 value: this.value() 10717 }; 10718 if ( this.options.values && this.options.values.length ) { 10719 uiHash.value = this.values( index ); 10720 uiHash.values = this.values(); 10721 } 10722 10723 this._trigger( "stop", event, uiHash ); 10724 }, 10725 10726 _change: function( event, index ) { 10727 if ( !this._keySliding && !this._mouseSliding ) { 10728 var uiHash = { 10729 handle: this.handles[ index ], 10730 value: this.value() 10731 }; 10732 if ( this.options.values && this.options.values.length ) { 10733 uiHash.value = this.values( index ); 10734 uiHash.values = this.values(); 10735 } 10736 10737 //store the last changed value index for reference when handles overlap 10738 this._lastChangedValue = index; 10739 10740 this._trigger( "change", event, uiHash ); 10741 } 10742 }, 10743 10744 value: function( newValue ) { 10745 if ( arguments.length ) { 10746 this.options.value = this._trimAlignValue( newValue ); 10747 this._refreshValue(); 10748 this._change( null, 0 ); 10749 return; 10750 } 10751 10752 return this._value(); 10753 }, 10754 10755 values: function( index, newValue ) { 10756 var vals, 10757 newValues, 10758 i; 10759 10760 if ( arguments.length > 1 ) { 10761 this.options.values[ index ] = this._trimAlignValue( newValue ); 10762 this._refreshValue(); 10763 this._change( null, index ); 10764 return; 10765 } 10766 10767 if ( arguments.length ) { 10768 if ( $.isArray( arguments[ 0 ] ) ) { 10769 vals = this.options.values; 10770 newValues = arguments[ 0 ]; 10771 for ( i = 0; i < vals.length; i += 1 ) { 10772 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 10773 this._change( null, i ); 10774 } 10775 this._refreshValue(); 10776 } else { 10777 if ( this.options.values && this.options.values.length ) { 10778 return this._values( index ); 10779 } else { 10780 return this.value(); 10781 } 10782 } 10783 } else { 10784 return this._values(); 10785 } 10786 }, 10787 10788 _setOption: function( key, value ) { 10789 var i, 10790 valsLength = 0; 10791 10792 if ( key === "range" && this.options.range === true ) { 10793 if ( value === "min" ) { 10794 this.options.value = this._values( 0 ); 10795 this.options.values = null; 10796 } else if ( value === "max" ) { 10797 this.options.value = this._values( this.options.values.length-1 ); 10798 this.options.values = null; 10799 } 10800 } 10801 10802 if ( $.isArray( this.options.values ) ) { 10803 valsLength = this.options.values.length; 10804 } 10805 10806 $.Widget.prototype._setOption.apply( this, arguments ); 10807 10808 switch ( key ) { 10809 case "orientation": 10810 this._detectOrientation(); 10811 this.element 10812 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 10813 .addClass( "ui-slider-" + this.orientation ); 10814 this._refreshValue(); 10815 break; 10816 case "value": 10817 this._animateOff = true; 10818 this._refreshValue(); 10819 this._change( null, 0 ); 10820 this._animateOff = false; 10821 break; 10822 case "values": 10823 this._animateOff = true; 10824 this._refreshValue(); 10825 for ( i = 0; i < valsLength; i += 1 ) { 10826 this._change( null, i ); 10827 } 10828 this._animateOff = false; 10829 break; 10830 case "min": 10831 case "max": 10832 this._animateOff = true; 10833 this._refreshValue(); 10834 this._animateOff = false; 10835 break; 10836 case "range": 10837 this._animateOff = true; 10838 this._refresh(); 10839 this._animateOff = false; 10840 break; 10841 } 10842 }, 10843 10844 //internal value getter 10845 // _value() returns value trimmed by min and max, aligned by step 10846 _value: function() { 10847 var val = this.options.value; 10848 val = this._trimAlignValue( val ); 10849 10850 return val; 10851 }, 10852 10853 //internal values getter 10854 // _values() returns array of values trimmed by min and max, aligned by step 10855 // _values( index ) returns single value trimmed by min and max, aligned by step 10856 _values: function( index ) { 10857 var val, 10858 vals, 10859 i; 10860 10861 if ( arguments.length ) { 10862 val = this.options.values[ index ]; 10863 val = this._trimAlignValue( val ); 10864 10865 return val; 10866 } else if ( this.options.values && this.options.values.length ) { 10867 // .slice() creates a copy of the array 10868 // this copy gets trimmed by min and max and then returned 10869 vals = this.options.values.slice(); 10870 for ( i = 0; i < vals.length; i+= 1) { 10871 vals[ i ] = this._trimAlignValue( vals[ i ] ); 10872 } 10873 10874 return vals; 10875 } else { 10876 return []; 10877 } 10878 }, 10879 10880 // returns the step-aligned value that val is closest to, between (inclusive) min and max 10881 _trimAlignValue: function( val ) { 10882 if ( val <= this._valueMin() ) { 10883 return this._valueMin(); 10884 } 10885 if ( val >= this._valueMax() ) { 10886 return this._valueMax(); 10887 } 10888 var step = ( this.options.step > 0 ) ? this.options.step : 1, 10889 valModStep = (val - this._valueMin()) % step, 10890 alignValue = val - valModStep; 10891 10892 if ( Math.abs(valModStep) * 2 >= step ) { 10893 alignValue += ( valModStep > 0 ) ? step : ( -step ); 10894 } 10895 10896 // Since JavaScript has problems with large floats, round 10897 // the final value to 5 digits after the decimal point (see #4124) 10898 return parseFloat( alignValue.toFixed(5) ); 10899 }, 10900 10901 _valueMin: function() { 10902 return this.options.min; 10903 }, 10904 10905 _valueMax: function() { 10906 return this.options.max; 10907 }, 10908 10909 _refreshValue: function() { 10910 var lastValPercent, valPercent, value, valueMin, valueMax, 10911 oRange = this.options.range, 10912 o = this.options, 10913 that = this, 10914 animate = ( !this._animateOff ) ? o.animate : false, 10915 _set = {}; 10916 10917 if ( this.options.values && this.options.values.length ) { 10918 this.handles.each(function( i ) { 10919 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 10920 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10921 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10922 if ( that.options.range === true ) { 10923 if ( that.orientation === "horizontal" ) { 10924 if ( i === 0 ) { 10925 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 10926 } 10927 if ( i === 1 ) { 10928 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10929 } 10930 } else { 10931 if ( i === 0 ) { 10932 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 10933 } 10934 if ( i === 1 ) { 10935 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10936 } 10937 } 10938 } 10939 lastValPercent = valPercent; 10940 }); 10941 } else { 10942 value = this.value(); 10943 valueMin = this._valueMin(); 10944 valueMax = this._valueMax(); 10945 valPercent = ( valueMax !== valueMin ) ? 10946 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 10947 0; 10948 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10949 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10950 10951 if ( oRange === "min" && this.orientation === "horizontal" ) { 10952 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 10953 } 10954 if ( oRange === "max" && this.orientation === "horizontal" ) { 10955 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10956 } 10957 if ( oRange === "min" && this.orientation === "vertical" ) { 10958 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 10959 } 10960 if ( oRange === "max" && this.orientation === "vertical" ) { 10961 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10962 } 10963 } 10964 }, 10965 10966 _handleEvents: { 10967 keydown: function( event ) { 10968 var allowed, curVal, newVal, step, 10969 index = $( event.target ).data( "ui-slider-handle-index" ); 10970 10971 switch ( event.keyCode ) { 10972 case $.ui.keyCode.HOME: 10973 case $.ui.keyCode.END: 10974 case $.ui.keyCode.PAGE_UP: 10975 case $.ui.keyCode.PAGE_DOWN: 10976 case $.ui.keyCode.UP: 10977 case $.ui.keyCode.RIGHT: 10978 case $.ui.keyCode.DOWN: 10979 case $.ui.keyCode.LEFT: 10980 event.preventDefault(); 10981 if ( !this._keySliding ) { 10982 this._keySliding = true; 10983 $( event.target ).addClass( "ui-state-active" ); 10984 allowed = this._start( event, index ); 10985 if ( allowed === false ) { 10986 return; 10987 } 10988 } 10989 break; 10990 } 10991 10992 step = this.options.step; 10993 if ( this.options.values && this.options.values.length ) { 10994 curVal = newVal = this.values( index ); 10995 } else { 10996 curVal = newVal = this.value(); 10997 } 10998 10999 switch ( event.keyCode ) { 11000 case $.ui.keyCode.HOME: 11001 newVal = this._valueMin(); 11002 break; 11003 case $.ui.keyCode.END: 11004 newVal = this._valueMax(); 11005 break; 11006 case $.ui.keyCode.PAGE_UP: 11007 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 11008 break; 11009 case $.ui.keyCode.PAGE_DOWN: 11010 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 11011 break; 11012 case $.ui.keyCode.UP: 11013 case $.ui.keyCode.RIGHT: 11014 if ( curVal === this._valueMax() ) { 11015 return; 11016 } 11017 newVal = this._trimAlignValue( curVal + step ); 11018 break; 11019 case $.ui.keyCode.DOWN: 11020 case $.ui.keyCode.LEFT: 11021 if ( curVal === this._valueMin() ) { 11022 return; 11023 } 11024 newVal = this._trimAlignValue( curVal - step ); 11025 break; 11026 } 11027 11028 this._slide( event, index, newVal ); 11029 }, 11030 click: function( event ) { 11031 event.preventDefault(); 11032 }, 11033 keyup: function( event ) { 11034 var index = $( event.target ).data( "ui-slider-handle-index" ); 11035 11036 if ( this._keySliding ) { 11037 this._keySliding = false; 11038 this._stop( event, index ); 11039 this._change( event, index ); 11040 $( event.target ).removeClass( "ui-state-active" ); 11041 } 11042 } 11043 } 11044 11045}); 11046 11047}(jQuery)); 11048(function( $ ) { 11049 11050function modifier( fn ) { 11051 return function() { 11052 var previous = this.element.val(); 11053 fn.apply( this, arguments ); 11054 this._refresh(); 11055 if ( previous !== this.element.val() ) { 11056 this._trigger( "change" ); 11057 } 11058 }; 11059} 11060 11061$.widget( "ui.spinner", { 11062 version: "1.10.4", 11063 defaultElement: "<input>", 11064 widgetEventPrefix: "spin", 11065 options: { 11066 culture: null, 11067 icons: { 11068 down: "ui-icon-triangle-1-s", 11069 up: "ui-icon-triangle-1-n" 11070 }, 11071 incremental: true, 11072 max: null, 11073 min: null, 11074 numberFormat: null, 11075 page: 10, 11076 step: 1, 11077 11078 change: null, 11079 spin: null, 11080 start: null, 11081 stop: null 11082 }, 11083 11084 _create: function() { 11085 // handle string values that need to be parsed 11086 this._setOption( "max", this.options.max ); 11087 this._setOption( "min", this.options.min ); 11088 this._setOption( "step", this.options.step ); 11089 11090 // Only format if there is a value, prevents the field from being marked 11091 // as invalid in Firefox, see #9573. 11092 if ( this.value() !== "" ) { 11093 // Format the value, but don't constrain. 11094 this._value( this.element.val(), true ); 11095 } 11096 11097 this._draw(); 11098 this._on( this._events ); 11099 this._refresh(); 11100 11101 // turning off autocomplete prevents the browser from remembering the 11102 // value when navigating through history, so we re-enable autocomplete 11103 // if the page is unloaded before the widget is destroyed. #7790 11104 this._on( this.window, { 11105 beforeunload: function() { 11106 this.element.removeAttr( "autocomplete" ); 11107 } 11108 }); 11109 }, 11110 11111 _getCreateOptions: function() { 11112 var options = {}, 11113 element = this.element; 11114 11115 $.each( [ "min", "max", "step" ], function( i, option ) { 11116 var value = element.attr( option ); 11117 if ( value !== undefined && value.length ) { 11118 options[ option ] = value; 11119 } 11120 }); 11121 11122 return options; 11123 }, 11124 11125 _events: { 11126 keydown: function( event ) { 11127 if ( this._start( event ) && this._keydown( event ) ) { 11128 event.preventDefault(); 11129 } 11130 }, 11131 keyup: "_stop", 11132 focus: function() { 11133 this.previous = this.element.val(); 11134 }, 11135 blur: function( event ) { 11136 if ( this.cancelBlur ) { 11137 delete this.cancelBlur; 11138 return; 11139 } 11140 11141 this._stop(); 11142 this._refresh(); 11143 if ( this.previous !== this.element.val() ) { 11144 this._trigger( "change", event ); 11145 } 11146 }, 11147 mousewheel: function( event, delta ) { 11148 if ( !delta ) { 11149 return; 11150 } 11151 if ( !this.spinning && !this._start( event ) ) { 11152 return false; 11153 } 11154 11155 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 11156 clearTimeout( this.mousewheelTimer ); 11157 this.mousewheelTimer = this._delay(function() { 11158 if ( this.spinning ) { 11159 this._stop( event ); 11160 } 11161 }, 100 ); 11162 event.preventDefault(); 11163 }, 11164 "mousedown .ui-spinner-button": function( event ) { 11165 var previous; 11166 11167 // We never want the buttons to have focus; whenever the user is 11168 // interacting with the spinner, the focus should be on the input. 11169 // If the input is focused then this.previous is properly set from 11170 // when the input first received focus. If the input is not focused 11171 // then we need to set this.previous based on the value before spinning. 11172 previous = this.element[0] === this.document[0].activeElement ? 11173 this.previous : this.element.val(); 11174 function checkFocus() { 11175 var isActive = this.element[0] === this.document[0].activeElement; 11176 if ( !isActive ) { 11177 this.element.focus(); 11178 this.previous = previous; 11179 // support: IE 11180 // IE sets focus asynchronously, so we need to check if focus 11181 // moved off of the input because the user clicked on the button. 11182 this._delay(function() { 11183 this.previous = previous; 11184 }); 11185 } 11186 } 11187 11188 // ensure focus is on (or stays on) the text field 11189 event.preventDefault(); 11190 checkFocus.call( this ); 11191 11192 // support: IE 11193 // IE doesn't prevent moving focus even with event.preventDefault() 11194 // so we set a flag to know when we should ignore the blur event 11195 // and check (again) if focus moved off of the input. 11196 this.cancelBlur = true; 11197 this._delay(function() { 11198 delete this.cancelBlur; 11199 checkFocus.call( this ); 11200 }); 11201 11202 if ( this._start( event ) === false ) { 11203 return; 11204 } 11205 11206 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11207 }, 11208 "mouseup .ui-spinner-button": "_stop", 11209 "mouseenter .ui-spinner-button": function( event ) { 11210 // button will add ui-state-active if mouse was down while mouseleave and kept down 11211 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 11212 return; 11213 } 11214 11215 if ( this._start( event ) === false ) { 11216 return false; 11217 } 11218 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11219 }, 11220 // TODO: do we really want to consider this a stop? 11221 // shouldn't we just stop the repeater and wait until mouseup before 11222 // we trigger the stop event? 11223 "mouseleave .ui-spinner-button": "_stop" 11224 }, 11225 11226 _draw: function() { 11227 var uiSpinner = this.uiSpinner = this.element 11228 .addClass( "ui-spinner-input" ) 11229 .attr( "autocomplete", "off" ) 11230 .wrap( this._uiSpinnerHtml() ) 11231 .parent() 11232 // add buttons 11233 .append( this._buttonHtml() ); 11234 11235 this.element.attr( "role", "spinbutton" ); 11236 11237 // button bindings 11238 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 11239 .attr( "tabIndex", -1 ) 11240 .button() 11241 .removeClass( "ui-corner-all" ); 11242 11243 // IE 6 doesn't understand height: 50% for the buttons 11244 // unless the wrapper has an explicit height 11245 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 11246 uiSpinner.height() > 0 ) { 11247 uiSpinner.height( uiSpinner.height() ); 11248 } 11249 11250 // disable spinner if element was already disabled 11251 if ( this.options.disabled ) { 11252 this.disable(); 11253 } 11254 }, 11255 11256 _keydown: function( event ) { 11257 var options = this.options, 11258 keyCode = $.ui.keyCode; 11259 11260 switch ( event.keyCode ) { 11261 case keyCode.UP: 11262 this._repeat( null, 1, event ); 11263 return true; 11264 case keyCode.DOWN: 11265 this._repeat( null, -1, event ); 11266 return true; 11267 case keyCode.PAGE_UP: 11268 this._repeat( null, options.page, event ); 11269 return true; 11270 case keyCode.PAGE_DOWN: 11271 this._repeat( null, -options.page, event ); 11272 return true; 11273 } 11274 11275 return false; 11276 }, 11277 11278 _uiSpinnerHtml: function() { 11279 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 11280 }, 11281 11282 _buttonHtml: function() { 11283 return "" + 11284 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 11285 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 11286 "</a>" + 11287 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 11288 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 11289 "</a>"; 11290 }, 11291 11292 _start: function( event ) { 11293 if ( !this.spinning && this._trigger( "start", event ) === false ) { 11294 return false; 11295 } 11296 11297 if ( !this.counter ) { 11298 this.counter = 1; 11299 } 11300 this.spinning = true; 11301 return true; 11302 }, 11303 11304 _repeat: function( i, steps, event ) { 11305 i = i || 500; 11306 11307 clearTimeout( this.timer ); 11308 this.timer = this._delay(function() { 11309 this._repeat( 40, steps, event ); 11310 }, i ); 11311 11312 this._spin( steps * this.options.step, event ); 11313 }, 11314 11315 _spin: function( step, event ) { 11316 var value = this.value() || 0; 11317 11318 if ( !this.counter ) { 11319 this.counter = 1; 11320 } 11321 11322 value = this._adjustValue( value + step * this._increment( this.counter ) ); 11323 11324 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 11325 this._value( value ); 11326 this.counter++; 11327 } 11328 }, 11329 11330 _increment: function( i ) { 11331 var incremental = this.options.incremental; 11332 11333 if ( incremental ) { 11334 return $.isFunction( incremental ) ? 11335 incremental( i ) : 11336 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 11337 } 11338 11339 return 1; 11340 }, 11341 11342 _precision: function() { 11343 var precision = this._precisionOf( this.options.step ); 11344 if ( this.options.min !== null ) { 11345 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 11346 } 11347 return precision; 11348 }, 11349 11350 _precisionOf: function( num ) { 11351 var str = num.toString(), 11352 decimal = str.indexOf( "." ); 11353 return decimal === -1 ? 0 : str.length - decimal - 1; 11354 }, 11355 11356 _adjustValue: function( value ) { 11357 var base, aboveMin, 11358 options = this.options; 11359 11360 // make sure we're at a valid step 11361 // - find out where we are relative to the base (min or 0) 11362 base = options.min !== null ? options.min : 0; 11363 aboveMin = value - base; 11364 // - round to the nearest step 11365 aboveMin = Math.round(aboveMin / options.step) * options.step; 11366 // - rounding is based on 0, so adjust back to our base 11367 value = base + aboveMin; 11368 11369 // fix precision from bad JS floating point math 11370 value = parseFloat( value.toFixed( this._precision() ) ); 11371 11372 // clamp the value 11373 if ( options.max !== null && value > options.max) { 11374 return options.max; 11375 } 11376 if ( options.min !== null && value < options.min ) { 11377 return options.min; 11378 } 11379 11380 return value; 11381 }, 11382 11383 _stop: function( event ) { 11384 if ( !this.spinning ) { 11385 return; 11386 } 11387 11388 clearTimeout( this.timer ); 11389 clearTimeout( this.mousewheelTimer ); 11390 this.counter = 0; 11391 this.spinning = false; 11392 this._trigger( "stop", event ); 11393 }, 11394 11395 _setOption: function( key, value ) { 11396 if ( key === "culture" || key === "numberFormat" ) { 11397 var prevValue = this._parse( this.element.val() ); 11398 this.options[ key ] = value; 11399 this.element.val( this._format( prevValue ) ); 11400 return; 11401 } 11402 11403 if ( key === "max" || key === "min" || key === "step" ) { 11404 if ( typeof value === "string" ) { 11405 value = this._parse( value ); 11406 } 11407 } 11408 if ( key === "icons" ) { 11409 this.buttons.first().find( ".ui-icon" ) 11410 .removeClass( this.options.icons.up ) 11411 .addClass( value.up ); 11412 this.buttons.last().find( ".ui-icon" ) 11413 .removeClass( this.options.icons.down ) 11414 .addClass( value.down ); 11415 } 11416 11417 this._super( key, value ); 11418 11419 if ( key === "disabled" ) { 11420 if ( value ) { 11421 this.element.prop( "disabled", true ); 11422 this.buttons.button( "disable" ); 11423 } else { 11424 this.element.prop( "disabled", false ); 11425 this.buttons.button( "enable" ); 11426 } 11427 } 11428 }, 11429 11430 _setOptions: modifier(function( options ) { 11431 this._super( options ); 11432 this._value( this.element.val() ); 11433 }), 11434 11435 _parse: function( val ) { 11436 if ( typeof val === "string" && val !== "" ) { 11437 val = window.Globalize && this.options.numberFormat ? 11438 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 11439 } 11440 return val === "" || isNaN( val ) ? null : val; 11441 }, 11442 11443 _format: function( value ) { 11444 if ( value === "" ) { 11445 return ""; 11446 } 11447 return window.Globalize && this.options.numberFormat ? 11448 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 11449 value; 11450 }, 11451 11452 _refresh: function() { 11453 this.element.attr({ 11454 "aria-valuemin": this.options.min, 11455 "aria-valuemax": this.options.max, 11456 // TODO: what should we do with values that can't be parsed? 11457 "aria-valuenow": this._parse( this.element.val() ) 11458 }); 11459 }, 11460 11461 // update the value without triggering change 11462 _value: function( value, allowAny ) { 11463 var parsed; 11464 if ( value !== "" ) { 11465 parsed = this._parse( value ); 11466 if ( parsed !== null ) { 11467 if ( !allowAny ) { 11468 parsed = this._adjustValue( parsed ); 11469 } 11470 value = this._format( parsed ); 11471 } 11472 } 11473 this.element.val( value ); 11474 this._refresh(); 11475 }, 11476 11477 _destroy: function() { 11478 this.element 11479 .removeClass( "ui-spinner-input" ) 11480 .prop( "disabled", false ) 11481 .removeAttr( "autocomplete" ) 11482 .removeAttr( "role" ) 11483 .removeAttr( "aria-valuemin" ) 11484 .removeAttr( "aria-valuemax" ) 11485 .removeAttr( "aria-valuenow" ); 11486 this.uiSpinner.replaceWith( this.element ); 11487 }, 11488 11489 stepUp: modifier(function( steps ) { 11490 this._stepUp( steps ); 11491 }), 11492 _stepUp: function( steps ) { 11493 if ( this._start() ) { 11494 this._spin( (steps || 1) * this.options.step ); 11495 this._stop(); 11496 } 11497 }, 11498 11499 stepDown: modifier(function( steps ) { 11500 this._stepDown( steps ); 11501 }), 11502 _stepDown: function( steps ) { 11503 if ( this._start() ) { 11504 this._spin( (steps || 1) * -this.options.step ); 11505 this._stop(); 11506 } 11507 }, 11508 11509 pageUp: modifier(function( pages ) { 11510 this._stepUp( (pages || 1) * this.options.page ); 11511 }), 11512 11513 pageDown: modifier(function( pages ) { 11514 this._stepDown( (pages || 1) * this.options.page ); 11515 }), 11516 11517 value: function( newVal ) { 11518 if ( !arguments.length ) { 11519 return this._parse( this.element.val() ); 11520 } 11521 modifier( this._value ).call( this, newVal ); 11522 }, 11523 11524 widget: function() { 11525 return this.uiSpinner; 11526 } 11527}); 11528 11529}( jQuery ) ); 11530(function( $, undefined ) { 11531 11532var tabId = 0, 11533 rhash = /#.*$/; 11534 11535function getNextTabId() { 11536 return ++tabId; 11537} 11538 11539function isLocal( anchor ) { 11540 // support: IE7 11541 // IE7 doesn't normalize the href property when set via script (#9317) 11542 anchor = anchor.cloneNode( false ); 11543 11544 return anchor.hash.length > 1 && 11545 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 11546 decodeURIComponent( location.href.replace( rhash, "" ) ); 11547} 11548 11549$.widget( "ui.tabs", { 11550 version: "1.10.4", 11551 delay: 300, 11552 options: { 11553 active: null, 11554 collapsible: false, 11555 event: "click", 11556 heightStyle: "content", 11557 hide: null, 11558 show: null, 11559 11560 // callbacks 11561 activate: null, 11562 beforeActivate: null, 11563 beforeLoad: null, 11564 load: null 11565 }, 11566 11567 _create: function() { 11568 var that = this, 11569 options = this.options; 11570 11571 this.running = false; 11572 11573 this.element 11574 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 11575 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 11576 // Prevent users from focusing disabled tabs via click 11577 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 11578 if ( $( this ).is( ".ui-state-disabled" ) ) { 11579 event.preventDefault(); 11580 } 11581 }) 11582 // support: IE <9 11583 // Preventing the default action in mousedown doesn't prevent IE 11584 // from focusing the element, so if the anchor gets focused, blur. 11585 // We don't have to worry about focusing the previously focused 11586 // element since clicking on a non-focusable element should focus 11587 // the body anyway. 11588 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 11589 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 11590 this.blur(); 11591 } 11592 }); 11593 11594 this._processTabs(); 11595 options.active = this._initialActive(); 11596 11597 // Take disabling tabs via class attribute from HTML 11598 // into account and update option properly. 11599 if ( $.isArray( options.disabled ) ) { 11600 options.disabled = $.unique( options.disabled.concat( 11601 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 11602 return that.tabs.index( li ); 11603 }) 11604 ) ).sort(); 11605 } 11606 11607 // check for length avoids error when initializing empty list 11608 if ( this.options.active !== false && this.anchors.length ) { 11609 this.active = this._findActive( options.active ); 11610 } else { 11611 this.active = $(); 11612 } 11613 11614 this._refresh(); 11615 11616 if ( this.active.length ) { 11617 this.load( options.active ); 11618 } 11619 }, 11620 11621 _initialActive: function() { 11622 var active = this.options.active, 11623 collapsible = this.options.collapsible, 11624 locationHash = location.hash.substring( 1 ); 11625 11626 if ( active === null ) { 11627 // check the fragment identifier in the URL 11628 if ( locationHash ) { 11629 this.tabs.each(function( i, tab ) { 11630 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 11631 active = i; 11632 return false; 11633 } 11634 }); 11635 } 11636 11637 // check for a tab marked active via a class 11638 if ( active === null ) { 11639 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 11640 } 11641 11642 // no active tab, set to false 11643 if ( active === null || active === -1 ) { 11644 active = this.tabs.length ? 0 : false; 11645 } 11646 } 11647 11648 // handle numbers: negative, out of range 11649 if ( active !== false ) { 11650 active = this.tabs.index( this.tabs.eq( active ) ); 11651 if ( active === -1 ) { 11652 active = collapsible ? false : 0; 11653 } 11654 } 11655 11656 // don't allow collapsible: false and active: false 11657 if ( !collapsible && active === false && this.anchors.length ) { 11658 active = 0; 11659 } 11660 11661 return active; 11662 }, 11663 11664 _getCreateEventData: function() { 11665 return { 11666 tab: this.active, 11667 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 11668 }; 11669 }, 11670 11671 _tabKeydown: function( event ) { 11672 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 11673 selectedIndex = this.tabs.index( focusedTab ), 11674 goingForward = true; 11675 11676 if ( this._handlePageNav( event ) ) { 11677 return; 11678 } 11679 11680 switch ( event.keyCode ) { 11681 case $.ui.keyCode.RIGHT: 11682 case $.ui.keyCode.DOWN: 11683 selectedIndex++; 11684 break; 11685 case $.ui.keyCode.UP: 11686 case $.ui.keyCode.LEFT: 11687 goingForward = false; 11688 selectedIndex--; 11689 break; 11690 case $.ui.keyCode.END: 11691 selectedIndex = this.anchors.length - 1; 11692 break; 11693 case $.ui.keyCode.HOME: 11694 selectedIndex = 0; 11695 break; 11696 case $.ui.keyCode.SPACE: 11697 // Activate only, no collapsing 11698 event.preventDefault(); 11699 clearTimeout( this.activating ); 11700 this._activate( selectedIndex ); 11701 return; 11702 case $.ui.keyCode.ENTER: 11703 // Toggle (cancel delayed activation, allow collapsing) 11704 event.preventDefault(); 11705 clearTimeout( this.activating ); 11706 // Determine if we should collapse or activate 11707 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 11708 return; 11709 default: 11710 return; 11711 } 11712 11713 // Focus the appropriate tab, based on which key was pressed 11714 event.preventDefault(); 11715 clearTimeout( this.activating ); 11716 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 11717 11718 // Navigating with control key will prevent automatic activation 11719 if ( !event.ctrlKey ) { 11720 // Update aria-selected immediately so that AT think the tab is already selected. 11721 // Otherwise AT may confuse the user by stating that they need to activate the tab, 11722 // but the tab will already be activated by the time the announcement finishes. 11723 focusedTab.attr( "aria-selected", "false" ); 11724 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 11725 11726 this.activating = this._delay(function() { 11727 this.option( "active", selectedIndex ); 11728 }, this.delay ); 11729 } 11730 }, 11731 11732 _panelKeydown: function( event ) { 11733 if ( this._handlePageNav( event ) ) { 11734 return; 11735 } 11736 11737 // Ctrl+up moves focus to the current tab 11738 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 11739 event.preventDefault(); 11740 this.active.focus(); 11741 } 11742 }, 11743 11744 // Alt+page up/down moves focus to the previous/next tab (and activates) 11745 _handlePageNav: function( event ) { 11746 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 11747 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 11748 return true; 11749 } 11750 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 11751 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 11752 return true; 11753 } 11754 }, 11755 11756 _findNextTab: function( index, goingForward ) { 11757 var lastTabIndex = this.tabs.length - 1; 11758 11759 function constrain() { 11760 if ( index > lastTabIndex ) { 11761 index = 0; 11762 } 11763 if ( index < 0 ) { 11764 index = lastTabIndex; 11765 } 11766 return index; 11767 } 11768 11769 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 11770 index = goingForward ? index + 1 : index - 1; 11771 } 11772 11773 return index; 11774 }, 11775 11776 _focusNextTab: function( index, goingForward ) { 11777 index = this._findNextTab( index, goingForward ); 11778 this.tabs.eq( index ).focus(); 11779 return index; 11780 }, 11781 11782 _setOption: function( key, value ) { 11783 if ( key === "active" ) { 11784 // _activate() will handle invalid values and update this.options 11785 this._activate( value ); 11786 return; 11787 } 11788 11789 if ( key === "disabled" ) { 11790 // don't use the widget factory's disabled handling 11791 this._setupDisabled( value ); 11792 return; 11793 } 11794 11795 this._super( key, value); 11796 11797 if ( key === "collapsible" ) { 11798 this.element.toggleClass( "ui-tabs-collapsible", value ); 11799 // Setting collapsible: false while collapsed; open first panel 11800 if ( !value && this.options.active === false ) { 11801 this._activate( 0 ); 11802 } 11803 } 11804 11805 if ( key === "event" ) { 11806 this._setupEvents( value ); 11807 } 11808 11809 if ( key === "heightStyle" ) { 11810 this._setupHeightStyle( value ); 11811 } 11812 }, 11813 11814 _tabId: function( tab ) { 11815 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 11816 }, 11817 11818 _sanitizeSelector: function( hash ) { 11819 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 11820 }, 11821 11822 refresh: function() { 11823 var options = this.options, 11824 lis = this.tablist.children( ":has(a[href])" ); 11825 11826 // get disabled tabs from class attribute from HTML 11827 // this will get converted to a boolean if needed in _refresh() 11828 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 11829 return lis.index( tab ); 11830 }); 11831 11832 this._processTabs(); 11833 11834 // was collapsed or no tabs 11835 if ( options.active === false || !this.anchors.length ) { 11836 options.active = false; 11837 this.active = $(); 11838 // was active, but active tab is gone 11839 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 11840 // all remaining tabs are disabled 11841 if ( this.tabs.length === options.disabled.length ) { 11842 options.active = false; 11843 this.active = $(); 11844 // activate previous tab 11845 } else { 11846 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 11847 } 11848 // was active, active tab still exists 11849 } else { 11850 // make sure active index is correct 11851 options.active = this.tabs.index( this.active ); 11852 } 11853 11854 this._refresh(); 11855 }, 11856 11857 _refresh: function() { 11858 this._setupDisabled( this.options.disabled ); 11859 this._setupEvents( this.options.event ); 11860 this._setupHeightStyle( this.options.heightStyle ); 11861 11862 this.tabs.not( this.active ).attr({ 11863 "aria-selected": "false", 11864 tabIndex: -1 11865 }); 11866 this.panels.not( this._getPanelForTab( this.active ) ) 11867 .hide() 11868 .attr({ 11869 "aria-expanded": "false", 11870 "aria-hidden": "true" 11871 }); 11872 11873 // Make sure one tab is in the tab order 11874 if ( !this.active.length ) { 11875 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 11876 } else { 11877 this.active 11878 .addClass( "ui-tabs-active ui-state-active" ) 11879 .attr({ 11880 "aria-selected": "true", 11881 tabIndex: 0 11882 }); 11883 this._getPanelForTab( this.active ) 11884 .show() 11885 .attr({ 11886 "aria-expanded": "true", 11887 "aria-hidden": "false" 11888 }); 11889 } 11890 }, 11891 11892 _processTabs: function() { 11893 var that = this; 11894 11895 this.tablist = this._getList() 11896 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11897 .attr( "role", "tablist" ); 11898 11899 this.tabs = this.tablist.find( "> li:has(a[href])" ) 11900 .addClass( "ui-state-default ui-corner-top" ) 11901 .attr({ 11902 role: "tab", 11903 tabIndex: -1 11904 }); 11905 11906 this.anchors = this.tabs.map(function() { 11907 return $( "a", this )[ 0 ]; 11908 }) 11909 .addClass( "ui-tabs-anchor" ) 11910 .attr({ 11911 role: "presentation", 11912 tabIndex: -1 11913 }); 11914 11915 this.panels = $(); 11916 11917 this.anchors.each(function( i, anchor ) { 11918 var selector, panel, panelId, 11919 anchorId = $( anchor ).uniqueId().attr( "id" ), 11920 tab = $( anchor ).closest( "li" ), 11921 originalAriaControls = tab.attr( "aria-controls" ); 11922 11923 // inline tab 11924 if ( isLocal( anchor ) ) { 11925 selector = anchor.hash; 11926 panel = that.element.find( that._sanitizeSelector( selector ) ); 11927 // remote tab 11928 } else { 11929 panelId = that._tabId( tab ); 11930 selector = "#" + panelId; 11931 panel = that.element.find( selector ); 11932 if ( !panel.length ) { 11933 panel = that._createPanel( panelId ); 11934 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 11935 } 11936 panel.attr( "aria-live", "polite" ); 11937 } 11938 11939 if ( panel.length) { 11940 that.panels = that.panels.add( panel ); 11941 } 11942 if ( originalAriaControls ) { 11943 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 11944 } 11945 tab.attr({ 11946 "aria-controls": selector.substring( 1 ), 11947 "aria-labelledby": anchorId 11948 }); 11949 panel.attr( "aria-labelledby", anchorId ); 11950 }); 11951 11952 this.panels 11953 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11954 .attr( "role", "tabpanel" ); 11955 }, 11956 11957 // allow overriding how to find the list for rare usage scenarios (#7715) 11958 _getList: function() { 11959 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 11960 }, 11961 11962 _createPanel: function( id ) { 11963 return $( "<div>" ) 11964 .attr( "id", id ) 11965 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11966 .data( "ui-tabs-destroy", true ); 11967 }, 11968 11969 _setupDisabled: function( disabled ) { 11970 if ( $.isArray( disabled ) ) { 11971 if ( !disabled.length ) { 11972 disabled = false; 11973 } else if ( disabled.length === this.anchors.length ) { 11974 disabled = true; 11975 } 11976 } 11977 11978 // disable tabs 11979 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 11980 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 11981 $( li ) 11982 .addClass( "ui-state-disabled" ) 11983 .attr( "aria-disabled", "true" ); 11984 } else { 11985 $( li ) 11986 .removeClass( "ui-state-disabled" ) 11987 .removeAttr( "aria-disabled" ); 11988 } 11989 } 11990 11991 this.options.disabled = disabled; 11992 }, 11993 11994 _setupEvents: function( event ) { 11995 var events = { 11996 click: function( event ) { 11997 event.preventDefault(); 11998 } 11999 }; 12000 if ( event ) { 12001 $.each( event.split(" "), function( index, eventName ) { 12002 events[ eventName ] = "_eventHandler"; 12003 }); 12004 } 12005 12006 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 12007 this._on( this.anchors, events ); 12008 this._on( this.tabs, { keydown: "_tabKeydown" } ); 12009 this._on( this.panels, { keydown: "_panelKeydown" } ); 12010 12011 this._focusable( this.tabs ); 12012 this._hoverable( this.tabs ); 12013 }, 12014 12015 _setupHeightStyle: function( heightStyle ) { 12016 var maxHeight, 12017 parent = this.element.parent(); 12018 12019 if ( heightStyle === "fill" ) { 12020 maxHeight = parent.height(); 12021 maxHeight -= this.element.outerHeight() - this.element.height(); 12022 12023 this.element.siblings( ":visible" ).each(function() { 12024 var elem = $( this ), 12025 position = elem.css( "position" ); 12026 12027 if ( position === "absolute" || position === "fixed" ) { 12028 return; 12029 } 12030 maxHeight -= elem.outerHeight( true ); 12031 }); 12032 12033 this.element.children().not( this.panels ).each(function() { 12034 maxHeight -= $( this ).outerHeight( true ); 12035 }); 12036 12037 this.panels.each(function() { 12038 $( this ).height( Math.max( 0, maxHeight - 12039 $( this ).innerHeight() + $( this ).height() ) ); 12040 }) 12041 .css( "overflow", "auto" ); 12042 } else if ( heightStyle === "auto" ) { 12043 maxHeight = 0; 12044 this.panels.each(function() { 12045 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 12046 }).height( maxHeight ); 12047 } 12048 }, 12049 12050 _eventHandler: function( event ) { 12051 var options = this.options, 12052 active = this.active, 12053 anchor = $( event.currentTarget ), 12054 tab = anchor.closest( "li" ), 12055 clickedIsActive = tab[ 0 ] === active[ 0 ], 12056 collapsing = clickedIsActive && options.collapsible, 12057 toShow = collapsing ? $() : this._getPanelForTab( tab ), 12058 toHide = !active.length ? $() : this._getPanelForTab( active ), 12059 eventData = { 12060 oldTab: active, 12061 oldPanel: toHide, 12062 newTab: collapsing ? $() : tab, 12063 newPanel: toShow 12064 }; 12065 12066 event.preventDefault(); 12067 12068 if ( tab.hasClass( "ui-state-disabled" ) || 12069 // tab is already loading 12070 tab.hasClass( "ui-tabs-loading" ) || 12071 // can't switch durning an animation 12072 this.running || 12073 // click on active header, but not collapsible 12074 ( clickedIsActive && !options.collapsible ) || 12075 // allow canceling activation 12076 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 12077 return; 12078 } 12079 12080 options.active = collapsing ? false : this.tabs.index( tab ); 12081 12082 this.active = clickedIsActive ? $() : tab; 12083 if ( this.xhr ) { 12084 this.xhr.abort(); 12085 } 12086 12087 if ( !toHide.length && !toShow.length ) { 12088 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 12089 } 12090 12091 if ( toShow.length ) { 12092 this.load( this.tabs.index( tab ), event ); 12093 } 12094 this._toggle( event, eventData ); 12095 }, 12096 12097 // handles show/hide for selecting tabs 12098 _toggle: function( event, eventData ) { 12099 var that = this, 12100 toShow = eventData.newPanel, 12101 toHide = eventData.oldPanel; 12102 12103 this.running = true; 12104 12105 function complete() { 12106 that.running = false; 12107 that._trigger( "activate", event, eventData ); 12108 } 12109 12110 function show() { 12111 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 12112 12113 if ( toShow.length && that.options.show ) { 12114 that._show( toShow, that.options.show, complete ); 12115 } else { 12116 toShow.show(); 12117 complete(); 12118 } 12119 } 12120 12121 // start out by hiding, then showing, then completing 12122 if ( toHide.length && this.options.hide ) { 12123 this._hide( toHide, this.options.hide, function() { 12124 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12125 show(); 12126 }); 12127 } else { 12128 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12129 toHide.hide(); 12130 show(); 12131 } 12132 12133 toHide.attr({ 12134 "aria-expanded": "false", 12135 "aria-hidden": "true" 12136 }); 12137 eventData.oldTab.attr( "aria-selected", "false" ); 12138 // If we're switching tabs, remove the old tab from the tab order. 12139 // If we're opening from collapsed state, remove the previous tab from the tab order. 12140 // If we're collapsing, then keep the collapsing tab in the tab order. 12141 if ( toShow.length && toHide.length ) { 12142 eventData.oldTab.attr( "tabIndex", -1 ); 12143 } else if ( toShow.length ) { 12144 this.tabs.filter(function() { 12145 return $( this ).attr( "tabIndex" ) === 0; 12146 }) 12147 .attr( "tabIndex", -1 ); 12148 } 12149 12150 toShow.attr({ 12151 "aria-expanded": "true", 12152 "aria-hidden": "false" 12153 }); 12154 eventData.newTab.attr({ 12155 "aria-selected": "true", 12156 tabIndex: 0 12157 }); 12158 }, 12159 12160 _activate: function( index ) { 12161 var anchor, 12162 active = this._findActive( index ); 12163 12164 // trying to activate the already active panel 12165 if ( active[ 0 ] === this.active[ 0 ] ) { 12166 return; 12167 } 12168 12169 // trying to collapse, simulate a click on the current active header 12170 if ( !active.length ) { 12171 active = this.active; 12172 } 12173 12174 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 12175 this._eventHandler({ 12176 target: anchor, 12177 currentTarget: anchor, 12178 preventDefault: $.noop 12179 }); 12180 }, 12181 12182 _findActive: function( index ) { 12183 return index === false ? $() : this.tabs.eq( index ); 12184 }, 12185 12186 _getIndex: function( index ) { 12187 // meta-function to give users option to provide a href string instead of a numerical index. 12188 if ( typeof index === "string" ) { 12189 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 12190 } 12191 12192 return index; 12193 }, 12194 12195 _destroy: function() { 12196 if ( this.xhr ) { 12197 this.xhr.abort(); 12198 } 12199 12200 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 12201 12202 this.tablist 12203 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 12204 .removeAttr( "role" ); 12205 12206 this.anchors 12207 .removeClass( "ui-tabs-anchor" ) 12208 .removeAttr( "role" ) 12209 .removeAttr( "tabIndex" ) 12210 .removeUniqueId(); 12211 12212 this.tabs.add( this.panels ).each(function() { 12213 if ( $.data( this, "ui-tabs-destroy" ) ) { 12214 $( this ).remove(); 12215 } else { 12216 $( this ) 12217 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 12218 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 12219 .removeAttr( "tabIndex" ) 12220 .removeAttr( "aria-live" ) 12221 .removeAttr( "aria-busy" ) 12222 .removeAttr( "aria-selected" ) 12223 .removeAttr( "aria-labelledby" ) 12224 .removeAttr( "aria-hidden" ) 12225 .removeAttr( "aria-expanded" ) 12226 .removeAttr( "role" ); 12227 } 12228 }); 12229 12230 this.tabs.each(function() { 12231 var li = $( this ), 12232 prev = li.data( "ui-tabs-aria-controls" ); 12233 if ( prev ) { 12234 li 12235 .attr( "aria-controls", prev ) 12236 .removeData( "ui-tabs-aria-controls" ); 12237 } else { 12238 li.removeAttr( "aria-controls" ); 12239 } 12240 }); 12241 12242 this.panels.show(); 12243 12244 if ( this.options.heightStyle !== "content" ) { 12245 this.panels.css( "height", "" ); 12246 } 12247 }, 12248 12249 enable: function( index ) { 12250 var disabled = this.options.disabled; 12251 if ( disabled === false ) { 12252 return; 12253 } 12254 12255 if ( index === undefined ) { 12256 disabled = false; 12257 } else { 12258 index = this._getIndex( index ); 12259 if ( $.isArray( disabled ) ) { 12260 disabled = $.map( disabled, function( num ) { 12261 return num !== index ? num : null; 12262 }); 12263 } else { 12264 disabled = $.map( this.tabs, function( li, num ) { 12265 return num !== index ? num : null; 12266 }); 12267 } 12268 } 12269 this._setupDisabled( disabled ); 12270 }, 12271 12272 disable: function( index ) { 12273 var disabled = this.options.disabled; 12274 if ( disabled === true ) { 12275 return; 12276 } 12277 12278 if ( index === undefined ) { 12279 disabled = true; 12280 } else { 12281 index = this._getIndex( index ); 12282 if ( $.inArray( index, disabled ) !== -1 ) { 12283 return; 12284 } 12285 if ( $.isArray( disabled ) ) { 12286 disabled = $.merge( [ index ], disabled ).sort(); 12287 } else { 12288 disabled = [ index ]; 12289 } 12290 } 12291 this._setupDisabled( disabled ); 12292 }, 12293 12294 load: function( index, event ) { 12295 index = this._getIndex( index ); 12296 var that = this, 12297 tab = this.tabs.eq( index ), 12298 anchor = tab.find( ".ui-tabs-anchor" ), 12299 panel = this._getPanelForTab( tab ), 12300 eventData = { 12301 tab: tab, 12302 panel: panel 12303 }; 12304 12305 // not remote 12306 if ( isLocal( anchor[ 0 ] ) ) { 12307 return; 12308 } 12309 12310 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 12311 12312 // support: jQuery <1.8 12313 // jQuery <1.8 returns false if the request is canceled in beforeSend, 12314 // but as of 1.8, $.ajax() always returns a jqXHR object. 12315 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 12316 tab.addClass( "ui-tabs-loading" ); 12317 panel.attr( "aria-busy", "true" ); 12318 12319 this.xhr 12320 .success(function( response ) { 12321 // support: jQuery <1.8 12322 // http://bugs.jquery.com/ticket/11778 12323 setTimeout(function() { 12324 panel.html( response ); 12325 that._trigger( "load", event, eventData ); 12326 }, 1 ); 12327 }) 12328 .complete(function( jqXHR, status ) { 12329 // support: jQuery <1.8 12330 // http://bugs.jquery.com/ticket/11778 12331 setTimeout(function() { 12332 if ( status === "abort" ) { 12333 that.panels.stop( false, true ); 12334 } 12335 12336 tab.removeClass( "ui-tabs-loading" ); 12337 panel.removeAttr( "aria-busy" ); 12338 12339 if ( jqXHR === that.xhr ) { 12340 delete that.xhr; 12341 } 12342 }, 1 ); 12343 }); 12344 } 12345 }, 12346 12347 _ajaxSettings: function( anchor, event, eventData ) { 12348 var that = this; 12349 return { 12350 url: anchor.attr( "href" ), 12351 beforeSend: function( jqXHR, settings ) { 12352 return that._trigger( "beforeLoad", event, 12353 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 12354 } 12355 }; 12356 }, 12357 12358 _getPanelForTab: function( tab ) { 12359 var id = $( tab ).attr( "aria-controls" ); 12360 return this.element.find( this._sanitizeSelector( "#" + id ) ); 12361 } 12362}); 12363 12364})( jQuery ); 12365(function( $ ) { 12366 12367var increments = 0; 12368 12369function addDescribedBy( elem, id ) { 12370 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 12371 describedby.push( id ); 12372 elem 12373 .data( "ui-tooltip-id", id ) 12374 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 12375} 12376 12377function removeDescribedBy( elem ) { 12378 var id = elem.data( "ui-tooltip-id" ), 12379 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 12380 index = $.inArray( id, describedby ); 12381 if ( index !== -1 ) { 12382 describedby.splice( index, 1 ); 12383 } 12384 12385 elem.removeData( "ui-tooltip-id" ); 12386 describedby = $.trim( describedby.join( " " ) ); 12387 if ( describedby ) { 12388 elem.attr( "aria-describedby", describedby ); 12389 } else { 12390 elem.removeAttr( "aria-describedby" ); 12391 } 12392} 12393 12394$.widget( "ui.tooltip", { 12395 version: "1.10.4", 12396 options: { 12397 content: function() { 12398 // support: IE<9, Opera in jQuery <1.7 12399 // .text() can't accept undefined, so coerce to a string 12400 var title = $( this ).attr( "title" ) || ""; 12401 // Escape title, since we're going from an attribute to raw HTML 12402 return $( "<a>" ).text( title ).html(); 12403 }, 12404 hide: true, 12405 // Disabled elements have inconsistent behavior across browsers (#8661) 12406 items: "[title]:not([disabled])", 12407 position: { 12408 my: "left top+15", 12409 at: "left bottom", 12410 collision: "flipfit flip" 12411 }, 12412 show: true, 12413 tooltipClass: null, 12414 track: false, 12415 12416 // callbacks 12417 close: null, 12418 open: null 12419 }, 12420 12421 _create: function() { 12422 this._on({ 12423 mouseover: "open", 12424 focusin: "open" 12425 }); 12426 12427 // IDs of generated tooltips, needed for destroy 12428 this.tooltips = {}; 12429 // IDs of parent tooltips where we removed the title attribute 12430 this.parents = {}; 12431 12432 if ( this.options.disabled ) { 12433 this._disable(); 12434 } 12435 }, 12436 12437 _setOption: function( key, value ) { 12438 var that = this; 12439 12440 if ( key === "disabled" ) { 12441 this[ value ? "_disable" : "_enable" ](); 12442 this.options[ key ] = value; 12443 // disable element style changes 12444 return; 12445 } 12446 12447 this._super( key, value ); 12448 12449 if ( key === "content" ) { 12450 $.each( this.tooltips, function( id, element ) { 12451 that._updateContent( element ); 12452 }); 12453 } 12454 }, 12455 12456 _disable: function() { 12457 var that = this; 12458 12459 // close open tooltips 12460 $.each( this.tooltips, function( id, element ) { 12461 var event = $.Event( "blur" ); 12462 event.target = event.currentTarget = element[0]; 12463 that.close( event, true ); 12464 }); 12465 12466 // remove title attributes to prevent native tooltips 12467 this.element.find( this.options.items ).addBack().each(function() { 12468 var element = $( this ); 12469 if ( element.is( "[title]" ) ) { 12470 element 12471 .data( "ui-tooltip-title", element.attr( "title" ) ) 12472 .attr( "title", "" ); 12473 } 12474 }); 12475 }, 12476 12477 _enable: function() { 12478 // restore title attributes 12479 this.element.find( this.options.items ).addBack().each(function() { 12480 var element = $( this ); 12481 if ( element.data( "ui-tooltip-title" ) ) { 12482 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12483 } 12484 }); 12485 }, 12486 12487 open: function( event ) { 12488 var that = this, 12489 target = $( event ? event.target : this.element ) 12490 // we need closest here due to mouseover bubbling, 12491 // but always pointing at the same event target 12492 .closest( this.options.items ); 12493 12494 // No element to show a tooltip for or the tooltip is already open 12495 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 12496 return; 12497 } 12498 12499 if ( target.attr( "title" ) ) { 12500 target.data( "ui-tooltip-title", target.attr( "title" ) ); 12501 } 12502 12503 target.data( "ui-tooltip-open", true ); 12504 12505 // kill parent tooltips, custom or native, for hover 12506 if ( event && event.type === "mouseover" ) { 12507 target.parents().each(function() { 12508 var parent = $( this ), 12509 blurEvent; 12510 if ( parent.data( "ui-tooltip-open" ) ) { 12511 blurEvent = $.Event( "blur" ); 12512 blurEvent.target = blurEvent.currentTarget = this; 12513 that.close( blurEvent, true ); 12514 } 12515 if ( parent.attr( "title" ) ) { 12516 parent.uniqueId(); 12517 that.parents[ this.id ] = { 12518 element: this, 12519 title: parent.attr( "title" ) 12520 }; 12521 parent.attr( "title", "" ); 12522 } 12523 }); 12524 } 12525 12526 this._updateContent( target, event ); 12527 }, 12528 12529 _updateContent: function( target, event ) { 12530 var content, 12531 contentOption = this.options.content, 12532 that = this, 12533 eventType = event ? event.type : null; 12534 12535 if ( typeof contentOption === "string" ) { 12536 return this._open( event, target, contentOption ); 12537 } 12538 12539 content = contentOption.call( target[0], function( response ) { 12540 // ignore async response if tooltip was closed already 12541 if ( !target.data( "ui-tooltip-open" ) ) { 12542 return; 12543 } 12544 // IE may instantly serve a cached response for ajax requests 12545 // delay this call to _open so the other call to _open runs first 12546 that._delay(function() { 12547 // jQuery creates a special event for focusin when it doesn't 12548 // exist natively. To improve performance, the native event 12549 // object is reused and the type is changed. Therefore, we can't 12550 // rely on the type being correct after the event finished 12551 // bubbling, so we set it back to the previous value. (#8740) 12552 if ( event ) { 12553 event.type = eventType; 12554 } 12555 this._open( event, target, response ); 12556 }); 12557 }); 12558 if ( content ) { 12559 this._open( event, target, content ); 12560 } 12561 }, 12562 12563 _open: function( event, target, content ) { 12564 var tooltip, events, delayedShow, 12565 positionOption = $.extend( {}, this.options.position ); 12566 12567 if ( !content ) { 12568 return; 12569 } 12570 12571 // Content can be updated multiple times. If the tooltip already 12572 // exists, then just update the content and bail. 12573 tooltip = this._find( target ); 12574 if ( tooltip.length ) { 12575 tooltip.find( ".ui-tooltip-content" ).html( content ); 12576 return; 12577 } 12578 12579 // if we have a title, clear it to prevent the native tooltip 12580 // we have to check first to avoid defining a title if none exists 12581 // (we don't want to cause an element to start matching [title]) 12582 // 12583 // We use removeAttr only for key events, to allow IE to export the correct 12584 // accessible attributes. For mouse events, set to empty string to avoid 12585 // native tooltip showing up (happens only when removing inside mouseover). 12586 if ( target.is( "[title]" ) ) { 12587 if ( event && event.type === "mouseover" ) { 12588 target.attr( "title", "" ); 12589 } else { 12590 target.removeAttr( "title" ); 12591 } 12592 } 12593 12594 tooltip = this._tooltip( target ); 12595 addDescribedBy( target, tooltip.attr( "id" ) ); 12596 tooltip.find( ".ui-tooltip-content" ).html( content ); 12597 12598 function position( event ) { 12599 positionOption.of = event; 12600 if ( tooltip.is( ":hidden" ) ) { 12601 return; 12602 } 12603 tooltip.position( positionOption ); 12604 } 12605 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 12606 this._on( this.document, { 12607 mousemove: position 12608 }); 12609 // trigger once to override element-relative positioning 12610 position( event ); 12611 } else { 12612 tooltip.position( $.extend({ 12613 of: target 12614 }, this.options.position ) ); 12615 } 12616 12617 tooltip.hide(); 12618 12619 this._show( tooltip, this.options.show ); 12620 // Handle tracking tooltips that are shown with a delay (#8644). As soon 12621 // as the tooltip is visible, position the tooltip using the most recent 12622 // event. 12623 if ( this.options.show && this.options.show.delay ) { 12624 delayedShow = this.delayedShow = setInterval(function() { 12625 if ( tooltip.is( ":visible" ) ) { 12626 position( positionOption.of ); 12627 clearInterval( delayedShow ); 12628 } 12629 }, $.fx.interval ); 12630 } 12631 12632 this._trigger( "open", event, { tooltip: tooltip } ); 12633 12634 events = { 12635 keyup: function( event ) { 12636 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 12637 var fakeEvent = $.Event(event); 12638 fakeEvent.currentTarget = target[0]; 12639 this.close( fakeEvent, true ); 12640 } 12641 }, 12642 remove: function() { 12643 this._removeTooltip( tooltip ); 12644 } 12645 }; 12646 if ( !event || event.type === "mouseover" ) { 12647 events.mouseleave = "close"; 12648 } 12649 if ( !event || event.type === "focusin" ) { 12650 events.focusout = "close"; 12651 } 12652 this._on( true, target, events ); 12653 }, 12654 12655 close: function( event ) { 12656 var that = this, 12657 target = $( event ? event.currentTarget : this.element ), 12658 tooltip = this._find( target ); 12659 12660 // disabling closes the tooltip, so we need to track when we're closing 12661 // to avoid an infinite loop in case the tooltip becomes disabled on close 12662 if ( this.closing ) { 12663 return; 12664 } 12665 12666 // Clear the interval for delayed tracking tooltips 12667 clearInterval( this.delayedShow ); 12668 12669 // only set title if we had one before (see comment in _open()) 12670 if ( target.data( "ui-tooltip-title" ) ) { 12671 target.attr( "title", target.data( "ui-tooltip-title" ) ); 12672 } 12673 12674 removeDescribedBy( target ); 12675 12676 tooltip.stop( true ); 12677 this._hide( tooltip, this.options.hide, function() { 12678 that._removeTooltip( $( this ) ); 12679 }); 12680 12681 target.removeData( "ui-tooltip-open" ); 12682 this._off( target, "mouseleave focusout keyup" ); 12683 // Remove 'remove' binding only on delegated targets 12684 if ( target[0] !== this.element[0] ) { 12685 this._off( target, "remove" ); 12686 } 12687 this._off( this.document, "mousemove" ); 12688 12689 if ( event && event.type === "mouseleave" ) { 12690 $.each( this.parents, function( id, parent ) { 12691 $( parent.element ).attr( "title", parent.title ); 12692 delete that.parents[ id ]; 12693 }); 12694 } 12695 12696 this.closing = true; 12697 this._trigger( "close", event, { tooltip: tooltip } ); 12698 this.closing = false; 12699 }, 12700 12701 _tooltip: function( element ) { 12702 var id = "ui-tooltip-" + increments++, 12703 tooltip = $( "<div>" ) 12704 .attr({ 12705 id: id, 12706 role: "tooltip" 12707 }) 12708 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 12709 ( this.options.tooltipClass || "" ) ); 12710 $( "<div>" ) 12711 .addClass( "ui-tooltip-content" ) 12712 .appendTo( tooltip ); 12713 tooltip.appendTo( this.document[0].body ); 12714 this.tooltips[ id ] = element; 12715 return tooltip; 12716 }, 12717 12718 _find: function( target ) { 12719 var id = target.data( "ui-tooltip-id" ); 12720 return id ? $( "#" + id ) : $(); 12721 }, 12722 12723 _removeTooltip: function( tooltip ) { 12724 tooltip.remove(); 12725 delete this.tooltips[ tooltip.attr( "id" ) ]; 12726 }, 12727 12728 _destroy: function() { 12729 var that = this; 12730 12731 // close open tooltips 12732 $.each( this.tooltips, function( id, element ) { 12733 // Delegate to close method to handle common cleanup 12734 var event = $.Event( "blur" ); 12735 event.target = event.currentTarget = element[0]; 12736 that.close( event, true ); 12737 12738 // Remove immediately; destroying an open tooltip doesn't use the 12739 // hide animation 12740 $( "#" + id ).remove(); 12741 12742 // Restore the title 12743 if ( element.data( "ui-tooltip-title" ) ) { 12744 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12745 element.removeData( "ui-tooltip-title" ); 12746 } 12747 }); 12748 } 12749}); 12750 12751}( jQuery ) ); 12752(function($, undefined) { 12753 12754var dataSpace = "ui-effects-"; 12755 12756$.effects = { 12757 effect: {} 12758}; 12759 12760/*! 12761 * jQuery Color Animations v2.1.2 12762 * https://github.com/jquery/jquery-color 12763 * 12764 * Copyright 2013 jQuery Foundation and other contributors 12765 * Released under the MIT license. 12766 * http://jquery.org/license 12767 * 12768 * Date: Wed Jan 16 08:47:09 2013 -0600 12769 */ 12770(function( jQuery, undefined ) { 12771 12772 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 12773 12774 // plusequals test for += 100 -= 100 12775 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 12776 // a set of RE's that can match strings and generate color tuples. 12777 stringParsers = [{ 12778 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12779 parse: function( execResult ) { 12780 return [ 12781 execResult[ 1 ], 12782 execResult[ 2 ], 12783 execResult[ 3 ], 12784 execResult[ 4 ] 12785 ]; 12786 } 12787 }, { 12788 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12789 parse: function( execResult ) { 12790 return [ 12791 execResult[ 1 ] * 2.55, 12792 execResult[ 2 ] * 2.55, 12793 execResult[ 3 ] * 2.55, 12794 execResult[ 4 ] 12795 ]; 12796 } 12797 }, { 12798 // this regex ignores A-F because it's compared against an already lowercased string 12799 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 12800 parse: function( execResult ) { 12801 return [ 12802 parseInt( execResult[ 1 ], 16 ), 12803 parseInt( execResult[ 2 ], 16 ), 12804 parseInt( execResult[ 3 ], 16 ) 12805 ]; 12806 } 12807 }, { 12808 // this regex ignores A-F because it's compared against an already lowercased string 12809 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 12810 parse: function( execResult ) { 12811 return [ 12812 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 12813 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 12814 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 12815 ]; 12816 } 12817 }, { 12818 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12819 space: "hsla", 12820 parse: function( execResult ) { 12821 return [ 12822 execResult[ 1 ], 12823 execResult[ 2 ] / 100, 12824 execResult[ 3 ] / 100, 12825 execResult[ 4 ] 12826 ]; 12827 } 12828 }], 12829 12830 // jQuery.Color( ) 12831 color = jQuery.Color = function( color, green, blue, alpha ) { 12832 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 12833 }, 12834 spaces = { 12835 rgba: { 12836 props: { 12837 red: { 12838 idx: 0, 12839 type: "byte" 12840 }, 12841 green: { 12842 idx: 1, 12843 type: "byte" 12844 }, 12845 blue: { 12846 idx: 2, 12847 type: "byte" 12848 } 12849 } 12850 }, 12851 12852 hsla: { 12853 props: { 12854 hue: { 12855 idx: 0, 12856 type: "degrees" 12857 }, 12858 saturation: { 12859 idx: 1, 12860 type: "percent" 12861 }, 12862 lightness: { 12863 idx: 2, 12864 type: "percent" 12865 } 12866 } 12867 } 12868 }, 12869 propTypes = { 12870 "byte": { 12871 floor: true, 12872 max: 255 12873 }, 12874 "percent": { 12875 max: 1 12876 }, 12877 "degrees": { 12878 mod: 360, 12879 floor: true 12880 } 12881 }, 12882 support = color.support = {}, 12883 12884 // element for support tests 12885 supportElem = jQuery( "<p>" )[ 0 ], 12886 12887 // colors = jQuery.Color.names 12888 colors, 12889 12890 // local aliases of functions called often 12891 each = jQuery.each; 12892 12893// determine rgba support immediately 12894supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 12895support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 12896 12897// define cache name and alpha properties 12898// for rgba and hsla spaces 12899each( spaces, function( spaceName, space ) { 12900 space.cache = "_" + spaceName; 12901 space.props.alpha = { 12902 idx: 3, 12903 type: "percent", 12904 def: 1 12905 }; 12906}); 12907 12908function clamp( value, prop, allowEmpty ) { 12909 var type = propTypes[ prop.type ] || {}; 12910 12911 if ( value == null ) { 12912 return (allowEmpty || !prop.def) ? null : prop.def; 12913 } 12914 12915 // ~~ is an short way of doing floor for positive numbers 12916 value = type.floor ? ~~value : parseFloat( value ); 12917 12918 // IE will pass in empty strings as value for alpha, 12919 // which will hit this case 12920 if ( isNaN( value ) ) { 12921 return prop.def; 12922 } 12923 12924 if ( type.mod ) { 12925 // we add mod before modding to make sure that negatives values 12926 // get converted properly: -10 -> 350 12927 return (value + type.mod) % type.mod; 12928 } 12929 12930 // for now all property types without mod have min and max 12931 return 0 > value ? 0 : type.max < value ? type.max : value; 12932} 12933 12934function stringParse( string ) { 12935 var inst = color(), 12936 rgba = inst._rgba = []; 12937 12938 string = string.toLowerCase(); 12939 12940 each( stringParsers, function( i, parser ) { 12941 var parsed, 12942 match = parser.re.exec( string ), 12943 values = match && parser.parse( match ), 12944 spaceName = parser.space || "rgba"; 12945 12946 if ( values ) { 12947 parsed = inst[ spaceName ]( values ); 12948 12949 // if this was an rgba parse the assignment might happen twice 12950 // oh well.... 12951 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12952 rgba = inst._rgba = parsed._rgba; 12953 12954 // exit each( stringParsers ) here because we matched 12955 return false; 12956 } 12957 }); 12958 12959 // Found a stringParser that handled it 12960 if ( rgba.length ) { 12961 12962 // if this came from a parsed string, force "transparent" when alpha is 0 12963 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12964 if ( rgba.join() === "0,0,0,0" ) { 12965 jQuery.extend( rgba, colors.transparent ); 12966 } 12967 return inst; 12968 } 12969 12970 // named colors 12971 return colors[ string ]; 12972} 12973 12974color.fn = jQuery.extend( color.prototype, { 12975 parse: function( red, green, blue, alpha ) { 12976 if ( red === undefined ) { 12977 this._rgba = [ null, null, null, null ]; 12978 return this; 12979 } 12980 if ( red.jquery || red.nodeType ) { 12981 red = jQuery( red ).css( green ); 12982 green = undefined; 12983 } 12984 12985 var inst = this, 12986 type = jQuery.type( red ), 12987 rgba = this._rgba = []; 12988 12989 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12990 if ( green !== undefined ) { 12991 red = [ red, green, blue, alpha ]; 12992 type = "array"; 12993 } 12994 12995 if ( type === "string" ) { 12996 return this.parse( stringParse( red ) || colors._default ); 12997 } 12998 12999 if ( type === "array" ) { 13000 each( spaces.rgba.props, function( key, prop ) { 13001 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 13002 }); 13003 return this; 13004 } 13005 13006 if ( type === "object" ) { 13007 if ( red instanceof color ) { 13008 each( spaces, function( spaceName, space ) { 13009 if ( red[ space.cache ] ) { 13010 inst[ space.cache ] = red[ space.cache ].slice(); 13011 } 13012 }); 13013 } else { 13014 each( spaces, function( spaceName, space ) { 13015 var cache = space.cache; 13016 each( space.props, function( key, prop ) { 13017 13018 // if the cache doesn't exist, and we know how to convert 13019 if ( !inst[ cache ] && space.to ) { 13020 13021 // if the value was null, we don't need to copy it 13022 // if the key was alpha, we don't need to copy it either 13023 if ( key === "alpha" || red[ key ] == null ) { 13024 return; 13025 } 13026 inst[ cache ] = space.to( inst._rgba ); 13027 } 13028 13029 // this is the only case where we allow nulls for ALL properties. 13030 // call clamp with alwaysAllowEmpty 13031 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 13032 }); 13033 13034 // everything defined but alpha? 13035 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 13036 // use the default of 1 13037 inst[ cache ][ 3 ] = 1; 13038 if ( space.from ) { 13039 inst._rgba = space.from( inst[ cache ] ); 13040 } 13041 } 13042 }); 13043 } 13044 return this; 13045 } 13046 }, 13047 is: function( compare ) { 13048 var is = color( compare ), 13049 same = true, 13050 inst = this; 13051 13052 each( spaces, function( _, space ) { 13053 var localCache, 13054 isCache = is[ space.cache ]; 13055 if (isCache) { 13056 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 13057 each( space.props, function( _, prop ) { 13058 if ( isCache[ prop.idx ] != null ) { 13059 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 13060 return same; 13061 } 13062 }); 13063 } 13064 return same; 13065 }); 13066 return same; 13067 }, 13068 _space: function() { 13069 var used = [], 13070 inst = this; 13071 each( spaces, function( spaceName, space ) { 13072 if ( inst[ space.cache ] ) { 13073 used.push( spaceName ); 13074 } 13075 }); 13076 return used.pop(); 13077 }, 13078 transition: function( other, distance ) { 13079 var end = color( other ), 13080 spaceName = end._space(), 13081 space = spaces[ spaceName ], 13082 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 13083 start = startColor[ space.cache ] || space.to( startColor._rgba ), 13084 result = start.slice(); 13085 13086 end = end[ space.cache ]; 13087 each( space.props, function( key, prop ) { 13088 var index = prop.idx, 13089 startValue = start[ index ], 13090 endValue = end[ index ], 13091 type = propTypes[ prop.type ] || {}; 13092 13093 // if null, don't override start value 13094 if ( endValue === null ) { 13095 return; 13096 } 13097 // if null - use end 13098 if ( startValue === null ) { 13099 result[ index ] = endValue; 13100 } else { 13101 if ( type.mod ) { 13102 if ( endValue - startValue > type.mod / 2 ) { 13103 startValue += type.mod; 13104 } else if ( startValue - endValue > type.mod / 2 ) { 13105 startValue -= type.mod; 13106 } 13107 } 13108 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 13109 } 13110 }); 13111 return this[ spaceName ]( result ); 13112 }, 13113 blend: function( opaque ) { 13114 // if we are already opaque - return ourself 13115 if ( this._rgba[ 3 ] === 1 ) { 13116 return this; 13117 } 13118 13119 var rgb = this._rgba.slice(), 13120 a = rgb.pop(), 13121 blend = color( opaque )._rgba; 13122 13123 return color( jQuery.map( rgb, function( v, i ) { 13124 return ( 1 - a ) * blend[ i ] + a * v; 13125 })); 13126 }, 13127 toRgbaString: function() { 13128 var prefix = "rgba(", 13129 rgba = jQuery.map( this._rgba, function( v, i ) { 13130 return v == null ? ( i > 2 ? 1 : 0 ) : v; 13131 }); 13132 13133 if ( rgba[ 3 ] === 1 ) { 13134 rgba.pop(); 13135 prefix = "rgb("; 13136 } 13137 13138 return prefix + rgba.join() + ")"; 13139 }, 13140 toHslaString: function() { 13141 var prefix = "hsla(", 13142 hsla = jQuery.map( this.hsla(), function( v, i ) { 13143 if ( v == null ) { 13144 v = i > 2 ? 1 : 0; 13145 } 13146 13147 // catch 1 and 2 13148 if ( i && i < 3 ) { 13149 v = Math.round( v * 100 ) + "%"; 13150 } 13151 return v; 13152 }); 13153 13154 if ( hsla[ 3 ] === 1 ) { 13155 hsla.pop(); 13156 prefix = "hsl("; 13157 } 13158 return prefix + hsla.join() + ")"; 13159 }, 13160 toHexString: function( includeAlpha ) { 13161 var rgba = this._rgba.slice(), 13162 alpha = rgba.pop(); 13163 13164 if ( includeAlpha ) { 13165 rgba.push( ~~( alpha * 255 ) ); 13166 } 13167 13168 return "#" + jQuery.map( rgba, function( v ) { 13169 13170 // default to 0 when nulls exist 13171 v = ( v || 0 ).toString( 16 ); 13172 return v.length === 1 ? "0" + v : v; 13173 }).join(""); 13174 }, 13175 toString: function() { 13176 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 13177 } 13178}); 13179color.fn.parse.prototype = color.fn; 13180 13181// hsla conversions adapted from: 13182// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 13183 13184function hue2rgb( p, q, h ) { 13185 h = ( h + 1 ) % 1; 13186 if ( h * 6 < 1 ) { 13187 return p + (q - p) * h * 6; 13188 } 13189 if ( h * 2 < 1) { 13190 return q; 13191 } 13192 if ( h * 3 < 2 ) { 13193 return p + (q - p) * ((2/3) - h) * 6; 13194 } 13195 return p; 13196} 13197 13198spaces.hsla.to = function ( rgba ) { 13199 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 13200 return [ null, null, null, rgba[ 3 ] ]; 13201 } 13202 var r = rgba[ 0 ] / 255, 13203 g = rgba[ 1 ] / 255, 13204 b = rgba[ 2 ] / 255, 13205 a = rgba[ 3 ], 13206 max = Math.max( r, g, b ), 13207 min = Math.min( r, g, b ), 13208 diff = max - min, 13209 add = max + min, 13210 l = add * 0.5, 13211 h, s; 13212 13213 if ( min === max ) { 13214 h = 0; 13215 } else if ( r === max ) { 13216 h = ( 60 * ( g - b ) / diff ) + 360; 13217 } else if ( g === max ) { 13218 h = ( 60 * ( b - r ) / diff ) + 120; 13219 } else { 13220 h = ( 60 * ( r - g ) / diff ) + 240; 13221 } 13222 13223 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 13224 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 13225 if ( diff === 0 ) { 13226 s = 0; 13227 } else if ( l <= 0.5 ) { 13228 s = diff / add; 13229 } else { 13230 s = diff / ( 2 - add ); 13231 } 13232 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 13233}; 13234 13235spaces.hsla.from = function ( hsla ) { 13236 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 13237 return [ null, null, null, hsla[ 3 ] ]; 13238 } 13239 var h = hsla[ 0 ] / 360, 13240 s = hsla[ 1 ], 13241 l = hsla[ 2 ], 13242 a = hsla[ 3 ], 13243 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 13244 p = 2 * l - q; 13245 13246 return [ 13247 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 13248 Math.round( hue2rgb( p, q, h ) * 255 ), 13249 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 13250 a 13251 ]; 13252}; 13253 13254 13255each( spaces, function( spaceName, space ) { 13256 var props = space.props, 13257 cache = space.cache, 13258 to = space.to, 13259 from = space.from; 13260 13261 // makes rgba() and hsla() 13262 color.fn[ spaceName ] = function( value ) { 13263 13264 // generate a cache for this space if it doesn't exist 13265 if ( to && !this[ cache ] ) { 13266 this[ cache ] = to( this._rgba ); 13267 } 13268 if ( value === undefined ) { 13269 return this[ cache ].slice(); 13270 } 13271 13272 var ret, 13273 type = jQuery.type( value ), 13274 arr = ( type === "array" || type === "object" ) ? value : arguments, 13275 local = this[ cache ].slice(); 13276 13277 each( props, function( key, prop ) { 13278 var val = arr[ type === "object" ? key : prop.idx ]; 13279 if ( val == null ) { 13280 val = local[ prop.idx ]; 13281 } 13282 local[ prop.idx ] = clamp( val, prop ); 13283 }); 13284 13285 if ( from ) { 13286 ret = color( from( local ) ); 13287 ret[ cache ] = local; 13288 return ret; 13289 } else { 13290 return color( local ); 13291 } 13292 }; 13293 13294 // makes red() green() blue() alpha() hue() saturation() lightness() 13295 each( props, function( key, prop ) { 13296 // alpha is included in more than one space 13297 if ( color.fn[ key ] ) { 13298 return; 13299 } 13300 color.fn[ key ] = function( value ) { 13301 var vtype = jQuery.type( value ), 13302 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 13303 local = this[ fn ](), 13304 cur = local[ prop.idx ], 13305 match; 13306 13307 if ( vtype === "undefined" ) { 13308 return cur; 13309 } 13310 13311 if ( vtype === "function" ) { 13312 value = value.call( this, cur ); 13313 vtype = jQuery.type( value ); 13314 } 13315 if ( value == null && prop.empty ) { 13316 return this; 13317 } 13318 if ( vtype === "string" ) { 13319 match = rplusequals.exec( value ); 13320 if ( match ) { 13321 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 13322 } 13323 } 13324 local[ prop.idx ] = value; 13325 return this[ fn ]( local ); 13326 }; 13327 }); 13328}); 13329 13330// add cssHook and .fx.step function for each named hook. 13331// accept a space separated string of properties 13332color.hook = function( hook ) { 13333 var hooks = hook.split( " " ); 13334 each( hooks, function( i, hook ) { 13335 jQuery.cssHooks[ hook ] = { 13336 set: function( elem, value ) { 13337 var parsed, curElem, 13338 backgroundColor = ""; 13339 13340 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 13341 value = color( parsed || value ); 13342 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 13343 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 13344 while ( 13345 (backgroundColor === "" || backgroundColor === "transparent") && 13346 curElem && curElem.style 13347 ) { 13348 try { 13349 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 13350 curElem = curElem.parentNode; 13351 } catch ( e ) { 13352 } 13353 } 13354 13355 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 13356 backgroundColor : 13357 "_default" ); 13358 } 13359 13360 value = value.toRgbaString(); 13361 } 13362 try { 13363 elem.style[ hook ] = value; 13364 } catch( e ) { 13365 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 13366 } 13367 } 13368 }; 13369 jQuery.fx.step[ hook ] = function( fx ) { 13370 if ( !fx.colorInit ) { 13371 fx.start = color( fx.elem, hook ); 13372 fx.end = color( fx.end ); 13373 fx.colorInit = true; 13374 } 13375 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 13376 }; 13377 }); 13378 13379}; 13380 13381color.hook( stepHooks ); 13382 13383jQuery.cssHooks.borderColor = { 13384 expand: function( value ) { 13385 var expanded = {}; 13386 13387 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 13388 expanded[ "border" + part + "Color" ] = value; 13389 }); 13390 return expanded; 13391 } 13392}; 13393 13394// Basic color names only. 13395// Usage of any of the other color names requires adding yourself or including 13396// jquery.color.svg-names.js. 13397colors = jQuery.Color.names = { 13398 // 4.1. Basic color keywords 13399 aqua: "#00ffff", 13400 black: "#000000", 13401 blue: "#0000ff", 13402 fuchsia: "#ff00ff", 13403 gray: "#808080", 13404 green: "#008000", 13405 lime: "#00ff00", 13406 maroon: "#800000", 13407 navy: "#000080", 13408 olive: "#808000", 13409 purple: "#800080", 13410 red: "#ff0000", 13411 silver: "#c0c0c0", 13412 teal: "#008080", 13413 white: "#ffffff", 13414 yellow: "#ffff00", 13415 13416 // 4.2.3. "transparent" color keyword 13417 transparent: [ null, null, null, 0 ], 13418 13419 _default: "#ffffff" 13420}; 13421 13422})( jQuery ); 13423 13424 13425/******************************************************************************/ 13426/****************************** CLASS ANIMATIONS ******************************/ 13427/******************************************************************************/ 13428(function() { 13429 13430var classAnimationActions = [ "add", "remove", "toggle" ], 13431 shorthandStyles = { 13432 border: 1, 13433 borderBottom: 1, 13434 borderColor: 1, 13435 borderLeft: 1, 13436 borderRight: 1, 13437 borderTop: 1, 13438 borderWidth: 1, 13439 margin: 1, 13440 padding: 1 13441 }; 13442 13443$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 13444 $.fx.step[ prop ] = function( fx ) { 13445 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 13446 jQuery.style( fx.elem, prop, fx.end ); 13447 fx.setAttr = true; 13448 } 13449 }; 13450}); 13451 13452function getElementStyles( elem ) { 13453 var key, len, 13454 style = elem.ownerDocument.defaultView ? 13455 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 13456 elem.currentStyle, 13457 styles = {}; 13458 13459 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 13460 len = style.length; 13461 while ( len-- ) { 13462 key = style[ len ]; 13463 if ( typeof style[ key ] === "string" ) { 13464 styles[ $.camelCase( key ) ] = style[ key ]; 13465 } 13466 } 13467 // support: Opera, IE <9 13468 } else { 13469 for ( key in style ) { 13470 if ( typeof style[ key ] === "string" ) { 13471 styles[ key ] = style[ key ]; 13472 } 13473 } 13474 } 13475 13476 return styles; 13477} 13478 13479 13480function styleDifference( oldStyle, newStyle ) { 13481 var diff = {}, 13482 name, value; 13483 13484 for ( name in newStyle ) { 13485 value = newStyle[ name ]; 13486 if ( oldStyle[ name ] !== value ) { 13487 if ( !shorthandStyles[ name ] ) { 13488 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 13489 diff[ name ] = value; 13490 } 13491 } 13492 } 13493 } 13494 13495 return diff; 13496} 13497 13498// support: jQuery <1.8 13499if ( !$.fn.addBack ) { 13500 $.fn.addBack = function( selector ) { 13501 return this.add( selector == null ? 13502 this.prevObject : this.prevObject.filter( selector ) 13503 ); 13504 }; 13505} 13506 13507$.effects.animateClass = function( value, duration, easing, callback ) { 13508 var o = $.speed( duration, easing, callback ); 13509 13510 return this.queue( function() { 13511 var animated = $( this ), 13512 baseClass = animated.attr( "class" ) || "", 13513 applyClassChange, 13514 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 13515 13516 // map the animated objects to store the original styles. 13517 allAnimations = allAnimations.map(function() { 13518 var el = $( this ); 13519 return { 13520 el: el, 13521 start: getElementStyles( this ) 13522 }; 13523 }); 13524 13525 // apply class change 13526 applyClassChange = function() { 13527 $.each( classAnimationActions, function(i, action) { 13528 if ( value[ action ] ) { 13529 animated[ action + "Class" ]( value[ action ] ); 13530 } 13531 }); 13532 }; 13533 applyClassChange(); 13534 13535 // map all animated objects again - calculate new styles and diff 13536 allAnimations = allAnimations.map(function() { 13537 this.end = getElementStyles( this.el[ 0 ] ); 13538 this.diff = styleDifference( this.start, this.end ); 13539 return this; 13540 }); 13541 13542 // apply original class 13543 animated.attr( "class", baseClass ); 13544 13545 // map all animated objects again - this time collecting a promise 13546 allAnimations = allAnimations.map(function() { 13547 var styleInfo = this, 13548 dfd = $.Deferred(), 13549 opts = $.extend({}, o, { 13550 queue: false, 13551 complete: function() { 13552 dfd.resolve( styleInfo ); 13553 } 13554 }); 13555 13556 this.el.animate( this.diff, opts ); 13557 return dfd.promise(); 13558 }); 13559 13560 // once all animations have completed: 13561 $.when.apply( $, allAnimations.get() ).done(function() { 13562 13563 // set the final class 13564 applyClassChange(); 13565 13566 // for each animated element, 13567 // clear all css properties that were animated 13568 $.each( arguments, function() { 13569 var el = this.el; 13570 $.each( this.diff, function(key) { 13571 el.css( key, "" ); 13572 }); 13573 }); 13574 13575 // this is guarnteed to be there if you use jQuery.speed() 13576 // it also handles dequeuing the next anim... 13577 o.complete.call( animated[ 0 ] ); 13578 }); 13579 }); 13580}; 13581 13582$.fn.extend({ 13583 addClass: (function( orig ) { 13584 return function( classNames, speed, easing, callback ) { 13585 return speed ? 13586 $.effects.animateClass.call( this, 13587 { add: classNames }, speed, easing, callback ) : 13588 orig.apply( this, arguments ); 13589 }; 13590 })( $.fn.addClass ), 13591 13592 removeClass: (function( orig ) { 13593 return function( classNames, speed, easing, callback ) { 13594 return arguments.length > 1 ? 13595 $.effects.animateClass.call( this, 13596 { remove: classNames }, speed, easing, callback ) : 13597 orig.apply( this, arguments ); 13598 }; 13599 })( $.fn.removeClass ), 13600 13601 toggleClass: (function( orig ) { 13602 return function( classNames, force, speed, easing, callback ) { 13603 if ( typeof force === "boolean" || force === undefined ) { 13604 if ( !speed ) { 13605 // without speed parameter 13606 return orig.apply( this, arguments ); 13607 } else { 13608 return $.effects.animateClass.call( this, 13609 (force ? { add: classNames } : { remove: classNames }), 13610 speed, easing, callback ); 13611 } 13612 } else { 13613 // without force parameter 13614 return $.effects.animateClass.call( this, 13615 { toggle: classNames }, force, speed, easing ); 13616 } 13617 }; 13618 })( $.fn.toggleClass ), 13619 13620 switchClass: function( remove, add, speed, easing, callback) { 13621 return $.effects.animateClass.call( this, { 13622 add: add, 13623 remove: remove 13624 }, speed, easing, callback ); 13625 } 13626}); 13627 13628})(); 13629 13630/******************************************************************************/ 13631/*********************************** EFFECTS **********************************/ 13632/******************************************************************************/ 13633 13634(function() { 13635 13636$.extend( $.effects, { 13637 version: "1.10.4", 13638 13639 // Saves a set of properties in a data storage 13640 save: function( element, set ) { 13641 for( var i=0; i < set.length; i++ ) { 13642 if ( set[ i ] !== null ) { 13643 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 13644 } 13645 } 13646 }, 13647 13648 // Restores a set of previously saved properties from a data storage 13649 restore: function( element, set ) { 13650 var val, i; 13651 for( i=0; i < set.length; i++ ) { 13652 if ( set[ i ] !== null ) { 13653 val = element.data( dataSpace + set[ i ] ); 13654 // support: jQuery 1.6.2 13655 // http://bugs.jquery.com/ticket/9917 13656 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 13657 // We can't differentiate between "" and 0 here, so we just assume 13658 // empty string since it's likely to be a more common value... 13659 if ( val === undefined ) { 13660 val = ""; 13661 } 13662 element.css( set[ i ], val ); 13663 } 13664 } 13665 }, 13666 13667 setMode: function( el, mode ) { 13668 if (mode === "toggle") { 13669 mode = el.is( ":hidden" ) ? "show" : "hide"; 13670 } 13671 return mode; 13672 }, 13673 13674 // Translates a [top,left] array into a baseline value 13675 // this should be a little more flexible in the future to handle a string & hash 13676 getBaseline: function( origin, original ) { 13677 var y, x; 13678 switch ( origin[ 0 ] ) { 13679 case "top": y = 0; break; 13680 case "middle": y = 0.5; break; 13681 case "bottom": y = 1; break; 13682 default: y = origin[ 0 ] / original.height; 13683 } 13684 switch ( origin[ 1 ] ) { 13685 case "left": x = 0; break; 13686 case "center": x = 0.5; break; 13687 case "right": x = 1; break; 13688 default: x = origin[ 1 ] / original.width; 13689 } 13690 return { 13691 x: x, 13692 y: y 13693 }; 13694 }, 13695 13696 // Wraps the element around a wrapper that copies position properties 13697 createWrapper: function( element ) { 13698 13699 // if the element is already wrapped, return it 13700 if ( element.parent().is( ".ui-effects-wrapper" )) { 13701 return element.parent(); 13702 } 13703 13704 // wrap the element 13705 var props = { 13706 width: element.outerWidth(true), 13707 height: element.outerHeight(true), 13708 "float": element.css( "float" ) 13709 }, 13710 wrapper = $( "<div></div>" ) 13711 .addClass( "ui-effects-wrapper" ) 13712 .css({ 13713 fontSize: "100%", 13714 background: "transparent", 13715 border: "none", 13716 margin: 0, 13717 padding: 0 13718 }), 13719 // Store the size in case width/height are defined in % - Fixes #5245 13720 size = { 13721 width: element.width(), 13722 height: element.height() 13723 }, 13724 active = document.activeElement; 13725 13726 // support: Firefox 13727 // Firefox incorrectly exposes anonymous content 13728 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 13729 try { 13730 active.id; 13731 } catch( e ) { 13732 active = document.body; 13733 } 13734 13735 element.wrap( wrapper ); 13736 13737 // Fixes #7595 - Elements lose focus when wrapped. 13738 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13739 $( active ).focus(); 13740 } 13741 13742 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 13743 13744 // transfer positioning properties to the wrapper 13745 if ( element.css( "position" ) === "static" ) { 13746 wrapper.css({ position: "relative" }); 13747 element.css({ position: "relative" }); 13748 } else { 13749 $.extend( props, { 13750 position: element.css( "position" ), 13751 zIndex: element.css( "z-index" ) 13752 }); 13753 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 13754 props[ pos ] = element.css( pos ); 13755 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 13756 props[ pos ] = "auto"; 13757 } 13758 }); 13759 element.css({ 13760 position: "relative", 13761 top: 0, 13762 left: 0, 13763 right: "auto", 13764 bottom: "auto" 13765 }); 13766 } 13767 element.css(size); 13768 13769 return wrapper.css( props ).show(); 13770 }, 13771 13772 removeWrapper: function( element ) { 13773 var active = document.activeElement; 13774 13775 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13776 element.parent().replaceWith( element ); 13777 13778 // Fixes #7595 - Elements lose focus when wrapped. 13779 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13780 $( active ).focus(); 13781 } 13782 } 13783 13784 13785 return element; 13786 }, 13787 13788 setTransition: function( element, list, factor, value ) { 13789 value = value || {}; 13790 $.each( list, function( i, x ) { 13791 var unit = element.cssUnit( x ); 13792 if ( unit[ 0 ] > 0 ) { 13793 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13794 } 13795 }); 13796 return value; 13797 } 13798}); 13799 13800// return an effect options object for the given parameters: 13801function _normalizeArguments( effect, options, speed, callback ) { 13802 13803 // allow passing all options as the first parameter 13804 if ( $.isPlainObject( effect ) ) { 13805 options = effect; 13806 effect = effect.effect; 13807 } 13808 13809 // convert to an object 13810 effect = { effect: effect }; 13811 13812 // catch (effect, null, ...) 13813 if ( options == null ) { 13814 options = {}; 13815 } 13816 13817 // catch (effect, callback) 13818 if ( $.isFunction( options ) ) { 13819 callback = options; 13820 speed = null; 13821 options = {}; 13822 } 13823 13824 // catch (effect, speed, ?) 13825 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13826 callback = speed; 13827 speed = options; 13828 options = {}; 13829 } 13830 13831 // catch (effect, options, callback) 13832 if ( $.isFunction( speed ) ) { 13833 callback = speed; 13834 speed = null; 13835 } 13836 13837 // add options to effect 13838 if ( options ) { 13839 $.extend( effect, options ); 13840 } 13841 13842 speed = speed || options.duration; 13843 effect.duration = $.fx.off ? 0 : 13844 typeof speed === "number" ? speed : 13845 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13846 $.fx.speeds._default; 13847 13848 effect.complete = callback || options.complete; 13849 13850 return effect; 13851} 13852 13853function standardAnimationOption( option ) { 13854 // Valid standard speeds (nothing, number, named speed) 13855 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 13856 return true; 13857 } 13858 13859 // Invalid strings - treat as "normal" speed 13860 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 13861 return true; 13862 } 13863 13864 // Complete callback 13865 if ( $.isFunction( option ) ) { 13866 return true; 13867 } 13868 13869 // Options hash (but not naming an effect) 13870 if ( typeof option === "object" && !option.effect ) { 13871 return true; 13872 } 13873 13874 // Didn't match any standard API 13875 return false; 13876} 13877 13878$.fn.extend({ 13879 effect: function( /* effect, options, speed, callback */ ) { 13880 var args = _normalizeArguments.apply( this, arguments ), 13881 mode = args.mode, 13882 queue = args.queue, 13883 effectMethod = $.effects.effect[ args.effect ]; 13884 13885 if ( $.fx.off || !effectMethod ) { 13886 // delegate to the original method (e.g., .show()) if possible 13887 if ( mode ) { 13888 return this[ mode ]( args.duration, args.complete ); 13889 } else { 13890 return this.each( function() { 13891 if ( args.complete ) { 13892 args.complete.call( this ); 13893 } 13894 }); 13895 } 13896 } 13897 13898 function run( next ) { 13899 var elem = $( this ), 13900 complete = args.complete, 13901 mode = args.mode; 13902 13903 function done() { 13904 if ( $.isFunction( complete ) ) { 13905 complete.call( elem[0] ); 13906 } 13907 if ( $.isFunction( next ) ) { 13908 next(); 13909 } 13910 } 13911 13912 // If the element already has the correct final state, delegate to 13913 // the core methods so the internal tracking of "olddisplay" works. 13914 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13915 elem[ mode ](); 13916 done(); 13917 } else { 13918 effectMethod.call( elem[0], args, done ); 13919 } 13920 } 13921 13922 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 13923 }, 13924 13925 show: (function( orig ) { 13926 return function( option ) { 13927 if ( standardAnimationOption( option ) ) { 13928 return orig.apply( this, arguments ); 13929 } else { 13930 var args = _normalizeArguments.apply( this, arguments ); 13931 args.mode = "show"; 13932 return this.effect.call( this, args ); 13933 } 13934 }; 13935 })( $.fn.show ), 13936 13937 hide: (function( orig ) { 13938 return function( option ) { 13939 if ( standardAnimationOption( option ) ) { 13940 return orig.apply( this, arguments ); 13941 } else { 13942 var args = _normalizeArguments.apply( this, arguments ); 13943 args.mode = "hide"; 13944 return this.effect.call( this, args ); 13945 } 13946 }; 13947 })( $.fn.hide ), 13948 13949 toggle: (function( orig ) { 13950 return function( option ) { 13951 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 13952 return orig.apply( this, arguments ); 13953 } else { 13954 var args = _normalizeArguments.apply( this, arguments ); 13955 args.mode = "toggle"; 13956 return this.effect.call( this, args ); 13957 } 13958 }; 13959 })( $.fn.toggle ), 13960 13961 // helper functions 13962 cssUnit: function(key) { 13963 var style = this.css( key ), 13964 val = []; 13965 13966 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13967 if ( style.indexOf( unit ) > 0 ) { 13968 val = [ parseFloat( style ), unit ]; 13969 } 13970 }); 13971 return val; 13972 } 13973}); 13974 13975})(); 13976 13977/******************************************************************************/ 13978/*********************************** EASING ***********************************/ 13979/******************************************************************************/ 13980 13981(function() { 13982 13983// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 13984 13985var baseEasings = {}; 13986 13987$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13988 baseEasings[ name ] = function( p ) { 13989 return Math.pow( p, i + 2 ); 13990 }; 13991}); 13992 13993$.extend( baseEasings, { 13994 Sine: function ( p ) { 13995 return 1 - Math.cos( p * Math.PI / 2 ); 13996 }, 13997 Circ: function ( p ) { 13998 return 1 - Math.sqrt( 1 - p * p ); 13999 }, 14000 Elastic: function( p ) { 14001 return p === 0 || p === 1 ? p : 14002 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 14003 }, 14004 Back: function( p ) { 14005 return p * p * ( 3 * p - 2 ); 14006 }, 14007 Bounce: function ( p ) { 14008 var pow2, 14009 bounce = 4; 14010 14011 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 14012 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 14013 } 14014}); 14015 14016$.each( baseEasings, function( name, easeIn ) { 14017 $.easing[ "easeIn" + name ] = easeIn; 14018 $.easing[ "easeOut" + name ] = function( p ) { 14019 return 1 - easeIn( 1 - p ); 14020 }; 14021 $.easing[ "easeInOut" + name ] = function( p ) { 14022 return p < 0.5 ? 14023 easeIn( p * 2 ) / 2 : 14024 1 - easeIn( p * -2 + 2 ) / 2; 14025 }; 14026}); 14027 14028})(); 14029 14030})(jQuery); 14031(function( $, undefined ) { 14032 14033$.effects.effect.drop = function( o, done ) { 14034 14035 var el = $( this ), 14036 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 14037 mode = $.effects.setMode( el, o.mode || "hide" ), 14038 show = mode === "show", 14039 direction = o.direction || "left", 14040 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14041 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 14042 animation = { 14043 opacity: show ? 1 : 0 14044 }, 14045 distance; 14046 14047 // Adjust 14048 $.effects.save( el, props ); 14049 el.show(); 14050 $.effects.createWrapper( el ); 14051 14052 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 14053 14054 if ( show ) { 14055 el 14056 .css( "opacity", 0 ) 14057 .css( ref, motion === "pos" ? -distance : distance ); 14058 } 14059 14060 // Animation 14061 animation[ ref ] = ( show ? 14062 ( motion === "pos" ? "+=" : "-=" ) : 14063 ( motion === "pos" ? "-=" : "+=" ) ) + 14064 distance; 14065 14066 // Animate 14067 el.animate( animation, { 14068 queue: false, 14069 duration: o.duration, 14070 easing: o.easing, 14071 complete: function() { 14072 if ( mode === "hide" ) { 14073 el.hide(); 14074 } 14075 $.effects.restore( el, props ); 14076 $.effects.removeWrapper( el ); 14077 done(); 14078 } 14079 }); 14080}; 14081 14082})(jQuery); 14083(function( $, undefined ) { 14084 14085$.effects.effect.fade = function( o, done ) { 14086 var el = $( this ), 14087 mode = $.effects.setMode( el, o.mode || "toggle" ); 14088 14089 el.animate({ 14090 opacity: mode 14091 }, { 14092 queue: false, 14093 duration: o.duration, 14094 easing: o.easing, 14095 complete: done 14096 }); 14097}; 14098 14099})( jQuery ); 14100(function( $, undefined ) { 14101 14102$.effects.effect.highlight = function( o, done ) { 14103 var elem = $( this ), 14104 props = [ "backgroundImage", "backgroundColor", "opacity" ], 14105 mode = $.effects.setMode( elem, o.mode || "show" ), 14106 animation = { 14107 backgroundColor: elem.css( "backgroundColor" ) 14108 }; 14109 14110 if (mode === "hide") { 14111 animation.opacity = 0; 14112 } 14113 14114 $.effects.save( elem, props ); 14115 14116 elem 14117 .show() 14118 .css({ 14119 backgroundImage: "none", 14120 backgroundColor: o.color || "#ffff99" 14121 }) 14122 .animate( animation, { 14123 queue: false, 14124 duration: o.duration, 14125 easing: o.easing, 14126 complete: function() { 14127 if ( mode === "hide" ) { 14128 elem.hide(); 14129 } 14130 $.effects.restore( elem, props ); 14131 done(); 14132 } 14133 }); 14134}; 14135 14136})(jQuery); 14137(function( $, undefined ) { 14138 14139$.effects.effect.slide = function( o, done ) { 14140 14141 // Create element 14142 var el = $( this ), 14143 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 14144 mode = $.effects.setMode( el, o.mode || "show" ), 14145 show = mode === "show", 14146 direction = o.direction || "left", 14147 ref = (direction === "up" || direction === "down") ? "top" : "left", 14148 positiveMotion = (direction === "up" || direction === "left"), 14149 distance, 14150 animation = {}; 14151 14152 // Adjust 14153 $.effects.save( el, props ); 14154 el.show(); 14155 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 14156 14157 $.effects.createWrapper( el ).css({ 14158 overflow: "hidden" 14159 }); 14160 14161 if ( show ) { 14162 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 14163 } 14164 14165 // Animation 14166 animation[ ref ] = ( show ? 14167 ( positiveMotion ? "+=" : "-=") : 14168 ( positiveMotion ? "-=" : "+=")) + 14169 distance; 14170 14171 // Animate 14172 el.animate( animation, { 14173 queue: false, 14174 duration: o.duration, 14175 easing: o.easing, 14176 complete: function() { 14177 if ( mode === "hide" ) { 14178 el.hide(); 14179 } 14180 $.effects.restore( el, props ); 14181 $.effects.removeWrapper( el ); 14182 done(); 14183 } 14184 }); 14185}; 14186 14187})(jQuery);
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.