vendor: 40,873 bytes, lines 1-1383
1/*! jQuery UI - v1.10.3 - 2013-05-03 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 4* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ 5(function( $, undefined ) { 6 7var uuid = 0, 8 runiqueId = /^ui-id-\d+$/; 9 10// $.ui might exist from components with no dependencies, e.g., $.ui.position 11$.ui = $.ui || {}; 12 13$.extend( $.ui, { 14 version: "1.10.3", 15 16 keyCode: { 17 BACKSPACE: 8, 18 COMMA: 188, 19 DELETE: 46, 20 DOWN: 40, 21 END: 35, 22 ENTER: 13, 23 ESCAPE: 27, 24 HOME: 36, 25 LEFT: 37, 26 NUMPAD_ADD: 107, 27 NUMPAD_DECIMAL: 110, 28 NUMPAD_DIVIDE: 111, 29 NUMPAD_ENTER: 108, 30 NUMPAD_MULTIPLY: 106, 31 NUMPAD_SUBTRACT: 109, 32 PAGE_DOWN: 34, 33 PAGE_UP: 33, 34 PERIOD: 190, 35 RIGHT: 39, 36 SPACE: 32, 37 TAB: 9, 38 UP: 38 39 } 40}); 41 42// plugins 43$.fn.extend({ 44 focus: (function( orig ) { 45 return function( delay, fn ) { 46 return typeof delay === "number" ? 47 this.each(function() { 48 var elem = this; 49 setTimeout(function() { 50 $( elem ).focus(); 51 if ( fn ) { 52 fn.call( elem ); 53 } 54 }, delay ); 55 }) : 56 orig.apply( this, arguments ); 57 }; 58 })( $.fn.focus ), 59 60 scrollParent: function() { 61 var scrollParent; 62 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 63 scrollParent = this.parents().filter(function() { 64 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 65 }).eq(0); 66 } else { 67 scrollParent = this.parents().filter(function() { 68 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 69 }).eq(0); 70 } 71 72 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 73 }, 74 75 zIndex: function( zIndex ) { 76 if ( zIndex !== undefined ) { 77 return this.css( "zIndex", zIndex ); 78 } 79 80 if ( this.length ) { 81 var elem = $( this[ 0 ] ), position, value; 82 while ( elem.length && elem[ 0 ] !== document ) { 83 // Ignore z-index if position is set to a value where z-index is ignored by the browser 84 // This makes behavior of this function consistent across browsers 85 // WebKit always returns auto if the element is positioned 86 position = elem.css( "position" ); 87 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 88 // IE returns 0 when zIndex is not specified 89 // other browsers return a string 90 // we ignore the case of nested elements with an explicit value of 0 91 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 92 value = parseInt( elem.css( "zIndex" ), 10 ); 93 if ( !isNaN( value ) && value !== 0 ) { 94 return value; 95 } 96 } 97 elem = elem.parent(); 98 } 99 } 100 101 return 0; 102 }, 103 104 uniqueId: function() { 105 return this.each(function() { 106 if ( !this.id ) { 107 this.id = "ui-id-" + (++uuid); 108 } 109 }); 110 }, 111 112 removeUniqueId: function() { 113 return this.each(function() { 114 if ( runiqueId.test( this.id ) ) { 115 $( this ).removeAttr( "id" ); 116 } 117 }); 118 } 119}); 120 121// selectors 122function focusable( element, isTabIndexNotNaN ) { 123 var map, mapName, img, 124 nodeName = element.nodeName.toLowerCase(); 125 if ( "area" === nodeName ) { 126 map = element.parentNode; 127 mapName = map.name; 128 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 129 return false; 130 } 131 img = $( "img[usemap=#" + mapName + "]" )[0]; 132 return !!img && visible( img ); 133 } 134 return ( /input|select|textarea|button|object/.test( nodeName ) ? 135 !element.disabled : 136 "a" === nodeName ? 137 element.href || isTabIndexNotNaN : 138 isTabIndexNotNaN) && 139 // the element and all of its ancestors must be visible 140 visible( element ); 141} 142 143function visible( element ) { 144 return $.expr.filters.visible( element ) && 145 !$( element ).parents().addBack().filter(function() { 146 return $.css( this, "visibility" ) === "hidden"; 147 }).length; 148} 149 150$.extend( $.expr[ ":" ], { 151 data: $.expr.createPseudo ? 152 $.expr.createPseudo(function( dataName ) { 153 return function( elem ) { 154 return !!$.data( elem, dataName ); 155 }; 156 }) : 157 // support: jQuery <1.8 158 function( elem, i, match ) { 159 return !!$.data( elem, match[ 3 ] ); 160 }, 161 162 focusable: function( element ) { 163 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 164 }, 165 166 tabbable: function( element ) { 167 var tabIndex = $.attr( element, "tabindex" ), 168 isTabIndexNaN = isNaN( tabIndex ); 169 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 170 } 171}); 172 173// support: jQuery <1.8 174if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 175 $.each( [ "Width", "Height" ], function( i, name ) { 176 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 177 type = name.toLowerCase(), 178 orig = { 179 innerWidth: $.fn.innerWidth, 180 innerHeight: $.fn.innerHeight, 181 outerWidth: $.fn.outerWidth, 182 outerHeight: $.fn.outerHeight 183 }; 184 185 function reduce( elem, size, border, margin ) { 186 $.each( side, function() { 187 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 188 if ( border ) { 189 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 190 } 191 if ( margin ) { 192 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 193 } 194 }); 195 return size; 196 } 197 198 $.fn[ "inner" + name ] = function( size ) { 199 if ( size === undefined ) { 200 return orig[ "inner" + name ].call( this ); 201 } 202 203 return this.each(function() { 204 $( this ).css( type, reduce( this, size ) + "px" ); 205 }); 206 }; 207 208 $.fn[ "outer" + name] = function( size, margin ) { 209 if ( typeof size !== "number" ) { 210 return orig[ "outer" + name ].call( this, size ); 211 } 212 213 return this.each(function() { 214 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 215 }); 216 }; 217 }); 218} 219 220// support: jQuery <1.8 221if ( !$.fn.addBack ) { 222 $.fn.addBack = function( selector ) { 223 return this.add( selector == null ? 224 this.prevObject : this.prevObject.filter( selector ) 225 ); 226 }; 227} 228 229// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 230if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 231 $.fn.removeData = (function( removeData ) { 232 return function( key ) { 233 if ( arguments.length ) { 234 return removeData.call( this, $.camelCase( key ) ); 235 } else { 236 return removeData.call( this ); 237 } 238 }; 239 })( $.fn.removeData ); 240} 241 242 243 244 245 246// deprecated 247$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 248 249$.support.selectstart = "onselectstart" in document.createElement( "div" ); 250$.fn.extend({ 251 disableSelection: function() { 252 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 253 ".ui-disableSelection", function( event ) { 254 event.preventDefault(); 255 }); 256 }, 257 258 enableSelection: function() { 259 return this.unbind( ".ui-disableSelection" ); 260 } 261}); 262 263$.extend( $.ui, { 264 // $.ui.plugin is deprecated. Use $.widget() extensions instead. 265 plugin: { 266 add: function( module, option, set ) { 267 var i, 268 proto = $.ui[ module ].prototype; 269 for ( i in set ) { 270 proto.plugins[ i ] = proto.plugins[ i ] || []; 271 proto.plugins[ i ].push( [ option, set[ i ] ] ); 272 } 273 }, 274 call: function( instance, name, args ) { 275 var i, 276 set = instance.plugins[ name ]; 277 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 278 return; 279 } 280 281 for ( i = 0; i < set.length; i++ ) { 282 if ( instance.options[ set[ i ][ 0 ] ] ) { 283 set[ i ][ 1 ].apply( instance.element, args ); 284 } 285 } 286 } 287 }, 288 289 // only used by resizable 290 hasScroll: function( el, a ) { 291 292 //If overflow is hidden, the element might have extra content, but the user wants to hide it 293 if ( $( el ).css( "overflow" ) === "hidden") { 294 return false; 295 } 296 297 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 298 has = false; 299 300 if ( el[ scroll ] > 0 ) { 301 return true; 302 } 303 304 // TODO: determine which cases actually cause this to happen 305 // if the element doesn't have the scroll set, see if it's possible to 306 // set the scroll 307 el[ scroll ] = 1; 308 has = ( el[ scroll ] > 0 ); 309 el[ scroll ] = 0; 310 return has; 311 } 312}); 313 314})( jQuery ); 315 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 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 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 ( value === undefined ) { 624 return curOption[ key ] === undefined ? null : curOption[ key ]; 625 } 626 curOption[ key ] = value; 627 } else { 628 if ( value === undefined ) { 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 ] ) { 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 828(function( $, undefined ) { 829 830var mouseHandled = false; 831$( document ).mouseup( function() { 832 mouseHandled = false; 833}); 834 835$.widget("ui.mouse", { 836 version: "1.10.3", 837 options: { 838 cancel: "input,textarea,button,select,option", 839 distance: 1, 840 delay: 0 841 }, 842 _mouseInit: function() { 843 var that = this; 844 845 this.element 846 .bind("mousedown."+this.widgetName, function(event) { 847 return that._mouseDown(event); 848 }) 849 .bind("click."+this.widgetName, function(event) { 850 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 851 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 852 event.stopImmediatePropagation(); 853 return false; 854 } 855 }); 856 857 this.started = false; 858 }, 859 860 // TODO: make sure destroying one instance of mouse doesn't mess with 861 // other instances of mouse 862 _mouseDestroy: function() { 863 this.element.unbind("."+this.widgetName); 864 if ( this._mouseMoveDelegate ) { 865 $(document) 866 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 867 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 868 } 869 }, 870 871 _mouseDown: function(event) { 872 // don't let more than one widget handle mouseStart 873 if( mouseHandled ) { return; } 874 875 // we may have missed mouseup (out of window) 876 (this._mouseStarted && this._mouseUp(event)); 877 878 this._mouseDownEvent = event; 879 880 var that = this, 881 btnIsLeft = (event.which === 1), 882 // event.target.nodeName works around a bug in IE 8 with 883 // disabled inputs (#7620) 884 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 885 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 886 return true; 887 } 888 889 this.mouseDelayMet = !this.options.delay; 890 if (!this.mouseDelayMet) { 891 this._mouseDelayTimer = setTimeout(function() { 892 that.mouseDelayMet = true; 893 }, this.options.delay); 894 } 895 896 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 897 this._mouseStarted = (this._mouseStart(event) !== false); 898 if (!this._mouseStarted) { 899 event.preventDefault(); 900 return true; 901 } 902 } 903 904 // Click event may never have fired (Gecko & Opera) 905 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 906 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 907 } 908 909 // these delegates are required to keep context 910 this._mouseMoveDelegate = function(event) { 911 return that._mouseMove(event); 912 }; 913 this._mouseUpDelegate = function(event) { 914 return that._mouseUp(event); 915 }; 916 $(document) 917 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 918 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 919 920 event.preventDefault(); 921 922 mouseHandled = true; 923 return true; 924 }, 925 926 _mouseMove: function(event) { 927 // IE mouseup check - mouseup happened when mouse was out of window 928 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 929 return this._mouseUp(event); 930 } 931 932 if (this._mouseStarted) { 933 this._mouseDrag(event); 934 return event.preventDefault(); 935 } 936 937 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 938 this._mouseStarted = 939 (this._mouseStart(this._mouseDownEvent, event) !== false); 940 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 941 } 942 943 return !this._mouseStarted; 944 }, 945 946 _mouseUp: function(event) { 947 $(document) 948 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 949 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 950 951 if (this._mouseStarted) { 952 this._mouseStarted = false; 953 954 if (event.target === this._mouseDownEvent.target) { 955 $.data(event.target, this.widgetName + ".preventClickEvent", true); 956 } 957 958 this._mouseStop(event); 959 } 960 961 return false; 962 }, 963 964 _mouseDistanceMet: function(event) { 965 return (Math.max( 966 Math.abs(this._mouseDownEvent.pageX - event.pageX), 967 Math.abs(this._mouseDownEvent.pageY - event.pageY) 968 ) >= this.options.distance 969 ); 970 }, 971 972 _mouseDelayMet: function(/* event */) { 973 return this.mouseDelayMet; 974 }, 975 976 // These are placeholder methods, to be overriden by extending plugin 977 _mouseStart: function(/* event */) {}, 978 _mouseDrag: function(/* event */) {}, 979 _mouseStop: function(/* event */) {}, 980 _mouseCapture: function(/* event */) { return true; } 981}); 982 983})(jQuery); 984 985(function( $, undefined ) { 986 987$.widget("ui.draggable", $.ui.mouse, { 988 version: "1.10.3", 989 widgetEventPrefix: "drag", 990 options: { 991 addClasses: true, 992 appendTo: "parent", 993 axis: false, 994 connectToSortable: false, 995 containment: false, 996 cursor: "auto", 997 cursorAt: false, 998 grid: false, 999 handle: false, 1000 helper: "original", 1001 iframeFix: false, 1002 opacity: false, 1003 refreshPositions: false, 1004 revert: false, 1005 revertDuration: 500, 1006 scope: "default", 1007 scroll: true, 1008 scrollSensitivity: 20, 1009 scrollSpeed: 20, 1010 snap: false, 1011 snapMode: "both", 1012 snapTolerance: 20, 1013 stack: false, 1014 zIndex: false, 1015 1016 // callbacks 1017 drag: null, 1018 start: null, 1019 stop: null 1020 }, 1021 _create: function() { 1022 1023 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1024 this.element[0].style.position = "relative"; 1025 } 1026 if (this.options.addClasses){ 1027 this.element.addClass("ui-draggable"); 1028 } 1029 if (this.options.disabled){ 1030 this.element.addClass("ui-draggable-disabled"); 1031 } 1032 1033 this._mouseInit(); 1034 1035 }, 1036 1037 _destroy: function() { 1038 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1039 this._mouseDestroy(); 1040 }, 1041 1042 _mouseCapture: function(event) { 1043 1044 var o = this.options; 1045 1046 // among others, prevent a drag on a resizable-handle 1047 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1048 return false; 1049 } 1050 1051 //Quit if we're not on a valid handle 1052 this.handle = this._getHandle(event); 1053 if (!this.handle) { 1054 return false; 1055 } 1056 1057 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1058 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1059 .css({ 1060 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1061 position: "absolute", opacity: "0.001", zIndex: 1000 1062 }) 1063 .css($(this).offset()) 1064 .appendTo("body"); 1065 }); 1066 1067 return true; 1068 1069 }, 1070 1071 _mouseStart: function(event) { 1072 1073 var o = this.options; 1074 1075 //Create and append the visible helper 1076 this.helper = this._createHelper(event); 1077 1078 this.helper.addClass("ui-draggable-dragging"); 1079 1080 //Cache the helper size 1081 this._cacheHelperProportions(); 1082 1083 //If ddmanager is used for droppables, set the global draggable 1084 if($.ui.ddmanager) { 1085 $.ui.ddmanager.current = this; 1086 } 1087 1088 /* 1089 * - Position generation - 1090 * This block generates everything position related - it's the core of draggables. 1091 */ 1092 1093 //Cache the margins of the original element 1094 this._cacheMargins(); 1095 1096 //Store the helper's css position 1097 this.cssPosition = this.helper.css( "position" ); 1098 this.scrollParent = this.helper.scrollParent(); 1099 this.offsetParent = this.helper.offsetParent(); 1100 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 1101 1102 //The element's absolute position on the page minus margins 1103 this.offset = this.positionAbs = this.element.offset(); 1104 this.offset = { 1105 top: this.offset.top - this.margins.top, 1106 left: this.offset.left - this.margins.left 1107 }; 1108 1109 //Reset scroll cache 1110 this.offset.scroll = false; 1111 1112 $.extend(this.offset, { 1113 click: { //Where the click happened, relative to the element 1114 left: event.pageX - this.offset.left, 1115 top: event.pageY - this.offset.top 1116 }, 1117 parent: this._getParentOffset(), 1118 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1119 }); 1120 1121 //Generate the original position 1122 this.originalPosition = this.position = this._generatePosition(event); 1123 this.originalPageX = event.pageX; 1124 this.originalPageY = event.pageY; 1125 1126 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1127 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1128 1129 //Set a containment if given in the options 1130 this._setContainment(); 1131 1132 //Trigger event + callbacks 1133 if(this._trigger("start", event) === false) { 1134 this._clear(); 1135 return false; 1136 } 1137 1138 //Recache the helper size 1139 this._cacheHelperProportions(); 1140 1141 //Prepare the droppable offsets 1142 if ($.ui.ddmanager && !o.dropBehaviour) { 1143 $.ui.ddmanager.prepareOffsets(this, event); 1144 } 1145 1146 1147 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1148 1149 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1150 if ( $.ui.ddmanager ) { 1151 $.ui.ddmanager.dragStart(this, event); 1152 } 1153 1154 return true; 1155 }, 1156 1157 _mouseDrag: function(event, noPropagation) { 1158 // reset any necessary cached properties (see #5009) 1159 if ( this.offsetParentCssPosition === "fixed" ) { 1160 this.offset.parent = this._getParentOffset(); 1161 } 1162 1163 //Compute the helpers position 1164 this.position = this._generatePosition(event); 1165 this.positionAbs = this._convertPositionTo("absolute"); 1166 1167 //Call plugins and callbacks and use the resulting position if something is returned 1168 if (!noPropagation) { 1169 var ui = this._uiHash(); 1170 if(this._trigger("drag", event, ui) === false) { 1171 this._mouseUp({}); 1172 return false; 1173 } 1174 this.position = ui.position; 1175 } 1176 1177 if(!this.options.axis || this.options.axis !== "y") { 1178 this.helper[0].style.left = this.position.left+"px"; 1179 } 1180 if(!this.options.axis || this.options.axis !== "x") { 1181 this.helper[0].style.top = this.position.top+"px"; 1182 } 1183 if($.ui.ddmanager) { 1184 $.ui.ddmanager.drag(this, event); 1185 } 1186 1187 return false; 1188 }, 1189 1190 _mouseStop: function(event) { 1191 1192 //If we are using droppables, inform the manager about the drop 1193 var that = this, 1194 dropped = false; 1195 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1196 dropped = $.ui.ddmanager.drop(this, event); 1197 } 1198 1199 //if a drop comes from outside (a sortable) 1200 if(this.dropped) { 1201 dropped = this.dropped; 1202 this.dropped = false; 1203 } 1204 1205 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1206 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { 1207 return false; 1208 } 1209 1210 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))) { 1211 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1212 if(that._trigger("stop", event) !== false) { 1213 that._clear(); 1214 } 1215 }); 1216 } else { 1217 if(this._trigger("stop", event) !== false) { 1218 this._clear(); 1219 } 1220 } 1221 1222 return false; 1223 }, 1224 1225 _mouseUp: function(event) { 1226 //Remove frame helpers 1227 $("div.ui-draggable-iframeFix").each(function() { 1228 this.parentNode.removeChild(this); 1229 }); 1230 1231 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1232 if( $.ui.ddmanager ) { 1233 $.ui.ddmanager.dragStop(this, event); 1234 } 1235 1236 return $.ui.mouse.prototype._mouseUp.call(this, event); 1237 }, 1238 1239 cancel: function() { 1240 1241 if(this.helper.is(".ui-draggable-dragging")) { 1242 this._mouseUp({}); 1243 } else { 1244 this._clear(); 1245 } 1246 1247 return this; 1248 1249 }, 1250 1251 _getHandle: function(event) { 1252 return this.options.handle ? 1253 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1254 true; 1255 }, 1256 1257 _createHelper: function(event) { 1258 1259 var o = this.options, 1260 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1261 1262 if(!helper.parents("body").length) { 1263 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1264 } 1265 1266 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1267 helper.css("position", "absolute"); 1268 } 1269 1270 return helper; 1271 1272 }, 1273 1274 _adjustOffsetFromHelper: function(obj) { 1275 if (typeof obj === "string") { 1276 obj = obj.split(" "); 1277 } 1278 if ($.isArray(obj)) { 1279 obj = {left: +obj[0], top: +obj[1] || 0}; 1280 } 1281 if ("left" in obj) { 1282 this.offset.click.left = obj.left + this.margins.left; 1283 } 1284 if ("right" in obj) { 1285 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1286 } 1287 if ("top" in obj) { 1288 this.offset.click.top = obj.top + this.margins.top; 1289 } 1290 if ("bottom" in obj) { 1291 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1292 } 1293 }, 1294 1295 _getParentOffset: function() { 1296 1297 //Get the offsetParent and cache its position 1298 var po = this.offsetParent.offset(); 1299 1300 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1301 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1302 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1303 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1304 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1305 po.left += this.scrollParent.scrollLeft(); 1306 po.top += this.scrollParent.scrollTop(); 1307 } 1308 1309 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1310 //Ugly IE fix 1311 if((this.offsetParent[0] === document.body) || 1312 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1313 po = { top: 0, left: 0 }; 1314 } 1315 1316 return { 1317 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 1318 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1319 }; 1320 1321 }, 1322 1323 _getRelativeOffset: function() { 1324 1325 if(this.cssPosition === "relative") { 1326 var p = this.element.position(); 1327 return { 1328 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1329 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1330 }; 1331 } else { 1332 return { top: 0, left: 0 }; 1333 } 1334 1335 }, 1336 1337 _cacheMargins: function() { 1338 this.margins = { 1339 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1340 top: (parseInt(this.element.css("marginTop"),10) || 0), 1341 right: (parseInt(this.element.css("marginRight"),10) || 0), 1342 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1343 }; 1344 }, 1345 1346 _cacheHelperProportions: function() { 1347 this.helperProportions = { 1348 width: this.helper.outerWidth(), 1349 height: this.helper.outerHeight() 1350 }; 1351 }, 1352 1353 _setContainment: function() { 1354 1355 var over, c, ce, 1356 o = this.options; 1357 1358 if ( !o.containment ) { 1359 this.containment = null; 1360 return; 1361 } 1362 1363 if ( o.containment === "window" ) { 1364 this.containment = [ 1365 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1366 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1367 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 1368 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1369 ]; 1370 return; 1371 } 1372 1373 if ( o.containment === "document") { 1374 this.containment = [ 1375 0, 1376 0, 1377 $( document ).width() - this.helperProportions.width - this.margins.left, 1378 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 1379 ]; 1380 return; 1381 } 1382 1383 if ( o.containment.constructor === Array ) {
vendor: 7,038 bytes, lines 1384-1560
1384 this.containment = o.containment; 1385 return; 1386 } 1387 1388 if ( o.containment === "parent" ) { 1389 o.containment = this.helper[ 0 ].parentNode; 1390 } 1391 1392 c = $( o.containment ); 1393 ce = c[ 0 ]; 1394 1395 if( !ce ) { 1396 return; 1397 } 1398 1399 over = c.css( "overflow" ) !== "hidden"; 1400 1401 this.containment = [ 1402 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 1403 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , 1404 ( 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, 1405 ( 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 1406 ]; 1407 this.relative_container = c; 1408 }, 1409 1410 _convertPositionTo: function(d, pos) { 1411 1412 if(!pos) { 1413 pos = this.position; 1414 } 1415 1416 var mod = d === "absolute" ? 1 : -1, 1417 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; 1418 1419 //Cache the scroll 1420 if (!this.offset.scroll) { 1421 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1422 } 1423 1424 return { 1425 top: ( 1426 pos.top + // The absolute mouse position 1427 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1428 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1429 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) 1430 ), 1431 left: ( 1432 pos.left + // The absolute mouse position 1433 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1434 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1435 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) 1436 ) 1437 }; 1438 1439 }, 1440 1441 _generatePosition: function(event) { 1442 1443 var containment, co, top, left, 1444 o = this.options, 1445 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, 1446 pageX = event.pageX, 1447 pageY = event.pageY; 1448 1449 //Cache the scroll 1450 if (!this.offset.scroll) { 1451 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 1452 } 1453 1454 /* 1455 * - Position constraining - 1456 * Constrain the position to a mix of grid, containment. 1457 */ 1458 1459 // If we are not dragging yet, we won't check for options 1460 if ( this.originalPosition ) { 1461 if ( this.containment ) { 1462 if ( this.relative_container ){ 1463 co = this.relative_container.offset(); 1464 containment = [ 1465 this.containment[ 0 ] + co.left, 1466 this.containment[ 1 ] + co.top, 1467 this.containment[ 2 ] + co.left, 1468 this.containment[ 3 ] + co.top 1469 ]; 1470 } 1471 else { 1472 containment = this.containment; 1473 } 1474 1475 if(event.pageX - this.offset.click.left < containment[0]) { 1476 pageX = containment[0] + this.offset.click.left; 1477 } 1478 if(event.pageY - this.offset.click.top < containment[1]) { 1479 pageY = containment[1] + this.offset.click.top; 1480 } 1481 if(event.pageX - this.offset.click.left > containment[2]) { 1482 pageX = containment[2] + this.offset.click.left; 1483 } 1484 if(event.pageY - this.offset.click.top > containment[3]) { 1485 pageY = containment[3] + this.offset.click.top; 1486 } 1487 } 1488 1489 if(o.grid) { 1490 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1491 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1492 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; 1493 1494 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1495 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; 1496 } 1497 1498 } 1499 1500 return { 1501 top: ( 1502 pageY - // The absolute mouse position 1503 this.offset.click.top - // Click offset (relative to the element) 1504 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1505 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1506 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) 1507 ), 1508 left: ( 1509 pageX - // The absolute mouse position 1510 this.offset.click.left - // Click offset (relative to the element) 1511 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1512 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1513 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) 1514 ) 1515 }; 1516 1517 }, 1518 1519 _clear: function() { 1520 this.helper.removeClass("ui-draggable-dragging"); 1521 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1522 this.helper.remove(); 1523 } 1524 this.helper = null; 1525 this.cancelHelperRemoval = false; 1526 }, 1527 1528 // From now on bulk stuff - mainly helpers 1529 1530 _trigger: function(type, event, ui) { 1531 ui = ui || this._uiHash(); 1532 $.ui.plugin.call(this, type, [event, ui]); 1533 //The absolute position has to be recalculated after plugins 1534 if(type === "drag") { 1535 this.positionAbs = this._convertPositionTo("absolute"); 1536 } 1537 return $.Widget.prototype._trigger.call(this, type, event, ui); 1538 }, 1539 1540 plugins: {}, 1541 1542 _uiHash: function() { 1543 return { 1544 helper: this.helper, 1545 position: this.position, 1546 originalPosition: this.originalPosition, 1547 offset: this.positionAbs 1548 }; 1549 } 1550 1551}); 1552 1553$.ui.plugin.add("draggable", "connectToSortable", { 1554 start: function(event, ui) { 1555 1556 var inst = $(this).data("ui-draggable"), o = inst.options, 1557 uiSortable = $.extend({}, ui, { item: inst.element }); 1558 inst.sortables = []; 1559 $(o.connectToSortable).each(function() { 1560 var sortable = $.data(this, "ui-sortable");
vendor: 13,398 bytes, lines 1561-1939
1561 if (sortable && !sortable.options.disabled) { 1562 inst.sortables.push({ 1563 instance: sortable, 1564 shouldRevert: sortable.options.revert 1565 }); 1566 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). 1567 sortable._trigger("activate", event, uiSortable); 1568 } 1569 }); 1570 1571 }, 1572 stop: function(event, ui) { 1573 1574 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1575 var inst = $(this).data("ui-draggable"), 1576 uiSortable = $.extend({}, ui, { item: inst.element }); 1577 1578 $.each(inst.sortables, function() { 1579 if(this.instance.isOver) { 1580 1581 this.instance.isOver = 0; 1582 1583 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1584 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1585 1586 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 1587 if(this.shouldRevert) { 1588 this.instance.options.revert = this.shouldRevert; 1589 } 1590 1591 //Trigger the stop of the sortable 1592 this.instance._mouseStop(event); 1593 1594 this.instance.options.helper = this.instance.options._helper; 1595 1596 //If the helper has been the original item, restore properties in the sortable 1597 if(inst.options.helper === "original") { 1598 this.instance.currentItem.css({ top: "auto", left: "auto" }); 1599 } 1600 1601 } else { 1602 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1603 this.instance._trigger("deactivate", event, uiSortable); 1604 } 1605 1606 }); 1607 1608 }, 1609 drag: function(event, ui) { 1610 1611 var inst = $(this).data("ui-draggable"), that = this; 1612 1613 $.each(inst.sortables, function() { 1614 1615 var innermostIntersecting = false, 1616 thisSortable = this; 1617 1618 //Copy over some variables to allow calling the sortable's native _intersectsWith 1619 this.instance.positionAbs = inst.positionAbs; 1620 this.instance.helperProportions = inst.helperProportions; 1621 this.instance.offset.click = inst.offset.click; 1622 1623 if(this.instance._intersectsWith(this.instance.containerCache)) { 1624 innermostIntersecting = true; 1625 $.each(inst.sortables, function () { 1626 this.instance.positionAbs = inst.positionAbs; 1627 this.instance.helperProportions = inst.helperProportions; 1628 this.instance.offset.click = inst.offset.click; 1629 if (this !== thisSortable && 1630 this.instance._intersectsWith(this.instance.containerCache) && 1631 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 1632 ) { 1633 innermostIntersecting = false; 1634 } 1635 return innermostIntersecting; 1636 }); 1637 } 1638 1639 1640 if(innermostIntersecting) { 1641 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1642 if(!this.instance.isOver) { 1643 1644 this.instance.isOver = 1; 1645 //Now we fake the start of dragging for the sortable instance, 1646 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1647 //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) 1648 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 1649 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1650 this.instance.options.helper = function() { return ui.helper[0]; }; 1651 1652 event.target = this.instance.currentItem[0]; 1653 this.instance._mouseCapture(event, true); 1654 this.instance._mouseStart(event, true, true); 1655 1656 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1657 this.instance.offset.click.top = inst.offset.click.top; 1658 this.instance.offset.click.left = inst.offset.click.left; 1659 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1660 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1661 1662 inst._trigger("toSortable", event); 1663 inst.dropped = this.instance.element; //draggable revert needs that 1664 //hack so receive/update callbacks work (mostly) 1665 inst.currentItem = inst.element; 1666 this.instance.fromOutside = inst; 1667 1668 } 1669 1670 //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 1671 if(this.instance.currentItem) { 1672 this.instance._mouseDrag(event); 1673 } 1674 1675 } else { 1676 1677 //If it doesn't intersect with the sortable, and it intersected before, 1678 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1679 if(this.instance.isOver) { 1680 1681 this.instance.isOver = 0; 1682 this.instance.cancelHelperRemoval = true; 1683 1684 //Prevent reverting on this forced stop 1685 this.instance.options.revert = false; 1686 1687 // The out event needs to be triggered independently 1688 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 1689 1690 this.instance._mouseStop(event, true); 1691 this.instance.options.helper = this.instance.options._helper; 1692 1693 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1694 this.instance.currentItem.remove(); 1695 if(this.instance.placeholder) { 1696 this.instance.placeholder.remove(); 1697 } 1698 1699 inst._trigger("fromSortable", event); 1700 inst.dropped = false; //draggable revert needs that 1701 } 1702 1703 } 1704 1705 }); 1706 1707 } 1708}); 1709 1710$.ui.plugin.add("draggable", "cursor", { 1711 start: function() { 1712 var t = $("body"), o = $(this).data("ui-draggable").options; 1713 if (t.css("cursor")) { 1714 o._cursor = t.css("cursor"); 1715 } 1716 t.css("cursor", o.cursor); 1717 }, 1718 stop: function() { 1719 var o = $(this).data("ui-draggable").options; 1720 if (o._cursor) { 1721 $("body").css("cursor", o._cursor); 1722 } 1723 } 1724}); 1725 1726$.ui.plugin.add("draggable", "opacity", { 1727 start: function(event, ui) { 1728 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1729 if(t.css("opacity")) { 1730 o._opacity = t.css("opacity"); 1731 } 1732 t.css("opacity", o.opacity); 1733 }, 1734 stop: function(event, ui) { 1735 var o = $(this).data("ui-draggable").options; 1736 if(o._opacity) { 1737 $(ui.helper).css("opacity", o._opacity); 1738 } 1739 } 1740}); 1741 1742$.ui.plugin.add("draggable", "scroll", { 1743 start: function() { 1744 var i = $(this).data("ui-draggable"); 1745 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1746 i.overflowOffset = i.scrollParent.offset(); 1747 } 1748 }, 1749 drag: function( event ) { 1750 1751 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 1752 1753 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1754 1755 if(!o.axis || o.axis !== "x") { 1756 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 1757 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1758 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 1759 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1760 } 1761 } 1762 1763 if(!o.axis || o.axis !== "y") { 1764 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 1765 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1766 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 1767 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1768 } 1769 } 1770 1771 } else { 1772 1773 if(!o.axis || o.axis !== "x") { 1774 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 1775 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1776 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 1777 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1778 } 1779 } 1780 1781 if(!o.axis || o.axis !== "y") { 1782 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 1783 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1784 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 1785 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1786 } 1787 } 1788 1789 } 1790 1791 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 1792 $.ui.ddmanager.prepareOffsets(i, event); 1793 } 1794 1795 } 1796}); 1797 1798$.ui.plugin.add("draggable", "snap", { 1799 start: function() { 1800 1801 var i = $(this).data("ui-draggable"), 1802 o = i.options; 1803 1804 i.snapElements = []; 1805 1806 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 1807 var $t = $(this), 1808 $o = $t.offset(); 1809 if(this !== i.element[0]) { 1810 i.snapElements.push({ 1811 item: this, 1812 width: $t.outerWidth(), height: $t.outerHeight(), 1813 top: $o.top, left: $o.left 1814 }); 1815 } 1816 }); 1817 1818 }, 1819 drag: function(event, ui) { 1820 1821 var ts, bs, ls, rs, l, r, t, b, i, first, 1822 inst = $(this).data("ui-draggable"), 1823 o = inst.options, 1824 d = o.snapTolerance, 1825 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1826 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1827 1828 for (i = inst.snapElements.length - 1; i >= 0; i--){ 1829 1830 l = inst.snapElements[i].left; 1831 r = l + inst.snapElements[i].width; 1832 t = inst.snapElements[i].top; 1833 b = t + inst.snapElements[i].height; 1834 1835 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 1836 if(inst.snapElements[i].snapping) { 1837 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1838 } 1839 inst.snapElements[i].snapping = false; 1840 continue; 1841 } 1842 1843 if(o.snapMode !== "inner") { 1844 ts = Math.abs(t - y2) <= d; 1845 bs = Math.abs(b - y1) <= d; 1846 ls = Math.abs(l - x2) <= d; 1847 rs = Math.abs(r - x1) <= d; 1848 if(ts) { 1849 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1850 } 1851 if(bs) { 1852 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1853 } 1854 if(ls) { 1855 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1856 } 1857 if(rs) { 1858 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1859 } 1860 } 1861 1862 first = (ts || bs || ls || rs); 1863 1864 if(o.snapMode !== "outer") { 1865 ts = Math.abs(t - y1) <= d; 1866 bs = Math.abs(b - y2) <= d; 1867 ls = Math.abs(l - x1) <= d; 1868 rs = Math.abs(r - x2) <= d; 1869 if(ts) { 1870 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1871 } 1872 if(bs) { 1873 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1874 } 1875 if(ls) { 1876 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1877 } 1878 if(rs) { 1879 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1880 } 1881 } 1882 1883 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 1884 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1885 } 1886 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1887 1888 } 1889 1890 } 1891}); 1892 1893$.ui.plugin.add("draggable", "stack", { 1894 start: function() { 1895 var min, 1896 o = this.data("ui-draggable").options, 1897 group = $.makeArray($(o.stack)).sort(function(a,b) { 1898 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1899 }); 1900 1901 if (!group.length) { return; } 1902 1903 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 1904 $(group).each(function(i) { 1905 $(this).css("zIndex", min + i); 1906 }); 1907 this.css("zIndex", (min + group.length)); 1908 } 1909}); 1910 1911$.ui.plugin.add("draggable", "zIndex", { 1912 start: function(event, ui) { 1913 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1914 if(t.css("zIndex")) { 1915 o._zIndex = t.css("zIndex"); 1916 } 1917 t.css("zIndex", o.zIndex); 1918 }, 1919 stop: function(event, ui) { 1920 var o = $(this).data("ui-draggable").options; 1921 if(o._zIndex) { 1922 $(ui.helper).css("zIndex", o._zIndex); 1923 } 1924 } 1925}); 1926 1927})(jQuery); 1928 1929(function( $, undefined ) { 1930 1931function isOverAxis( x, reference, size ) { 1932 return ( x > reference ) && ( x < ( reference + size ) ); 1933} 1934 1935$.widget("ui.droppable", { 1936 version: "1.10.3", 1937 widgetEventPrefix: "drop", 1938 options: { 1939 accept: "*",
1940 activeClass: false, 1941 addClasses: true, 1942 greedy: false, 1943 hoverClass: false, 1944 scope: "default", 1945 tolerance: "intersect", 1946 1947 // callbacks 1948 activate: null, 1949 deactivate: null, 1950 drop: null, 1951 out: null, 1952 over: null 1953 }, 1954 _create: function() { 1955 1956 var o = this.options, 1957 accept = o.accept; 1958 1959 this.isover = false; 1960 this.isout = true; 1961 1962 this.accept = $.isFunction(accept) ? accept : function(d) { 1963 return d.is(accept); 1964 }; 1965 1966 //Store the droppable's proportions 1967 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1968 1969 // Add the reference and positions to the manager 1970 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1971 $.ui.ddmanager.droppables[o.scope].push(this); 1972 1973 (o.addClasses && this.element.addClass("ui-droppable")); 1974 1975 }, 1976 1977 _destroy: function() { 1978 var i = 0, 1979 drop = $.ui.ddmanager.droppables[this.options.scope]; 1980 1981 for ( ; i < drop.length; i++ ) { 1982 if ( drop[i] === this ) { 1983 drop.splice(i, 1); 1984 } 1985 } 1986 1987 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1988 }, 1989 1990 _setOption: function(key, value) { 1991 1992 if(key === "accept") { 1993 this.accept = $.isFunction(value) ? value : function(d) { 1994 return d.is(value); 1995 }; 1996 } 1997 $.Widget.prototype._setOption.apply(this, arguments); 1998 }, 1999 2000 _activate: function(event) { 2001 var draggable = $.ui.ddmanager.current; 2002 if(this.options.activeClass) { 2003 this.element.addClass(this.options.activeClass); 2004 } 2005 if(draggable){ 2006 this._trigger("activate", event, this.ui(draggable)); 2007 } 2008 }, 2009 2010 _deactivate: function(event) { 2011 var draggable = $.ui.ddmanager.current; 2012 if(this.options.activeClass) { 2013 this.element.removeClass(this.options.activeClass); 2014 } 2015 if(draggable){ 2016 this._trigger("deactivate", event, this.ui(draggable)); 2017 } 2018 }, 2019 2020 _over: function(event) { 2021 2022 var draggable = $.ui.ddmanager.current; 2023 2024 // Bail if draggable and droppable are same element 2025 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2026 return; 2027 } 2028 2029 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2030 if(this.options.hoverClass) { 2031 this.element.addClass(this.options.hoverClass); 2032 } 2033 this._trigger("over", event, this.ui(draggable)); 2034 } 2035 2036 }, 2037 2038 _out: function(event) { 2039 2040 var draggable = $.ui.ddmanager.current; 2041 2042 // Bail if draggable and droppable are same element 2043 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2044 return; 2045 } 2046 2047 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2048 if(this.options.hoverClass) { 2049 this.element.removeClass(this.options.hoverClass); 2050 } 2051 this._trigger("out", event, this.ui(draggable)); 2052 } 2053 2054 }, 2055 2056 _drop: function(event,custom) { 2057 2058 var draggable = custom || $.ui.ddmanager.current, 2059 childrenIntersection = false; 2060 2061 // Bail if draggable and droppable are same element 2062 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2063 return false; 2064 } 2065 2066 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2067 var inst = $.data(this, "ui-droppable"); 2068 if( 2069 inst.options.greedy && 2070 !inst.options.disabled && 2071 inst.options.scope === draggable.options.scope && 2072 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2073 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2074 ) { childrenIntersection = true; return false; } 2075 }); 2076 if(childrenIntersection) { 2077 return false; 2078 } 2079 2080 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2081 if(this.options.activeClass) { 2082 this.element.removeClass(this.options.activeClass); 2083 } 2084 if(this.options.hoverClass) { 2085 this.element.removeClass(this.options.hoverClass); 2086 } 2087 this._trigger("drop", event, this.ui(draggable)); 2088 return this.element; 2089 } 2090 2091 return false; 2092 2093 }, 2094 2095 ui: function(c) { 2096 return { 2097 draggable: (c.currentItem || c.element), 2098 helper: c.helper, 2099 position: c.position, 2100 offset: c.positionAbs 2101 }; 2102 } 2103 2104}); 2105 2106$.ui.intersect = function(draggable, droppable, toleranceMode) { 2107 2108 if (!droppable.offset) { 2109 return false; 2110 } 2111 2112 var draggableLeft, draggableTop, 2113 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2114 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2115 l = droppable.offset.left, r = l + droppable.proportions.width, 2116 t = droppable.offset.top, b = t + droppable.proportions.height; 2117 2118 switch (toleranceMode) { 2119 case "fit":
vendor: 21,983 bytes, lines 2120-2851
2120 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2121 case "intersect": 2122 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2123 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2124 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2125 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2126 case "pointer": 2127 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2128 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2129 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2130 case "touch": 2131 return ( 2132 (y1 >= t && y1 <= b) || // Top edge touching 2133 (y2 >= t && y2 <= b) || // Bottom edge touching 2134 (y1 < t && y2 > b) // Surrounded vertically 2135 ) && ( 2136 (x1 >= l && x1 <= r) || // Left edge touching 2137 (x2 >= l && x2 <= r) || // Right edge touching 2138 (x1 < l && x2 > r) // Surrounded horizontally 2139 ); 2140 default: 2141 return false; 2142 } 2143 2144}; 2145 2146/* 2147 This manager tracks offsets of draggables and droppables 2148*/ 2149$.ui.ddmanager = { 2150 current: null, 2151 droppables: { "default": [] }, 2152 prepareOffsets: function(t, event) { 2153 2154 var i, j, 2155 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2156 type = event ? event.type : null, // workaround for #2317 2157 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2158 2159 droppablesLoop: for (i = 0; i < m.length; i++) { 2160 2161 //No disabled and non-accepted 2162 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2163 continue; 2164 } 2165 2166 // Filter out elements in the current dragged item 2167 for (j=0; j < list.length; j++) { 2168 if(list[j] === m[i].element[0]) { 2169 m[i].proportions.height = 0; 2170 continue droppablesLoop; 2171 } 2172 } 2173 2174 m[i].visible = m[i].element.css("display") !== "none"; 2175 if(!m[i].visible) { 2176 continue; 2177 } 2178 2179 //Activate the droppable if used directly from draggables 2180 if(type === "mousedown") { 2181 m[i]._activate.call(m[i], event); 2182 } 2183 2184 m[i].offset = m[i].element.offset(); 2185 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2186 2187 } 2188 2189 }, 2190 drop: function(draggable, event) { 2191 2192 var dropped = false; 2193 // Create a copy of the droppables in case the list changes during the drop (#9116) 2194 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2195 2196 if(!this.options) { 2197 return; 2198 } 2199 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2200 dropped = this._drop.call(this, event) || dropped; 2201 } 2202 2203 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2204 this.isout = true; 2205 this.isover = false; 2206 this._deactivate.call(this, event); 2207 } 2208 2209 }); 2210 return dropped; 2211 2212 }, 2213 dragStart: function( draggable, event ) { 2214 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2215 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2216 if( !draggable.options.refreshPositions ) { 2217 $.ui.ddmanager.prepareOffsets( draggable, event ); 2218 } 2219 }); 2220 }, 2221 drag: function(draggable, event) { 2222 2223 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2224 if(draggable.options.refreshPositions) { 2225 $.ui.ddmanager.prepareOffsets(draggable, event); 2226 } 2227 2228 //Run through all droppables and check their positions based on specific tolerance options 2229 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2230 2231 if(this.options.disabled || this.greedyChild || !this.visible) { 2232 return; 2233 } 2234 2235 var parentInstance, scope, parent, 2236 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2237 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2238 if(!c) { 2239 return; 2240 } 2241 2242 if (this.options.greedy) { 2243 // find droppable parents with same scope 2244 scope = this.options.scope; 2245 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2246 return $.data(this, "ui-droppable").options.scope === scope; 2247 }); 2248 2249 if (parent.length) { 2250 parentInstance = $.data(parent[0], "ui-droppable"); 2251 parentInstance.greedyChild = (c === "isover"); 2252 } 2253 } 2254 2255 // we just moved into a greedy child 2256 if (parentInstance && c === "isover") { 2257 parentInstance.isover = false; 2258 parentInstance.isout = true; 2259 parentInstance._out.call(parentInstance, event); 2260 } 2261 2262 this[c] = true; 2263 this[c === "isout" ? "isover" : "isout"] = false; 2264 this[c === "isover" ? "_over" : "_out"].call(this, event); 2265 2266 // we just moved out of a greedy child 2267 if (parentInstance && c === "isout") { 2268 parentInstance.isout = false; 2269 parentInstance.isover = true; 2270 parentInstance._over.call(parentInstance, event); 2271 } 2272 }); 2273 2274 }, 2275 dragStop: function( draggable, event ) { 2276 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2277 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2278 if( !draggable.options.refreshPositions ) { 2279 $.ui.ddmanager.prepareOffsets( draggable, event ); 2280 } 2281 } 2282}; 2283 2284})(jQuery); 2285 2286(function( $, undefined ) { 2287 2288function num(v) { 2289 return parseInt(v, 10) || 0; 2290} 2291 2292function isNumber(value) { 2293 return !isNaN(parseInt(value, 10)); 2294} 2295 2296$.widget("ui.resizable", $.ui.mouse, { 2297 version: "1.10.3", 2298 widgetEventPrefix: "resize", 2299 options: { 2300 alsoResize: false, 2301 animate: false, 2302 animateDuration: "slow", 2303 animateEasing: "swing", 2304 aspectRatio: false, 2305 autoHide: false, 2306 containment: false, 2307 ghost: false, 2308 grid: false, 2309 handles: "e,s,se", 2310 helper: false, 2311 maxHeight: null, 2312 maxWidth: null, 2313 minHeight: 10, 2314 minWidth: 10, 2315 // See #7960 2316 zIndex: 90, 2317 2318 // callbacks 2319 resize: null, 2320 start: null, 2321 stop: null 2322 }, 2323 _create: function() { 2324 2325 var n, i, handle, axis, hname, 2326 that = this, 2327 o = this.options; 2328 this.element.addClass("ui-resizable"); 2329 2330 $.extend(this, { 2331 _aspectRatio: !!(o.aspectRatio), 2332 aspectRatio: o.aspectRatio, 2333 originalElement: this.element, 2334 _proportionallyResizeElements: [], 2335 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2336 }); 2337 2338 //Wrap the element if it cannot hold child nodes 2339 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2340 2341 //Create a wrapper element and set the wrapper to the new current internal element 2342 this.element.wrap( 2343 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2344 position: this.element.css("position"), 2345 width: this.element.outerWidth(), 2346 height: this.element.outerHeight(), 2347 top: this.element.css("top"), 2348 left: this.element.css("left") 2349 }) 2350 ); 2351 2352 //Overwrite the original this.element 2353 this.element = this.element.parent().data( 2354 "ui-resizable", this.element.data("ui-resizable") 2355 ); 2356 2357 this.elementIsWrapper = true; 2358 2359 //Move margins to the wrapper 2360 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2361 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2362 2363 //Prevent Safari textarea resize 2364 this.originalResizeStyle = this.originalElement.css("resize"); 2365 this.originalElement.css("resize", "none"); 2366 2367 //Push the actual element to our proportionallyResize internal array 2368 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2369 2370 // avoid IE jump (hard set the margin) 2371 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2372 2373 // fix handlers offset 2374 this._proportionallyResize(); 2375 2376 } 2377 2378 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" }); 2379 if(this.handles.constructor === String) { 2380 2381 if ( this.handles === "all") { 2382 this.handles = "n,e,s,w,se,sw,ne,nw"; 2383 } 2384 2385 n = this.handles.split(","); 2386 this.handles = {}; 2387 2388 for(i = 0; i < n.length; i++) { 2389 2390 handle = $.trim(n[i]); 2391 hname = "ui-resizable-"+handle; 2392 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2393 2394 // Apply zIndex to all handles - see #7960 2395 axis.css({ zIndex: o.zIndex }); 2396 2397 //TODO : What's going on here? 2398 if ("se" === handle) { 2399 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2400 } 2401 2402 //Insert into internal handles object and append to element 2403 this.handles[handle] = ".ui-resizable-"+handle; 2404 this.element.append(axis); 2405 } 2406 2407 } 2408 2409 this._renderAxis = function(target) { 2410 2411 var i, axis, padPos, padWrapper; 2412 2413 target = target || this.element; 2414 2415 for(i in this.handles) { 2416 2417 if(this.handles[i].constructor === String) { 2418 this.handles[i] = $(this.handles[i], this.element).show(); 2419 } 2420 2421 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2422 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2423 2424 axis = $(this.handles[i], this.element); 2425 2426 //Checking the correct pad and border 2427 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2428 2429 //The padding type i have to apply... 2430 padPos = [ "padding", 2431 /ne|nw|n/.test(i) ? "Top" : 2432 /se|sw|s/.test(i) ? "Bottom" : 2433 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2434 2435 target.css(padPos, padWrapper); 2436 2437 this._proportionallyResize(); 2438 2439 } 2440 2441 //TODO: What's that good for? There's not anything to be executed left 2442 if(!$(this.handles[i]).length) { 2443 continue; 2444 } 2445 } 2446 }; 2447 2448 //TODO: make renderAxis a prototype function 2449 this._renderAxis(this.element); 2450 2451 this._handles = $(".ui-resizable-handle", this.element) 2452 .disableSelection(); 2453 2454 //Matching axis name 2455 this._handles.mouseover(function() { 2456 if (!that.resizing) { 2457 if (this.className) { 2458 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2459 } 2460 //Axis, default = se 2461 that.axis = axis && axis[1] ? axis[1] : "se"; 2462 } 2463 }); 2464 2465 //If we want to auto hide the elements 2466 if (o.autoHide) { 2467 this._handles.hide(); 2468 $(this.element) 2469 .addClass("ui-resizable-autohide") 2470 .mouseenter(function() { 2471 if (o.disabled) { 2472 return; 2473 } 2474 $(this).removeClass("ui-resizable-autohide"); 2475 that._handles.show(); 2476 }) 2477 .mouseleave(function(){ 2478 if (o.disabled) { 2479 return; 2480 } 2481 if (!that.resizing) { 2482 $(this).addClass("ui-resizable-autohide"); 2483 that._handles.hide(); 2484 } 2485 }); 2486 } 2487 2488 //Initialize the mouse interaction 2489 this._mouseInit(); 2490 2491 }, 2492 2493 _destroy: function() { 2494 2495 this._mouseDestroy(); 2496 2497 var wrapper, 2498 _destroy = function(exp) { 2499 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2500 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2501 }; 2502 2503 //TODO: Unwrap at same DOM position 2504 if (this.elementIsWrapper) { 2505 _destroy(this.element); 2506 wrapper = this.element; 2507 this.originalElement.css({ 2508 position: wrapper.css("position"), 2509 width: wrapper.outerWidth(), 2510 height: wrapper.outerHeight(), 2511 top: wrapper.css("top"), 2512 left: wrapper.css("left") 2513 }).insertAfter( wrapper ); 2514 wrapper.remove(); 2515 } 2516 2517 this.originalElement.css("resize", this.originalResizeStyle); 2518 _destroy(this.originalElement); 2519 2520 return this; 2521 }, 2522 2523 _mouseCapture: function(event) { 2524 var i, handle, 2525 capture = false; 2526 2527 for (i in this.handles) { 2528 handle = $(this.handles[i])[0]; 2529 if (handle === event.target || $.contains(handle, event.target)) { 2530 capture = true; 2531 } 2532 } 2533 2534 return !this.options.disabled && capture; 2535 }, 2536 2537 _mouseStart: function(event) { 2538 2539 var curleft, curtop, cursor, 2540 o = this.options, 2541 iniPos = this.element.position(), 2542 el = this.element; 2543 2544 this.resizing = true; 2545 2546 // bugfix for http://dev.jquery.com/ticket/1749 2547 if ( (/absolute/).test( el.css("position") ) ) { 2548 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 2549 } else if (el.is(".ui-draggable")) { 2550 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 2551 } 2552 2553 this._renderProxy(); 2554 2555 curleft = num(this.helper.css("left")); 2556 curtop = num(this.helper.css("top")); 2557 2558 if (o.containment) { 2559 curleft += $(o.containment).scrollLeft() || 0; 2560 curtop += $(o.containment).scrollTop() || 0; 2561 } 2562 2563 //Store needed variables 2564 this.offset = this.helper.offset(); 2565 this.position = { left: curleft, top: curtop }; 2566 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2567 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2568 this.originalPosition = { left: curleft, top: curtop }; 2569 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2570 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2571 2572 //Aspect Ratio 2573 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2574 2575 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 2576 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 2577 2578 el.addClass("ui-resizable-resizing"); 2579 this._propagate("start", event); 2580 return true; 2581 }, 2582 2583 _mouseDrag: function(event) { 2584 2585 //Increase performance, avoid regex 2586 var data, 2587 el = this.helper, props = {}, 2588 smp = this.originalMousePosition, 2589 a = this.axis, 2590 prevTop = this.position.top, 2591 prevLeft = this.position.left, 2592 prevWidth = this.size.width, 2593 prevHeight = this.size.height, 2594 dx = (event.pageX-smp.left)||0, 2595 dy = (event.pageY-smp.top)||0, 2596 trigger = this._change[a]; 2597 2598 if (!trigger) { 2599 return false; 2600 } 2601 2602 // Calculate the attrs that will be change 2603 data = trigger.apply(this, [event, dx, dy]); 2604 2605 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2606 this._updateVirtualBoundaries(event.shiftKey); 2607 if (this._aspectRatio || event.shiftKey) { 2608 data = this._updateRatio(data, event); 2609 } 2610 2611 data = this._respectSize(data, event); 2612 2613 this._updateCache(data); 2614 2615 // plugins callbacks need to be called first 2616 this._propagate("resize", event); 2617 2618 if (this.position.top !== prevTop) { 2619 props.top = this.position.top + "px"; 2620 } 2621 if (this.position.left !== prevLeft) { 2622 props.left = this.position.left + "px"; 2623 } 2624 if (this.size.width !== prevWidth) { 2625 props.width = this.size.width + "px"; 2626 } 2627 if (this.size.height !== prevHeight) { 2628 props.height = this.size.height + "px"; 2629 } 2630 el.css(props); 2631 2632 if (!this._helper && this._proportionallyResizeElements.length) { 2633 this._proportionallyResize(); 2634 } 2635 2636 // Call the user callback if the element was resized 2637 if ( ! $.isEmptyObject(props) ) { 2638 this._trigger("resize", event, this.ui()); 2639 } 2640 2641 return false; 2642 }, 2643 2644 _mouseStop: function(event) { 2645 2646 this.resizing = false; 2647 var pr, ista, soffseth, soffsetw, s, left, top, 2648 o = this.options, that = this; 2649 2650 if(this._helper) { 2651 2652 pr = this._proportionallyResizeElements; 2653 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 2654 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 2655 soffsetw = ista ? 0 : that.sizeDiff.width; 2656 2657 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 2658 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 2659 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2660 2661 if (!o.animate) { 2662 this.element.css($.extend(s, { top: top, left: left })); 2663 } 2664 2665 that.helper.height(that.size.height); 2666 that.helper.width(that.size.width); 2667 2668 if (this._helper && !o.animate) { 2669 this._proportionallyResize(); 2670 } 2671 } 2672 2673 $("body").css("cursor", "auto"); 2674 2675 this.element.removeClass("ui-resizable-resizing"); 2676 2677 this._propagate("stop", event); 2678 2679 if (this._helper) { 2680 this.helper.remove(); 2681 } 2682 2683 return false; 2684 2685 }, 2686 2687 _updateVirtualBoundaries: function(forceAspectRatio) { 2688 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2689 o = this.options; 2690 2691 b = { 2692 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2693 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2694 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2695 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2696 }; 2697 2698 if(this._aspectRatio || forceAspectRatio) { 2699 // We want to create an enclosing box whose aspect ration is the requested one 2700 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2701 pMinWidth = b.minHeight * this.aspectRatio; 2702 pMinHeight = b.minWidth / this.aspectRatio; 2703 pMaxWidth = b.maxHeight * this.aspectRatio; 2704 pMaxHeight = b.maxWidth / this.aspectRatio; 2705 2706 if(pMinWidth > b.minWidth) { 2707 b.minWidth = pMinWidth; 2708 } 2709 if(pMinHeight > b.minHeight) { 2710 b.minHeight = pMinHeight; 2711 } 2712 if(pMaxWidth < b.maxWidth) { 2713 b.maxWidth = pMaxWidth; 2714 } 2715 if(pMaxHeight < b.maxHeight) { 2716 b.maxHeight = pMaxHeight; 2717 } 2718 } 2719 this._vBoundaries = b; 2720 }, 2721 2722 _updateCache: function(data) { 2723 this.offset = this.helper.offset(); 2724 if (isNumber(data.left)) { 2725 this.position.left = data.left; 2726 } 2727 if (isNumber(data.top)) { 2728 this.position.top = data.top; 2729 } 2730 if (isNumber(data.height)) { 2731 this.size.height = data.height; 2732 } 2733 if (isNumber(data.width)) { 2734 this.size.width = data.width; 2735 } 2736 }, 2737 2738 _updateRatio: function( data ) { 2739 2740 var cpos = this.position, 2741 csize = this.size, 2742 a = this.axis; 2743 2744 if (isNumber(data.height)) { 2745 data.width = (data.height * this.aspectRatio); 2746 } else if (isNumber(data.width)) { 2747 data.height = (data.width / this.aspectRatio); 2748 } 2749 2750 if (a === "sw") { 2751 data.left = cpos.left + (csize.width - data.width); 2752 data.top = null; 2753 } 2754 if (a === "nw") { 2755 data.top = cpos.top + (csize.height - data.height); 2756 data.left = cpos.left + (csize.width - data.width); 2757 } 2758 2759 return data; 2760 }, 2761 2762 _respectSize: function( data ) { 2763 2764 var o = this._vBoundaries, 2765 a = this.axis, 2766 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2767 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 2768 dw = this.originalPosition.left + this.originalSize.width, 2769 dh = this.position.top + this.size.height, 2770 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2771 if (isminw) { 2772 data.width = o.minWidth; 2773 } 2774 if (isminh) { 2775 data.height = o.minHeight; 2776 } 2777 if (ismaxw) { 2778 data.width = o.maxWidth; 2779 } 2780 if (ismaxh) { 2781 data.height = o.maxHeight; 2782 } 2783 2784 if (isminw && cw) { 2785 data.left = dw - o.minWidth; 2786 } 2787 if (ismaxw && cw) { 2788 data.left = dw - o.maxWidth; 2789 } 2790 if (isminh && ch) { 2791 data.top = dh - o.minHeight; 2792 } 2793 if (ismaxh && ch) { 2794 data.top = dh - o.maxHeight; 2795 } 2796 2797 // fixing jump error on top/left - bug #2330 2798 if (!data.width && !data.height && !data.left && data.top) { 2799 data.top = null; 2800 } else if (!data.width && !data.height && !data.top && data.left) { 2801 data.left = null; 2802 } 2803 2804 return data; 2805 }, 2806 2807 _proportionallyResize: function() { 2808 2809 if (!this._proportionallyResizeElements.length) { 2810 return; 2811 } 2812 2813 var i, j, borders, paddings, prel, 2814 element = this.helper || this.element; 2815 2816 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 2817 2818 prel = this._proportionallyResizeElements[i]; 2819 2820 if (!this.borderDif) { 2821 this.borderDif = []; 2822 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 2823 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 2824 2825 for ( j = 0; j < borders.length; j++ ) { 2826 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 2827 } 2828 } 2829 2830 prel.css({ 2831 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2832 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2833 }); 2834 2835 } 2836 2837 }, 2838 2839 _renderProxy: function() { 2840 2841 var el = this.element, o = this.options; 2842 this.elementOffset = el.offset(); 2843 2844 if(this._helper) { 2845 2846 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 2847 2848 this.helper.addClass(this._helper).css({ 2849 width: this.element.outerWidth() - 1, 2850 height: this.element.outerHeight() - 1, 2851 position: "absolute",
vendor: 1,348 bytes, lines 2852-2895
2852 left: this.elementOffset.left +"px", 2853 top: this.elementOffset.top +"px", 2854 zIndex: ++o.zIndex //TODO: Don't modify option 2855 }); 2856 2857 this.helper 2858 .appendTo("body") 2859 .disableSelection(); 2860 2861 } else { 2862 this.helper = this.element; 2863 } 2864 2865 }, 2866 2867 _change: { 2868 e: function(event, dx) { 2869 return { width: this.originalSize.width + dx }; 2870 }, 2871 w: function(event, dx) { 2872 var cs = this.originalSize, sp = this.originalPosition; 2873 return { left: sp.left + dx, width: cs.width - dx }; 2874 }, 2875 n: function(event, dx, dy) { 2876 var cs = this.originalSize, sp = this.originalPosition; 2877 return { top: sp.top + dy, height: cs.height - dy }; 2878 }, 2879 s: function(event, dx, dy) { 2880 return { height: this.originalSize.height + dy }; 2881 }, 2882 se: function(event, dx, dy) { 2883 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2884 }, 2885 sw: function(event, dx, dy) { 2886 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2887 }, 2888 ne: function(event, dx, dy) { 2889 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2890 }, 2891 nw: function(event, dx, dy) { 2892 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2893 } 2894 }, 2895
vendor: 46,301 bytes, lines 2896-4410
2896 _propagate: function(n, event) { 2897 $.ui.plugin.call(this, n, [event, this.ui()]); 2898 (n !== "resize" && this._trigger(n, event, this.ui())); 2899 }, 2900 2901 plugins: {}, 2902 2903 ui: function() { 2904 return { 2905 originalElement: this.originalElement, 2906 element: this.element, 2907 helper: this.helper, 2908 position: this.position, 2909 size: this.size, 2910 originalSize: this.originalSize, 2911 originalPosition: this.originalPosition 2912 }; 2913 } 2914 2915}); 2916 2917/* 2918 * Resizable Extensions 2919 */ 2920 2921$.ui.plugin.add("resizable", "animate", { 2922 2923 stop: function( event ) { 2924 var that = $(this).data("ui-resizable"), 2925 o = that.options, 2926 pr = that._proportionallyResizeElements, 2927 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2928 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2929 soffsetw = ista ? 0 : that.sizeDiff.width, 2930 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2931 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 2932 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2933 2934 that.element.animate( 2935 $.extend(style, top && left ? { top: top, left: left } : {}), { 2936 duration: o.animateDuration, 2937 easing: o.animateEasing, 2938 step: function() { 2939 2940 var data = { 2941 width: parseInt(that.element.css("width"), 10), 2942 height: parseInt(that.element.css("height"), 10), 2943 top: parseInt(that.element.css("top"), 10), 2944 left: parseInt(that.element.css("left"), 10) 2945 }; 2946 2947 if (pr && pr.length) { 2948 $(pr[0]).css({ width: data.width, height: data.height }); 2949 } 2950 2951 // propagating resize, and updating values for each animation step 2952 that._updateCache(data); 2953 that._propagate("resize", event); 2954 2955 } 2956 } 2957 ); 2958 } 2959 2960}); 2961 2962$.ui.plugin.add("resizable", "containment", { 2963 2964 start: function() { 2965 var element, p, co, ch, cw, width, height, 2966 that = $(this).data("ui-resizable"), 2967 o = that.options, 2968 el = that.element, 2969 oc = o.containment, 2970 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2971 2972 if (!ce) { 2973 return; 2974 } 2975 2976 that.containerElement = $(ce); 2977 2978 if (/document/.test(oc) || oc === document) { 2979 that.containerOffset = { left: 0, top: 0 }; 2980 that.containerPosition = { left: 0, top: 0 }; 2981 2982 that.parentData = { 2983 element: $(document), left: 0, top: 0, 2984 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2985 }; 2986 } 2987 2988 // i'm a node, so compute top, left, right, bottom 2989 else { 2990 element = $(ce); 2991 p = []; 2992 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2993 2994 that.containerOffset = element.offset(); 2995 that.containerPosition = element.position(); 2996 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2997 2998 co = that.containerOffset; 2999 ch = that.containerSize.height; 3000 cw = that.containerSize.width; 3001 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 3002 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3003 3004 that.parentData = { 3005 element: ce, left: co.left, top: co.top, width: width, height: height 3006 }; 3007 } 3008 }, 3009 3010 resize: function( event ) { 3011 var woset, hoset, isParent, isOffsetRelative, 3012 that = $(this).data("ui-resizable"), 3013 o = that.options, 3014 co = that.containerOffset, cp = that.position, 3015 pRatio = that._aspectRatio || event.shiftKey, 3016 cop = { top:0, left:0 }, ce = that.containerElement; 3017 3018 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3019 cop = co; 3020 } 3021 3022 if (cp.left < (that._helper ? co.left : 0)) { 3023 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3024 if (pRatio) { 3025 that.size.height = that.size.width / that.aspectRatio; 3026 } 3027 that.position.left = o.helper ? co.left : 0; 3028 } 3029 3030 if (cp.top < (that._helper ? co.top : 0)) { 3031 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3032 if (pRatio) { 3033 that.size.width = that.size.height * that.aspectRatio; 3034 } 3035 that.position.top = that._helper ? co.top : 0; 3036 } 3037 3038 that.offset.left = that.parentData.left+that.position.left; 3039 that.offset.top = that.parentData.top+that.position.top; 3040 3041 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3042 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3043 3044 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3045 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3046 3047 if(isParent && isOffsetRelative) { 3048 woset -= that.parentData.left; 3049 } 3050 3051 if (woset + that.size.width >= that.parentData.width) { 3052 that.size.width = that.parentData.width - woset; 3053 if (pRatio) { 3054 that.size.height = that.size.width / that.aspectRatio; 3055 } 3056 } 3057 3058 if (hoset + that.size.height >= that.parentData.height) { 3059 that.size.height = that.parentData.height - hoset; 3060 if (pRatio) { 3061 that.size.width = that.size.height * that.aspectRatio; 3062 } 3063 } 3064 }, 3065 3066 stop: function(){ 3067 var that = $(this).data("ui-resizable"), 3068 o = that.options, 3069 co = that.containerOffset, 3070 cop = that.containerPosition, 3071 ce = that.containerElement, 3072 helper = $(that.helper), 3073 ho = helper.offset(), 3074 w = helper.outerWidth() - that.sizeDiff.width, 3075 h = helper.outerHeight() - that.sizeDiff.height; 3076 3077 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3078 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3079 } 3080 3081 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3082 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3083 } 3084 3085 } 3086}); 3087 3088$.ui.plugin.add("resizable", "alsoResize", { 3089 3090 start: function () { 3091 var that = $(this).data("ui-resizable"), 3092 o = that.options, 3093 _store = function (exp) { 3094 $(exp).each(function() { 3095 var el = $(this); 3096 el.data("ui-resizable-alsoresize", { 3097 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3098 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3099 }); 3100 }); 3101 }; 3102 3103 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3104 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3105 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3106 }else{ 3107 _store(o.alsoResize); 3108 } 3109 }, 3110 3111 resize: function (event, ui) { 3112 var that = $(this).data("ui-resizable"), 3113 o = that.options, 3114 os = that.originalSize, 3115 op = that.originalPosition, 3116 delta = { 3117 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3118 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3119 }, 3120 3121 _alsoResize = function (exp, c) { 3122 $(exp).each(function() { 3123 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3124 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3125 3126 $.each(css, function (i, prop) { 3127 var sum = (start[prop]||0) + (delta[prop]||0); 3128 if (sum && sum >= 0) { 3129 style[prop] = sum || null; 3130 } 3131 }); 3132 3133 el.css(style); 3134 }); 3135 }; 3136 3137 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3138 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3139 }else{ 3140 _alsoResize(o.alsoResize); 3141 } 3142 }, 3143 3144 stop: function () { 3145 $(this).removeData("resizable-alsoresize"); 3146 } 3147}); 3148 3149$.ui.plugin.add("resizable", "ghost", { 3150 3151 start: function() { 3152 3153 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3154 3155 that.ghost = that.originalElement.clone(); 3156 that.ghost 3157 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3158 .addClass("ui-resizable-ghost") 3159 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3160 3161 that.ghost.appendTo(that.helper); 3162 3163 }, 3164 3165 resize: function(){ 3166 var that = $(this).data("ui-resizable"); 3167 if (that.ghost) { 3168 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3169 } 3170 }, 3171 3172 stop: function() { 3173 var that = $(this).data("ui-resizable"); 3174 if (that.ghost && that.helper) { 3175 that.helper.get(0).removeChild(that.ghost.get(0)); 3176 } 3177 } 3178 3179}); 3180 3181$.ui.plugin.add("resizable", "grid", { 3182 3183 resize: function() { 3184 var that = $(this).data("ui-resizable"), 3185 o = that.options, 3186 cs = that.size, 3187 os = that.originalSize, 3188 op = that.originalPosition, 3189 a = that.axis, 3190 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3191 gridX = (grid[0]||1), 3192 gridY = (grid[1]||1), 3193 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3194 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3195 newWidth = os.width + ox, 3196 newHeight = os.height + oy, 3197 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3198 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3199 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3200 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3201 3202 o.grid = grid; 3203 3204 if (isMinWidth) { 3205 newWidth = newWidth + gridX; 3206 } 3207 if (isMinHeight) { 3208 newHeight = newHeight + gridY; 3209 } 3210 if (isMaxWidth) { 3211 newWidth = newWidth - gridX; 3212 } 3213 if (isMaxHeight) { 3214 newHeight = newHeight - gridY; 3215 } 3216 3217 if (/^(se|s|e)$/.test(a)) { 3218 that.size.width = newWidth; 3219 that.size.height = newHeight; 3220 } else if (/^(ne)$/.test(a)) { 3221 that.size.width = newWidth; 3222 that.size.height = newHeight; 3223 that.position.top = op.top - oy; 3224 } else if (/^(sw)$/.test(a)) { 3225 that.size.width = newWidth; 3226 that.size.height = newHeight; 3227 that.position.left = op.left - ox; 3228 } else { 3229 that.size.width = newWidth; 3230 that.size.height = newHeight; 3231 that.position.top = op.top - oy; 3232 that.position.left = op.left - ox; 3233 } 3234 } 3235 3236}); 3237 3238})(jQuery); 3239 3240(function( $, undefined ) { 3241 3242$.widget("ui.selectable", $.ui.mouse, { 3243 version: "1.10.3", 3244 options: { 3245 appendTo: "body", 3246 autoRefresh: true, 3247 distance: 0, 3248 filter: "*", 3249 tolerance: "touch", 3250 3251 // callbacks 3252 selected: null, 3253 selecting: null, 3254 start: null, 3255 stop: null, 3256 unselected: null, 3257 unselecting: null 3258 }, 3259 _create: function() { 3260 var selectees, 3261 that = this; 3262 3263 this.element.addClass("ui-selectable"); 3264 3265 this.dragged = false; 3266 3267 // cache selectee children based on filter 3268 this.refresh = function() { 3269 selectees = $(that.options.filter, that.element[0]); 3270 selectees.addClass("ui-selectee"); 3271 selectees.each(function() { 3272 var $this = $(this), 3273 pos = $this.offset(); 3274 $.data(this, "selectable-item", { 3275 element: this, 3276 $element: $this, 3277 left: pos.left, 3278 top: pos.top, 3279 right: pos.left + $this.outerWidth(), 3280 bottom: pos.top + $this.outerHeight(), 3281 startselected: false, 3282 selected: $this.hasClass("ui-selected"), 3283 selecting: $this.hasClass("ui-selecting"), 3284 unselecting: $this.hasClass("ui-unselecting") 3285 }); 3286 }); 3287 }; 3288 this.refresh(); 3289 3290 this.selectees = selectees.addClass("ui-selectee"); 3291 3292 this._mouseInit(); 3293 3294 this.helper = $("<div class='ui-selectable-helper'></div>"); 3295 }, 3296 3297 _destroy: function() { 3298 this.selectees 3299 .removeClass("ui-selectee") 3300 .removeData("selectable-item"); 3301 this.element 3302 .removeClass("ui-selectable ui-selectable-disabled"); 3303 this._mouseDestroy(); 3304 }, 3305 3306 _mouseStart: function(event) { 3307 var that = this, 3308 options = this.options; 3309 3310 this.opos = [event.pageX, event.pageY]; 3311 3312 if (this.options.disabled) { 3313 return; 3314 } 3315 3316 this.selectees = $(options.filter, this.element[0]); 3317 3318 this._trigger("start", event); 3319 3320 $(options.appendTo).append(this.helper); 3321 // position helper (lasso) 3322 this.helper.css({ 3323 "left": event.pageX, 3324 "top": event.pageY, 3325 "width": 0, 3326 "height": 0 3327 }); 3328 3329 if (options.autoRefresh) { 3330 this.refresh(); 3331 } 3332 3333 this.selectees.filter(".ui-selected").each(function() { 3334 var selectee = $.data(this, "selectable-item"); 3335 selectee.startselected = true; 3336 if (!event.metaKey && !event.ctrlKey) { 3337 selectee.$element.removeClass("ui-selected"); 3338 selectee.selected = false; 3339 selectee.$element.addClass("ui-unselecting"); 3340 selectee.unselecting = true; 3341 // selectable UNSELECTING callback 3342 that._trigger("unselecting", event, { 3343 unselecting: selectee.element 3344 }); 3345 } 3346 }); 3347 3348 $(event.target).parents().addBack().each(function() { 3349 var doSelect, 3350 selectee = $.data(this, "selectable-item"); 3351 if (selectee) { 3352 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3353 selectee.$element 3354 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3355 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3356 selectee.unselecting = !doSelect; 3357 selectee.selecting = doSelect; 3358 selectee.selected = doSelect; 3359 // selectable (UN)SELECTING callback 3360 if (doSelect) { 3361 that._trigger("selecting", event, { 3362 selecting: selectee.element 3363 }); 3364 } else { 3365 that._trigger("unselecting", event, { 3366 unselecting: selectee.element 3367 }); 3368 } 3369 return false; 3370 } 3371 }); 3372 3373 }, 3374 3375 _mouseDrag: function(event) { 3376 3377 this.dragged = true; 3378 3379 if (this.options.disabled) { 3380 return; 3381 } 3382 3383 var tmp, 3384 that = this, 3385 options = this.options, 3386 x1 = this.opos[0], 3387 y1 = this.opos[1], 3388 x2 = event.pageX, 3389 y2 = event.pageY; 3390 3391 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3392 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3393 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3394 3395 this.selectees.each(function() { 3396 var selectee = $.data(this, "selectable-item"), 3397 hit = false; 3398 3399 //prevent helper from being selected if appendTo: selectable 3400 if (!selectee || selectee.element === that.element[0]) { 3401 return; 3402 } 3403 3404 if (options.tolerance === "touch") { 3405 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3406 } else if (options.tolerance === "fit") { 3407 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3408 } 3409 3410 if (hit) { 3411 // SELECT 3412 if (selectee.selected) { 3413 selectee.$element.removeClass("ui-selected"); 3414 selectee.selected = false; 3415 } 3416 if (selectee.unselecting) { 3417 selectee.$element.removeClass("ui-unselecting"); 3418 selectee.unselecting = false; 3419 } 3420 if (!selectee.selecting) { 3421 selectee.$element.addClass("ui-selecting"); 3422 selectee.selecting = true; 3423 // selectable SELECTING callback 3424 that._trigger("selecting", event, { 3425 selecting: selectee.element 3426 }); 3427 } 3428 } else { 3429 // UNSELECT 3430 if (selectee.selecting) { 3431 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3432 selectee.$element.removeClass("ui-selecting"); 3433 selectee.selecting = false; 3434 selectee.$element.addClass("ui-selected"); 3435 selectee.selected = true; 3436 } else { 3437 selectee.$element.removeClass("ui-selecting"); 3438 selectee.selecting = false; 3439 if (selectee.startselected) { 3440 selectee.$element.addClass("ui-unselecting"); 3441 selectee.unselecting = true; 3442 } 3443 // selectable UNSELECTING callback 3444 that._trigger("unselecting", event, { 3445 unselecting: selectee.element 3446 }); 3447 } 3448 } 3449 if (selectee.selected) { 3450 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3451 selectee.$element.removeClass("ui-selected"); 3452 selectee.selected = false; 3453 3454 selectee.$element.addClass("ui-unselecting"); 3455 selectee.unselecting = true; 3456 // selectable UNSELECTING callback 3457 that._trigger("unselecting", event, { 3458 unselecting: selectee.element 3459 }); 3460 } 3461 } 3462 } 3463 }); 3464 3465 return false; 3466 }, 3467 3468 _mouseStop: function(event) { 3469 var that = this; 3470 3471 this.dragged = false; 3472 3473 $(".ui-unselecting", this.element[0]).each(function() { 3474 var selectee = $.data(this, "selectable-item"); 3475 selectee.$element.removeClass("ui-unselecting"); 3476 selectee.unselecting = false; 3477 selectee.startselected = false; 3478 that._trigger("unselected", event, { 3479 unselected: selectee.element 3480 }); 3481 }); 3482 $(".ui-selecting", this.element[0]).each(function() { 3483 var selectee = $.data(this, "selectable-item"); 3484 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3485 selectee.selecting = false; 3486 selectee.selected = true; 3487 selectee.startselected = true; 3488 that._trigger("selected", event, { 3489 selected: selectee.element 3490 }); 3491 }); 3492 this._trigger("stop", event); 3493 3494 this.helper.remove(); 3495 3496 return false; 3497 } 3498 3499}); 3500 3501})(jQuery); 3502 3503(function( $, undefined ) { 3504 3505/*jshint loopfunc: true */ 3506 3507function isOverAxis( x, reference, size ) { 3508 return ( x > reference ) && ( x < ( reference + size ) ); 3509} 3510 3511function isFloating(item) { 3512 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 3513} 3514 3515$.widget("ui.sortable", $.ui.mouse, { 3516 version: "1.10.3", 3517 widgetEventPrefix: "sort", 3518 ready: false, 3519 options: { 3520 appendTo: "parent", 3521 axis: false, 3522 connectWith: false, 3523 containment: false, 3524 cursor: "auto", 3525 cursorAt: false, 3526 dropOnEmpty: true, 3527 forcePlaceholderSize: false, 3528 forceHelperSize: false, 3529 grid: false, 3530 handle: false, 3531 helper: "original", 3532 items: "> *", 3533 opacity: false, 3534 placeholder: false, 3535 revert: false, 3536 scroll: true, 3537 scrollSensitivity: 20, 3538 scrollSpeed: 20, 3539 scope: "default", 3540 tolerance: "intersect", 3541 zIndex: 1000, 3542 3543 // callbacks 3544 activate: null, 3545 beforeStop: null, 3546 change: null, 3547 deactivate: null, 3548 out: null, 3549 over: null, 3550 receive: null, 3551 remove: null, 3552 sort: null, 3553 start: null, 3554 stop: null, 3555 update: null 3556 }, 3557 _create: function() { 3558 3559 var o = this.options; 3560 this.containerCache = {}; 3561 this.element.addClass("ui-sortable"); 3562 3563 //Get the items 3564 this.refresh(); 3565 3566 //Let's determine if the items are being displayed horizontally 3567 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 3568 3569 //Let's determine the parent's offset 3570 this.offset = this.element.offset(); 3571 3572 //Initialize mouse events for interaction 3573 this._mouseInit(); 3574 3575 //We're ready to go 3576 this.ready = true; 3577 3578 }, 3579 3580 _destroy: function() { 3581 this.element 3582 .removeClass("ui-sortable ui-sortable-disabled"); 3583 this._mouseDestroy(); 3584 3585 for ( var i = this.items.length - 1; i >= 0; i-- ) { 3586 this.items[i].item.removeData(this.widgetName + "-item"); 3587 } 3588 3589 return this; 3590 }, 3591 3592 _setOption: function(key, value){ 3593 if ( key === "disabled" ) { 3594 this.options[ key ] = value; 3595 3596 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3597 } else { 3598 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3599 $.Widget.prototype._setOption.apply(this, arguments); 3600 } 3601 }, 3602 3603 _mouseCapture: function(event, overrideHandle) { 3604 var currentItem = null, 3605 validHandle = false, 3606 that = this; 3607 3608 if (this.reverting) { 3609 return false; 3610 } 3611 3612 if(this.options.disabled || this.options.type === "static") { 3613 return false; 3614 } 3615 3616 //We have to refresh the items data once first 3617 this._refreshItems(event); 3618 3619 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3620 $(event.target).parents().each(function() { 3621 if($.data(this, that.widgetName + "-item") === that) { 3622 currentItem = $(this); 3623 return false; 3624 } 3625 }); 3626 if($.data(event.target, that.widgetName + "-item") === that) { 3627 currentItem = $(event.target); 3628 } 3629 3630 if(!currentItem) { 3631 return false; 3632 } 3633 if(this.options.handle && !overrideHandle) { 3634 $(this.options.handle, currentItem).find("*").addBack().each(function() { 3635 if(this === event.target) { 3636 validHandle = true; 3637 } 3638 }); 3639 if(!validHandle) { 3640 return false; 3641 } 3642 } 3643 3644 this.currentItem = currentItem; 3645 this._removeCurrentsFromItems(); 3646 return true; 3647 3648 }, 3649 3650 _mouseStart: function(event, overrideHandle, noActivation) { 3651 3652 var i, body, 3653 o = this.options; 3654 3655 this.currentContainer = this; 3656 3657 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3658 this.refreshPositions(); 3659 3660 //Create and append the visible helper 3661 this.helper = this._createHelper(event); 3662 3663 //Cache the helper size 3664 this._cacheHelperProportions(); 3665 3666 /* 3667 * - Position generation - 3668 * This block generates everything position related - it's the core of draggables. 3669 */ 3670 3671 //Cache the margins of the original element 3672 this._cacheMargins(); 3673 3674 //Get the next scrolling parent 3675 this.scrollParent = this.helper.scrollParent(); 3676 3677 //The element's absolute position on the page minus margins 3678 this.offset = this.currentItem.offset(); 3679 this.offset = { 3680 top: this.offset.top - this.margins.top, 3681 left: this.offset.left - this.margins.left 3682 }; 3683 3684 $.extend(this.offset, { 3685 click: { //Where the click happened, relative to the element 3686 left: event.pageX - this.offset.left, 3687 top: event.pageY - this.offset.top 3688 }, 3689 parent: this._getParentOffset(), 3690 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3691 }); 3692 3693 // Only after we got the offset, we can change the helper's position to absolute 3694 // TODO: Still need to figure out a way to make relative sorting possible 3695 this.helper.css("position", "absolute"); 3696 this.cssPosition = this.helper.css("position"); 3697 3698 //Generate the original position 3699 this.originalPosition = this._generatePosition(event); 3700 this.originalPageX = event.pageX; 3701 this.originalPageY = event.pageY; 3702 3703 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 3704 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3705 3706 //Cache the former DOM position 3707 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3708 3709 //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 3710 if(this.helper[0] !== this.currentItem[0]) { 3711 this.currentItem.hide(); 3712 } 3713 3714 //Create the placeholder 3715 this._createPlaceholder(); 3716 3717 //Set a containment if given in the options 3718 if(o.containment) { 3719 this._setContainment(); 3720 } 3721 3722 if( o.cursor && o.cursor !== "auto" ) { // cursor option 3723 body = this.document.find( "body" ); 3724 3725 // support: IE 3726 this.storedCursor = body.css( "cursor" ); 3727 body.css( "cursor", o.cursor ); 3728 3729 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 3730 } 3731 3732 if(o.opacity) { // opacity option 3733 if (this.helper.css("opacity")) { 3734 this._storedOpacity = this.helper.css("opacity"); 3735 } 3736 this.helper.css("opacity", o.opacity); 3737 } 3738 3739 if(o.zIndex) { // zIndex option 3740 if (this.helper.css("zIndex")) { 3741 this._storedZIndex = this.helper.css("zIndex"); 3742 } 3743 this.helper.css("zIndex", o.zIndex); 3744 } 3745 3746 //Prepare scrolling 3747 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3748 this.overflowOffset = this.scrollParent.offset(); 3749 } 3750 3751 //Call callbacks 3752 this._trigger("start", event, this._uiHash()); 3753 3754 //Recache the helper size 3755 if(!this._preserveHelperProportions) { 3756 this._cacheHelperProportions(); 3757 } 3758 3759 3760 //Post "activate" events to possible containers 3761 if( !noActivation ) { 3762 for ( i = this.containers.length - 1; i >= 0; i-- ) { 3763 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 3764 } 3765 } 3766 3767 //Prepare possible droppables 3768 if($.ui.ddmanager) { 3769 $.ui.ddmanager.current = this; 3770 } 3771 3772 if ($.ui.ddmanager && !o.dropBehaviour) { 3773 $.ui.ddmanager.prepareOffsets(this, event); 3774 } 3775 3776 this.dragging = true; 3777 3778 this.helper.addClass("ui-sortable-helper"); 3779 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3780 return true; 3781 3782 }, 3783 3784 _mouseDrag: function(event) { 3785 var i, item, itemElement, intersection, 3786 o = this.options, 3787 scrolled = false; 3788 3789 //Compute the helpers position 3790 this.position = this._generatePosition(event); 3791 this.positionAbs = this._convertPositionTo("absolute"); 3792 3793 if (!this.lastPositionAbs) { 3794 this.lastPositionAbs = this.positionAbs; 3795 } 3796 3797 //Do scrolling 3798 if(this.options.scroll) { 3799 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3800 3801 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 3802 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3803 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 3804 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3805 } 3806 3807 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 3808 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3809 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 3810 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3811 } 3812 3813 } else { 3814 3815 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 3816 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3817 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 3818 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3819 } 3820 3821 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 3822 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3823 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 3824 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3825 } 3826 3827 } 3828 3829 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 3830 $.ui.ddmanager.prepareOffsets(this, event); 3831 } 3832 } 3833 3834 //Regenerate the absolute position used for position checks 3835 this.positionAbs = this._convertPositionTo("absolute"); 3836 3837 //Set the helper position 3838 if(!this.options.axis || this.options.axis !== "y") { 3839 this.helper[0].style.left = this.position.left+"px"; 3840 } 3841 if(!this.options.axis || this.options.axis !== "x") { 3842 this.helper[0].style.top = this.position.top+"px"; 3843 } 3844 3845 //Rearrange 3846 for (i = this.items.length - 1; i >= 0; i--) { 3847 3848 //Cache variables and intersection, continue if no intersection 3849 item = this.items[i]; 3850 itemElement = item.item[0]; 3851 intersection = this._intersectsWithPointer(item); 3852 if (!intersection) { 3853 continue; 3854 } 3855 3856 // Only put the placeholder inside the current Container, skip all 3857 // items form other containers. This works because when moving 3858 // an item from one container to another the 3859 // currentContainer is switched before the placeholder is moved. 3860 // 3861 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3862 // beetween the outer and inner container. 3863 if (item.instance !== this.currentContainer) { 3864 continue; 3865 } 3866 3867 // cannot intersect with itself 3868 // no useless actions that have been done before 3869 // no action if the item moved is the parent of the item checked 3870 if (itemElement !== this.currentItem[0] && 3871 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 3872 !$.contains(this.placeholder[0], itemElement) && 3873 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 3874 ) { 3875 3876 this.direction = intersection === 1 ? "down" : "up"; 3877 3878 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 3879 this._rearrange(event, item); 3880 } else { 3881 break; 3882 } 3883 3884 this._trigger("change", event, this._uiHash()); 3885 break; 3886 } 3887 } 3888 3889 //Post events to containers 3890 this._contactContainers(event); 3891 3892 //Interconnect with droppables 3893 if($.ui.ddmanager) { 3894 $.ui.ddmanager.drag(this, event); 3895 } 3896 3897 //Call callbacks 3898 this._trigger("sort", event, this._uiHash()); 3899 3900 this.lastPositionAbs = this.positionAbs; 3901 return false; 3902 3903 }, 3904 3905 _mouseStop: function(event, noPropagation) { 3906 3907 if(!event) { 3908 return; 3909 } 3910 3911 //If we are using droppables, inform the manager about the drop 3912 if ($.ui.ddmanager && !this.options.dropBehaviour) { 3913 $.ui.ddmanager.drop(this, event); 3914 } 3915 3916 if(this.options.revert) { 3917 var that = this, 3918 cur = this.placeholder.offset(), 3919 axis = this.options.axis, 3920 animation = {}; 3921 3922 if ( !axis || axis === "x" ) { 3923 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 3924 } 3925 if ( !axis || axis === "y" ) { 3926 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 3927 } 3928 this.reverting = true; 3929 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 3930 that._clear(event); 3931 }); 3932 } else { 3933 this._clear(event, noPropagation); 3934 } 3935 3936 return false; 3937 3938 }, 3939 3940 cancel: function() { 3941 3942 if(this.dragging) { 3943 3944 this._mouseUp({ target: null }); 3945 3946 if(this.options.helper === "original") { 3947 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3948 } else { 3949 this.currentItem.show(); 3950 } 3951 3952 //Post deactivating events to containers 3953 for (var i = this.containers.length - 1; i >= 0; i--){ 3954 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3955 if(this.containers[i].containerCache.over) { 3956 this.containers[i]._trigger("out", null, this._uiHash(this)); 3957 this.containers[i].containerCache.over = 0; 3958 } 3959 } 3960 3961 } 3962 3963 if (this.placeholder) { 3964 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3965 if(this.placeholder[0].parentNode) { 3966 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3967 } 3968 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 3969 this.helper.remove(); 3970 } 3971 3972 $.extend(this, { 3973 helper: null, 3974 dragging: false, 3975 reverting: false, 3976 _noFinalSort: null 3977 }); 3978 3979 if(this.domPosition.prev) { 3980 $(this.domPosition.prev).after(this.currentItem); 3981 } else { 3982 $(this.domPosition.parent).prepend(this.currentItem); 3983 } 3984 } 3985 3986 return this; 3987 3988 }, 3989 3990 serialize: function(o) { 3991 3992 var items = this._getItemsAsjQuery(o && o.connected), 3993 str = []; 3994 o = o || {}; 3995 3996 $(items).each(function() { 3997 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 3998 if (res) { 3999 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4000 } 4001 }); 4002 4003 if(!str.length && o.key) { 4004 str.push(o.key + "="); 4005 } 4006 4007 return str.join("&"); 4008 4009 }, 4010 4011 toArray: function(o) { 4012 4013 var items = this._getItemsAsjQuery(o && o.connected), 4014 ret = []; 4015 4016 o = o || {}; 4017 4018 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4019 return ret; 4020 4021 }, 4022 4023 /* Be careful with the following core functions */ 4024 _intersectsWith: function(item) { 4025 4026 var x1 = this.positionAbs.left, 4027 x2 = x1 + this.helperProportions.width, 4028 y1 = this.positionAbs.top, 4029 y2 = y1 + this.helperProportions.height, 4030 l = item.left, 4031 r = l + item.width, 4032 t = item.top, 4033 b = t + item.height, 4034 dyClick = this.offset.click.top, 4035 dxClick = this.offset.click.left, 4036 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 4037 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 4038 isOverElement = isOverElementHeight && isOverElementWidth; 4039 4040 if ( this.options.tolerance === "pointer" || 4041 this.options.forcePointerForContainers || 4042 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4043 ) { 4044 return isOverElement; 4045 } else { 4046 4047 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4048 x2 - (this.helperProportions.width / 2) < r && // Left Half 4049 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4050 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4051 4052 } 4053 }, 4054 4055 _intersectsWithPointer: function(item) { 4056 4057 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4058 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4059 isOverElement = isOverElementHeight && isOverElementWidth, 4060 verticalDirection = this._getDragVerticalDirection(), 4061 horizontalDirection = this._getDragHorizontalDirection(); 4062 4063 if (!isOverElement) { 4064 return false; 4065 } 4066 4067 return this.floating ? 4068 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4069 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4070 4071 }, 4072 4073 _intersectsWithSides: function(item) { 4074 4075 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4076 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4077 verticalDirection = this._getDragVerticalDirection(), 4078 horizontalDirection = this._getDragHorizontalDirection(); 4079 4080 if (this.floating && horizontalDirection) { 4081 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4082 } else { 4083 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4084 } 4085 4086 }, 4087 4088 _getDragVerticalDirection: function() { 4089 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4090 return delta !== 0 && (delta > 0 ? "down" : "up"); 4091 }, 4092 4093 _getDragHorizontalDirection: function() { 4094 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4095 return delta !== 0 && (delta > 0 ? "right" : "left"); 4096 }, 4097 4098 refresh: function(event) { 4099 this._refreshItems(event); 4100 this.refreshPositions(); 4101 return this; 4102 }, 4103 4104 _connectWith: function() { 4105 var options = this.options; 4106 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4107 }, 4108 4109 _getItemsAsjQuery: function(connected) { 4110 4111 var i, j, cur, inst, 4112 items = [], 4113 queries = [], 4114 connectWith = this._connectWith(); 4115 4116 if(connectWith && connected) { 4117 for (i = connectWith.length - 1; i >= 0; i--){ 4118 cur = $(connectWith[i]); 4119 for ( j = cur.length - 1; j >= 0; j--){ 4120 inst = $.data(cur[j], this.widgetFullName); 4121 if(inst && inst !== this && !inst.options.disabled) { 4122 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]); 4123 } 4124 } 4125 } 4126 } 4127 4128 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]); 4129 4130 for (i = queries.length - 1; i >= 0; i--){ 4131 queries[i][0].each(function() { 4132 items.push(this); 4133 }); 4134 } 4135 4136 return $(items); 4137 4138 }, 4139 4140 _removeCurrentsFromItems: function() { 4141 4142 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4143 4144 this.items = $.grep(this.items, function (item) { 4145 for (var j=0; j < list.length; j++) { 4146 if(list[j] === item.item[0]) { 4147 return false; 4148 } 4149 } 4150 return true; 4151 }); 4152 4153 }, 4154 4155 _refreshItems: function(event) { 4156 4157 this.items = []; 4158 this.containers = [this]; 4159 4160 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4161 items = this.items, 4162 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4163 connectWith = this._connectWith(); 4164 4165 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4166 for (i = connectWith.length - 1; i >= 0; i--){ 4167 cur = $(connectWith[i]); 4168 for (j = cur.length - 1; j >= 0; j--){ 4169 inst = $.data(cur[j], this.widgetFullName); 4170 if(inst && inst !== this && !inst.options.disabled) { 4171 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4172 this.containers.push(inst); 4173 } 4174 } 4175 } 4176 } 4177 4178 for (i = queries.length - 1; i >= 0; i--) { 4179 targetData = queries[i][1]; 4180 _queries = queries[i][0]; 4181 4182 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4183 item = $(_queries[j]); 4184 4185 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4186 4187 items.push({ 4188 item: item, 4189 instance: targetData, 4190 width: 0, height: 0, 4191 left: 0, top: 0 4192 }); 4193 } 4194 } 4195 4196 }, 4197 4198 refreshPositions: function(fast) { 4199 4200 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4201 if(this.offsetParent && this.helper) { 4202 this.offset.parent = this._getParentOffset(); 4203 } 4204 4205 var i, item, t, p; 4206 4207 for (i = this.items.length - 1; i >= 0; i--){ 4208 item = this.items[i]; 4209 4210 //We ignore calculating positions of all connected containers when we're not over them 4211 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4212 continue; 4213 } 4214 4215 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4216 4217 if (!fast) { 4218 item.width = t.outerWidth(); 4219 item.height = t.outerHeight(); 4220 } 4221 4222 p = t.offset(); 4223 item.left = p.left; 4224 item.top = p.top; 4225 } 4226 4227 if(this.options.custom && this.options.custom.refreshContainers) { 4228 this.options.custom.refreshContainers.call(this); 4229 } else { 4230 for (i = this.containers.length - 1; i >= 0; i--){ 4231 p = this.containers[i].element.offset(); 4232 this.containers[i].containerCache.left = p.left; 4233 this.containers[i].containerCache.top = p.top; 4234 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4235 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4236 } 4237 } 4238 4239 return this; 4240 }, 4241 4242 _createPlaceholder: function(that) { 4243 that = that || this; 4244 var className, 4245 o = that.options; 4246 4247 if(!o.placeholder || o.placeholder.constructor === String) { 4248 className = o.placeholder; 4249 o.placeholder = { 4250 element: function() { 4251 4252 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4253 element = $( "<" + nodeName + ">", that.document[0] ) 4254 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4255 .removeClass("ui-sortable-helper"); 4256 4257 if ( nodeName === "tr" ) { 4258 that.currentItem.children().each(function() { 4259 $( "<td> </td>", that.document[0] ) 4260 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 4261 .appendTo( element ); 4262 }); 4263 } else if ( nodeName === "img" ) { 4264 element.attr( "src", that.currentItem.attr( "src" ) ); 4265 } 4266 4267 if ( !className ) { 4268 element.css( "visibility", "hidden" ); 4269 } 4270 4271 return element; 4272 }, 4273 update: function(container, p) { 4274 4275 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4276 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4277 if(className && !o.forcePlaceholderSize) { 4278 return; 4279 } 4280 4281 //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 4282 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4283 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4284 } 4285 }; 4286 } 4287 4288 //Create the placeholder 4289 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4290 4291 //Append it after the actual current item 4292 that.currentItem.after(that.placeholder); 4293 4294 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4295 o.placeholder.update(that, that.placeholder); 4296 4297 }, 4298 4299 _contactContainers: function(event) { 4300 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4301 innermostContainer = null, 4302 innermostIndex = null; 4303 4304 // get innermost container that intersects with item 4305 for (i = this.containers.length - 1; i >= 0; i--) { 4306 4307 // never consider a container that's located within the item itself 4308 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4309 continue; 4310 } 4311 4312 if(this._intersectsWith(this.containers[i].containerCache)) { 4313 4314 // if we've already found a container and it's more "inner" than this, then continue 4315 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4316 continue; 4317 } 4318 4319 innermostContainer = this.containers[i]; 4320 innermostIndex = i; 4321 4322 } else { 4323 // container doesn't intersect. trigger "out" event if necessary 4324 if(this.containers[i].containerCache.over) { 4325 this.containers[i]._trigger("out", event, this._uiHash(this)); 4326 this.containers[i].containerCache.over = 0; 4327 } 4328 } 4329 4330 } 4331 4332 // if no intersecting containers found, return 4333 if(!innermostContainer) { 4334 return; 4335 } 4336 4337 // move the item into the container if it's not there already 4338 if(this.containers.length === 1) { 4339 if (!this.containers[innermostIndex].containerCache.over) { 4340 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4341 this.containers[innermostIndex].containerCache.over = 1; 4342 } 4343 } else { 4344 4345 //When entering a new container, we will find the item with the least distance and append our item near it 4346 dist = 10000; 4347 itemWithLeastDistance = null; 4348 floating = innermostContainer.floating || isFloating(this.currentItem); 4349 posProperty = floating ? "left" : "top"; 4350 sizeProperty = floating ? "width" : "height"; 4351 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4352 for (j = this.items.length - 1; j >= 0; j--) { 4353 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4354 continue; 4355 } 4356 if(this.items[j].item[0] === this.currentItem[0]) { 4357 continue; 4358 } 4359 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 4360 continue; 4361 } 4362 cur = this.items[j].item.offset()[posProperty]; 4363 nearBottom = false; 4364 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4365 nearBottom = true; 4366 cur += this.items[j][sizeProperty]; 4367 } 4368 4369 if(Math.abs(cur - base) < dist) { 4370 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4371 this.direction = nearBottom ? "up": "down"; 4372 } 4373 } 4374 4375 //Check if dropOnEmpty is enabled 4376 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4377 return; 4378 } 4379 4380 if(this.currentContainer === this.containers[innermostIndex]) { 4381 return; 4382 } 4383 4384 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4385 this._trigger("change", event, this._uiHash()); 4386 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4387 this.currentContainer = this.containers[innermostIndex]; 4388 4389 //Update the placeholder 4390 this.options.placeholder.update(this.currentContainer, this.placeholder); 4391 4392 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4393 this.containers[innermostIndex].containerCache.over = 1; 4394 } 4395 4396 4397 }, 4398 4399 _createHelper: function(event) { 4400 4401 var o = this.options, 4402 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4403 4404 //Add the helper to the DOM if that didn't happen already 4405 if(!helper.parents("body").length) { 4406 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4407 } 4408 4409 if(helper[0] === this.currentItem[0]) { 4410 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left
vendor: 4,496 bytes, lines 4410-4527
4410: this.currentItem.css("left") }; 4411 } 4412 4413 if(!helper[0].style.width || o.forceHelperSize) { 4414 helper.width(this.currentItem.width()); 4415 } 4416 if(!helper[0].style.height || o.forceHelperSize) { 4417 helper.height(this.currentItem.height()); 4418 } 4419 4420 return helper; 4421 4422 }, 4423 4424 _adjustOffsetFromHelper: function(obj) { 4425 if (typeof obj === "string") { 4426 obj = obj.split(" "); 4427 } 4428 if ($.isArray(obj)) { 4429 obj = {left: +obj[0], top: +obj[1] || 0}; 4430 } 4431 if ("left" in obj) { 4432 this.offset.click.left = obj.left + this.margins.left; 4433 } 4434 if ("right" in obj) { 4435 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4436 } 4437 if ("top" in obj) { 4438 this.offset.click.top = obj.top + this.margins.top; 4439 } 4440 if ("bottom" in obj) { 4441 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4442 } 4443 }, 4444 4445 _getParentOffset: function() { 4446 4447 4448 //Get the offsetParent and cache its position 4449 this.offsetParent = this.helper.offsetParent(); 4450 var po = this.offsetParent.offset(); 4451 4452 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4453 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4454 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4455 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4456 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4457 po.left += this.scrollParent.scrollLeft(); 4458 po.top += this.scrollParent.scrollTop(); 4459 } 4460 4461 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4462 // with an ugly IE fix 4463 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4464 po = { top: 0, left: 0 }; 4465 } 4466 4467 return { 4468 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4469 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4470 }; 4471 4472 }, 4473 4474 _getRelativeOffset: function() { 4475 4476 if(this.cssPosition === "relative") { 4477 var p = this.currentItem.position(); 4478 return { 4479 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4480 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4481 }; 4482 } else { 4483 return { top: 0, left: 0 }; 4484 } 4485 4486 }, 4487 4488 _cacheMargins: function() { 4489 this.margins = { 4490 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4491 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4492 }; 4493 }, 4494 4495 _cacheHelperProportions: function() { 4496 this.helperProportions = { 4497 width: this.helper.outerWidth(), 4498 height: this.helper.outerHeight() 4499 }; 4500 }, 4501 4502 _setContainment: function() { 4503 4504 var ce, co, over, 4505 o = this.options; 4506 if(o.containment === "parent") { 4507 o.containment = this.helper[0].parentNode; 4508 } 4509 if(o.containment === "document" || o.containment === "window") { 4510 this.containment = [ 4511 0 - this.offset.relative.left - this.offset.parent.left, 4512 0 - this.offset.relative.top - this.offset.parent.top, 4513 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4514 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4515 ]; 4516 } 4517 4518 if(!(/^(document|window|parent)$/).test(o.containment)) { 4519 ce = $(o.containment)[0]; 4520 co = $(o.containment).offset(); 4521 over = ($(ce).css("overflow") !== "hidden"); 4522 4523 this.containment = [ 4524 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4525 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4526 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, 4527 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 68,701 bytes, lines 4527-6965
452710) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4528 ]; 4529 } 4530 4531 }, 4532 4533 _convertPositionTo: function(d, pos) { 4534 4535 if(!pos) { 4536 pos = this.position; 4537 } 4538 var mod = d === "absolute" ? 1 : -1, 4539 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4540 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4541 4542 return { 4543 top: ( 4544 pos.top + // The absolute mouse position 4545 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4546 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4547 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4548 ), 4549 left: ( 4550 pos.left + // The absolute mouse position 4551 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4552 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4553 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4554 ) 4555 }; 4556 4557 }, 4558 4559 _generatePosition: function(event) { 4560 4561 var top, left, 4562 o = this.options, 4563 pageX = event.pageX, 4564 pageY = event.pageY, 4565 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); 4566 4567 // This is another very weird special case that only happens for relative elements: 4568 // 1. If the css position is relative 4569 // 2. and the scroll parent is the document or similar to the offset parent 4570 // we have to refresh the relative offset during the scroll so there are no jumps 4571 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 4572 this.offset.relative = this._getRelativeOffset(); 4573 } 4574 4575 /* 4576 * - Position constraining - 4577 * Constrain the position to a mix of grid, containment. 4578 */ 4579 4580 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4581 4582 if(this.containment) { 4583 if(event.pageX - this.offset.click.left < this.containment[0]) { 4584 pageX = this.containment[0] + this.offset.click.left; 4585 } 4586 if(event.pageY - this.offset.click.top < this.containment[1]) { 4587 pageY = this.containment[1] + this.offset.click.top; 4588 } 4589 if(event.pageX - this.offset.click.left > this.containment[2]) { 4590 pageX = this.containment[2] + this.offset.click.left; 4591 } 4592 if(event.pageY - this.offset.click.top > this.containment[3]) { 4593 pageY = this.containment[3] + this.offset.click.top; 4594 } 4595 } 4596 4597 if(o.grid) { 4598 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4599 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; 4600 4601 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4602 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; 4603 } 4604 4605 } 4606 4607 return { 4608 top: ( 4609 pageY - // The absolute mouse position 4610 this.offset.click.top - // Click offset (relative to the element) 4611 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 4612 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 4613 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4614 ), 4615 left: ( 4616 pageX - // The absolute mouse position 4617 this.offset.click.left - // Click offset (relative to the element) 4618 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 4619 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 4620 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4621 ) 4622 }; 4623 4624 }, 4625 4626 _rearrange: function(event, i, a, hardRefresh) { 4627 4628 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)); 4629 4630 //Various things done here to improve the performance: 4631 // 1. we create a setTimeout, that calls refreshPositions 4632 // 2. on the instance, we have a counter variable, that get's higher after every append 4633 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4634 // 4. this lets only the last addition to the timeout stack through 4635 this.counter = this.counter ? ++this.counter : 1; 4636 var counter = this.counter; 4637 4638 this._delay(function() { 4639 if(counter === this.counter) { 4640 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4641 } 4642 }); 4643 4644 }, 4645 4646 _clear: function(event, noPropagation) { 4647 4648 this.reverting = false; 4649 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4650 // everything else normalized again 4651 var i, 4652 delayedTriggers = []; 4653 4654 // We first have to update the dom position of the actual currentItem 4655 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4656 if(!this._noFinalSort && this.currentItem.parent().length) { 4657 this.placeholder.before(this.currentItem); 4658 } 4659 this._noFinalSort = null; 4660 4661 if(this.helper[0] === this.currentItem[0]) { 4662 for(i in this._storedCSS) { 4663 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 4664 this._storedCSS[i] = ""; 4665 } 4666 } 4667 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4668 } else { 4669 this.currentItem.show(); 4670 } 4671 4672 if(this.fromOutside && !noPropagation) { 4673 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4674 } 4675 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 4676 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4677 } 4678 4679 // Check if the items Container has Changed and trigger appropriate 4680 // events. 4681 if (this !== this.currentContainer) { 4682 if(!noPropagation) { 4683 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4684 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4685 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4686 } 4687 } 4688 4689 4690 //Post events to containers 4691 for (i = this.containers.length - 1; i >= 0; i--){ 4692 if(!noPropagation) { 4693 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4694 } 4695 if(this.containers[i].containerCache.over) { 4696 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4697 this.containers[i].containerCache.over = 0; 4698 } 4699 } 4700 4701 //Do what was originally in plugins 4702 if ( this.storedCursor ) { 4703 this.document.find( "body" ).css( "cursor", this.storedCursor ); 4704 this.storedStylesheet.remove(); 4705 } 4706 if(this._storedOpacity) { 4707 this.helper.css("opacity", this._storedOpacity); 4708 } 4709 if(this._storedZIndex) { 4710 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 4711 } 4712 4713 this.dragging = false; 4714 if(this.cancelHelperRemoval) { 4715 if(!noPropagation) { 4716 this._trigger("beforeStop", event, this._uiHash()); 4717 for (i=0; i < delayedTriggers.length; i++) { 4718 delayedTriggers[i].call(this, event); 4719 } //Trigger all delayed events 4720 this._trigger("stop", event, this._uiHash()); 4721 } 4722 4723 this.fromOutside = false; 4724 return false; 4725 } 4726 4727 if(!noPropagation) { 4728 this._trigger("beforeStop", event, this._uiHash()); 4729 } 4730 4731 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4732 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4733 4734 if(this.helper[0] !== this.currentItem[0]) { 4735 this.helper.remove(); 4736 } 4737 this.helper = null; 4738 4739 if(!noPropagation) { 4740 for (i=0; i < delayedTriggers.length; i++) { 4741 delayedTriggers[i].call(this, event); 4742 } //Trigger all delayed events 4743 this._trigger("stop", event, this._uiHash()); 4744 } 4745 4746 this.fromOutside = false; 4747 return true; 4748 4749 }, 4750 4751 _trigger: function() { 4752 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4753 this.cancel(); 4754 } 4755 }, 4756 4757 _uiHash: function(_inst) { 4758 var inst = _inst || this; 4759 return { 4760 helper: inst.helper, 4761 placeholder: inst.placeholder || $([]), 4762 position: inst.position, 4763 originalPosition: inst.originalPosition, 4764 offset: inst.positionAbs, 4765 item: inst.currentItem, 4766 sender: _inst ? _inst.element : null 4767 }; 4768 } 4769 4770}); 4771 4772})(jQuery); 4773 4774(function($, undefined) { 4775 4776var dataSpace = "ui-effects-"; 4777 4778$.effects = { 4779 effect: {} 4780}; 4781 4782/*! 4783 * jQuery Color Animations v2.1.2 4784 * https://github.com/jquery/jquery-color 4785 * 4786 * Copyright 2013 jQuery Foundation and other contributors 4787 * Released under the MIT license. 4788 * http://jquery.org/license 4789 * 4790 * Date: Wed Jan 16 08:47:09 2013 -0600 4791 */ 4792(function( jQuery, undefined ) { 4793 4794 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4795 4796 // plusequals test for += 100 -= 100 4797 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4798 // a set of RE's that can match strings and generate color tuples. 4799 stringParsers = [{ 4800 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4801 parse: function( execResult ) { 4802 return [ 4803 execResult[ 1 ], 4804 execResult[ 2 ], 4805 execResult[ 3 ], 4806 execResult[ 4 ] 4807 ]; 4808 } 4809 }, { 4810 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4811 parse: function( execResult ) { 4812 return [ 4813 execResult[ 1 ] * 2.55, 4814 execResult[ 2 ] * 2.55, 4815 execResult[ 3 ] * 2.55, 4816 execResult[ 4 ] 4817 ]; 4818 } 4819 }, { 4820 // this regex ignores A-F because it's compared against an already lowercased string 4821 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4822 parse: function( execResult ) { 4823 return [ 4824 parseInt( execResult[ 1 ], 16 ), 4825 parseInt( execResult[ 2 ], 16 ), 4826 parseInt( execResult[ 3 ], 16 ) 4827 ]; 4828 } 4829 }, { 4830 // this regex ignores A-F because it's compared against an already lowercased string 4831 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4832 parse: function( execResult ) { 4833 return [ 4834 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4835 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4836 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4837 ]; 4838 } 4839 }, { 4840 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4841 space: "hsla", 4842 parse: function( execResult ) { 4843 return [ 4844 execResult[ 1 ], 4845 execResult[ 2 ] / 100, 4846 execResult[ 3 ] / 100, 4847 execResult[ 4 ] 4848 ]; 4849 } 4850 }], 4851 4852 // jQuery.Color( ) 4853 color = jQuery.Color = function( color, green, blue, alpha ) { 4854 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4855 }, 4856 spaces = { 4857 rgba: { 4858 props: { 4859 red: { 4860 idx: 0, 4861 type: "byte" 4862 }, 4863 green: { 4864 idx: 1, 4865 type: "byte" 4866 }, 4867 blue: { 4868 idx: 2, 4869 type: "byte" 4870 } 4871 } 4872 }, 4873 4874 hsla: { 4875 props: { 4876 hue: { 4877 idx: 0, 4878 type: "degrees" 4879 }, 4880 saturation: { 4881 idx: 1, 4882 type: "percent" 4883 }, 4884 lightness: { 4885 idx: 2, 4886 type: "percent" 4887 } 4888 } 4889 } 4890 }, 4891 propTypes = { 4892 "byte": { 4893 floor: true, 4894 max: 255 4895 }, 4896 "percent": { 4897 max: 1 4898 }, 4899 "degrees": { 4900 mod: 360, 4901 floor: true 4902 } 4903 }, 4904 support = color.support = {}, 4905 4906 // element for support tests 4907 supportElem = jQuery( "<p>" )[ 0 ], 4908 4909 // colors = jQuery.Color.names 4910 colors, 4911 4912 // local aliases of functions called often 4913 each = jQuery.each; 4914 4915// determine rgba support immediately 4916supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4917support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4918 4919// define cache name and alpha properties 4920// for rgba and hsla spaces 4921each( spaces, function( spaceName, space ) { 4922 space.cache = "_" + spaceName; 4923 space.props.alpha = { 4924 idx: 3, 4925 type: "percent", 4926 def: 1 4927 }; 4928}); 4929 4930function clamp( value, prop, allowEmpty ) { 4931 var type = propTypes[ prop.type ] || {}; 4932 4933 if ( value == null ) { 4934 return (allowEmpty || !prop.def) ? null : prop.def; 4935 } 4936 4937 // ~~ is an short way of doing floor for positive numbers 4938 value = type.floor ? ~~value : parseFloat( value ); 4939 4940 // IE will pass in empty strings as value for alpha, 4941 // which will hit this case 4942 if ( isNaN( value ) ) { 4943 return prop.def; 4944 } 4945 4946 if ( type.mod ) { 4947 // we add mod before modding to make sure that negatives values 4948 // get converted properly: -10 -> 350 4949 return (value + type.mod) % type.mod; 4950 } 4951 4952 // for now all property types without mod have min and max 4953 return 0 > value ? 0 : type.max < value ? type.max : value; 4954} 4955 4956function stringParse( string ) { 4957 var inst = color(), 4958 rgba = inst._rgba = []; 4959 4960 string = string.toLowerCase(); 4961 4962 each( stringParsers, function( i, parser ) { 4963 var parsed, 4964 match = parser.re.exec( string ), 4965 values = match && parser.parse( match ), 4966 spaceName = parser.space || "rgba"; 4967 4968 if ( values ) { 4969 parsed = inst[ spaceName ]( values ); 4970 4971 // if this was an rgba parse the assignment might happen twice 4972 // oh well.... 4973 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4974 rgba = inst._rgba = parsed._rgba; 4975 4976 // exit each( stringParsers ) here because we matched 4977 return false; 4978 } 4979 }); 4980 4981 // Found a stringParser that handled it 4982 if ( rgba.length ) { 4983 4984 // if this came from a parsed string, force "transparent" when alpha is 0 4985 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4986 if ( rgba.join() === "0,0,0,0" ) { 4987 jQuery.extend( rgba, colors.transparent ); 4988 } 4989 return inst; 4990 } 4991 4992 // named colors 4993 return colors[ string ]; 4994} 4995 4996color.fn = jQuery.extend( color.prototype, { 4997 parse: function( red, green, blue, alpha ) { 4998 if ( red === undefined ) { 4999 this._rgba = [ null, null, null, null ]; 5000 return this; 5001 } 5002 if ( red.jquery || red.nodeType ) { 5003 red = jQuery( red ).css( green ); 5004 green = undefined; 5005 } 5006 5007 var inst = this, 5008 type = jQuery.type( red ), 5009 rgba = this._rgba = []; 5010 5011 // more than 1 argument specified - assume ( red, green, blue, alpha ) 5012 if ( green !== undefined ) { 5013 red = [ red, green, blue, alpha ]; 5014 type = "array"; 5015 } 5016 5017 if ( type === "string" ) { 5018 return this.parse( stringParse( red ) || colors._default ); 5019 } 5020 5021 if ( type === "array" ) { 5022 each( spaces.rgba.props, function( key, prop ) { 5023 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 5024 }); 5025 return this; 5026 } 5027 5028 if ( type === "object" ) { 5029 if ( red instanceof color ) { 5030 each( spaces, function( spaceName, space ) { 5031 if ( red[ space.cache ] ) { 5032 inst[ space.cache ] = red[ space.cache ].slice(); 5033 } 5034 }); 5035 } else { 5036 each( spaces, function( spaceName, space ) { 5037 var cache = space.cache; 5038 each( space.props, function( key, prop ) { 5039 5040 // if the cache doesn't exist, and we know how to convert 5041 if ( !inst[ cache ] && space.to ) { 5042 5043 // if the value was null, we don't need to copy it 5044 // if the key was alpha, we don't need to copy it either 5045 if ( key === "alpha" || red[ key ] == null ) { 5046 return; 5047 } 5048 inst[ cache ] = space.to( inst._rgba ); 5049 } 5050 5051 // this is the only case where we allow nulls for ALL properties. 5052 // call clamp with alwaysAllowEmpty 5053 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 5054 }); 5055 5056 // everything defined but alpha? 5057 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 5058 // use the default of 1 5059 inst[ cache ][ 3 ] = 1; 5060 if ( space.from ) { 5061 inst._rgba = space.from( inst[ cache ] ); 5062 } 5063 } 5064 }); 5065 } 5066 return this; 5067 } 5068 }, 5069 is: function( compare ) { 5070 var is = color( compare ), 5071 same = true, 5072 inst = this; 5073 5074 each( spaces, function( _, space ) { 5075 var localCache, 5076 isCache = is[ space.cache ]; 5077 if (isCache) { 5078 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 5079 each( space.props, function( _, prop ) { 5080 if ( isCache[ prop.idx ] != null ) { 5081 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 5082 return same; 5083 } 5084 }); 5085 } 5086 return same; 5087 }); 5088 return same; 5089 }, 5090 _space: function() { 5091 var used = [], 5092 inst = this; 5093 each( spaces, function( spaceName, space ) { 5094 if ( inst[ space.cache ] ) { 5095 used.push( spaceName ); 5096 } 5097 }); 5098 return used.pop(); 5099 }, 5100 transition: function( other, distance ) { 5101 var end = color( other ), 5102 spaceName = end._space(), 5103 space = spaces[ spaceName ], 5104 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 5105 start = startColor[ space.cache ] || space.to( startColor._rgba ), 5106 result = start.slice(); 5107 5108 end = end[ space.cache ]; 5109 each( space.props, function( key, prop ) { 5110 var index = prop.idx, 5111 startValue = start[ index ], 5112 endValue = end[ index ], 5113 type = propTypes[ prop.type ] || {}; 5114 5115 // if null, don't override start value 5116 if ( endValue === null ) { 5117 return; 5118 } 5119 // if null - use end 5120 if ( startValue === null ) { 5121 result[ index ] = endValue; 5122 } else { 5123 if ( type.mod ) { 5124 if ( endValue - startValue > type.mod / 2 ) { 5125 startValue += type.mod; 5126 } else if ( startValue - endValue > type.mod / 2 ) { 5127 startValue -= type.mod; 5128 } 5129 } 5130 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 5131 } 5132 }); 5133 return this[ spaceName ]( result ); 5134 }, 5135 blend: function( opaque ) { 5136 // if we are already opaque - return ourself 5137 if ( this._rgba[ 3 ] === 1 ) { 5138 return this; 5139 } 5140 5141 var rgb = this._rgba.slice(), 5142 a = rgb.pop(), 5143 blend = color( opaque )._rgba; 5144 5145 return color( jQuery.map( rgb, function( v, i ) { 5146 return ( 1 - a ) * blend[ i ] + a * v; 5147 })); 5148 }, 5149 toRgbaString: function() { 5150 var prefix = "rgba(", 5151 rgba = jQuery.map( this._rgba, function( v, i ) { 5152 return v == null ? ( i > 2 ? 1 : 0 ) : v; 5153 }); 5154 5155 if ( rgba[ 3 ] === 1 ) { 5156 rgba.pop(); 5157 prefix = "rgb("; 5158 } 5159 5160 return prefix + rgba.join() + ")"; 5161 }, 5162 toHslaString: function() { 5163 var prefix = "hsla(", 5164 hsla = jQuery.map( this.hsla(), function( v, i ) { 5165 if ( v == null ) { 5166 v = i > 2 ? 1 : 0; 5167 } 5168 5169 // catch 1 and 2 5170 if ( i && i < 3 ) { 5171 v = Math.round( v * 100 ) + "%"; 5172 } 5173 return v; 5174 }); 5175 5176 if ( hsla[ 3 ] === 1 ) { 5177 hsla.pop(); 5178 prefix = "hsl("; 5179 } 5180 return prefix + hsla.join() + ")"; 5181 }, 5182 toHexString: function( includeAlpha ) { 5183 var rgba = this._rgba.slice(), 5184 alpha = rgba.pop(); 5185 5186 if ( includeAlpha ) { 5187 rgba.push( ~~( alpha * 255 ) ); 5188 } 5189 5190 return "#" + jQuery.map( rgba, function( v ) { 5191 5192 // default to 0 when nulls exist 5193 v = ( v || 0 ).toString( 16 ); 5194 return v.length === 1 ? "0" + v : v; 5195 }).join(""); 5196 }, 5197 toString: function() { 5198 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 5199 } 5200}); 5201color.fn.parse.prototype = color.fn; 5202 5203// hsla conversions adapted from: 5204// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 5205 5206function hue2rgb( p, q, h ) { 5207 h = ( h + 1 ) % 1; 5208 if ( h * 6 < 1 ) { 5209 return p + (q - p) * h * 6; 5210 } 5211 if ( h * 2 < 1) { 5212 return q; 5213 } 5214 if ( h * 3 < 2 ) { 5215 return p + (q - p) * ((2/3) - h) * 6; 5216 } 5217 return p; 5218} 5219 5220spaces.hsla.to = function ( rgba ) { 5221 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 5222 return [ null, null, null, rgba[ 3 ] ]; 5223 } 5224 var r = rgba[ 0 ] / 255, 5225 g = rgba[ 1 ] / 255, 5226 b = rgba[ 2 ] / 255, 5227 a = rgba[ 3 ], 5228 max = Math.max( r, g, b ), 5229 min = Math.min( r, g, b ), 5230 diff = max - min, 5231 add = max + min, 5232 l = add * 0.5, 5233 h, s; 5234 5235 if ( min === max ) { 5236 h = 0; 5237 } else if ( r === max ) { 5238 h = ( 60 * ( g - b ) / diff ) + 360; 5239 } else if ( g === max ) { 5240 h = ( 60 * ( b - r ) / diff ) + 120; 5241 } else { 5242 h = ( 60 * ( r - g ) / diff ) + 240; 5243 } 5244 5245 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5246 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5247 if ( diff === 0 ) { 5248 s = 0; 5249 } else if ( l <= 0.5 ) { 5250 s = diff / add; 5251 } else { 5252 s = diff / ( 2 - add ); 5253 } 5254 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 5255}; 5256 5257spaces.hsla.from = function ( hsla ) { 5258 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5259 return [ null, null, null, hsla[ 3 ] ]; 5260 } 5261 var h = hsla[ 0 ] / 360, 5262 s = hsla[ 1 ], 5263 l = hsla[ 2 ], 5264 a = hsla[ 3 ], 5265 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5266 p = 2 * l - q; 5267 5268 return [ 5269 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5270 Math.round( hue2rgb( p, q, h ) * 255 ), 5271 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5272 a 5273 ]; 5274}; 5275 5276 5277each( spaces, function( spaceName, space ) { 5278 var props = space.props, 5279 cache = space.cache, 5280 to = space.to, 5281 from = space.from; 5282 5283 // makes rgba() and hsla() 5284 color.fn[ spaceName ] = function( value ) { 5285 5286 // generate a cache for this space if it doesn't exist 5287 if ( to && !this[ cache ] ) { 5288 this[ cache ] = to( this._rgba ); 5289 } 5290 if ( value === undefined ) { 5291 return this[ cache ].slice(); 5292 } 5293 5294 var ret, 5295 type = jQuery.type( value ), 5296 arr = ( type === "array" || type === "object" ) ? value : arguments, 5297 local = this[ cache ].slice(); 5298 5299 each( props, function( key, prop ) { 5300 var val = arr[ type === "object" ? key : prop.idx ]; 5301 if ( val == null ) { 5302 val = local[ prop.idx ]; 5303 } 5304 local[ prop.idx ] = clamp( val, prop ); 5305 }); 5306 5307 if ( from ) { 5308 ret = color( from( local ) ); 5309 ret[ cache ] = local; 5310 return ret; 5311 } else { 5312 return color( local ); 5313 } 5314 }; 5315 5316 // makes red() green() blue() alpha() hue() saturation() lightness() 5317 each( props, function( key, prop ) { 5318 // alpha is included in more than one space 5319 if ( color.fn[ key ] ) { 5320 return; 5321 } 5322 color.fn[ key ] = function( value ) { 5323 var vtype = jQuery.type( value ), 5324 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5325 local = this[ fn ](), 5326 cur = local[ prop.idx ], 5327 match; 5328 5329 if ( vtype === "undefined" ) { 5330 return cur; 5331 } 5332 5333 if ( vtype === "function" ) { 5334 value = value.call( this, cur ); 5335 vtype = jQuery.type( value ); 5336 } 5337 if ( value == null && prop.empty ) { 5338 return this; 5339 } 5340 if ( vtype === "string" ) { 5341 match = rplusequals.exec( value ); 5342 if ( match ) { 5343 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5344 } 5345 } 5346 local[ prop.idx ] = value; 5347 return this[ fn ]( local ); 5348 }; 5349 }); 5350}); 5351 5352// add cssHook and .fx.step function for each named hook. 5353// accept a space separated string of properties 5354color.hook = function( hook ) { 5355 var hooks = hook.split( " " ); 5356 each( hooks, function( i, hook ) { 5357 jQuery.cssHooks[ hook ] = { 5358 set: function( elem, value ) { 5359 var parsed, curElem, 5360 backgroundColor = ""; 5361 5362 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 5363 value = color( parsed || value ); 5364 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5365 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5366 while ( 5367 (backgroundColor === "" || backgroundColor === "transparent") && 5368 curElem && curElem.style 5369 ) { 5370 try { 5371 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5372 curElem = curElem.parentNode; 5373 } catch ( e ) { 5374 } 5375 } 5376 5377 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5378 backgroundColor : 5379 "_default" ); 5380 } 5381 5382 value = value.toRgbaString(); 5383 } 5384 try { 5385 elem.style[ hook ] = value; 5386 } catch( e ) { 5387 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 5388 } 5389 } 5390 }; 5391 jQuery.fx.step[ hook ] = function( fx ) { 5392 if ( !fx.colorInit ) { 5393 fx.start = color( fx.elem, hook ); 5394 fx.end = color( fx.end ); 5395 fx.colorInit = true; 5396 } 5397 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5398 }; 5399 }); 5400 5401}; 5402 5403color.hook( stepHooks ); 5404 5405jQuery.cssHooks.borderColor = { 5406 expand: function( value ) { 5407 var expanded = {}; 5408 5409 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5410 expanded[ "border" + part + "Color" ] = value; 5411 }); 5412 return expanded; 5413 } 5414}; 5415 5416// Basic color names only. 5417// Usage of any of the other color names requires adding yourself or including 5418// jquery.color.svg-names.js. 5419colors = jQuery.Color.names = { 5420 // 4.1. Basic color keywords 5421 aqua: "#00ffff", 5422 black: "#000000", 5423 blue: "#0000ff", 5424 fuchsia: "#ff00ff", 5425 gray: "#808080", 5426 green: "#008000", 5427 lime: "#00ff00", 5428 maroon: "#800000", 5429 navy: "#000080", 5430 olive: "#808000", 5431 purple: "#800080", 5432 red: "#ff0000", 5433 silver: "#c0c0c0", 5434 teal: "#008080", 5435 white: "#ffffff", 5436 yellow: "#ffff00", 5437 5438 // 4.2.3. "transparent" color keyword 5439 transparent: [ null, null, null, 0 ], 5440 5441 _default: "#ffffff" 5442}; 5443 5444})( jQuery ); 5445 5446 5447/******************************************************************************/ 5448/****************************** CLASS ANIMATIONS ******************************/ 5449/******************************************************************************/ 5450(function() { 5451 5452var classAnimationActions = [ "add", "remove", "toggle" ], 5453 shorthandStyles = { 5454 border: 1, 5455 borderBottom: 1, 5456 borderColor: 1, 5457 borderLeft: 1, 5458 borderRight: 1, 5459 borderTop: 1, 5460 borderWidth: 1, 5461 margin: 1, 5462 padding: 1 5463 }; 5464 5465$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 5466 $.fx.step[ prop ] = function( fx ) { 5467 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5468 jQuery.style( fx.elem, prop, fx.end ); 5469 fx.setAttr = true; 5470 } 5471 }; 5472}); 5473 5474function getElementStyles( elem ) { 5475 var key, len, 5476 style = elem.ownerDocument.defaultView ? 5477 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5478 elem.currentStyle, 5479 styles = {}; 5480 5481 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5482 len = style.length; 5483 while ( len-- ) { 5484 key = style[ len ]; 5485 if ( typeof style[ key ] === "string" ) { 5486 styles[ $.camelCase( key ) ] = style[ key ]; 5487 } 5488 } 5489 // support: Opera, IE <9 5490 } else { 5491 for ( key in style ) { 5492 if ( typeof style[ key ] === "string" ) { 5493 styles[ key ] = style[ key ]; 5494 } 5495 } 5496 } 5497 5498 return styles; 5499} 5500 5501 5502function styleDifference( oldStyle, newStyle ) { 5503 var diff = {}, 5504 name, value; 5505 5506 for ( name in newStyle ) { 5507 value = newStyle[ name ]; 5508 if ( oldStyle[ name ] !== value ) { 5509 if ( !shorthandStyles[ name ] ) { 5510 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5511 diff[ name ] = value; 5512 } 5513 } 5514 } 5515 } 5516 5517 return diff; 5518} 5519 5520// support: jQuery <1.8 5521if ( !$.fn.addBack ) { 5522 $.fn.addBack = function( selector ) { 5523 return this.add( selector == null ? 5524 this.prevObject : this.prevObject.filter( selector ) 5525 ); 5526 }; 5527} 5528 5529$.effects.animateClass = function( value, duration, easing, callback ) { 5530 var o = $.speed( duration, easing, callback ); 5531 5532 return this.queue( function() { 5533 var animated = $( this ), 5534 baseClass = animated.attr( "class" ) || "", 5535 applyClassChange, 5536 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5537 5538 // map the animated objects to store the original styles. 5539 allAnimations = allAnimations.map(function() { 5540 var el = $( this ); 5541 return { 5542 el: el, 5543 start: getElementStyles( this ) 5544 }; 5545 }); 5546 5547 // apply class change 5548 applyClassChange = function() { 5549 $.each( classAnimationActions, function(i, action) { 5550 if ( value[ action ] ) { 5551 animated[ action + "Class" ]( value[ action ] ); 5552 } 5553 }); 5554 }; 5555 applyClassChange(); 5556 5557 // map all animated objects again - calculate new styles and diff 5558 allAnimations = allAnimations.map(function() { 5559 this.end = getElementStyles( this.el[ 0 ] ); 5560 this.diff = styleDifference( this.start, this.end ); 5561 return this; 5562 }); 5563 5564 // apply original class 5565 animated.attr( "class", baseClass ); 5566 5567 // map all animated objects again - this time collecting a promise 5568 allAnimations = allAnimations.map(function() { 5569 var styleInfo = this, 5570 dfd = $.Deferred(), 5571 opts = $.extend({}, o, { 5572 queue: false, 5573 complete: function() { 5574 dfd.resolve( styleInfo ); 5575 } 5576 }); 5577 5578 this.el.animate( this.diff, opts ); 5579 return dfd.promise(); 5580 }); 5581 5582 // once all animations have completed: 5583 $.when.apply( $, allAnimations.get() ).done(function() { 5584 5585 // set the final class 5586 applyClassChange(); 5587 5588 // for each animated element, 5589 // clear all css properties that were animated 5590 $.each( arguments, function() { 5591 var el = this.el; 5592 $.each( this.diff, function(key) { 5593 el.css( key, "" ); 5594 }); 5595 }); 5596 5597 // this is guarnteed to be there if you use jQuery.speed() 5598 // it also handles dequeuing the next anim... 5599 o.complete.call( animated[ 0 ] ); 5600 }); 5601 }); 5602}; 5603 5604$.fn.extend({ 5605 addClass: (function( orig ) { 5606 return function( classNames, speed, easing, callback ) { 5607 return speed ? 5608 $.effects.animateClass.call( this, 5609 { add: classNames }, speed, easing, callback ) : 5610 orig.apply( this, arguments ); 5611 }; 5612 })( $.fn.addClass ), 5613 5614 removeClass: (function( orig ) { 5615 return function( classNames, speed, easing, callback ) { 5616 return arguments.length > 1 ? 5617 $.effects.animateClass.call( this, 5618 { remove: classNames }, speed, easing, callback ) : 5619 orig.apply( this, arguments ); 5620 }; 5621 })( $.fn.removeClass ), 5622 5623 toggleClass: (function( orig ) { 5624 return function( classNames, force, speed, easing, callback ) { 5625 if ( typeof force === "boolean" || force === undefined ) { 5626 if ( !speed ) { 5627 // without speed parameter 5628 return orig.apply( this, arguments ); 5629 } else { 5630 return $.effects.animateClass.call( this, 5631 (force ? { add: classNames } : { remove: classNames }), 5632 speed, easing, callback ); 5633 } 5634 } else { 5635 // without force parameter 5636 return $.effects.animateClass.call( this, 5637 { toggle: classNames }, force, speed, easing ); 5638 } 5639 }; 5640 })( $.fn.toggleClass ), 5641 5642 switchClass: function( remove, add, speed, easing, callback) { 5643 return $.effects.animateClass.call( this, { 5644 add: add, 5645 remove: remove 5646 }, speed, easing, callback ); 5647 } 5648}); 5649 5650})(); 5651 5652/******************************************************************************/ 5653/*********************************** EFFECTS **********************************/ 5654/******************************************************************************/ 5655 5656(function() { 5657 5658$.extend( $.effects, { 5659 version: "1.10.3", 5660 5661 // Saves a set of properties in a data storage 5662 save: function( element, set ) { 5663 for( var i=0; i < set.length; i++ ) { 5664 if ( set[ i ] !== null ) { 5665 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5666 } 5667 } 5668 }, 5669 5670 // Restores a set of previously saved properties from a data storage 5671 restore: function( element, set ) { 5672 var val, i; 5673 for( i=0; i < set.length; i++ ) { 5674 if ( set[ i ] !== null ) { 5675 val = element.data( dataSpace + set[ i ] ); 5676 // support: jQuery 1.6.2 5677 // http://bugs.jquery.com/ticket/9917 5678 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5679 // We can't differentiate between "" and 0 here, so we just assume 5680 // empty string since it's likely to be a more common value... 5681 if ( val === undefined ) { 5682 val = ""; 5683 } 5684 element.css( set[ i ], val ); 5685 } 5686 } 5687 }, 5688 5689 setMode: function( el, mode ) { 5690 if (mode === "toggle") { 5691 mode = el.is( ":hidden" ) ? "show" : "hide"; 5692 } 5693 return mode; 5694 }, 5695 5696 // Translates a [top,left] array into a baseline value 5697 // this should be a little more flexible in the future to handle a string & hash 5698 getBaseline: function( origin, original ) { 5699 var y, x; 5700 switch ( origin[ 0 ] ) { 5701 case "top": y = 0; break; 5702 case "middle": y = 0.5; break; 5703 case "bottom": y = 1; break; 5704 default: y = origin[ 0 ] / original.height; 5705 } 5706 switch ( origin[ 1 ] ) { 5707 case "left": x = 0; break; 5708 case "center": x = 0.5; break; 5709 case "right": x = 1; break; 5710 default: x = origin[ 1 ] / original.width; 5711 } 5712 return { 5713 x: x, 5714 y: y 5715 }; 5716 }, 5717 5718 // Wraps the element around a wrapper that copies position properties 5719 createWrapper: function( element ) { 5720 5721 // if the element is already wrapped, return it 5722 if ( element.parent().is( ".ui-effects-wrapper" )) { 5723 return element.parent(); 5724 } 5725 5726 // wrap the element 5727 var props = { 5728 width: element.outerWidth(true), 5729 height: element.outerHeight(true), 5730 "float": element.css( "float" ) 5731 }, 5732 wrapper = $( "<div></div>" ) 5733 .addClass( "ui-effects-wrapper" ) 5734 .css({ 5735 fontSize: "100%", 5736 background: "transparent", 5737 border: "none", 5738 margin: 0, 5739 padding: 0 5740 }), 5741 // Store the size in case width/height are defined in % - Fixes #5245 5742 size = { 5743 width: element.width(), 5744 height: element.height() 5745 }, 5746 active = document.activeElement; 5747 5748 // support: Firefox 5749 // Firefox incorrectly exposes anonymous content 5750 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5751 try { 5752 active.id; 5753 } catch( e ) { 5754 active = document.body; 5755 } 5756 5757 element.wrap( wrapper ); 5758 5759 // Fixes #7595 - Elements lose focus when wrapped. 5760 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5761 $( active ).focus(); 5762 } 5763 5764 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5765 5766 // transfer positioning properties to the wrapper 5767 if ( element.css( "position" ) === "static" ) { 5768 wrapper.css({ position: "relative" }); 5769 element.css({ position: "relative" }); 5770 } else { 5771 $.extend( props, { 5772 position: element.css( "position" ), 5773 zIndex: element.css( "z-index" ) 5774 }); 5775 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5776 props[ pos ] = element.css( pos ); 5777 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5778 props[ pos ] = "auto"; 5779 } 5780 }); 5781 element.css({ 5782 position: "relative", 5783 top: 0, 5784 left: 0, 5785 right: "auto", 5786 bottom: "auto" 5787 }); 5788 } 5789 element.css(size); 5790 5791 return wrapper.css( props ).show(); 5792 }, 5793 5794 removeWrapper: function( element ) { 5795 var active = document.activeElement; 5796 5797 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5798 element.parent().replaceWith( element ); 5799 5800 // Fixes #7595 - Elements lose focus when wrapped. 5801 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5802 $( active ).focus(); 5803 } 5804 } 5805 5806 5807 return element; 5808 }, 5809 5810 setTransition: function( element, list, factor, value ) { 5811 value = value || {}; 5812 $.each( list, function( i, x ) { 5813 var unit = element.cssUnit( x ); 5814 if ( unit[ 0 ] > 0 ) { 5815 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5816 } 5817 }); 5818 return value; 5819 } 5820}); 5821 5822// return an effect options object for the given parameters: 5823function _normalizeArguments( effect, options, speed, callback ) { 5824 5825 // allow passing all options as the first parameter 5826 if ( $.isPlainObject( effect ) ) { 5827 options = effect; 5828 effect = effect.effect; 5829 } 5830 5831 // convert to an object 5832 effect = { effect: effect }; 5833 5834 // catch (effect, null, ...) 5835 if ( options == null ) { 5836 options = {}; 5837 } 5838 5839 // catch (effect, callback) 5840 if ( $.isFunction( options ) ) { 5841 callback = options; 5842 speed = null; 5843 options = {}; 5844 } 5845 5846 // catch (effect, speed, ?) 5847 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5848 callback = speed; 5849 speed = options; 5850 options = {}; 5851 } 5852 5853 // catch (effect, options, callback) 5854 if ( $.isFunction( speed ) ) { 5855 callback = speed; 5856 speed = null; 5857 } 5858 5859 // add options to effect 5860 if ( options ) { 5861 $.extend( effect, options ); 5862 } 5863 5864 speed = speed || options.duration; 5865 effect.duration = $.fx.off ? 0 : 5866 typeof speed === "number" ? speed : 5867 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5868 $.fx.speeds._default; 5869 5870 effect.complete = callback || options.complete; 5871 5872 return effect; 5873} 5874 5875function standardAnimationOption( option ) { 5876 // Valid standard speeds (nothing, number, named speed) 5877 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 5878 return true; 5879 } 5880 5881 // Invalid strings - treat as "normal" speed 5882 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 5883 return true; 5884 } 5885 5886 // Complete callback 5887 if ( $.isFunction( option ) ) { 5888 return true; 5889 } 5890 5891 // Options hash (but not naming an effect) 5892 if ( typeof option === "object" && !option.effect ) { 5893 return true; 5894 } 5895 5896 // Didn't match any standard API 5897 return false; 5898} 5899 5900$.fn.extend({ 5901 effect: function( /* effect, options, speed, callback */ ) { 5902 var args = _normalizeArguments.apply( this, arguments ), 5903 mode = args.mode, 5904 queue = args.queue, 5905 effectMethod = $.effects.effect[ args.effect ]; 5906 5907 if ( $.fx.off || !effectMethod ) { 5908 // delegate to the original method (e.g., .show()) if possible 5909 if ( mode ) { 5910 return this[ mode ]( args.duration, args.complete ); 5911 } else { 5912 return this.each( function() { 5913 if ( args.complete ) { 5914 args.complete.call( this ); 5915 } 5916 }); 5917 } 5918 } 5919 5920 function run( next ) { 5921 var elem = $( this ), 5922 complete = args.complete, 5923 mode = args.mode; 5924 5925 function done() { 5926 if ( $.isFunction( complete ) ) { 5927 complete.call( elem[0] ); 5928 } 5929 if ( $.isFunction( next ) ) { 5930 next(); 5931 } 5932 } 5933 5934 // If the element already has the correct final state, delegate to 5935 // the core methods so the internal tracking of "olddisplay" works. 5936 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5937 elem[ mode ](); 5938 done(); 5939 } else { 5940 effectMethod.call( elem[0], args, done ); 5941 } 5942 } 5943 5944 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5945 }, 5946 5947 show: (function( orig ) { 5948 return function( option ) { 5949 if ( standardAnimationOption( option ) ) { 5950 return orig.apply( this, arguments ); 5951 } else { 5952 var args = _normalizeArguments.apply( this, arguments ); 5953 args.mode = "show"; 5954 return this.effect.call( this, args ); 5955 } 5956 }; 5957 })( $.fn.show ), 5958 5959 hide: (function( orig ) { 5960 return function( option ) { 5961 if ( standardAnimationOption( option ) ) { 5962 return orig.apply( this, arguments ); 5963 } else { 5964 var args = _normalizeArguments.apply( this, arguments ); 5965 args.mode = "hide"; 5966 return this.effect.call( this, args ); 5967 } 5968 }; 5969 })( $.fn.hide ), 5970 5971 toggle: (function( orig ) { 5972 return function( option ) { 5973 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 5974 return orig.apply( this, arguments ); 5975 } else { 5976 var args = _normalizeArguments.apply( this, arguments ); 5977 args.mode = "toggle"; 5978 return this.effect.call( this, args ); 5979 } 5980 }; 5981 })( $.fn.toggle ), 5982 5983 // helper functions 5984 cssUnit: function(key) { 5985 var style = this.css( key ), 5986 val = []; 5987 5988 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5989 if ( style.indexOf( unit ) > 0 ) { 5990 val = [ parseFloat( style ), unit ]; 5991 } 5992 }); 5993 return val; 5994 } 5995}); 5996 5997})(); 5998 5999/******************************************************************************/ 6000/*********************************** EASING ***********************************/ 6001/******************************************************************************/ 6002 6003(function() { 6004 6005// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 6006 6007var baseEasings = {}; 6008 6009$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 6010 baseEasings[ name ] = function( p ) { 6011 return Math.pow( p, i + 2 ); 6012 }; 6013}); 6014 6015$.extend( baseEasings, { 6016 Sine: function ( p ) { 6017 return 1 - Math.cos( p * Math.PI / 2 ); 6018 }, 6019 Circ: function ( p ) { 6020 return 1 - Math.sqrt( 1 - p * p ); 6021 }, 6022 Elastic: function( p ) { 6023 return p === 0 || p === 1 ? p : 6024 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 6025 }, 6026 Back: function( p ) { 6027 return p * p * ( 3 * p - 2 ); 6028 }, 6029 Bounce: function ( p ) { 6030 var pow2, 6031 bounce = 4; 6032 6033 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 6034 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 6035 } 6036}); 6037 6038$.each( baseEasings, function( name, easeIn ) { 6039 $.easing[ "easeIn" + name ] = easeIn; 6040 $.easing[ "easeOut" + name ] = function( p ) { 6041 return 1 - easeIn( 1 - p ); 6042 }; 6043 $.easing[ "easeInOut" + name ] = function( p ) { 6044 return p < 0.5 ? 6045 easeIn( p * 2 ) / 2 : 6046 1 - easeIn( p * -2 + 2 ) / 2; 6047 }; 6048}); 6049 6050})(); 6051 6052})(jQuery); 6053 6054(function( $, undefined ) { 6055 6056var uid = 0, 6057 hideProps = {}, 6058 showProps = {}; 6059 6060hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 6061 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 6062showProps.height = showProps.paddingTop = showProps.paddingBottom = 6063 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 6064 6065$.widget( "ui.accordion", { 6066 version: "1.10.3", 6067 options: { 6068 active: 0, 6069 animated: {}, 6070 collapsible: false, 6071 event: "click", 6072 header: "> li > :first-child,> :not(li):even", 6073 heightStyle: "auto", 6074 icons: { 6075 activeHeader: "ui-icon-triangle-1-s", 6076 header: "ui-icon-triangle-1-e" 6077 }, 6078 6079 // callbacks 6080 activate: null, 6081 beforeActivate: null 6082 }, 6083 6084 _create: function() { 6085 var options = this.options; 6086 this.prevShow = this.prevHide = $(); 6087 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 6088 // ARIA 6089 .attr( "role", "tablist" ); 6090 6091 // don't allow collapsible: false and active: false / null 6092 if ( !options.collapsible && (options.active === false || options.active == null) ) { 6093 options.active = 0; 6094 } 6095 6096 this._processPanels(); 6097 // handle negative values 6098 if ( options.active < 0 ) { 6099 options.active += this.headers.length; 6100 } 6101 this._refresh(); 6102 }, 6103 6104 _getCreateEventData: function() { 6105 return { 6106 header: this.active, 6107 panel: !this.active.length ? $() : this.active.next(), 6108 content: !this.active.length ? $() : this.active.next() 6109 }; 6110 }, 6111 6112 _createIcons: function() { 6113 var icons = this.options.icons; 6114 if ( icons ) { 6115 $( "<span>" ) 6116 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 6117 .prependTo( this.headers ); 6118 this.active.children( ".ui-accordion-header-icon" ) 6119 .removeClass( icons.header ) 6120 .addClass( icons.activeHeader ); 6121 this.headers.addClass( "ui-accordion-icons" ); 6122 } 6123 }, 6124 6125 _destroyIcons: function() { 6126 this.headers 6127 .removeClass( "ui-accordion-icons" ) 6128 .children( ".ui-accordion-header-icon" ) 6129 .remove(); 6130 }, 6131 6132 _destroy: function() { 6133 var contents; 6134 6135 // clean up main element 6136 this.element 6137 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 6138 .removeAttr( "role" ); 6139 6140 // clean up headers 6141 this.headers 6142 .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" ) 6143 .removeAttr( "role" ) 6144 .removeAttr( "aria-selected" ) 6145 .removeAttr( "aria-controls" ) 6146 .removeAttr( "tabIndex" ) 6147 .each(function() { 6148 if ( /^ui-accordion/.test( this.id ) ) { 6149 this.removeAttribute( "id" ); 6150 } 6151 }); 6152 this._destroyIcons(); 6153 6154 // clean up content panels 6155 contents = this.headers.next() 6156 .css( "display", "" ) 6157 .removeAttr( "role" ) 6158 .removeAttr( "aria-expanded" ) 6159 .removeAttr( "aria-hidden" ) 6160 .removeAttr( "aria-labelledby" ) 6161 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 6162 .each(function() { 6163 if ( /^ui-accordion/.test( this.id ) ) { 6164 this.removeAttribute( "id" ); 6165 } 6166 }); 6167 if ( this.options.heightStyle !== "content" ) { 6168 contents.css( "height", "" ); 6169 } 6170 }, 6171 6172 _setOption: function( key, value ) { 6173 if ( key === "active" ) { 6174 // _activate() will handle invalid values and update this.options 6175 this._activate( value ); 6176 return; 6177 } 6178 6179 if ( key === "event" ) { 6180 if ( this.options.event ) { 6181 this._off( this.headers, this.options.event ); 6182 } 6183 this._setupEvents( value ); 6184 } 6185 6186 this._super( key, value ); 6187 6188 // setting collapsible: false while collapsed; open first panel 6189 if ( key === "collapsible" && !value && this.options.active === false ) { 6190 this._activate( 0 ); 6191 } 6192 6193 if ( key === "icons" ) { 6194 this._destroyIcons(); 6195 if ( value ) { 6196 this._createIcons(); 6197 } 6198 } 6199 6200 // #5332 - opacity doesn't cascade to positioned elements in IE 6201 // so we need to add the disabled class to the headers and panels 6202 if ( key === "disabled" ) { 6203 this.headers.add( this.headers.next() ) 6204 .toggleClass( "ui-state-disabled", !!value ); 6205 } 6206 }, 6207 6208 _keydown: function( event ) { 6209 /*jshint maxcomplexity:15*/ 6210 if ( event.altKey || event.ctrlKey ) { 6211 return; 6212 } 6213 6214 var keyCode = $.ui.keyCode, 6215 length = this.headers.length, 6216 currentIndex = this.headers.index( event.target ), 6217 toFocus = false; 6218 6219 switch ( event.keyCode ) { 6220 case keyCode.RIGHT: 6221 case keyCode.DOWN: 6222 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6223 break; 6224 case keyCode.LEFT: 6225 case keyCode.UP: 6226 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6227 break; 6228 case keyCode.SPACE: 6229 case keyCode.ENTER: 6230 this._eventHandler( event ); 6231 break; 6232 case keyCode.HOME: 6233 toFocus = this.headers[ 0 ]; 6234 break; 6235 case keyCode.END: 6236 toFocus = this.headers[ length - 1 ]; 6237 break; 6238 } 6239 6240 if ( toFocus ) { 6241 $( event.target ).attr( "tabIndex", -1 ); 6242 $( toFocus ).attr( "tabIndex", 0 ); 6243 toFocus.focus(); 6244 event.preventDefault(); 6245 } 6246 }, 6247 6248 _panelKeyDown : function( event ) { 6249 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6250 $( event.currentTarget ).prev().focus(); 6251 } 6252 }, 6253 6254 refresh: function() { 6255 var options = this.options; 6256 this._processPanels(); 6257 6258 // was collapsed or no panel 6259 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6260 options.active = false; 6261 this.active = $(); 6262 // active false only when collapsible is true 6263 } else if ( options.active === false ) { 6264 this._activate( 0 ); 6265 // was active, but active panel is gone 6266 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6267 // all remaining panel are disabled 6268 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6269 options.active = false; 6270 this.active = $(); 6271 // activate previous panel 6272 } else { 6273 this._activate( Math.max( 0, options.active - 1 ) ); 6274 } 6275 // was active, active panel still exists 6276 } else { 6277 // make sure active index is correct 6278 options.active = this.headers.index( this.active ); 6279 } 6280 6281 this._destroyIcons(); 6282 6283 this._refresh(); 6284 }, 6285 6286 _processPanels: function() { 6287 this.headers = this.element.find( this.options.header ) 6288 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 6289 6290 this.headers.next() 6291 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6292 .filter(":not(.ui-accordion-content-active)") 6293 .hide(); 6294 }, 6295 6296 _refresh: function() { 6297 var maxHeight, 6298 options = this.options, 6299 heightStyle = options.heightStyle, 6300 parent = this.element.parent(), 6301 accordionId = this.accordionId = "ui-accordion-" + 6302 (this.element.attr( "id" ) || ++uid); 6303 6304 this.active = this._findActive( options.active ) 6305 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6306 .removeClass( "ui-corner-all" ); 6307 this.active.next() 6308 .addClass( "ui-accordion-content-active" ) 6309 .show(); 6310 6311 this.headers 6312 .attr( "role", "tab" ) 6313 .each(function( i ) { 6314 var header = $( this ), 6315 headerId = header.attr( "id" ), 6316 panel = header.next(), 6317 panelId = panel.attr( "id" ); 6318 if ( !headerId ) { 6319 headerId = accordionId + "-header-" + i; 6320 header.attr( "id", headerId ); 6321 } 6322 if ( !panelId ) { 6323 panelId = accordionId + "-panel-" + i; 6324 panel.attr( "id", panelId ); 6325 } 6326 header.attr( "aria-controls", panelId ); 6327 panel.attr( "aria-labelledby", headerId ); 6328 }) 6329 .next() 6330 .attr( "role", "tabpanel" ); 6331 6332 this.headers 6333 .not( this.active ) 6334 .attr({ 6335 "aria-selected": "false", 6336 tabIndex: -1 6337 }) 6338 .next() 6339 .attr({ 6340 "aria-expanded": "false", 6341 "aria-hidden": "true" 6342 }) 6343 .hide(); 6344 6345 // make sure at least one header is in the tab order 6346 if ( !this.active.length ) { 6347 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6348 } else { 6349 this.active.attr({ 6350 "aria-selected": "true", 6351 tabIndex: 0 6352 }) 6353 .next() 6354 .attr({ 6355 "aria-expanded": "true", 6356 "aria-hidden": "false" 6357 }); 6358 } 6359 6360 this._createIcons(); 6361 6362 this._setupEvents( options.event ); 6363 6364 if ( heightStyle === "fill" ) { 6365 maxHeight = parent.height(); 6366 this.element.siblings( ":visible" ).each(function() { 6367 var elem = $( this ), 6368 position = elem.css( "position" ); 6369 6370 if ( position === "absolute" || position === "fixed" ) { 6371 return; 6372 } 6373 maxHeight -= elem.outerHeight( true ); 6374 }); 6375 6376 this.headers.each(function() { 6377 maxHeight -= $( this ).outerHeight( true ); 6378 }); 6379 6380 this.headers.next() 6381 .each(function() { 6382 $( this ).height( Math.max( 0, maxHeight - 6383 $( this ).innerHeight() + $( this ).height() ) ); 6384 }) 6385 .css( "overflow", "auto" ); 6386 } else if ( heightStyle === "auto" ) { 6387 maxHeight = 0; 6388 this.headers.next() 6389 .each(function() { 6390 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6391 }) 6392 .height( maxHeight ); 6393 } 6394 }, 6395 6396 _activate: function( index ) { 6397 var active = this._findActive( index )[ 0 ]; 6398 6399 // trying to activate the already active panel 6400 if ( active === this.active[ 0 ] ) { 6401 return; 6402 } 6403 6404 // trying to collapse, simulate a click on the currently active header 6405 active = active || this.active[ 0 ]; 6406 6407 this._eventHandler({ 6408 target: active, 6409 currentTarget: active, 6410 preventDefault: $.noop 6411 }); 6412 }, 6413 6414 _findActive: function( selector ) { 6415 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6416 }, 6417 6418 _setupEvents: function( event ) { 6419 var events = { 6420 keydown: "_keydown" 6421 }; 6422 if ( event ) { 6423 $.each( event.split(" "), function( index, eventName ) { 6424 events[ eventName ] = "_eventHandler"; 6425 }); 6426 } 6427 6428 this._off( this.headers.add( this.headers.next() ) ); 6429 this._on( this.headers, events ); 6430 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6431 this._hoverable( this.headers ); 6432 this._focusable( this.headers ); 6433 }, 6434 6435 _eventHandler: function( event ) { 6436 var options = this.options, 6437 active = this.active, 6438 clicked = $( event.currentTarget ), 6439 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6440 collapsing = clickedIsActive && options.collapsible, 6441 toShow = collapsing ? $() : clicked.next(), 6442 toHide = active.next(), 6443 eventData = { 6444 oldHeader: active, 6445 oldPanel: toHide, 6446 newHeader: collapsing ? $() : clicked, 6447 newPanel: toShow 6448 }; 6449 6450 event.preventDefault(); 6451 6452 if ( 6453 // click on active header, but not collapsible 6454 ( clickedIsActive && !options.collapsible ) || 6455 // allow canceling activation 6456 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6457 return; 6458 } 6459 6460 options.active = collapsing ? false : this.headers.index( clicked ); 6461 6462 // when the call to ._toggle() comes after the class changes 6463 // it causes a very odd bug in IE 8 (see #6720) 6464 this.active = clickedIsActive ? $() : clicked; 6465 this._toggle( eventData ); 6466 6467 // switch classes 6468 // corner classes on the previously active header stay after the animation 6469 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6470 if ( options.icons ) { 6471 active.children( ".ui-accordion-header-icon" ) 6472 .removeClass( options.icons.activeHeader ) 6473 .addClass( options.icons.header ); 6474 } 6475 6476 if ( !clickedIsActive ) { 6477 clicked 6478 .removeClass( "ui-corner-all" ) 6479 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6480 if ( options.icons ) { 6481 clicked.children( ".ui-accordion-header-icon" ) 6482 .removeClass( options.icons.header ) 6483 .addClass( options.icons.activeHeader ); 6484 } 6485 6486 clicked 6487 .next() 6488 .addClass( "ui-accordion-content-active" ); 6489 } 6490 }, 6491 6492 _toggle: function( data ) { 6493 var toShow = data.newPanel, 6494 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6495 6496 // handle activating a panel during the animation for another activation 6497 this.prevShow.add( this.prevHide ).stop( true, true ); 6498 this.prevShow = toShow; 6499 this.prevHide = toHide; 6500 6501 if ( this.options.animate ) { 6502 this._animate( toShow, toHide, data ); 6503 } else { 6504 toHide.hide(); 6505 toShow.show(); 6506 this._toggleComplete( data ); 6507 } 6508 6509 toHide.attr({ 6510 "aria-expanded": "false", 6511 "aria-hidden": "true" 6512 }); 6513 toHide.prev().attr( "aria-selected", "false" ); 6514 // if we're switching panels, remove the old header from the tab order 6515 // if we're opening from collapsed state, remove the previous header from the tab order 6516 // if we're collapsing, then keep the collapsing header in the tab order 6517 if ( toShow.length && toHide.length ) { 6518 toHide.prev().attr( "tabIndex", -1 ); 6519 } else if ( toShow.length ) { 6520 this.headers.filter(function() { 6521 return $( this ).attr( "tabIndex" ) === 0; 6522 }) 6523 .attr( "tabIndex", -1 ); 6524 } 6525 6526 toShow 6527 .attr({ 6528 "aria-expanded": "true", 6529 "aria-hidden": "false" 6530 }) 6531 .prev() 6532 .attr({ 6533 "aria-selected": "true", 6534 tabIndex: 0 6535 }); 6536 }, 6537 6538 _animate: function( toShow, toHide, data ) { 6539 var total, easing, duration, 6540 that = this, 6541 adjust = 0, 6542 down = toShow.length && 6543 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6544 animate = this.options.animate || {}, 6545 options = down && animate.down || animate, 6546 complete = function() { 6547 that._toggleComplete( data ); 6548 }; 6549 6550 if ( typeof options === "number" ) { 6551 duration = options; 6552 } 6553 if ( typeof options === "string" ) { 6554 easing = options; 6555 } 6556 // fall back from options to animation in case of partial down settings 6557 easing = easing || options.easing || animate.easing; 6558 duration = duration || options.duration || animate.duration; 6559 6560 if ( !toHide.length ) { 6561 return toShow.animate( showProps, duration, easing, complete ); 6562 } 6563 if ( !toShow.length ) { 6564 return toHide.animate( hideProps, duration, easing, complete ); 6565 } 6566 6567 total = toShow.show().outerHeight(); 6568 toHide.animate( hideProps, { 6569 duration: duration, 6570 easing: easing, 6571 step: function( now, fx ) { 6572 fx.now = Math.round( now ); 6573 } 6574 }); 6575 toShow 6576 .hide() 6577 .animate( showProps, { 6578 duration: duration, 6579 easing: easing, 6580 complete: complete, 6581 step: function( now, fx ) { 6582 fx.now = Math.round( now ); 6583 if ( fx.prop !== "height" ) { 6584 adjust += fx.now; 6585 } else if ( that.options.heightStyle !== "content" ) { 6586 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6587 adjust = 0; 6588 } 6589 } 6590 }); 6591 }, 6592 6593 _toggleComplete: function( data ) { 6594 var toHide = data.oldPanel; 6595 6596 toHide 6597 .removeClass( "ui-accordion-content-active" ) 6598 .prev() 6599 .removeClass( "ui-corner-top" ) 6600 .addClass( "ui-corner-all" ); 6601 6602 // Work around for rendering bug in IE (#5421) 6603 if ( toHide.length ) { 6604 toHide.parent()[0].className = toHide.parent()[0].className; 6605 } 6606 6607 this._trigger( "activate", null, data ); 6608 } 6609}); 6610 6611})( jQuery ); 6612 6613(function( $, undefined ) { 6614 6615// used to prevent race conditions with remote data sources 6616var requestIndex = 0; 6617 6618$.widget( "ui.autocomplete", { 6619 version: "1.10.3", 6620 defaultElement: "<input>", 6621 options: { 6622 appendTo: null, 6623 autoFocus: false, 6624 delay: 300, 6625 minLength: 1, 6626 position: { 6627 my: "left top", 6628 at: "left bottom", 6629 collision: "none" 6630 }, 6631 source: null, 6632 6633 // callbacks 6634 change: null, 6635 close: null, 6636 focus: null, 6637 open: null, 6638 response: null, 6639 search: null, 6640 select: null 6641 }, 6642 6643 pending: 0, 6644 6645 _create: function() { 6646 // Some browsers only repeat keydown events, not keypress events, 6647 // so we use the suppressKeyPress flag to determine if we've already 6648 // handled the keydown event. #7269 6649 // Unfortunately the code for & in keypress is the same as the up arrow, 6650 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6651 // events when we know the keydown event was used to modify the 6652 // search term. #7799 6653 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6654 nodeName = this.element[0].nodeName.toLowerCase(), 6655 isTextarea = nodeName === "textarea", 6656 isInput = nodeName === "input"; 6657 6658 this.isMultiLine = 6659 // Textareas are always multi-line 6660 isTextarea ? true : 6661 // Inputs are always single-line, even if inside a contentEditable element 6662 // IE also treats inputs as contentEditable 6663 isInput ? false : 6664 // All other element types are determined by whether or not they're contentEditable 6665 this.element.prop( "isContentEditable" ); 6666 6667 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6668 this.isNewMenu = true; 6669 6670 this.element 6671 .addClass( "ui-autocomplete-input" ) 6672 .attr( "autocomplete", "off" ); 6673 6674 this._on( this.element, { 6675 keydown: function( event ) { 6676 /*jshint maxcomplexity:15*/ 6677 if ( this.element.prop( "readOnly" ) ) { 6678 suppressKeyPress = true; 6679 suppressInput = true; 6680 suppressKeyPressRepeat = true; 6681 return; 6682 } 6683 6684 suppressKeyPress = false; 6685 suppressInput = false; 6686 suppressKeyPressRepeat = false; 6687 var keyCode = $.ui.keyCode; 6688 switch( event.keyCode ) { 6689 case keyCode.PAGE_UP: 6690 suppressKeyPress = true; 6691 this._move( "previousPage", event ); 6692 break; 6693 case keyCode.PAGE_DOWN: 6694 suppressKeyPress = true; 6695 this._move( "nextPage", event ); 6696 break; 6697 case keyCode.UP: 6698 suppressKeyPress = true; 6699 this._keyEvent( "previous", event ); 6700 break; 6701 case keyCode.DOWN: 6702 suppressKeyPress = true; 6703 this._keyEvent( "next", event ); 6704 break; 6705 case keyCode.ENTER: 6706 case keyCode.NUMPAD_ENTER: 6707 // when menu is open and has focus 6708 if ( this.menu.active ) { 6709 // #6055 - Opera still allows the keypress to occur 6710 // which causes forms to submit 6711 suppressKeyPress = true; 6712 event.preventDefault(); 6713 this.menu.select( event ); 6714 } 6715 break; 6716 case keyCode.TAB: 6717 if ( this.menu.active ) { 6718 this.menu.select( event ); 6719 } 6720 break; 6721 case keyCode.ESCAPE: 6722 if ( this.menu.element.is( ":visible" ) ) { 6723 this._value( this.term ); 6724 this.close( event ); 6725 // Different browsers have different default behavior for escape 6726 // Single press can mean undo or clear 6727 // Double press in IE means clear the whole form 6728 event.preventDefault(); 6729 } 6730 break; 6731 default: 6732 suppressKeyPressRepeat = true; 6733 // search timeout should be triggered before the input value is changed 6734 this._searchTimeout( event ); 6735 break; 6736 } 6737 }, 6738 keypress: function( event ) { 6739 if ( suppressKeyPress ) { 6740 suppressKeyPress = false; 6741 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6742 event.preventDefault(); 6743 } 6744 return; 6745 } 6746 if ( suppressKeyPressRepeat ) { 6747 return; 6748 } 6749 6750 // replicate some key handlers to allow them to repeat in Firefox and Opera 6751 var keyCode = $.ui.keyCode; 6752 switch( event.keyCode ) { 6753 case keyCode.PAGE_UP: 6754 this._move( "previousPage", event ); 6755 break; 6756 case keyCode.PAGE_DOWN: 6757 this._move( "nextPage", event ); 6758 break; 6759 case keyCode.UP: 6760 this._keyEvent( "previous", event ); 6761 break; 6762 case keyCode.DOWN: 6763 this._keyEvent( "next", event ); 6764 break; 6765 } 6766 }, 6767 input: function( event ) { 6768 if ( suppressInput ) { 6769 suppressInput = false; 6770 event.preventDefault(); 6771 return; 6772 } 6773 this._searchTimeout( event ); 6774 }, 6775 focus: function() { 6776 this.selectedItem = null; 6777 this.previous = this._value(); 6778 }, 6779 blur: function( event ) { 6780 if ( this.cancelBlur ) { 6781 delete this.cancelBlur; 6782 return; 6783 } 6784 6785 clearTimeout( this.searching ); 6786 this.close( event ); 6787 this._change( event ); 6788 } 6789 }); 6790 6791 this._initSource(); 6792 this.menu = $( "<ul>" ) 6793 .addClass( "ui-autocomplete ui-front" ) 6794 .appendTo( this._appendTo() ) 6795 .menu({ 6796 // disable ARIA support, the live region takes care of that 6797 role: null 6798 }) 6799 .hide() 6800 .data( "ui-menu" ); 6801 6802 this._on( this.menu.element, { 6803 mousedown: function( event ) { 6804 // prevent moving focus out of the text field 6805 event.preventDefault(); 6806 6807 // IE doesn't prevent moving focus even with event.preventDefault() 6808 // so we set a flag to know when we should ignore the blur event 6809 this.cancelBlur = true; 6810 this._delay(function() { 6811 delete this.cancelBlur; 6812 }); 6813 6814 // clicking on the scrollbar causes focus to shift to the body 6815 // but we can't detect a mouseup or a click immediately afterward 6816 // so we have to track the next mousedown and close the menu if 6817 // the user clicks somewhere outside of the autocomplete 6818 var menuElement = this.menu.element[ 0 ]; 6819 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6820 this._delay(function() { 6821 var that = this; 6822 this.document.one( "mousedown", function( event ) { 6823 if ( event.target !== that.element[ 0 ] && 6824 event.target !== menuElement && 6825 !$.contains( menuElement, event.target ) ) { 6826 that.close(); 6827 } 6828 }); 6829 }); 6830 } 6831 }, 6832 menufocus: function( event, ui ) { 6833 // support: Firefox 6834 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6835 if ( this.isNewMenu ) { 6836 this.isNewMenu = false; 6837 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6838 this.menu.blur(); 6839 6840 this.document.one( "mousemove", function() { 6841 $( event.target ).trigger( event.originalEvent ); 6842 }); 6843 6844 return; 6845 } 6846 } 6847 6848 var item = ui.item.data( "ui-autocomplete-item" ); 6849 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6850 // use value to match what will end up in the input, if it was a key event 6851 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6852 this._value( item.value ); 6853 } 6854 } else { 6855 // Normally the input is populated with the item's value as the 6856 // menu is navigated, causing screen readers to notice a change and 6857 // announce the item. Since the focus event was canceled, this doesn't 6858 // happen, so we update the live region so that screen readers can 6859 // still notice the change and announce it. 6860 this.liveRegion.text( item.value ); 6861 } 6862 }, 6863 menuselect: function( event, ui ) { 6864 var item = ui.item.data( "ui-autocomplete-item" ), 6865 previous = this.previous; 6866 6867 // only trigger when focus was lost (click on menu) 6868 if ( this.element[0] !== this.document[0].activeElement ) { 6869 this.element.focus(); 6870 this.previous = previous; 6871 // #6109 - IE triggers two focus events and the second 6872 // is asynchronous, so we need to reset the previous 6873 // term synchronously and asynchronously :-( 6874 this._delay(function() { 6875 this.previous = previous; 6876 this.selectedItem = item; 6877 }); 6878 } 6879 6880 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6881 this._value( item.value ); 6882 } 6883 // reset the term after the select event 6884 // this allows custom select handling to work properly 6885 this.term = this._value(); 6886 6887 this.close( event ); 6888 this.selectedItem = item; 6889 } 6890 }); 6891 6892 this.liveRegion = $( "<span>", { 6893 role: "status", 6894 "aria-live": "polite" 6895 }) 6896 .addClass( "ui-helper-hidden-accessible" ) 6897 .insertBefore( this.element ); 6898 6899 // turning off autocomplete prevents the browser from remembering the 6900 // value when navigating through history, so we re-enable autocomplete 6901 // if the page is unloaded before the widget is destroyed. #7790 6902 this._on( this.window, { 6903 beforeunload: function() { 6904 this.element.removeAttr( "autocomplete" ); 6905 } 6906 }); 6907 }, 6908 6909 _destroy: function() { 6910 clearTimeout( this.searching ); 6911 this.element 6912 .removeClass( "ui-autocomplete-input" ) 6913 .removeAttr( "autocomplete" ); 6914 this.menu.element.remove(); 6915 this.liveRegion.remove(); 6916 }, 6917 6918 _setOption: function( key, value ) { 6919 this._super( key, value ); 6920 if ( key === "source" ) { 6921 this._initSource(); 6922 } 6923 if ( key === "appendTo" ) { 6924 this.menu.element.appendTo( this._appendTo() ); 6925 } 6926 if ( key === "disabled" && value && this.xhr ) { 6927 this.xhr.abort(); 6928 } 6929 }, 6930 6931 _appendTo: function() { 6932 var element = this.options.appendTo; 6933 6934 if ( element ) { 6935 element = element.jquery || element.nodeType ? 6936 $( element ) : 6937 this.document.find( element ).eq( 0 ); 6938 } 6939 6940 if ( !element ) { 6941 element = this.element.closest( ".ui-front" ); 6942 } 6943 6944 if ( !element.length ) { 6945 element = this.document[0].body; 6946 } 6947 6948 return element; 6949 }, 6950 6951 _initSource: function() { 6952 var array, url, 6953 that = this; 6954 if ( $.isArray(this.options.source) ) { 6955 array = this.options.source; 6956 this.source = function( request, response ) { 6957 response( $.ui.autocomplete.filter( array, request.term ) ); 6958 }; 6959 } else if ( typeof this.options.source === "string" ) { 6960 url = this.options.source; 6961 this.source = function( request, response ) { 6962 if ( that.xhr ) { 6963 that.xhr.abort(); 6964 } 6965 that.xhr = $.ajax({
vendor: 5,929 bytes, lines 6966-7206
6966 url: url, 6967 data: request, 6968 dataType: "json", 6969 success: function( data ) { 6970 response( data ); 6971 }, 6972 error: function() { 6973 response( [] ); 6974 } 6975 }); 6976 }; 6977 } else { 6978 this.source = this.options.source; 6979 } 6980 }, 6981 6982 _searchTimeout: function( event ) { 6983 clearTimeout( this.searching ); 6984 this.searching = this._delay(function() { 6985 // only search if the value has changed 6986 if ( this.term !== this._value() ) { 6987 this.selectedItem = null; 6988 this.search( null, event ); 6989 } 6990 }, this.options.delay ); 6991 }, 6992 6993 search: function( value, event ) { 6994 value = value != null ? value : this._value(); 6995 6996 // always save the actual value, not the one passed as an argument 6997 this.term = this._value(); 6998 6999 if ( value.length < this.options.minLength ) { 7000 return this.close( event ); 7001 } 7002 7003 if ( this._trigger( "search", event ) === false ) { 7004 return; 7005 } 7006 7007 return this._search( value ); 7008 }, 7009 7010 _search: function( value ) { 7011 this.pending++; 7012 this.element.addClass( "ui-autocomplete-loading" ); 7013 this.cancelSearch = false; 7014 7015 this.source( { term: value }, this._response() ); 7016 }, 7017 7018 _response: function() { 7019 var that = this, 7020 index = ++requestIndex; 7021 7022 return function( content ) { 7023 if ( index === requestIndex ) { 7024 that.__response( content ); 7025 } 7026 7027 that.pending--; 7028 if ( !that.pending ) { 7029 that.element.removeClass( "ui-autocomplete-loading" ); 7030 } 7031 }; 7032 }, 7033 7034 __response: function( content ) { 7035 if ( content ) { 7036 content = this._normalize( content ); 7037 } 7038 this._trigger( "response", null, { content: content } ); 7039 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7040 this._suggest( content ); 7041 this._trigger( "open" ); 7042 } else { 7043 // use ._close() instead of .close() so we don't cancel future searches 7044 this._close(); 7045 } 7046 }, 7047 7048 close: function( event ) { 7049 this.cancelSearch = true; 7050 this._close( event ); 7051 }, 7052 7053 _close: function( event ) { 7054 if ( this.menu.element.is( ":visible" ) ) { 7055 this.menu.element.hide(); 7056 this.menu.blur(); 7057 this.isNewMenu = true; 7058 this._trigger( "close", event ); 7059 } 7060 }, 7061 7062 _change: function( event ) { 7063 if ( this.previous !== this._value() ) { 7064 this._trigger( "change", event, { item: this.selectedItem } ); 7065 } 7066 }, 7067 7068 _normalize: function( items ) { 7069 // assume all items have the right format when the first item is complete 7070 if ( items.length && items[0].label && items[0].value ) { 7071 return items; 7072 } 7073 return $.map( items, function( item ) { 7074 if ( typeof item === "string" ) { 7075 return { 7076 label: item, 7077 value: item 7078 }; 7079 } 7080 return $.extend({ 7081 label: item.label || item.value, 7082 value: item.value || item.label 7083 }, item ); 7084 }); 7085 }, 7086 7087 _suggest: function( items ) { 7088 var ul = this.menu.element.empty(); 7089 this._renderMenu( ul, items ); 7090 this.isNewMenu = true; 7091 this.menu.refresh(); 7092 7093 // size and position menu 7094 ul.show(); 7095 this._resizeMenu(); 7096 ul.position( $.extend({ 7097 of: this.element 7098 }, this.options.position )); 7099 7100 if ( this.options.autoFocus ) { 7101 this.menu.next(); 7102 } 7103 }, 7104 7105 _resizeMenu: function() { 7106 var ul = this.menu.element; 7107 ul.outerWidth( Math.max( 7108 // Firefox wraps long text (possibly a rounding bug) 7109 // so we add 1px to avoid the wrapping (#7513) 7110 ul.width( "" ).outerWidth() + 1, 7111 this.element.outerWidth() 7112 ) ); 7113 }, 7114 7115 _renderMenu: function( ul, items ) { 7116 var that = this; 7117 $.each( items, function( index, item ) { 7118 that._renderItemData( ul, item ); 7119 }); 7120 }, 7121 7122 _renderItemData: function( ul, item ) { 7123 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7124 }, 7125 7126 _renderItem: function( ul, item ) { 7127 return $( "<li>" ) 7128 .append( $( "<a>" ).text( item.label ) ) 7129 .appendTo( ul ); 7130 }, 7131 7132 _move: function( direction, event ) { 7133 if ( !this.menu.element.is( ":visible" ) ) { 7134 this.search( null, event ); 7135 return; 7136 } 7137 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7138 this.menu.isLastItem() && /^next/.test( direction ) ) { 7139 this._value( this.term ); 7140 this.menu.blur(); 7141 return; 7142 } 7143 this.menu[ direction ]( event ); 7144 }, 7145 7146 widget: function() { 7147 return this.menu.element; 7148 }, 7149 7150 _value: function() { 7151 return this.valueMethod.apply( this.element, arguments ); 7152 }, 7153 7154 _keyEvent: function( keyEvent, event ) { 7155 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7156 this._move( keyEvent, event ); 7157 7158 // prevents moving cursor to beginning/end of the text field in some browsers 7159 event.preventDefault(); 7160 } 7161 } 7162}); 7163 7164$.extend( $.ui.autocomplete, { 7165 escapeRegex: function( value ) { 7166 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 7167 }, 7168 filter: function(array, term) { 7169 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 7170 return $.grep( array, function(value) { 7171 return matcher.test( value.label || value.value || value ); 7172 }); 7173 } 7174}); 7175 7176 7177// live region extension, adding a `messages` option 7178// NOTE: This is an experimental API. We are still investigating 7179// a full solution for string manipulation and internationalization. 7180$.widget( "ui.autocomplete", $.ui.autocomplete, { 7181 options: { 7182 messages: { 7183 noResults: "No search results.", 7184 results: function( amount ) { 7185 return amount + ( amount > 1 ? " results are" : " result is" ) + 7186 " available, use up and down arrow keys to navigate."; 7187 } 7188 } 7189 }, 7190 7191 __response: function( content ) { 7192 var message; 7193 this._superApply( arguments ); 7194 if ( this.options.disabled || this.cancelSearch ) { 7195 return; 7196 } 7197 if ( content && content.length ) { 7198 message = this.options.messages.results( content.length ); 7199 } else { 7200 message = this.options.messages.noResults; 7201 } 7202 this.liveRegion.text( message ); 7203 } 7204}); 7205 7206}( jQuery ));
vendor: 15,161 bytes, lines 7207-7662
7207 7208(function( $, undefined ) { 7209 7210var lastActive, startXPos, startYPos, clickDragged, 7211 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7212 stateClasses = "ui-state-hover ui-state-active ", 7213 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", 7214 formResetHandler = function() { 7215 var form = $( this ); 7216 setTimeout(function() { 7217 form.find( ":ui-button" ).button( "refresh" ); 7218 }, 1 ); 7219 }, 7220 radioGroup = function( radio ) { 7221 var name = radio.name, 7222 form = radio.form, 7223 radios = $( [] ); 7224 if ( name ) { 7225 name = name.replace( /'/g, "\\'" ); 7226 if ( form ) { 7227 radios = $( form ).find( "[name='" + name + "']" ); 7228 } else { 7229 radios = $( "[name='" + name + "']", radio.ownerDocument ) 7230 .filter(function() { 7231 return !this.form; 7232 }); 7233 } 7234 } 7235 return radios; 7236 }; 7237 7238$.widget( "ui.button", { 7239 version: "1.10.3", 7240 defaultElement: "<button>", 7241 options: { 7242 disabled: null, 7243 text: true, 7244 label: null, 7245 icons: { 7246 primary: null, 7247 secondary: null 7248 } 7249 }, 7250 _create: function() { 7251 this.element.closest( "form" ) 7252 .unbind( "reset" + this.eventNamespace ) 7253 .bind( "reset" + this.eventNamespace, formResetHandler ); 7254 7255 if ( typeof this.options.disabled !== "boolean" ) { 7256 this.options.disabled = !!this.element.prop( "disabled" ); 7257 } else { 7258 this.element.prop( "disabled", this.options.disabled ); 7259 } 7260 7261 this._determineButtonType(); 7262 this.hasTitle = !!this.buttonElement.attr( "title" ); 7263 7264 var that = this, 7265 options = this.options, 7266 toggleButton = this.type === "checkbox" || this.type === "radio", 7267 activeClass = !toggleButton ? "ui-state-active" : "", 7268 focusClass = "ui-state-focus"; 7269 7270 if ( options.label === null ) { 7271 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7272 } 7273 7274 this._hoverable( this.buttonElement ); 7275 7276 this.buttonElement 7277 .addClass( baseClasses ) 7278 .attr( "role", "button" ) 7279 .bind( "mouseenter" + this.eventNamespace, function() { 7280 if ( options.disabled ) { 7281 return; 7282 } 7283 if ( this === lastActive ) { 7284 $( this ).addClass( "ui-state-active" ); 7285 } 7286 }) 7287 .bind( "mouseleave" + this.eventNamespace, function() { 7288 if ( options.disabled ) { 7289 return; 7290 } 7291 $( this ).removeClass( activeClass ); 7292 }) 7293 .bind( "click" + this.eventNamespace, function( event ) { 7294 if ( options.disabled ) { 7295 event.preventDefault(); 7296 event.stopImmediatePropagation(); 7297 } 7298 }); 7299 7300 this.element 7301 .bind( "focus" + this.eventNamespace, function() { 7302 // no need to check disabled, focus won't be triggered anyway 7303 that.buttonElement.addClass( focusClass ); 7304 }) 7305 .bind( "blur" + this.eventNamespace, function() { 7306 that.buttonElement.removeClass( focusClass ); 7307 }); 7308 7309 if ( toggleButton ) { 7310 this.element.bind( "change" + this.eventNamespace, function() { 7311 if ( clickDragged ) { 7312 return; 7313 } 7314 that.refresh(); 7315 }); 7316 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 7317 // prevents issue where button state changes but checkbox/radio checked state 7318 // does not in Firefox (see ticket #6970) 7319 this.buttonElement 7320 .bind( "mousedown" + this.eventNamespace, function( event ) { 7321 if ( options.disabled ) { 7322 return; 7323 } 7324 clickDragged = false; 7325 startXPos = event.pageX; 7326 startYPos = event.pageY; 7327 }) 7328 .bind( "mouseup" + this.eventNamespace, function( event ) { 7329 if ( options.disabled ) { 7330 return; 7331 } 7332 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 7333 clickDragged = true; 7334 } 7335 }); 7336 } 7337 7338 if ( this.type === "checkbox" ) { 7339 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7340 if ( options.disabled || clickDragged ) { 7341 return false; 7342 } 7343 }); 7344 } else if ( this.type === "radio" ) { 7345 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7346 if ( options.disabled || clickDragged ) { 7347 return false; 7348 } 7349 $( this ).addClass( "ui-state-active" ); 7350 that.buttonElement.attr( "aria-pressed", "true" ); 7351 7352 var radio = that.element[ 0 ]; 7353 radioGroup( radio ) 7354 .not( radio ) 7355 .map(function() { 7356 return $( this ).button( "widget" )[ 0 ]; 7357 }) 7358 .removeClass( "ui-state-active" ) 7359 .attr( "aria-pressed", "false" ); 7360 }); 7361 } else { 7362 this.buttonElement 7363 .bind( "mousedown" + this.eventNamespace, function() { 7364 if ( options.disabled ) { 7365 return false; 7366 } 7367 $( this ).addClass( "ui-state-active" ); 7368 lastActive = this; 7369 that.document.one( "mouseup", function() { 7370 lastActive = null; 7371 }); 7372 }) 7373 .bind( "mouseup" + this.eventNamespace, function() { 7374 if ( options.disabled ) { 7375 return false; 7376 } 7377 $( this ).removeClass( "ui-state-active" ); 7378 }) 7379 .bind( "keydown" + this.eventNamespace, function(event) { 7380 if ( options.disabled ) { 7381 return false; 7382 } 7383 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7384 $( this ).addClass( "ui-state-active" ); 7385 } 7386 }) 7387 // see #8559, we bind to blur here in case the button element loses 7388 // focus between keydown and keyup, it would be left in an "active" state 7389 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7390 $( this ).removeClass( "ui-state-active" ); 7391 }); 7392 7393 if ( this.buttonElement.is("a") ) { 7394 this.buttonElement.keyup(function(event) { 7395 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7396 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7397 $( this ).click(); 7398 } 7399 }); 7400 } 7401 } 7402 7403 // TODO: pull out $.Widget's handling for the disabled option into 7404 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7405 // be overridden by individual plugins 7406 this._setOption( "disabled", options.disabled ); 7407 this._resetButton(); 7408 }, 7409 7410 _determineButtonType: function() { 7411 var ancestor, labelSelector, checked; 7412 7413 if ( this.element.is("[type=checkbox]") ) { 7414 this.type = "checkbox"; 7415 } else if ( this.element.is("[type=radio]") ) { 7416 this.type = "radio"; 7417 } else if ( this.element.is("input") ) { 7418 this.type = "input"; 7419 } else { 7420 this.type = "button"; 7421 } 7422 7423 if ( this.type === "checkbox" || this.type === "radio" ) { 7424 // we don't search against the document in case the element 7425 // is disconnected from the DOM 7426 ancestor = this.element.parents().last(); 7427 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7428 this.buttonElement = ancestor.find( labelSelector ); 7429 if ( !this.buttonElement.length ) { 7430 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7431 this.buttonElement = ancestor.filter( labelSelector ); 7432 if ( !this.buttonElement.length ) { 7433 this.buttonElement = ancestor.find( labelSelector ); 7434 } 7435 } 7436 this.element.addClass( "ui-helper-hidden-accessible" ); 7437 7438 checked = this.element.is( ":checked" ); 7439 if ( checked ) { 7440 this.buttonElement.addClass( "ui-state-active" ); 7441 } 7442 this.buttonElement.prop( "aria-pressed", checked ); 7443 } else { 7444 this.buttonElement = this.element; 7445 } 7446 }, 7447 7448 widget: function() { 7449 return this.buttonElement; 7450 }, 7451 7452 _destroy: function() { 7453 this.element 7454 .removeClass( "ui-helper-hidden-accessible" ); 7455 this.buttonElement 7456 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7457 .removeAttr( "role" ) 7458 .removeAttr( "aria-pressed" ) 7459 .html( this.buttonElement.find(".ui-button-text").html() ); 7460 7461 if ( !this.hasTitle ) { 7462 this.buttonElement.removeAttr( "title" ); 7463 } 7464 }, 7465 7466 _setOption: function( key, value ) { 7467 this._super( key, value ); 7468 if ( key === "disabled" ) { 7469 if ( value ) { 7470 this.element.prop( "disabled", true ); 7471 } else { 7472 this.element.prop( "disabled", false ); 7473 } 7474 return; 7475 } 7476 this._resetButton(); 7477 }, 7478 7479 refresh: function() { 7480 //See #8237 & #8828 7481 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7482 7483 if ( isDisabled !== this.options.disabled ) { 7484 this._setOption( "disabled", isDisabled ); 7485 } 7486 if ( this.type === "radio" ) { 7487 radioGroup( this.element[0] ).each(function() { 7488 if ( $( this ).is( ":checked" ) ) { 7489 $( this ).button( "widget" ) 7490 .addClass( "ui-state-active" ) 7491 .attr( "aria-pressed", "true" ); 7492 } else { 7493 $( this ).button( "widget" ) 7494 .removeClass( "ui-state-active" ) 7495 .attr( "aria-pressed", "false" ); 7496 } 7497 }); 7498 } else if ( this.type === "checkbox" ) { 7499 if ( this.element.is( ":checked" ) ) { 7500 this.buttonElement 7501 .addClass( "ui-state-active" ) 7502 .attr( "aria-pressed", "true" ); 7503 } else { 7504 this.buttonElement 7505 .removeClass( "ui-state-active" ) 7506 .attr( "aria-pressed", "false" ); 7507 } 7508 } 7509 }, 7510 7511 _resetButton: function() { 7512 if ( this.type === "input" ) { 7513 if ( this.options.label ) { 7514 this.element.val( this.options.label ); 7515 } 7516 return; 7517 } 7518 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7519 buttonText = $( "<span></span>", this.document[0] ) 7520 .addClass( "ui-button-text" ) 7521 .html( this.options.label ) 7522 .appendTo( buttonElement.empty() ) 7523 .text(), 7524 icons = this.options.icons, 7525 multipleIcons = icons.primary && icons.secondary, 7526 buttonClasses = []; 7527 7528 if ( icons.primary || icons.secondary ) { 7529 if ( this.options.text ) { 7530 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7531 } 7532 7533 if ( icons.primary ) { 7534 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7535 } 7536 7537 if ( icons.secondary ) { 7538 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7539 } 7540 7541 if ( !this.options.text ) { 7542 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7543 7544 if ( !this.hasTitle ) { 7545 buttonElement.attr( "title", $.trim( buttonText ) ); 7546 } 7547 } 7548 } else { 7549 buttonClasses.push( "ui-button-text-only" ); 7550 } 7551 buttonElement.addClass( buttonClasses.join( " " ) ); 7552 } 7553}); 7554 7555$.widget( "ui.buttonset", { 7556 version: "1.10.3", 7557 options: { 7558 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7559 }, 7560 7561 _create: function() { 7562 this.element.addClass( "ui-buttonset" ); 7563 }, 7564 7565 _init: function() { 7566 this.refresh(); 7567 }, 7568 7569 _setOption: function( key, value ) { 7570 if ( key === "disabled" ) { 7571 this.buttons.button( "option", key, value ); 7572 } 7573 7574 this._super( key, value ); 7575 }, 7576 7577 refresh: function() { 7578 var rtl = this.element.css( "direction" ) === "rtl"; 7579 7580 this.buttons = this.element.find( this.options.items ) 7581 .filter( ":ui-button" ) 7582 .button( "refresh" ) 7583 .end() 7584 .not( ":ui-button" ) 7585 .button() 7586 .end() 7587 .map(function() { 7588 return $( this ).button( "widget" )[ 0 ]; 7589 }) 7590 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7591 .filter( ":first" ) 7592 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7593 .end() 7594 .filter( ":last" ) 7595 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7596 .end() 7597 .end(); 7598 }, 7599 7600 _destroy: function() { 7601 this.element.removeClass( "ui-buttonset" ); 7602 this.buttons 7603 .map(function() { 7604 return $( this ).button( "widget" )[ 0 ]; 7605 }) 7606 .removeClass( "ui-corner-left ui-corner-right" ) 7607 .end() 7608 .button( "destroy" ); 7609 } 7610}); 7611 7612}( jQuery ) ); 7613 7614(function( $, undefined ) { 7615 7616$.extend($.ui, { datepicker: { version: "1.10.3" } }); 7617 7618var PROP_NAME = "datepicker", 7619 instActive; 7620 7621/* Date picker manager. 7622 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7623 Settings for (groups of) date pickers are maintained in an instance object, 7624 allowing multiple different settings on the same page. */ 7625 7626function Datepicker() { 7627 this._curInst = null; // The current instance in use 7628 this._keyEvent = false; // If the last event was a key event 7629 this._disabledInputs = []; // List of date picker inputs that have been disabled 7630 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7631 this._inDialog = false; // True if showing within a "dialog", false if not 7632 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7633 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7634 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7635 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7636 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7637 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7638 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7639 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7640 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7641 this.regional = []; // Available regional settings, indexed by language code 7642 this.regional[""] = { // Default regional settings 7643 closeText: "Done", // Display text for close link 7644 prevText: "Prev", // Display text for previous month link 7645 nextText: "Next", // Display text for next month link 7646 currentText: "Today", // Display text for current month link 7647 monthNames: ["January","February","March","April","May","June", 7648 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7649 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7650 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7651 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7652 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7653 weekHeader: "Wk", // Column header for week of the year 7654 dateFormat: "mm/dd/yy", // See format options on parseDate 7655 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7656 isRTL: false, // True if right-to-left language, false if left-to-right 7657 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7658 yearSuffix: "" // Additional text to append to the year in the month headers 7659 }; 7660 this._defaults = { // Global defaults for all the date picker instances 7661 showOn: "focus", // "focus" for popup on focus, 7662 // "button" for trigger button, or "both" for either
vendor: 6,490 bytes, lines 7663-7792
7663 showAnim: "fadeIn", // Name of jQuery animation for popup 7664 showOptions: {}, // Options for enhanced animations 7665 defaultDate: null, // Used when field is blank: actual date, 7666 // +/-number for offset from today, null for today 7667 appendText: "", // Display text following the input box, e.g. showing the format 7668 buttonText: "...", // Text for trigger button 7669 buttonImage: "", // URL for trigger button image 7670 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7671 hideIfNoPrevNext: false, // True to hide next/previous month links 7672 // if not applicable, false to just disable them 7673 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7674 gotoCurrent: false, // True if today link goes back to current selection instead 7675 changeMonth: false, // True if month can be selected directly, false if only prev/next 7676 changeYear: false, // True if year can be selected directly, false if only prev/next 7677 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7678 // either relative to today's year (-nn:+nn), relative to currently displayed year 7679 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7680 showOtherMonths: false, // True to show dates in other months, false to leave blank 7681 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7682 showWeek: false, // True to show week of the year, false to not show it 7683 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7684 // takes a Date and returns the number of the week for it 7685 shortYearCutoff: "+10", // Short year values < this are in the current century, 7686 // > this are in the previous century, 7687 // string value starting with "+" for current year + value 7688 minDate: null, // The earliest selectable date, or null for no limit 7689 maxDate: null, // The latest selectable date, or null for no limit 7690 duration: "fast", // Duration of display/closure 7691 beforeShowDay: null, // Function that takes a date and returns an array with 7692 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7693 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7694 beforeShow: null, // Function that takes an input field and 7695 // returns a set of custom settings for the date picker 7696 onSelect: null, // Define a callback function when a date is selected 7697 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7698 onClose: null, // Define a callback function when the datepicker is closed 7699 numberOfMonths: 1, // Number of months to show at a time 7700 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7701 stepMonths: 1, // Number of months to step back/forward 7702 stepBigMonths: 12, // Number of months to step back/forward for the big links 7703 altField: "", // Selector for an alternate field to store selected dates into 7704 altFormat: "", // The date format to use for the alternate field 7705 constrainInput: true, // The input is constrained by the current date format 7706 showButtonPanel: false, // True to show button panel, false to not show it 7707 autoSize: false, // True to size the input for the date format, false to leave as is 7708 disabled: false // The initial disabled state 7709 }; 7710 $.extend(this._defaults, this.regional[""]); 7711 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7712} 7713 7714$.extend(Datepicker.prototype, { 7715 /* Class name added to elements to indicate already configured with a date picker. */ 7716 markerClassName: "hasDatepicker", 7717 7718 //Keep track of the maximum number of rows displayed (see #7043) 7719 maxRows: 4, 7720 7721 // TODO rename to "widget" when switching to widget factory 7722 _widgetDatepicker: function() { 7723 return this.dpDiv; 7724 }, 7725 7726 /* Override the default settings for all instances of the date picker. 7727 * @param settings object - the new settings to use as defaults (anonymous object) 7728 * @return the manager object 7729 */ 7730 setDefaults: function(settings) { 7731 extendRemove(this._defaults, settings || {}); 7732 return this; 7733 }, 7734 7735 /* Attach the date picker to a jQuery selection. 7736 * @param target element - the target input field or division or span 7737 * @param settings object - the new settings to use for this date picker instance (anonymous) 7738 */ 7739 _attachDatepicker: function(target, settings) { 7740 var nodeName, inline, inst; 7741 nodeName = target.nodeName.toLowerCase(); 7742 inline = (nodeName === "div" || nodeName === "span"); 7743 if (!target.id) { 7744 this.uuid += 1; 7745 target.id = "dp" + this.uuid; 7746 } 7747 inst = this._newInst($(target), inline); 7748 inst.settings = $.extend({}, settings || {}); 7749 if (nodeName === "input") { 7750 this._connectDatepicker(target, inst); 7751 } else if (inline) { 7752 this._inlineDatepicker(target, inst); 7753 } 7754 }, 7755 7756 /* Create a new instance object. */ 7757 _newInst: function(target, inline) { 7758 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 7759 return {id: id, input: target, // associated target 7760 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7761 drawMonth: 0, drawYear: 0, // month being drawn 7762 inline: inline, // is datepicker inline or not 7763 dpDiv: (!inline ? this.dpDiv : // presentation div 7764 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7765 }, 7766 7767 /* Attach the date picker to an input field. */ 7768 _connectDatepicker: function(target, inst) { 7769 var input = $(target); 7770 inst.append = $([]); 7771 inst.trigger = $([]); 7772 if (input.hasClass(this.markerClassName)) { 7773 return; 7774 } 7775 this._attachments(input, inst); 7776 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7777 keypress(this._doKeyPress).keyup(this._doKeyUp); 7778 this._autoSize(inst); 7779 $.data(target, PROP_NAME, inst); 7780 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7781 if( inst.settings.disabled ) { 7782 this._disableDatepicker( target ); 7783 } 7784 }, 7785 7786 /* Make attachments based on settings. */ 7787 _attachments: function(input, inst) { 7788 var showOn, buttonText, buttonImage, 7789 appendText = this._get(inst, "appendText"), 7790 isRTL = this._get(inst, "isRTL"); 7791 7792 if (inst.append) {
vendor: 5,933 bytes, lines 7793-7948
7793 inst.append.remove(); 7794 } 7795 if (appendText) { 7796 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7797 input[isRTL ? "before" : "after"](inst.append); 7798 } 7799 7800 input.unbind("focus", this._showDatepicker); 7801 7802 if (inst.trigger) { 7803 inst.trigger.remove(); 7804 } 7805 7806 showOn = this._get(inst, "showOn"); 7807 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7808 input.focus(this._showDatepicker); 7809 } 7810 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7811 buttonText = this._get(inst, "buttonText"); 7812 buttonImage = this._get(inst, "buttonImage"); 7813 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7814 $("<img/>").addClass(this._triggerClass). 7815 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7816 $("<button type='button'></button>").addClass(this._triggerClass). 7817 html(!buttonImage ? buttonText : $("<img/>").attr( 7818 { src:buttonImage, alt:buttonText, title:buttonText }))); 7819 input[isRTL ? "before" : "after"](inst.trigger); 7820 inst.trigger.click(function() { 7821 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7822 $.datepicker._hideDatepicker(); 7823 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7824 $.datepicker._hideDatepicker(); 7825 $.datepicker._showDatepicker(input[0]); 7826 } else { 7827 $.datepicker._showDatepicker(input[0]); 7828 } 7829 return false; 7830 }); 7831 } 7832 }, 7833 7834 /* Apply the maximum length for the date format. */ 7835 _autoSize: function(inst) { 7836 if (this._get(inst, "autoSize") && !inst.inline) { 7837 var findMax, max, maxI, i, 7838 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7839 dateFormat = this._get(inst, "dateFormat"); 7840 7841 if (dateFormat.match(/[DM]/)) { 7842 findMax = function(names) { 7843 max = 0; 7844 maxI = 0; 7845 for (i = 0; i < names.length; i++) { 7846 if (names[i].length > max) { 7847 max = names[i].length; 7848 maxI = i; 7849 } 7850 } 7851 return maxI; 7852 }; 7853 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7854 "monthNames" : "monthNamesShort")))); 7855 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7856 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7857 } 7858 inst.input.attr("size", this._formatDate(inst, date).length); 7859 } 7860 }, 7861 7862 /* Attach an inline date picker to a div. */ 7863 _inlineDatepicker: function(target, inst) { 7864 var divSpan = $(target); 7865 if (divSpan.hasClass(this.markerClassName)) { 7866 return; 7867 } 7868 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7869 $.data(target, PROP_NAME, inst); 7870 this._setDate(inst, this._getDefaultDate(inst), true); 7871 this._updateDatepicker(inst); 7872 this._updateAlternate(inst); 7873 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7874 if( inst.settings.disabled ) { 7875 this._disableDatepicker( target ); 7876 } 7877 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7878 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7879 inst.dpDiv.css( "display", "block" ); 7880 }, 7881 7882 /* Pop-up the date picker in a "dialog" box. 7883 * @param input element - ignored 7884 * @param date string or Date - the initial date to display 7885 * @param onSelect function - the function to call when a date is selected 7886 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7887 * @param pos int[2] - coordinates for the dialog's position within the screen or 7888 * event - with x/y coordinates or 7889 * leave empty for default (screen centre) 7890 * @return the manager object 7891 */ 7892 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7893 var id, browserWidth, browserHeight, scrollX, scrollY, 7894 inst = this._dialogInst; // internal instance 7895 7896 if (!inst) { 7897 this.uuid += 1; 7898 id = "dp" + this.uuid; 7899 this._dialogInput = $("<input type='text' id='" + id + 7900 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7901 this._dialogInput.keydown(this._doKeyDown); 7902 $("body").append(this._dialogInput); 7903 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7904 inst.settings = {}; 7905 $.data(this._dialogInput[0], PROP_NAME, inst); 7906 } 7907 extendRemove(inst.settings, settings || {}); 7908 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7909 this._dialogInput.val(date); 7910 7911 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7912 if (!this._pos) { 7913 browserWidth = document.documentElement.clientWidth; 7914 browserHeight = document.documentElement.clientHeight; 7915 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7916 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7917 this._pos = // should use actual width/height below 7918 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7919 } 7920 7921 // move input on screen for focus, but hidden behind dialog 7922 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7923 inst.settings.onSelect = onSelect; 7924 this._inDialog = true; 7925 this.dpDiv.addClass(this._dialogClass); 7926 this._showDatepicker(this._dialogInput[0]); 7927 if ($.blockUI) { 7928 $.blockUI(this.dpDiv); 7929 } 7930 $.data(this._dialogInput[0], PROP_NAME, inst); 7931 return this; 7932 }, 7933 7934 /* Detach a datepicker from its control. 7935 * @param target element - the target input field or division or span 7936 */ 7937 _destroyDatepicker: function(target) { 7938 var nodeName, 7939 $target = $(target), 7940 inst = $.data(target, PROP_NAME); 7941 7942 if (!$target.hasClass(this.markerClassName)) { 7943 return; 7944 } 7945 7946 nodeName = target.nodeName.toLowerCase(); 7947 $.removeData(target, PROP_NAME); 7948 if (nodeName === "input") {
vendor: 11,661 bytes, lines 7949-8280
7949 inst.append.remove(); 7950 inst.trigger.remove(); 7951 $target.removeClass(this.markerClassName). 7952 unbind("focus", this._showDatepicker). 7953 unbind("keydown", this._doKeyDown). 7954 unbind("keypress", this._doKeyPress). 7955 unbind("keyup", this._doKeyUp); 7956 } else if (nodeName === "div" || nodeName === "span") { 7957 $target.removeClass(this.markerClassName).empty(); 7958 } 7959 }, 7960 7961 /* Enable the date picker to a jQuery selection. 7962 * @param target element - the target input field or division or span 7963 */ 7964 _enableDatepicker: function(target) { 7965 var nodeName, inline, 7966 $target = $(target), 7967 inst = $.data(target, PROP_NAME); 7968 7969 if (!$target.hasClass(this.markerClassName)) { 7970 return; 7971 } 7972 7973 nodeName = target.nodeName.toLowerCase(); 7974 if (nodeName === "input") { 7975 target.disabled = false; 7976 inst.trigger.filter("button"). 7977 each(function() { this.disabled = false; }).end(). 7978 filter("img").css({opacity: "1.0", cursor: ""}); 7979 } else if (nodeName === "div" || nodeName === "span") { 7980 inline = $target.children("." + this._inlineClass); 7981 inline.children().removeClass("ui-state-disabled"); 7982 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7983 prop("disabled", false); 7984 } 7985 this._disabledInputs = $.map(this._disabledInputs, 7986 function(value) { return (value === target ? null : value); }); // delete entry 7987 }, 7988 7989 /* Disable the date picker to a jQuery selection. 7990 * @param target element - the target input field or division or span 7991 */ 7992 _disableDatepicker: function(target) { 7993 var nodeName, inline, 7994 $target = $(target), 7995 inst = $.data(target, PROP_NAME); 7996 7997 if (!$target.hasClass(this.markerClassName)) { 7998 return; 7999 } 8000 8001 nodeName = target.nodeName.toLowerCase(); 8002 if (nodeName === "input") { 8003 target.disabled = true; 8004 inst.trigger.filter("button"). 8005 each(function() { this.disabled = true; }).end(). 8006 filter("img").css({opacity: "0.5", cursor: "default"}); 8007 } else if (nodeName === "div" || nodeName === "span") { 8008 inline = $target.children("." + this._inlineClass); 8009 inline.children().addClass("ui-state-disabled"); 8010 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 8011 prop("disabled", true); 8012 } 8013 this._disabledInputs = $.map(this._disabledInputs, 8014 function(value) { return (value === target ? null : value); }); // delete entry 8015 this._disabledInputs[this._disabledInputs.length] = target; 8016 }, 8017 8018 /* Is the first field in a jQuery collection disabled as a datepicker? 8019 * @param target element - the target input field or division or span 8020 * @return boolean - true if disabled, false if enabled 8021 */ 8022 _isDisabledDatepicker: function(target) { 8023 if (!target) { 8024 return false; 8025 } 8026 for (var i = 0; i < this._disabledInputs.length; i++) { 8027 if (this._disabledInputs[i] === target) { 8028 return true; 8029 } 8030 } 8031 return false; 8032 }, 8033 8034 /* Retrieve the instance data for the target control. 8035 * @param target element - the target input field or division or span 8036 * @return object - the associated instance data 8037 * @throws error if a jQuery problem getting data 8038 */ 8039 _getInst: function(target) { 8040 try { 8041 return $.data(target, PROP_NAME); 8042 } 8043 catch (err) { 8044 throw "Missing instance data for this datepicker"; 8045 } 8046 }, 8047 8048 /* Update or retrieve the settings for a date picker attached to an input field or division. 8049 * @param target element - the target input field or division or span 8050 * @param name object - the new settings to update or 8051 * string - the name of the setting to change or retrieve, 8052 * when retrieving also "all" for all instance settings or 8053 * "defaults" for all global defaults 8054 * @param value any - the new value for the setting 8055 * (omit if above is an object or to retrieve a value) 8056 */ 8057 _optionDatepicker: function(target, name, value) { 8058 var settings, date, minDate, maxDate, 8059 inst = this._getInst(target); 8060 8061 if (arguments.length === 2 && typeof name === "string") { 8062 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8063 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8064 this._get(inst, name)) : null)); 8065 } 8066 8067 settings = name || {}; 8068 if (typeof name === "string") { 8069 settings = {}; 8070 settings[name] = value; 8071 } 8072 8073 if (inst) { 8074 if (this._curInst === inst) { 8075 this._hideDatepicker(); 8076 } 8077 8078 date = this._getDateDatepicker(target, true); 8079 minDate = this._getMinMaxDate(inst, "min"); 8080 maxDate = this._getMinMaxDate(inst, "max"); 8081 extendRemove(inst.settings, settings); 8082 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8083 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8084 inst.settings.minDate = this._formatDate(inst, minDate); 8085 } 8086 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8087 inst.settings.maxDate = this._formatDate(inst, maxDate); 8088 } 8089 if ( "disabled" in settings ) { 8090 if ( settings.disabled ) { 8091 this._disableDatepicker(target); 8092 } else { 8093 this._enableDatepicker(target); 8094 } 8095 } 8096 this._attachments($(target), inst); 8097 this._autoSize(inst); 8098 this._setDate(inst, date); 8099 this._updateAlternate(inst); 8100 this._updateDatepicker(inst); 8101 } 8102 }, 8103 8104 // change method deprecated 8105 _changeDatepicker: function(target, name, value) { 8106 this._optionDatepicker(target, name, value); 8107 }, 8108 8109 /* Redraw the date picker attached to an input field or division. 8110 * @param target element - the target input field or division or span 8111 */ 8112 _refreshDatepicker: function(target) { 8113 var inst = this._getInst(target); 8114 if (inst) { 8115 this._updateDatepicker(inst); 8116 } 8117 }, 8118 8119 /* Set the dates for a jQuery selection. 8120 * @param target element - the target input field or division or span 8121 * @param date Date - the new date 8122 */ 8123 _setDateDatepicker: function(target, date) { 8124 var inst = this._getInst(target); 8125 if (inst) { 8126 this._setDate(inst, date); 8127 this._updateDatepicker(inst); 8128 this._updateAlternate(inst); 8129 } 8130 }, 8131 8132 /* Get the date(s) for the first entry in a jQuery selection. 8133 * @param target element - the target input field or division or span 8134 * @param noDefault boolean - true if no default date is to be used 8135 * @return Date - the current date 8136 */ 8137 _getDateDatepicker: function(target, noDefault) { 8138 var inst = this._getInst(target); 8139 if (inst && !inst.inline) { 8140 this._setDateFromField(inst, noDefault); 8141 } 8142 return (inst ? this._getDate(inst) : null); 8143 }, 8144 8145 /* Handle keystrokes. */ 8146 _doKeyDown: function(event) { 8147 var onSelect, dateStr, sel, 8148 inst = $.datepicker._getInst(event.target), 8149 handled = true, 8150 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8151 8152 inst._keyEvent = true; 8153 if ($.datepicker._datepickerShowing) { 8154 switch (event.keyCode) { 8155 case 9: $.datepicker._hideDatepicker(); 8156 handled = false; 8157 break; // hide on tab out 8158 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8159 $.datepicker._currentClass + ")", inst.dpDiv); 8160 if (sel[0]) { 8161 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8162 } 8163 8164 onSelect = $.datepicker._get(inst, "onSelect"); 8165 if (onSelect) { 8166 dateStr = $.datepicker._formatDate(inst); 8167 8168 // trigger custom callback 8169 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8170 } else { 8171 $.datepicker._hideDatepicker(); 8172 } 8173 8174 return false; // don't submit the form 8175 case 27: $.datepicker._hideDatepicker(); 8176 break; // hide on escape 8177 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8178 -$.datepicker._get(inst, "stepBigMonths") : 8179 -$.datepicker._get(inst, "stepMonths")), "M"); 8180 break; // previous month/year on page up/+ ctrl 8181 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8182 +$.datepicker._get(inst, "stepBigMonths") : 8183 +$.datepicker._get(inst, "stepMonths")), "M"); 8184 break; // next month/year on page down/+ ctrl 8185 case 35: if (event.ctrlKey || event.metaKey) { 8186 $.datepicker._clearDate(event.target); 8187 } 8188 handled = event.ctrlKey || event.metaKey; 8189 break; // clear on ctrl or command +end 8190 case 36: if (event.ctrlKey || event.metaKey) { 8191 $.datepicker._gotoToday(event.target); 8192 } 8193 handled = event.ctrlKey || event.metaKey; 8194 break; // current on ctrl or command +home 8195 case 37: if (event.ctrlKey || event.metaKey) { 8196 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8197 } 8198 handled = event.ctrlKey || event.metaKey; 8199 // -1 day on ctrl or command +left 8200 if (event.originalEvent.altKey) { 8201 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8202 -$.datepicker._get(inst, "stepBigMonths") : 8203 -$.datepicker._get(inst, "stepMonths")), "M"); 8204 } 8205 // next month/year on alt +left on Mac 8206 break; 8207 case 38: if (event.ctrlKey || event.metaKey) { 8208 $.datepicker._adjustDate(event.target, -7, "D"); 8209 } 8210 handled = event.ctrlKey || event.metaKey; 8211 break; // -1 week on ctrl or command +up 8212 case 39: if (event.ctrlKey || event.metaKey) { 8213 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8214 } 8215 handled = event.ctrlKey || event.metaKey; 8216 // +1 day on ctrl or command +right 8217 if (event.originalEvent.altKey) { 8218 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8219 +$.datepicker._get(inst, "stepBigMonths") : 8220 +$.datepicker._get(inst, "stepMonths")), "M"); 8221 } 8222 // next month/year on alt +right 8223 break; 8224 case 40: if (event.ctrlKey || event.metaKey) { 8225 $.datepicker._adjustDate(event.target, +7, "D"); 8226 } 8227 handled = event.ctrlKey || event.metaKey; 8228 break; // +1 week on ctrl or command +down 8229 default: handled = false; 8230 } 8231 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8232 $.datepicker._showDatepicker(this); 8233 } else { 8234 handled = false; 8235 } 8236 8237 if (handled) { 8238 event.preventDefault(); 8239 event.stopPropagation(); 8240 } 8241 }, 8242 8243 /* Filter entered characters - based on date format. */ 8244 _doKeyPress: function(event) { 8245 var chars, chr, 8246 inst = $.datepicker._getInst(event.target); 8247 8248 if ($.datepicker._get(inst, "constrainInput")) { 8249 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8250 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8251 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8252 } 8253 }, 8254 8255 /* Synchronise manual entry and field/alternate field. */ 8256 _doKeyUp: function(event) { 8257 var date, 8258 inst = $.datepicker._getInst(event.target); 8259 8260 if (inst.input.val() !== inst.lastVal) { 8261 try { 8262 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8263 (inst.input ? inst.input.val() : null), 8264 $.datepicker._getFormatConfig(inst)); 8265 8266 if (date) { // only if valid 8267 $.datepicker._setDateFromField(inst); 8268 $.datepicker._updateAlternate(inst); 8269 $.datepicker._updateDatepicker(inst); 8270 } 8271 } 8272 catch (err) { 8273 } 8274 } 8275 return true; 8276 }, 8277 8278 /* Pop-up the date picker for a given input field. 8279 * If false returned from beforeShow event handler do not show. 8280 * @param input element - the input field attached to the date picker or
vendor: 14,080 bytes, lines 8281-8683
8281 * event - if triggered by focus 8282 */ 8283 _showDatepicker: function(input) { 8284 input = input.target || input; 8285 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8286 input = $("input", input.parentNode)[0]; 8287 } 8288 8289 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8290 return; 8291 } 8292 8293 var inst, beforeShow, beforeShowSettings, isFixed, 8294 offset, showAnim, duration; 8295 8296 inst = $.datepicker._getInst(input); 8297 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8298 $.datepicker._curInst.dpDiv.stop(true, true); 8299 if ( inst && $.datepicker._datepickerShowing ) { 8300 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8301 } 8302 } 8303 8304 beforeShow = $.datepicker._get(inst, "beforeShow"); 8305 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8306 if(beforeShowSettings === false){ 8307 return; 8308 } 8309 extendRemove(inst.settings, beforeShowSettings); 8310 8311 inst.lastVal = null; 8312 $.datepicker._lastInput = input; 8313 $.datepicker._setDateFromField(inst); 8314 8315 if ($.datepicker._inDialog) { // hide cursor 8316 input.value = ""; 8317 } 8318 if (!$.datepicker._pos) { // position below input 8319 $.datepicker._pos = $.datepicker._findPos(input); 8320 $.datepicker._pos[1] += input.offsetHeight; // add the height 8321 } 8322 8323 isFixed = false; 8324 $(input).parents().each(function() { 8325 isFixed |= $(this).css("position") === "fixed"; 8326 return !isFixed; 8327 }); 8328 8329 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8330 $.datepicker._pos = null; 8331 //to avoid flashes on Firefox 8332 inst.dpDiv.empty(); 8333 // determine sizing offscreen 8334 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8335 $.datepicker._updateDatepicker(inst); 8336 // fix width for dynamic number of date pickers 8337 // and adjust position before showing 8338 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8339 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8340 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8341 left: offset.left + "px", top: offset.top + "px"}); 8342 8343 if (!inst.inline) { 8344 showAnim = $.datepicker._get(inst, "showAnim"); 8345 duration = $.datepicker._get(inst, "duration"); 8346 inst.dpDiv.zIndex($(input).zIndex()+1); 8347 $.datepicker._datepickerShowing = true; 8348 8349 if ( $.effects && $.effects.effect[ showAnim ] ) { 8350 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8351 } else { 8352 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8353 } 8354 8355 if ( $.datepicker._shouldFocusInput( inst ) ) { 8356 inst.input.focus(); 8357 } 8358 8359 $.datepicker._curInst = inst; 8360 } 8361 }, 8362 8363 /* Generate the date picker content. */ 8364 _updateDatepicker: function(inst) { 8365 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8366 instActive = inst; // for delegate hover events 8367 inst.dpDiv.empty().append(this._generateHTML(inst)); 8368 this._attachHandlers(inst); 8369 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8370 8371 var origyearshtml, 8372 numMonths = this._getNumberOfMonths(inst), 8373 cols = numMonths[1], 8374 width = 17; 8375 8376 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8377 if (cols > 1) { 8378 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8379 } 8380 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8381 "Class"]("ui-datepicker-multi"); 8382 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8383 "Class"]("ui-datepicker-rtl"); 8384 8385 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8386 inst.input.focus(); 8387 } 8388 8389 // deffered render of the years select (to avoid flashes on Firefox) 8390 if( inst.yearshtml ){ 8391 origyearshtml = inst.yearshtml; 8392 setTimeout(function(){ 8393 //assure that inst.yearshtml didn't change. 8394 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8395 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8396 } 8397 origyearshtml = inst.yearshtml = null; 8398 }, 0); 8399 } 8400 }, 8401 8402 // #6694 - don't focus the input if it's already focused 8403 // this breaks the change event in IE 8404 // Support: IE and jQuery <1.9 8405 _shouldFocusInput: function( inst ) { 8406 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 8407 }, 8408 8409 /* Check positioning to remain on screen. */ 8410 _checkOffset: function(inst, offset, isFixed) { 8411 var dpWidth = inst.dpDiv.outerWidth(), 8412 dpHeight = inst.dpDiv.outerHeight(), 8413 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8414 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8415 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8416 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8417 8418 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8419 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8420 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8421 8422 // now check if datepicker is showing outside window viewport - move to a better place if so. 8423 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8424 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8425 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8426 Math.abs(dpHeight + inputHeight) : 0); 8427 8428 return offset; 8429 }, 8430 8431 /* Find an object's position on the screen. */ 8432 _findPos: function(obj) { 8433 var position, 8434 inst = this._getInst(obj), 8435 isRTL = this._get(inst, "isRTL"); 8436 8437 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8438 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8439 } 8440 8441 position = $(obj).offset(); 8442 return [position.left, position.top]; 8443 }, 8444 8445 /* Hide the date picker from view. 8446 * @param input element - the input field attached to the date picker 8447 */ 8448 _hideDatepicker: function(input) { 8449 var showAnim, duration, postProcess, onClose, 8450 inst = this._curInst; 8451 8452 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 8453 return; 8454 } 8455 8456 if (this._datepickerShowing) { 8457 showAnim = this._get(inst, "showAnim"); 8458 duration = this._get(inst, "duration"); 8459 postProcess = function() { 8460 $.datepicker._tidyDialog(inst); 8461 }; 8462 8463 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8464 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8465 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8466 } else { 8467 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8468 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8469 } 8470 8471 if (!showAnim) { 8472 postProcess(); 8473 } 8474 this._datepickerShowing = false; 8475 8476 onClose = this._get(inst, "onClose"); 8477 if (onClose) { 8478 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8479 } 8480 8481 this._lastInput = null; 8482 if (this._inDialog) { 8483 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8484 if ($.blockUI) { 8485 $.unblockUI(); 8486 $("body").append(this.dpDiv); 8487 } 8488 } 8489 this._inDialog = false; 8490 } 8491 }, 8492 8493 /* Tidy up after a dialog display. */ 8494 _tidyDialog: function(inst) { 8495 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8496 }, 8497 8498 /* Close date picker if clicked elsewhere. */ 8499 _checkExternalClick: function(event) { 8500 if (!$.datepicker._curInst) { 8501 return; 8502 } 8503 8504 var $target = $(event.target), 8505 inst = $.datepicker._getInst($target[0]); 8506 8507 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8508 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8509 !$target.hasClass($.datepicker.markerClassName) && 8510 !$target.closest("." + $.datepicker._triggerClass).length && 8511 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8512 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8513 $.datepicker._hideDatepicker(); 8514 } 8515 }, 8516 8517 /* Adjust one of the date sub-fields. */ 8518 _adjustDate: function(id, offset, period) { 8519 var target = $(id), 8520 inst = this._getInst(target[0]); 8521 8522 if (this._isDisabledDatepicker(target[0])) { 8523 return; 8524 } 8525 this._adjustInstDate(inst, offset + 8526 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8527 period); 8528 this._updateDatepicker(inst); 8529 }, 8530 8531 /* Action for current link. */ 8532 _gotoToday: function(id) { 8533 var date, 8534 target = $(id), 8535 inst = this._getInst(target[0]); 8536 8537 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8538 inst.selectedDay = inst.currentDay; 8539 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8540 inst.drawYear = inst.selectedYear = inst.currentYear; 8541 } else { 8542 date = new Date(); 8543 inst.selectedDay = date.getDate(); 8544 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8545 inst.drawYear = inst.selectedYear = date.getFullYear(); 8546 } 8547 this._notifyChange(inst); 8548 this._adjustDate(target); 8549 }, 8550 8551 /* Action for selecting a new month/year. */ 8552 _selectMonthYear: function(id, select, period) { 8553 var target = $(id), 8554 inst = this._getInst(target[0]); 8555 8556 inst["selected" + (period === "M" ? "Month" : "Year")] = 8557 inst["draw" + (period === "M" ? "Month" : "Year")] = 8558 parseInt(select.options[select.selectedIndex].value,10); 8559 8560 this._notifyChange(inst); 8561 this._adjustDate(target); 8562 }, 8563 8564 /* Action for selecting a day. */ 8565 _selectDay: function(id, month, year, td) { 8566 var inst, 8567 target = $(id); 8568 8569 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8570 return; 8571 } 8572 8573 inst = this._getInst(target[0]); 8574 inst.selectedDay = inst.currentDay = $("a", td).html(); 8575 inst.selectedMonth = inst.currentMonth = month; 8576 inst.selectedYear = inst.currentYear = year; 8577 this._selectDate(id, this._formatDate(inst, 8578 inst.currentDay, inst.currentMonth, inst.currentYear)); 8579 }, 8580 8581 /* Erase the input field and hide the date picker. */ 8582 _clearDate: function(id) { 8583 var target = $(id); 8584 this._selectDate(target, ""); 8585 }, 8586 8587 /* Update the input field with the selected date. */ 8588 _selectDate: function(id, dateStr) { 8589 var onSelect, 8590 target = $(id), 8591 inst = this._getInst(target[0]); 8592 8593 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8594 if (inst.input) { 8595 inst.input.val(dateStr); 8596 } 8597 this._updateAlternate(inst); 8598 8599 onSelect = this._get(inst, "onSelect"); 8600 if (onSelect) { 8601 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8602 } else if (inst.input) { 8603 inst.input.trigger("change"); // fire the change event 8604 } 8605 8606 if (inst.inline){ 8607 this._updateDatepicker(inst); 8608 } else { 8609 this._hideDatepicker(); 8610 this._lastInput = inst.input[0]; 8611 if (typeof(inst.input[0]) !== "object") { 8612 inst.input.focus(); // restore focus 8613 } 8614 this._lastInput = null; 8615 } 8616 }, 8617 8618 /* Update any alternate field to synchronise with the main field. */ 8619 _updateAlternate: function(inst) { 8620 var altFormat, date, dateStr, 8621 altField = this._get(inst, "altField"); 8622 8623 if (altField) { // update alternate field too 8624 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8625 date = this._getDate(inst); 8626 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8627 $(altField).each(function() { $(this).val(dateStr); }); 8628 } 8629 }, 8630 8631 /* Set as beforeShowDay function to prevent selection of weekends. 8632 * @param date Date - the date to customise 8633 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8634 */ 8635 noWeekends: function(date) { 8636 var day = date.getDay(); 8637 return [(day > 0 && day < 6), ""]; 8638 }, 8639 8640 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8641 * @param date Date - the date to get the week for 8642 * @return number - the number of the week within the year that contains this date 8643 */ 8644 iso8601Week: function(date) { 8645 var time, 8646 checkDate = new Date(date.getTime()); 8647 8648 // Find Thursday of this week starting on Monday 8649 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8650 8651 time = checkDate.getTime(); 8652 checkDate.setMonth(0); // Compare with Jan 1 8653 checkDate.setDate(1); 8654 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8655 }, 8656 8657 /* Parse a string value into a date object. 8658 * See formatDate below for the possible formats. 8659 * 8660 * @param format string - the expected format of the date 8661 * @param value string - the date in the above format 8662 * @param settings Object - attributes include: 8663 * shortYearCutoff number - the cutoff year for determining the century (optional) 8664 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8665 * dayNames string[7] - names of the days from Sunday (optional) 8666 * monthNamesShort string[12] - abbreviated names of the months (optional) 8667 * monthNames string[12] - names of the months (optional) 8668 * @return Date - the extracted date value or null if value is blank 8669 */ 8670 parseDate: function (format, value, settings) { 8671 if (format == null || value == null) { 8672 throw "Invalid arguments"; 8673 } 8674 8675 value = (typeof value === "object" ? value.toString() : value + ""); 8676 if (value === "") { 8677 return null; 8678 } 8679 8680 var iFormat, dim, extra, 8681 iValue = 0, 8682 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8683 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 15,706 bytes, lines 8683-9183
8683: 8684 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8685 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8686 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8687 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8688 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8689 year = -1, 8690 month = -1, 8691 day = -1, 8692 doy = -1, 8693 literal = false, 8694 date, 8695 // Check whether a format character is doubled 8696 lookAhead = function(match) { 8697 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8698 if (matches) { 8699 iFormat++; 8700 } 8701 return matches; 8702 }, 8703 // Extract a number from the string value 8704 getNumber = function(match) { 8705 var isDoubled = lookAhead(match), 8706 size = (match === "@" ? 14 : (match === "!" ? 20 : 8707 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8708 digits = new RegExp("^\\d{1," + size + "}"), 8709 num = value.substring(iValue).match(digits); 8710 if (!num) { 8711 throw "Missing number at position " + iValue; 8712 } 8713 iValue += num[0].length; 8714 return parseInt(num[0], 10); 8715 }, 8716 // Extract a name from the string value and convert to an index 8717 getName = function(match, shortNames, longNames) { 8718 var index = -1, 8719 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8720 return [ [k, v] ]; 8721 }).sort(function (a, b) { 8722 return -(a[1].length - b[1].length); 8723 }); 8724 8725 $.each(names, function (i, pair) { 8726 var name = pair[1]; 8727 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8728 index = pair[0]; 8729 iValue += name.length; 8730 return false; 8731 } 8732 }); 8733 if (index !== -1) { 8734 return index + 1; 8735 } else { 8736 throw "Unknown name at position " + iValue; 8737 } 8738 }, 8739 // Confirm that a literal character matches the string value 8740 checkLiteral = function() { 8741 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8742 throw "Unexpected literal at position " + iValue; 8743 } 8744 iValue++; 8745 }; 8746 8747 for (iFormat = 0; iFormat < format.length; iFormat++) { 8748 if (literal) { 8749 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8750 literal = false; 8751 } else { 8752 checkLiteral(); 8753 } 8754 } else { 8755 switch (format.charAt(iFormat)) { 8756 case "d": 8757 day = getNumber("d"); 8758 break; 8759 case "D": 8760 getName("D", dayNamesShort, dayNames); 8761 break; 8762 case "o": 8763 doy = getNumber("o"); 8764 break; 8765 case "m": 8766 month = getNumber("m"); 8767 break; 8768 case "M": 8769 month = getName("M", monthNamesShort, monthNames); 8770 break; 8771 case "y": 8772 year = getNumber("y"); 8773 break; 8774 case "@": 8775 date = new Date(getNumber("@")); 8776 year = date.getFullYear(); 8777 month = date.getMonth() + 1; 8778 day = date.getDate(); 8779 break; 8780 case "!": 8781 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8782 year = date.getFullYear(); 8783 month = date.getMonth() + 1; 8784 day = date.getDate(); 8785 break; 8786 case "'": 8787 if (lookAhead("'")){ 8788 checkLiteral(); 8789 } else { 8790 literal = true; 8791 } 8792 break; 8793 default: 8794 checkLiteral(); 8795 } 8796 } 8797 } 8798 8799 if (iValue < value.length){ 8800 extra = value.substr(iValue); 8801 if (!/^\s+/.test(extra)) { 8802 throw "Extra/unparsed characters found in date: " + extra; 8803 } 8804 } 8805 8806 if (year === -1) { 8807 year = new Date().getFullYear(); 8808 } else if (year < 100) { 8809 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8810 (year <= shortYearCutoff ? 0 : -100); 8811 } 8812 8813 if (doy > -1) { 8814 month = 1; 8815 day = doy; 8816 do { 8817 dim = this._getDaysInMonth(year, month - 1); 8818 if (day <= dim) { 8819 break; 8820 } 8821 month++; 8822 day -= dim; 8823 } while (true); 8824 } 8825 8826 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8827 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8828 throw "Invalid date"; // E.g. 31/02/00 8829 } 8830 return date; 8831 }, 8832 8833 /* Standard date formats. */ 8834 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8835 COOKIE: "D, dd M yy", 8836 ISO_8601: "yy-mm-dd", 8837 RFC_822: "D, d M y", 8838 RFC_850: "DD, dd-M-y", 8839 RFC_1036: "D, d M y", 8840 RFC_1123: "D, d M yy", 8841 RFC_2822: "D, d M yy", 8842 RSS: "D, d M y", // RFC 822 8843 TICKS: "!", 8844 TIMESTAMP: "@", 8845 W3C: "yy-mm-dd", // ISO 8601 8846 8847 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8848 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8849 8850 /* Format a date object into a string value. 8851 * The format can be combinations of the following: 8852 * d - day of month (no leading zero) 8853 * dd - day of month (two digit) 8854 * o - day of year (no leading zeros) 8855 * oo - day of year (three digit) 8856 * D - day name short 8857 * DD - day name long 8858 * m - month of year (no leading zero) 8859 * mm - month of year (two digit) 8860 * M - month name short 8861 * MM - month name long 8862 * y - year (two digit) 8863 * yy - year (four digit) 8864 * @ - Unix timestamp (ms since 01/01/1970) 8865 * ! - Windows ticks (100ns since 01/01/0001) 8866 * "..." - literal text 8867 * '' - single quote 8868 * 8869 * @param format string - the desired format of the date 8870 * @param date Date - the date value to format 8871 * @param settings Object - attributes include: 8872 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8873 * dayNames string[7] - names of the days from Sunday (optional) 8874 * monthNamesShort string[12] - abbreviated names of the months (optional) 8875 * monthNames string[12] - names of the months (optional) 8876 * @return string - the date in the above format 8877 */ 8878 formatDate: function (format, date, settings) { 8879 if (!date) { 8880 return ""; 8881 } 8882 8883 var iFormat, 8884 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8885 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8886 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8887 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8888 // Check whether a format character is doubled 8889 lookAhead = function(match) { 8890 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8891 if (matches) { 8892 iFormat++; 8893 } 8894 return matches; 8895 }, 8896 // Format a number, with leading zero if necessary 8897 formatNumber = function(match, value, len) { 8898 var num = "" + value; 8899 if (lookAhead(match)) { 8900 while (num.length < len) { 8901 num = "0" + num; 8902 } 8903 } 8904 return num; 8905 }, 8906 // Format a name, short or long as requested 8907 formatName = function(match, value, shortNames, longNames) { 8908 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8909 }, 8910 output = "", 8911 literal = false; 8912 8913 if (date) { 8914 for (iFormat = 0; iFormat < format.length; iFormat++) { 8915 if (literal) { 8916 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8917 literal = false; 8918 } else { 8919 output += format.charAt(iFormat); 8920 } 8921 } else { 8922 switch (format.charAt(iFormat)) { 8923 case "d": 8924 output += formatNumber("d", date.getDate(), 2); 8925 break; 8926 case "D": 8927 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8928 break; 8929 case "o": 8930 output += formatNumber("o", 8931 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8932 break; 8933 case "m": 8934 output += formatNumber("m", date.getMonth() + 1, 2); 8935 break; 8936 case "M": 8937 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8938 break; 8939 case "y": 8940 output += (lookAhead("y") ? date.getFullYear() : 8941 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8942 break; 8943 case "@": 8944 output += date.getTime(); 8945 break; 8946 case "!": 8947 output += date.getTime() * 10000 + this._ticksTo1970; 8948 break; 8949 case "'": 8950 if (lookAhead("'")) { 8951 output += "'"; 8952 } else { 8953 literal = true; 8954 } 8955 break; 8956 default: 8957 output += format.charAt(iFormat); 8958 } 8959 } 8960 } 8961 } 8962 return output; 8963 }, 8964 8965 /* Extract all possible characters from the date format. */ 8966 _possibleChars: function (format) { 8967 var iFormat, 8968 chars = "", 8969 literal = false, 8970 // Check whether a format character is doubled 8971 lookAhead = function(match) { 8972 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8973 if (matches) { 8974 iFormat++; 8975 } 8976 return matches; 8977 }; 8978 8979 for (iFormat = 0; iFormat < format.length; iFormat++) { 8980 if (literal) { 8981 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8982 literal = false; 8983 } else { 8984 chars += format.charAt(iFormat); 8985 } 8986 } else { 8987 switch (format.charAt(iFormat)) { 8988 case "d": case "m": case "y": case "@": 8989 chars += "0123456789"; 8990 break; 8991 case "D": case "M": 8992 return null; // Accept anything 8993 case "'": 8994 if (lookAhead("'")) { 8995 chars += "'"; 8996 } else { 8997 literal = true; 8998 } 8999 break; 9000 default: 9001 chars += format.charAt(iFormat); 9002 } 9003 } 9004 } 9005 return chars; 9006 }, 9007 9008 /* Get a setting value, defaulting if necessary. */ 9009 _get: function(inst, name) { 9010 return inst.settings[name] !== undefined ? 9011 inst.settings[name] : this._defaults[name]; 9012 }, 9013 9014 /* Parse existing date and initialise date picker. */ 9015 _setDateFromField: function(inst, noDefault) { 9016 if (inst.input.val() === inst.lastVal) { 9017 return; 9018 } 9019 9020 var dateFormat = this._get(inst, "dateFormat"), 9021 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9022 defaultDate = this._getDefaultDate(inst), 9023 date = defaultDate, 9024 settings = this._getFormatConfig(inst); 9025 9026 try { 9027 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9028 } catch (event) { 9029 dates = (noDefault ? "" : dates); 9030 } 9031 inst.selectedDay = date.getDate(); 9032 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9033 inst.drawYear = inst.selectedYear = date.getFullYear(); 9034 inst.currentDay = (dates ? date.getDate() : 0); 9035 inst.currentMonth = (dates ? date.getMonth() : 0); 9036 inst.currentYear = (dates ? date.getFullYear() : 0); 9037 this._adjustInstDate(inst); 9038 }, 9039 9040 /* Retrieve the default date shown on opening. */ 9041 _getDefaultDate: function(inst) { 9042 return this._restrictMinMax(inst, 9043 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9044 }, 9045 9046 /* A date may be specified as an exact value or a relative one. */ 9047 _determineDate: function(inst, date, defaultDate) { 9048 var offsetNumeric = function(offset) { 9049 var date = new Date(); 9050 date.setDate(date.getDate() + offset); 9051 return date; 9052 }, 9053 offsetString = function(offset) { 9054 try { 9055 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9056 offset, $.datepicker._getFormatConfig(inst)); 9057 } 9058 catch (e) { 9059 // Ignore 9060 } 9061 9062 var date = (offset.toLowerCase().match(/^c/) ? 9063 $.datepicker._getDate(inst) : null) || new Date(), 9064 year = date.getFullYear(), 9065 month = date.getMonth(), 9066 day = date.getDate(), 9067 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9068 matches = pattern.exec(offset); 9069 9070 while (matches) { 9071 switch (matches[2] || "d") { 9072 case "d" : case "D" : 9073 day += parseInt(matches[1],10); break; 9074 case "w" : case "W" : 9075 day += parseInt(matches[1],10) * 7; break; 9076 case "m" : case "M" : 9077 month += parseInt(matches[1],10); 9078 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9079 break; 9080 case "y": case "Y" : 9081 year += parseInt(matches[1],10); 9082 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9083 break; 9084 } 9085 matches = pattern.exec(offset); 9086 } 9087 return new Date(year, month, day); 9088 }, 9089 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9090 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9091 9092 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9093 if (newDate) { 9094 newDate.setHours(0); 9095 newDate.setMinutes(0); 9096 newDate.setSeconds(0); 9097 newDate.setMilliseconds(0); 9098 } 9099 return this._daylightSavingAdjust(newDate); 9100 }, 9101 9102 /* Handle switch to/from daylight saving. 9103 * Hours may be non-zero on daylight saving cut-over: 9104 * > 12 when midnight changeover, but then cannot generate 9105 * midnight datetime, so jump to 1AM, otherwise reset. 9106 * @param date (Date) the date to check 9107 * @return (Date) the corrected date 9108 */ 9109 _daylightSavingAdjust: function(date) { 9110 if (!date) { 9111 return null; 9112 } 9113 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9114 return date; 9115 }, 9116 9117 /* Set the date(s) directly. */ 9118 _setDate: function(inst, date, noChange) { 9119 var clear = !date, 9120 origMonth = inst.selectedMonth, 9121 origYear = inst.selectedYear, 9122 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9123 9124 inst.selectedDay = inst.currentDay = newDate.getDate(); 9125 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9126 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9127 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9128 this._notifyChange(inst); 9129 } 9130 this._adjustInstDate(inst); 9131 if (inst.input) { 9132 inst.input.val(clear ? "" : this._formatDate(inst)); 9133 } 9134 }, 9135 9136 /* Retrieve the date(s) directly. */ 9137 _getDate: function(inst) { 9138 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9139 this._daylightSavingAdjust(new Date( 9140 inst.currentYear, inst.currentMonth, inst.currentDay))); 9141 return startDate; 9142 }, 9143 9144 /* Attach the onxxx handlers. These are declared statically so 9145 * they work with static code transformers like Caja. 9146 */ 9147 _attachHandlers: function(inst) { 9148 var stepMonths = this._get(inst, "stepMonths"), 9149 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9150 inst.dpDiv.find("[data-handler]").map(function () { 9151 var handler = { 9152 prev: function () { 9153 $.datepicker._adjustDate(id, -stepMonths, "M"); 9154 }, 9155 next: function () { 9156 $.datepicker._adjustDate(id, +stepMonths, "M"); 9157 }, 9158 hide: function () { 9159 $.datepicker._hideDatepicker(); 9160 }, 9161 today: function () { 9162 $.datepicker._gotoToday(id); 9163 }, 9164 selectDay: function () { 9165 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9166 return false; 9167 }, 9168 selectMonth: function () { 9169 $.datepicker._selectMonthYear(id, this, "M"); 9170 return false; 9171 }, 9172 selectYear: function () { 9173 $.datepicker._selectMonthYear(id, this, "Y"); 9174 return false; 9175 } 9176 }; 9177 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9178 }); 9179 }, 9180 9181 /* Generate the HTML for the current state of the date picker. */ 9182 _generateHTML: function(inst) { 9183 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
vendor: 164,611 bytes, lines 9184-14920
9184 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9185 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9186 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9187 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9188 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9189 tempDate = new Date(), 9190 today = this._daylightSavingAdjust( 9191 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9192 isRTL = this._get(inst, "isRTL"), 9193 showButtonPanel = this._get(inst, "showButtonPanel"), 9194 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9195 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9196 numMonths = this._getNumberOfMonths(inst), 9197 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9198 stepMonths = this._get(inst, "stepMonths"), 9199 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9200 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9201 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9202 minDate = this._getMinMaxDate(inst, "min"), 9203 maxDate = this._getMinMaxDate(inst, "max"), 9204 drawMonth = inst.drawMonth - showCurrentAtPos, 9205 drawYear = inst.drawYear; 9206 9207 if (drawMonth < 0) { 9208 drawMonth += 12; 9209 drawYear--; 9210 } 9211 if (maxDate) { 9212 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9213 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9214 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9215 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9216 drawMonth--; 9217 if (drawMonth < 0) { 9218 drawMonth = 11; 9219 drawYear--; 9220 } 9221 } 9222 } 9223 inst.drawMonth = drawMonth; 9224 inst.drawYear = drawYear; 9225 9226 prevText = this._get(inst, "prevText"); 9227 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9228 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9229 this._getFormatConfig(inst))); 9230 9231 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9232 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9233 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9234 (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>")); 9235 9236 nextText = this._get(inst, "nextText"); 9237 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9238 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9239 this._getFormatConfig(inst))); 9240 9241 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9242 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9243 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9244 (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>")); 9245 9246 currentText = this._get(inst, "currentText"); 9247 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9248 currentText = (!navigationAsDateFormat ? currentText : 9249 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9250 9251 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'>" + 9252 this._get(inst, "closeText") + "</button>" : ""); 9253 9254 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9255 (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'" + 9256 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9257 9258 firstDay = parseInt(this._get(inst, "firstDay"),10); 9259 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9260 9261 showWeek = this._get(inst, "showWeek"); 9262 dayNames = this._get(inst, "dayNames"); 9263 dayNamesMin = this._get(inst, "dayNamesMin"); 9264 monthNames = this._get(inst, "monthNames"); 9265 monthNamesShort = this._get(inst, "monthNamesShort"); 9266 beforeShowDay = this._get(inst, "beforeShowDay"); 9267 showOtherMonths = this._get(inst, "showOtherMonths"); 9268 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9269 defaultDate = this._getDefaultDate(inst); 9270 html = ""; 9271 dow; 9272 for (row = 0; row < numMonths[0]; row++) { 9273 group = ""; 9274 this.maxRows = 4; 9275 for (col = 0; col < numMonths[1]; col++) { 9276 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9277 cornerClass = " ui-corner-all"; 9278 calender = ""; 9279 if (isMultiMonth) { 9280 calender += "<div class='ui-datepicker-group"; 9281 if (numMonths[1] > 1) { 9282 switch (col) { 9283 case 0: calender += " ui-datepicker-group-first"; 9284 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9285 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9286 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9287 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9288 } 9289 } 9290 calender += "'>"; 9291 } 9292 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9293 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9294 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9295 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9296 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9297 "</div><table class='ui-datepicker-calendar'><thead>" + 9298 "<tr>"; 9299 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9300 for (dow = 0; dow < 7; dow++) { // days of the week 9301 day = (dow + firstDay) % 7; 9302 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9303 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9304 } 9305 calender += thead + "</tr></thead><tbody>"; 9306 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9307 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9308 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9309 } 9310 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9311 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9312 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9313 this.maxRows = numRows; 9314 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9315 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9316 calender += "<tr>"; 9317 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9318 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9319 for (dow = 0; dow < 7; dow++) { // create date picker days 9320 daySettings = (beforeShowDay ? 9321 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9322 otherMonth = (printDate.getMonth() !== drawMonth); 9323 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9324 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9325 tbody += "<td class='" + 9326 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9327 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9328 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9329 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9330 // or defaultDate is current printedDate and defaultDate is selectedDate 9331 " " + this._dayOverClass : "") + // highlight selected day 9332 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9333 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9334 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9335 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9336 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9337 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9338 (otherMonth && !showOtherMonths ? " " : // display for other months 9339 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9340 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9341 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9342 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9343 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9344 printDate.setDate(printDate.getDate() + 1); 9345 printDate = this._daylightSavingAdjust(printDate); 9346 } 9347 calender += tbody + "</tr>"; 9348 } 9349 drawMonth++; 9350 if (drawMonth > 11) { 9351 drawMonth = 0; 9352 drawYear++; 9353 } 9354 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9355 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9356 group += calender; 9357 } 9358 html += group; 9359 } 9360 html += buttonPanel; 9361 inst._keyEvent = false; 9362 return html; 9363 }, 9364 9365 /* Generate the month and year header. */ 9366 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9367 secondary, monthNames, monthNamesShort) { 9368 9369 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9370 changeMonth = this._get(inst, "changeMonth"), 9371 changeYear = this._get(inst, "changeYear"), 9372 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9373 html = "<div class='ui-datepicker-title'>", 9374 monthHtml = ""; 9375 9376 // month selection 9377 if (secondary || !changeMonth) { 9378 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9379 } else { 9380 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9381 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9382 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9383 for ( month = 0; month < 12; month++) { 9384 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9385 monthHtml += "<option value='" + month + "'" + 9386 (month === drawMonth ? " selected='selected'" : "") + 9387 ">" + monthNamesShort[month] + "</option>"; 9388 } 9389 } 9390 monthHtml += "</select>"; 9391 } 9392 9393 if (!showMonthAfterYear) { 9394 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9395 } 9396 9397 // year selection 9398 if ( !inst.yearshtml ) { 9399 inst.yearshtml = ""; 9400 if (secondary || !changeYear) { 9401 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9402 } else { 9403 // determine range of years to display 9404 years = this._get(inst, "yearRange").split(":"); 9405 thisYear = new Date().getFullYear(); 9406 determineYear = function(value) { 9407 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9408 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9409 parseInt(value, 10))); 9410 return (isNaN(year) ? thisYear : year); 9411 }; 9412 year = determineYear(years[0]); 9413 endYear = Math.max(year, determineYear(years[1] || "")); 9414 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9415 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9416 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9417 for (; year <= endYear; year++) { 9418 inst.yearshtml += "<option value='" + year + "'" + 9419 (year === drawYear ? " selected='selected'" : "") + 9420 ">" + year + "</option>"; 9421 } 9422 inst.yearshtml += "</select>"; 9423 9424 html += inst.yearshtml; 9425 inst.yearshtml = null; 9426 } 9427 } 9428 9429 html += this._get(inst, "yearSuffix"); 9430 if (showMonthAfterYear) { 9431 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9432 } 9433 html += "</div>"; // Close datepicker_header 9434 return html; 9435 }, 9436 9437 /* Adjust one of the date sub-fields. */ 9438 _adjustInstDate: function(inst, offset, period) { 9439 var year = inst.drawYear + (period === "Y" ? offset : 0), 9440 month = inst.drawMonth + (period === "M" ? offset : 0), 9441 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9442 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9443 9444 inst.selectedDay = date.getDate(); 9445 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9446 inst.drawYear = inst.selectedYear = date.getFullYear(); 9447 if (period === "M" || period === "Y") { 9448 this._notifyChange(inst); 9449 } 9450 }, 9451 9452 /* Ensure a date is within any min/max bounds. */ 9453 _restrictMinMax: function(inst, date) { 9454 var minDate = this._getMinMaxDate(inst, "min"), 9455 maxDate = this._getMinMaxDate(inst, "max"), 9456 newDate = (minDate && date < minDate ? minDate : date); 9457 return (maxDate && newDate > maxDate ? maxDate : newDate); 9458 }, 9459 9460 /* Notify change of month/year. */ 9461 _notifyChange: function(inst) { 9462 var onChange = this._get(inst, "onChangeMonthYear"); 9463 if (onChange) { 9464 onChange.apply((inst.input ? inst.input[0] : null), 9465 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9466 } 9467 }, 9468 9469 /* Determine the number of months to show. */ 9470 _getNumberOfMonths: function(inst) { 9471 var numMonths = this._get(inst, "numberOfMonths"); 9472 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9473 }, 9474 9475 /* Determine the current maximum date - ensure no time components are set. */ 9476 _getMinMaxDate: function(inst, minMax) { 9477 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9478 }, 9479 9480 /* Find the number of days in a given month. */ 9481 _getDaysInMonth: function(year, month) { 9482 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9483 }, 9484 9485 /* Find the day of the week of the first of a month. */ 9486 _getFirstDayOfMonth: function(year, month) { 9487 return new Date(year, month, 1).getDay(); 9488 }, 9489 9490 /* Determines if we should allow a "next/prev" month display change. */ 9491 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9492 var numMonths = this._getNumberOfMonths(inst), 9493 date = this._daylightSavingAdjust(new Date(curYear, 9494 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9495 9496 if (offset < 0) { 9497 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9498 } 9499 return this._isInRange(inst, date); 9500 }, 9501 9502 /* Is the given date in the accepted range? */ 9503 _isInRange: function(inst, date) { 9504 var yearSplit, currentYear, 9505 minDate = this._getMinMaxDate(inst, "min"), 9506 maxDate = this._getMinMaxDate(inst, "max"), 9507 minYear = null, 9508 maxYear = null, 9509 years = this._get(inst, "yearRange"); 9510 if (years){ 9511 yearSplit = years.split(":"); 9512 currentYear = new Date().getFullYear(); 9513 minYear = parseInt(yearSplit[0], 10); 9514 maxYear = parseInt(yearSplit[1], 10); 9515 if ( yearSplit[0].match(/[+\-].*/) ) { 9516 minYear += currentYear; 9517 } 9518 if ( yearSplit[1].match(/[+\-].*/) ) { 9519 maxYear += currentYear; 9520 } 9521 } 9522 9523 return ((!minDate || date.getTime() >= minDate.getTime()) && 9524 (!maxDate || date.getTime() <= maxDate.getTime()) && 9525 (!minYear || date.getFullYear() >= minYear) && 9526 (!maxYear || date.getFullYear() <= maxYear)); 9527 }, 9528 9529 /* Provide the configuration settings for formatting/parsing. */ 9530 _getFormatConfig: function(inst) { 9531 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9532 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9533 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9534 return {shortYearCutoff: shortYearCutoff, 9535 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9536 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9537 }, 9538 9539 /* Format the given date for display. */ 9540 _formatDate: function(inst, day, month, year) { 9541 if (!day) { 9542 inst.currentDay = inst.selectedDay; 9543 inst.currentMonth = inst.selectedMonth; 9544 inst.currentYear = inst.selectedYear; 9545 } 9546 var date = (day ? (typeof day === "object" ? day : 9547 this._daylightSavingAdjust(new Date(year, month, day))) : 9548 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9549 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9550 } 9551}); 9552 9553/* 9554 * Bind hover events for datepicker elements. 9555 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9556 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9557 */ 9558function bindHover(dpDiv) { 9559 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9560 return dpDiv.delegate(selector, "mouseout", function() { 9561 $(this).removeClass("ui-state-hover"); 9562 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9563 $(this).removeClass("ui-datepicker-prev-hover"); 9564 } 9565 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9566 $(this).removeClass("ui-datepicker-next-hover"); 9567 } 9568 }) 9569 .delegate(selector, "mouseover", function(){ 9570 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9571 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9572 $(this).addClass("ui-state-hover"); 9573 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9574 $(this).addClass("ui-datepicker-prev-hover"); 9575 } 9576 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9577 $(this).addClass("ui-datepicker-next-hover"); 9578 } 9579 } 9580 }); 9581} 9582 9583/* jQuery extend now ignores nulls! */ 9584function extendRemove(target, props) { 9585 $.extend(target, props); 9586 for (var name in props) { 9587 if (props[name] == null) { 9588 target[name] = props[name]; 9589 } 9590 } 9591 return target; 9592} 9593 9594/* Invoke the datepicker functionality. 9595 @param options string - a command, optionally followed by additional parameters or 9596 Object - settings for attaching new datepicker functionality 9597 @return jQuery object */ 9598$.fn.datepicker = function(options){ 9599 9600 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9601 if ( !this.length ) { 9602 return this; 9603 } 9604 9605 /* Initialise the date picker. */ 9606 if (!$.datepicker.initialized) { 9607 $(document).mousedown($.datepicker._checkExternalClick); 9608 $.datepicker.initialized = true; 9609 } 9610 9611 /* Append datepicker main container to body if not exist. */ 9612 if ($("#"+$.datepicker._mainDivId).length === 0) { 9613 $("body").append($.datepicker.dpDiv); 9614 } 9615 9616 var otherArgs = Array.prototype.slice.call(arguments, 1); 9617 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9618 return $.datepicker["_" + options + "Datepicker"]. 9619 apply($.datepicker, [this[0]].concat(otherArgs)); 9620 } 9621 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9622 return $.datepicker["_" + options + "Datepicker"]. 9623 apply($.datepicker, [this[0]].concat(otherArgs)); 9624 } 9625 return this.each(function() { 9626 typeof options === "string" ? 9627 $.datepicker["_" + options + "Datepicker"]. 9628 apply($.datepicker, [this].concat(otherArgs)) : 9629 $.datepicker._attachDatepicker(this, options); 9630 }); 9631}; 9632 9633$.datepicker = new Datepicker(); // singleton instance 9634$.datepicker.initialized = false; 9635$.datepicker.uuid = new Date().getTime(); 9636$.datepicker.version = "1.10.3"; 9637 9638})(jQuery); 9639 9640(function( $, undefined ) { 9641 9642var sizeRelatedOptions = { 9643 buttons: true, 9644 height: true, 9645 maxHeight: true, 9646 maxWidth: true, 9647 minHeight: true, 9648 minWidth: true, 9649 width: true 9650 }, 9651 resizableRelatedOptions = { 9652 maxHeight: true, 9653 maxWidth: true, 9654 minHeight: true, 9655 minWidth: true 9656 }; 9657 9658$.widget( "ui.dialog", { 9659 version: "1.10.3", 9660 options: { 9661 appendTo: "body", 9662 autoOpen: true, 9663 buttons: [], 9664 closeOnEscape: true, 9665 closeText: "", 9666 dialogClass: "", 9667 draggable: true, 9668 hide: null, 9669 height: "auto", 9670 maxHeight: null, 9671 maxWidth: null, 9672 minHeight: null, 9673 minWidth: 150, 9674 modal: false, 9675 position: { 9676 my: "center", 9677 at: "center", 9678 of: window, 9679 collision: "fit", 9680 // Ensure the titlebar is always visible 9681 using: function( pos ) { 9682 var topOffset = $( this ).css( pos ).offset().top; 9683 if ( topOffset < 0 ) { 9684 $( this ).css( "top", pos.top - topOffset ); 9685 } 9686 } 9687 }, 9688 resizable: true, 9689 show: null, 9690 title: null, 9691 width: 300, 9692 9693 // callbacks 9694 beforeClose: null, 9695 close: null, 9696 drag: null, 9697 dragStart: null, 9698 dragStop: null, 9699 focus: null, 9700 open: null, 9701 resize: null, 9702 resizeStart: null, 9703 resizeStop: null 9704 }, 9705 9706 _create: function() { 9707 this.originalCss = { 9708 display: this.element[0].style.display, 9709 width: this.element[0].style.width, 9710 minHeight: this.element[0].style.minHeight, 9711 maxHeight: this.element[0].style.maxHeight, 9712 height: this.element[0].style.height 9713 }; 9714 this.originalPosition = { 9715 parent: this.element.parent(), 9716 index: this.element.parent().children().index( this.element ) 9717 }; 9718 this.originalTitle = this.element.attr("title"); 9719 this.options.title = this.options.title || this.originalTitle; 9720 9721 this._createWrapper(); 9722 9723 this.element 9724 .show() 9725 .removeAttr("title") 9726 .addClass("ui-dialog-content ui-widget-content") 9727 .appendTo( this.uiDialog ); 9728 9729 this._createTitlebar(); 9730 this._createButtonPane(); 9731 9732 if ( this.options.draggable && $.fn.draggable ) { 9733 this._makeDraggable(); 9734 } 9735 if ( this.options.resizable && $.fn.resizable ) { 9736 this._makeResizable(); 9737 } 9738 9739 this._isOpen = false; 9740 }, 9741 9742 _init: function() { 9743 if ( this.options.autoOpen ) { 9744 this.open(); 9745 } 9746 }, 9747 9748 _appendTo: function() { 9749 var element = this.options.appendTo; 9750 if ( element && (element.jquery || element.nodeType) ) { 9751 return $( element ); 9752 } 9753 return this.document.find( element || "body" ).eq( 0 ); 9754 }, 9755 9756 _destroy: function() { 9757 var next, 9758 originalPosition = this.originalPosition; 9759 9760 this._destroyOverlay(); 9761 9762 this.element 9763 .removeUniqueId() 9764 .removeClass("ui-dialog-content ui-widget-content") 9765 .css( this.originalCss ) 9766 // Without detaching first, the following becomes really slow 9767 .detach(); 9768 9769 this.uiDialog.stop( true, true ).remove(); 9770 9771 if ( this.originalTitle ) { 9772 this.element.attr( "title", this.originalTitle ); 9773 } 9774 9775 next = originalPosition.parent.children().eq( originalPosition.index ); 9776 // Don't try to place the dialog next to itself (#8613) 9777 if ( next.length && next[0] !== this.element[0] ) { 9778 next.before( this.element ); 9779 } else { 9780 originalPosition.parent.append( this.element ); 9781 } 9782 }, 9783 9784 widget: function() { 9785 return this.uiDialog; 9786 }, 9787 9788 disable: $.noop, 9789 enable: $.noop, 9790 9791 close: function( event ) { 9792 var that = this; 9793 9794 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9795 return; 9796 } 9797 9798 this._isOpen = false; 9799 this._destroyOverlay(); 9800 9801 if ( !this.opener.filter(":focusable").focus().length ) { 9802 // Hiding a focused element doesn't trigger blur in WebKit 9803 // so in case we have nothing to focus on, explicitly blur the active element 9804 // https://bugs.webkit.org/show_bug.cgi?id=47182 9805 $( this.document[0].activeElement ).blur(); 9806 } 9807 9808 this._hide( this.uiDialog, this.options.hide, function() { 9809 that._trigger( "close", event ); 9810 }); 9811 }, 9812 9813 isOpen: function() { 9814 return this._isOpen; 9815 }, 9816 9817 moveToTop: function() { 9818 this._moveToTop(); 9819 }, 9820 9821 _moveToTop: function( event, silent ) { 9822 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9823 if ( moved && !silent ) { 9824 this._trigger( "focus", event ); 9825 } 9826 return moved; 9827 }, 9828 9829 open: function() { 9830 var that = this; 9831 if ( this._isOpen ) { 9832 if ( this._moveToTop() ) { 9833 this._focusTabbable(); 9834 } 9835 return; 9836 } 9837 9838 this._isOpen = true; 9839 this.opener = $( this.document[0].activeElement ); 9840 9841 this._size(); 9842 this._position(); 9843 this._createOverlay(); 9844 this._moveToTop( null, true ); 9845 this._show( this.uiDialog, this.options.show, function() { 9846 that._focusTabbable(); 9847 that._trigger("focus"); 9848 }); 9849 9850 this._trigger("open"); 9851 }, 9852 9853 _focusTabbable: function() { 9854 // Set focus to the first match: 9855 // 1. First element inside the dialog matching [autofocus] 9856 // 2. Tabbable element inside the content element 9857 // 3. Tabbable element inside the buttonpane 9858 // 4. The close button 9859 // 5. The dialog itself 9860 var hasFocus = this.element.find("[autofocus]"); 9861 if ( !hasFocus.length ) { 9862 hasFocus = this.element.find(":tabbable"); 9863 } 9864 if ( !hasFocus.length ) { 9865 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9866 } 9867 if ( !hasFocus.length ) { 9868 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9869 } 9870 if ( !hasFocus.length ) { 9871 hasFocus = this.uiDialog; 9872 } 9873 hasFocus.eq( 0 ).focus(); 9874 }, 9875 9876 _keepFocus: function( event ) { 9877 function checkFocus() { 9878 var activeElement = this.document[0].activeElement, 9879 isActive = this.uiDialog[0] === activeElement || 9880 $.contains( this.uiDialog[0], activeElement ); 9881 if ( !isActive ) { 9882 this._focusTabbable(); 9883 } 9884 } 9885 event.preventDefault(); 9886 checkFocus.call( this ); 9887 // support: IE 9888 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9889 // so we check again later 9890 this._delay( checkFocus ); 9891 }, 9892 9893 _createWrapper: function() { 9894 this.uiDialog = $("<div>") 9895 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9896 this.options.dialogClass ) 9897 .hide() 9898 .attr({ 9899 // Setting tabIndex makes the div focusable 9900 tabIndex: -1, 9901 role: "dialog" 9902 }) 9903 .appendTo( this._appendTo() ); 9904 9905 this._on( this.uiDialog, { 9906 keydown: function( event ) { 9907 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9908 event.keyCode === $.ui.keyCode.ESCAPE ) { 9909 event.preventDefault(); 9910 this.close( event ); 9911 return; 9912 } 9913 9914 // prevent tabbing out of dialogs 9915 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9916 return; 9917 } 9918 var tabbables = this.uiDialog.find(":tabbable"), 9919 first = tabbables.filter(":first"), 9920 last = tabbables.filter(":last"); 9921 9922 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9923 first.focus( 1 ); 9924 event.preventDefault(); 9925 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9926 last.focus( 1 ); 9927 event.preventDefault(); 9928 } 9929 }, 9930 mousedown: function( event ) { 9931 if ( this._moveToTop( event ) ) { 9932 this._focusTabbable(); 9933 } 9934 } 9935 }); 9936 9937 // We assume that any existing aria-describedby attribute means 9938 // that the dialog content is marked up properly 9939 // otherwise we brute force the content as the description 9940 if ( !this.element.find("[aria-describedby]").length ) { 9941 this.uiDialog.attr({ 9942 "aria-describedby": this.element.uniqueId().attr("id") 9943 }); 9944 } 9945 }, 9946 9947 _createTitlebar: function() { 9948 var uiDialogTitle; 9949 9950 this.uiDialogTitlebar = $("<div>") 9951 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9952 .prependTo( this.uiDialog ); 9953 this._on( this.uiDialogTitlebar, { 9954 mousedown: function( event ) { 9955 // Don't prevent click on close button (#8838) 9956 // Focusing a dialog that is partially scrolled out of view 9957 // causes the browser to scroll it into view, preventing the click event 9958 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9959 // Dialog isn't getting focus when dragging (#8063) 9960 this.uiDialog.focus(); 9961 } 9962 } 9963 }); 9964 9965 this.uiDialogTitlebarClose = $("<button></button>") 9966 .button({ 9967 label: this.options.closeText, 9968 icons: { 9969 primary: "ui-icon-closethick" 9970 }, 9971 text: false 9972 }) 9973 .addClass("ui-dialog-titlebar-close") 9974 .appendTo( this.uiDialogTitlebar ); 9975 this._on( this.uiDialogTitlebarClose, { 9976 click: function( event ) { 9977 event.preventDefault(); 9978 this.close( event ); 9979 } 9980 }); 9981 9982 uiDialogTitle = $("<span>") 9983 .uniqueId() 9984 .addClass("ui-dialog-title") 9985 .prependTo( this.uiDialogTitlebar ); 9986 this._title( uiDialogTitle ); 9987 9988 this.uiDialog.attr({ 9989 "aria-labelledby": uiDialogTitle.attr("id") 9990 }); 9991 }, 9992 9993 _title: function( title ) { 9994 if ( !this.options.title ) { 9995 title.html(" "); 9996 } 9997 title.text( this.options.title ); 9998 }, 9999 10000 _createButtonPane: function() { 10001 this.uiDialogButtonPane = $("<div>") 10002 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 10003 10004 this.uiButtonSet = $("<div>") 10005 .addClass("ui-dialog-buttonset") 10006 .appendTo( this.uiDialogButtonPane ); 10007 10008 this._createButtons(); 10009 }, 10010 10011 _createButtons: function() { 10012 var that = this, 10013 buttons = this.options.buttons; 10014 10015 // if we already have a button pane, remove it 10016 this.uiDialogButtonPane.remove(); 10017 this.uiButtonSet.empty(); 10018 10019 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10020 this.uiDialog.removeClass("ui-dialog-buttons"); 10021 return; 10022 } 10023 10024 $.each( buttons, function( name, props ) { 10025 var click, buttonOptions; 10026 props = $.isFunction( props ) ? 10027 { click: props, text: name } : 10028 props; 10029 // Default to a non-submitting button 10030 props = $.extend( { type: "button" }, props ); 10031 // Change the context for the click callback to be the main element 10032 click = props.click; 10033 props.click = function() { 10034 click.apply( that.element[0], arguments ); 10035 }; 10036 buttonOptions = { 10037 icons: props.icons, 10038 text: props.showText 10039 }; 10040 delete props.icons; 10041 delete props.showText; 10042 $( "<button></button>", props ) 10043 .button( buttonOptions ) 10044 .appendTo( that.uiButtonSet ); 10045 }); 10046 this.uiDialog.addClass("ui-dialog-buttons"); 10047 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10048 }, 10049 10050 _makeDraggable: function() { 10051 var that = this, 10052 options = this.options; 10053 10054 function filteredUi( ui ) { 10055 return { 10056 position: ui.position, 10057 offset: ui.offset 10058 }; 10059 } 10060 10061 this.uiDialog.draggable({ 10062 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10063 handle: ".ui-dialog-titlebar", 10064 containment: "document", 10065 start: function( event, ui ) { 10066 $( this ).addClass("ui-dialog-dragging"); 10067 that._blockFrames(); 10068 that._trigger( "dragStart", event, filteredUi( ui ) ); 10069 }, 10070 drag: function( event, ui ) { 10071 that._trigger( "drag", event, filteredUi( ui ) ); 10072 }, 10073 stop: function( event, ui ) { 10074 options.position = [ 10075 ui.position.left - that.document.scrollLeft(), 10076 ui.position.top - that.document.scrollTop() 10077 ]; 10078 $( this ).removeClass("ui-dialog-dragging"); 10079 that._unblockFrames(); 10080 that._trigger( "dragStop", event, filteredUi( ui ) ); 10081 } 10082 }); 10083 }, 10084 10085 _makeResizable: function() { 10086 var that = this, 10087 options = this.options, 10088 handles = options.resizable, 10089 // .ui-resizable has position: relative defined in the stylesheet 10090 // but dialogs have to use absolute or fixed positioning 10091 position = this.uiDialog.css("position"), 10092 resizeHandles = typeof handles === "string" ? 10093 handles : 10094 "n,e,s,w,se,sw,ne,nw"; 10095 10096 function filteredUi( ui ) { 10097 return { 10098 originalPosition: ui.originalPosition, 10099 originalSize: ui.originalSize, 10100 position: ui.position, 10101 size: ui.size 10102 }; 10103 } 10104 10105 this.uiDialog.resizable({ 10106 cancel: ".ui-dialog-content", 10107 containment: "document", 10108 alsoResize: this.element, 10109 maxWidth: options.maxWidth, 10110 maxHeight: options.maxHeight, 10111 minWidth: options.minWidth, 10112 minHeight: this._minHeight(), 10113 handles: resizeHandles, 10114 start: function( event, ui ) { 10115 $( this ).addClass("ui-dialog-resizing"); 10116 that._blockFrames(); 10117 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10118 }, 10119 resize: function( event, ui ) { 10120 that._trigger( "resize", event, filteredUi( ui ) ); 10121 }, 10122 stop: function( event, ui ) { 10123 options.height = $( this ).height(); 10124 options.width = $( this ).width(); 10125 $( this ).removeClass("ui-dialog-resizing"); 10126 that._unblockFrames(); 10127 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10128 } 10129 }) 10130 .css( "position", position ); 10131 }, 10132 10133 _minHeight: function() { 10134 var options = this.options; 10135 10136 return options.height === "auto" ? 10137 options.minHeight : 10138 Math.min( options.minHeight, options.height ); 10139 }, 10140 10141 _position: function() { 10142 // Need to show the dialog to get the actual offset in the position plugin 10143 var isVisible = this.uiDialog.is(":visible"); 10144 if ( !isVisible ) { 10145 this.uiDialog.show(); 10146 } 10147 this.uiDialog.position( this.options.position ); 10148 if ( !isVisible ) { 10149 this.uiDialog.hide(); 10150 } 10151 }, 10152 10153 _setOptions: function( options ) { 10154 var that = this, 10155 resize = false, 10156 resizableOptions = {}; 10157 10158 $.each( options, function( key, value ) { 10159 that._setOption( key, value ); 10160 10161 if ( key in sizeRelatedOptions ) { 10162 resize = true; 10163 } 10164 if ( key in resizableRelatedOptions ) { 10165 resizableOptions[ key ] = value; 10166 } 10167 }); 10168 10169 if ( resize ) { 10170 this._size(); 10171 this._position(); 10172 } 10173 if ( this.uiDialog.is(":data(ui-resizable)") ) { 10174 this.uiDialog.resizable( "option", resizableOptions ); 10175 } 10176 }, 10177 10178 _setOption: function( key, value ) { 10179 /*jshint maxcomplexity:15*/ 10180 var isDraggable, isResizable, 10181 uiDialog = this.uiDialog; 10182 10183 if ( key === "dialogClass" ) { 10184 uiDialog 10185 .removeClass( this.options.dialogClass ) 10186 .addClass( value ); 10187 } 10188 10189 if ( key === "disabled" ) { 10190 return; 10191 } 10192 10193 this._super( key, value ); 10194 10195 if ( key === "appendTo" ) { 10196 this.uiDialog.appendTo( this._appendTo() ); 10197 } 10198 10199 if ( key === "buttons" ) { 10200 this._createButtons(); 10201 } 10202 10203 if ( key === "closeText" ) { 10204 this.uiDialogTitlebarClose.button({ 10205 // Ensure that we always pass a string 10206 label: "" + value 10207 }); 10208 } 10209 10210 if ( key === "draggable" ) { 10211 isDraggable = uiDialog.is(":data(ui-draggable)"); 10212 if ( isDraggable && !value ) { 10213 uiDialog.draggable("destroy"); 10214 } 10215 10216 if ( !isDraggable && value ) { 10217 this._makeDraggable(); 10218 } 10219 } 10220 10221 if ( key === "position" ) { 10222 this._position(); 10223 } 10224 10225 if ( key === "resizable" ) { 10226 // currently resizable, becoming non-resizable 10227 isResizable = uiDialog.is(":data(ui-resizable)"); 10228 if ( isResizable && !value ) { 10229 uiDialog.resizable("destroy"); 10230 } 10231 10232 // currently resizable, changing handles 10233 if ( isResizable && typeof value === "string" ) { 10234 uiDialog.resizable( "option", "handles", value ); 10235 } 10236 10237 // currently non-resizable, becoming resizable 10238 if ( !isResizable && value !== false ) { 10239 this._makeResizable(); 10240 } 10241 } 10242 10243 if ( key === "title" ) { 10244 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 10245 } 10246 }, 10247 10248 _size: function() { 10249 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10250 // divs will both have width and height set, so we need to reset them 10251 var nonContentHeight, minContentHeight, maxContentHeight, 10252 options = this.options; 10253 10254 // Reset content sizing 10255 this.element.show().css({ 10256 width: "auto", 10257 minHeight: 0, 10258 maxHeight: "none", 10259 height: 0 10260 }); 10261 10262 if ( options.minWidth > options.width ) { 10263 options.width = options.minWidth; 10264 } 10265 10266 // reset wrapper sizing 10267 // determine the height of all the non-content elements 10268 nonContentHeight = this.uiDialog.css({ 10269 height: "auto", 10270 width: options.width 10271 }) 10272 .outerHeight(); 10273 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10274 maxContentHeight = typeof options.maxHeight === "number" ? 10275 Math.max( 0, options.maxHeight - nonContentHeight ) : 10276 "none"; 10277 10278 if ( options.height === "auto" ) { 10279 this.element.css({ 10280 minHeight: minContentHeight, 10281 maxHeight: maxContentHeight, 10282 height: "auto" 10283 }); 10284 } else { 10285 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10286 } 10287 10288 if (this.uiDialog.is(":data(ui-resizable)") ) { 10289 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10290 } 10291 }, 10292 10293 _blockFrames: function() { 10294 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10295 var iframe = $( this ); 10296 10297 return $( "<div>" ) 10298 .css({ 10299 position: "absolute", 10300 width: iframe.outerWidth(), 10301 height: iframe.outerHeight() 10302 }) 10303 .appendTo( iframe.parent() ) 10304 .offset( iframe.offset() )[0]; 10305 }); 10306 }, 10307 10308 _unblockFrames: function() { 10309 if ( this.iframeBlocks ) { 10310 this.iframeBlocks.remove(); 10311 delete this.iframeBlocks; 10312 } 10313 }, 10314 10315 _allowInteraction: function( event ) { 10316 if ( $( event.target ).closest(".ui-dialog").length ) { 10317 return true; 10318 } 10319 10320 // TODO: Remove hack when datepicker implements 10321 // the .ui-front logic (#8989) 10322 return !!$( event.target ).closest(".ui-datepicker").length; 10323 }, 10324 10325 _createOverlay: function() { 10326 if ( !this.options.modal ) { 10327 return; 10328 } 10329 10330 var that = this, 10331 widgetFullName = this.widgetFullName; 10332 if ( !$.ui.dialog.overlayInstances ) { 10333 // Prevent use of anchors and inputs. 10334 // We use a delay in case the overlay is created from an 10335 // event that we're going to be cancelling. (#2804) 10336 this._delay(function() { 10337 // Handle .dialog().dialog("close") (#4065) 10338 if ( $.ui.dialog.overlayInstances ) { 10339 this.document.bind( "focusin.dialog", function( event ) { 10340 if ( !that._allowInteraction( event ) ) { 10341 event.preventDefault(); 10342 $(".ui-dialog:visible:last .ui-dialog-content") 10343 .data( widgetFullName )._focusTabbable(); 10344 } 10345 }); 10346 } 10347 }); 10348 } 10349 10350 this.overlay = $("<div>") 10351 .addClass("ui-widget-overlay ui-front") 10352 .appendTo( this._appendTo() ); 10353 this._on( this.overlay, { 10354 mousedown: "_keepFocus" 10355 }); 10356 $.ui.dialog.overlayInstances++; 10357 }, 10358 10359 _destroyOverlay: function() { 10360 if ( !this.options.modal ) { 10361 return; 10362 } 10363 10364 if ( this.overlay ) { 10365 $.ui.dialog.overlayInstances--; 10366 10367 if ( !$.ui.dialog.overlayInstances ) { 10368 this.document.unbind( "focusin.dialog" ); 10369 } 10370 this.overlay.remove(); 10371 this.overlay = null; 10372 } 10373 } 10374}); 10375 10376$.ui.dialog.overlayInstances = 0; 10377 10378// DEPRECATED 10379if ( $.uiBackCompat !== false ) { 10380 // position option with array notation 10381 // just override with old implementation 10382 $.widget( "ui.dialog", $.ui.dialog, { 10383 _position: function() { 10384 var position = this.options.position, 10385 myAt = [], 10386 offset = [ 0, 0 ], 10387 isVisible; 10388 10389 if ( position ) { 10390 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10391 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10392 if ( myAt.length === 1 ) { 10393 myAt[1] = myAt[0]; 10394 } 10395 10396 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10397 if ( +myAt[ i ] === myAt[ i ] ) { 10398 offset[ i ] = myAt[ i ]; 10399 myAt[ i ] = offsetPosition; 10400 } 10401 }); 10402 10403 position = { 10404 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10405 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10406 at: myAt.join(" ") 10407 }; 10408 } 10409 10410 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10411 } else { 10412 position = $.ui.dialog.prototype.options.position; 10413 } 10414 10415 // need to show the dialog to get the actual offset in the position plugin 10416 isVisible = this.uiDialog.is(":visible"); 10417 if ( !isVisible ) { 10418 this.uiDialog.show(); 10419 } 10420 this.uiDialog.position( position ); 10421 if ( !isVisible ) { 10422 this.uiDialog.hide(); 10423 } 10424 } 10425 }); 10426} 10427 10428}( jQuery ) ); 10429 10430(function( $, undefined ) { 10431 10432var rvertical = /up|down|vertical/, 10433 rpositivemotion = /up|left|vertical|horizontal/; 10434 10435$.effects.effect.blind = function( o, done ) { 10436 // Create element 10437 var el = $( this ), 10438 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10439 mode = $.effects.setMode( el, o.mode || "hide" ), 10440 direction = o.direction || "up", 10441 vertical = rvertical.test( direction ), 10442 ref = vertical ? "height" : "width", 10443 ref2 = vertical ? "top" : "left", 10444 motion = rpositivemotion.test( direction ), 10445 animation = {}, 10446 show = mode === "show", 10447 wrapper, distance, margin; 10448 10449 // if already wrapped, the wrapper's properties are my property. #6245 10450 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10451 $.effects.save( el.parent(), props ); 10452 } else { 10453 $.effects.save( el, props ); 10454 } 10455 el.show(); 10456 wrapper = $.effects.createWrapper( el ).css({ 10457 overflow: "hidden" 10458 }); 10459 10460 distance = wrapper[ ref ](); 10461 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10462 10463 animation[ ref ] = show ? distance : 0; 10464 if ( !motion ) { 10465 el 10466 .css( vertical ? "bottom" : "right", 0 ) 10467 .css( vertical ? "top" : "left", "auto" ) 10468 .css({ position: "absolute" }); 10469 10470 animation[ ref2 ] = show ? margin : distance + margin; 10471 } 10472 10473 // start at 0 if we are showing 10474 if ( show ) { 10475 wrapper.css( ref, 0 ); 10476 if ( ! motion ) { 10477 wrapper.css( ref2, margin + distance ); 10478 } 10479 } 10480 10481 // Animate 10482 wrapper.animate( animation, { 10483 duration: o.duration, 10484 easing: o.easing, 10485 queue: false, 10486 complete: function() { 10487 if ( mode === "hide" ) { 10488 el.hide(); 10489 } 10490 $.effects.restore( el, props ); 10491 $.effects.removeWrapper( el ); 10492 done(); 10493 } 10494 }); 10495 10496}; 10497 10498})(jQuery); 10499 10500(function( $, undefined ) { 10501 10502$.effects.effect.bounce = function( o, done ) { 10503 var el = $( this ), 10504 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10505 10506 // defaults: 10507 mode = $.effects.setMode( el, o.mode || "effect" ), 10508 hide = mode === "hide", 10509 show = mode === "show", 10510 direction = o.direction || "up", 10511 distance = o.distance, 10512 times = o.times || 5, 10513 10514 // number of internal animations 10515 anims = times * 2 + ( show || hide ? 1 : 0 ), 10516 speed = o.duration / anims, 10517 easing = o.easing, 10518 10519 // utility: 10520 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10521 motion = ( direction === "up" || direction === "left" ), 10522 i, 10523 upAnim, 10524 downAnim, 10525 10526 // we will need to re-assemble the queue to stack our animations in place 10527 queue = el.queue(), 10528 queuelen = queue.length; 10529 10530 // Avoid touching opacity to prevent clearType and PNG issues in IE 10531 if ( show || hide ) { 10532 props.push( "opacity" ); 10533 } 10534 10535 $.effects.save( el, props ); 10536 el.show(); 10537 $.effects.createWrapper( el ); // Create Wrapper 10538 10539 // default distance for the BIGGEST bounce is the outer Distance / 3 10540 if ( !distance ) { 10541 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10542 } 10543 10544 if ( show ) { 10545 downAnim = { opacity: 1 }; 10546 downAnim[ ref ] = 0; 10547 10548 // if we are showing, force opacity 0 and set the initial position 10549 // then do the "first" animation 10550 el.css( "opacity", 0 ) 10551 .css( ref, motion ? -distance * 2 : distance * 2 ) 10552 .animate( downAnim, speed, easing ); 10553 } 10554 10555 // start at the smallest distance if we are hiding 10556 if ( hide ) { 10557 distance = distance / Math.pow( 2, times - 1 ); 10558 } 10559 10560 downAnim = {}; 10561 downAnim[ ref ] = 0; 10562 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10563 for ( i = 0; i < times; i++ ) { 10564 upAnim = {}; 10565 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10566 10567 el.animate( upAnim, speed, easing ) 10568 .animate( downAnim, speed, easing ); 10569 10570 distance = hide ? distance * 2 : distance / 2; 10571 } 10572 10573 // Last Bounce when Hiding 10574 if ( hide ) { 10575 upAnim = { opacity: 0 }; 10576 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10577 10578 el.animate( upAnim, speed, easing ); 10579 } 10580 10581 el.queue(function() { 10582 if ( hide ) { 10583 el.hide(); 10584 } 10585 $.effects.restore( el, props ); 10586 $.effects.removeWrapper( el ); 10587 done(); 10588 }); 10589 10590 // inject all the animations we just queued to be first in line (after "inprogress") 10591 if ( queuelen > 1) { 10592 queue.splice.apply( queue, 10593 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10594 } 10595 el.dequeue(); 10596 10597}; 10598 10599})(jQuery); 10600 10601(function( $, undefined ) { 10602 10603$.effects.effect.clip = function( o, done ) { 10604 // Create element 10605 var el = $( this ), 10606 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10607 mode = $.effects.setMode( el, o.mode || "hide" ), 10608 show = mode === "show", 10609 direction = o.direction || "vertical", 10610 vert = direction === "vertical", 10611 size = vert ? "height" : "width", 10612 position = vert ? "top" : "left", 10613 animation = {}, 10614 wrapper, animate, distance; 10615 10616 // Save & Show 10617 $.effects.save( el, props ); 10618 el.show(); 10619 10620 // Create Wrapper 10621 wrapper = $.effects.createWrapper( el ).css({ 10622 overflow: "hidden" 10623 }); 10624 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10625 distance = animate[ size ](); 10626 10627 // Shift 10628 if ( show ) { 10629 animate.css( size, 0 ); 10630 animate.css( position, distance / 2 ); 10631 } 10632 10633 // Create Animation Object: 10634 animation[ size ] = show ? distance : 0; 10635 animation[ position ] = show ? 0 : distance / 2; 10636 10637 // Animate 10638 animate.animate( animation, { 10639 queue: false, 10640 duration: o.duration, 10641 easing: o.easing, 10642 complete: function() { 10643 if ( !show ) { 10644 el.hide(); 10645 } 10646 $.effects.restore( el, props ); 10647 $.effects.removeWrapper( el ); 10648 done(); 10649 } 10650 }); 10651 10652}; 10653 10654})(jQuery); 10655 10656(function( $, undefined ) { 10657 10658$.effects.effect.drop = function( o, done ) { 10659 10660 var el = $( this ), 10661 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10662 mode = $.effects.setMode( el, o.mode || "hide" ), 10663 show = mode === "show", 10664 direction = o.direction || "left", 10665 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10666 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10667 animation = { 10668 opacity: show ? 1 : 0 10669 }, 10670 distance; 10671 10672 // Adjust 10673 $.effects.save( el, props ); 10674 el.show(); 10675 $.effects.createWrapper( el ); 10676 10677 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10678 10679 if ( show ) { 10680 el 10681 .css( "opacity", 0 ) 10682 .css( ref, motion === "pos" ? -distance : distance ); 10683 } 10684 10685 // Animation 10686 animation[ ref ] = ( show ? 10687 ( motion === "pos" ? "+=" : "-=" ) : 10688 ( motion === "pos" ? "-=" : "+=" ) ) + 10689 distance; 10690 10691 // Animate 10692 el.animate( animation, { 10693 queue: false, 10694 duration: o.duration, 10695 easing: o.easing, 10696 complete: function() { 10697 if ( mode === "hide" ) { 10698 el.hide(); 10699 } 10700 $.effects.restore( el, props ); 10701 $.effects.removeWrapper( el ); 10702 done(); 10703 } 10704 }); 10705}; 10706 10707})(jQuery); 10708 10709(function( $, undefined ) { 10710 10711$.effects.effect.explode = function( o, done ) { 10712 10713 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10714 cells = rows, 10715 el = $( this ), 10716 mode = $.effects.setMode( el, o.mode || "hide" ), 10717 show = mode === "show", 10718 10719 // show and then visibility:hidden the element before calculating offset 10720 offset = el.show().css( "visibility", "hidden" ).offset(), 10721 10722 // width and height of a piece 10723 width = Math.ceil( el.outerWidth() / cells ), 10724 height = Math.ceil( el.outerHeight() / rows ), 10725 pieces = [], 10726 10727 // loop 10728 i, j, left, top, mx, my; 10729 10730 // children animate complete: 10731 function childComplete() { 10732 pieces.push( this ); 10733 if ( pieces.length === rows * cells ) { 10734 animComplete(); 10735 } 10736 } 10737 10738 // clone the element for each row and cell. 10739 for( i = 0; i < rows ; i++ ) { // ===> 10740 top = offset.top + i * height; 10741 my = i - ( rows - 1 ) / 2 ; 10742 10743 for( j = 0; j < cells ; j++ ) { // ||| 10744 left = offset.left + j * width; 10745 mx = j - ( cells - 1 ) / 2 ; 10746 10747 // Create a clone of the now hidden main element that will be absolute positioned 10748 // within a wrapper div off the -left and -top equal to size of our pieces 10749 el 10750 .clone() 10751 .appendTo( "body" ) 10752 .wrap( "<div></div>" ) 10753 .css({ 10754 position: "absolute", 10755 visibility: "visible", 10756 left: -j * width, 10757 top: -i * height 10758 }) 10759 10760 // select the wrapper - make it overflow: hidden and absolute positioned based on 10761 // where the original was located +left and +top equal to the size of pieces 10762 .parent() 10763 .addClass( "ui-effects-explode" ) 10764 .css({ 10765 position: "absolute", 10766 overflow: "hidden", 10767 width: width, 10768 height: height, 10769 left: left + ( show ? mx * width : 0 ), 10770 top: top + ( show ? my * height : 0 ), 10771 opacity: show ? 0 : 1 10772 }).animate({ 10773 left: left + ( show ? 0 : mx * width ), 10774 top: top + ( show ? 0 : my * height ), 10775 opacity: show ? 1 : 0 10776 }, o.duration || 500, o.easing, childComplete ); 10777 } 10778 } 10779 10780 function animComplete() { 10781 el.css({ 10782 visibility: "visible" 10783 }); 10784 $( pieces ).remove(); 10785 if ( !show ) { 10786 el.hide(); 10787 } 10788 done(); 10789 } 10790}; 10791 10792})(jQuery); 10793 10794(function( $, undefined ) { 10795 10796$.effects.effect.fade = function( o, done ) { 10797 var el = $( this ), 10798 mode = $.effects.setMode( el, o.mode || "toggle" ); 10799 10800 el.animate({ 10801 opacity: mode 10802 }, { 10803 queue: false, 10804 duration: o.duration, 10805 easing: o.easing, 10806 complete: done 10807 }); 10808}; 10809 10810})( jQuery ); 10811 10812(function( $, undefined ) { 10813 10814$.effects.effect.fold = function( o, done ) { 10815 10816 // Create element 10817 var el = $( this ), 10818 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10819 mode = $.effects.setMode( el, o.mode || "hide" ), 10820 show = mode === "show", 10821 hide = mode === "hide", 10822 size = o.size || 15, 10823 percent = /([0-9]+)%/.exec( size ), 10824 horizFirst = !!o.horizFirst, 10825 widthFirst = show !== horizFirst, 10826 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10827 duration = o.duration / 2, 10828 wrapper, distance, 10829 animation1 = {}, 10830 animation2 = {}; 10831 10832 $.effects.save( el, props ); 10833 el.show(); 10834 10835 // Create Wrapper 10836 wrapper = $.effects.createWrapper( el ).css({ 10837 overflow: "hidden" 10838 }); 10839 distance = widthFirst ? 10840 [ wrapper.width(), wrapper.height() ] : 10841 [ wrapper.height(), wrapper.width() ]; 10842 10843 if ( percent ) { 10844 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10845 } 10846 if ( show ) { 10847 wrapper.css( horizFirst ? { 10848 height: 0, 10849 width: size 10850 } : { 10851 height: size, 10852 width: 0 10853 }); 10854 } 10855 10856 // Animation 10857 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10858 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10859 10860 // Animate 10861 wrapper 10862 .animate( animation1, duration, o.easing ) 10863 .animate( animation2, duration, o.easing, function() { 10864 if ( hide ) { 10865 el.hide(); 10866 } 10867 $.effects.restore( el, props ); 10868 $.effects.removeWrapper( el ); 10869 done(); 10870 }); 10871 10872}; 10873 10874})(jQuery); 10875 10876(function( $, undefined ) { 10877 10878$.effects.effect.highlight = function( o, done ) { 10879 var elem = $( this ), 10880 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10881 mode = $.effects.setMode( elem, o.mode || "show" ), 10882 animation = { 10883 backgroundColor: elem.css( "backgroundColor" ) 10884 }; 10885 10886 if (mode === "hide") { 10887 animation.opacity = 0; 10888 } 10889 10890 $.effects.save( elem, props ); 10891 10892 elem 10893 .show() 10894 .css({ 10895 backgroundImage: "none", 10896 backgroundColor: o.color || "#ffff99" 10897 }) 10898 .animate( animation, { 10899 queue: false, 10900 duration: o.duration, 10901 easing: o.easing, 10902 complete: function() { 10903 if ( mode === "hide" ) { 10904 elem.hide(); 10905 } 10906 $.effects.restore( elem, props ); 10907 done(); 10908 } 10909 }); 10910}; 10911 10912})(jQuery); 10913 10914(function( $, undefined ) { 10915 10916$.effects.effect.pulsate = function( o, done ) { 10917 var elem = $( this ), 10918 mode = $.effects.setMode( elem, o.mode || "show" ), 10919 show = mode === "show", 10920 hide = mode === "hide", 10921 showhide = ( show || mode === "hide" ), 10922 10923 // showing or hiding leaves of the "last" animation 10924 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10925 duration = o.duration / anims, 10926 animateTo = 0, 10927 queue = elem.queue(), 10928 queuelen = queue.length, 10929 i; 10930 10931 if ( show || !elem.is(":visible")) { 10932 elem.css( "opacity", 0 ).show(); 10933 animateTo = 1; 10934 } 10935 10936 // anims - 1 opacity "toggles" 10937 for ( i = 1; i < anims; i++ ) { 10938 elem.animate({ 10939 opacity: animateTo 10940 }, duration, o.easing ); 10941 animateTo = 1 - animateTo; 10942 } 10943 10944 elem.animate({ 10945 opacity: animateTo 10946 }, duration, o.easing); 10947 10948 elem.queue(function() { 10949 if ( hide ) { 10950 elem.hide(); 10951 } 10952 done(); 10953 }); 10954 10955 // We just queued up "anims" animations, we need to put them next in the queue 10956 if ( queuelen > 1 ) { 10957 queue.splice.apply( queue, 10958 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10959 } 10960 elem.dequeue(); 10961}; 10962 10963})(jQuery); 10964 10965(function( $, undefined ) { 10966 10967$.effects.effect.puff = function( o, done ) { 10968 var elem = $( this ), 10969 mode = $.effects.setMode( elem, o.mode || "hide" ), 10970 hide = mode === "hide", 10971 percent = parseInt( o.percent, 10 ) || 150, 10972 factor = percent / 100, 10973 original = { 10974 height: elem.height(), 10975 width: elem.width(), 10976 outerHeight: elem.outerHeight(), 10977 outerWidth: elem.outerWidth() 10978 }; 10979 10980 $.extend( o, { 10981 effect: "scale", 10982 queue: false, 10983 fade: true, 10984 mode: mode, 10985 complete: done, 10986 percent: hide ? percent : 100, 10987 from: hide ? 10988 original : 10989 { 10990 height: original.height * factor, 10991 width: original.width * factor, 10992 outerHeight: original.outerHeight * factor, 10993 outerWidth: original.outerWidth * factor 10994 } 10995 }); 10996 10997 elem.effect( o ); 10998}; 10999 11000$.effects.effect.scale = function( o, done ) { 11001 11002 // Create element 11003 var el = $( this ), 11004 options = $.extend( true, {}, o ), 11005 mode = $.effects.setMode( el, o.mode || "effect" ), 11006 percent = parseInt( o.percent, 10 ) || 11007 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 11008 direction = o.direction || "both", 11009 origin = o.origin, 11010 original = { 11011 height: el.height(), 11012 width: el.width(), 11013 outerHeight: el.outerHeight(), 11014 outerWidth: el.outerWidth() 11015 }, 11016 factor = { 11017 y: direction !== "horizontal" ? (percent / 100) : 1, 11018 x: direction !== "vertical" ? (percent / 100) : 1 11019 }; 11020 11021 // We are going to pass this effect to the size effect: 11022 options.effect = "size"; 11023 options.queue = false; 11024 options.complete = done; 11025 11026 // Set default origin and restore for show/hide 11027 if ( mode !== "effect" ) { 11028 options.origin = origin || ["middle","center"]; 11029 options.restore = true; 11030 } 11031 11032 options.from = o.from || ( mode === "show" ? { 11033 height: 0, 11034 width: 0, 11035 outerHeight: 0, 11036 outerWidth: 0 11037 } : original ); 11038 options.to = { 11039 height: original.height * factor.y, 11040 width: original.width * factor.x, 11041 outerHeight: original.outerHeight * factor.y, 11042 outerWidth: original.outerWidth * factor.x 11043 }; 11044 11045 // Fade option to support puff 11046 if ( options.fade ) { 11047 if ( mode === "show" ) { 11048 options.from.opacity = 0; 11049 options.to.opacity = 1; 11050 } 11051 if ( mode === "hide" ) { 11052 options.from.opacity = 1; 11053 options.to.opacity = 0; 11054 } 11055 } 11056 11057 // Animate 11058 el.effect( options ); 11059 11060}; 11061 11062$.effects.effect.size = function( o, done ) { 11063 11064 // Create element 11065 var original, baseline, factor, 11066 el = $( this ), 11067 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11068 11069 // Always restore 11070 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11071 11072 // Copy for children 11073 props2 = [ "width", "height", "overflow" ], 11074 cProps = [ "fontSize" ], 11075 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11076 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11077 11078 // Set options 11079 mode = $.effects.setMode( el, o.mode || "effect" ), 11080 restore = o.restore || mode !== "effect", 11081 scale = o.scale || "both", 11082 origin = o.origin || [ "middle", "center" ], 11083 position = el.css( "position" ), 11084 props = restore ? props0 : props1, 11085 zero = { 11086 height: 0, 11087 width: 0, 11088 outerHeight: 0, 11089 outerWidth: 0 11090 }; 11091 11092 if ( mode === "show" ) { 11093 el.show(); 11094 } 11095 original = { 11096 height: el.height(), 11097 width: el.width(), 11098 outerHeight: el.outerHeight(), 11099 outerWidth: el.outerWidth() 11100 }; 11101 11102 if ( o.mode === "toggle" && mode === "show" ) { 11103 el.from = o.to || zero; 11104 el.to = o.from || original; 11105 } else { 11106 el.from = o.from || ( mode === "show" ? zero : original ); 11107 el.to = o.to || ( mode === "hide" ? zero : original ); 11108 } 11109 11110 // Set scaling factor 11111 factor = { 11112 from: { 11113 y: el.from.height / original.height, 11114 x: el.from.width / original.width 11115 }, 11116 to: { 11117 y: el.to.height / original.height, 11118 x: el.to.width / original.width 11119 } 11120 }; 11121 11122 // Scale the css box 11123 if ( scale === "box" || scale === "both" ) { 11124 11125 // Vertical props scaling 11126 if ( factor.from.y !== factor.to.y ) { 11127 props = props.concat( vProps ); 11128 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11129 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11130 } 11131 11132 // Horizontal props scaling 11133 if ( factor.from.x !== factor.to.x ) { 11134 props = props.concat( hProps ); 11135 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11136 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11137 } 11138 } 11139 11140 // Scale the content 11141 if ( scale === "content" || scale === "both" ) { 11142 11143 // Vertical props scaling 11144 if ( factor.from.y !== factor.to.y ) { 11145 props = props.concat( cProps ).concat( props2 ); 11146 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11147 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11148 } 11149 } 11150 11151 $.effects.save( el, props ); 11152 el.show(); 11153 $.effects.createWrapper( el ); 11154 el.css( "overflow", "hidden" ).css( el.from ); 11155 11156 // Adjust 11157 if (origin) { // Calculate baseline shifts 11158 baseline = $.effects.getBaseline( origin, original ); 11159 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11160 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11161 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11162 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11163 } 11164 el.css( el.from ); // set top & left 11165 11166 // Animate 11167 if ( scale === "content" || scale === "both" ) { // Scale the children 11168 11169 // Add margins/font-size 11170 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11171 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11172 props2 = props0.concat(vProps).concat(hProps); 11173 11174 el.find( "*[width]" ).each( function(){ 11175 var child = $( this ), 11176 c_original = { 11177 height: child.height(), 11178 width: child.width(), 11179 outerHeight: child.outerHeight(), 11180 outerWidth: child.outerWidth() 11181 }; 11182 if (restore) { 11183 $.effects.save(child, props2); 11184 } 11185 11186 child.from = { 11187 height: c_original.height * factor.from.y, 11188 width: c_original.width * factor.from.x, 11189 outerHeight: c_original.outerHeight * factor.from.y, 11190 outerWidth: c_original.outerWidth * factor.from.x 11191 }; 11192 child.to = { 11193 height: c_original.height * factor.to.y, 11194 width: c_original.width * factor.to.x, 11195 outerHeight: c_original.height * factor.to.y, 11196 outerWidth: c_original.width * factor.to.x 11197 }; 11198 11199 // Vertical props scaling 11200 if ( factor.from.y !== factor.to.y ) { 11201 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11202 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11203 } 11204 11205 // Horizontal props scaling 11206 if ( factor.from.x !== factor.to.x ) { 11207 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11208 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11209 } 11210 11211 // Animate children 11212 child.css( child.from ); 11213 child.animate( child.to, o.duration, o.easing, function() { 11214 11215 // Restore children 11216 if ( restore ) { 11217 $.effects.restore( child, props2 ); 11218 } 11219 }); 11220 }); 11221 } 11222 11223 // Animate 11224 el.animate( el.to, { 11225 queue: false, 11226 duration: o.duration, 11227 easing: o.easing, 11228 complete: function() { 11229 if ( el.to.opacity === 0 ) { 11230 el.css( "opacity", el.from.opacity ); 11231 } 11232 if( mode === "hide" ) { 11233 el.hide(); 11234 } 11235 $.effects.restore( el, props ); 11236 if ( !restore ) { 11237 11238 // we need to calculate our new positioning based on the scaling 11239 if ( position === "static" ) { 11240 el.css({ 11241 position: "relative", 11242 top: el.to.top, 11243 left: el.to.left 11244 }); 11245 } else { 11246 $.each([ "top", "left" ], function( idx, pos ) { 11247 el.css( pos, function( _, str ) { 11248 var val = parseInt( str, 10 ), 11249 toRef = idx ? el.to.left : el.to.top; 11250 11251 // if original was "auto", recalculate the new value from wrapper 11252 if ( str === "auto" ) { 11253 return toRef + "px"; 11254 } 11255 11256 return val + toRef + "px"; 11257 }); 11258 }); 11259 } 11260 } 11261 11262 $.effects.removeWrapper( el ); 11263 done(); 11264 } 11265 }); 11266 11267}; 11268 11269})(jQuery); 11270 11271(function( $, undefined ) { 11272 11273$.effects.effect.shake = function( o, done ) { 11274 11275 var el = $( this ), 11276 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11277 mode = $.effects.setMode( el, o.mode || "effect" ), 11278 direction = o.direction || "left", 11279 distance = o.distance || 20, 11280 times = o.times || 3, 11281 anims = times * 2 + 1, 11282 speed = Math.round(o.duration/anims), 11283 ref = (direction === "up" || direction === "down") ? "top" : "left", 11284 positiveMotion = (direction === "up" || direction === "left"), 11285 animation = {}, 11286 animation1 = {}, 11287 animation2 = {}, 11288 i, 11289 11290 // we will need to re-assemble the queue to stack our animations in place 11291 queue = el.queue(), 11292 queuelen = queue.length; 11293 11294 $.effects.save( el, props ); 11295 el.show(); 11296 $.effects.createWrapper( el ); 11297 11298 // Animation 11299 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11300 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11301 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11302 11303 // Animate 11304 el.animate( animation, speed, o.easing ); 11305 11306 // Shakes 11307 for ( i = 1; i < times; i++ ) { 11308 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11309 } 11310 el 11311 .animate( animation1, speed, o.easing ) 11312 .animate( animation, speed / 2, o.easing ) 11313 .queue(function() { 11314 if ( mode === "hide" ) { 11315 el.hide(); 11316 } 11317 $.effects.restore( el, props ); 11318 $.effects.removeWrapper( el ); 11319 done(); 11320 }); 11321 11322 // inject all the animations we just queued to be first in line (after "inprogress") 11323 if ( queuelen > 1) { 11324 queue.splice.apply( queue, 11325 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11326 } 11327 el.dequeue(); 11328 11329}; 11330 11331})(jQuery); 11332 11333(function( $, undefined ) { 11334 11335$.effects.effect.slide = function( o, done ) { 11336 11337 // Create element 11338 var el = $( this ), 11339 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11340 mode = $.effects.setMode( el, o.mode || "show" ), 11341 show = mode === "show", 11342 direction = o.direction || "left", 11343 ref = (direction === "up" || direction === "down") ? "top" : "left", 11344 positiveMotion = (direction === "up" || direction === "left"), 11345 distance, 11346 animation = {}; 11347 11348 // Adjust 11349 $.effects.save( el, props ); 11350 el.show(); 11351 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11352 11353 $.effects.createWrapper( el ).css({ 11354 overflow: "hidden" 11355 }); 11356 11357 if ( show ) { 11358 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11359 } 11360 11361 // Animation 11362 animation[ ref ] = ( show ? 11363 ( positiveMotion ? "+=" : "-=") : 11364 ( positiveMotion ? "-=" : "+=")) + 11365 distance; 11366 11367 // Animate 11368 el.animate( animation, { 11369 queue: false, 11370 duration: o.duration, 11371 easing: o.easing, 11372 complete: function() { 11373 if ( mode === "hide" ) { 11374 el.hide(); 11375 } 11376 $.effects.restore( el, props ); 11377 $.effects.removeWrapper( el ); 11378 done(); 11379 } 11380 }); 11381}; 11382 11383})(jQuery); 11384 11385(function( $, undefined ) { 11386 11387$.effects.effect.transfer = function( o, done ) { 11388 var elem = $( this ), 11389 target = $( o.to ), 11390 targetFixed = target.css( "position" ) === "fixed", 11391 body = $("body"), 11392 fixTop = targetFixed ? body.scrollTop() : 0, 11393 fixLeft = targetFixed ? body.scrollLeft() : 0, 11394 endPosition = target.offset(), 11395 animation = { 11396 top: endPosition.top - fixTop , 11397 left: endPosition.left - fixLeft , 11398 height: target.innerHeight(), 11399 width: target.innerWidth() 11400 }, 11401 startPosition = elem.offset(), 11402 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11403 .appendTo( document.body ) 11404 .addClass( o.className ) 11405 .css({ 11406 top: startPosition.top - fixTop , 11407 left: startPosition.left - fixLeft , 11408 height: elem.innerHeight(), 11409 width: elem.innerWidth(), 11410 position: targetFixed ? "fixed" : "absolute" 11411 }) 11412 .animate( animation, o.duration, o.easing, function() { 11413 transfer.remove(); 11414 done(); 11415 }); 11416}; 11417 11418})(jQuery); 11419 11420(function( $, undefined ) { 11421 11422$.widget( "ui.menu", { 11423 version: "1.10.3", 11424 defaultElement: "<ul>", 11425 delay: 300, 11426 options: { 11427 icons: { 11428 submenu: "ui-icon-carat-1-e" 11429 }, 11430 menus: "ul", 11431 position: { 11432 my: "left top", 11433 at: "right top" 11434 }, 11435 role: "menu", 11436 11437 // callbacks 11438 blur: null, 11439 focus: null, 11440 select: null 11441 }, 11442 11443 _create: function() { 11444 this.activeMenu = this.element; 11445 // flag used to prevent firing of the click handler 11446 // as the event bubbles up through nested menus 11447 this.mouseHandled = false; 11448 this.element 11449 .uniqueId() 11450 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11451 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 11452 .attr({ 11453 role: this.options.role, 11454 tabIndex: 0 11455 }) 11456 // need to catch all clicks on disabled menu 11457 // not possible through _on 11458 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 11459 if ( this.options.disabled ) { 11460 event.preventDefault(); 11461 } 11462 }, this )); 11463 11464 if ( this.options.disabled ) { 11465 this.element 11466 .addClass( "ui-state-disabled" ) 11467 .attr( "aria-disabled", "true" ); 11468 } 11469 11470 this._on({ 11471 // Prevent focus from sticking to links inside menu after clicking 11472 // them (focus should always stay on UL during navigation). 11473 "mousedown .ui-menu-item > a": function( event ) { 11474 event.preventDefault(); 11475 }, 11476 "click .ui-state-disabled > a": function( event ) { 11477 event.preventDefault(); 11478 }, 11479 "click .ui-menu-item:has(a)": function( event ) { 11480 var target = $( event.target ).closest( ".ui-menu-item" ); 11481 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 11482 this.mouseHandled = true; 11483 11484 this.select( event ); 11485 // Open submenu on click 11486 if ( target.has( ".ui-menu" ).length ) { 11487 this.expand( event ); 11488 } else if ( !this.element.is( ":focus" ) ) { 11489 // Redirect focus to the menu 11490 this.element.trigger( "focus", [ true ] ); 11491 11492 // If the active item is on the top level, let it stay active. 11493 // Otherwise, blur the active item since it is no longer visible. 11494 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 11495 clearTimeout( this.timer ); 11496 } 11497 } 11498 } 11499 }, 11500 "mouseenter .ui-menu-item": function( event ) { 11501 var target = $( event.currentTarget ); 11502 // Remove ui-state-active class from siblings of the newly focused menu item 11503 // to avoid a jump caused by adjacent elements both having a class with a border 11504 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 11505 this.focus( event, target ); 11506 }, 11507 mouseleave: "collapseAll", 11508 "mouseleave .ui-menu": "collapseAll", 11509 focus: function( event, keepActiveItem ) { 11510 // If there's already an active item, keep it active 11511 // If not, activate the first item 11512 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 11513 11514 if ( !keepActiveItem ) { 11515 this.focus( event, item ); 11516 } 11517 }, 11518 blur: function( event ) { 11519 this._delay(function() { 11520 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 11521 this.collapseAll( event ); 11522 } 11523 }); 11524 }, 11525 keydown: "_keydown" 11526 }); 11527 11528 this.refresh(); 11529 11530 // Clicks outside of a menu collapse any open menus 11531 this._on( this.document, { 11532 click: function( event ) { 11533 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11534 this.collapseAll( event ); 11535 } 11536 11537 // Reset the mouseHandled flag 11538 this.mouseHandled = false; 11539 } 11540 }); 11541 }, 11542 11543 _destroy: function() { 11544 // Destroy (sub)menus 11545 this.element 11546 .removeAttr( "aria-activedescendant" ) 11547 .find( ".ui-menu" ).addBack() 11548 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11549 .removeAttr( "role" ) 11550 .removeAttr( "tabIndex" ) 11551 .removeAttr( "aria-labelledby" ) 11552 .removeAttr( "aria-expanded" ) 11553 .removeAttr( "aria-hidden" ) 11554 .removeAttr( "aria-disabled" ) 11555 .removeUniqueId() 11556 .show(); 11557 11558 // Destroy menu items 11559 this.element.find( ".ui-menu-item" ) 11560 .removeClass( "ui-menu-item" ) 11561 .removeAttr( "role" ) 11562 .removeAttr( "aria-disabled" ) 11563 .children( "a" ) 11564 .removeUniqueId() 11565 .removeClass( "ui-corner-all ui-state-hover" ) 11566 .removeAttr( "tabIndex" ) 11567 .removeAttr( "role" ) 11568 .removeAttr( "aria-haspopup" ) 11569 .children().each( function() { 11570 var elem = $( this ); 11571 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11572 elem.remove(); 11573 } 11574 }); 11575 11576 // Destroy menu dividers 11577 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11578 }, 11579 11580 _keydown: function( event ) { 11581 /*jshint maxcomplexity:20*/ 11582 var match, prev, character, skip, regex, 11583 preventDefault = true; 11584 11585 function escape( value ) { 11586 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11587 } 11588 11589 switch ( event.keyCode ) { 11590 case $.ui.keyCode.PAGE_UP: 11591 this.previousPage( event ); 11592 break; 11593 case $.ui.keyCode.PAGE_DOWN: 11594 this.nextPage( event ); 11595 break; 11596 case $.ui.keyCode.HOME: 11597 this._move( "first", "first", event ); 11598 break; 11599 case $.ui.keyCode.END: 11600 this._move( "last", "last", event ); 11601 break; 11602 case $.ui.keyCode.UP: 11603 this.previous( event ); 11604 break; 11605 case $.ui.keyCode.DOWN: 11606 this.next( event ); 11607 break; 11608 case $.ui.keyCode.LEFT: 11609 this.collapse( event ); 11610 break; 11611 case $.ui.keyCode.RIGHT: 11612 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11613 this.expand( event ); 11614 } 11615 break; 11616 case $.ui.keyCode.ENTER: 11617 case $.ui.keyCode.SPACE: 11618 this._activate( event ); 11619 break; 11620 case $.ui.keyCode.ESCAPE: 11621 this.collapse( event ); 11622 break; 11623 default: 11624 preventDefault = false; 11625 prev = this.previousFilter || ""; 11626 character = String.fromCharCode( event.keyCode ); 11627 skip = false; 11628 11629 clearTimeout( this.filterTimer ); 11630 11631 if ( character === prev ) { 11632 skip = true; 11633 } else { 11634 character = prev + character; 11635 } 11636 11637 regex = new RegExp( "^" + escape( character ), "i" ); 11638 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11639 return regex.test( $( this ).children( "a" ).text() ); 11640 }); 11641 match = skip && match.index( this.active.next() ) !== -1 ? 11642 this.active.nextAll( ".ui-menu-item" ) : 11643 match; 11644 11645 // If no matches on the current filter, reset to the last character pressed 11646 // to move down the menu to the first item that starts with that character 11647 if ( !match.length ) { 11648 character = String.fromCharCode( event.keyCode ); 11649 regex = new RegExp( "^" + escape( character ), "i" ); 11650 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11651 return regex.test( $( this ).children( "a" ).text() ); 11652 }); 11653 } 11654 11655 if ( match.length ) { 11656 this.focus( event, match ); 11657 if ( match.length > 1 ) { 11658 this.previousFilter = character; 11659 this.filterTimer = this._delay(function() { 11660 delete this.previousFilter; 11661 }, 1000 ); 11662 } else { 11663 delete this.previousFilter; 11664 } 11665 } else { 11666 delete this.previousFilter; 11667 } 11668 } 11669 11670 if ( preventDefault ) { 11671 event.preventDefault(); 11672 } 11673 }, 11674 11675 _activate: function( event ) { 11676 if ( !this.active.is( ".ui-state-disabled" ) ) { 11677 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11678 this.expand( event ); 11679 } else { 11680 this.select( event ); 11681 } 11682 } 11683 }, 11684 11685 refresh: function() { 11686 var menus, 11687 icon = this.options.icons.submenu, 11688 submenus = this.element.find( this.options.menus ); 11689 11690 // Initialize nested menus 11691 submenus.filter( ":not(.ui-menu)" ) 11692 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11693 .hide() 11694 .attr({ 11695 role: this.options.role, 11696 "aria-hidden": "true", 11697 "aria-expanded": "false" 11698 }) 11699 .each(function() { 11700 var menu = $( this ), 11701 item = menu.prev( "a" ), 11702 submenuCarat = $( "<span>" ) 11703 .addClass( "ui-menu-icon ui-icon " + icon ) 11704 .data( "ui-menu-submenu-carat", true ); 11705 11706 item 11707 .attr( "aria-haspopup", "true" ) 11708 .prepend( submenuCarat ); 11709 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11710 }); 11711 11712 menus = submenus.add( this.element ); 11713 11714 // Don't refresh list items that are already adapted 11715 menus.children( ":not(.ui-menu-item):has(a)" ) 11716 .addClass( "ui-menu-item" ) 11717 .attr( "role", "presentation" ) 11718 .children( "a" ) 11719 .uniqueId() 11720 .addClass( "ui-corner-all" ) 11721 .attr({ 11722 tabIndex: -1, 11723 role: this._itemRole() 11724 }); 11725 11726 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11727 menus.children( ":not(.ui-menu-item)" ).each(function() { 11728 var item = $( this ); 11729 // hyphen, em dash, en dash 11730 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 11731 item.addClass( "ui-widget-content ui-menu-divider" ); 11732 } 11733 }); 11734 11735 // Add aria-disabled attribute to any disabled menu item 11736 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11737 11738 // If the active item has been removed, blur the menu 11739 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11740 this.blur(); 11741 } 11742 }, 11743 11744 _itemRole: function() { 11745 return { 11746 menu: "menuitem", 11747 listbox: "option" 11748 }[ this.options.role ]; 11749 }, 11750 11751 _setOption: function( key, value ) { 11752 if ( key === "icons" ) { 11753 this.element.find( ".ui-menu-icon" ) 11754 .removeClass( this.options.icons.submenu ) 11755 .addClass( value.submenu ); 11756 } 11757 this._super( key, value ); 11758 }, 11759 11760 focus: function( event, item ) { 11761 var nested, focused; 11762 this.blur( event, event && event.type === "focus" ); 11763 11764 this._scrollIntoView( item ); 11765 11766 this.active = item.first(); 11767 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11768 // Only update aria-activedescendant if there's a role 11769 // otherwise we assume focus is managed elsewhere 11770 if ( this.options.role ) { 11771 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11772 } 11773 11774 // Highlight active parent menu item, if any 11775 this.active 11776 .parent() 11777 .closest( ".ui-menu-item" ) 11778 .children( "a:first" ) 11779 .addClass( "ui-state-active" ); 11780 11781 if ( event && event.type === "keydown" ) { 11782 this._close(); 11783 } else { 11784 this.timer = this._delay(function() { 11785 this._close(); 11786 }, this.delay ); 11787 } 11788 11789 nested = item.children( ".ui-menu" ); 11790 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11791 this._startOpening(nested); 11792 } 11793 this.activeMenu = item.parent(); 11794 11795 this._trigger( "focus", event, { item: item } ); 11796 }, 11797 11798 _scrollIntoView: function( item ) { 11799 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11800 if ( this._hasScroll() ) { 11801 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11802 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11803 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11804 scroll = this.activeMenu.scrollTop(); 11805 elementHeight = this.activeMenu.height(); 11806 itemHeight = item.height(); 11807 11808 if ( offset < 0 ) { 11809 this.activeMenu.scrollTop( scroll + offset ); 11810 } else if ( offset + itemHeight > elementHeight ) { 11811 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11812 } 11813 } 11814 }, 11815 11816 blur: function( event, fromFocus ) { 11817 if ( !fromFocus ) { 11818 clearTimeout( this.timer ); 11819 } 11820 11821 if ( !this.active ) { 11822 return; 11823 } 11824 11825 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11826 this.active = null; 11827 11828 this._trigger( "blur", event, { item: this.active } ); 11829 }, 11830 11831 _startOpening: function( submenu ) { 11832 clearTimeout( this.timer ); 11833 11834 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11835 // shift in the submenu position when mousing over the carat icon 11836 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11837 return; 11838 } 11839 11840 this.timer = this._delay(function() { 11841 this._close(); 11842 this._open( submenu ); 11843 }, this.delay ); 11844 }, 11845 11846 _open: function( submenu ) { 11847 var position = $.extend({ 11848 of: this.active 11849 }, this.options.position ); 11850 11851 clearTimeout( this.timer ); 11852 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11853 .hide() 11854 .attr( "aria-hidden", "true" ); 11855 11856 submenu 11857 .show() 11858 .removeAttr( "aria-hidden" ) 11859 .attr( "aria-expanded", "true" ) 11860 .position( position ); 11861 }, 11862 11863 collapseAll: function( event, all ) { 11864 clearTimeout( this.timer ); 11865 this.timer = this._delay(function() { 11866 // If we were passed an event, look for the submenu that contains the event 11867 var currentMenu = all ? this.element : 11868 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11869 11870 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11871 if ( !currentMenu.length ) { 11872 currentMenu = this.element; 11873 } 11874 11875 this._close( currentMenu ); 11876 11877 this.blur( event ); 11878 this.activeMenu = currentMenu; 11879 }, this.delay ); 11880 }, 11881 11882 // With no arguments, closes the currently active menu - if nothing is active 11883 // it closes all menus. If passed an argument, it will search for menus BELOW 11884 _close: function( startMenu ) { 11885 if ( !startMenu ) { 11886 startMenu = this.active ? this.active.parent() : this.element; 11887 } 11888 11889 startMenu 11890 .find( ".ui-menu" ) 11891 .hide() 11892 .attr( "aria-hidden", "true" ) 11893 .attr( "aria-expanded", "false" ) 11894 .end() 11895 .find( "a.ui-state-active" ) 11896 .removeClass( "ui-state-active" ); 11897 }, 11898 11899 collapse: function( event ) { 11900 var newItem = this.active && 11901 this.active.parent().closest( ".ui-menu-item", this.element ); 11902 if ( newItem && newItem.length ) { 11903 this._close(); 11904 this.focus( event, newItem ); 11905 } 11906 }, 11907 11908 expand: function( event ) { 11909 var newItem = this.active && 11910 this.active 11911 .children( ".ui-menu " ) 11912 .children( ".ui-menu-item" ) 11913 .first(); 11914 11915 if ( newItem && newItem.length ) { 11916 this._open( newItem.parent() ); 11917 11918 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11919 this._delay(function() { 11920 this.focus( event, newItem ); 11921 }); 11922 } 11923 }, 11924 11925 next: function( event ) { 11926 this._move( "next", "first", event ); 11927 }, 11928 11929 previous: function( event ) { 11930 this._move( "prev", "last", event ); 11931 }, 11932 11933 isFirstItem: function() { 11934 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11935 }, 11936 11937 isLastItem: function() { 11938 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11939 }, 11940 11941 _move: function( direction, filter, event ) { 11942 var next; 11943 if ( this.active ) { 11944 if ( direction === "first" || direction === "last" ) { 11945 next = this.active 11946 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11947 .eq( -1 ); 11948 } else { 11949 next = this.active 11950 [ direction + "All" ]( ".ui-menu-item" ) 11951 .eq( 0 ); 11952 } 11953 } 11954 if ( !next || !next.length || !this.active ) { 11955 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11956 } 11957 11958 this.focus( event, next ); 11959 }, 11960 11961 nextPage: function( event ) { 11962 var item, base, height; 11963 11964 if ( !this.active ) { 11965 this.next( event ); 11966 return; 11967 } 11968 if ( this.isLastItem() ) { 11969 return; 11970 } 11971 if ( this._hasScroll() ) { 11972 base = this.active.offset().top; 11973 height = this.element.height(); 11974 this.active.nextAll( ".ui-menu-item" ).each(function() { 11975 item = $( this ); 11976 return item.offset().top - base - height < 0; 11977 }); 11978 11979 this.focus( event, item ); 11980 } else { 11981 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11982 [ !this.active ? "first" : "last" ]() ); 11983 } 11984 }, 11985 11986 previousPage: function( event ) { 11987 var item, base, height; 11988 if ( !this.active ) { 11989 this.next( event ); 11990 return; 11991 } 11992 if ( this.isFirstItem() ) { 11993 return; 11994 } 11995 if ( this._hasScroll() ) { 11996 base = this.active.offset().top; 11997 height = this.element.height(); 11998 this.active.prevAll( ".ui-menu-item" ).each(function() { 11999 item = $( this ); 12000 return item.offset().top - base + height > 0; 12001 }); 12002 12003 this.focus( event, item ); 12004 } else { 12005 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 12006 } 12007 }, 12008 12009 _hasScroll: function() { 12010 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 12011 }, 12012 12013 select: function( event ) { 12014 // TODO: It should never be possible to not have an active item at this 12015 // point, but the tests don't trigger mouseenter before click. 12016 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 12017 var ui = { item: this.active }; 12018 if ( !this.active.has( ".ui-menu" ).length ) { 12019 this.collapseAll( event, true ); 12020 } 12021 this._trigger( "select", event, ui ); 12022 } 12023}); 12024 12025}( jQuery )); 12026 12027(function( $, undefined ) { 12028 12029$.ui = $.ui || {}; 12030 12031var cachedScrollbarWidth, 12032 max = Math.max, 12033 abs = Math.abs, 12034 round = Math.round, 12035 rhorizontal = /left|center|right/, 12036 rvertical = /top|center|bottom/, 12037 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 12038 rposition = /^\w+/, 12039 rpercent = /%$/, 12040 _position = $.fn.position; 12041 12042function getOffsets( offsets, width, height ) { 12043 return [ 12044 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 12045 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 12046 ]; 12047} 12048 12049function parseCss( element, property ) { 12050 return parseInt( $.css( element, property ), 10 ) || 0; 12051} 12052 12053function getDimensions( elem ) { 12054 var raw = elem[0]; 12055 if ( raw.nodeType === 9 ) { 12056 return { 12057 width: elem.width(), 12058 height: elem.height(), 12059 offset: { top: 0, left: 0 } 12060 }; 12061 } 12062 if ( $.isWindow( raw ) ) { 12063 return { 12064 width: elem.width(), 12065 height: elem.height(), 12066 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 12067 }; 12068 } 12069 if ( raw.preventDefault ) { 12070 return { 12071 width: 0, 12072 height: 0, 12073 offset: { top: raw.pageY, left: raw.pageX } 12074 }; 12075 } 12076 return { 12077 width: elem.outerWidth(), 12078 height: elem.outerHeight(), 12079 offset: elem.offset() 12080 }; 12081} 12082 12083$.position = { 12084 scrollbarWidth: function() { 12085 if ( cachedScrollbarWidth !== undefined ) { 12086 return cachedScrollbarWidth; 12087 } 12088 var w1, w2, 12089 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 12090 innerDiv = div.children()[0]; 12091 12092 $( "body" ).append( div ); 12093 w1 = innerDiv.offsetWidth; 12094 div.css( "overflow", "scroll" ); 12095 12096 w2 = innerDiv.offsetWidth; 12097 12098 if ( w1 === w2 ) { 12099 w2 = div[0].clientWidth; 12100 } 12101 12102 div.remove(); 12103 12104 return (cachedScrollbarWidth = w1 - w2); 12105 }, 12106 getScrollInfo: function( within ) { 12107 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 12108 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 12109 hasOverflowX = overflowX === "scroll" || 12110 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 12111 hasOverflowY = overflowY === "scroll" || 12112 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 12113 return { 12114 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 12115 height: hasOverflowX ? $.position.scrollbarWidth() : 0 12116 }; 12117 }, 12118 getWithinInfo: function( element ) { 12119 var withinElement = $( element || window ), 12120 isWindow = $.isWindow( withinElement[0] ); 12121 return { 12122 element: withinElement, 12123 isWindow: isWindow, 12124 offset: withinElement.offset() || { left: 0, top: 0 }, 12125 scrollLeft: withinElement.scrollLeft(), 12126 scrollTop: withinElement.scrollTop(), 12127 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 12128 height: isWindow ? withinElement.height() : withinElement.outerHeight() 12129 }; 12130 } 12131}; 12132 12133$.fn.position = function( options ) { 12134 if ( !options || !options.of ) { 12135 return _position.apply( this, arguments ); 12136 } 12137 12138 // make a copy, we don't want to modify arguments 12139 options = $.extend( {}, options ); 12140 12141 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 12142 target = $( options.of ), 12143 within = $.position.getWithinInfo( options.within ), 12144 scrollInfo = $.position.getScrollInfo( within ), 12145 collision = ( options.collision || "flip" ).split( " " ), 12146 offsets = {}; 12147 12148 dimensions = getDimensions( target ); 12149 if ( target[0].preventDefault ) { 12150 // force left top to allow flipping 12151 options.at = "left top"; 12152 } 12153 targetWidth = dimensions.width; 12154 targetHeight = dimensions.height; 12155 targetOffset = dimensions.offset; 12156 // clone to reuse original targetOffset later 12157 basePosition = $.extend( {}, targetOffset ); 12158 12159 // force my and at to have valid horizontal and vertical positions 12160 // if a value is missing or invalid, it will be converted to center 12161 $.each( [ "my", "at" ], function() { 12162 var pos = ( options[ this ] || "" ).split( " " ), 12163 horizontalOffset, 12164 verticalOffset; 12165 12166 if ( pos.length === 1) { 12167 pos = rhorizontal.test( pos[ 0 ] ) ? 12168 pos.concat( [ "center" ] ) : 12169 rvertical.test( pos[ 0 ] ) ? 12170 [ "center" ].concat( pos ) : 12171 [ "center", "center" ]; 12172 } 12173 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 12174 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 12175 12176 // calculate offsets 12177 horizontalOffset = roffset.exec( pos[ 0 ] ); 12178 verticalOffset = roffset.exec( pos[ 1 ] ); 12179 offsets[ this ] = [ 12180 horizontalOffset ? horizontalOffset[ 0 ] : 0, 12181 verticalOffset ? verticalOffset[ 0 ] : 0 12182 ]; 12183 12184 // reduce to just the positions without the offsets 12185 options[ this ] = [ 12186 rposition.exec( pos[ 0 ] )[ 0 ], 12187 rposition.exec( pos[ 1 ] )[ 0 ] 12188 ]; 12189 }); 12190 12191 // normalize collision option 12192 if ( collision.length === 1 ) { 12193 collision[ 1 ] = collision[ 0 ]; 12194 } 12195 12196 if ( options.at[ 0 ] === "right" ) { 12197 basePosition.left += targetWidth; 12198 } else if ( options.at[ 0 ] === "center" ) { 12199 basePosition.left += targetWidth / 2; 12200 } 12201 12202 if ( options.at[ 1 ] === "bottom" ) { 12203 basePosition.top += targetHeight; 12204 } else if ( options.at[ 1 ] === "center" ) { 12205 basePosition.top += targetHeight / 2; 12206 } 12207 12208 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 12209 basePosition.left += atOffset[ 0 ]; 12210 basePosition.top += atOffset[ 1 ]; 12211 12212 return this.each(function() { 12213 var collisionPosition, using, 12214 elem = $( this ), 12215 elemWidth = elem.outerWidth(), 12216 elemHeight = elem.outerHeight(), 12217 marginLeft = parseCss( this, "marginLeft" ), 12218 marginTop = parseCss( this, "marginTop" ), 12219 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 12220 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 12221 position = $.extend( {}, basePosition ), 12222 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 12223 12224 if ( options.my[ 0 ] === "right" ) { 12225 position.left -= elemWidth; 12226 } else if ( options.my[ 0 ] === "center" ) { 12227 position.left -= elemWidth / 2; 12228 } 12229 12230 if ( options.my[ 1 ] === "bottom" ) { 12231 position.top -= elemHeight; 12232 } else if ( options.my[ 1 ] === "center" ) { 12233 position.top -= elemHeight / 2; 12234 } 12235 12236 position.left += myOffset[ 0 ]; 12237 position.top += myOffset[ 1 ]; 12238 12239 // if the browser doesn't support fractions, then round for consistent results 12240 if ( !$.support.offsetFractions ) { 12241 position.left = round( position.left ); 12242 position.top = round( position.top ); 12243 } 12244 12245 collisionPosition = { 12246 marginLeft: marginLeft, 12247 marginTop: marginTop 12248 }; 12249 12250 $.each( [ "left", "top" ], function( i, dir ) { 12251 if ( $.ui.position[ collision[ i ] ] ) { 12252 $.ui.position[ collision[ i ] ][ dir ]( position, { 12253 targetWidth: targetWidth, 12254 targetHeight: targetHeight, 12255 elemWidth: elemWidth, 12256 elemHeight: elemHeight, 12257 collisionPosition: collisionPosition, 12258 collisionWidth: collisionWidth, 12259 collisionHeight: collisionHeight, 12260 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 12261 my: options.my, 12262 at: options.at, 12263 within: within, 12264 elem : elem 12265 }); 12266 } 12267 }); 12268 12269 if ( options.using ) { 12270 // adds feedback as second argument to using callback, if present 12271 using = function( props ) { 12272 var left = targetOffset.left - position.left, 12273 right = left + targetWidth - elemWidth, 12274 top = targetOffset.top - position.top, 12275 bottom = top + targetHeight - elemHeight, 12276 feedback = { 12277 target: { 12278 element: target, 12279 left: targetOffset.left, 12280 top: targetOffset.top, 12281 width: targetWidth, 12282 height: targetHeight 12283 }, 12284 element: { 12285 element: elem, 12286 left: position.left, 12287 top: position.top, 12288 width: elemWidth, 12289 height: elemHeight 12290 }, 12291 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 12292 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 12293 }; 12294 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 12295 feedback.horizontal = "center"; 12296 } 12297 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 12298 feedback.vertical = "middle"; 12299 } 12300 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 12301 feedback.important = "horizontal"; 12302 } else { 12303 feedback.important = "vertical"; 12304 } 12305 options.using.call( this, props, feedback ); 12306 }; 12307 } 12308 12309 elem.offset( $.extend( position, { using: using } ) ); 12310 }); 12311}; 12312 12313$.ui.position = { 12314 fit: { 12315 left: function( position, data ) { 12316 var within = data.within, 12317 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 12318 outerWidth = within.width, 12319 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12320 overLeft = withinOffset - collisionPosLeft, 12321 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 12322 newOverRight; 12323 12324 // element is wider than within 12325 if ( data.collisionWidth > outerWidth ) { 12326 // element is initially over the left side of within 12327 if ( overLeft > 0 && overRight <= 0 ) { 12328 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 12329 position.left += overLeft - newOverRight; 12330 // element is initially over right side of within 12331 } else if ( overRight > 0 && overLeft <= 0 ) { 12332 position.left = withinOffset; 12333 // element is initially over both left and right sides of within 12334 } else { 12335 if ( overLeft > overRight ) { 12336 position.left = withinOffset + outerWidth - data.collisionWidth; 12337 } else { 12338 position.left = withinOffset; 12339 } 12340 } 12341 // too far left -> align with left edge 12342 } else if ( overLeft > 0 ) { 12343 position.left += overLeft; 12344 // too far right -> align with right edge 12345 } else if ( overRight > 0 ) { 12346 position.left -= overRight; 12347 // adjust based on position and margin 12348 } else { 12349 position.left = max( position.left - collisionPosLeft, position.left ); 12350 } 12351 }, 12352 top: function( position, data ) { 12353 var within = data.within, 12354 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 12355 outerHeight = data.within.height, 12356 collisionPosTop = position.top - data.collisionPosition.marginTop, 12357 overTop = withinOffset - collisionPosTop, 12358 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 12359 newOverBottom; 12360 12361 // element is taller than within 12362 if ( data.collisionHeight > outerHeight ) { 12363 // element is initially over the top of within 12364 if ( overTop > 0 && overBottom <= 0 ) { 12365 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 12366 position.top += overTop - newOverBottom; 12367 // element is initially over bottom of within 12368 } else if ( overBottom > 0 && overTop <= 0 ) { 12369 position.top = withinOffset; 12370 // element is initially over both top and bottom of within 12371 } else { 12372 if ( overTop > overBottom ) { 12373 position.top = withinOffset + outerHeight - data.collisionHeight; 12374 } else { 12375 position.top = withinOffset; 12376 } 12377 } 12378 // too far up -> align with top 12379 } else if ( overTop > 0 ) { 12380 position.top += overTop; 12381 // too far down -> align with bottom edge 12382 } else if ( overBottom > 0 ) { 12383 position.top -= overBottom; 12384 // adjust based on position and margin 12385 } else { 12386 position.top = max( position.top - collisionPosTop, position.top ); 12387 } 12388 } 12389 }, 12390 flip: { 12391 left: function( position, data ) { 12392 var within = data.within, 12393 withinOffset = within.offset.left + within.scrollLeft, 12394 outerWidth = within.width, 12395 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12396 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12397 overLeft = collisionPosLeft - offsetLeft, 12398 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12399 myOffset = data.my[ 0 ] === "left" ? 12400 -data.elemWidth : 12401 data.my[ 0 ] === "right" ? 12402 data.elemWidth : 12403 0, 12404 atOffset = data.at[ 0 ] === "left" ? 12405 data.targetWidth : 12406 data.at[ 0 ] === "right" ? 12407 -data.targetWidth : 12408 0, 12409 offset = -2 * data.offset[ 0 ], 12410 newOverRight, 12411 newOverLeft; 12412 12413 if ( overLeft < 0 ) { 12414 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 12415 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12416 position.left += myOffset + atOffset + offset; 12417 } 12418 } 12419 else if ( overRight > 0 ) { 12420 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 12421 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12422 position.left += myOffset + atOffset + offset; 12423 } 12424 } 12425 }, 12426 top: function( position, data ) { 12427 var within = data.within, 12428 withinOffset = within.offset.top + within.scrollTop, 12429 outerHeight = within.height, 12430 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12431 collisionPosTop = position.top - data.collisionPosition.marginTop, 12432 overTop = collisionPosTop - offsetTop, 12433 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12434 top = data.my[ 1 ] === "top", 12435 myOffset = top ? 12436 -data.elemHeight : 12437 data.my[ 1 ] === "bottom" ? 12438 data.elemHeight : 12439 0, 12440 atOffset = data.at[ 1 ] === "top" ? 12441 data.targetHeight : 12442 data.at[ 1 ] === "bottom" ? 12443 -data.targetHeight : 12444 0, 12445 offset = -2 * data.offset[ 1 ], 12446 newOverTop, 12447 newOverBottom; 12448 if ( overTop < 0 ) { 12449 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 12450 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 12451 position.top += myOffset + atOffset + offset; 12452 } 12453 } 12454 else if ( overBottom > 0 ) { 12455 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 12456 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 12457 position.top += myOffset + atOffset + offset; 12458 } 12459 } 12460 } 12461 }, 12462 flipfit: { 12463 left: function() { 12464 $.ui.position.flip.left.apply( this, arguments ); 12465 $.ui.position.fit.left.apply( this, arguments ); 12466 }, 12467 top: function() { 12468 $.ui.position.flip.top.apply( this, arguments ); 12469 $.ui.position.fit.top.apply( this, arguments ); 12470 } 12471 } 12472}; 12473 12474// fraction support test 12475(function () { 12476 var testElement, testElementParent, testElementStyle, offsetLeft, i, 12477 body = document.getElementsByTagName( "body" )[ 0 ], 12478 div = document.createElement( "div" ); 12479 12480 //Create a "fake body" for testing based on method used in jQuery.support 12481 testElement = document.createElement( body ? "div" : "body" ); 12482 testElementStyle = { 12483 visibility: "hidden", 12484 width: 0, 12485 height: 0, 12486 border: 0, 12487 margin: 0, 12488 background: "none" 12489 }; 12490 if ( body ) { 12491 $.extend( testElementStyle, { 12492 position: "absolute", 12493 left: "-1000px", 12494 top: "-1000px" 12495 }); 12496 } 12497 for ( i in testElementStyle ) { 12498 testElement.style[ i ] = testElementStyle[ i ]; 12499 } 12500 testElement.appendChild( div ); 12501 testElementParent = body || document.documentElement; 12502 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 12503 12504 div.style.cssText = "position: absolute; left: 10.7432222px;"; 12505 12506 offsetLeft = $( div ).offset().left; 12507 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 12508 12509 testElement.innerHTML = ""; 12510 testElementParent.removeChild( testElement ); 12511})(); 12512 12513}( jQuery ) ); 12514 12515(function( $, undefined ) { 12516 12517$.widget( "ui.progressbar", { 12518 version: "1.10.3", 12519 options: { 12520 max: 100, 12521 value: 0, 12522 12523 change: null, 12524 complete: null 12525 }, 12526 12527 min: 0, 12528 12529 _create: function() { 12530 // Constrain initial value 12531 this.oldValue = this.options.value = this._constrainedValue(); 12532 12533 this.element 12534 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12535 .attr({ 12536 // Only set static values, aria-valuenow and aria-valuemax are 12537 // set inside _refreshValue() 12538 role: "progressbar", 12539 "aria-valuemin": this.min 12540 }); 12541 12542 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12543 .appendTo( this.element ); 12544 12545 this._refreshValue(); 12546 }, 12547 12548 _destroy: function() { 12549 this.element 12550 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12551 .removeAttr( "role" ) 12552 .removeAttr( "aria-valuemin" ) 12553 .removeAttr( "aria-valuemax" ) 12554 .removeAttr( "aria-valuenow" ); 12555 12556 this.valueDiv.remove(); 12557 }, 12558 12559 value: function( newValue ) { 12560 if ( newValue === undefined ) { 12561 return this.options.value; 12562 } 12563 12564 this.options.value = this._constrainedValue( newValue ); 12565 this._refreshValue(); 12566 }, 12567 12568 _constrainedValue: function( newValue ) { 12569 if ( newValue === undefined ) { 12570 newValue = this.options.value; 12571 } 12572 12573 this.indeterminate = newValue === false; 12574 12575 // sanitize value 12576 if ( typeof newValue !== "number" ) { 12577 newValue = 0; 12578 } 12579 12580 return this.indeterminate ? false : 12581 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12582 }, 12583 12584 _setOptions: function( options ) { 12585 // Ensure "value" option is set after other values (like max) 12586 var value = options.value; 12587 delete options.value; 12588 12589 this._super( options ); 12590 12591 this.options.value = this._constrainedValue( value ); 12592 this._refreshValue(); 12593 }, 12594 12595 _setOption: function( key, value ) { 12596 if ( key === "max" ) { 12597 // Don't allow a max less than min 12598 value = Math.max( this.min, value ); 12599 } 12600 12601 this._super( key, value ); 12602 }, 12603 12604 _percentage: function() { 12605 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12606 }, 12607 12608 _refreshValue: function() { 12609 var value = this.options.value, 12610 percentage = this._percentage(); 12611 12612 this.valueDiv 12613 .toggle( this.indeterminate || value > this.min ) 12614 .toggleClass( "ui-corner-right", value === this.options.max ) 12615 .width( percentage.toFixed(0) + "%" ); 12616 12617 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12618 12619 if ( this.indeterminate ) { 12620 this.element.removeAttr( "aria-valuenow" ); 12621 if ( !this.overlayDiv ) { 12622 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12623 } 12624 } else { 12625 this.element.attr({ 12626 "aria-valuemax": this.options.max, 12627 "aria-valuenow": value 12628 }); 12629 if ( this.overlayDiv ) { 12630 this.overlayDiv.remove(); 12631 this.overlayDiv = null; 12632 } 12633 } 12634 12635 if ( this.oldValue !== value ) { 12636 this.oldValue = value; 12637 this._trigger( "change" ); 12638 } 12639 if ( value === this.options.max ) { 12640 this._trigger( "complete" ); 12641 } 12642 } 12643}); 12644 12645})( jQuery ); 12646 12647(function( $, undefined ) { 12648 12649// number of pages in a slider 12650// (how many times can you page up/down to go through the whole range) 12651var numPages = 5; 12652 12653$.widget( "ui.slider", $.ui.mouse, { 12654 version: "1.10.3", 12655 widgetEventPrefix: "slide", 12656 12657 options: { 12658 animate: false, 12659 distance: 0, 12660 max: 100, 12661 min: 0, 12662 orientation: "horizontal", 12663 range: false, 12664 step: 1, 12665 value: 0, 12666 values: null, 12667 12668 // callbacks 12669 change: null, 12670 slide: null, 12671 start: null, 12672 stop: null 12673 }, 12674 12675 _create: function() { 12676 this._keySliding = false; 12677 this._mouseSliding = false; 12678 this._animateOff = true; 12679 this._handleIndex = null; 12680 this._detectOrientation(); 12681 this._mouseInit(); 12682 12683 this.element 12684 .addClass( "ui-slider" + 12685 " ui-slider-" + this.orientation + 12686 " ui-widget" + 12687 " ui-widget-content" + 12688 " ui-corner-all"); 12689 12690 this._refresh(); 12691 this._setOption( "disabled", this.options.disabled ); 12692 12693 this._animateOff = false; 12694 }, 12695 12696 _refresh: function() { 12697 this._createRange(); 12698 this._createHandles(); 12699 this._setupEvents(); 12700 this._refreshValue(); 12701 }, 12702 12703 _createHandles: function() { 12704 var i, handleCount, 12705 options = this.options, 12706 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12707 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12708 handles = []; 12709 12710 handleCount = ( options.values && options.values.length ) || 1; 12711 12712 if ( existingHandles.length > handleCount ) { 12713 existingHandles.slice( handleCount ).remove(); 12714 existingHandles = existingHandles.slice( 0, handleCount ); 12715 } 12716 12717 for ( i = existingHandles.length; i < handleCount; i++ ) { 12718 handles.push( handle ); 12719 } 12720 12721 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12722 12723 this.handle = this.handles.eq( 0 ); 12724 12725 this.handles.each(function( i ) { 12726 $( this ).data( "ui-slider-handle-index", i ); 12727 }); 12728 }, 12729 12730 _createRange: function() { 12731 var options = this.options, 12732 classes = ""; 12733 12734 if ( options.range ) { 12735 if ( options.range === true ) { 12736 if ( !options.values ) { 12737 options.values = [ this._valueMin(), this._valueMin() ]; 12738 } else if ( options.values.length && options.values.length !== 2 ) { 12739 options.values = [ options.values[0], options.values[0] ]; 12740 } else if ( $.isArray( options.values ) ) { 12741 options.values = options.values.slice(0); 12742 } 12743 } 12744 12745 if ( !this.range || !this.range.length ) { 12746 this.range = $( "<div></div>" ) 12747 .appendTo( this.element ); 12748 12749 classes = "ui-slider-range" + 12750 // note: this isn't the most fittingly semantic framework class for this element, 12751 // but worked best visually with a variety of themes 12752 " ui-widget-header ui-corner-all"; 12753 } else { 12754 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12755 // Handle range switching from true to min/max 12756 .css({ 12757 "left": "", 12758 "bottom": "" 12759 }); 12760 } 12761 12762 this.range.addClass( classes + 12763 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12764 } else { 12765 this.range = $([]); 12766 } 12767 }, 12768 12769 _setupEvents: function() { 12770 var elements = this.handles.add( this.range ).filter( "a" ); 12771 this._off( elements ); 12772 this._on( elements, this._handleEvents ); 12773 this._hoverable( elements ); 12774 this._focusable( elements ); 12775 }, 12776 12777 _destroy: function() { 12778 this.handles.remove(); 12779 this.range.remove(); 12780 12781 this.element 12782 .removeClass( "ui-slider" + 12783 " ui-slider-horizontal" + 12784 " ui-slider-vertical" + 12785 " ui-widget" + 12786 " ui-widget-content" + 12787 " ui-corner-all" ); 12788 12789 this._mouseDestroy(); 12790 }, 12791 12792 _mouseCapture: function( event ) { 12793 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12794 that = this, 12795 o = this.options; 12796 12797 if ( o.disabled ) { 12798 return false; 12799 } 12800 12801 this.elementSize = { 12802 width: this.element.outerWidth(), 12803 height: this.element.outerHeight() 12804 }; 12805 this.elementOffset = this.element.offset(); 12806 12807 position = { x: event.pageX, y: event.pageY }; 12808 normValue = this._normValueFromMouse( position ); 12809 distance = this._valueMax() - this._valueMin() + 1; 12810 this.handles.each(function( i ) { 12811 var thisDistance = Math.abs( normValue - that.values(i) ); 12812 if (( distance > thisDistance ) || 12813 ( distance === thisDistance && 12814 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12815 distance = thisDistance; 12816 closestHandle = $( this ); 12817 index = i; 12818 } 12819 }); 12820 12821 allowed = this._start( event, index ); 12822 if ( allowed === false ) { 12823 return false; 12824 } 12825 this._mouseSliding = true; 12826 12827 this._handleIndex = index; 12828 12829 closestHandle 12830 .addClass( "ui-state-active" ) 12831 .focus(); 12832 12833 offset = closestHandle.offset(); 12834 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12835 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12836 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12837 top: event.pageY - offset.top - 12838 ( closestHandle.height() / 2 ) - 12839 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12840 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12841 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12842 }; 12843 12844 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12845 this._slide( event, index, normValue ); 12846 } 12847 this._animateOff = true; 12848 return true; 12849 }, 12850 12851 _mouseStart: function() { 12852 return true; 12853 }, 12854 12855 _mouseDrag: function( event ) { 12856 var position = { x: event.pageX, y: event.pageY }, 12857 normValue = this._normValueFromMouse( position ); 12858 12859 this._slide( event, this._handleIndex, normValue ); 12860 12861 return false; 12862 }, 12863 12864 _mouseStop: function( event ) { 12865 this.handles.removeClass( "ui-state-active" ); 12866 this._mouseSliding = false; 12867 12868 this._stop( event, this._handleIndex ); 12869 this._change( event, this._handleIndex ); 12870 12871 this._handleIndex = null; 12872 this._clickOffset = null; 12873 this._animateOff = false; 12874 12875 return false; 12876 }, 12877 12878 _detectOrientation: function() { 12879 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12880 }, 12881 12882 _normValueFromMouse: function( position ) { 12883 var pixelTotal, 12884 pixelMouse, 12885 percentMouse, 12886 valueTotal, 12887 valueMouse; 12888 12889 if ( this.orientation === "horizontal" ) { 12890 pixelTotal = this.elementSize.width; 12891 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12892 } else { 12893 pixelTotal = this.elementSize.height; 12894 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12895 } 12896 12897 percentMouse = ( pixelMouse / pixelTotal ); 12898 if ( percentMouse > 1 ) { 12899 percentMouse = 1; 12900 } 12901 if ( percentMouse < 0 ) { 12902 percentMouse = 0; 12903 } 12904 if ( this.orientation === "vertical" ) { 12905 percentMouse = 1 - percentMouse; 12906 } 12907 12908 valueTotal = this._valueMax() - this._valueMin(); 12909 valueMouse = this._valueMin() + percentMouse * valueTotal; 12910 12911 return this._trimAlignValue( valueMouse ); 12912 }, 12913 12914 _start: function( event, index ) { 12915 var uiHash = { 12916 handle: this.handles[ index ], 12917 value: this.value() 12918 }; 12919 if ( this.options.values && this.options.values.length ) { 12920 uiHash.value = this.values( index ); 12921 uiHash.values = this.values(); 12922 } 12923 return this._trigger( "start", event, uiHash ); 12924 }, 12925 12926 _slide: function( event, index, newVal ) { 12927 var otherVal, 12928 newValues, 12929 allowed; 12930 12931 if ( this.options.values && this.options.values.length ) { 12932 otherVal = this.values( index ? 0 : 1 ); 12933 12934 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12935 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12936 ) { 12937 newVal = otherVal; 12938 } 12939 12940 if ( newVal !== this.values( index ) ) { 12941 newValues = this.values(); 12942 newValues[ index ] = newVal; 12943 // A slide can be canceled by returning false from the slide callback 12944 allowed = this._trigger( "slide", event, { 12945 handle: this.handles[ index ], 12946 value: newVal, 12947 values: newValues 12948 } ); 12949 otherVal = this.values( index ? 0 : 1 ); 12950 if ( allowed !== false ) { 12951 this.values( index, newVal, true ); 12952 } 12953 } 12954 } else { 12955 if ( newVal !== this.value() ) { 12956 // A slide can be canceled by returning false from the slide callback 12957 allowed = this._trigger( "slide", event, { 12958 handle: this.handles[ index ], 12959 value: newVal 12960 } ); 12961 if ( allowed !== false ) { 12962 this.value( newVal ); 12963 } 12964 } 12965 } 12966 }, 12967 12968 _stop: function( event, index ) { 12969 var uiHash = { 12970 handle: this.handles[ index ], 12971 value: this.value() 12972 }; 12973 if ( this.options.values && this.options.values.length ) { 12974 uiHash.value = this.values( index ); 12975 uiHash.values = this.values(); 12976 } 12977 12978 this._trigger( "stop", event, uiHash ); 12979 }, 12980 12981 _change: function( event, index ) { 12982 if ( !this._keySliding && !this._mouseSliding ) { 12983 var uiHash = { 12984 handle: this.handles[ index ], 12985 value: this.value() 12986 }; 12987 if ( this.options.values && this.options.values.length ) { 12988 uiHash.value = this.values( index ); 12989 uiHash.values = this.values(); 12990 } 12991 12992 //store the last changed value index for reference when handles overlap 12993 this._lastChangedValue = index; 12994 12995 this._trigger( "change", event, uiHash ); 12996 } 12997 }, 12998 12999 value: function( newValue ) { 13000 if ( arguments.length ) { 13001 this.options.value = this._trimAlignValue( newValue ); 13002 this._refreshValue(); 13003 this._change( null, 0 ); 13004 return; 13005 } 13006 13007 return this._value(); 13008 }, 13009 13010 values: function( index, newValue ) { 13011 var vals, 13012 newValues, 13013 i; 13014 13015 if ( arguments.length > 1 ) { 13016 this.options.values[ index ] = this._trimAlignValue( newValue ); 13017 this._refreshValue(); 13018 this._change( null, index ); 13019 return; 13020 } 13021 13022 if ( arguments.length ) { 13023 if ( $.isArray( arguments[ 0 ] ) ) { 13024 vals = this.options.values; 13025 newValues = arguments[ 0 ]; 13026 for ( i = 0; i < vals.length; i += 1 ) { 13027 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13028 this._change( null, i ); 13029 } 13030 this._refreshValue(); 13031 } else { 13032 if ( this.options.values && this.options.values.length ) { 13033 return this._values( index ); 13034 } else { 13035 return this.value(); 13036 } 13037 } 13038 } else { 13039 return this._values(); 13040 } 13041 }, 13042 13043 _setOption: function( key, value ) { 13044 var i, 13045 valsLength = 0; 13046 13047 if ( key === "range" && this.options.range === true ) { 13048 if ( value === "min" ) { 13049 this.options.value = this._values( 0 ); 13050 this.options.values = null; 13051 } else if ( value === "max" ) { 13052 this.options.value = this._values( this.options.values.length-1 ); 13053 this.options.values = null; 13054 } 13055 } 13056 13057 if ( $.isArray( this.options.values ) ) { 13058 valsLength = this.options.values.length; 13059 } 13060 13061 $.Widget.prototype._setOption.apply( this, arguments ); 13062 13063 switch ( key ) { 13064 case "orientation": 13065 this._detectOrientation(); 13066 this.element 13067 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13068 .addClass( "ui-slider-" + this.orientation ); 13069 this._refreshValue(); 13070 break; 13071 case "value": 13072 this._animateOff = true; 13073 this._refreshValue(); 13074 this._change( null, 0 ); 13075 this._animateOff = false; 13076 break; 13077 case "values": 13078 this._animateOff = true; 13079 this._refreshValue(); 13080 for ( i = 0; i < valsLength; i += 1 ) { 13081 this._change( null, i ); 13082 } 13083 this._animateOff = false; 13084 break; 13085 case "min": 13086 case "max": 13087 this._animateOff = true; 13088 this._refreshValue(); 13089 this._animateOff = false; 13090 break; 13091 case "range": 13092 this._animateOff = true; 13093 this._refresh(); 13094 this._animateOff = false; 13095 break; 13096 } 13097 }, 13098 13099 //internal value getter 13100 // _value() returns value trimmed by min and max, aligned by step 13101 _value: function() { 13102 var val = this.options.value; 13103 val = this._trimAlignValue( val ); 13104 13105 return val; 13106 }, 13107 13108 //internal values getter 13109 // _values() returns array of values trimmed by min and max, aligned by step 13110 // _values( index ) returns single value trimmed by min and max, aligned by step 13111 _values: function( index ) { 13112 var val, 13113 vals, 13114 i; 13115 13116 if ( arguments.length ) { 13117 val = this.options.values[ index ]; 13118 val = this._trimAlignValue( val ); 13119 13120 return val; 13121 } else if ( this.options.values && this.options.values.length ) { 13122 // .slice() creates a copy of the array 13123 // this copy gets trimmed by min and max and then returned 13124 vals = this.options.values.slice(); 13125 for ( i = 0; i < vals.length; i+= 1) { 13126 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13127 } 13128 13129 return vals; 13130 } else { 13131 return []; 13132 } 13133 }, 13134 13135 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13136 _trimAlignValue: function( val ) { 13137 if ( val <= this._valueMin() ) { 13138 return this._valueMin(); 13139 } 13140 if ( val >= this._valueMax() ) { 13141 return this._valueMax(); 13142 } 13143 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13144 valModStep = (val - this._valueMin()) % step, 13145 alignValue = val - valModStep; 13146 13147 if ( Math.abs(valModStep) * 2 >= step ) { 13148 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13149 } 13150 13151 // Since JavaScript has problems with large floats, round 13152 // the final value to 5 digits after the decimal point (see #4124) 13153 return parseFloat( alignValue.toFixed(5) ); 13154 }, 13155 13156 _valueMin: function() { 13157 return this.options.min; 13158 }, 13159 13160 _valueMax: function() { 13161 return this.options.max; 13162 }, 13163 13164 _refreshValue: function() { 13165 var lastValPercent, valPercent, value, valueMin, valueMax, 13166 oRange = this.options.range, 13167 o = this.options, 13168 that = this, 13169 animate = ( !this._animateOff ) ? o.animate : false, 13170 _set = {}; 13171 13172 if ( this.options.values && this.options.values.length ) { 13173 this.handles.each(function( i ) { 13174 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13175 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13176 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13177 if ( that.options.range === true ) { 13178 if ( that.orientation === "horizontal" ) { 13179 if ( i === 0 ) { 13180 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13181 } 13182 if ( i === 1 ) { 13183 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13184 } 13185 } else { 13186 if ( i === 0 ) { 13187 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13188 } 13189 if ( i === 1 ) { 13190 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13191 } 13192 } 13193 } 13194 lastValPercent = valPercent; 13195 }); 13196 } else { 13197 value = this.value(); 13198 valueMin = this._valueMin(); 13199 valueMax = this._valueMax(); 13200 valPercent = ( valueMax !== valueMin ) ? 13201 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13202 0; 13203 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13204 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13205 13206 if ( oRange === "min" && this.orientation === "horizontal" ) { 13207 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13208 } 13209 if ( oRange === "max" && this.orientation === "horizontal" ) { 13210 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13211 } 13212 if ( oRange === "min" && this.orientation === "vertical" ) { 13213 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13214 } 13215 if ( oRange === "max" && this.orientation === "vertical" ) { 13216 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13217 } 13218 } 13219 }, 13220 13221 _handleEvents: { 13222 keydown: function( event ) { 13223 /*jshint maxcomplexity:25*/ 13224 var allowed, curVal, newVal, step, 13225 index = $( event.target ).data( "ui-slider-handle-index" ); 13226 13227 switch ( event.keyCode ) { 13228 case $.ui.keyCode.HOME: 13229 case $.ui.keyCode.END: 13230 case $.ui.keyCode.PAGE_UP: 13231 case $.ui.keyCode.PAGE_DOWN: 13232 case $.ui.keyCode.UP: 13233 case $.ui.keyCode.RIGHT: 13234 case $.ui.keyCode.DOWN: 13235 case $.ui.keyCode.LEFT: 13236 event.preventDefault(); 13237 if ( !this._keySliding ) { 13238 this._keySliding = true; 13239 $( event.target ).addClass( "ui-state-active" ); 13240 allowed = this._start( event, index ); 13241 if ( allowed === false ) { 13242 return; 13243 } 13244 } 13245 break; 13246 } 13247 13248 step = this.options.step; 13249 if ( this.options.values && this.options.values.length ) { 13250 curVal = newVal = this.values( index ); 13251 } else { 13252 curVal = newVal = this.value(); 13253 } 13254 13255 switch ( event.keyCode ) { 13256 case $.ui.keyCode.HOME: 13257 newVal = this._valueMin(); 13258 break; 13259 case $.ui.keyCode.END: 13260 newVal = this._valueMax(); 13261 break; 13262 case $.ui.keyCode.PAGE_UP: 13263 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13264 break; 13265 case $.ui.keyCode.PAGE_DOWN: 13266 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13267 break; 13268 case $.ui.keyCode.UP: 13269 case $.ui.keyCode.RIGHT: 13270 if ( curVal === this._valueMax() ) { 13271 return; 13272 } 13273 newVal = this._trimAlignValue( curVal + step ); 13274 break; 13275 case $.ui.keyCode.DOWN: 13276 case $.ui.keyCode.LEFT: 13277 if ( curVal === this._valueMin() ) { 13278 return; 13279 } 13280 newVal = this._trimAlignValue( curVal - step ); 13281 break; 13282 } 13283 13284 this._slide( event, index, newVal ); 13285 }, 13286 click: function( event ) { 13287 event.preventDefault(); 13288 }, 13289 keyup: function( event ) { 13290 var index = $( event.target ).data( "ui-slider-handle-index" ); 13291 13292 if ( this._keySliding ) { 13293 this._keySliding = false; 13294 this._stop( event, index ); 13295 this._change( event, index ); 13296 $( event.target ).removeClass( "ui-state-active" ); 13297 } 13298 } 13299 } 13300 13301}); 13302 13303}(jQuery)); 13304 13305(function( $ ) { 13306 13307function modifier( fn ) { 13308 return function() { 13309 var previous = this.element.val(); 13310 fn.apply( this, arguments ); 13311 this._refresh(); 13312 if ( previous !== this.element.val() ) { 13313 this._trigger( "change" ); 13314 } 13315 }; 13316} 13317 13318$.widget( "ui.spinner", { 13319 version: "1.10.3", 13320 defaultElement: "<input>", 13321 widgetEventPrefix: "spin", 13322 options: { 13323 culture: null, 13324 icons: { 13325 down: "ui-icon-triangle-1-s", 13326 up: "ui-icon-triangle-1-n" 13327 }, 13328 incremental: true, 13329 max: null, 13330 min: null, 13331 numberFormat: null, 13332 page: 10, 13333 step: 1, 13334 13335 change: null, 13336 spin: null, 13337 start: null, 13338 stop: null 13339 }, 13340 13341 _create: function() { 13342 // handle string values that need to be parsed 13343 this._setOption( "max", this.options.max ); 13344 this._setOption( "min", this.options.min ); 13345 this._setOption( "step", this.options.step ); 13346 13347 // format the value, but don't constrain 13348 this._value( this.element.val(), true ); 13349 13350 this._draw(); 13351 this._on( this._events ); 13352 this._refresh(); 13353 13354 // turning off autocomplete prevents the browser from remembering the 13355 // value when navigating through history, so we re-enable autocomplete 13356 // if the page is unloaded before the widget is destroyed. #7790 13357 this._on( this.window, { 13358 beforeunload: function() { 13359 this.element.removeAttr( "autocomplete" ); 13360 } 13361 }); 13362 }, 13363 13364 _getCreateOptions: function() { 13365 var options = {}, 13366 element = this.element; 13367 13368 $.each( [ "min", "max", "step" ], function( i, option ) { 13369 var value = element.attr( option ); 13370 if ( value !== undefined && value.length ) { 13371 options[ option ] = value; 13372 } 13373 }); 13374 13375 return options; 13376 }, 13377 13378 _events: { 13379 keydown: function( event ) { 13380 if ( this._start( event ) && this._keydown( event ) ) { 13381 event.preventDefault(); 13382 } 13383 }, 13384 keyup: "_stop", 13385 focus: function() { 13386 this.previous = this.element.val(); 13387 }, 13388 blur: function( event ) { 13389 if ( this.cancelBlur ) { 13390 delete this.cancelBlur; 13391 return; 13392 } 13393 13394 this._stop(); 13395 this._refresh(); 13396 if ( this.previous !== this.element.val() ) { 13397 this._trigger( "change", event ); 13398 } 13399 }, 13400 mousewheel: function( event, delta ) { 13401 if ( !delta ) { 13402 return; 13403 } 13404 if ( !this.spinning && !this._start( event ) ) { 13405 return false; 13406 } 13407 13408 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13409 clearTimeout( this.mousewheelTimer ); 13410 this.mousewheelTimer = this._delay(function() { 13411 if ( this.spinning ) { 13412 this._stop( event ); 13413 } 13414 }, 100 ); 13415 event.preventDefault(); 13416 }, 13417 "mousedown .ui-spinner-button": function( event ) { 13418 var previous; 13419 13420 // We never want the buttons to have focus; whenever the user is 13421 // interacting with the spinner, the focus should be on the input. 13422 // If the input is focused then this.previous is properly set from 13423 // when the input first received focus. If the input is not focused 13424 // then we need to set this.previous based on the value before spinning. 13425 previous = this.element[0] === this.document[0].activeElement ? 13426 this.previous : this.element.val(); 13427 function checkFocus() { 13428 var isActive = this.element[0] === this.document[0].activeElement; 13429 if ( !isActive ) { 13430 this.element.focus(); 13431 this.previous = previous; 13432 // support: IE 13433 // IE sets focus asynchronously, so we need to check if focus 13434 // moved off of the input because the user clicked on the button. 13435 this._delay(function() { 13436 this.previous = previous; 13437 }); 13438 } 13439 } 13440 13441 // ensure focus is on (or stays on) the text field 13442 event.preventDefault(); 13443 checkFocus.call( this ); 13444 13445 // support: IE 13446 // IE doesn't prevent moving focus even with event.preventDefault() 13447 // so we set a flag to know when we should ignore the blur event 13448 // and check (again) if focus moved off of the input. 13449 this.cancelBlur = true; 13450 this._delay(function() { 13451 delete this.cancelBlur; 13452 checkFocus.call( this ); 13453 }); 13454 13455 if ( this._start( event ) === false ) { 13456 return; 13457 } 13458 13459 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13460 }, 13461 "mouseup .ui-spinner-button": "_stop", 13462 "mouseenter .ui-spinner-button": function( event ) { 13463 // button will add ui-state-active if mouse was down while mouseleave and kept down 13464 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13465 return; 13466 } 13467 13468 if ( this._start( event ) === false ) { 13469 return false; 13470 } 13471 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13472 }, 13473 // TODO: do we really want to consider this a stop? 13474 // shouldn't we just stop the repeater and wait until mouseup before 13475 // we trigger the stop event? 13476 "mouseleave .ui-spinner-button": "_stop" 13477 }, 13478 13479 _draw: function() { 13480 var uiSpinner = this.uiSpinner = this.element 13481 .addClass( "ui-spinner-input" ) 13482 .attr( "autocomplete", "off" ) 13483 .wrap( this._uiSpinnerHtml() ) 13484 .parent() 13485 // add buttons 13486 .append( this._buttonHtml() ); 13487 13488 this.element.attr( "role", "spinbutton" ); 13489 13490 // button bindings 13491 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13492 .attr( "tabIndex", -1 ) 13493 .button() 13494 .removeClass( "ui-corner-all" ); 13495 13496 // IE 6 doesn't understand height: 50% for the buttons 13497 // unless the wrapper has an explicit height 13498 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13499 uiSpinner.height() > 0 ) { 13500 uiSpinner.height( uiSpinner.height() ); 13501 } 13502 13503 // disable spinner if element was already disabled 13504 if ( this.options.disabled ) { 13505 this.disable(); 13506 } 13507 }, 13508 13509 _keydown: function( event ) { 13510 var options = this.options, 13511 keyCode = $.ui.keyCode; 13512 13513 switch ( event.keyCode ) { 13514 case keyCode.UP: 13515 this._repeat( null, 1, event ); 13516 return true; 13517 case keyCode.DOWN: 13518 this._repeat( null, -1, event ); 13519 return true; 13520 case keyCode.PAGE_UP: 13521 this._repeat( null, options.page, event ); 13522 return true; 13523 case keyCode.PAGE_DOWN: 13524 this._repeat( null, -options.page, event ); 13525 return true; 13526 } 13527 13528 return false; 13529 }, 13530 13531 _uiSpinnerHtml: function() { 13532 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13533 }, 13534 13535 _buttonHtml: function() { 13536 return "" + 13537 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13538 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13539 "</a>" + 13540 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13541 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13542 "</a>"; 13543 }, 13544 13545 _start: function( event ) { 13546 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13547 return false; 13548 } 13549 13550 if ( !this.counter ) { 13551 this.counter = 1; 13552 } 13553 this.spinning = true; 13554 return true; 13555 }, 13556 13557 _repeat: function( i, steps, event ) { 13558 i = i || 500; 13559 13560 clearTimeout( this.timer ); 13561 this.timer = this._delay(function() { 13562 this._repeat( 40, steps, event ); 13563 }, i ); 13564 13565 this._spin( steps * this.options.step, event ); 13566 }, 13567 13568 _spin: function( step, event ) { 13569 var value = this.value() || 0; 13570 13571 if ( !this.counter ) { 13572 this.counter = 1; 13573 } 13574 13575 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13576 13577 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13578 this._value( value ); 13579 this.counter++; 13580 } 13581 }, 13582 13583 _increment: function( i ) { 13584 var incremental = this.options.incremental; 13585 13586 if ( incremental ) { 13587 return $.isFunction( incremental ) ? 13588 incremental( i ) : 13589 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13590 } 13591 13592 return 1; 13593 }, 13594 13595 _precision: function() { 13596 var precision = this._precisionOf( this.options.step ); 13597 if ( this.options.min !== null ) { 13598 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13599 } 13600 return precision; 13601 }, 13602 13603 _precisionOf: function( num ) { 13604 var str = num.toString(), 13605 decimal = str.indexOf( "." ); 13606 return decimal === -1 ? 0 : str.length - decimal - 1; 13607 }, 13608 13609 _adjustValue: function( value ) { 13610 var base, aboveMin, 13611 options = this.options; 13612 13613 // make sure we're at a valid step 13614 // - find out where we are relative to the base (min or 0) 13615 base = options.min !== null ? options.min : 0; 13616 aboveMin = value - base; 13617 // - round to the nearest step 13618 aboveMin = Math.round(aboveMin / options.step) * options.step; 13619 // - rounding is based on 0, so adjust back to our base 13620 value = base + aboveMin; 13621 13622 // fix precision from bad JS floating point math 13623 value = parseFloat( value.toFixed( this._precision() ) ); 13624 13625 // clamp the value 13626 if ( options.max !== null && value > options.max) { 13627 return options.max; 13628 } 13629 if ( options.min !== null && value < options.min ) { 13630 return options.min; 13631 } 13632 13633 return value; 13634 }, 13635 13636 _stop: function( event ) { 13637 if ( !this.spinning ) { 13638 return; 13639 } 13640 13641 clearTimeout( this.timer ); 13642 clearTimeout( this.mousewheelTimer ); 13643 this.counter = 0; 13644 this.spinning = false; 13645 this._trigger( "stop", event ); 13646 }, 13647 13648 _setOption: function( key, value ) { 13649 if ( key === "culture" || key === "numberFormat" ) { 13650 var prevValue = this._parse( this.element.val() ); 13651 this.options[ key ] = value; 13652 this.element.val( this._format( prevValue ) ); 13653 return; 13654 } 13655 13656 if ( key === "max" || key === "min" || key === "step" ) { 13657 if ( typeof value === "string" ) { 13658 value = this._parse( value ); 13659 } 13660 } 13661 if ( key === "icons" ) { 13662 this.buttons.first().find( ".ui-icon" ) 13663 .removeClass( this.options.icons.up ) 13664 .addClass( value.up ); 13665 this.buttons.last().find( ".ui-icon" ) 13666 .removeClass( this.options.icons.down ) 13667 .addClass( value.down ); 13668 } 13669 13670 this._super( key, value ); 13671 13672 if ( key === "disabled" ) { 13673 if ( value ) { 13674 this.element.prop( "disabled", true ); 13675 this.buttons.button( "disable" ); 13676 } else { 13677 this.element.prop( "disabled", false ); 13678 this.buttons.button( "enable" ); 13679 } 13680 } 13681 }, 13682 13683 _setOptions: modifier(function( options ) { 13684 this._super( options ); 13685 this._value( this.element.val() ); 13686 }), 13687 13688 _parse: function( val ) { 13689 if ( typeof val === "string" && val !== "" ) { 13690 val = window.Globalize && this.options.numberFormat ? 13691 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13692 } 13693 return val === "" || isNaN( val ) ? null : val; 13694 }, 13695 13696 _format: function( value ) { 13697 if ( value === "" ) { 13698 return ""; 13699 } 13700 return window.Globalize && this.options.numberFormat ? 13701 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13702 value; 13703 }, 13704 13705 _refresh: function() { 13706 this.element.attr({ 13707 "aria-valuemin": this.options.min, 13708 "aria-valuemax": this.options.max, 13709 // TODO: what should we do with values that can't be parsed? 13710 "aria-valuenow": this._parse( this.element.val() ) 13711 }); 13712 }, 13713 13714 // update the value without triggering change 13715 _value: function( value, allowAny ) { 13716 var parsed; 13717 if ( value !== "" ) { 13718 parsed = this._parse( value ); 13719 if ( parsed !== null ) { 13720 if ( !allowAny ) { 13721 parsed = this._adjustValue( parsed ); 13722 } 13723 value = this._format( parsed ); 13724 } 13725 } 13726 this.element.val( value ); 13727 this._refresh(); 13728 }, 13729 13730 _destroy: function() { 13731 this.element 13732 .removeClass( "ui-spinner-input" ) 13733 .prop( "disabled", false ) 13734 .removeAttr( "autocomplete" ) 13735 .removeAttr( "role" ) 13736 .removeAttr( "aria-valuemin" ) 13737 .removeAttr( "aria-valuemax" ) 13738 .removeAttr( "aria-valuenow" ); 13739 this.uiSpinner.replaceWith( this.element ); 13740 }, 13741 13742 stepUp: modifier(function( steps ) { 13743 this._stepUp( steps ); 13744 }), 13745 _stepUp: function( steps ) { 13746 if ( this._start() ) { 13747 this._spin( (steps || 1) * this.options.step ); 13748 this._stop(); 13749 } 13750 }, 13751 13752 stepDown: modifier(function( steps ) { 13753 this._stepDown( steps ); 13754 }), 13755 _stepDown: function( steps ) { 13756 if ( this._start() ) { 13757 this._spin( (steps || 1) * -this.options.step ); 13758 this._stop(); 13759 } 13760 }, 13761 13762 pageUp: modifier(function( pages ) { 13763 this._stepUp( (pages || 1) * this.options.page ); 13764 }), 13765 13766 pageDown: modifier(function( pages ) { 13767 this._stepDown( (pages || 1) * this.options.page ); 13768 }), 13769 13770 value: function( newVal ) { 13771 if ( !arguments.length ) { 13772 return this._parse( this.element.val() ); 13773 } 13774 modifier( this._value ).call( this, newVal ); 13775 }, 13776 13777 widget: function() { 13778 return this.uiSpinner; 13779 } 13780}); 13781 13782}( jQuery ) ); 13783 13784(function( $, undefined ) { 13785 13786var tabId = 0, 13787 rhash = /#.*$/; 13788 13789function getNextTabId() { 13790 return ++tabId; 13791} 13792 13793function isLocal( anchor ) { 13794 return anchor.hash.length > 1 && 13795 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13796 decodeURIComponent( location.href.replace( rhash, "" ) ); 13797} 13798 13799$.widget( "ui.tabs", { 13800 version: "1.10.3", 13801 delay: 300, 13802 options: { 13803 active: null, 13804 collapsible: false, 13805 event: "click", 13806 heightStyle: "content", 13807 hide: null, 13808 show: null, 13809 13810 // callbacks 13811 activate: null, 13812 beforeActivate: null, 13813 beforeLoad: null, 13814 load: null 13815 }, 13816 13817 _create: function() { 13818 var that = this, 13819 options = this.options; 13820 13821 this.running = false; 13822 13823 this.element 13824 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13825 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13826 // Prevent users from focusing disabled tabs via click 13827 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13828 if ( $( this ).is( ".ui-state-disabled" ) ) { 13829 event.preventDefault(); 13830 } 13831 }) 13832 // support: IE <9 13833 // Preventing the default action in mousedown doesn't prevent IE 13834 // from focusing the element, so if the anchor gets focused, blur. 13835 // We don't have to worry about focusing the previously focused 13836 // element since clicking on a non-focusable element should focus 13837 // the body anyway. 13838 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13839 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13840 this.blur(); 13841 } 13842 }); 13843 13844 this._processTabs(); 13845 options.active = this._initialActive(); 13846 13847 // Take disabling tabs via class attribute from HTML 13848 // into account and update option properly. 13849 if ( $.isArray( options.disabled ) ) { 13850 options.disabled = $.unique( options.disabled.concat( 13851 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13852 return that.tabs.index( li ); 13853 }) 13854 ) ).sort(); 13855 } 13856 13857 // check for length avoids error when initializing empty list 13858 if ( this.options.active !== false && this.anchors.length ) { 13859 this.active = this._findActive( options.active ); 13860 } else { 13861 this.active = $(); 13862 } 13863 13864 this._refresh(); 13865 13866 if ( this.active.length ) { 13867 this.load( options.active ); 13868 } 13869 }, 13870 13871 _initialActive: function() { 13872 var active = this.options.active, 13873 collapsible = this.options.collapsible, 13874 locationHash = location.hash.substring( 1 ); 13875 13876 if ( active === null ) { 13877 // check the fragment identifier in the URL 13878 if ( locationHash ) { 13879 this.tabs.each(function( i, tab ) { 13880 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13881 active = i; 13882 return false; 13883 } 13884 }); 13885 } 13886 13887 // check for a tab marked active via a class 13888 if ( active === null ) { 13889 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13890 } 13891 13892 // no active tab, set to false 13893 if ( active === null || active === -1 ) { 13894 active = this.tabs.length ? 0 : false; 13895 } 13896 } 13897 13898 // handle numbers: negative, out of range 13899 if ( active !== false ) { 13900 active = this.tabs.index( this.tabs.eq( active ) ); 13901 if ( active === -1 ) { 13902 active = collapsible ? false : 0; 13903 } 13904 } 13905 13906 // don't allow collapsible: false and active: false 13907 if ( !collapsible && active === false && this.anchors.length ) { 13908 active = 0; 13909 } 13910 13911 return active; 13912 }, 13913 13914 _getCreateEventData: function() { 13915 return { 13916 tab: this.active, 13917 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13918 }; 13919 }, 13920 13921 _tabKeydown: function( event ) { 13922 /*jshint maxcomplexity:15*/ 13923 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13924 selectedIndex = this.tabs.index( focusedTab ), 13925 goingForward = true; 13926 13927 if ( this._handlePageNav( event ) ) { 13928 return; 13929 } 13930 13931 switch ( event.keyCode ) { 13932 case $.ui.keyCode.RIGHT: 13933 case $.ui.keyCode.DOWN: 13934 selectedIndex++; 13935 break; 13936 case $.ui.keyCode.UP: 13937 case $.ui.keyCode.LEFT: 13938 goingForward = false; 13939 selectedIndex--; 13940 break; 13941 case $.ui.keyCode.END: 13942 selectedIndex = this.anchors.length - 1; 13943 break; 13944 case $.ui.keyCode.HOME: 13945 selectedIndex = 0; 13946 break; 13947 case $.ui.keyCode.SPACE: 13948 // Activate only, no collapsing 13949 event.preventDefault(); 13950 clearTimeout( this.activating ); 13951 this._activate( selectedIndex ); 13952 return; 13953 case $.ui.keyCode.ENTER: 13954 // Toggle (cancel delayed activation, allow collapsing) 13955 event.preventDefault(); 13956 clearTimeout( this.activating ); 13957 // Determine if we should collapse or activate 13958 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13959 return; 13960 default: 13961 return; 13962 } 13963 13964 // Focus the appropriate tab, based on which key was pressed 13965 event.preventDefault(); 13966 clearTimeout( this.activating ); 13967 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13968 13969 // Navigating with control key will prevent automatic activation 13970 if ( !event.ctrlKey ) { 13971 // Update aria-selected immediately so that AT think the tab is already selected. 13972 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13973 // but the tab will already be activated by the time the announcement finishes. 13974 focusedTab.attr( "aria-selected", "false" ); 13975 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13976 13977 this.activating = this._delay(function() { 13978 this.option( "active", selectedIndex ); 13979 }, this.delay ); 13980 } 13981 }, 13982 13983 _panelKeydown: function( event ) { 13984 if ( this._handlePageNav( event ) ) { 13985 return; 13986 } 13987 13988 // Ctrl+up moves focus to the current tab 13989 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13990 event.preventDefault(); 13991 this.active.focus(); 13992 } 13993 }, 13994 13995 // Alt+page up/down moves focus to the previous/next tab (and activates) 13996 _handlePageNav: function( event ) { 13997 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13998 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13999 return true; 14000 } 14001 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14002 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14003 return true; 14004 } 14005 }, 14006 14007 _findNextTab: function( index, goingForward ) { 14008 var lastTabIndex = this.tabs.length - 1; 14009 14010 function constrain() { 14011 if ( index > lastTabIndex ) { 14012 index = 0; 14013 } 14014 if ( index < 0 ) { 14015 index = lastTabIndex; 14016 } 14017 return index; 14018 } 14019 14020 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14021 index = goingForward ? index + 1 : index - 1; 14022 } 14023 14024 return index; 14025 }, 14026 14027 _focusNextTab: function( index, goingForward ) { 14028 index = this._findNextTab( index, goingForward ); 14029 this.tabs.eq( index ).focus(); 14030 return index; 14031 }, 14032 14033 _setOption: function( key, value ) { 14034 if ( key === "active" ) { 14035 // _activate() will handle invalid values and update this.options 14036 this._activate( value ); 14037 return; 14038 } 14039 14040 if ( key === "disabled" ) { 14041 // don't use the widget factory's disabled handling 14042 this._setupDisabled( value ); 14043 return; 14044 } 14045 14046 this._super( key, value); 14047 14048 if ( key === "collapsible" ) { 14049 this.element.toggleClass( "ui-tabs-collapsible", value ); 14050 // Setting collapsible: false while collapsed; open first panel 14051 if ( !value && this.options.active === false ) { 14052 this._activate( 0 ); 14053 } 14054 } 14055 14056 if ( key === "event" ) { 14057 this._setupEvents( value ); 14058 } 14059 14060 if ( key === "heightStyle" ) { 14061 this._setupHeightStyle( value ); 14062 } 14063 }, 14064 14065 _tabId: function( tab ) { 14066 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14067 }, 14068 14069 _sanitizeSelector: function( hash ) { 14070 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14071 }, 14072 14073 refresh: function() { 14074 var options = this.options, 14075 lis = this.tablist.children( ":has(a[href])" ); 14076 14077 // get disabled tabs from class attribute from HTML 14078 // this will get converted to a boolean if needed in _refresh() 14079 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14080 return lis.index( tab ); 14081 }); 14082 14083 this._processTabs(); 14084 14085 // was collapsed or no tabs 14086 if ( options.active === false || !this.anchors.length ) { 14087 options.active = false; 14088 this.active = $(); 14089 // was active, but active tab is gone 14090 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14091 // all remaining tabs are disabled 14092 if ( this.tabs.length === options.disabled.length ) { 14093 options.active = false; 14094 this.active = $(); 14095 // activate previous tab 14096 } else { 14097 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14098 } 14099 // was active, active tab still exists 14100 } else { 14101 // make sure active index is correct 14102 options.active = this.tabs.index( this.active ); 14103 } 14104 14105 this._refresh(); 14106 }, 14107 14108 _refresh: function() { 14109 this._setupDisabled( this.options.disabled ); 14110 this._setupEvents( this.options.event ); 14111 this._setupHeightStyle( this.options.heightStyle ); 14112 14113 this.tabs.not( this.active ).attr({ 14114 "aria-selected": "false", 14115 tabIndex: -1 14116 }); 14117 this.panels.not( this._getPanelForTab( this.active ) ) 14118 .hide() 14119 .attr({ 14120 "aria-expanded": "false", 14121 "aria-hidden": "true" 14122 }); 14123 14124 // Make sure one tab is in the tab order 14125 if ( !this.active.length ) { 14126 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14127 } else { 14128 this.active 14129 .addClass( "ui-tabs-active ui-state-active" ) 14130 .attr({ 14131 "aria-selected": "true", 14132 tabIndex: 0 14133 }); 14134 this._getPanelForTab( this.active ) 14135 .show() 14136 .attr({ 14137 "aria-expanded": "true", 14138 "aria-hidden": "false" 14139 }); 14140 } 14141 }, 14142 14143 _processTabs: function() { 14144 var that = this; 14145 14146 this.tablist = this._getList() 14147 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14148 .attr( "role", "tablist" ); 14149 14150 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14151 .addClass( "ui-state-default ui-corner-top" ) 14152 .attr({ 14153 role: "tab", 14154 tabIndex: -1 14155 }); 14156 14157 this.anchors = this.tabs.map(function() { 14158 return $( "a", this )[ 0 ]; 14159 }) 14160 .addClass( "ui-tabs-anchor" ) 14161 .attr({ 14162 role: "presentation", 14163 tabIndex: -1 14164 }); 14165 14166 this.panels = $(); 14167 14168 this.anchors.each(function( i, anchor ) { 14169 var selector, panel, panelId, 14170 anchorId = $( anchor ).uniqueId().attr( "id" ), 14171 tab = $( anchor ).closest( "li" ), 14172 originalAriaControls = tab.attr( "aria-controls" ); 14173 14174 // inline tab 14175 if ( isLocal( anchor ) ) { 14176 selector = anchor.hash; 14177 panel = that.element.find( that._sanitizeSelector( selector ) ); 14178 // remote tab 14179 } else { 14180 panelId = that._tabId( tab ); 14181 selector = "#" + panelId; 14182 panel = that.element.find( selector ); 14183 if ( !panel.length ) { 14184 panel = that._createPanel( panelId ); 14185 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14186 } 14187 panel.attr( "aria-live", "polite" ); 14188 } 14189 14190 if ( panel.length) { 14191 that.panels = that.panels.add( panel ); 14192 } 14193 if ( originalAriaControls ) { 14194 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14195 } 14196 tab.attr({ 14197 "aria-controls": selector.substring( 1 ), 14198 "aria-labelledby": anchorId 14199 }); 14200 panel.attr( "aria-labelledby", anchorId ); 14201 }); 14202 14203 this.panels 14204 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14205 .attr( "role", "tabpanel" ); 14206 }, 14207 14208 // allow overriding how to find the list for rare usage scenarios (#7715) 14209 _getList: function() { 14210 return this.element.find( "ol,ul" ).eq( 0 ); 14211 }, 14212 14213 _createPanel: function( id ) { 14214 return $( "<div>" ) 14215 .attr( "id", id ) 14216 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14217 .data( "ui-tabs-destroy", true ); 14218 }, 14219 14220 _setupDisabled: function( disabled ) { 14221 if ( $.isArray( disabled ) ) { 14222 if ( !disabled.length ) { 14223 disabled = false; 14224 } else if ( disabled.length === this.anchors.length ) { 14225 disabled = true; 14226 } 14227 } 14228 14229 // disable tabs 14230 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14231 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14232 $( li ) 14233 .addClass( "ui-state-disabled" ) 14234 .attr( "aria-disabled", "true" ); 14235 } else { 14236 $( li ) 14237 .removeClass( "ui-state-disabled" ) 14238 .removeAttr( "aria-disabled" ); 14239 } 14240 } 14241 14242 this.options.disabled = disabled; 14243 }, 14244 14245 _setupEvents: function( event ) { 14246 var events = { 14247 click: function( event ) { 14248 event.preventDefault(); 14249 } 14250 }; 14251 if ( event ) { 14252 $.each( event.split(" "), function( index, eventName ) { 14253 events[ eventName ] = "_eventHandler"; 14254 }); 14255 } 14256 14257 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14258 this._on( this.anchors, events ); 14259 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14260 this._on( this.panels, { keydown: "_panelKeydown" } ); 14261 14262 this._focusable( this.tabs ); 14263 this._hoverable( this.tabs ); 14264 }, 14265 14266 _setupHeightStyle: function( heightStyle ) { 14267 var maxHeight, 14268 parent = this.element.parent(); 14269 14270 if ( heightStyle === "fill" ) { 14271 maxHeight = parent.height(); 14272 maxHeight -= this.element.outerHeight() - this.element.height(); 14273 14274 this.element.siblings( ":visible" ).each(function() { 14275 var elem = $( this ), 14276 position = elem.css( "position" ); 14277 14278 if ( position === "absolute" || position === "fixed" ) { 14279 return; 14280 } 14281 maxHeight -= elem.outerHeight( true ); 14282 }); 14283 14284 this.element.children().not( this.panels ).each(function() { 14285 maxHeight -= $( this ).outerHeight( true ); 14286 }); 14287 14288 this.panels.each(function() { 14289 $( this ).height( Math.max( 0, maxHeight - 14290 $( this ).innerHeight() + $( this ).height() ) ); 14291 }) 14292 .css( "overflow", "auto" ); 14293 } else if ( heightStyle === "auto" ) { 14294 maxHeight = 0; 14295 this.panels.each(function() { 14296 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14297 }).height( maxHeight ); 14298 } 14299 }, 14300 14301 _eventHandler: function( event ) { 14302 var options = this.options, 14303 active = this.active, 14304 anchor = $( event.currentTarget ), 14305 tab = anchor.closest( "li" ), 14306 clickedIsActive = tab[ 0 ] === active[ 0 ], 14307 collapsing = clickedIsActive && options.collapsible, 14308 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14309 toHide = !active.length ? $() : this._getPanelForTab( active ), 14310 eventData = { 14311 oldTab: active, 14312 oldPanel: toHide, 14313 newTab: collapsing ? $() : tab, 14314 newPanel: toShow 14315 }; 14316 14317 event.preventDefault(); 14318 14319 if ( tab.hasClass( "ui-state-disabled" ) || 14320 // tab is already loading 14321 tab.hasClass( "ui-tabs-loading" ) || 14322 // can't switch durning an animation 14323 this.running || 14324 // click on active header, but not collapsible 14325 ( clickedIsActive && !options.collapsible ) || 14326 // allow canceling activation 14327 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14328 return; 14329 } 14330 14331 options.active = collapsing ? false : this.tabs.index( tab ); 14332 14333 this.active = clickedIsActive ? $() : tab; 14334 if ( this.xhr ) { 14335 this.xhr.abort(); 14336 } 14337 14338 if ( !toHide.length && !toShow.length ) { 14339 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14340 } 14341 14342 if ( toShow.length ) { 14343 this.load( this.tabs.index( tab ), event ); 14344 } 14345 this._toggle( event, eventData ); 14346 }, 14347 14348 // handles show/hide for selecting tabs 14349 _toggle: function( event, eventData ) { 14350 var that = this, 14351 toShow = eventData.newPanel, 14352 toHide = eventData.oldPanel; 14353 14354 this.running = true; 14355 14356 function complete() { 14357 that.running = false; 14358 that._trigger( "activate", event, eventData ); 14359 } 14360 14361 function show() { 14362 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14363 14364 if ( toShow.length && that.options.show ) { 14365 that._show( toShow, that.options.show, complete ); 14366 } else { 14367 toShow.show(); 14368 complete(); 14369 } 14370 } 14371 14372 // start out by hiding, then showing, then completing 14373 if ( toHide.length && this.options.hide ) { 14374 this._hide( toHide, this.options.hide, function() { 14375 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14376 show(); 14377 }); 14378 } else { 14379 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14380 toHide.hide(); 14381 show(); 14382 } 14383 14384 toHide.attr({ 14385 "aria-expanded": "false", 14386 "aria-hidden": "true" 14387 }); 14388 eventData.oldTab.attr( "aria-selected", "false" ); 14389 // If we're switching tabs, remove the old tab from the tab order. 14390 // If we're opening from collapsed state, remove the previous tab from the tab order. 14391 // If we're collapsing, then keep the collapsing tab in the tab order. 14392 if ( toShow.length && toHide.length ) { 14393 eventData.oldTab.attr( "tabIndex", -1 ); 14394 } else if ( toShow.length ) { 14395 this.tabs.filter(function() { 14396 return $( this ).attr( "tabIndex" ) === 0; 14397 }) 14398 .attr( "tabIndex", -1 ); 14399 } 14400 14401 toShow.attr({ 14402 "aria-expanded": "true", 14403 "aria-hidden": "false" 14404 }); 14405 eventData.newTab.attr({ 14406 "aria-selected": "true", 14407 tabIndex: 0 14408 }); 14409 }, 14410 14411 _activate: function( index ) { 14412 var anchor, 14413 active = this._findActive( index ); 14414 14415 // trying to activate the already active panel 14416 if ( active[ 0 ] === this.active[ 0 ] ) { 14417 return; 14418 } 14419 14420 // trying to collapse, simulate a click on the current active header 14421 if ( !active.length ) { 14422 active = this.active; 14423 } 14424 14425 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14426 this._eventHandler({ 14427 target: anchor, 14428 currentTarget: anchor, 14429 preventDefault: $.noop 14430 }); 14431 }, 14432 14433 _findActive: function( index ) { 14434 return index === false ? $() : this.tabs.eq( index ); 14435 }, 14436 14437 _getIndex: function( index ) { 14438 // meta-function to give users option to provide a href string instead of a numerical index. 14439 if ( typeof index === "string" ) { 14440 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14441 } 14442 14443 return index; 14444 }, 14445 14446 _destroy: function() { 14447 if ( this.xhr ) { 14448 this.xhr.abort(); 14449 } 14450 14451 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14452 14453 this.tablist 14454 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14455 .removeAttr( "role" ); 14456 14457 this.anchors 14458 .removeClass( "ui-tabs-anchor" ) 14459 .removeAttr( "role" ) 14460 .removeAttr( "tabIndex" ) 14461 .removeUniqueId(); 14462 14463 this.tabs.add( this.panels ).each(function() { 14464 if ( $.data( this, "ui-tabs-destroy" ) ) { 14465 $( this ).remove(); 14466 } else { 14467 $( this ) 14468 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14469 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14470 .removeAttr( "tabIndex" ) 14471 .removeAttr( "aria-live" ) 14472 .removeAttr( "aria-busy" ) 14473 .removeAttr( "aria-selected" ) 14474 .removeAttr( "aria-labelledby" ) 14475 .removeAttr( "aria-hidden" ) 14476 .removeAttr( "aria-expanded" ) 14477 .removeAttr( "role" ); 14478 } 14479 }); 14480 14481 this.tabs.each(function() { 14482 var li = $( this ), 14483 prev = li.data( "ui-tabs-aria-controls" ); 14484 if ( prev ) { 14485 li 14486 .attr( "aria-controls", prev ) 14487 .removeData( "ui-tabs-aria-controls" ); 14488 } else { 14489 li.removeAttr( "aria-controls" ); 14490 } 14491 }); 14492 14493 this.panels.show(); 14494 14495 if ( this.options.heightStyle !== "content" ) { 14496 this.panels.css( "height", "" ); 14497 } 14498 }, 14499 14500 enable: function( index ) { 14501 var disabled = this.options.disabled; 14502 if ( disabled === false ) { 14503 return; 14504 } 14505 14506 if ( index === undefined ) { 14507 disabled = false; 14508 } else { 14509 index = this._getIndex( index ); 14510 if ( $.isArray( disabled ) ) { 14511 disabled = $.map( disabled, function( num ) { 14512 return num !== index ? num : null; 14513 }); 14514 } else { 14515 disabled = $.map( this.tabs, function( li, num ) { 14516 return num !== index ? num : null; 14517 }); 14518 } 14519 } 14520 this._setupDisabled( disabled ); 14521 }, 14522 14523 disable: function( index ) { 14524 var disabled = this.options.disabled; 14525 if ( disabled === true ) { 14526 return; 14527 } 14528 14529 if ( index === undefined ) { 14530 disabled = true; 14531 } else { 14532 index = this._getIndex( index ); 14533 if ( $.inArray( index, disabled ) !== -1 ) { 14534 return; 14535 } 14536 if ( $.isArray( disabled ) ) { 14537 disabled = $.merge( [ index ], disabled ).sort(); 14538 } else { 14539 disabled = [ index ]; 14540 } 14541 } 14542 this._setupDisabled( disabled ); 14543 }, 14544 14545 load: function( index, event ) { 14546 index = this._getIndex( index ); 14547 var that = this, 14548 tab = this.tabs.eq( index ), 14549 anchor = tab.find( ".ui-tabs-anchor" ), 14550 panel = this._getPanelForTab( tab ), 14551 eventData = { 14552 tab: tab, 14553 panel: panel 14554 }; 14555 14556 // not remote 14557 if ( isLocal( anchor[ 0 ] ) ) { 14558 return; 14559 } 14560 14561 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14562 14563 // support: jQuery <1.8 14564 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14565 // but as of 1.8, $.ajax() always returns a jqXHR object. 14566 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14567 tab.addClass( "ui-tabs-loading" ); 14568 panel.attr( "aria-busy", "true" ); 14569 14570 this.xhr 14571 .success(function( response ) { 14572 // support: jQuery <1.8 14573 // http://bugs.jquery.com/ticket/11778 14574 setTimeout(function() { 14575 panel.html( response ); 14576 that._trigger( "load", event, eventData ); 14577 }, 1 ); 14578 }) 14579 .complete(function( jqXHR, status ) { 14580 // support: jQuery <1.8 14581 // http://bugs.jquery.com/ticket/11778 14582 setTimeout(function() { 14583 if ( status === "abort" ) { 14584 that.panels.stop( false, true ); 14585 } 14586 14587 tab.removeClass( "ui-tabs-loading" ); 14588 panel.removeAttr( "aria-busy" ); 14589 14590 if ( jqXHR === that.xhr ) { 14591 delete that.xhr; 14592 } 14593 }, 1 ); 14594 }); 14595 } 14596 }, 14597 14598 _ajaxSettings: function( anchor, event, eventData ) { 14599 var that = this; 14600 return { 14601 url: anchor.attr( "href" ), 14602 beforeSend: function( jqXHR, settings ) { 14603 return that._trigger( "beforeLoad", event, 14604 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14605 } 14606 }; 14607 }, 14608 14609 _getPanelForTab: function( tab ) { 14610 var id = $( tab ).attr( "aria-controls" ); 14611 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14612 } 14613}); 14614 14615})( jQuery ); 14616 14617(function( $ ) { 14618 14619var increments = 0; 14620 14621function addDescribedBy( elem, id ) { 14622 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14623 describedby.push( id ); 14624 elem 14625 .data( "ui-tooltip-id", id ) 14626 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14627} 14628 14629function removeDescribedBy( elem ) { 14630 var id = elem.data( "ui-tooltip-id" ), 14631 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14632 index = $.inArray( id, describedby ); 14633 if ( index !== -1 ) { 14634 describedby.splice( index, 1 ); 14635 } 14636 14637 elem.removeData( "ui-tooltip-id" ); 14638 describedby = $.trim( describedby.join( " " ) ); 14639 if ( describedby ) { 14640 elem.attr( "aria-describedby", describedby ); 14641 } else { 14642 elem.removeAttr( "aria-describedby" ); 14643 } 14644} 14645 14646$.widget( "ui.tooltip", { 14647 version: "1.10.3", 14648 options: { 14649 content: function() { 14650 // support: IE<9, Opera in jQuery <1.7 14651 // .text() can't accept undefined, so coerce to a string 14652 var title = $( this ).attr( "title" ) || ""; 14653 // Escape title, since we're going from an attribute to raw HTML 14654 return $( "<a>" ).text( title ).html(); 14655 }, 14656 hide: true, 14657 // Disabled elements have inconsistent behavior across browsers (#8661) 14658 items: "[title]:not([disabled])", 14659 position: { 14660 my: "left top+15", 14661 at: "left bottom", 14662 collision: "flipfit flip" 14663 }, 14664 show: true, 14665 tooltipClass: null, 14666 track: false, 14667 14668 // callbacks 14669 close: null, 14670 open: null 14671 }, 14672 14673 _create: function() { 14674 this._on({ 14675 mouseover: "open", 14676 focusin: "open" 14677 }); 14678 14679 // IDs of generated tooltips, needed for destroy 14680 this.tooltips = {}; 14681 // IDs of parent tooltips where we removed the title attribute 14682 this.parents = {}; 14683 14684 if ( this.options.disabled ) { 14685 this._disable(); 14686 } 14687 }, 14688 14689 _setOption: function( key, value ) { 14690 var that = this; 14691 14692 if ( key === "disabled" ) { 14693 this[ value ? "_disable" : "_enable" ](); 14694 this.options[ key ] = value; 14695 // disable element style changes 14696 return; 14697 } 14698 14699 this._super( key, value ); 14700 14701 if ( key === "content" ) { 14702 $.each( this.tooltips, function( id, element ) { 14703 that._updateContent( element ); 14704 }); 14705 } 14706 }, 14707 14708 _disable: function() { 14709 var that = this; 14710 14711 // close open tooltips 14712 $.each( this.tooltips, function( id, element ) { 14713 var event = $.Event( "blur" ); 14714 event.target = event.currentTarget = element[0]; 14715 that.close( event, true ); 14716 }); 14717 14718 // remove title attributes to prevent native tooltips 14719 this.element.find( this.options.items ).addBack().each(function() { 14720 var element = $( this ); 14721 if ( element.is( "[title]" ) ) { 14722 element 14723 .data( "ui-tooltip-title", element.attr( "title" ) ) 14724 .attr( "title", "" ); 14725 } 14726 }); 14727 }, 14728 14729 _enable: function() { 14730 // restore title attributes 14731 this.element.find( this.options.items ).addBack().each(function() { 14732 var element = $( this ); 14733 if ( element.data( "ui-tooltip-title" ) ) { 14734 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14735 } 14736 }); 14737 }, 14738 14739 open: function( event ) { 14740 var that = this, 14741 target = $( event ? event.target : this.element ) 14742 // we need closest here due to mouseover bubbling, 14743 // but always pointing at the same event target 14744 .closest( this.options.items ); 14745 14746 // No element to show a tooltip for or the tooltip is already open 14747 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14748 return; 14749 } 14750 14751 if ( target.attr( "title" ) ) { 14752 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14753 } 14754 14755 target.data( "ui-tooltip-open", true ); 14756 14757 // kill parent tooltips, custom or native, for hover 14758 if ( event && event.type === "mouseover" ) { 14759 target.parents().each(function() { 14760 var parent = $( this ), 14761 blurEvent; 14762 if ( parent.data( "ui-tooltip-open" ) ) { 14763 blurEvent = $.Event( "blur" ); 14764 blurEvent.target = blurEvent.currentTarget = this; 14765 that.close( blurEvent, true ); 14766 } 14767 if ( parent.attr( "title" ) ) { 14768 parent.uniqueId(); 14769 that.parents[ this.id ] = { 14770 element: this, 14771 title: parent.attr( "title" ) 14772 }; 14773 parent.attr( "title", "" ); 14774 } 14775 }); 14776 } 14777 14778 this._updateContent( target, event ); 14779 }, 14780 14781 _updateContent: function( target, event ) { 14782 var content, 14783 contentOption = this.options.content, 14784 that = this, 14785 eventType = event ? event.type : null; 14786 14787 if ( typeof contentOption === "string" ) { 14788 return this._open( event, target, contentOption ); 14789 } 14790 14791 content = contentOption.call( target[0], function( response ) { 14792 // ignore async response if tooltip was closed already 14793 if ( !target.data( "ui-tooltip-open" ) ) { 14794 return; 14795 } 14796 // IE may instantly serve a cached response for ajax requests 14797 // delay this call to _open so the other call to _open runs first 14798 that._delay(function() { 14799 // jQuery creates a special event for focusin when it doesn't 14800 // exist natively. To improve performance, the native event 14801 // object is reused and the type is changed. Therefore, we can't 14802 // rely on the type being correct after the event finished 14803 // bubbling, so we set it back to the previous value. (#8740) 14804 if ( event ) { 14805 event.type = eventType; 14806 } 14807 this._open( event, target, response ); 14808 }); 14809 }); 14810 if ( content ) { 14811 this._open( event, target, content ); 14812 } 14813 }, 14814 14815 _open: function( event, target, content ) { 14816 var tooltip, events, delayedShow, 14817 positionOption = $.extend( {}, this.options.position ); 14818 14819 if ( !content ) { 14820 return; 14821 } 14822 14823 // Content can be updated multiple times. If the tooltip already 14824 // exists, then just update the content and bail. 14825 tooltip = this._find( target ); 14826 if ( tooltip.length ) { 14827 tooltip.find( ".ui-tooltip-content" ).html( content ); 14828 return; 14829 } 14830 14831 // if we have a title, clear it to prevent the native tooltip 14832 // we have to check first to avoid defining a title if none exists 14833 // (we don't want to cause an element to start matching [title]) 14834 // 14835 // We use removeAttr only for key events, to allow IE to export the correct 14836 // accessible attributes. For mouse events, set to empty string to avoid 14837 // native tooltip showing up (happens only when removing inside mouseover). 14838 if ( target.is( "[title]" ) ) { 14839 if ( event && event.type === "mouseover" ) { 14840 target.attr( "title", "" ); 14841 } else { 14842 target.removeAttr( "title" ); 14843 } 14844 } 14845 14846 tooltip = this._tooltip( target ); 14847 addDescribedBy( target, tooltip.attr( "id" ) ); 14848 tooltip.find( ".ui-tooltip-content" ).html( content ); 14849 14850 function position( event ) { 14851 positionOption.of = event; 14852 if ( tooltip.is( ":hidden" ) ) { 14853 return; 14854 } 14855 tooltip.position( positionOption ); 14856 } 14857 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14858 this._on( this.document, { 14859 mousemove: position 14860 }); 14861 // trigger once to override element-relative positioning 14862 position( event ); 14863 } else { 14864 tooltip.position( $.extend({ 14865 of: target 14866 }, this.options.position ) ); 14867 } 14868 14869 tooltip.hide(); 14870 14871 this._show( tooltip, this.options.show ); 14872 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14873 // as the tooltip is visible, position the tooltip using the most recent 14874 // event. 14875 if ( this.options.show && this.options.show.delay ) { 14876 delayedShow = this.delayedShow = setInterval(function() { 14877 if ( tooltip.is( ":visible" ) ) { 14878 position( positionOption.of ); 14879 clearInterval( delayedShow ); 14880 } 14881 }, $.fx.interval ); 14882 } 14883 14884 this._trigger( "open", event, { tooltip: tooltip } ); 14885 14886 events = { 14887 keyup: function( event ) { 14888 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14889 var fakeEvent = $.Event(event); 14890 fakeEvent.currentTarget = target[0]; 14891 this.close( fakeEvent, true ); 14892 } 14893 }, 14894 remove: function() { 14895 this._removeTooltip( tooltip ); 14896 } 14897 }; 14898 if ( !event || event.type === "mouseover" ) { 14899 events.mouseleave = "close"; 14900 } 14901 if ( !event || event.type === "focusin" ) { 14902 events.focusout = "close"; 14903 } 14904 this._on( true, target, events ); 14905 }, 14906 14907 close: function( event ) { 14908 var that = this, 14909 target = $( event ? event.currentTarget : this.element ), 14910 tooltip = this._find( target ); 14911 14912 // disabling closes the tooltip, so we need to track when we're closing 14913 // to avoid an infinite loop in case the tooltip becomes disabled on close 14914 if ( this.closing ) { 14915 return; 14916 } 14917 14918 // Clear the interval for delayed tracking tooltips 14919 clearInterval( this.delayedShow ); 14920
14921 // only set title if we had one before (see comment in _open()) 14922 if ( target.data( "ui-tooltip-title" ) ) { 14923 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14924 } 14925 14926 removeDescribedBy( target ); 14927 14928 tooltip.stop( true ); 14929 this._hide( tooltip, this.options.hide, function() { 14930 that._removeTooltip( $( this ) ); 14931 }); 14932 14933 target.removeData( "ui-tooltip-open" ); 14934 this._off( target, "mouseleave focusout keyup" ); 14935 // Remove 'remove' binding only on delegated targets 14936 if ( target[0] !== this.element[0] ) { 14937 this._off( target, "remove" ); 14938 } 14939 this._off( this.document, "mousemove" ); 14940 14941 if ( event && event.type === "mouseleave" ) { 14942 $.each( this.parents, function( id, parent ) { 14943 $( parent.element ).attr( "title", parent.title ); 14944 delete that.parents[ id ]; 14945 }); 14946 } 14947 14948 this.closing = true; 14949 this._trigger( "close", event, { tooltip: tooltip } ); 14950 this.closing = false; 14951 }, 14952 14953 _tooltip: function( element ) { 14954 var id = "ui-tooltip-" + increments++, 14955 tooltip = $( "<div>" ) 14956 .attr({ 14957 id: id, 14958 role: "tooltip" 14959 }) 14960 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14961 ( this.options.tooltipClass || "" ) ); 14962 $( "<div>" ) 14963 .addClass( "ui-tooltip-content" ) 14964 .appendTo( tooltip ); 14965 tooltip.appendTo( this.document[0].body ); 14966 this.tooltips[ id ] = element; 14967 return tooltip; 14968 }, 14969 14970 _find: function( target ) { 14971 var id = target.data( "ui-tooltip-id" ); 14972 return id ? $( "#" + id ) : $(); 14973 }, 14974 14975 _removeTooltip: function( tooltip ) { 14976 tooltip.remove(); 14977 delete this.tooltips[ tooltip.attr( "id" ) ]; 14978 }, 14979 14980 _destroy: function() { 14981 var that = this; 14982 14983 // close open tooltips 14984 $.each( this.tooltips, function( id, element ) { 14985 // Delegate to close method to handle common cleanup 14986 var event = $.Event( "blur" ); 14987 event.target = event.currentTarget = element[0]; 14988 that.close( event, true ); 14989 14990 // Remove immediately; destroying an open tooltip doesn't use the 14991 // hide animation 14992 $( "#" + id ).remove(); 14993 14994 // Restore the title 14995 if ( element.data( "ui-tooltip-title" ) ) { 14996 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14997 element.removeData( "ui-tooltip-title" ); 14998 } 14999 }); 15000 } 15001}); 15002 15003}( 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.