1/*! jQuery UI - v1.10.1 - 2013-02-15 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 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// prevent duplicate loading 12// this is only a problem because we proxy existing functions 13// and we don't want to double proxy them 14$.ui = $.ui || {}; 15if ( $.ui.version ) { 16 return; 17} 18 19$.extend( $.ui, { 20 version: "1.10.1", 21 22 keyCode: { 23 BACKSPACE: 8, 24 COMMA: 188, 25 DELETE: 46, 26 DOWN: 40, 27 END: 35, 28 ENTER: 13, 29 ESCAPE: 27, 30 HOME: 36, 31 LEFT: 37, 32 NUMPAD_ADD: 107, 33 NUMPAD_DECIMAL: 110, 34 NUMPAD_DIVIDE: 111, 35 NUMPAD_ENTER: 108, 36 NUMPAD_MULTIPLY: 106, 37 NUMPAD_SUBTRACT: 109, 38 PAGE_DOWN: 34, 39 PAGE_UP: 33, 40 PERIOD: 190, 41 RIGHT: 39, 42 SPACE: 32, 43 TAB: 9, 44 UP: 38 45 } 46}); 47 48// plugins 49$.fn.extend({ 50 _focus: $.fn.focus, 51 focus: function( delay, fn ) { 52 return typeof delay === "number" ? 53 this.each(function() { 54 var elem = this; 55 setTimeout(function() { 56 $( elem ).focus(); 57 if ( fn ) { 58 fn.call( elem ); 59 } 60 }, delay ); 61 }) : 62 this._focus.apply( this, arguments ); 63 }, 64 65 scrollParent: function() { 66 var scrollParent; 67 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 68 scrollParent = this.parents().filter(function() { 69 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } else { 72 scrollParent = this.parents().filter(function() { 73 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 74 }).eq(0); 75 } 76 77 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 78 }, 79 80 zIndex: function( zIndex ) { 81 if ( zIndex !== undefined ) { 82 return this.css( "zIndex", zIndex ); 83 } 84 85 if ( this.length ) { 86 var elem = $( this[ 0 ] ), position, value; 87 while ( elem.length && elem[ 0 ] !== document ) { 88 // Ignore z-index if position is set to a value where z-index is ignored by the browser 89 // This makes behavior of this function consistent across browsers 90 // WebKit always returns auto if the element is positioned 91 position = elem.css( "position" ); 92 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 93 // IE returns 0 when zIndex is not specified 94 // other browsers return a string 95 // we ignore the case of nested elements with an explicit value of 0 96 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 97 value = parseInt( elem.css( "zIndex" ), 10 ); 98 if ( !isNaN( value ) && value !== 0 ) { 99 return value; 100 } 101 } 102 elem = elem.parent(); 103 } 104 } 105 106 return 0; 107 }, 108 109 uniqueId: function() { 110 return this.each(function() { 111 if ( !this.id ) { 112 this.id = "ui-id-" + (++uuid); 113 } 114 }); 115 }, 116 117 removeUniqueId: function() { 118 return this.each(function() { 119 if ( runiqueId.test( this.id ) ) { 120 $( this ).removeAttr( "id" ); 121 } 122 }); 123 } 124}); 125 126// selectors 127function focusable( element, isTabIndexNotNaN ) { 128 var map, mapName, img, 129 nodeName = element.nodeName.toLowerCase(); 130 if ( "area" === nodeName ) { 131 map = element.parentNode; 132 mapName = map.name; 133 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 134 return false;
vendor: 33,404 bytes, lines 135-1334
135 } 136 img = $( "img[usemap=#" + mapName + "]" )[0]; 137 return !!img && visible( img ); 138 } 139 return ( /input|select|textarea|button|object/.test( nodeName ) ? 140 !element.disabled : 141 "a" === nodeName ? 142 element.href || isTabIndexNotNaN : 143 isTabIndexNotNaN) && 144 // the element and all of its ancestors must be visible 145 visible( element ); 146} 147 148function visible( element ) { 149 return $.expr.filters.visible( element ) && 150 !$( element ).parents().addBack().filter(function() { 151 return $.css( this, "visibility" ) === "hidden"; 152 }).length; 153} 154 155$.extend( $.expr[ ":" ], { 156 data: $.expr.createPseudo ? 157 $.expr.createPseudo(function( dataName ) { 158 return function( elem ) { 159 return !!$.data( elem, dataName ); 160 }; 161 }) : 162 // support: jQuery <1.8 163 function( elem, i, match ) { 164 return !!$.data( elem, match[ 3 ] ); 165 }, 166 167 focusable: function( element ) { 168 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 169 }, 170 171 tabbable: function( element ) { 172 var tabIndex = $.attr( element, "tabindex" ), 173 isTabIndexNaN = isNaN( tabIndex ); 174 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 175 } 176}); 177 178// support: jQuery <1.8 179if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 180 $.each( [ "Width", "Height" ], function( i, name ) { 181 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 182 type = name.toLowerCase(), 183 orig = { 184 innerWidth: $.fn.innerWidth, 185 innerHeight: $.fn.innerHeight, 186 outerWidth: $.fn.outerWidth, 187 outerHeight: $.fn.outerHeight 188 }; 189 190 function reduce( elem, size, border, margin ) { 191 $.each( side, function() { 192 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 193 if ( border ) { 194 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 195 } 196 if ( margin ) { 197 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 198 } 199 }); 200 return size; 201 } 202 203 $.fn[ "inner" + name ] = function( size ) { 204 if ( size === undefined ) { 205 return orig[ "inner" + name ].call( this ); 206 } 207 208 return this.each(function() { 209 $( this ).css( type, reduce( this, size ) + "px" ); 210 }); 211 }; 212 213 $.fn[ "outer" + name] = function( size, margin ) { 214 if ( typeof size !== "number" ) { 215 return orig[ "outer" + name ].call( this, size ); 216 } 217 218 return this.each(function() { 219 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 220 }); 221 }; 222 }); 223} 224 225// support: jQuery <1.8 226if ( !$.fn.addBack ) { 227 $.fn.addBack = function( selector ) { 228 return this.add( selector == null ? 229 this.prevObject : this.prevObject.filter( selector ) 230 ); 231 }; 232} 233 234// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 235if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 236 $.fn.removeData = (function( removeData ) { 237 return function( key ) { 238 if ( arguments.length ) { 239 return removeData.call( this, $.camelCase( key ) ); 240 } else { 241 return removeData.call( this ); 242 } 243 }; 244 })( $.fn.removeData ); 245} 246 247 248 249 250 251// deprecated 252$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 253 254$.support.selectstart = "onselectstart" in document.createElement( "div" ); 255$.fn.extend({ 256 disableSelection: function() { 257 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 258 ".ui-disableSelection", function( event ) { 259 event.preventDefault(); 260 }); 261 }, 262 263 enableSelection: function() { 264 return this.unbind( ".ui-disableSelection" ); 265 } 266}); 267 268$.extend( $.ui, { 269 // $.ui.plugin is deprecated. Use the proxy pattern instead. 270 plugin: { 271 add: function( module, option, set ) { 272 var i, 273 proto = $.ui[ module ].prototype; 274 for ( i in set ) { 275 proto.plugins[ i ] = proto.plugins[ i ] || []; 276 proto.plugins[ i ].push( [ option, set[ i ] ] ); 277 } 278 }, 279 call: function( instance, name, args ) { 280 var i, 281 set = instance.plugins[ name ]; 282 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 283 return; 284 } 285 286 for ( i = 0; i < set.length; i++ ) { 287 if ( instance.options[ set[ i ][ 0 ] ] ) { 288 set[ i ][ 1 ].apply( instance.element, args ); 289 } 290 } 291 } 292 }, 293 294 // only used by resizable 295 hasScroll: function( el, a ) { 296 297 //If overflow is hidden, the element might have extra content, but the user wants to hide it 298 if ( $( el ).css( "overflow" ) === "hidden") { 299 return false; 300 } 301 302 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 303 has = false; 304 305 if ( el[ scroll ] > 0 ) { 306 return true; 307 } 308 309 // TODO: determine which cases actually cause this to happen 310 // if the element doesn't have the scroll set, see if it's possible to 311 // set the scroll 312 el[ scroll ] = 1; 313 has = ( el[ scroll ] > 0 ); 314 el[ scroll ] = 0; 315 return has; 316 } 317}); 318 319})( jQuery ); 320 321(function( $, undefined ) { 322 323var uuid = 0, 324 slice = Array.prototype.slice, 325 _cleanData = $.cleanData; 326$.cleanData = function( elems ) { 327 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 328 try { 329 $( elem ).triggerHandler( "remove" ); 330 // http://bugs.jquery.com/ticket/8235 331 } catch( e ) {} 332 } 333 _cleanData( elems ); 334}; 335 336$.widget = function( name, base, prototype ) { 337 var fullName, existingConstructor, constructor, basePrototype, 338 // proxiedPrototype allows the provided prototype to remain unmodified 339 // so that it can be used as a mixin for multiple widgets (#8876) 340 proxiedPrototype = {}, 341 namespace = name.split( "." )[ 0 ]; 342 343 name = name.split( "." )[ 1 ]; 344 fullName = namespace + "-" + name; 345 346 if ( !prototype ) { 347 prototype = base; 348 base = $.Widget; 349 } 350 351 // create selector for plugin 352 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 353 return !!$.data( elem, fullName ); 354 }; 355 356 $[ namespace ] = $[ namespace ] || {}; 357 existingConstructor = $[ namespace ][ name ]; 358 constructor = $[ namespace ][ name ] = function( options, element ) { 359 // allow instantiation without "new" keyword 360 if ( !this._createWidget ) { 361 return new constructor( options, element ); 362 } 363 364 // allow instantiation without initializing for simple inheritance 365 // must use "new" keyword (the code above always passes args) 366 if ( arguments.length ) { 367 this._createWidget( options, element ); 368 } 369 }; 370 // extend with the existing constructor to carry over any static properties 371 $.extend( constructor, existingConstructor, { 372 version: prototype.version, 373 // copy the object used to create the prototype in case we need to 374 // redefine the widget later 375 _proto: $.extend( {}, prototype ), 376 // track widgets that inherit from this widget in case this widget is 377 // redefined after a widget inherits from it 378 _childConstructors: [] 379 }); 380 381 basePrototype = new base(); 382 // we need to make the options hash a property directly on the new instance 383 // otherwise we'll modify the options hash on the prototype that we're 384 // inheriting from 385 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 386 $.each( prototype, function( prop, value ) { 387 if ( !$.isFunction( value ) ) { 388 proxiedPrototype[ prop ] = value; 389 return; 390 } 391 proxiedPrototype[ prop ] = (function() { 392 var _super = function() { 393 return base.prototype[ prop ].apply( this, arguments ); 394 }, 395 _superApply = function( args ) { 396 return base.prototype[ prop ].apply( this, args ); 397 }; 398 return function() { 399 var __super = this._super, 400 __superApply = this._superApply, 401 returnValue; 402 403 this._super = _super; 404 this._superApply = _superApply; 405 406 returnValue = value.apply( this, arguments ); 407 408 this._super = __super; 409 this._superApply = __superApply; 410 411 return returnValue; 412 }; 413 })(); 414 }); 415 constructor.prototype = $.widget.extend( basePrototype, { 416 // TODO: remove support for widgetEventPrefix 417 // always use the name + a colon as the prefix, e.g., draggable:start 418 // don't prefix for widgets that aren't DOM-based 419 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 420 }, proxiedPrototype, { 421 constructor: constructor, 422 namespace: namespace, 423 widgetName: name, 424 widgetFullName: fullName 425 }); 426 427 // If this widget is being redefined then we need to find all widgets that 428 // are inheriting from it and redefine all of them so that they inherit from 429 // the new version of this widget. We're essentially trying to replace one 430 // level in the prototype chain. 431 if ( existingConstructor ) { 432 $.each( existingConstructor._childConstructors, function( i, child ) { 433 var childPrototype = child.prototype; 434 435 // redefine the child widget using the same prototype that was 436 // originally used, but inherit from the new version of the base 437 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 438 }); 439 // remove the list of existing child constructors from the old constructor 440 // so the old child constructors can be garbage collected 441 delete existingConstructor._childConstructors; 442 } else { 443 base._childConstructors.push( constructor ); 444 } 445 446 $.widget.bridge( name, constructor ); 447}; 448 449$.widget.extend = function( target ) { 450 var input = slice.call( arguments, 1 ), 451 inputIndex = 0, 452 inputLength = input.length, 453 key, 454 value; 455 for ( ; inputIndex < inputLength; inputIndex++ ) { 456 for ( key in input[ inputIndex ] ) { 457 value = input[ inputIndex ][ key ]; 458 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 459 // Clone objects 460 if ( $.isPlainObject( value ) ) { 461 target[ key ] = $.isPlainObject( target[ key ] ) ? 462 $.widget.extend( {}, target[ key ], value ) : 463 // Don't extend strings, arrays, etc. with objects 464 $.widget.extend( {}, value ); 465 // Copy everything else by reference 466 } else { 467 target[ key ] = value; 468 } 469 } 470 } 471 } 472 return target; 473}; 474 475$.widget.bridge = function( name, object ) { 476 var fullName = object.prototype.widgetFullName || name; 477 $.fn[ name ] = function( options ) { 478 var isMethodCall = typeof options === "string", 479 args = slice.call( arguments, 1 ), 480 returnValue = this; 481 482 // allow multiple hashes to be passed on init 483 options = !isMethodCall && args.length ? 484 $.widget.extend.apply( null, [ options ].concat(args) ) : 485 options; 486 487 if ( isMethodCall ) { 488 this.each(function() { 489 var methodValue, 490 instance = $.data( this, fullName ); 491 if ( !instance ) { 492 return $.error( "cannot call methods on " + name + " prior to initialization; " + 493 "attempted to call method '" + options + "'" ); 494 } 495 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 496 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 497 } 498 methodValue = instance[ options ].apply( instance, args ); 499 if ( methodValue !== instance && methodValue !== undefined ) { 500 returnValue = methodValue && methodValue.jquery ? 501 returnValue.pushStack( methodValue.get() ) : 502 methodValue; 503 return false; 504 } 505 }); 506 } else { 507 this.each(function() { 508 var instance = $.data( this, fullName ); 509 if ( instance ) { 510 instance.option( options || {} )._init(); 511 } else { 512 $.data( this, fullName, new object( options, this ) ); 513 } 514 }); 515 } 516 517 return returnValue; 518 }; 519}; 520 521$.Widget = function( /* options, element */ ) {}; 522$.Widget._childConstructors = []; 523 524$.Widget.prototype = { 525 widgetName: "widget", 526 widgetEventPrefix: "", 527 defaultElement: "<div>", 528 options: { 529 disabled: false, 530 531 // callbacks 532 create: null 533 }, 534 _createWidget: function( options, element ) { 535 element = $( element || this.defaultElement || this )[ 0 ]; 536 this.element = $( element ); 537 this.uuid = uuid++; 538 this.eventNamespace = "." + this.widgetName + this.uuid; 539 this.options = $.widget.extend( {}, 540 this.options, 541 this._getCreateOptions(), 542 options ); 543 544 this.bindings = $(); 545 this.hoverable = $(); 546 this.focusable = $(); 547 548 if ( element !== this ) { 549 $.data( element, this.widgetFullName, this ); 550 this._on( true, this.element, { 551 remove: function( event ) { 552 if ( event.target === element ) { 553 this.destroy(); 554 } 555 } 556 }); 557 this.document = $( element.style ? 558 // element within the document 559 element.ownerDocument : 560 // element is window or document 561 element.document || element ); 562 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 563 } 564 565 this._create(); 566 this._trigger( "create", null, this._getCreateEventData() ); 567 this._init(); 568 }, 569 _getCreateOptions: $.noop, 570 _getCreateEventData: $.noop, 571 _create: $.noop, 572 _init: $.noop, 573 574 destroy: function() { 575 this._destroy(); 576 // we can probably remove the unbind calls in 2.0 577 // all event bindings should go through this._on() 578 this.element 579 .unbind( this.eventNamespace ) 580 // 1.9 BC for #7810 581 // TODO remove dual storage 582 .removeData( this.widgetName ) 583 .removeData( this.widgetFullName ) 584 // support: jquery <1.6.3 585 // http://bugs.jquery.com/ticket/9413 586 .removeData( $.camelCase( this.widgetFullName ) ); 587 this.widget() 588 .unbind( this.eventNamespace ) 589 .removeAttr( "aria-disabled" ) 590 .removeClass( 591 this.widgetFullName + "-disabled " + 592 "ui-state-disabled" ); 593 594 // clean up events and states 595 this.bindings.unbind( this.eventNamespace ); 596 this.hoverable.removeClass( "ui-state-hover" ); 597 this.focusable.removeClass( "ui-state-focus" ); 598 }, 599 _destroy: $.noop, 600 601 widget: function() { 602 return this.element; 603 }, 604 605 option: function( key, value ) { 606 var options = key, 607 parts, 608 curOption, 609 i; 610 611 if ( arguments.length === 0 ) { 612 // don't return a reference to the internal hash 613 return $.widget.extend( {}, this.options ); 614 } 615 616 if ( typeof key === "string" ) { 617 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 618 options = {}; 619 parts = key.split( "." ); 620 key = parts.shift(); 621 if ( parts.length ) { 622 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 623 for ( i = 0; i < parts.length - 1; i++ ) { 624 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 625 curOption = curOption[ parts[ i ] ]; 626 } 627 key = parts.pop(); 628 if ( value === undefined ) { 629 return curOption[ key ] === undefined ? null : curOption[ key ]; 630 } 631 curOption[ key ] = value; 632 } else { 633 if ( value === undefined ) { 634 return this.options[ key ] === undefined ? null : this.options[ key ]; 635 } 636 options[ key ] = value; 637 } 638 } 639 640 this._setOptions( options ); 641 642 return this; 643 }, 644 _setOptions: function( options ) { 645 var key; 646 647 for ( key in options ) { 648 this._setOption( key, options[ key ] ); 649 } 650 651 return this; 652 }, 653 _setOption: function( key, value ) { 654 this.options[ key ] = value; 655 656 if ( key === "disabled" ) { 657 this.widget() 658 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 659 .attr( "aria-disabled", value ); 660 this.hoverable.removeClass( "ui-state-hover" ); 661 this.focusable.removeClass( "ui-state-focus" ); 662 } 663 664 return this; 665 }, 666 667 enable: function() { 668 return this._setOption( "disabled", false ); 669 }, 670 disable: function() { 671 return this._setOption( "disabled", true ); 672 }, 673 674 _on: function( suppressDisabledCheck, element, handlers ) { 675 var delegateElement, 676 instance = this; 677 678 // no suppressDisabledCheck flag, shuffle arguments 679 if ( typeof suppressDisabledCheck !== "boolean" ) { 680 handlers = element; 681 element = suppressDisabledCheck; 682 suppressDisabledCheck = false; 683 } 684 685 // no element argument, shuffle and use this.element 686 if ( !handlers ) { 687 handlers = element; 688 element = this.element; 689 delegateElement = this.widget(); 690 } else { 691 // accept selectors, DOM elements 692 element = delegateElement = $( element ); 693 this.bindings = this.bindings.add( element ); 694 } 695 696 $.each( handlers, function( event, handler ) { 697 function handlerProxy() { 698 // allow widgets to customize the disabled handling 699 // - disabled as an array instead of boolean 700 // - disabled class as method for disabling individual parts 701 if ( !suppressDisabledCheck && 702 ( instance.options.disabled === true || 703 $( this ).hasClass( "ui-state-disabled" ) ) ) { 704 return; 705 } 706 return ( typeof handler === "string" ? instance[ handler ] : handler ) 707 .apply( instance, arguments ); 708 } 709 710 // copy the guid so direct unbinding works 711 if ( typeof handler !== "string" ) { 712 handlerProxy.guid = handler.guid = 713 handler.guid || handlerProxy.guid || $.guid++; 714 } 715 716 var match = event.match( /^(\w+)\s*(.*)$/ ), 717 eventName = match[1] + instance.eventNamespace, 718 selector = match[2]; 719 if ( selector ) { 720 delegateElement.delegate( selector, eventName, handlerProxy ); 721 } else { 722 element.bind( eventName, handlerProxy ); 723 } 724 }); 725 }, 726 727 _off: function( element, eventName ) { 728 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 729 element.unbind( eventName ).undelegate( eventName ); 730 }, 731 732 _delay: function( handler, delay ) { 733 function handlerProxy() { 734 return ( typeof handler === "string" ? instance[ handler ] : handler ) 735 .apply( instance, arguments ); 736 } 737 var instance = this; 738 return setTimeout( handlerProxy, delay || 0 ); 739 }, 740 741 _hoverable: function( element ) { 742 this.hoverable = this.hoverable.add( element ); 743 this._on( element, { 744 mouseenter: function( event ) { 745 $( event.currentTarget ).addClass( "ui-state-hover" ); 746 }, 747 mouseleave: function( event ) { 748 $( event.currentTarget ).removeClass( "ui-state-hover" ); 749 } 750 }); 751 }, 752 753 _focusable: function( element ) { 754 this.focusable = this.focusable.add( element ); 755 this._on( element, { 756 focusin: function( event ) { 757 $( event.currentTarget ).addClass( "ui-state-focus" ); 758 }, 759 focusout: function( event ) { 760 $( event.currentTarget ).removeClass( "ui-state-focus" ); 761 } 762 }); 763 }, 764 765 _trigger: function( type, event, data ) { 766 var prop, orig, 767 callback = this.options[ type ]; 768 769 data = data || {}; 770 event = $.Event( event ); 771 event.type = ( type === this.widgetEventPrefix ? 772 type : 773 this.widgetEventPrefix + type ).toLowerCase(); 774 // the original event may come from any element 775 // so we need to reset the target on the new event 776 event.target = this.element[ 0 ]; 777 778 // copy original event properties over to the new event 779 orig = event.originalEvent; 780 if ( orig ) { 781 for ( prop in orig ) { 782 if ( !( prop in event ) ) { 783 event[ prop ] = orig[ prop ]; 784 } 785 } 786 } 787 788 this.element.trigger( event, data ); 789 return !( $.isFunction( callback ) && 790 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 791 event.isDefaultPrevented() ); 792 } 793}; 794 795$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 796 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 797 if ( typeof options === "string" ) { 798 options = { effect: options }; 799 } 800 var hasOptions, 801 effectName = !options ? 802 method : 803 options === true || typeof options === "number" ? 804 defaultEffect : 805 options.effect || defaultEffect; 806 options = options || {}; 807 if ( typeof options === "number" ) { 808 options = { duration: options }; 809 } 810 hasOptions = !$.isEmptyObject( options ); 811 options.complete = callback; 812 if ( options.delay ) { 813 element.delay( options.delay ); 814 } 815 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 816 element[ method ]( options ); 817 } else if ( effectName !== method && element[ effectName ] ) { 818 element[ effectName ]( options.duration, options.easing, callback ); 819 } else { 820 element.queue(function( next ) { 821 $( this )[ method ](); 822 if ( callback ) { 823 callback.call( element[ 0 ] ); 824 } 825 next(); 826 }); 827 } 828 }; 829}); 830 831})( jQuery ); 832 833(function( $, undefined ) { 834 835var mouseHandled = false; 836$( document ).mouseup( function() { 837 mouseHandled = false; 838}); 839 840$.widget("ui.mouse", { 841 version: "1.10.1", 842 options: { 843 cancel: "input,textarea,button,select,option", 844 distance: 1, 845 delay: 0 846 }, 847 _mouseInit: function() { 848 var that = this; 849 850 this.element 851 .bind("mousedown."+this.widgetName, function(event) { 852 return that._mouseDown(event); 853 }) 854 .bind("click."+this.widgetName, function(event) { 855 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 856 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 857 event.stopImmediatePropagation(); 858 return false; 859 } 860 }); 861 862 this.started = false; 863 }, 864 865 // TODO: make sure destroying one instance of mouse doesn't mess with 866 // other instances of mouse 867 _mouseDestroy: function() { 868 this.element.unbind("."+this.widgetName); 869 if ( this._mouseMoveDelegate ) { 870 $(document) 871 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 872 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 873 } 874 }, 875 876 _mouseDown: function(event) { 877 // don't let more than one widget handle mouseStart 878 if( mouseHandled ) { return; } 879 880 // we may have missed mouseup (out of window) 881 (this._mouseStarted && this._mouseUp(event)); 882 883 this._mouseDownEvent = event; 884 885 var that = this, 886 btnIsLeft = (event.which === 1), 887 // event.target.nodeName works around a bug in IE 8 with 888 // disabled inputs (#7620) 889 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 890 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 891 return true; 892 } 893 894 this.mouseDelayMet = !this.options.delay; 895 if (!this.mouseDelayMet) { 896 this._mouseDelayTimer = setTimeout(function() { 897 that.mouseDelayMet = true; 898 }, this.options.delay); 899 } 900 901 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 902 this._mouseStarted = (this._mouseStart(event) !== false); 903 if (!this._mouseStarted) { 904 event.preventDefault(); 905 return true; 906 } 907 } 908 909 // Click event may never have fired (Gecko & Opera) 910 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 911 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 912 } 913 914 // these delegates are required to keep context 915 this._mouseMoveDelegate = function(event) { 916 return that._mouseMove(event); 917 }; 918 this._mouseUpDelegate = function(event) { 919 return that._mouseUp(event); 920 }; 921 $(document) 922 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 923 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 924 925 event.preventDefault(); 926 927 mouseHandled = true; 928 return true; 929 }, 930 931 _mouseMove: function(event) { 932 // IE mouseup check - mouseup happened when mouse was out of window 933 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 934 return this._mouseUp(event); 935 } 936 937 if (this._mouseStarted) { 938 this._mouseDrag(event); 939 return event.preventDefault(); 940 } 941 942 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 943 this._mouseStarted = 944 (this._mouseStart(this._mouseDownEvent, event) !== false); 945 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 946 } 947 948 return !this._mouseStarted; 949 }, 950 951 _mouseUp: function(event) { 952 $(document) 953 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 954 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 955 956 if (this._mouseStarted) { 957 this._mouseStarted = false; 958 959 if (event.target === this._mouseDownEvent.target) { 960 $.data(event.target, this.widgetName + ".preventClickEvent", true); 961 } 962 963 this._mouseStop(event); 964 } 965 966 return false; 967 }, 968 969 _mouseDistanceMet: function(event) { 970 return (Math.max( 971 Math.abs(this._mouseDownEvent.pageX - event.pageX), 972 Math.abs(this._mouseDownEvent.pageY - event.pageY) 973 ) >= this.options.distance 974 ); 975 }, 976 977 _mouseDelayMet: function(/* event */) { 978 return this.mouseDelayMet; 979 }, 980 981 // These are placeholder methods, to be overriden by extending plugin 982 _mouseStart: function(/* event */) {}, 983 _mouseDrag: function(/* event */) {}, 984 _mouseStop: function(/* event */) {}, 985 _mouseCapture: function(/* event */) { return true; } 986}); 987 988})(jQuery); 989 990(function( $, undefined ) { 991 992$.widget("ui.draggable", $.ui.mouse, { 993 version: "1.10.1", 994 widgetEventPrefix: "drag", 995 options: { 996 addClasses: true, 997 appendTo: "parent", 998 axis: false, 999 connectToSortable: false, 1000 containment: false, 1001 cursor: "auto", 1002 cursorAt: false, 1003 grid: false, 1004 handle: false, 1005 helper: "original", 1006 iframeFix: false, 1007 opacity: false, 1008 refreshPositions: false, 1009 revert: false, 1010 revertDuration: 500, 1011 scope: "default", 1012 scroll: true, 1013 scrollSensitivity: 20, 1014 scrollSpeed: 20, 1015 snap: false, 1016 snapMode: "both", 1017 snapTolerance: 20, 1018 stack: false, 1019 zIndex: false, 1020 1021 // callbacks 1022 drag: null, 1023 start: null, 1024 stop: null 1025 }, 1026 _create: function() { 1027 1028 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1029 this.element[0].style.position = "relative"; 1030 } 1031 if (this.options.addClasses){ 1032 this.element.addClass("ui-draggable"); 1033 } 1034 if (this.options.disabled){ 1035 this.element.addClass("ui-draggable-disabled"); 1036 } 1037 1038 this._mouseInit(); 1039 1040 }, 1041 1042 _destroy: function() { 1043 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1044 this._mouseDestroy(); 1045 }, 1046 1047 _mouseCapture: function(event) { 1048 1049 var o = this.options; 1050 1051 // among others, prevent a drag on a resizable-handle 1052 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1053 return false; 1054 } 1055 1056 //Quit if we're not on a valid handle 1057 this.handle = this._getHandle(event); 1058 if (!this.handle) { 1059 return false; 1060 } 1061 1062 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1063 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1064 .css({ 1065 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1066 position: "absolute", opacity: "0.001", zIndex: 1000 1067 }) 1068 .css($(this).offset()) 1069 .appendTo("body"); 1070 }); 1071 1072 return true; 1073 1074 }, 1075 1076 _mouseStart: function(event) { 1077 1078 var o = this.options; 1079 1080 //Create and append the visible helper 1081 this.helper = this._createHelper(event); 1082 1083 this.helper.addClass("ui-draggable-dragging"); 1084 1085 //Cache the helper size 1086 this._cacheHelperProportions(); 1087 1088 //If ddmanager is used for droppables, set the global draggable 1089 if($.ui.ddmanager) { 1090 $.ui.ddmanager.current = this; 1091 } 1092 1093 /* 1094 * - Position generation - 1095 * This block generates everything position related - it's the core of draggables. 1096 */ 1097 1098 //Cache the margins of the original element 1099 this._cacheMargins(); 1100 1101 //Store the helper's css position 1102 this.cssPosition = this.helper.css("position"); 1103 this.scrollParent = this.helper.scrollParent(); 1104 1105 //The element's absolute position on the page minus margins 1106 this.offset = this.positionAbs = this.element.offset(); 1107 this.offset = { 1108 top: this.offset.top - this.margins.top, 1109 left: this.offset.left - this.margins.left 1110 }; 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 if(o.containment) { 1131 this._setContainment(); 1132 } 1133 1134 //Trigger event + callbacks 1135 if(this._trigger("start", event) === false) { 1136 this._clear(); 1137 return false; 1138 } 1139 1140 //Recache the helper size 1141 this._cacheHelperProportions(); 1142 1143 //Prepare the droppable offsets 1144 if ($.ui.ddmanager && !o.dropBehaviour) { 1145 $.ui.ddmanager.prepareOffsets(this, event); 1146 } 1147 1148 1149 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1150 1151 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1152 if ( $.ui.ddmanager ) { 1153 $.ui.ddmanager.dragStart(this, event); 1154 } 1155 1156 return true; 1157 }, 1158 1159 _mouseDrag: function(event, noPropagation) { 1160 1161 //Compute the helpers position 1162 this.position = this._generatePosition(event); 1163 this.positionAbs = this._convertPositionTo("absolute"); 1164 1165 //Call plugins and callbacks and use the resulting position if something is returned 1166 if (!noPropagation) { 1167 var ui = this._uiHash(); 1168 if(this._trigger("drag", event, ui) === false) { 1169 this._mouseUp({}); 1170 return false; 1171 } 1172 this.position = ui.position; 1173 } 1174 1175 if(!this.options.axis || this.options.axis !== "y") { 1176 this.helper[0].style.left = this.position.left+"px"; 1177 } 1178 if(!this.options.axis || this.options.axis !== "x") { 1179 this.helper[0].style.top = this.position.top+"px"; 1180 } 1181 if($.ui.ddmanager) { 1182 $.ui.ddmanager.drag(this, event); 1183 } 1184 1185 return false; 1186 }, 1187 1188 _mouseStop: function(event) { 1189 1190 //If we are using droppables, inform the manager about the drop 1191 var element, 1192 that = this, 1193 elementInDom = false, 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 element = this.element[0]; 1207 while ( element && (element = element.parentNode) ) { 1208 if (element === document ) { 1209 elementInDom = true; 1210 } 1211 } 1212 if ( !elementInDom && this.options.helper === "original" ) { 1213 return false; 1214 } 1215 1216 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))) { 1217 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1218 if(that._trigger("stop", event) !== false) { 1219 that._clear(); 1220 } 1221 }); 1222 } else { 1223 if(this._trigger("stop", event) !== false) { 1224 this._clear(); 1225 } 1226 } 1227 1228 return false; 1229 }, 1230 1231 _mouseUp: function(event) { 1232 //Remove frame helpers 1233 $("div.ui-draggable-iframeFix").each(function() { 1234 this.parentNode.removeChild(this); 1235 }); 1236 1237 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1238 if( $.ui.ddmanager ) { 1239 $.ui.ddmanager.dragStop(this, event); 1240 } 1241 1242 return $.ui.mouse.prototype._mouseUp.call(this, event); 1243 }, 1244 1245 cancel: function() { 1246 1247 if(this.helper.is(".ui-draggable-dragging")) { 1248 this._mouseUp({}); 1249 } else { 1250 this._clear(); 1251 } 1252 1253 return this; 1254 1255 }, 1256 1257 _getHandle: function(event) { 1258 1259 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1260 $(this.options.handle, this.element) 1261 .find("*") 1262 .addBack() 1263 .each(function() { 1264 if(this === event.target) { 1265 handle = true; 1266 } 1267 }); 1268 1269 return handle; 1270 1271 }, 1272 1273 _createHelper: function(event) { 1274 1275 var o = this.options, 1276 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1277 1278 if(!helper.parents("body").length) { 1279 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1280 } 1281 1282 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1283 helper.css("position", "absolute"); 1284 } 1285 1286 return helper; 1287 1288 }, 1289 1290 _adjustOffsetFromHelper: function(obj) { 1291 if (typeof obj === "string") { 1292 obj = obj.split(" "); 1293 } 1294 if ($.isArray(obj)) { 1295 obj = {left: +obj[0], top: +obj[1] || 0}; 1296 } 1297 if ("left" in obj) { 1298 this.offset.click.left = obj.left + this.margins.left; 1299 } 1300 if ("right" in obj) { 1301 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1302 } 1303 if ("top" in obj) { 1304 this.offset.click.top = obj.top + this.margins.top; 1305 } 1306 if ("bottom" in obj) { 1307 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1308 } 1309 }, 1310 1311 _getParentOffset: function() { 1312 1313 //Get the offsetParent and cache its position 1314 this.offsetParent = this.helper.offsetParent(); 1315 var po = this.offsetParent.offset(); 1316 1317 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1318 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1319 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1320 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1321 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1322 po.left += this.scrollParent.scrollLeft(); 1323 po.top += this.scrollParent.scrollTop(); 1324 } 1325 1326 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1327 //Ugly IE fix 1328 if((this.offsetParent[0] === document.body) || 1329 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1330 po = { top: 0, left: 0 }; 1331 } 1332 1333 return { 1334 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
vendor: 1,408 bytes, lines 1334-1381
133410) || 0), 1335 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1336 }; 1337 1338 }, 1339 1340 _getRelativeOffset: function() { 1341 1342 if(this.cssPosition === "relative") { 1343 var p = this.element.position(); 1344 return { 1345 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1346 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1347 }; 1348 } else { 1349 return { top: 0, left: 0 }; 1350 } 1351 1352 }, 1353 1354 _cacheMargins: function() { 1355 this.margins = { 1356 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1357 top: (parseInt(this.element.css("marginTop"),10) || 0), 1358 right: (parseInt(this.element.css("marginRight"),10) || 0), 1359 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1360 }; 1361 }, 1362 1363 _cacheHelperProportions: function() { 1364 this.helperProportions = { 1365 width: this.helper.outerWidth(), 1366 height: this.helper.outerHeight() 1367 }; 1368 }, 1369 1370 _setContainment: function() { 1371 1372 var over, c, ce, 1373 o = this.options; 1374 1375 if(o.containment === "parent") { 1376 o.containment = this.helper[0].parentNode; 1377 } 1378 if(o.containment === "document" || o.containment === "window") { 1379 this.containment = [ 1380 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1381 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
vendor: 6,288 bytes, lines 1382-1514
1382 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 1383 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1384 ]; 1385 } 1386 1387 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { 1388 c = $(o.containment); 1389 ce = c[0]; 1390 1391 if(!ce) { 1392 return; 1393 } 1394 1395 over = ($(ce).css("overflow") !== "hidden"); 1396 1397 this.containment = [ 1398 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1399 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1400 (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 - this.margins.right, 1401 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom 1402 ]; 1403 this.relative_container = c; 1404 1405 } else if(o.containment.constructor === Array) { 1406 this.containment = o.containment; 1407 } 1408 1409 }, 1410 1411 _convertPositionTo: function(d, pos) { 1412 1413 if(!pos) { 1414 pos = this.position; 1415 } 1416 1417 var mod = d === "absolute" ? 1 : -1, 1418 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); 1419 1420 return { 1421 top: ( 1422 pos.top + // The absolute mouse position 1423 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1424 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1425 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1426 ), 1427 left: ( 1428 pos.left + // The absolute mouse position 1429 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1430 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1431 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1432 ) 1433 }; 1434 1435 }, 1436 1437 _generatePosition: function(event) { 1438 1439 var containment, co, top, left, 1440 o = this.options, 1441 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 1442 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), 1443 pageX = event.pageX, 1444 pageY = event.pageY; 1445 1446 /* 1447 * - Position constraining - 1448 * Constrain the position to a mix of grid, containment. 1449 */ 1450 1451 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1452 if(this.containment) { 1453 if (this.relative_container){ 1454 co = this.relative_container.offset(); 1455 containment = [ this.containment[0] + co.left, 1456 this.containment[1] + co.top, 1457 this.containment[2] + co.left, 1458 this.containment[3] + co.top ]; 1459 } 1460 else { 1461 containment = this.containment; 1462 } 1463 1464 if(event.pageX - this.offset.click.left < containment[0]) { 1465 pageX = containment[0] + this.offset.click.left; 1466 } 1467 if(event.pageY - this.offset.click.top < containment[1]) { 1468 pageY = containment[1] + this.offset.click.top; 1469 } 1470 if(event.pageX - this.offset.click.left > containment[2]) { 1471 pageX = containment[2] + this.offset.click.left; 1472 } 1473 if(event.pageY - this.offset.click.top > containment[3]) { 1474 pageY = containment[3] + this.offset.click.top; 1475 } 1476 } 1477 1478 if(o.grid) { 1479 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1480 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1481 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; 1482 1483 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1484 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; 1485 } 1486 1487 } 1488 1489 return { 1490 top: ( 1491 pageY - // The absolute mouse position 1492 this.offset.click.top - // Click offset (relative to the element) 1493 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1494 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1495 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1496 ), 1497 left: ( 1498 pageX - // The absolute mouse position 1499 this.offset.click.left - // Click offset (relative to the element) 1500 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1501 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1502 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1503 ) 1504 }; 1505 1506 }, 1507 1508 _clear: function() { 1509 this.helper.removeClass("ui-draggable-dragging"); 1510 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1511 this.helper.remove(); 1512 } 1513 this.helper = null; 1514 this.cancelHelperRemoval = false;
1515 }, 1516 1517 // From now on bulk stuff - mainly helpers 1518 1519 _trigger: function(type, event, ui) { 1520 ui = ui || this._uiHash(); 1521 $.ui.plugin.call(this, type, [event, ui]); 1522 //The absolute position has to be recalculated after plugins 1523 if(type === "drag") { 1524 this.positionAbs = this._convertPositionTo("absolute"); 1525 } 1526 return $.Widget.prototype._trigger.call(this, type, event, ui); 1527 }, 1528 1529 plugins: {}, 1530 1531 _uiHash: function() { 1532 return { 1533 helper: this.helper, 1534 position: this.position, 1535 originalPosition: this.originalPosition, 1536 offset: this.positionAbs 1537 }; 1538 } 1539 1540}); 1541 1542$.ui.plugin.add("draggable", "connectToSortable", { 1543 start: function(event, ui) { 1544 1545 var inst = $(this).data("ui-draggable"), o = inst.options, 1546 uiSortable = $.extend({}, ui, { item: inst.element }); 1547 inst.sortables = []; 1548 $(o.connectToSortable).each(function() { 1549 var sortable = $.data(this, "ui-sortable"); 1550 if (sortable && !sortable.options.disabled) { 1551 inst.sortables.push({ 1552 instance: sortable, 1553 shouldRevert: sortable.options.revert 1554 }); 1555 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). 1556 sortable._trigger("activate", event, uiSortable); 1557 } 1558 }); 1559 1560 }, 1561 stop: function(event, ui) { 1562 1563 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1564 var inst = $(this).data("ui-draggable"), 1565 uiSortable = $.extend({}, ui, { item: inst.element }); 1566 1567 $.each(inst.sortables, function() { 1568 if(this.instance.isOver) { 1569 1570 this.instance.isOver = 0; 1571 1572 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1573 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1574 1575 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 1576 if(this.shouldRevert) { 1577 this.instance.options.revert = true; 1578 } 1579 1580 //Trigger the stop of the sortable 1581 this.instance._mouseStop(event); 1582 1583 this.instance.options.helper = this.instance.options._helper; 1584 1585 //If the helper has been the original item, restore properties in the sortable 1586 if(inst.options.helper === "original") { 1587 this.instance.currentItem.css({ top: "auto", left: "auto" }); 1588 } 1589 1590 } else { 1591 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1592 this.instance._trigger("deactivate", event, uiSortable); 1593 } 1594 1595 }); 1596 1597 }, 1598 drag: function(event, ui) { 1599 1600 var inst = $(this).data("ui-draggable"), that = this; 1601 1602 $.each(inst.sortables, function() { 1603 1604 var innermostIntersecting = false, 1605 thisSortable = this; 1606 1607 //Copy over some variables to allow calling the sortable's native _intersectsWith 1608 this.instance.positionAbs = inst.positionAbs; 1609 this.instance.helperProportions = inst.helperProportions; 1610 this.instance.offset.click = inst.offset.click; 1611 1612 if(this.instance._intersectsWith(this.instance.containerCache)) { 1613 innermostIntersecting = true; 1614 $.each(inst.sortables, function () { 1615 this.instance.positionAbs = inst.positionAbs; 1616 this.instance.helperProportions = inst.helperProportions; 1617 this.instance.offset.click = inst.offset.click; 1618 if (this !== thisSortable && 1619 this.instance._intersectsWith(this.instance.containerCache) && 1620 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 1621 ) { 1622 innermostIntersecting = false; 1623 } 1624 return innermostIntersecting; 1625 }); 1626 } 1627 1628 1629 if(innermostIntersecting) { 1630 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1631 if(!this.instance.isOver) { 1632 1633 this.instance.isOver = 1; 1634 //Now we fake the start of dragging for the sortable instance, 1635 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1636 //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) 1637 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 1638 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1639 this.instance.options.helper = function() { return ui.helper[0]; }; 1640 1641 event.target = this.instance.currentItem[0]; 1642 this.instance._mouseCapture(event, true); 1643 this.instance._mouseStart(event, true, true); 1644
1645 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1646 this.instance.offset.click.top = inst.offset.click.top; 1647 this.instance.offset.click.left = inst.offset.click.left; 1648 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1649 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1650 1651 inst._trigger("toSortable", event); 1652 inst.dropped = this.instance.element; //draggable revert needs that 1653 //hack so receive/update callbacks work (mostly) 1654 inst.currentItem = inst.element; 1655 this.instance.fromOutside = inst; 1656 1657 } 1658 1659 //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 1660 if(this.instance.currentItem) { 1661 this.instance._mouseDrag(event); 1662 } 1663 1664 } else { 1665 1666 //If it doesn't intersect with the sortable, and it intersected before, 1667 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1668 if(this.instance.isOver) { 1669 1670 this.instance.isOver = 0; 1671 this.instance.cancelHelperRemoval = true; 1672 1673 //Prevent reverting on this forced stop 1674 this.instance.options.revert = false; 1675 1676 // The out event needs to be triggered independently 1677 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 1678 1679 this.instance._mouseStop(event, true); 1680 this.instance.options.helper = this.instance.options._helper; 1681 1682 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1683 this.instance.currentItem.remove(); 1684 if(this.instance.placeholder) { 1685 this.instance.placeholder.remove(); 1686 } 1687 1688 inst._trigger("fromSortable", event); 1689 inst.dropped = false; //draggable revert needs that 1690 } 1691 1692 } 1693 1694 }); 1695 1696 } 1697}); 1698 1699$.ui.plugin.add("draggable", "cursor", { 1700 start: function() { 1701 var t = $("body"), o = $(this).data("ui-draggable").options; 1702 if (t.css("cursor")) { 1703 o._cursor = t.css("cursor"); 1704 } 1705 t.css("cursor", o.cursor); 1706 }, 1707 stop: function() { 1708 var o = $(this).data("ui-draggable").options; 1709 if (o._cursor) { 1710 $("body").css("cursor", o._cursor); 1711 } 1712 } 1713}); 1714 1715$.ui.plugin.add("draggable", "opacity", { 1716 start: function(event, ui) { 1717 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1718 if(t.css("opacity")) { 1719 o._opacity = t.css("opacity"); 1720 } 1721 t.css("opacity", o.opacity); 1722 }, 1723 stop: function(event, ui) { 1724 var o = $(this).data("ui-draggable").options; 1725 if(o._opacity) { 1726 $(ui.helper).css("opacity", o._opacity); 1727 } 1728 } 1729}); 1730 1731$.ui.plugin.add("draggable", "scroll", { 1732 start: function() { 1733 var i = $(this).data("ui-draggable"); 1734 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1735 i.overflowOffset = i.scrollParent.offset(); 1736 } 1737 }, 1738 drag: function( event ) { 1739 1740 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 1741 1742 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1743 1744 if(!o.axis || o.axis !== "x") { 1745 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 1746 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1747 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 1748 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1749 } 1750 } 1751 1752 if(!o.axis || o.axis !== "y") { 1753 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 1754 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1755 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 1756 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1757 } 1758 } 1759 1760 } else { 1761 1762 if(!o.axis || o.axis !== "x") { 1763 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 1764 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1765 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 1766 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1767 } 1768 } 1769 1770 if(!o.axis || o.axis !== "y") { 1771 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 1772 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1773 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 1774 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1775 } 1776 } 1777 1778 } 1779 1780 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 1781 $.ui.ddmanager.prepareOffsets(i, event); 1782 } 1783 1784 } 1785}); 1786 1787$.ui.plugin.add("draggable", "snap", { 1788 start: function() { 1789 1790 var i = $(this).data("ui-draggable"), 1791 o = i.options; 1792 1793 i.snapElements = []; 1794 1795 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 1796 var $t = $(this), 1797 $o = $t.offset(); 1798 if(this !== i.element[0]) { 1799 i.snapElements.push({ 1800 item: this, 1801 width: $t.outerWidth(), height: $t.outerHeight(), 1802 top: $o.top, left: $o.left 1803 }); 1804 } 1805 }); 1806 1807 }, 1808 drag: function(event, ui) { 1809 1810 var ts, bs, ls, rs, l, r, t, b, i, first, 1811 inst = $(this).data("ui-draggable"), 1812 o = inst.options, 1813 d = o.snapTolerance, 1814 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1815 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1816 1817 for (i = inst.snapElements.length - 1; i >= 0; i--){ 1818 1819 l = inst.snapElements[i].left; 1820 r = l + inst.snapElements[i].width; 1821 t = inst.snapElements[i].top; 1822 b = t + inst.snapElements[i].height; 1823 1824 //Yes, I know, this is insane ;) 1825 if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { 1826 if(inst.snapElements[i].snapping) { 1827 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1828 } 1829 inst.snapElements[i].snapping = false;
vendor: 32,428 bytes, lines 1830-2971
1830 continue; 1831 } 1832 1833 if(o.snapMode !== "inner") { 1834 ts = Math.abs(t - y2) <= d; 1835 bs = Math.abs(b - y1) <= d; 1836 ls = Math.abs(l - x2) <= d; 1837 rs = Math.abs(r - x1) <= d; 1838 if(ts) { 1839 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1840 } 1841 if(bs) { 1842 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1843 } 1844 if(ls) { 1845 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1846 } 1847 if(rs) { 1848 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1849 } 1850 } 1851 1852 first = (ts || bs || ls || rs); 1853 1854 if(o.snapMode !== "outer") { 1855 ts = Math.abs(t - y1) <= d; 1856 bs = Math.abs(b - y2) <= d; 1857 ls = Math.abs(l - x1) <= d; 1858 rs = Math.abs(r - x2) <= d; 1859 if(ts) { 1860 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1861 } 1862 if(bs) { 1863 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1864 } 1865 if(ls) { 1866 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1867 } 1868 if(rs) { 1869 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1870 } 1871 } 1872 1873 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 1874 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1875 } 1876 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1877 1878 } 1879 1880 } 1881}); 1882 1883$.ui.plugin.add("draggable", "stack", { 1884 start: function() { 1885 var min, 1886 o = this.data("ui-draggable").options, 1887 group = $.makeArray($(o.stack)).sort(function(a,b) { 1888 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1889 }); 1890 1891 if (!group.length) { return; } 1892 1893 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 1894 $(group).each(function(i) { 1895 $(this).css("zIndex", min + i); 1896 }); 1897 this.css("zIndex", (min + group.length)); 1898 } 1899}); 1900 1901$.ui.plugin.add("draggable", "zIndex", { 1902 start: function(event, ui) { 1903 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1904 if(t.css("zIndex")) { 1905 o._zIndex = t.css("zIndex"); 1906 } 1907 t.css("zIndex", o.zIndex); 1908 }, 1909 stop: function(event, ui) { 1910 var o = $(this).data("ui-draggable").options; 1911 if(o._zIndex) { 1912 $(ui.helper).css("zIndex", o._zIndex); 1913 } 1914 } 1915}); 1916 1917})(jQuery); 1918 1919(function( $, undefined ) { 1920 1921function isOverAxis( x, reference, size ) { 1922 return ( x > reference ) && ( x < ( reference + size ) ); 1923} 1924 1925$.widget("ui.droppable", { 1926 version: "1.10.1", 1927 widgetEventPrefix: "drop", 1928 options: { 1929 accept: "*", 1930 activeClass: false, 1931 addClasses: true, 1932 greedy: false, 1933 hoverClass: false, 1934 scope: "default", 1935 tolerance: "intersect", 1936 1937 // callbacks 1938 activate: null, 1939 deactivate: null, 1940 drop: null, 1941 out: null, 1942 over: null 1943 }, 1944 _create: function() { 1945 1946 var o = this.options, 1947 accept = o.accept; 1948 1949 this.isover = false; 1950 this.isout = true; 1951 1952 this.accept = $.isFunction(accept) ? accept : function(d) { 1953 return d.is(accept); 1954 }; 1955 1956 //Store the droppable's proportions 1957 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1958 1959 // Add the reference and positions to the manager 1960 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1961 $.ui.ddmanager.droppables[o.scope].push(this); 1962 1963 (o.addClasses && this.element.addClass("ui-droppable")); 1964 1965 }, 1966 1967 _destroy: function() { 1968 var i = 0, 1969 drop = $.ui.ddmanager.droppables[this.options.scope]; 1970 1971 for ( ; i < drop.length; i++ ) { 1972 if ( drop[i] === this ) { 1973 drop.splice(i, 1); 1974 } 1975 } 1976 1977 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1978 }, 1979 1980 _setOption: function(key, value) { 1981 1982 if(key === "accept") { 1983 this.accept = $.isFunction(value) ? value : function(d) { 1984 return d.is(value); 1985 }; 1986 } 1987 $.Widget.prototype._setOption.apply(this, arguments); 1988 }, 1989 1990 _activate: function(event) { 1991 var draggable = $.ui.ddmanager.current; 1992 if(this.options.activeClass) { 1993 this.element.addClass(this.options.activeClass); 1994 } 1995 if(draggable){ 1996 this._trigger("activate", event, this.ui(draggable)); 1997 } 1998 }, 1999 2000 _deactivate: function(event) { 2001 var draggable = $.ui.ddmanager.current; 2002 if(this.options.activeClass) { 2003 this.element.removeClass(this.options.activeClass); 2004 } 2005 if(draggable){ 2006 this._trigger("deactivate", event, this.ui(draggable)); 2007 } 2008 }, 2009 2010 _over: function(event) { 2011 2012 var draggable = $.ui.ddmanager.current; 2013 2014 // Bail if draggable and droppable are same element 2015 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2016 return; 2017 } 2018 2019 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2020 if(this.options.hoverClass) { 2021 this.element.addClass(this.options.hoverClass); 2022 } 2023 this._trigger("over", event, this.ui(draggable)); 2024 } 2025 2026 }, 2027 2028 _out: function(event) { 2029 2030 var draggable = $.ui.ddmanager.current; 2031 2032 // Bail if draggable and droppable are same element 2033 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2034 return; 2035 } 2036 2037 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2038 if(this.options.hoverClass) { 2039 this.element.removeClass(this.options.hoverClass); 2040 } 2041 this._trigger("out", event, this.ui(draggable)); 2042 } 2043 2044 }, 2045 2046 _drop: function(event,custom) { 2047 2048 var draggable = custom || $.ui.ddmanager.current, 2049 childrenIntersection = false; 2050 2051 // Bail if draggable and droppable are same element 2052 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2053 return false; 2054 } 2055 2056 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2057 var inst = $.data(this, "ui-droppable"); 2058 if( 2059 inst.options.greedy && 2060 !inst.options.disabled && 2061 inst.options.scope === draggable.options.scope && 2062 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2063 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2064 ) { childrenIntersection = true; return false; } 2065 }); 2066 if(childrenIntersection) { 2067 return false; 2068 } 2069 2070 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2071 if(this.options.activeClass) { 2072 this.element.removeClass(this.options.activeClass); 2073 } 2074 if(this.options.hoverClass) { 2075 this.element.removeClass(this.options.hoverClass); 2076 } 2077 this._trigger("drop", event, this.ui(draggable)); 2078 return this.element; 2079 } 2080 2081 return false; 2082 2083 }, 2084 2085 ui: function(c) { 2086 return { 2087 draggable: (c.currentItem || c.element), 2088 helper: c.helper, 2089 position: c.position, 2090 offset: c.positionAbs 2091 }; 2092 } 2093 2094}); 2095 2096$.ui.intersect = function(draggable, droppable, toleranceMode) { 2097 2098 if (!droppable.offset) { 2099 return false; 2100 } 2101 2102 var draggableLeft, draggableTop, 2103 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2104 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2105 l = droppable.offset.left, r = l + droppable.proportions.width, 2106 t = droppable.offset.top, b = t + droppable.proportions.height; 2107 2108 switch (toleranceMode) { 2109 case "fit": 2110 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2111 case "intersect": 2112 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2113 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2114 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2115 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2116 case "pointer": 2117 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2118 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2119 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2120 case "touch": 2121 return ( 2122 (y1 >= t && y1 <= b) || // Top edge touching 2123 (y2 >= t && y2 <= b) || // Bottom edge touching 2124 (y1 < t && y2 > b) // Surrounded vertically 2125 ) && ( 2126 (x1 >= l && x1 <= r) || // Left edge touching 2127 (x2 >= l && x2 <= r) || // Right edge touching 2128 (x1 < l && x2 > r) // Surrounded horizontally 2129 ); 2130 default: 2131 return false; 2132 } 2133 2134}; 2135 2136/* 2137 This manager tracks offsets of draggables and droppables 2138*/ 2139$.ui.ddmanager = { 2140 current: null, 2141 droppables: { "default": [] }, 2142 prepareOffsets: function(t, event) { 2143 2144 var i, j, 2145 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2146 type = event ? event.type : null, // workaround for #2317 2147 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2148 2149 droppablesLoop: for (i = 0; i < m.length; i++) { 2150 2151 //No disabled and non-accepted 2152 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2153 continue; 2154 } 2155 2156 // Filter out elements in the current dragged item 2157 for (j=0; j < list.length; j++) { 2158 if(list[j] === m[i].element[0]) { 2159 m[i].proportions.height = 0; 2160 continue droppablesLoop; 2161 } 2162 } 2163 2164 m[i].visible = m[i].element.css("display") !== "none"; 2165 if(!m[i].visible) { 2166 continue; 2167 } 2168 2169 //Activate the droppable if used directly from draggables 2170 if(type === "mousedown") { 2171 m[i]._activate.call(m[i], event); 2172 } 2173 2174 m[i].offset = m[i].element.offset(); 2175 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2176 2177 } 2178 2179 }, 2180 drop: function(draggable, event) { 2181 2182 var dropped = false; 2183 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2184 2185 if(!this.options) { 2186 return; 2187 } 2188 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2189 dropped = this._drop.call(this, event) || dropped; 2190 } 2191 2192 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2193 this.isout = true; 2194 this.isover = false; 2195 this._deactivate.call(this, event); 2196 } 2197 2198 }); 2199 return dropped; 2200 2201 }, 2202 dragStart: function( draggable, event ) { 2203 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2204 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2205 if( !draggable.options.refreshPositions ) { 2206 $.ui.ddmanager.prepareOffsets( draggable, event ); 2207 } 2208 }); 2209 }, 2210 drag: function(draggable, event) { 2211 2212 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2213 if(draggable.options.refreshPositions) { 2214 $.ui.ddmanager.prepareOffsets(draggable, event); 2215 } 2216 2217 //Run through all droppables and check their positions based on specific tolerance options 2218 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2219 2220 if(this.options.disabled || this.greedyChild || !this.visible) { 2221 return; 2222 } 2223 2224 var parentInstance, scope, parent, 2225 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2226 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2227 if(!c) { 2228 return; 2229 } 2230 2231 if (this.options.greedy) { 2232 // find droppable parents with same scope 2233 scope = this.options.scope; 2234 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2235 return $.data(this, "ui-droppable").options.scope === scope; 2236 }); 2237 2238 if (parent.length) { 2239 parentInstance = $.data(parent[0], "ui-droppable"); 2240 parentInstance.greedyChild = (c === "isover"); 2241 } 2242 } 2243 2244 // we just moved into a greedy child 2245 if (parentInstance && c === "isover") { 2246 parentInstance.isover = false; 2247 parentInstance.isout = true; 2248 parentInstance._out.call(parentInstance, event); 2249 } 2250 2251 this[c] = true; 2252 this[c === "isout" ? "isover" : "isout"] = false; 2253 this[c === "isover" ? "_over" : "_out"].call(this, event); 2254 2255 // we just moved out of a greedy child 2256 if (parentInstance && c === "isout") { 2257 parentInstance.isout = false; 2258 parentInstance.isover = true; 2259 parentInstance._over.call(parentInstance, event); 2260 } 2261 }); 2262 2263 }, 2264 dragStop: function( draggable, event ) { 2265 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2266 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2267 if( !draggable.options.refreshPositions ) { 2268 $.ui.ddmanager.prepareOffsets( draggable, event ); 2269 } 2270 } 2271}; 2272 2273})(jQuery); 2274 2275(function( $, undefined ) { 2276 2277function num(v) { 2278 return parseInt(v, 10) || 0; 2279} 2280 2281function isNumber(value) { 2282 return !isNaN(parseInt(value, 10)); 2283} 2284 2285$.widget("ui.resizable", $.ui.mouse, { 2286 version: "1.10.1", 2287 widgetEventPrefix: "resize", 2288 options: { 2289 alsoResize: false, 2290 animate: false, 2291 animateDuration: "slow", 2292 animateEasing: "swing", 2293 aspectRatio: false, 2294 autoHide: false, 2295 containment: false, 2296 ghost: false, 2297 grid: false, 2298 handles: "e,s,se", 2299 helper: false, 2300 maxHeight: null, 2301 maxWidth: null, 2302 minHeight: 10, 2303 minWidth: 10, 2304 // See #7960 2305 zIndex: 90, 2306 2307 // callbacks 2308 resize: null, 2309 start: null, 2310 stop: null 2311 }, 2312 _create: function() { 2313 2314 var n, i, handle, axis, hname, 2315 that = this, 2316 o = this.options; 2317 this.element.addClass("ui-resizable"); 2318 2319 $.extend(this, { 2320 _aspectRatio: !!(o.aspectRatio), 2321 aspectRatio: o.aspectRatio, 2322 originalElement: this.element, 2323 _proportionallyResizeElements: [], 2324 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2325 }); 2326 2327 //Wrap the element if it cannot hold child nodes 2328 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2329 2330 //Create a wrapper element and set the wrapper to the new current internal element 2331 this.element.wrap( 2332 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2333 position: this.element.css("position"), 2334 width: this.element.outerWidth(), 2335 height: this.element.outerHeight(), 2336 top: this.element.css("top"), 2337 left: this.element.css("left") 2338 }) 2339 ); 2340 2341 //Overwrite the original this.element 2342 this.element = this.element.parent().data( 2343 "ui-resizable", this.element.data("ui-resizable") 2344 ); 2345 2346 this.elementIsWrapper = true; 2347 2348 //Move margins to the wrapper 2349 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2350 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2351 2352 //Prevent Safari textarea resize 2353 this.originalResizeStyle = this.originalElement.css("resize"); 2354 this.originalElement.css("resize", "none"); 2355 2356 //Push the actual element to our proportionallyResize internal array 2357 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2358 2359 // avoid IE jump (hard set the margin) 2360 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2361 2362 // fix handlers offset 2363 this._proportionallyResize(); 2364 2365 } 2366 2367 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" }); 2368 if(this.handles.constructor === String) { 2369 2370 if ( this.handles === "all") { 2371 this.handles = "n,e,s,w,se,sw,ne,nw"; 2372 } 2373 2374 n = this.handles.split(","); 2375 this.handles = {}; 2376 2377 for(i = 0; i < n.length; i++) { 2378 2379 handle = $.trim(n[i]); 2380 hname = "ui-resizable-"+handle; 2381 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2382 2383 // Apply zIndex to all handles - see #7960 2384 axis.css({ zIndex: o.zIndex }); 2385 2386 //TODO : What's going on here? 2387 if ("se" === handle) { 2388 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2389 } 2390 2391 //Insert into internal handles object and append to element 2392 this.handles[handle] = ".ui-resizable-"+handle; 2393 this.element.append(axis); 2394 } 2395 2396 } 2397 2398 this._renderAxis = function(target) { 2399 2400 var i, axis, padPos, padWrapper; 2401 2402 target = target || this.element; 2403 2404 for(i in this.handles) { 2405 2406 if(this.handles[i].constructor === String) { 2407 this.handles[i] = $(this.handles[i], this.element).show(); 2408 } 2409 2410 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2411 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2412 2413 axis = $(this.handles[i], this.element); 2414 2415 //Checking the correct pad and border 2416 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2417 2418 //The padding type i have to apply... 2419 padPos = [ "padding", 2420 /ne|nw|n/.test(i) ? "Top" : 2421 /se|sw|s/.test(i) ? "Bottom" : 2422 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2423 2424 target.css(padPos, padWrapper); 2425 2426 this._proportionallyResize(); 2427 2428 } 2429 2430 //TODO: What's that good for? There's not anything to be executed left 2431 if(!$(this.handles[i]).length) { 2432 continue; 2433 } 2434 } 2435 }; 2436 2437 //TODO: make renderAxis a prototype function 2438 this._renderAxis(this.element); 2439 2440 this._handles = $(".ui-resizable-handle", this.element) 2441 .disableSelection(); 2442 2443 //Matching axis name 2444 this._handles.mouseover(function() { 2445 if (!that.resizing) { 2446 if (this.className) { 2447 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2448 } 2449 //Axis, default = se 2450 that.axis = axis && axis[1] ? axis[1] : "se"; 2451 } 2452 }); 2453 2454 //If we want to auto hide the elements 2455 if (o.autoHide) { 2456 this._handles.hide(); 2457 $(this.element) 2458 .addClass("ui-resizable-autohide") 2459 .mouseenter(function() { 2460 if (o.disabled) { 2461 return; 2462 } 2463 $(this).removeClass("ui-resizable-autohide"); 2464 that._handles.show(); 2465 }) 2466 .mouseleave(function(){ 2467 if (o.disabled) { 2468 return; 2469 } 2470 if (!that.resizing) { 2471 $(this).addClass("ui-resizable-autohide"); 2472 that._handles.hide(); 2473 } 2474 }); 2475 } 2476 2477 //Initialize the mouse interaction 2478 this._mouseInit(); 2479 2480 }, 2481 2482 _destroy: function() { 2483 2484 this._mouseDestroy(); 2485 2486 var wrapper, 2487 _destroy = function(exp) { 2488 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2489 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2490 }; 2491 2492 //TODO: Unwrap at same DOM position 2493 if (this.elementIsWrapper) { 2494 _destroy(this.element); 2495 wrapper = this.element; 2496 this.originalElement.css({ 2497 position: wrapper.css("position"), 2498 width: wrapper.outerWidth(), 2499 height: wrapper.outerHeight(), 2500 top: wrapper.css("top"), 2501 left: wrapper.css("left") 2502 }).insertAfter( wrapper ); 2503 wrapper.remove(); 2504 } 2505 2506 this.originalElement.css("resize", this.originalResizeStyle); 2507 _destroy(this.originalElement); 2508 2509 return this; 2510 }, 2511 2512 _mouseCapture: function(event) { 2513 var i, handle, 2514 capture = false; 2515 2516 for (i in this.handles) { 2517 handle = $(this.handles[i])[0]; 2518 if (handle === event.target || $.contains(handle, event.target)) { 2519 capture = true; 2520 } 2521 } 2522 2523 return !this.options.disabled && capture; 2524 }, 2525 2526 _mouseStart: function(event) { 2527 2528 var curleft, curtop, cursor, 2529 o = this.options, 2530 iniPos = this.element.position(), 2531 el = this.element; 2532 2533 this.resizing = true; 2534 2535 // bugfix for http://dev.jquery.com/ticket/1749 2536 if ( (/absolute/).test( el.css("position") ) ) { 2537 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 2538 } else if (el.is(".ui-draggable")) { 2539 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 2540 } 2541 2542 this._renderProxy(); 2543 2544 curleft = num(this.helper.css("left")); 2545 curtop = num(this.helper.css("top")); 2546 2547 if (o.containment) { 2548 curleft += $(o.containment).scrollLeft() || 0; 2549 curtop += $(o.containment).scrollTop() || 0; 2550 } 2551 2552 //Store needed variables 2553 this.offset = this.helper.offset(); 2554 this.position = { left: curleft, top: curtop }; 2555 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2556 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2557 this.originalPosition = { left: curleft, top: curtop }; 2558 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2559 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2560 2561 //Aspect Ratio 2562 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2563 2564 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 2565 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 2566 2567 el.addClass("ui-resizable-resizing"); 2568 this._propagate("start", event); 2569 return true; 2570 }, 2571 2572 _mouseDrag: function(event) { 2573 2574 //Increase performance, avoid regex 2575 var data, 2576 el = this.helper, props = {}, 2577 smp = this.originalMousePosition, 2578 a = this.axis, 2579 prevTop = this.position.top, 2580 prevLeft = this.position.left, 2581 prevWidth = this.size.width, 2582 prevHeight = this.size.height, 2583 dx = (event.pageX-smp.left)||0, 2584 dy = (event.pageY-smp.top)||0, 2585 trigger = this._change[a]; 2586 2587 if (!trigger) { 2588 return false; 2589 } 2590 2591 // Calculate the attrs that will be change 2592 data = trigger.apply(this, [event, dx, dy]); 2593 2594 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2595 this._updateVirtualBoundaries(event.shiftKey); 2596 if (this._aspectRatio || event.shiftKey) { 2597 data = this._updateRatio(data, event); 2598 } 2599 2600 data = this._respectSize(data, event); 2601 2602 this._updateCache(data); 2603 2604 // plugins callbacks need to be called first 2605 this._propagate("resize", event); 2606 2607 if (this.position.top !== prevTop) { 2608 props.top = this.position.top + "px"; 2609 } 2610 if (this.position.left !== prevLeft) { 2611 props.left = this.position.left + "px"; 2612 } 2613 if (this.size.width !== prevWidth) { 2614 props.width = this.size.width + "px"; 2615 } 2616 if (this.size.height !== prevHeight) { 2617 props.height = this.size.height + "px"; 2618 } 2619 el.css(props); 2620 2621 if (!this._helper && this._proportionallyResizeElements.length) { 2622 this._proportionallyResize(); 2623 } 2624 2625 // Call the user callback if the element was resized 2626 if ( ! $.isEmptyObject(props) ) { 2627 this._trigger("resize", event, this.ui()); 2628 } 2629 2630 return false; 2631 }, 2632 2633 _mouseStop: function(event) { 2634 2635 this.resizing = false; 2636 var pr, ista, soffseth, soffsetw, s, left, top, 2637 o = this.options, that = this; 2638 2639 if(this._helper) { 2640 2641 pr = this._proportionallyResizeElements; 2642 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 2643 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 2644 soffsetw = ista ? 0 : that.sizeDiff.width; 2645 2646 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 2647 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 2648 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2649 2650 if (!o.animate) { 2651 this.element.css($.extend(s, { top: top, left: left })); 2652 } 2653 2654 that.helper.height(that.size.height); 2655 that.helper.width(that.size.width); 2656 2657 if (this._helper && !o.animate) { 2658 this._proportionallyResize(); 2659 } 2660 } 2661 2662 $("body").css("cursor", "auto"); 2663 2664 this.element.removeClass("ui-resizable-resizing"); 2665 2666 this._propagate("stop", event); 2667 2668 if (this._helper) { 2669 this.helper.remove(); 2670 } 2671 2672 return false; 2673 2674 }, 2675 2676 _updateVirtualBoundaries: function(forceAspectRatio) { 2677 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2678 o = this.options; 2679 2680 b = { 2681 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2682 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2683 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2684 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2685 }; 2686 2687 if(this._aspectRatio || forceAspectRatio) { 2688 // We want to create an enclosing box whose aspect ration is the requested one 2689 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2690 pMinWidth = b.minHeight * this.aspectRatio; 2691 pMinHeight = b.minWidth / this.aspectRatio; 2692 pMaxWidth = b.maxHeight * this.aspectRatio; 2693 pMaxHeight = b.maxWidth / this.aspectRatio; 2694 2695 if(pMinWidth > b.minWidth) { 2696 b.minWidth = pMinWidth; 2697 } 2698 if(pMinHeight > b.minHeight) { 2699 b.minHeight = pMinHeight; 2700 } 2701 if(pMaxWidth < b.maxWidth) { 2702 b.maxWidth = pMaxWidth; 2703 } 2704 if(pMaxHeight < b.maxHeight) { 2705 b.maxHeight = pMaxHeight; 2706 } 2707 } 2708 this._vBoundaries = b; 2709 }, 2710 2711 _updateCache: function(data) { 2712 this.offset = this.helper.offset(); 2713 if (isNumber(data.left)) { 2714 this.position.left = data.left; 2715 } 2716 if (isNumber(data.top)) { 2717 this.position.top = data.top; 2718 } 2719 if (isNumber(data.height)) { 2720 this.size.height = data.height; 2721 } 2722 if (isNumber(data.width)) { 2723 this.size.width = data.width; 2724 } 2725 }, 2726 2727 _updateRatio: function( data ) { 2728 2729 var cpos = this.position, 2730 csize = this.size, 2731 a = this.axis; 2732 2733 if (isNumber(data.height)) { 2734 data.width = (data.height * this.aspectRatio); 2735 } else if (isNumber(data.width)) { 2736 data.height = (data.width / this.aspectRatio); 2737 } 2738 2739 if (a === "sw") { 2740 data.left = cpos.left + (csize.width - data.width); 2741 data.top = null; 2742 } 2743 if (a === "nw") { 2744 data.top = cpos.top + (csize.height - data.height); 2745 data.left = cpos.left + (csize.width - data.width); 2746 } 2747 2748 return data; 2749 }, 2750 2751 _respectSize: function( data ) { 2752 2753 var o = this._vBoundaries, 2754 a = this.axis, 2755 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2756 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 2757 dw = this.originalPosition.left + this.originalSize.width, 2758 dh = this.position.top + this.size.height, 2759 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2760 if (isminw) { 2761 data.width = o.minWidth; 2762 } 2763 if (isminh) { 2764 data.height = o.minHeight; 2765 } 2766 if (ismaxw) { 2767 data.width = o.maxWidth; 2768 } 2769 if (ismaxh) { 2770 data.height = o.maxHeight; 2771 } 2772 2773 if (isminw && cw) { 2774 data.left = dw - o.minWidth; 2775 } 2776 if (ismaxw && cw) { 2777 data.left = dw - o.maxWidth; 2778 } 2779 if (isminh && ch) { 2780 data.top = dh - o.minHeight; 2781 } 2782 if (ismaxh && ch) { 2783 data.top = dh - o.maxHeight; 2784 } 2785 2786 // fixing jump error on top/left - bug #2330 2787 if (!data.width && !data.height && !data.left && data.top) { 2788 data.top = null; 2789 } else if (!data.width && !data.height && !data.top && data.left) { 2790 data.left = null; 2791 } 2792 2793 return data; 2794 }, 2795 2796 _proportionallyResize: function() { 2797 2798 if (!this._proportionallyResizeElements.length) { 2799 return; 2800 } 2801 2802 var i, j, borders, paddings, prel, 2803 element = this.helper || this.element; 2804 2805 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 2806 2807 prel = this._proportionallyResizeElements[i]; 2808 2809 if (!this.borderDif) { 2810 this.borderDif = []; 2811 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 2812 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 2813 2814 for ( j = 0; j < borders.length; j++ ) { 2815 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 2816 } 2817 } 2818 2819 prel.css({ 2820 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2821 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2822 }); 2823 2824 } 2825 2826 }, 2827 2828 _renderProxy: function() { 2829 2830 var el = this.element, o = this.options; 2831 this.elementOffset = el.offset(); 2832 2833 if(this._helper) { 2834 2835 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 2836 2837 this.helper.addClass(this._helper).css({ 2838 width: this.element.outerWidth() - 1, 2839 height: this.element.outerHeight() - 1, 2840 position: "absolute", 2841 left: this.elementOffset.left +"px", 2842 top: this.elementOffset.top +"px", 2843 zIndex: ++o.zIndex //TODO: Don't modify option 2844 }); 2845 2846 this.helper 2847 .appendTo("body") 2848 .disableSelection(); 2849 2850 } else { 2851 this.helper = this.element; 2852 } 2853 2854 }, 2855 2856 _change: { 2857 e: function(event, dx) { 2858 return { width: this.originalSize.width + dx }; 2859 }, 2860 w: function(event, dx) { 2861 var cs = this.originalSize, sp = this.originalPosition; 2862 return { left: sp.left + dx, width: cs.width - dx }; 2863 }, 2864 n: function(event, dx, dy) { 2865 var cs = this.originalSize, sp = this.originalPosition; 2866 return { top: sp.top + dy, height: cs.height - dy }; 2867 }, 2868 s: function(event, dx, dy) { 2869 return { height: this.originalSize.height + dy }; 2870 }, 2871 se: function(event, dx, dy) { 2872 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2873 }, 2874 sw: function(event, dx, dy) { 2875 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2876 }, 2877 ne: function(event, dx, dy) { 2878 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2879 }, 2880 nw: function(event, dx, dy) { 2881 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2882 } 2883 }, 2884 2885 _propagate: function(n, event) { 2886 $.ui.plugin.call(this, n, [event, this.ui()]); 2887 (n !== "resize" && this._trigger(n, event, this.ui())); 2888 }, 2889 2890 plugins: {}, 2891 2892 ui: function() { 2893 return { 2894 originalElement: this.originalElement, 2895 element: this.element, 2896 helper: this.helper, 2897 position: this.position, 2898 size: this.size, 2899 originalSize: this.originalSize, 2900 originalPosition: this.originalPosition 2901 }; 2902 } 2903 2904}); 2905 2906/* 2907 * Resizable Extensions 2908 */ 2909 2910$.ui.plugin.add("resizable", "animate", { 2911 2912 stop: function( event ) { 2913 var that = $(this).data("ui-resizable"), 2914 o = that.options, 2915 pr = that._proportionallyResizeElements, 2916 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2917 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2918 soffsetw = ista ? 0 : that.sizeDiff.width, 2919 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2920 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 2921 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2922 2923 that.element.animate( 2924 $.extend(style, top && left ? { top: top, left: left } : {}), { 2925 duration: o.animateDuration, 2926 easing: o.animateEasing, 2927 step: function() { 2928 2929 var data = { 2930 width: parseInt(that.element.css("width"), 10), 2931 height: parseInt(that.element.css("height"), 10), 2932 top: parseInt(that.element.css("top"), 10), 2933 left: parseInt(that.element.css("left"), 10) 2934 }; 2935 2936 if (pr && pr.length) { 2937 $(pr[0]).css({ width: data.width, height: data.height }); 2938 } 2939 2940 // propagating resize, and updating values for each animation step 2941 that._updateCache(data); 2942 that._propagate("resize", event); 2943 2944 } 2945 } 2946 ); 2947 } 2948 2949}); 2950 2951$.ui.plugin.add("resizable", "containment", { 2952 2953 start: function() { 2954 var element, p, co, ch, cw, width, height, 2955 that = $(this).data("ui-resizable"), 2956 o = that.options, 2957 el = that.element, 2958 oc = o.containment, 2959 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2960 2961 if (!ce) { 2962 return; 2963 } 2964 2965 that.containerElement = $(ce); 2966 2967 if (/document/.test(oc) || oc === document) { 2968 that.containerOffset = { left: 0, top: 0 }; 2969 that.containerPosition = { left: 0, top: 0 }; 2970 2971 that.parentData = {
2972 element: $(document), left: 0, top: 0, 2973 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2974 }; 2975 } 2976 2977 // i'm a node, so compute top, left, right, bottom 2978 else { 2979 element = $(ce); 2980 p = []; 2981 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2982 2983 that.containerOffset = element.offset(); 2984 that.containerPosition = element.position(); 2985 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2986 2987 co = that.containerOffset; 2988 ch = that.containerSize.height; 2989 cw = that.containerSize.width; 2990 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 2991 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2992 2993 that.parentData = { 2994 element: ce, left: co.left, top: co.top, width: width, height: height 2995 }; 2996 } 2997 }, 2998 2999 resize: function( event ) { 3000 var woset, hoset, isParent, isOffsetRelative, 3001 that = $(this).data("ui-resizable"), 3002 o = that.options, 3003 co = that.containerOffset, cp = that.position, 3004 pRatio = that._aspectRatio || event.shiftKey, 3005 cop = { top:0, left:0 }, ce = that.containerElement; 3006 3007 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3008 cop = co; 3009 } 3010 3011 if (cp.left < (that._helper ? co.left : 0)) { 3012 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3013 if (pRatio) { 3014 that.size.height = that.size.width / that.aspectRatio; 3015 } 3016 that.position.left = o.helper ? co.left : 0; 3017 } 3018 3019 if (cp.top < (that._helper ? co.top : 0)) { 3020 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3021 if (pRatio) { 3022 that.size.width = that.size.height * that.aspectRatio; 3023 } 3024 that.position.top = that._helper ? co.top : 0; 3025 } 3026 3027 that.offset.left = that.parentData.left+that.position.left; 3028 that.offset.top = that.parentData.top+that.position.top; 3029 3030 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3031 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3032 3033 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3034 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3035 3036 if(isParent && isOffsetRelative) { 3037 woset -= that.parentData.left; 3038 } 3039 3040 if (woset + that.size.width >= that.parentData.width) { 3041 that.size.width = that.parentData.width - woset; 3042 if (pRatio) { 3043 that.size.height = that.size.width / that.aspectRatio; 3044 } 3045 } 3046 3047 if (hoset + that.size.height >= that.parentData.height) { 3048 that.size.height = that.parentData.height - hoset; 3049 if (pRatio) { 3050 that.size.width = that.size.height * that.aspectRatio; 3051 } 3052 } 3053 }, 3054 3055 stop: function(){ 3056 var that = $(this).data("ui-resizable"), 3057 o = that.options, 3058 co = that.containerOffset, 3059 cop = that.containerPosition, 3060 ce = that.containerElement, 3061 helper = $(that.helper), 3062 ho = helper.offset(), 3063 w = helper.outerWidth() - that.sizeDiff.width, 3064 h = helper.outerHeight() - that.sizeDiff.height; 3065 3066 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3067 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3068 } 3069 3070 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3071 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3072 } 3073 3074 } 3075}); 3076 3077$.ui.plugin.add("resizable", "alsoResize", { 3078 3079 start: function () { 3080 var that = $(this).data("ui-resizable"), 3081 o = that.options, 3082 _store = function (exp) { 3083 $(exp).each(function() { 3084 var el = $(this); 3085 el.data("ui-resizable-alsoresize", { 3086 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3087 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3088 }); 3089 }); 3090 }; 3091 3092 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3093 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3094 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3095 }else{ 3096 _store(o.alsoResize); 3097 } 3098 }, 3099 3100 resize: function (event, ui) { 3101 var that = $(this).data("ui-resizable"), 3102 o = that.options, 3103 os = that.originalSize, 3104 op = that.originalPosition, 3105 delta = { 3106 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3107 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3108 }, 3109 3110 _alsoResize = function (exp, c) { 3111 $(exp).each(function() { 3112 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3113 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3114
vendor: 36,306 bytes, lines 3115-4365
3115 $.each(css, function (i, prop) { 3116 var sum = (start[prop]||0) + (delta[prop]||0); 3117 if (sum && sum >= 0) { 3118 style[prop] = sum || null; 3119 } 3120 }); 3121 3122 el.css(style); 3123 }); 3124 }; 3125 3126 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3127 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3128 }else{ 3129 _alsoResize(o.alsoResize); 3130 } 3131 }, 3132 3133 stop: function () { 3134 $(this).removeData("resizable-alsoresize"); 3135 } 3136}); 3137 3138$.ui.plugin.add("resizable", "ghost", { 3139 3140 start: function() { 3141 3142 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3143 3144 that.ghost = that.originalElement.clone(); 3145 that.ghost 3146 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3147 .addClass("ui-resizable-ghost") 3148 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3149 3150 that.ghost.appendTo(that.helper); 3151 3152 }, 3153 3154 resize: function(){ 3155 var that = $(this).data("ui-resizable"); 3156 if (that.ghost) { 3157 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3158 } 3159 }, 3160 3161 stop: function() { 3162 var that = $(this).data("ui-resizable"); 3163 if (that.ghost && that.helper) { 3164 that.helper.get(0).removeChild(that.ghost.get(0)); 3165 } 3166 } 3167 3168}); 3169 3170$.ui.plugin.add("resizable", "grid", { 3171 3172 resize: function() { 3173 var that = $(this).data("ui-resizable"), 3174 o = that.options, 3175 cs = that.size, 3176 os = that.originalSize, 3177 op = that.originalPosition, 3178 a = that.axis, 3179 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3180 gridX = (grid[0]||1), 3181 gridY = (grid[1]||1), 3182 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3183 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3184 newWidth = os.width + ox, 3185 newHeight = os.height + oy, 3186 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3187 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3188 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3189 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3190 3191 o.grid = grid; 3192 3193 if (isMinWidth) { 3194 newWidth = newWidth + gridX; 3195 } 3196 if (isMinHeight) { 3197 newHeight = newHeight + gridY; 3198 } 3199 if (isMaxWidth) { 3200 newWidth = newWidth - gridX; 3201 } 3202 if (isMaxHeight) { 3203 newHeight = newHeight - gridY; 3204 } 3205 3206 if (/^(se|s|e)$/.test(a)) { 3207 that.size.width = newWidth; 3208 that.size.height = newHeight; 3209 } else if (/^(ne)$/.test(a)) { 3210 that.size.width = newWidth; 3211 that.size.height = newHeight; 3212 that.position.top = op.top - oy; 3213 } else if (/^(sw)$/.test(a)) { 3214 that.size.width = newWidth; 3215 that.size.height = newHeight; 3216 that.position.left = op.left - ox; 3217 } else { 3218 that.size.width = newWidth; 3219 that.size.height = newHeight; 3220 that.position.top = op.top - oy; 3221 that.position.left = op.left - ox; 3222 } 3223 } 3224 3225}); 3226 3227})(jQuery); 3228 3229(function( $, undefined ) { 3230 3231$.widget("ui.selectable", $.ui.mouse, { 3232 version: "1.10.1", 3233 options: { 3234 appendTo: "body", 3235 autoRefresh: true, 3236 distance: 0, 3237 filter: "*", 3238 tolerance: "touch", 3239 3240 // callbacks 3241 selected: null, 3242 selecting: null, 3243 start: null, 3244 stop: null, 3245 unselected: null, 3246 unselecting: null 3247 }, 3248 _create: function() { 3249 var selectees, 3250 that = this; 3251 3252 this.element.addClass("ui-selectable"); 3253 3254 this.dragged = false; 3255 3256 // cache selectee children based on filter 3257 this.refresh = function() { 3258 selectees = $(that.options.filter, that.element[0]); 3259 selectees.addClass("ui-selectee"); 3260 selectees.each(function() { 3261 var $this = $(this), 3262 pos = $this.offset(); 3263 $.data(this, "selectable-item", { 3264 element: this, 3265 $element: $this, 3266 left: pos.left, 3267 top: pos.top, 3268 right: pos.left + $this.outerWidth(), 3269 bottom: pos.top + $this.outerHeight(), 3270 startselected: false, 3271 selected: $this.hasClass("ui-selected"), 3272 selecting: $this.hasClass("ui-selecting"), 3273 unselecting: $this.hasClass("ui-unselecting") 3274 }); 3275 }); 3276 }; 3277 this.refresh(); 3278 3279 this.selectees = selectees.addClass("ui-selectee"); 3280 3281 this._mouseInit(); 3282 3283 this.helper = $("<div class='ui-selectable-helper'></div>"); 3284 }, 3285 3286 _destroy: function() { 3287 this.selectees 3288 .removeClass("ui-selectee") 3289 .removeData("selectable-item"); 3290 this.element 3291 .removeClass("ui-selectable ui-selectable-disabled"); 3292 this._mouseDestroy(); 3293 }, 3294 3295 _mouseStart: function(event) { 3296 var that = this, 3297 options = this.options; 3298 3299 this.opos = [event.pageX, event.pageY]; 3300 3301 if (this.options.disabled) { 3302 return; 3303 } 3304 3305 this.selectees = $(options.filter, this.element[0]); 3306 3307 this._trigger("start", event); 3308 3309 $(options.appendTo).append(this.helper); 3310 // position helper (lasso) 3311 this.helper.css({ 3312 "left": event.pageX, 3313 "top": event.pageY, 3314 "width": 0, 3315 "height": 0 3316 }); 3317 3318 if (options.autoRefresh) { 3319 this.refresh(); 3320 } 3321 3322 this.selectees.filter(".ui-selected").each(function() { 3323 var selectee = $.data(this, "selectable-item"); 3324 selectee.startselected = true; 3325 if (!event.metaKey && !event.ctrlKey) { 3326 selectee.$element.removeClass("ui-selected"); 3327 selectee.selected = false; 3328 selectee.$element.addClass("ui-unselecting"); 3329 selectee.unselecting = true; 3330 // selectable UNSELECTING callback 3331 that._trigger("unselecting", event, { 3332 unselecting: selectee.element 3333 }); 3334 } 3335 }); 3336 3337 $(event.target).parents().addBack().each(function() { 3338 var doSelect, 3339 selectee = $.data(this, "selectable-item"); 3340 if (selectee) { 3341 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3342 selectee.$element 3343 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3344 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3345 selectee.unselecting = !doSelect; 3346 selectee.selecting = doSelect; 3347 selectee.selected = doSelect; 3348 // selectable (UN)SELECTING callback 3349 if (doSelect) { 3350 that._trigger("selecting", event, { 3351 selecting: selectee.element 3352 }); 3353 } else { 3354 that._trigger("unselecting", event, { 3355 unselecting: selectee.element 3356 }); 3357 } 3358 return false; 3359 } 3360 }); 3361 3362 }, 3363 3364 _mouseDrag: function(event) { 3365 3366 this.dragged = true; 3367 3368 if (this.options.disabled) { 3369 return; 3370 } 3371 3372 var tmp, 3373 that = this, 3374 options = this.options, 3375 x1 = this.opos[0], 3376 y1 = this.opos[1], 3377 x2 = event.pageX, 3378 y2 = event.pageY; 3379 3380 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3381 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3382 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3383 3384 this.selectees.each(function() { 3385 var selectee = $.data(this, "selectable-item"), 3386 hit = false; 3387 3388 //prevent helper from being selected if appendTo: selectable 3389 if (!selectee || selectee.element === that.element[0]) { 3390 return; 3391 } 3392 3393 if (options.tolerance === "touch") { 3394 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3395 } else if (options.tolerance === "fit") { 3396 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3397 } 3398 3399 if (hit) { 3400 // SELECT 3401 if (selectee.selected) { 3402 selectee.$element.removeClass("ui-selected"); 3403 selectee.selected = false; 3404 } 3405 if (selectee.unselecting) { 3406 selectee.$element.removeClass("ui-unselecting"); 3407 selectee.unselecting = false; 3408 } 3409 if (!selectee.selecting) { 3410 selectee.$element.addClass("ui-selecting"); 3411 selectee.selecting = true; 3412 // selectable SELECTING callback 3413 that._trigger("selecting", event, { 3414 selecting: selectee.element 3415 }); 3416 } 3417 } else { 3418 // UNSELECT 3419 if (selectee.selecting) { 3420 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3421 selectee.$element.removeClass("ui-selecting"); 3422 selectee.selecting = false; 3423 selectee.$element.addClass("ui-selected"); 3424 selectee.selected = true; 3425 } else { 3426 selectee.$element.removeClass("ui-selecting"); 3427 selectee.selecting = false; 3428 if (selectee.startselected) { 3429 selectee.$element.addClass("ui-unselecting"); 3430 selectee.unselecting = true; 3431 } 3432 // selectable UNSELECTING callback 3433 that._trigger("unselecting", event, { 3434 unselecting: selectee.element 3435 }); 3436 } 3437 } 3438 if (selectee.selected) { 3439 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3440 selectee.$element.removeClass("ui-selected"); 3441 selectee.selected = false; 3442 3443 selectee.$element.addClass("ui-unselecting"); 3444 selectee.unselecting = true; 3445 // selectable UNSELECTING callback 3446 that._trigger("unselecting", event, { 3447 unselecting: selectee.element 3448 }); 3449 } 3450 } 3451 } 3452 }); 3453 3454 return false; 3455 }, 3456 3457 _mouseStop: function(event) { 3458 var that = this; 3459 3460 this.dragged = false; 3461 3462 $(".ui-unselecting", this.element[0]).each(function() { 3463 var selectee = $.data(this, "selectable-item"); 3464 selectee.$element.removeClass("ui-unselecting"); 3465 selectee.unselecting = false; 3466 selectee.startselected = false; 3467 that._trigger("unselected", event, { 3468 unselected: selectee.element 3469 }); 3470 }); 3471 $(".ui-selecting", this.element[0]).each(function() { 3472 var selectee = $.data(this, "selectable-item"); 3473 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3474 selectee.selecting = false; 3475 selectee.selected = true; 3476 selectee.startselected = true; 3477 that._trigger("selected", event, { 3478 selected: selectee.element 3479 }); 3480 }); 3481 this._trigger("stop", event); 3482 3483 this.helper.remove(); 3484 3485 return false; 3486 } 3487 3488}); 3489 3490})(jQuery); 3491 3492(function( $, undefined ) { 3493 3494/*jshint loopfunc: true */ 3495 3496function isOverAxis( x, reference, size ) { 3497 return ( x > reference ) && ( x < ( reference + size ) ); 3498} 3499 3500$.widget("ui.sortable", $.ui.mouse, { 3501 version: "1.10.1", 3502 widgetEventPrefix: "sort", 3503 ready: false, 3504 options: { 3505 appendTo: "parent", 3506 axis: false, 3507 connectWith: false, 3508 containment: false, 3509 cursor: "auto", 3510 cursorAt: false, 3511 dropOnEmpty: true, 3512 forcePlaceholderSize: false, 3513 forceHelperSize: false, 3514 grid: false, 3515 handle: false, 3516 helper: "original", 3517 items: "> *", 3518 opacity: false, 3519 placeholder: false, 3520 revert: false, 3521 scroll: true, 3522 scrollSensitivity: 20, 3523 scrollSpeed: 20, 3524 scope: "default", 3525 tolerance: "intersect", 3526 zIndex: 1000, 3527 3528 // callbacks 3529 activate: null, 3530 beforeStop: null, 3531 change: null, 3532 deactivate: null, 3533 out: null, 3534 over: null, 3535 receive: null, 3536 remove: null, 3537 sort: null, 3538 start: null, 3539 stop: null, 3540 update: null 3541 }, 3542 _create: function() { 3543 3544 var o = this.options; 3545 this.containerCache = {}; 3546 this.element.addClass("ui-sortable"); 3547 3548 //Get the items 3549 this.refresh(); 3550 3551 //Let's determine if the items are being displayed horizontally 3552 this.floating = this.items.length ? o.axis === "x" || (/left|right/).test(this.items[0].item.css("float")) || (/inline|table-cell/).test(this.items[0].item.css("display")) : false; 3553 3554 //Let's determine the parent's offset 3555 this.offset = this.element.offset(); 3556 3557 //Initialize mouse events for interaction 3558 this._mouseInit(); 3559 3560 //We're ready to go 3561 this.ready = true; 3562 3563 }, 3564 3565 _destroy: function() { 3566 this.element 3567 .removeClass("ui-sortable ui-sortable-disabled"); 3568 this._mouseDestroy(); 3569 3570 for ( var i = this.items.length - 1; i >= 0; i-- ) { 3571 this.items[i].item.removeData(this.widgetName + "-item"); 3572 } 3573 3574 return this; 3575 }, 3576 3577 _setOption: function(key, value){ 3578 if ( key === "disabled" ) { 3579 this.options[ key ] = value; 3580 3581 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3582 } else { 3583 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3584 $.Widget.prototype._setOption.apply(this, arguments); 3585 } 3586 }, 3587 3588 _mouseCapture: function(event, overrideHandle) { 3589 var currentItem = null, 3590 validHandle = false, 3591 that = this; 3592 3593 if (this.reverting) { 3594 return false; 3595 } 3596 3597 if(this.options.disabled || this.options.type === "static") { 3598 return false; 3599 } 3600 3601 //We have to refresh the items data once first 3602 this._refreshItems(event); 3603 3604 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3605 $(event.target).parents().each(function() { 3606 if($.data(this, that.widgetName + "-item") === that) { 3607 currentItem = $(this); 3608 return false; 3609 } 3610 }); 3611 if($.data(event.target, that.widgetName + "-item") === that) { 3612 currentItem = $(event.target); 3613 } 3614 3615 if(!currentItem) { 3616 return false; 3617 } 3618 if(this.options.handle && !overrideHandle) { 3619 $(this.options.handle, currentItem).find("*").addBack().each(function() { 3620 if(this === event.target) { 3621 validHandle = true; 3622 } 3623 }); 3624 if(!validHandle) { 3625 return false; 3626 } 3627 } 3628 3629 this.currentItem = currentItem; 3630 this._removeCurrentsFromItems(); 3631 return true; 3632 3633 }, 3634 3635 _mouseStart: function(event, overrideHandle, noActivation) { 3636 3637 var i, 3638 o = this.options; 3639 3640 this.currentContainer = this; 3641 3642 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3643 this.refreshPositions(); 3644 3645 //Create and append the visible helper 3646 this.helper = this._createHelper(event); 3647 3648 //Cache the helper size 3649 this._cacheHelperProportions(); 3650 3651 /* 3652 * - Position generation - 3653 * This block generates everything position related - it's the core of draggables. 3654 */ 3655 3656 //Cache the margins of the original element 3657 this._cacheMargins(); 3658 3659 //Get the next scrolling parent 3660 this.scrollParent = this.helper.scrollParent(); 3661 3662 //The element's absolute position on the page minus margins 3663 this.offset = this.currentItem.offset(); 3664 this.offset = { 3665 top: this.offset.top - this.margins.top, 3666 left: this.offset.left - this.margins.left 3667 }; 3668 3669 $.extend(this.offset, { 3670 click: { //Where the click happened, relative to the element 3671 left: event.pageX - this.offset.left, 3672 top: event.pageY - this.offset.top 3673 }, 3674 parent: this._getParentOffset(), 3675 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3676 }); 3677 3678 // Only after we got the offset, we can change the helper's position to absolute 3679 // TODO: Still need to figure out a way to make relative sorting possible 3680 this.helper.css("position", "absolute"); 3681 this.cssPosition = this.helper.css("position"); 3682 3683 //Generate the original position 3684 this.originalPosition = this._generatePosition(event); 3685 this.originalPageX = event.pageX; 3686 this.originalPageY = event.pageY; 3687 3688 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 3689 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3690 3691 //Cache the former DOM position 3692 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3693 3694 //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 3695 if(this.helper[0] !== this.currentItem[0]) { 3696 this.currentItem.hide(); 3697 } 3698 3699 //Create the placeholder 3700 this._createPlaceholder(); 3701 3702 //Set a containment if given in the options 3703 if(o.containment) { 3704 this._setContainment(); 3705 } 3706 3707 if(o.cursor) { // cursor option 3708 if ($("body").css("cursor")) { 3709 this._storedCursor = $("body").css("cursor"); 3710 } 3711 $("body").css("cursor", o.cursor); 3712 } 3713 3714 if(o.opacity) { // opacity option 3715 if (this.helper.css("opacity")) { 3716 this._storedOpacity = this.helper.css("opacity"); 3717 } 3718 this.helper.css("opacity", o.opacity); 3719 } 3720 3721 if(o.zIndex) { // zIndex option 3722 if (this.helper.css("zIndex")) { 3723 this._storedZIndex = this.helper.css("zIndex"); 3724 } 3725 this.helper.css("zIndex", o.zIndex); 3726 } 3727 3728 //Prepare scrolling 3729 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3730 this.overflowOffset = this.scrollParent.offset(); 3731 } 3732 3733 //Call callbacks 3734 this._trigger("start", event, this._uiHash()); 3735 3736 //Recache the helper size 3737 if(!this._preserveHelperProportions) { 3738 this._cacheHelperProportions(); 3739 } 3740 3741 3742 //Post "activate" events to possible containers 3743 if( !noActivation ) { 3744 for ( i = this.containers.length - 1; i >= 0; i-- ) { 3745 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 3746 } 3747 } 3748 3749 //Prepare possible droppables 3750 if($.ui.ddmanager) { 3751 $.ui.ddmanager.current = this; 3752 } 3753 3754 if ($.ui.ddmanager && !o.dropBehaviour) { 3755 $.ui.ddmanager.prepareOffsets(this, event); 3756 } 3757 3758 this.dragging = true; 3759 3760 this.helper.addClass("ui-sortable-helper"); 3761 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3762 return true; 3763 3764 }, 3765 3766 _mouseDrag: function(event) { 3767 var i, item, itemElement, intersection, 3768 o = this.options, 3769 scrolled = false; 3770 3771 //Compute the helpers position 3772 this.position = this._generatePosition(event); 3773 this.positionAbs = this._convertPositionTo("absolute"); 3774 3775 if (!this.lastPositionAbs) { 3776 this.lastPositionAbs = this.positionAbs; 3777 } 3778 3779 //Do scrolling 3780 if(this.options.scroll) { 3781 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3782 3783 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 3784 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3785 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 3786 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3787 } 3788 3789 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 3790 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3791 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 3792 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3793 } 3794 3795 } else { 3796 3797 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 3798 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3799 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 3800 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3801 } 3802 3803 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 3804 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3805 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 3806 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3807 } 3808 3809 } 3810 3811 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 3812 $.ui.ddmanager.prepareOffsets(this, event); 3813 } 3814 } 3815 3816 //Regenerate the absolute position used for position checks 3817 this.positionAbs = this._convertPositionTo("absolute"); 3818 3819 //Set the helper position 3820 if(!this.options.axis || this.options.axis !== "y") { 3821 this.helper[0].style.left = this.position.left+"px"; 3822 } 3823 if(!this.options.axis || this.options.axis !== "x") { 3824 this.helper[0].style.top = this.position.top+"px"; 3825 } 3826 3827 //Rearrange 3828 for (i = this.items.length - 1; i >= 0; i--) { 3829 3830 //Cache variables and intersection, continue if no intersection 3831 item = this.items[i]; 3832 itemElement = item.item[0]; 3833 intersection = this._intersectsWithPointer(item); 3834 if (!intersection) { 3835 continue; 3836 } 3837 3838 // Only put the placeholder inside the current Container, skip all 3839 // items form other containers. This works because when moving 3840 // an item from one container to another the 3841 // currentContainer is switched before the placeholder is moved. 3842 // 3843 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3844 // beetween the outer and inner container. 3845 if (item.instance !== this.currentContainer) { 3846 continue; 3847 } 3848 3849 // cannot intersect with itself 3850 // no useless actions that have been done before 3851 // no action if the item moved is the parent of the item checked 3852 if (itemElement !== this.currentItem[0] && 3853 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 3854 !$.contains(this.placeholder[0], itemElement) && 3855 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 3856 ) { 3857 3858 this.direction = intersection === 1 ? "down" : "up"; 3859 3860 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 3861 this._rearrange(event, item); 3862 } else { 3863 break; 3864 } 3865 3866 this._trigger("change", event, this._uiHash()); 3867 break; 3868 } 3869 } 3870 3871 //Post events to containers 3872 this._contactContainers(event); 3873 3874 //Interconnect with droppables 3875 if($.ui.ddmanager) { 3876 $.ui.ddmanager.drag(this, event); 3877 } 3878 3879 //Call callbacks 3880 this._trigger("sort", event, this._uiHash()); 3881 3882 this.lastPositionAbs = this.positionAbs; 3883 return false; 3884 3885 }, 3886 3887 _mouseStop: function(event, noPropagation) { 3888 3889 if(!event) { 3890 return; 3891 } 3892 3893 //If we are using droppables, inform the manager about the drop 3894 if ($.ui.ddmanager && !this.options.dropBehaviour) { 3895 $.ui.ddmanager.drop(this, event); 3896 } 3897 3898 if(this.options.revert) { 3899 var that = this, 3900 cur = this.placeholder.offset(); 3901 3902 this.reverting = true; 3903 3904 $(this.helper).animate({ 3905 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft), 3906 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop) 3907 }, parseInt(this.options.revert, 10) || 500, function() { 3908 that._clear(event); 3909 }); 3910 } else { 3911 this._clear(event, noPropagation); 3912 } 3913 3914 return false; 3915 3916 }, 3917 3918 cancel: function() { 3919 3920 if(this.dragging) { 3921 3922 this._mouseUp({ target: null }); 3923 3924 if(this.options.helper === "original") { 3925 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3926 } else { 3927 this.currentItem.show(); 3928 } 3929 3930 //Post deactivating events to containers 3931 for (var i = this.containers.length - 1; i >= 0; i--){ 3932 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3933 if(this.containers[i].containerCache.over) { 3934 this.containers[i]._trigger("out", null, this._uiHash(this)); 3935 this.containers[i].containerCache.over = 0; 3936 } 3937 } 3938 3939 } 3940 3941 if (this.placeholder) { 3942 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3943 if(this.placeholder[0].parentNode) { 3944 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3945 } 3946 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 3947 this.helper.remove(); 3948 } 3949 3950 $.extend(this, { 3951 helper: null, 3952 dragging: false, 3953 reverting: false, 3954 _noFinalSort: null 3955 }); 3956 3957 if(this.domPosition.prev) { 3958 $(this.domPosition.prev).after(this.currentItem); 3959 } else { 3960 $(this.domPosition.parent).prepend(this.currentItem); 3961 } 3962 } 3963 3964 return this; 3965 3966 }, 3967 3968 serialize: function(o) { 3969 3970 var items = this._getItemsAsjQuery(o && o.connected), 3971 str = []; 3972 o = o || {}; 3973 3974 $(items).each(function() { 3975 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 3976 if (res) { 3977 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 3978 } 3979 }); 3980 3981 if(!str.length && o.key) { 3982 str.push(o.key + "="); 3983 } 3984 3985 return str.join("&"); 3986 3987 }, 3988 3989 toArray: function(o) { 3990 3991 var items = this._getItemsAsjQuery(o && o.connected), 3992 ret = []; 3993 3994 o = o || {}; 3995 3996 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 3997 return ret; 3998 3999 }, 4000 4001 /* Be careful with the following core functions */ 4002 _intersectsWith: function(item) { 4003 4004 var x1 = this.positionAbs.left, 4005 x2 = x1 + this.helperProportions.width, 4006 y1 = this.positionAbs.top, 4007 y2 = y1 + this.helperProportions.height, 4008 l = item.left, 4009 r = l + item.width, 4010 t = item.top, 4011 b = t + item.height, 4012 dyClick = this.offset.click.top, 4013 dxClick = this.offset.click.left, 4014 isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4015 4016 if ( this.options.tolerance === "pointer" || 4017 this.options.forcePointerForContainers || 4018 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4019 ) { 4020 return isOverElement; 4021 } else { 4022 4023 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4024 x2 - (this.helperProportions.width / 2) < r && // Left Half 4025 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4026 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4027 4028 } 4029 }, 4030 4031 _intersectsWithPointer: function(item) { 4032 4033 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4034 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4035 isOverElement = isOverElementHeight && isOverElementWidth, 4036 verticalDirection = this._getDragVerticalDirection(), 4037 horizontalDirection = this._getDragHorizontalDirection(); 4038 4039 if (!isOverElement) { 4040 return false; 4041 } 4042 4043 return this.floating ? 4044 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4045 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4046 4047 }, 4048 4049 _intersectsWithSides: function(item) { 4050 4051 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4052 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4053 verticalDirection = this._getDragVerticalDirection(), 4054 horizontalDirection = this._getDragHorizontalDirection(); 4055 4056 if (this.floating && horizontalDirection) { 4057 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4058 } else { 4059 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4060 } 4061 4062 }, 4063 4064 _getDragVerticalDirection: function() { 4065 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4066 return delta !== 0 && (delta > 0 ? "down" : "up"); 4067 }, 4068 4069 _getDragHorizontalDirection: function() { 4070 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4071 return delta !== 0 && (delta > 0 ? "right" : "left"); 4072 }, 4073 4074 refresh: function(event) { 4075 this._refreshItems(event); 4076 this.refreshPositions(); 4077 return this; 4078 }, 4079 4080 _connectWith: function() { 4081 var options = this.options; 4082 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4083 }, 4084 4085 _getItemsAsjQuery: function(connected) { 4086 4087 var i, j, cur, inst, 4088 items = [], 4089 queries = [], 4090 connectWith = this._connectWith(); 4091 4092 if(connectWith && connected) { 4093 for (i = connectWith.length - 1; i >= 0; i--){ 4094 cur = $(connectWith[i]); 4095 for ( j = cur.length - 1; j >= 0; j--){ 4096 inst = $.data(cur[j], this.widgetFullName); 4097 if(inst && inst !== this && !inst.options.disabled) { 4098 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]); 4099 } 4100 } 4101 } 4102 } 4103 4104 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]); 4105 4106 for (i = queries.length - 1; i >= 0; i--){ 4107 queries[i][0].each(function() { 4108 items.push(this); 4109 }); 4110 } 4111 4112 return $(items); 4113 4114 }, 4115 4116 _removeCurrentsFromItems: function() { 4117 4118 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4119 4120 this.items = $.grep(this.items, function (item) { 4121 for (var j=0; j < list.length; j++) { 4122 if(list[j] === item.item[0]) { 4123 return false; 4124 } 4125 } 4126 return true; 4127 }); 4128 4129 }, 4130 4131 _refreshItems: function(event) { 4132 4133 this.items = []; 4134 this.containers = [this]; 4135 4136 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4137 items = this.items, 4138 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4139 connectWith = this._connectWith(); 4140 4141 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4142 for (i = connectWith.length - 1; i >= 0; i--){ 4143 cur = $(connectWith[i]); 4144 for (j = cur.length - 1; j >= 0; j--){ 4145 inst = $.data(cur[j], this.widgetFullName); 4146 if(inst && inst !== this && !inst.options.disabled) { 4147 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4148 this.containers.push(inst); 4149 } 4150 } 4151 } 4152 } 4153 4154 for (i = queries.length - 1; i >= 0; i--) { 4155 targetData = queries[i][1]; 4156 _queries = queries[i][0]; 4157 4158 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4159 item = $(_queries[j]); 4160 4161 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4162 4163 items.push({ 4164 item: item, 4165 instance: targetData, 4166 width: 0, height: 0, 4167 left: 0, top: 0 4168 }); 4169 } 4170 } 4171 4172 }, 4173 4174 refreshPositions: function(fast) { 4175 4176 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4177 if(this.offsetParent && this.helper) { 4178 this.offset.parent = this._getParentOffset(); 4179 } 4180 4181 var i, item, t, p; 4182 4183 for (i = this.items.length - 1; i >= 0; i--){ 4184 item = this.items[i]; 4185 4186 //We ignore calculating positions of all connected containers when we're not over them 4187 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4188 continue; 4189 } 4190 4191 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4192 4193 if (!fast) { 4194 item.width = t.outerWidth(); 4195 item.height = t.outerHeight(); 4196 } 4197 4198 p = t.offset(); 4199 item.left = p.left; 4200 item.top = p.top; 4201 } 4202 4203 if(this.options.custom && this.options.custom.refreshContainers) { 4204 this.options.custom.refreshContainers.call(this); 4205 } else { 4206 for (i = this.containers.length - 1; i >= 0; i--){ 4207 p = this.containers[i].element.offset(); 4208 this.containers[i].containerCache.left = p.left; 4209 this.containers[i].containerCache.top = p.top; 4210 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4211 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4212 } 4213 } 4214 4215 return this; 4216 }, 4217 4218 _createPlaceholder: function(that) { 4219 that = that || this; 4220 var className, 4221 o = that.options; 4222 4223 if(!o.placeholder || o.placeholder.constructor === String) { 4224 className = o.placeholder; 4225 o.placeholder = { 4226 element: function() { 4227 4228 var el = $(document.createElement(that.currentItem[0].nodeName)) 4229 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4230 .removeClass("ui-sortable-helper")[0]; 4231 4232 if(!className) { 4233 el.style.visibility = "hidden"; 4234 } 4235 4236 return el; 4237 }, 4238 update: function(container, p) { 4239 4240 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4241 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4242 if(className && !o.forcePlaceholderSize) { 4243 return; 4244 } 4245 4246 //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 4247 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4248 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4249 } 4250 }; 4251 } 4252 4253 //Create the placeholder 4254 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4255 4256 //Append it after the actual current item 4257 that.currentItem.after(that.placeholder); 4258 4259 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4260 o.placeholder.update(that, that.placeholder); 4261 4262 }, 4263 4264 _contactContainers: function(event) { 4265 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, 4266 innermostContainer = null, 4267 innermostIndex = null; 4268 4269 // get innermost container that intersects with item 4270 for (i = this.containers.length - 1; i >= 0; i--) { 4271 4272 // never consider a container that's located within the item itself 4273 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4274 continue; 4275 } 4276 4277 if(this._intersectsWith(this.containers[i].containerCache)) { 4278 4279 // if we've already found a container and it's more "inner" than this, then continue 4280 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4281 continue; 4282 } 4283 4284 innermostContainer = this.containers[i]; 4285 innermostIndex = i; 4286 4287 } else { 4288 // container doesn't intersect. trigger "out" event if necessary 4289 if(this.containers[i].containerCache.over) { 4290 this.containers[i]._trigger("out", event, this._uiHash(this)); 4291 this.containers[i].containerCache.over = 0; 4292 } 4293 } 4294 4295 } 4296 4297 // if no intersecting containers found, return 4298 if(!innermostContainer) { 4299 return; 4300 } 4301 4302 // move the item into the container if it's not there already 4303 if(this.containers.length === 1) { 4304 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4305 this.containers[innermostIndex].containerCache.over = 1; 4306 } else { 4307 4308 //When entering a new container, we will find the item with the least distance and append our item near it 4309 dist = 10000; 4310 itemWithLeastDistance = null; 4311 posProperty = this.containers[innermostIndex].floating ? "left" : "top"; 4312 sizeProperty = this.containers[innermostIndex].floating ? "width" : "height"; 4313 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4314 for (j = this.items.length - 1; j >= 0; j--) { 4315 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4316 continue; 4317 } 4318 if(this.items[j].item[0] === this.currentItem[0]) { 4319 continue; 4320 } 4321 cur = this.items[j].item.offset()[posProperty]; 4322 nearBottom = false; 4323 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4324 nearBottom = true; 4325 cur += this.items[j][sizeProperty]; 4326 } 4327 4328 if(Math.abs(cur - base) < dist) { 4329 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4330 this.direction = nearBottom ? "up": "down"; 4331 } 4332 } 4333 4334 //Check if dropOnEmpty is enabled 4335 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4336 return; 4337 } 4338 4339 this.currentContainer = this.containers[innermostIndex]; 4340 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4341 this._trigger("change", event, this._uiHash()); 4342 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4343 4344 //Update the placeholder 4345 this.options.placeholder.update(this.currentContainer, this.placeholder); 4346 4347 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4348 this.containers[innermostIndex].containerCache.over = 1; 4349 } 4350 4351 4352 }, 4353 4354 _createHelper: function(event) { 4355 4356 var o = this.options, 4357 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4358 4359 //Add the helper to the DOM if that didn't happen already 4360 if(!helper.parents("body").length) { 4361 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4362 } 4363 4364 if(helper[0] === this.currentItem[0]) { 4365 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,379 bytes, lines 4365-4482
4365: this.currentItem.css("left") }; 4366 } 4367 4368 if(!helper[0].style.width || o.forceHelperSize) { 4369 helper.width(this.currentItem.width()); 4370 } 4371 if(!helper[0].style.height || o.forceHelperSize) { 4372 helper.height(this.currentItem.height()); 4373 } 4374 4375 return helper; 4376 4377 }, 4378 4379 _adjustOffsetFromHelper: function(obj) { 4380 if (typeof obj === "string") { 4381 obj = obj.split(" "); 4382 } 4383 if ($.isArray(obj)) { 4384 obj = {left: +obj[0], top: +obj[1] || 0}; 4385 } 4386 if ("left" in obj) { 4387 this.offset.click.left = obj.left + this.margins.left; 4388 } 4389 if ("right" in obj) { 4390 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4391 } 4392 if ("top" in obj) { 4393 this.offset.click.top = obj.top + this.margins.top; 4394 } 4395 if ("bottom" in obj) { 4396 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4397 } 4398 }, 4399 4400 _getParentOffset: function() { 4401 4402 4403 //Get the offsetParent and cache its position 4404 this.offsetParent = this.helper.offsetParent(); 4405 var po = this.offsetParent.offset(); 4406 4407 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4408 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4409 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4410 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4411 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4412 po.left += this.scrollParent.scrollLeft(); 4413 po.top += this.scrollParent.scrollTop(); 4414 } 4415 4416 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4417 // with an ugly IE fix 4418 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4419 po = { top: 0, left: 0 }; 4420 } 4421 4422 return { 4423 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4424 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4425 }; 4426 4427 }, 4428 4429 _getRelativeOffset: function() { 4430 4431 if(this.cssPosition === "relative") { 4432 var p = this.currentItem.position(); 4433 return { 4434 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4435 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4436 }; 4437 } else { 4438 return { top: 0, left: 0 }; 4439 } 4440 4441 }, 4442 4443 _cacheMargins: function() { 4444 this.margins = { 4445 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4446 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4447 }; 4448 }, 4449 4450 _cacheHelperProportions: function() { 4451 this.helperProportions = { 4452 width: this.helper.outerWidth(), 4453 height: this.helper.outerHeight() 4454 }; 4455 }, 4456 4457 _setContainment: function() { 4458 4459 var ce, co, over, 4460 o = this.options; 4461 if(o.containment === "parent") { 4462 o.containment = this.helper[0].parentNode; 4463 } 4464 if(o.containment === "document" || o.containment === "window") { 4465 this.containment = [ 4466 0 - this.offset.relative.left - this.offset.parent.left, 4467 0 - this.offset.relative.top - this.offset.parent.top, 4468 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4469 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4470 ]; 4471 } 4472 4473 if(!(/^(document|window|parent)$/).test(o.containment)) { 4474 ce = $(o.containment)[0]; 4475 co = $(o.containment).offset(); 4476 over = ($(ce).css("overflow") !== "hidden"); 4477 4478 this.containment = [ 4479 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4480 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4481 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, 4482 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 5,508 bytes, lines 4482-4594
448210) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4483 ]; 4484 } 4485 4486 }, 4487 4488 _convertPositionTo: function(d, pos) { 4489 4490 if(!pos) { 4491 pos = this.position; 4492 } 4493 var mod = d === "absolute" ? 1 : -1, 4494 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4495 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4496 4497 return { 4498 top: ( 4499 pos.top + // The absolute mouse position 4500 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4501 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4502 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4503 ), 4504 left: ( 4505 pos.left + // The absolute mouse position 4506 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4507 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4508 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4509 ) 4510 }; 4511 4512 }, 4513 4514 _generatePosition: function(event) { 4515 4516 var top, left, 4517 o = this.options, 4518 pageX = event.pageX, 4519 pageY = event.pageY, 4520 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); 4521 4522 // This is another very weird special case that only happens for relative elements: 4523 // 1. If the css position is relative 4524 // 2. and the scroll parent is the document or similar to the offset parent 4525 // we have to refresh the relative offset during the scroll so there are no jumps 4526 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 4527 this.offset.relative = this._getRelativeOffset(); 4528 } 4529 4530 /* 4531 * - Position constraining - 4532 * Constrain the position to a mix of grid, containment. 4533 */ 4534 4535 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4536 4537 if(this.containment) { 4538 if(event.pageX - this.offset.click.left < this.containment[0]) { 4539 pageX = this.containment[0] + this.offset.click.left; 4540 } 4541 if(event.pageY - this.offset.click.top < this.containment[1]) { 4542 pageY = this.containment[1] + this.offset.click.top; 4543 } 4544 if(event.pageX - this.offset.click.left > this.containment[2]) { 4545 pageX = this.containment[2] + this.offset.click.left; 4546 } 4547 if(event.pageY - this.offset.click.top > this.containment[3]) { 4548 pageY = this.containment[3] + this.offset.click.top; 4549 } 4550 } 4551 4552 if(o.grid) { 4553 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4554 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; 4555 4556 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4557 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; 4558 } 4559 4560 } 4561 4562 return { 4563 top: ( 4564 pageY - // The absolute mouse position 4565 this.offset.click.top - // Click offset (relative to the element) 4566 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 4567 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 4568 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4569 ), 4570 left: ( 4571 pageX - // The absolute mouse position 4572 this.offset.click.left - // Click offset (relative to the element) 4573 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 4574 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 4575 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4576 ) 4577 }; 4578 4579 }, 4580 4581 _rearrange: function(event, i, a, hardRefresh) { 4582 4583 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)); 4584 4585 //Various things done here to improve the performance: 4586 // 1. we create a setTimeout, that calls refreshPositions 4587 // 2. on the instance, we have a counter variable, that get's higher after every append 4588 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4589 // 4. this lets only the last addition to the timeout stack through 4590 this.counter = this.counter ? ++this.counter : 1; 4591 var counter = this.counter; 4592 4593 this._delay(function() { 4594 if(counter === this.counter) {
vendor: 3,274 bytes, lines 4595-4677
4595 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4596 } 4597 }); 4598 4599 }, 4600 4601 _clear: function(event, noPropagation) { 4602 4603 this.reverting = false; 4604 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4605 // everything else normalized again 4606 var i, 4607 delayedTriggers = []; 4608 4609 // We first have to update the dom position of the actual currentItem 4610 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4611 if(!this._noFinalSort && this.currentItem.parent().length) { 4612 this.placeholder.before(this.currentItem); 4613 } 4614 this._noFinalSort = null; 4615 4616 if(this.helper[0] === this.currentItem[0]) { 4617 for(i in this._storedCSS) { 4618 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 4619 this._storedCSS[i] = ""; 4620 } 4621 } 4622 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4623 } else { 4624 this.currentItem.show(); 4625 } 4626 4627 if(this.fromOutside && !noPropagation) { 4628 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4629 } 4630 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 4631 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4632 } 4633 4634 // Check if the items Container has Changed and trigger appropriate 4635 // events. 4636 if (this !== this.currentContainer) { 4637 if(!noPropagation) { 4638 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4639 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4640 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4641 } 4642 } 4643 4644 4645 //Post events to containers 4646 for (i = this.containers.length - 1; i >= 0; i--){ 4647 if(!noPropagation) { 4648 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4649 } 4650 if(this.containers[i].containerCache.over) { 4651 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4652 this.containers[i].containerCache.over = 0; 4653 } 4654 } 4655 4656 //Do what was originally in plugins 4657 if(this._storedCursor) { 4658 $("body").css("cursor", this._storedCursor); 4659 } 4660 if(this._storedOpacity) { 4661 this.helper.css("opacity", this._storedOpacity); 4662 } 4663 if(this._storedZIndex) { 4664 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 4665 } 4666 4667 this.dragging = false; 4668 if(this.cancelHelperRemoval) { 4669 if(!noPropagation) { 4670 this._trigger("beforeStop", event, this._uiHash()); 4671 for (i=0; i < delayedTriggers.length; i++) { 4672 delayedTriggers[i].call(this, event); 4673 } //Trigger all delayed events 4674 this._trigger("stop", event, this._uiHash()); 4675 } 4676 4677 this.fromOutside = false;
vendor: 77,299 bytes, lines 4678-7594
4678 return false; 4679 } 4680 4681 if(!noPropagation) { 4682 this._trigger("beforeStop", event, this._uiHash()); 4683 } 4684 4685 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4686 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4687 4688 if(this.helper[0] !== this.currentItem[0]) { 4689 this.helper.remove(); 4690 } 4691 this.helper = null; 4692 4693 if(!noPropagation) { 4694 for (i=0; i < delayedTriggers.length; i++) { 4695 delayedTriggers[i].call(this, event); 4696 } //Trigger all delayed events 4697 this._trigger("stop", event, this._uiHash()); 4698 } 4699 4700 this.fromOutside = false; 4701 return true; 4702 4703 }, 4704 4705 _trigger: function() { 4706 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4707 this.cancel(); 4708 } 4709 }, 4710 4711 _uiHash: function(_inst) { 4712 var inst = _inst || this; 4713 return { 4714 helper: inst.helper, 4715 placeholder: inst.placeholder || $([]), 4716 position: inst.position, 4717 originalPosition: inst.originalPosition, 4718 offset: inst.positionAbs, 4719 item: inst.currentItem, 4720 sender: _inst ? _inst.element : null 4721 }; 4722 } 4723 4724}); 4725 4726})(jQuery); 4727 4728;(jQuery.effects || (function($, undefined) { 4729 4730var dataSpace = "ui-effects-"; 4731 4732$.effects = { 4733 effect: {} 4734}; 4735 4736/*! 4737 * jQuery Color Animations v2.1.2 4738 * https://github.com/jquery/jquery-color 4739 * 4740 * Copyright 2013 jQuery Foundation and other contributors 4741 * Released under the MIT license. 4742 * http://jquery.org/license 4743 * 4744 * Date: Wed Jan 16 08:47:09 2013 -0600 4745 */ 4746(function( jQuery, undefined ) { 4747 4748 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4749 4750 // plusequals test for += 100 -= 100 4751 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4752 // a set of RE's that can match strings and generate color tuples. 4753 stringParsers = [{ 4754 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4755 parse: function( execResult ) { 4756 return [ 4757 execResult[ 1 ], 4758 execResult[ 2 ], 4759 execResult[ 3 ], 4760 execResult[ 4 ] 4761 ]; 4762 } 4763 }, { 4764 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4765 parse: function( execResult ) { 4766 return [ 4767 execResult[ 1 ] * 2.55, 4768 execResult[ 2 ] * 2.55, 4769 execResult[ 3 ] * 2.55, 4770 execResult[ 4 ] 4771 ]; 4772 } 4773 }, { 4774 // this regex ignores A-F because it's compared against an already lowercased string 4775 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4776 parse: function( execResult ) { 4777 return [ 4778 parseInt( execResult[ 1 ], 16 ), 4779 parseInt( execResult[ 2 ], 16 ), 4780 parseInt( execResult[ 3 ], 16 ) 4781 ]; 4782 } 4783 }, { 4784 // this regex ignores A-F because it's compared against an already lowercased string 4785 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4786 parse: function( execResult ) { 4787 return [ 4788 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4789 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4790 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4791 ]; 4792 } 4793 }, { 4794 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4795 space: "hsla", 4796 parse: function( execResult ) { 4797 return [ 4798 execResult[ 1 ], 4799 execResult[ 2 ] / 100, 4800 execResult[ 3 ] / 100, 4801 execResult[ 4 ] 4802 ]; 4803 } 4804 }], 4805 4806 // jQuery.Color( ) 4807 color = jQuery.Color = function( color, green, blue, alpha ) { 4808 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4809 }, 4810 spaces = { 4811 rgba: { 4812 props: { 4813 red: { 4814 idx: 0, 4815 type: "byte" 4816 }, 4817 green: { 4818 idx: 1, 4819 type: "byte" 4820 }, 4821 blue: { 4822 idx: 2, 4823 type: "byte" 4824 } 4825 } 4826 }, 4827 4828 hsla: { 4829 props: { 4830 hue: { 4831 idx: 0, 4832 type: "degrees" 4833 }, 4834 saturation: { 4835 idx: 1, 4836 type: "percent" 4837 }, 4838 lightness: { 4839 idx: 2, 4840 type: "percent" 4841 } 4842 } 4843 } 4844 }, 4845 propTypes = { 4846 "byte": { 4847 floor: true, 4848 max: 255 4849 }, 4850 "percent": { 4851 max: 1 4852 }, 4853 "degrees": { 4854 mod: 360, 4855 floor: true 4856 } 4857 }, 4858 support = color.support = {}, 4859 4860 // element for support tests 4861 supportElem = jQuery( "<p>" )[ 0 ], 4862 4863 // colors = jQuery.Color.names 4864 colors, 4865 4866 // local aliases of functions called often 4867 each = jQuery.each; 4868 4869// determine rgba support immediately 4870supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4871support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4872 4873// define cache name and alpha properties 4874// for rgba and hsla spaces 4875each( spaces, function( spaceName, space ) { 4876 space.cache = "_" + spaceName; 4877 space.props.alpha = { 4878 idx: 3, 4879 type: "percent", 4880 def: 1 4881 }; 4882}); 4883 4884function clamp( value, prop, allowEmpty ) { 4885 var type = propTypes[ prop.type ] || {}; 4886 4887 if ( value == null ) { 4888 return (allowEmpty || !prop.def) ? null : prop.def; 4889 } 4890 4891 // ~~ is an short way of doing floor for positive numbers 4892 value = type.floor ? ~~value : parseFloat( value ); 4893 4894 // IE will pass in empty strings as value for alpha, 4895 // which will hit this case 4896 if ( isNaN( value ) ) { 4897 return prop.def; 4898 } 4899 4900 if ( type.mod ) { 4901 // we add mod before modding to make sure that negatives values 4902 // get converted properly: -10 -> 350 4903 return (value + type.mod) % type.mod; 4904 } 4905 4906 // for now all property types without mod have min and max 4907 return 0 > value ? 0 : type.max < value ? type.max : value; 4908} 4909 4910function stringParse( string ) { 4911 var inst = color(), 4912 rgba = inst._rgba = []; 4913 4914 string = string.toLowerCase(); 4915 4916 each( stringParsers, function( i, parser ) { 4917 var parsed, 4918 match = parser.re.exec( string ), 4919 values = match && parser.parse( match ), 4920 spaceName = parser.space || "rgba"; 4921 4922 if ( values ) { 4923 parsed = inst[ spaceName ]( values ); 4924 4925 // if this was an rgba parse the assignment might happen twice 4926 // oh well.... 4927 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4928 rgba = inst._rgba = parsed._rgba; 4929 4930 // exit each( stringParsers ) here because we matched 4931 return false; 4932 } 4933 }); 4934 4935 // Found a stringParser that handled it 4936 if ( rgba.length ) { 4937 4938 // if this came from a parsed string, force "transparent" when alpha is 0 4939 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4940 if ( rgba.join() === "0,0,0,0" ) { 4941 jQuery.extend( rgba, colors.transparent ); 4942 } 4943 return inst; 4944 } 4945 4946 // named colors 4947 return colors[ string ]; 4948} 4949 4950color.fn = jQuery.extend( color.prototype, { 4951 parse: function( red, green, blue, alpha ) { 4952 if ( red === undefined ) { 4953 this._rgba = [ null, null, null, null ]; 4954 return this; 4955 } 4956 if ( red.jquery || red.nodeType ) { 4957 red = jQuery( red ).css( green ); 4958 green = undefined; 4959 } 4960 4961 var inst = this, 4962 type = jQuery.type( red ), 4963 rgba = this._rgba = []; 4964 4965 // more than 1 argument specified - assume ( red, green, blue, alpha ) 4966 if ( green !== undefined ) { 4967 red = [ red, green, blue, alpha ]; 4968 type = "array"; 4969 } 4970 4971 if ( type === "string" ) { 4972 return this.parse( stringParse( red ) || colors._default ); 4973 } 4974 4975 if ( type === "array" ) { 4976 each( spaces.rgba.props, function( key, prop ) { 4977 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 4978 }); 4979 return this; 4980 } 4981 4982 if ( type === "object" ) { 4983 if ( red instanceof color ) { 4984 each( spaces, function( spaceName, space ) { 4985 if ( red[ space.cache ] ) { 4986 inst[ space.cache ] = red[ space.cache ].slice(); 4987 } 4988 }); 4989 } else { 4990 each( spaces, function( spaceName, space ) { 4991 var cache = space.cache; 4992 each( space.props, function( key, prop ) { 4993 4994 // if the cache doesn't exist, and we know how to convert 4995 if ( !inst[ cache ] && space.to ) { 4996 4997 // if the value was null, we don't need to copy it 4998 // if the key was alpha, we don't need to copy it either 4999 if ( key === "alpha" || red[ key ] == null ) { 5000 return; 5001 } 5002 inst[ cache ] = space.to( inst._rgba ); 5003 } 5004 5005 // this is the only case where we allow nulls for ALL properties. 5006 // call clamp with alwaysAllowEmpty 5007 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 5008 }); 5009 5010 // everything defined but alpha? 5011 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 5012 // use the default of 1 5013 inst[ cache ][ 3 ] = 1; 5014 if ( space.from ) { 5015 inst._rgba = space.from( inst[ cache ] ); 5016 } 5017 } 5018 }); 5019 } 5020 return this; 5021 } 5022 }, 5023 is: function( compare ) { 5024 var is = color( compare ), 5025 same = true, 5026 inst = this; 5027 5028 each( spaces, function( _, space ) { 5029 var localCache, 5030 isCache = is[ space.cache ]; 5031 if (isCache) { 5032 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 5033 each( space.props, function( _, prop ) { 5034 if ( isCache[ prop.idx ] != null ) { 5035 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 5036 return same; 5037 } 5038 }); 5039 } 5040 return same; 5041 }); 5042 return same; 5043 }, 5044 _space: function() { 5045 var used = [], 5046 inst = this; 5047 each( spaces, function( spaceName, space ) { 5048 if ( inst[ space.cache ] ) { 5049 used.push( spaceName ); 5050 } 5051 }); 5052 return used.pop(); 5053 }, 5054 transition: function( other, distance ) { 5055 var end = color( other ), 5056 spaceName = end._space(), 5057 space = spaces[ spaceName ], 5058 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 5059 start = startColor[ space.cache ] || space.to( startColor._rgba ), 5060 result = start.slice(); 5061 5062 end = end[ space.cache ]; 5063 each( space.props, function( key, prop ) { 5064 var index = prop.idx, 5065 startValue = start[ index ], 5066 endValue = end[ index ], 5067 type = propTypes[ prop.type ] || {}; 5068 5069 // if null, don't override start value 5070 if ( endValue === null ) { 5071 return; 5072 } 5073 // if null - use end 5074 if ( startValue === null ) { 5075 result[ index ] = endValue; 5076 } else { 5077 if ( type.mod ) { 5078 if ( endValue - startValue > type.mod / 2 ) { 5079 startValue += type.mod; 5080 } else if ( startValue - endValue > type.mod / 2 ) { 5081 startValue -= type.mod; 5082 } 5083 } 5084 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 5085 } 5086 }); 5087 return this[ spaceName ]( result ); 5088 }, 5089 blend: function( opaque ) { 5090 // if we are already opaque - return ourself 5091 if ( this._rgba[ 3 ] === 1 ) { 5092 return this; 5093 } 5094 5095 var rgb = this._rgba.slice(), 5096 a = rgb.pop(), 5097 blend = color( opaque )._rgba; 5098 5099 return color( jQuery.map( rgb, function( v, i ) { 5100 return ( 1 - a ) * blend[ i ] + a * v; 5101 })); 5102 }, 5103 toRgbaString: function() { 5104 var prefix = "rgba(", 5105 rgba = jQuery.map( this._rgba, function( v, i ) { 5106 return v == null ? ( i > 2 ? 1 : 0 ) : v; 5107 }); 5108 5109 if ( rgba[ 3 ] === 1 ) { 5110 rgba.pop(); 5111 prefix = "rgb("; 5112 } 5113 5114 return prefix + rgba.join() + ")"; 5115 }, 5116 toHslaString: function() { 5117 var prefix = "hsla(", 5118 hsla = jQuery.map( this.hsla(), function( v, i ) { 5119 if ( v == null ) { 5120 v = i > 2 ? 1 : 0; 5121 } 5122 5123 // catch 1 and 2 5124 if ( i && i < 3 ) { 5125 v = Math.round( v * 100 ) + "%"; 5126 } 5127 return v; 5128 }); 5129 5130 if ( hsla[ 3 ] === 1 ) { 5131 hsla.pop(); 5132 prefix = "hsl("; 5133 } 5134 return prefix + hsla.join() + ")"; 5135 }, 5136 toHexString: function( includeAlpha ) { 5137 var rgba = this._rgba.slice(), 5138 alpha = rgba.pop(); 5139 5140 if ( includeAlpha ) { 5141 rgba.push( ~~( alpha * 255 ) ); 5142 } 5143 5144 return "#" + jQuery.map( rgba, function( v ) { 5145 5146 // default to 0 when nulls exist 5147 v = ( v || 0 ).toString( 16 ); 5148 return v.length === 1 ? "0" + v : v; 5149 }).join(""); 5150 }, 5151 toString: function() { 5152 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 5153 } 5154}); 5155color.fn.parse.prototype = color.fn; 5156 5157// hsla conversions adapted from: 5158// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 5159 5160function hue2rgb( p, q, h ) { 5161 h = ( h + 1 ) % 1; 5162 if ( h * 6 < 1 ) { 5163 return p + (q - p) * h * 6; 5164 } 5165 if ( h * 2 < 1) { 5166 return q; 5167 } 5168 if ( h * 3 < 2 ) { 5169 return p + (q - p) * ((2/3) - h) * 6; 5170 } 5171 return p; 5172} 5173 5174spaces.hsla.to = function ( rgba ) { 5175 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 5176 return [ null, null, null, rgba[ 3 ] ]; 5177 } 5178 var r = rgba[ 0 ] / 255, 5179 g = rgba[ 1 ] / 255, 5180 b = rgba[ 2 ] / 255, 5181 a = rgba[ 3 ], 5182 max = Math.max( r, g, b ), 5183 min = Math.min( r, g, b ), 5184 diff = max - min, 5185 add = max + min, 5186 l = add * 0.5, 5187 h, s; 5188 5189 if ( min === max ) { 5190 h = 0; 5191 } else if ( r === max ) { 5192 h = ( 60 * ( g - b ) / diff ) + 360; 5193 } else if ( g === max ) { 5194 h = ( 60 * ( b - r ) / diff ) + 120; 5195 } else { 5196 h = ( 60 * ( r - g ) / diff ) + 240; 5197 } 5198 5199 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5200 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5201 if ( diff === 0 ) { 5202 s = 0; 5203 } else if ( l <= 0.5 ) { 5204 s = diff / add; 5205 } else { 5206 s = diff / ( 2 - add ); 5207 } 5208 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 5209}; 5210 5211spaces.hsla.from = function ( hsla ) { 5212 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5213 return [ null, null, null, hsla[ 3 ] ]; 5214 } 5215 var h = hsla[ 0 ] / 360, 5216 s = hsla[ 1 ], 5217 l = hsla[ 2 ], 5218 a = hsla[ 3 ], 5219 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5220 p = 2 * l - q; 5221 5222 return [ 5223 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5224 Math.round( hue2rgb( p, q, h ) * 255 ), 5225 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5226 a 5227 ]; 5228}; 5229 5230 5231each( spaces, function( spaceName, space ) { 5232 var props = space.props, 5233 cache = space.cache, 5234 to = space.to, 5235 from = space.from; 5236 5237 // makes rgba() and hsla() 5238 color.fn[ spaceName ] = function( value ) { 5239 5240 // generate a cache for this space if it doesn't exist 5241 if ( to && !this[ cache ] ) { 5242 this[ cache ] = to( this._rgba ); 5243 } 5244 if ( value === undefined ) { 5245 return this[ cache ].slice(); 5246 } 5247 5248 var ret, 5249 type = jQuery.type( value ), 5250 arr = ( type === "array" || type === "object" ) ? value : arguments, 5251 local = this[ cache ].slice(); 5252 5253 each( props, function( key, prop ) { 5254 var val = arr[ type === "object" ? key : prop.idx ]; 5255 if ( val == null ) { 5256 val = local[ prop.idx ]; 5257 } 5258 local[ prop.idx ] = clamp( val, prop ); 5259 }); 5260 5261 if ( from ) { 5262 ret = color( from( local ) ); 5263 ret[ cache ] = local; 5264 return ret; 5265 } else { 5266 return color( local ); 5267 } 5268 }; 5269 5270 // makes red() green() blue() alpha() hue() saturation() lightness() 5271 each( props, function( key, prop ) { 5272 // alpha is included in more than one space 5273 if ( color.fn[ key ] ) { 5274 return; 5275 } 5276 color.fn[ key ] = function( value ) { 5277 var vtype = jQuery.type( value ), 5278 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5279 local = this[ fn ](), 5280 cur = local[ prop.idx ], 5281 match; 5282 5283 if ( vtype === "undefined" ) { 5284 return cur; 5285 } 5286 5287 if ( vtype === "function" ) { 5288 value = value.call( this, cur ); 5289 vtype = jQuery.type( value ); 5290 } 5291 if ( value == null && prop.empty ) { 5292 return this; 5293 } 5294 if ( vtype === "string" ) { 5295 match = rplusequals.exec( value ); 5296 if ( match ) { 5297 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5298 } 5299 } 5300 local[ prop.idx ] = value; 5301 return this[ fn ]( local ); 5302 }; 5303 }); 5304}); 5305 5306// add cssHook and .fx.step function for each named hook. 5307// accept a space separated string of properties 5308color.hook = function( hook ) { 5309 var hooks = hook.split( " " ); 5310 each( hooks, function( i, hook ) { 5311 jQuery.cssHooks[ hook ] = { 5312 set: function( elem, value ) { 5313 var parsed, curElem, 5314 backgroundColor = ""; 5315 5316 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 5317 value = color( parsed || value ); 5318 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5319 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5320 while ( 5321 (backgroundColor === "" || backgroundColor === "transparent") && 5322 curElem && curElem.style 5323 ) { 5324 try { 5325 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5326 curElem = curElem.parentNode; 5327 } catch ( e ) { 5328 } 5329 } 5330 5331 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5332 backgroundColor : 5333 "_default" ); 5334 } 5335 5336 value = value.toRgbaString(); 5337 } 5338 try { 5339 elem.style[ hook ] = value; 5340 } catch( e ) { 5341 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 5342 } 5343 } 5344 }; 5345 jQuery.fx.step[ hook ] = function( fx ) { 5346 if ( !fx.colorInit ) { 5347 fx.start = color( fx.elem, hook ); 5348 fx.end = color( fx.end ); 5349 fx.colorInit = true; 5350 } 5351 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5352 }; 5353 }); 5354 5355}; 5356 5357color.hook( stepHooks ); 5358 5359jQuery.cssHooks.borderColor = { 5360 expand: function( value ) { 5361 var expanded = {}; 5362 5363 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5364 expanded[ "border" + part + "Color" ] = value; 5365 }); 5366 return expanded; 5367 } 5368}; 5369 5370// Basic color names only. 5371// Usage of any of the other color names requires adding yourself or including 5372// jquery.color.svg-names.js. 5373colors = jQuery.Color.names = { 5374 // 4.1. Basic color keywords 5375 aqua: "#00ffff", 5376 black: "#000000", 5377 blue: "#0000ff", 5378 fuchsia: "#ff00ff", 5379 gray: "#808080", 5380 green: "#008000", 5381 lime: "#00ff00", 5382 maroon: "#800000", 5383 navy: "#000080", 5384 olive: "#808000", 5385 purple: "#800080", 5386 red: "#ff0000", 5387 silver: "#c0c0c0", 5388 teal: "#008080", 5389 white: "#ffffff", 5390 yellow: "#ffff00", 5391 5392 // 4.2.3. "transparent" color keyword 5393 transparent: [ null, null, null, 0 ], 5394 5395 _default: "#ffffff" 5396}; 5397 5398})( jQuery ); 5399 5400 5401/******************************************************************************/ 5402/****************************** CLASS ANIMATIONS ******************************/ 5403/******************************************************************************/ 5404(function() { 5405 5406var classAnimationActions = [ "add", "remove", "toggle" ], 5407 shorthandStyles = { 5408 border: 1, 5409 borderBottom: 1, 5410 borderColor: 1, 5411 borderLeft: 1, 5412 borderRight: 1, 5413 borderTop: 1, 5414 borderWidth: 1, 5415 margin: 1, 5416 padding: 1 5417 }; 5418 5419$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 5420 $.fx.step[ prop ] = function( fx ) { 5421 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5422 jQuery.style( fx.elem, prop, fx.end ); 5423 fx.setAttr = true; 5424 } 5425 }; 5426}); 5427 5428function getElementStyles( elem ) { 5429 var key, len, 5430 style = elem.ownerDocument.defaultView ? 5431 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5432 elem.currentStyle, 5433 styles = {}; 5434 5435 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5436 len = style.length; 5437 while ( len-- ) { 5438 key = style[ len ]; 5439 if ( typeof style[ key ] === "string" ) { 5440 styles[ $.camelCase( key ) ] = style[ key ]; 5441 } 5442 } 5443 // support: Opera, IE <9 5444 } else { 5445 for ( key in style ) { 5446 if ( typeof style[ key ] === "string" ) { 5447 styles[ key ] = style[ key ]; 5448 } 5449 } 5450 } 5451 5452 return styles; 5453} 5454 5455 5456function styleDifference( oldStyle, newStyle ) { 5457 var diff = {}, 5458 name, value; 5459 5460 for ( name in newStyle ) { 5461 value = newStyle[ name ]; 5462 if ( oldStyle[ name ] !== value ) { 5463 if ( !shorthandStyles[ name ] ) { 5464 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5465 diff[ name ] = value; 5466 } 5467 } 5468 } 5469 } 5470 5471 return diff; 5472} 5473 5474// support: jQuery <1.8 5475if ( !$.fn.addBack ) { 5476 $.fn.addBack = function( selector ) { 5477 return this.add( selector == null ? 5478 this.prevObject : this.prevObject.filter( selector ) 5479 ); 5480 }; 5481} 5482 5483$.effects.animateClass = function( value, duration, easing, callback ) { 5484 var o = $.speed( duration, easing, callback ); 5485 5486 return this.queue( function() { 5487 var animated = $( this ), 5488 baseClass = animated.attr( "class" ) || "", 5489 applyClassChange, 5490 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5491 5492 // map the animated objects to store the original styles. 5493 allAnimations = allAnimations.map(function() { 5494 var el = $( this ); 5495 return { 5496 el: el, 5497 start: getElementStyles( this ) 5498 }; 5499 }); 5500 5501 // apply class change 5502 applyClassChange = function() { 5503 $.each( classAnimationActions, function(i, action) { 5504 if ( value[ action ] ) { 5505 animated[ action + "Class" ]( value[ action ] ); 5506 } 5507 }); 5508 }; 5509 applyClassChange(); 5510 5511 // map all animated objects again - calculate new styles and diff 5512 allAnimations = allAnimations.map(function() { 5513 this.end = getElementStyles( this.el[ 0 ] ); 5514 this.diff = styleDifference( this.start, this.end ); 5515 return this; 5516 }); 5517 5518 // apply original class 5519 animated.attr( "class", baseClass ); 5520 5521 // map all animated objects again - this time collecting a promise 5522 allAnimations = allAnimations.map(function() { 5523 var styleInfo = this, 5524 dfd = $.Deferred(), 5525 opts = $.extend({}, o, { 5526 queue: false, 5527 complete: function() { 5528 dfd.resolve( styleInfo ); 5529 } 5530 }); 5531 5532 this.el.animate( this.diff, opts ); 5533 return dfd.promise(); 5534 }); 5535 5536 // once all animations have completed: 5537 $.when.apply( $, allAnimations.get() ).done(function() { 5538 5539 // set the final class 5540 applyClassChange(); 5541 5542 // for each animated element, 5543 // clear all css properties that were animated 5544 $.each( arguments, function() { 5545 var el = this.el; 5546 $.each( this.diff, function(key) { 5547 el.css( key, "" ); 5548 }); 5549 }); 5550 5551 // this is guarnteed to be there if you use jQuery.speed() 5552 // it also handles dequeuing the next anim... 5553 o.complete.call( animated[ 0 ] ); 5554 }); 5555 }); 5556}; 5557 5558$.fn.extend({ 5559 _addClass: $.fn.addClass, 5560 addClass: function( classNames, speed, easing, callback ) { 5561 return speed ? 5562 $.effects.animateClass.call( this, 5563 { add: classNames }, speed, easing, callback ) : 5564 this._addClass( classNames ); 5565 }, 5566 5567 _removeClass: $.fn.removeClass, 5568 removeClass: function( classNames, speed, easing, callback ) { 5569 return arguments.length > 1 ? 5570 $.effects.animateClass.call( this, 5571 { remove: classNames }, speed, easing, callback ) : 5572 this._removeClass.apply( this, arguments ); 5573 }, 5574 5575 _toggleClass: $.fn.toggleClass, 5576 toggleClass: function( classNames, force, speed, easing, callback ) { 5577 if ( typeof force === "boolean" || force === undefined ) { 5578 if ( !speed ) { 5579 // without speed parameter 5580 return this._toggleClass( classNames, force ); 5581 } else { 5582 return $.effects.animateClass.call( this, 5583 (force ? { add: classNames } : { remove: classNames }), 5584 speed, easing, callback ); 5585 } 5586 } else { 5587 // without force parameter 5588 return $.effects.animateClass.call( this, 5589 { toggle: classNames }, force, speed, easing ); 5590 } 5591 }, 5592 5593 switchClass: function( remove, add, speed, easing, callback) { 5594 return $.effects.animateClass.call( this, { 5595 add: add, 5596 remove: remove 5597 }, speed, easing, callback ); 5598 } 5599}); 5600 5601})(); 5602 5603/******************************************************************************/ 5604/*********************************** EFFECTS **********************************/ 5605/******************************************************************************/ 5606 5607(function() { 5608 5609$.extend( $.effects, { 5610 version: "1.10.1", 5611 5612 // Saves a set of properties in a data storage 5613 save: function( element, set ) { 5614 for( var i=0; i < set.length; i++ ) { 5615 if ( set[ i ] !== null ) { 5616 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5617 } 5618 } 5619 }, 5620 5621 // Restores a set of previously saved properties from a data storage 5622 restore: function( element, set ) { 5623 var val, i; 5624 for( i=0; i < set.length; i++ ) { 5625 if ( set[ i ] !== null ) { 5626 val = element.data( dataSpace + set[ i ] ); 5627 // support: jQuery 1.6.2 5628 // http://bugs.jquery.com/ticket/9917 5629 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5630 // We can't differentiate between "" and 0 here, so we just assume 5631 // empty string since it's likely to be a more common value... 5632 if ( val === undefined ) { 5633 val = ""; 5634 } 5635 element.css( set[ i ], val ); 5636 } 5637 } 5638 }, 5639 5640 setMode: function( el, mode ) { 5641 if (mode === "toggle") { 5642 mode = el.is( ":hidden" ) ? "show" : "hide"; 5643 } 5644 return mode; 5645 }, 5646 5647 // Translates a [top,left] array into a baseline value 5648 // this should be a little more flexible in the future to handle a string & hash 5649 getBaseline: function( origin, original ) { 5650 var y, x; 5651 switch ( origin[ 0 ] ) { 5652 case "top": y = 0; break; 5653 case "middle": y = 0.5; break; 5654 case "bottom": y = 1; break; 5655 default: y = origin[ 0 ] / original.height; 5656 } 5657 switch ( origin[ 1 ] ) { 5658 case "left": x = 0; break; 5659 case "center": x = 0.5; break; 5660 case "right": x = 1; break; 5661 default: x = origin[ 1 ] / original.width; 5662 } 5663 return { 5664 x: x, 5665 y: y 5666 }; 5667 }, 5668 5669 // Wraps the element around a wrapper that copies position properties 5670 createWrapper: function( element ) { 5671 5672 // if the element is already wrapped, return it 5673 if ( element.parent().is( ".ui-effects-wrapper" )) { 5674 return element.parent(); 5675 } 5676 5677 // wrap the element 5678 var props = { 5679 width: element.outerWidth(true), 5680 height: element.outerHeight(true), 5681 "float": element.css( "float" ) 5682 }, 5683 wrapper = $( "<div></div>" ) 5684 .addClass( "ui-effects-wrapper" ) 5685 .css({ 5686 fontSize: "100%", 5687 background: "transparent", 5688 border: "none", 5689 margin: 0, 5690 padding: 0 5691 }), 5692 // Store the size in case width/height are defined in % - Fixes #5245 5693 size = { 5694 width: element.width(), 5695 height: element.height() 5696 }, 5697 active = document.activeElement; 5698 5699 // support: Firefox 5700 // Firefox incorrectly exposes anonymous content 5701 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5702 try { 5703 active.id; 5704 } catch( e ) { 5705 active = document.body; 5706 } 5707 5708 element.wrap( wrapper ); 5709 5710 // Fixes #7595 - Elements lose focus when wrapped. 5711 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5712 $( active ).focus(); 5713 } 5714 5715 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5716 5717 // transfer positioning properties to the wrapper 5718 if ( element.css( "position" ) === "static" ) { 5719 wrapper.css({ position: "relative" }); 5720 element.css({ position: "relative" }); 5721 } else { 5722 $.extend( props, { 5723 position: element.css( "position" ), 5724 zIndex: element.css( "z-index" ) 5725 }); 5726 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5727 props[ pos ] = element.css( pos ); 5728 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5729 props[ pos ] = "auto"; 5730 } 5731 }); 5732 element.css({ 5733 position: "relative", 5734 top: 0, 5735 left: 0, 5736 right: "auto", 5737 bottom: "auto" 5738 }); 5739 } 5740 element.css(size); 5741 5742 return wrapper.css( props ).show(); 5743 }, 5744 5745 removeWrapper: function( element ) { 5746 var active = document.activeElement; 5747 5748 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5749 element.parent().replaceWith( element ); 5750 5751 // Fixes #7595 - Elements lose focus when wrapped. 5752 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5753 $( active ).focus(); 5754 } 5755 } 5756 5757 5758 return element; 5759 }, 5760 5761 setTransition: function( element, list, factor, value ) { 5762 value = value || {}; 5763 $.each( list, function( i, x ) { 5764 var unit = element.cssUnit( x ); 5765 if ( unit[ 0 ] > 0 ) { 5766 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5767 } 5768 }); 5769 return value; 5770 } 5771}); 5772 5773// return an effect options object for the given parameters: 5774function _normalizeArguments( effect, options, speed, callback ) { 5775 5776 // allow passing all options as the first parameter 5777 if ( $.isPlainObject( effect ) ) { 5778 options = effect; 5779 effect = effect.effect; 5780 } 5781 5782 // convert to an object 5783 effect = { effect: effect }; 5784 5785 // catch (effect, null, ...) 5786 if ( options == null ) { 5787 options = {}; 5788 } 5789 5790 // catch (effect, callback) 5791 if ( $.isFunction( options ) ) { 5792 callback = options; 5793 speed = null; 5794 options = {}; 5795 } 5796 5797 // catch (effect, speed, ?) 5798 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5799 callback = speed; 5800 speed = options; 5801 options = {}; 5802 } 5803 5804 // catch (effect, options, callback) 5805 if ( $.isFunction( speed ) ) { 5806 callback = speed; 5807 speed = null; 5808 } 5809 5810 // add options to effect 5811 if ( options ) { 5812 $.extend( effect, options ); 5813 } 5814 5815 speed = speed || options.duration; 5816 effect.duration = $.fx.off ? 0 : 5817 typeof speed === "number" ? speed : 5818 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5819 $.fx.speeds._default; 5820 5821 effect.complete = callback || options.complete; 5822 5823 return effect; 5824} 5825 5826function standardSpeed( speed ) { 5827 // valid standard speeds 5828 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 5829 return true; 5830 } 5831 5832 // invalid strings - treat as "normal" speed 5833 return typeof speed === "string" && !$.effects.effect[ speed ]; 5834} 5835 5836$.fn.extend({ 5837 effect: function( /* effect, options, speed, callback */ ) { 5838 var args = _normalizeArguments.apply( this, arguments ), 5839 mode = args.mode, 5840 queue = args.queue, 5841 effectMethod = $.effects.effect[ args.effect ]; 5842 5843 if ( $.fx.off || !effectMethod ) { 5844 // delegate to the original method (e.g., .show()) if possible 5845 if ( mode ) { 5846 return this[ mode ]( args.duration, args.complete ); 5847 } else { 5848 return this.each( function() { 5849 if ( args.complete ) { 5850 args.complete.call( this ); 5851 } 5852 }); 5853 } 5854 } 5855 5856 function run( next ) { 5857 var elem = $( this ), 5858 complete = args.complete, 5859 mode = args.mode; 5860 5861 function done() { 5862 if ( $.isFunction( complete ) ) { 5863 complete.call( elem[0] ); 5864 } 5865 if ( $.isFunction( next ) ) { 5866 next(); 5867 } 5868 } 5869 5870 // if the element is hiddden and mode is hide, 5871 // or element is visible and mode is show 5872 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5873 done(); 5874 } else { 5875 effectMethod.call( elem[0], args, done ); 5876 } 5877 } 5878 5879 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5880 }, 5881 5882 _show: $.fn.show, 5883 show: function( speed ) { 5884 if ( standardSpeed( speed ) ) { 5885 return this._show.apply( this, arguments ); 5886 } else { 5887 var args = _normalizeArguments.apply( this, arguments ); 5888 args.mode = "show"; 5889 return this.effect.call( this, args ); 5890 } 5891 }, 5892 5893 _hide: $.fn.hide, 5894 hide: function( speed ) { 5895 if ( standardSpeed( speed ) ) { 5896 return this._hide.apply( this, arguments ); 5897 } else { 5898 var args = _normalizeArguments.apply( this, arguments ); 5899 args.mode = "hide"; 5900 return this.effect.call( this, args ); 5901 } 5902 }, 5903 5904 // jQuery core overloads toggle and creates _toggle 5905 __toggle: $.fn.toggle, 5906 toggle: function( speed ) { 5907 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 5908 return this.__toggle.apply( this, arguments ); 5909 } else { 5910 var args = _normalizeArguments.apply( this, arguments ); 5911 args.mode = "toggle"; 5912 return this.effect.call( this, args ); 5913 } 5914 }, 5915 5916 // helper functions 5917 cssUnit: function(key) { 5918 var style = this.css( key ), 5919 val = []; 5920 5921 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5922 if ( style.indexOf( unit ) > 0 ) { 5923 val = [ parseFloat( style ), unit ]; 5924 } 5925 }); 5926 return val; 5927 } 5928}); 5929 5930})(); 5931 5932/******************************************************************************/ 5933/*********************************** EASING ***********************************/ 5934/******************************************************************************/ 5935 5936(function() { 5937 5938// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 5939 5940var baseEasings = {}; 5941 5942$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 5943 baseEasings[ name ] = function( p ) { 5944 return Math.pow( p, i + 2 ); 5945 }; 5946}); 5947 5948$.extend( baseEasings, { 5949 Sine: function ( p ) { 5950 return 1 - Math.cos( p * Math.PI / 2 ); 5951 }, 5952 Circ: function ( p ) { 5953 return 1 - Math.sqrt( 1 - p * p ); 5954 }, 5955 Elastic: function( p ) { 5956 return p === 0 || p === 1 ? p : 5957 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 5958 }, 5959 Back: function( p ) { 5960 return p * p * ( 3 * p - 2 ); 5961 }, 5962 Bounce: function ( p ) { 5963 var pow2, 5964 bounce = 4; 5965 5966 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 5967 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 5968 } 5969}); 5970 5971$.each( baseEasings, function( name, easeIn ) { 5972 $.easing[ "easeIn" + name ] = easeIn; 5973 $.easing[ "easeOut" + name ] = function( p ) { 5974 return 1 - easeIn( 1 - p ); 5975 }; 5976 $.easing[ "easeInOut" + name ] = function( p ) { 5977 return p < 0.5 ? 5978 easeIn( p * 2 ) / 2 : 5979 1 - easeIn( p * -2 + 2 ) / 2; 5980 }; 5981}); 5982 5983})(); 5984 5985})(jQuery)); 5986 5987(function( $, undefined ) { 5988 5989var uid = 0, 5990 hideProps = {}, 5991 showProps = {}; 5992 5993hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5994 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5995showProps.height = showProps.paddingTop = showProps.paddingBottom = 5996 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5997 5998$.widget( "ui.accordion", { 5999 version: "1.10.1", 6000 options: { 6001 active: 0, 6002 animate: {}, 6003 collapsible: false, 6004 event: "click", 6005 header: "> li > :first-child,> :not(li):even", 6006 heightStyle: "auto", 6007 icons: { 6008 activeHeader: "ui-icon-triangle-1-s", 6009 header: "ui-icon-triangle-1-e" 6010 }, 6011 6012 // callbacks 6013 activate: null, 6014 beforeActivate: null 6015 }, 6016 6017 _create: function() { 6018 var options = this.options; 6019 this.prevShow = this.prevHide = $(); 6020 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 6021 // ARIA 6022 .attr( "role", "tablist" ); 6023 6024 // don't allow collapsible: false and active: false / null 6025 if ( !options.collapsible && (options.active === false || options.active == null) ) { 6026 options.active = 0; 6027 } 6028 6029 this._processPanels(); 6030 // handle negative values 6031 if ( options.active < 0 ) { 6032 options.active += this.headers.length; 6033 } 6034 this._refresh(); 6035 }, 6036 6037 _getCreateEventData: function() { 6038 return { 6039 header: this.active, 6040 panel: !this.active.length ? $() : this.active.next(), 6041 content: !this.active.length ? $() : this.active.next() 6042 }; 6043 }, 6044 6045 _createIcons: function() { 6046 var icons = this.options.icons; 6047 if ( icons ) { 6048 $( "<span>" ) 6049 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 6050 .prependTo( this.headers ); 6051 this.active.children( ".ui-accordion-header-icon" ) 6052 .removeClass( icons.header ) 6053 .addClass( icons.activeHeader ); 6054 this.headers.addClass( "ui-accordion-icons" ); 6055 } 6056 }, 6057 6058 _destroyIcons: function() { 6059 this.headers 6060 .removeClass( "ui-accordion-icons" ) 6061 .children( ".ui-accordion-header-icon" ) 6062 .remove(); 6063 }, 6064 6065 _destroy: function() { 6066 var contents; 6067 6068 // clean up main element 6069 this.element 6070 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 6071 .removeAttr( "role" ); 6072 6073 // clean up headers 6074 this.headers 6075 .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" ) 6076 .removeAttr( "role" ) 6077 .removeAttr( "aria-selected" ) 6078 .removeAttr( "aria-controls" ) 6079 .removeAttr( "tabIndex" ) 6080 .each(function() { 6081 if ( /^ui-accordion/.test( this.id ) ) { 6082 this.removeAttribute( "id" ); 6083 } 6084 }); 6085 this._destroyIcons(); 6086 6087 // clean up content panels 6088 contents = this.headers.next() 6089 .css( "display", "" ) 6090 .removeAttr( "role" ) 6091 .removeAttr( "aria-expanded" ) 6092 .removeAttr( "aria-hidden" ) 6093 .removeAttr( "aria-labelledby" ) 6094 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 6095 .each(function() { 6096 if ( /^ui-accordion/.test( this.id ) ) { 6097 this.removeAttribute( "id" ); 6098 } 6099 }); 6100 if ( this.options.heightStyle !== "content" ) { 6101 contents.css( "height", "" ); 6102 } 6103 }, 6104 6105 _setOption: function( key, value ) { 6106 if ( key === "active" ) { 6107 // _activate() will handle invalid values and update this.options 6108 this._activate( value ); 6109 return; 6110 } 6111 6112 if ( key === "event" ) { 6113 if ( this.options.event ) { 6114 this._off( this.headers, this.options.event ); 6115 } 6116 this._setupEvents( value ); 6117 } 6118 6119 this._super( key, value ); 6120 6121 // setting collapsible: false while collapsed; open first panel 6122 if ( key === "collapsible" && !value && this.options.active === false ) { 6123 this._activate( 0 ); 6124 } 6125 6126 if ( key === "icons" ) { 6127 this._destroyIcons(); 6128 if ( value ) { 6129 this._createIcons(); 6130 } 6131 } 6132 6133 // #5332 - opacity doesn't cascade to positioned elements in IE 6134 // so we need to add the disabled class to the headers and panels 6135 if ( key === "disabled" ) { 6136 this.headers.add( this.headers.next() ) 6137 .toggleClass( "ui-state-disabled", !!value ); 6138 } 6139 }, 6140 6141 _keydown: function( event ) { 6142 /*jshint maxcomplexity:15*/ 6143 if ( event.altKey || event.ctrlKey ) { 6144 return; 6145 } 6146 6147 var keyCode = $.ui.keyCode, 6148 length = this.headers.length, 6149 currentIndex = this.headers.index( event.target ), 6150 toFocus = false; 6151 6152 switch ( event.keyCode ) { 6153 case keyCode.RIGHT: 6154 case keyCode.DOWN: 6155 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6156 break; 6157 case keyCode.LEFT: 6158 case keyCode.UP: 6159 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6160 break; 6161 case keyCode.SPACE: 6162 case keyCode.ENTER: 6163 this._eventHandler( event ); 6164 break; 6165 case keyCode.HOME: 6166 toFocus = this.headers[ 0 ]; 6167 break; 6168 case keyCode.END: 6169 toFocus = this.headers[ length - 1 ]; 6170 break; 6171 } 6172 6173 if ( toFocus ) { 6174 $( event.target ).attr( "tabIndex", -1 ); 6175 $( toFocus ).attr( "tabIndex", 0 ); 6176 toFocus.focus(); 6177 event.preventDefault(); 6178 } 6179 }, 6180 6181 _panelKeyDown : function( event ) { 6182 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6183 $( event.currentTarget ).prev().focus(); 6184 } 6185 }, 6186 6187 refresh: function() { 6188 var options = this.options; 6189 this._processPanels(); 6190 6191 // was collapsed or no panel 6192 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6193 options.active = false; 6194 this.active = $(); 6195 // active false only when collapsible is true 6196 } if ( options.active === false ) { 6197 this._activate( 0 ); 6198 // was active, but active panel is gone 6199 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6200 // all remaining panel are disabled 6201 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6202 options.active = false; 6203 this.active = $(); 6204 // activate previous panel 6205 } else { 6206 this._activate( Math.max( 0, options.active - 1 ) ); 6207 } 6208 // was active, active panel still exists 6209 } else { 6210 // make sure active index is correct 6211 options.active = this.headers.index( this.active ); 6212 } 6213 6214 this._destroyIcons(); 6215 6216 this._refresh(); 6217 }, 6218 6219 _processPanels: function() { 6220 this.headers = this.element.find( this.options.header ) 6221 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 6222 6223 this.headers.next() 6224 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6225 .filter(":not(.ui-accordion-content-active)") 6226 .hide(); 6227 }, 6228 6229 _refresh: function() { 6230 var maxHeight, 6231 options = this.options, 6232 heightStyle = options.heightStyle, 6233 parent = this.element.parent(), 6234 accordionId = this.accordionId = "ui-accordion-" + 6235 (this.element.attr( "id" ) || ++uid); 6236 6237 this.active = this._findActive( options.active ) 6238 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6239 .removeClass( "ui-corner-all" ); 6240 this.active.next() 6241 .addClass( "ui-accordion-content-active" ) 6242 .show(); 6243 6244 this.headers 6245 .attr( "role", "tab" ) 6246 .each(function( i ) { 6247 var header = $( this ), 6248 headerId = header.attr( "id" ), 6249 panel = header.next(), 6250 panelId = panel.attr( "id" ); 6251 if ( !headerId ) { 6252 headerId = accordionId + "-header-" + i; 6253 header.attr( "id", headerId ); 6254 } 6255 if ( !panelId ) { 6256 panelId = accordionId + "-panel-" + i; 6257 panel.attr( "id", panelId ); 6258 } 6259 header.attr( "aria-controls", panelId ); 6260 panel.attr( "aria-labelledby", headerId ); 6261 }) 6262 .next() 6263 .attr( "role", "tabpanel" ); 6264 6265 this.headers 6266 .not( this.active ) 6267 .attr({ 6268 "aria-selected": "false", 6269 tabIndex: -1 6270 }) 6271 .next() 6272 .attr({ 6273 "aria-expanded": "false", 6274 "aria-hidden": "true" 6275 }) 6276 .hide(); 6277 6278 // make sure at least one header is in the tab order 6279 if ( !this.active.length ) { 6280 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6281 } else { 6282 this.active.attr({ 6283 "aria-selected": "true", 6284 tabIndex: 0 6285 }) 6286 .next() 6287 .attr({ 6288 "aria-expanded": "true", 6289 "aria-hidden": "false" 6290 }); 6291 } 6292 6293 this._createIcons(); 6294 6295 this._setupEvents( options.event ); 6296 6297 if ( heightStyle === "fill" ) { 6298 maxHeight = parent.height(); 6299 this.element.siblings( ":visible" ).each(function() { 6300 var elem = $( this ), 6301 position = elem.css( "position" ); 6302 6303 if ( position === "absolute" || position === "fixed" ) { 6304 return; 6305 } 6306 maxHeight -= elem.outerHeight( true ); 6307 }); 6308 6309 this.headers.each(function() { 6310 maxHeight -= $( this ).outerHeight( true ); 6311 }); 6312 6313 this.headers.next() 6314 .each(function() { 6315 $( this ).height( Math.max( 0, maxHeight - 6316 $( this ).innerHeight() + $( this ).height() ) ); 6317 }) 6318 .css( "overflow", "auto" ); 6319 } else if ( heightStyle === "auto" ) { 6320 maxHeight = 0; 6321 this.headers.next() 6322 .each(function() { 6323 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6324 }) 6325 .height( maxHeight ); 6326 } 6327 }, 6328 6329 _activate: function( index ) { 6330 var active = this._findActive( index )[ 0 ]; 6331 6332 // trying to activate the already active panel 6333 if ( active === this.active[ 0 ] ) { 6334 return; 6335 } 6336 6337 // trying to collapse, simulate a click on the currently active header 6338 active = active || this.active[ 0 ]; 6339 6340 this._eventHandler({ 6341 target: active, 6342 currentTarget: active, 6343 preventDefault: $.noop 6344 }); 6345 }, 6346 6347 _findActive: function( selector ) { 6348 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6349 }, 6350 6351 _setupEvents: function( event ) { 6352 var events = { 6353 keydown: "_keydown" 6354 }; 6355 if ( event ) { 6356 $.each( event.split(" "), function( index, eventName ) { 6357 events[ eventName ] = "_eventHandler"; 6358 }); 6359 } 6360 6361 this._off( this.headers.add( this.headers.next() ) ); 6362 this._on( this.headers, events ); 6363 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6364 this._hoverable( this.headers ); 6365 this._focusable( this.headers ); 6366 }, 6367 6368 _eventHandler: function( event ) { 6369 var options = this.options, 6370 active = this.active, 6371 clicked = $( event.currentTarget ), 6372 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6373 collapsing = clickedIsActive && options.collapsible, 6374 toShow = collapsing ? $() : clicked.next(), 6375 toHide = active.next(), 6376 eventData = { 6377 oldHeader: active, 6378 oldPanel: toHide, 6379 newHeader: collapsing ? $() : clicked, 6380 newPanel: toShow 6381 }; 6382 6383 event.preventDefault(); 6384 6385 if ( 6386 // click on active header, but not collapsible 6387 ( clickedIsActive && !options.collapsible ) || 6388 // allow canceling activation 6389 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6390 return; 6391 } 6392 6393 options.active = collapsing ? false : this.headers.index( clicked ); 6394 6395 // when the call to ._toggle() comes after the class changes 6396 // it causes a very odd bug in IE 8 (see #6720) 6397 this.active = clickedIsActive ? $() : clicked; 6398 this._toggle( eventData ); 6399 6400 // switch classes 6401 // corner classes on the previously active header stay after the animation 6402 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6403 if ( options.icons ) { 6404 active.children( ".ui-accordion-header-icon" ) 6405 .removeClass( options.icons.activeHeader ) 6406 .addClass( options.icons.header ); 6407 } 6408 6409 if ( !clickedIsActive ) { 6410 clicked 6411 .removeClass( "ui-corner-all" ) 6412 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6413 if ( options.icons ) { 6414 clicked.children( ".ui-accordion-header-icon" ) 6415 .removeClass( options.icons.header ) 6416 .addClass( options.icons.activeHeader ); 6417 } 6418 6419 clicked 6420 .next() 6421 .addClass( "ui-accordion-content-active" ); 6422 } 6423 }, 6424 6425 _toggle: function( data ) { 6426 var toShow = data.newPanel, 6427 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6428 6429 // handle activating a panel during the animation for another activation 6430 this.prevShow.add( this.prevHide ).stop( true, true ); 6431 this.prevShow = toShow; 6432 this.prevHide = toHide; 6433 6434 if ( this.options.animate ) { 6435 this._animate( toShow, toHide, data ); 6436 } else { 6437 toHide.hide(); 6438 toShow.show(); 6439 this._toggleComplete( data ); 6440 } 6441 6442 toHide.attr({ 6443 "aria-expanded": "false", 6444 "aria-hidden": "true" 6445 }); 6446 toHide.prev().attr( "aria-selected", "false" ); 6447 // if we're switching panels, remove the old header from the tab order 6448 // if we're opening from collapsed state, remove the previous header from the tab order 6449 // if we're collapsing, then keep the collapsing header in the tab order 6450 if ( toShow.length && toHide.length ) { 6451 toHide.prev().attr( "tabIndex", -1 ); 6452 } else if ( toShow.length ) { 6453 this.headers.filter(function() { 6454 return $( this ).attr( "tabIndex" ) === 0; 6455 }) 6456 .attr( "tabIndex", -1 ); 6457 } 6458 6459 toShow 6460 .attr({ 6461 "aria-expanded": "true", 6462 "aria-hidden": "false" 6463 }) 6464 .prev() 6465 .attr({ 6466 "aria-selected": "true", 6467 tabIndex: 0 6468 }); 6469 }, 6470 6471 _animate: function( toShow, toHide, data ) { 6472 var total, easing, duration, 6473 that = this, 6474 adjust = 0, 6475 down = toShow.length && 6476 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6477 animate = this.options.animate || {}, 6478 options = down && animate.down || animate, 6479 complete = function() { 6480 that._toggleComplete( data ); 6481 }; 6482 6483 if ( typeof options === "number" ) { 6484 duration = options; 6485 } 6486 if ( typeof options === "string" ) { 6487 easing = options; 6488 } 6489 // fall back from options to animation in case of partial down settings 6490 easing = easing || options.easing || animate.easing; 6491 duration = duration || options.duration || animate.duration; 6492 6493 if ( !toHide.length ) { 6494 return toShow.animate( showProps, duration, easing, complete ); 6495 } 6496 if ( !toShow.length ) { 6497 return toHide.animate( hideProps, duration, easing, complete ); 6498 } 6499 6500 total = toShow.show().outerHeight(); 6501 toHide.animate( hideProps, { 6502 duration: duration, 6503 easing: easing, 6504 step: function( now, fx ) { 6505 fx.now = Math.round( now ); 6506 } 6507 }); 6508 toShow 6509 .hide() 6510 .animate( showProps, { 6511 duration: duration, 6512 easing: easing, 6513 complete: complete, 6514 step: function( now, fx ) { 6515 fx.now = Math.round( now ); 6516 if ( fx.prop !== "height" ) { 6517 adjust += fx.now; 6518 } else if ( that.options.heightStyle !== "content" ) { 6519 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6520 adjust = 0; 6521 } 6522 } 6523 }); 6524 }, 6525 6526 _toggleComplete: function( data ) { 6527 var toHide = data.oldPanel; 6528 6529 toHide 6530 .removeClass( "ui-accordion-content-active" ) 6531 .prev() 6532 .removeClass( "ui-corner-top" ) 6533 .addClass( "ui-corner-all" ); 6534 6535 // Work around for rendering bug in IE (#5421) 6536 if ( toHide.length ) { 6537 toHide.parent()[0].className = toHide.parent()[0].className; 6538 } 6539 6540 this._trigger( "activate", null, data ); 6541 } 6542}); 6543 6544})( jQuery ); 6545 6546(function( $, undefined ) { 6547 6548// used to prevent race conditions with remote data sources 6549var requestIndex = 0; 6550 6551$.widget( "ui.autocomplete", { 6552 version: "1.10.1", 6553 defaultElement: "<input>", 6554 options: { 6555 appendTo: null, 6556 autoFocus: false, 6557 delay: 300, 6558 minLength: 1, 6559 position: { 6560 my: "left top", 6561 at: "left bottom", 6562 collision: "none" 6563 }, 6564 source: null, 6565 6566 // callbacks 6567 change: null, 6568 close: null, 6569 focus: null, 6570 open: null, 6571 response: null, 6572 search: null, 6573 select: null 6574 }, 6575 6576 pending: 0, 6577 6578 _create: function() { 6579 // Some browsers only repeat keydown events, not keypress events, 6580 // so we use the suppressKeyPress flag to determine if we've already 6581 // handled the keydown event. #7269 6582 // Unfortunately the code for & in keypress is the same as the up arrow, 6583 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6584 // events when we know the keydown event was used to modify the 6585 // search term. #7799 6586 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6587 nodeName = this.element[0].nodeName.toLowerCase(), 6588 isTextarea = nodeName === "textarea", 6589 isInput = nodeName === "input"; 6590 6591 this.isMultiLine = 6592 // Textareas are always multi-line 6593 isTextarea ? true : 6594 // Inputs are always single-line, even if inside a contentEditable element 6595 // IE also treats inputs as contentEditable 6596 isInput ? false : 6597 // All other element types are determined by whether or not they're contentEditable 6598 this.element.prop( "isContentEditable" ); 6599 6600 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6601 this.isNewMenu = true; 6602 6603 this.element 6604 .addClass( "ui-autocomplete-input" ) 6605 .attr( "autocomplete", "off" ); 6606 6607 this._on( this.element, { 6608 keydown: function( event ) { 6609 /*jshint maxcomplexity:15*/ 6610 if ( this.element.prop( "readOnly" ) ) { 6611 suppressKeyPress = true; 6612 suppressInput = true; 6613 suppressKeyPressRepeat = true; 6614 return; 6615 } 6616 6617 suppressKeyPress = false; 6618 suppressInput = false; 6619 suppressKeyPressRepeat = false; 6620 var keyCode = $.ui.keyCode; 6621 switch( event.keyCode ) { 6622 case keyCode.PAGE_UP: 6623 suppressKeyPress = true; 6624 this._move( "previousPage", event ); 6625 break; 6626 case keyCode.PAGE_DOWN: 6627 suppressKeyPress = true; 6628 this._move( "nextPage", event ); 6629 break; 6630 case keyCode.UP: 6631 suppressKeyPress = true; 6632 this._keyEvent( "previous", event ); 6633 break; 6634 case keyCode.DOWN: 6635 suppressKeyPress = true; 6636 this._keyEvent( "next", event ); 6637 break; 6638 case keyCode.ENTER: 6639 case keyCode.NUMPAD_ENTER: 6640 // when menu is open and has focus 6641 if ( this.menu.active ) { 6642 // #6055 - Opera still allows the keypress to occur 6643 // which causes forms to submit 6644 suppressKeyPress = true; 6645 event.preventDefault(); 6646 this.menu.select( event ); 6647 } 6648 break; 6649 case keyCode.TAB: 6650 if ( this.menu.active ) { 6651 this.menu.select( event ); 6652 } 6653 break; 6654 case keyCode.ESCAPE: 6655 if ( this.menu.element.is( ":visible" ) ) { 6656 this._value( this.term ); 6657 this.close( event ); 6658 // Different browsers have different default behavior for escape 6659 // Single press can mean undo or clear 6660 // Double press in IE means clear the whole form 6661 event.preventDefault(); 6662 } 6663 break; 6664 default: 6665 suppressKeyPressRepeat = true; 6666 // search timeout should be triggered before the input value is changed 6667 this._searchTimeout( event ); 6668 break; 6669 } 6670 }, 6671 keypress: function( event ) { 6672 if ( suppressKeyPress ) { 6673 suppressKeyPress = false; 6674 event.preventDefault(); 6675 return; 6676 } 6677 if ( suppressKeyPressRepeat ) { 6678 return; 6679 } 6680 6681 // replicate some key handlers to allow them to repeat in Firefox and Opera 6682 var keyCode = $.ui.keyCode; 6683 switch( event.keyCode ) { 6684 case keyCode.PAGE_UP: 6685 this._move( "previousPage", event ); 6686 break; 6687 case keyCode.PAGE_DOWN: 6688 this._move( "nextPage", event ); 6689 break; 6690 case keyCode.UP: 6691 this._keyEvent( "previous", event ); 6692 break; 6693 case keyCode.DOWN: 6694 this._keyEvent( "next", event ); 6695 break; 6696 } 6697 }, 6698 input: function( event ) { 6699 if ( suppressInput ) { 6700 suppressInput = false; 6701 event.preventDefault(); 6702 return; 6703 } 6704 this._searchTimeout( event ); 6705 }, 6706 focus: function() { 6707 this.selectedItem = null; 6708 this.previous = this._value(); 6709 }, 6710 blur: function( event ) { 6711 if ( this.cancelBlur ) { 6712 delete this.cancelBlur; 6713 return; 6714 } 6715 6716 clearTimeout( this.searching ); 6717 this.close( event ); 6718 this._change( event ); 6719 } 6720 }); 6721 6722 this._initSource(); 6723 this.menu = $( "<ul>" ) 6724 .addClass( "ui-autocomplete ui-front" ) 6725 .appendTo( this._appendTo() ) 6726 .menu({ 6727 // custom key handling for now 6728 input: $(), 6729 // disable ARIA support, the live region takes care of that 6730 role: null 6731 }) 6732 .hide() 6733 .data( "ui-menu" ); 6734 6735 this._on( this.menu.element, { 6736 mousedown: function( event ) { 6737 // prevent moving focus out of the text field 6738 event.preventDefault(); 6739 6740 // IE doesn't prevent moving focus even with event.preventDefault() 6741 // so we set a flag to know when we should ignore the blur event 6742 this.cancelBlur = true; 6743 this._delay(function() { 6744 delete this.cancelBlur; 6745 }); 6746 6747 // clicking on the scrollbar causes focus to shift to the body 6748 // but we can't detect a mouseup or a click immediately afterward 6749 // so we have to track the next mousedown and close the menu if 6750 // the user clicks somewhere outside of the autocomplete 6751 var menuElement = this.menu.element[ 0 ]; 6752 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6753 this._delay(function() { 6754 var that = this; 6755 this.document.one( "mousedown", function( event ) { 6756 if ( event.target !== that.element[ 0 ] && 6757 event.target !== menuElement && 6758 !$.contains( menuElement, event.target ) ) { 6759 that.close(); 6760 } 6761 }); 6762 }); 6763 } 6764 }, 6765 menufocus: function( event, ui ) { 6766 // #7024 - Prevent accidental activation of menu items in Firefox 6767 if ( this.isNewMenu ) { 6768 this.isNewMenu = false; 6769 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6770 this.menu.blur(); 6771 6772 this.document.one( "mousemove", function() { 6773 $( event.target ).trigger( event.originalEvent ); 6774 }); 6775 6776 return; 6777 } 6778 } 6779 6780 var item = ui.item.data( "ui-autocomplete-item" ); 6781 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6782 // use value to match what will end up in the input, if it was a key event 6783 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6784 this._value( item.value ); 6785 } 6786 } else { 6787 // Normally the input is populated with the item's value as the 6788 // menu is navigated, causing screen readers to notice a change and 6789 // announce the item. Since the focus event was canceled, this doesn't 6790 // happen, so we update the live region so that screen readers can 6791 // still notice the change and announce it. 6792 this.liveRegion.text( item.value ); 6793 } 6794 }, 6795 menuselect: function( event, ui ) { 6796 var item = ui.item.data( "ui-autocomplete-item" ), 6797 previous = this.previous; 6798 6799 // only trigger when focus was lost (click on menu) 6800 if ( this.element[0] !== this.document[0].activeElement ) { 6801 this.element.focus(); 6802 this.previous = previous; 6803 // #6109 - IE triggers two focus events and the second 6804 // is asynchronous, so we need to reset the previous 6805 // term synchronously and asynchronously :-( 6806 this._delay(function() { 6807 this.previous = previous; 6808 this.selectedItem = item; 6809 }); 6810 } 6811 6812 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6813 this._value( item.value ); 6814 } 6815 // reset the term after the select event 6816 // this allows custom select handling to work properly 6817 this.term = this._value(); 6818 6819 this.close( event ); 6820 this.selectedItem = item; 6821 } 6822 }); 6823 6824 this.liveRegion = $( "<span>", { 6825 role: "status", 6826 "aria-live": "polite" 6827 }) 6828 .addClass( "ui-helper-hidden-accessible" ) 6829 .insertAfter( this.element ); 6830 6831 // turning off autocomplete prevents the browser from remembering the 6832 // value when navigating through history, so we re-enable autocomplete 6833 // if the page is unloaded before the widget is destroyed. #7790 6834 this._on( this.window, { 6835 beforeunload: function() { 6836 this.element.removeAttr( "autocomplete" ); 6837 } 6838 }); 6839 }, 6840 6841 _destroy: function() { 6842 clearTimeout( this.searching ); 6843 this.element 6844 .removeClass( "ui-autocomplete-input" ) 6845 .removeAttr( "autocomplete" ); 6846 this.menu.element.remove(); 6847 this.liveRegion.remove(); 6848 }, 6849 6850 _setOption: function( key, value ) { 6851 this._super( key, value ); 6852 if ( key === "source" ) { 6853 this._initSource(); 6854 } 6855 if ( key === "appendTo" ) { 6856 this.menu.element.appendTo( this._appendTo() ); 6857 } 6858 if ( key === "disabled" && value && this.xhr ) { 6859 this.xhr.abort(); 6860 } 6861 }, 6862 6863 _appendTo: function() { 6864 var element = this.options.appendTo; 6865 6866 if ( element ) { 6867 element = element.jquery || element.nodeType ? 6868 $( element ) : 6869 this.document.find( element ).eq( 0 ); 6870 } 6871 6872 if ( !element ) { 6873 element = this.element.closest( ".ui-front" ); 6874 } 6875 6876 if ( !element.length ) { 6877 element = this.document[0].body; 6878 } 6879 6880 return element; 6881 }, 6882 6883 _initSource: function() { 6884 var array, url, 6885 that = this; 6886 if ( $.isArray(this.options.source) ) { 6887 array = this.options.source; 6888 this.source = function( request, response ) { 6889 response( $.ui.autocomplete.filter( array, request.term ) ); 6890 }; 6891 } else if ( typeof this.options.source === "string" ) { 6892 url = this.options.source; 6893 this.source = function( request, response ) { 6894 if ( that.xhr ) { 6895 that.xhr.abort(); 6896 } 6897 that.xhr = $.ajax({ 6898 url: url, 6899 data: request, 6900 dataType: "json", 6901 success: function( data ) { 6902 response( data ); 6903 }, 6904 error: function() { 6905 response( [] ); 6906 } 6907 }); 6908 }; 6909 } else { 6910 this.source = this.options.source; 6911 } 6912 }, 6913 6914 _searchTimeout: function( event ) { 6915 clearTimeout( this.searching ); 6916 this.searching = this._delay(function() { 6917 // only search if the value has changed 6918 if ( this.term !== this._value() ) { 6919 this.selectedItem = null; 6920 this.search( null, event ); 6921 } 6922 }, this.options.delay ); 6923 }, 6924 6925 search: function( value, event ) { 6926 value = value != null ? value : this._value(); 6927 6928 // always save the actual value, not the one passed as an argument 6929 this.term = this._value(); 6930 6931 if ( value.length < this.options.minLength ) { 6932 return this.close( event ); 6933 } 6934 6935 if ( this._trigger( "search", event ) === false ) { 6936 return; 6937 } 6938 6939 return this._search( value ); 6940 }, 6941 6942 _search: function( value ) { 6943 this.pending++; 6944 this.element.addClass( "ui-autocomplete-loading" ); 6945 this.cancelSearch = false; 6946 6947 this.source( { term: value }, this._response() ); 6948 }, 6949 6950 _response: function() { 6951 var that = this, 6952 index = ++requestIndex; 6953 6954 return function( content ) { 6955 if ( index === requestIndex ) { 6956 that.__response( content ); 6957 } 6958 6959 that.pending--; 6960 if ( !that.pending ) { 6961 that.element.removeClass( "ui-autocomplete-loading" ); 6962 } 6963 }; 6964 }, 6965 6966 __response: function( content ) { 6967 if ( content ) { 6968 content = this._normalize( content ); 6969 } 6970 this._trigger( "response", null, { content: content } ); 6971 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6972 this._suggest( content ); 6973 this._trigger( "open" ); 6974 } else { 6975 // use ._close() instead of .close() so we don't cancel future searches 6976 this._close(); 6977 } 6978 }, 6979 6980 close: function( event ) { 6981 this.cancelSearch = true; 6982 this._close( event ); 6983 }, 6984 6985 _close: function( event ) { 6986 if ( this.menu.element.is( ":visible" ) ) { 6987 this.menu.element.hide(); 6988 this.menu.blur(); 6989 this.isNewMenu = true; 6990 this._trigger( "close", event ); 6991 } 6992 }, 6993 6994 _change: function( event ) { 6995 if ( this.previous !== this._value() ) { 6996 this._trigger( "change", event, { item: this.selectedItem } ); 6997 } 6998 }, 6999 7000 _normalize: function( items ) { 7001 // assume all items have the right format when the first item is complete 7002 if ( items.length && items[0].label && items[0].value ) { 7003 return items; 7004 } 7005 return $.map( items, function( item ) { 7006 if ( typeof item === "string" ) { 7007 return { 7008 label: item, 7009 value: item 7010 }; 7011 } 7012 return $.extend({ 7013 label: item.label || item.value, 7014 value: item.value || item.label 7015 }, item ); 7016 }); 7017 }, 7018 7019 _suggest: function( items ) { 7020 var ul = this.menu.element.empty(); 7021 this._renderMenu( ul, items ); 7022 this.menu.refresh(); 7023 7024 // size and position menu 7025 ul.show(); 7026 this._resizeMenu(); 7027 ul.position( $.extend({ 7028 of: this.element 7029 }, this.options.position )); 7030 7031 if ( this.options.autoFocus ) { 7032 this.menu.next(); 7033 } 7034 }, 7035 7036 _resizeMenu: function() { 7037 var ul = this.menu.element; 7038 ul.outerWidth( Math.max( 7039 // Firefox wraps long text (possibly a rounding bug) 7040 // so we add 1px to avoid the wrapping (#7513) 7041 ul.width( "" ).outerWidth() + 1, 7042 this.element.outerWidth() 7043 ) ); 7044 }, 7045 7046 _renderMenu: function( ul, items ) { 7047 var that = this; 7048 $.each( items, function( index, item ) { 7049 that._renderItemData( ul, item ); 7050 }); 7051 }, 7052 7053 _renderItemData: function( ul, item ) { 7054 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7055 }, 7056 7057 _renderItem: function( ul, item ) { 7058 return $( "<li>" ) 7059 .append( $( "<a>" ).text( item.label ) ) 7060 .appendTo( ul ); 7061 }, 7062 7063 _move: function( direction, event ) { 7064 if ( !this.menu.element.is( ":visible" ) ) { 7065 this.search( null, event ); 7066 return; 7067 } 7068 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7069 this.menu.isLastItem() && /^next/.test( direction ) ) { 7070 this._value( this.term ); 7071 this.menu.blur(); 7072 return; 7073 } 7074 this.menu[ direction ]( event ); 7075 }, 7076 7077 widget: function() { 7078 return this.menu.element; 7079 }, 7080 7081 _value: function() { 7082 return this.valueMethod.apply( this.element, arguments ); 7083 }, 7084 7085 _keyEvent: function( keyEvent, event ) { 7086 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7087 this._move( keyEvent, event ); 7088 7089 // prevents moving cursor to beginning/end of the text field in some browsers 7090 event.preventDefault(); 7091 } 7092 } 7093}); 7094 7095$.extend( $.ui.autocomplete, { 7096 escapeRegex: function( value ) { 7097 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 7098 }, 7099 filter: function(array, term) { 7100 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 7101 return $.grep( array, function(value) { 7102 return matcher.test( value.label || value.value || value ); 7103 }); 7104 } 7105}); 7106 7107 7108// live region extension, adding a `messages` option 7109// NOTE: This is an experimental API. We are still investigating 7110// a full solution for string manipulation and internationalization. 7111$.widget( "ui.autocomplete", $.ui.autocomplete, { 7112 options: { 7113 messages: { 7114 noResults: "No search results.", 7115 results: function( amount ) { 7116 return amount + ( amount > 1 ? " results are" : " result is" ) + 7117 " available, use up and down arrow keys to navigate."; 7118 } 7119 } 7120 }, 7121 7122 __response: function( content ) { 7123 var message; 7124 this._superApply( arguments ); 7125 if ( this.options.disabled || this.cancelSearch ) { 7126 return; 7127 } 7128 if ( content && content.length ) { 7129 message = this.options.messages.results( content.length ); 7130 } else { 7131 message = this.options.messages.noResults; 7132 } 7133 this.liveRegion.text( message ); 7134 } 7135}); 7136 7137}( jQuery )); 7138 7139(function( $, undefined ) { 7140 7141var lastActive, startXPos, startYPos, clickDragged, 7142 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7143 stateClasses = "ui-state-hover ui-state-active ", 7144 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", 7145 formResetHandler = function() { 7146 var buttons = $( this ).find( ":ui-button" ); 7147 setTimeout(function() { 7148 buttons.button( "refresh" ); 7149 }, 1 ); 7150 }, 7151 radioGroup = function( radio ) { 7152 var name = radio.name, 7153 form = radio.form, 7154 radios = $( [] ); 7155 if ( name ) { 7156 name = name.replace( /'/g, "\\'" ); 7157 if ( form ) { 7158 radios = $( form ).find( "[name='" + name + "']" ); 7159 } else { 7160 radios = $( "[name='" + name + "']", radio.ownerDocument ) 7161 .filter(function() { 7162 return !this.form; 7163 }); 7164 } 7165 } 7166 return radios; 7167 }; 7168 7169$.widget( "ui.button", { 7170 version: "1.10.1", 7171 defaultElement: "<button>", 7172 options: { 7173 disabled: null, 7174 text: true, 7175 label: null, 7176 icons: { 7177 primary: null, 7178 secondary: null 7179 } 7180 }, 7181 _create: function() { 7182 this.element.closest( "form" ) 7183 .unbind( "reset" + this.eventNamespace ) 7184 .bind( "reset" + this.eventNamespace, formResetHandler ); 7185 7186 if ( typeof this.options.disabled !== "boolean" ) { 7187 this.options.disabled = !!this.element.prop( "disabled" ); 7188 } else { 7189 this.element.prop( "disabled", this.options.disabled ); 7190 } 7191 7192 this._determineButtonType(); 7193 this.hasTitle = !!this.buttonElement.attr( "title" ); 7194 7195 var that = this, 7196 options = this.options, 7197 toggleButton = this.type === "checkbox" || this.type === "radio", 7198 activeClass = !toggleButton ? "ui-state-active" : "", 7199 focusClass = "ui-state-focus"; 7200 7201 if ( options.label === null ) { 7202 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7203 } 7204 7205 this._hoverable( this.buttonElement ); 7206 7207 this.buttonElement 7208 .addClass( baseClasses ) 7209 .attr( "role", "button" ) 7210 .bind( "mouseenter" + this.eventNamespace, function() { 7211 if ( options.disabled ) { 7212 return; 7213 } 7214 if ( this === lastActive ) { 7215 $( this ).addClass( "ui-state-active" ); 7216 } 7217 }) 7218 .bind( "mouseleave" + this.eventNamespace, function() { 7219 if ( options.disabled ) { 7220 return; 7221 } 7222 $( this ).removeClass( activeClass ); 7223 }) 7224 .bind( "click" + this.eventNamespace, function( event ) { 7225 if ( options.disabled ) { 7226 event.preventDefault(); 7227 event.stopImmediatePropagation(); 7228 } 7229 }); 7230 7231 this.element 7232 .bind( "focus" + this.eventNamespace, function() { 7233 // no need to check disabled, focus won't be triggered anyway 7234 that.buttonElement.addClass( focusClass ); 7235 }) 7236 .bind( "blur" + this.eventNamespace, function() { 7237 that.buttonElement.removeClass( focusClass ); 7238 }); 7239 7240 if ( toggleButton ) { 7241 this.element.bind( "change" + this.eventNamespace, function() { 7242 if ( clickDragged ) { 7243 return; 7244 } 7245 that.refresh(); 7246 }); 7247 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 7248 // prevents issue where button state changes but checkbox/radio checked state 7249 // does not in Firefox (see ticket #6970) 7250 this.buttonElement 7251 .bind( "mousedown" + this.eventNamespace, function( event ) { 7252 if ( options.disabled ) { 7253 return; 7254 } 7255 clickDragged = false; 7256 startXPos = event.pageX; 7257 startYPos = event.pageY; 7258 }) 7259 .bind( "mouseup" + this.eventNamespace, function( event ) { 7260 if ( options.disabled ) { 7261 return; 7262 } 7263 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 7264 clickDragged = true; 7265 } 7266 }); 7267 } 7268 7269 if ( this.type === "checkbox" ) { 7270 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7271 if ( options.disabled || clickDragged ) { 7272 return false; 7273 } 7274 }); 7275 } else if ( this.type === "radio" ) { 7276 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7277 if ( options.disabled || clickDragged ) { 7278 return false; 7279 } 7280 $( this ).addClass( "ui-state-active" ); 7281 that.buttonElement.attr( "aria-pressed", "true" ); 7282 7283 var radio = that.element[ 0 ]; 7284 radioGroup( radio ) 7285 .not( radio ) 7286 .map(function() { 7287 return $( this ).button( "widget" )[ 0 ]; 7288 }) 7289 .removeClass( "ui-state-active" ) 7290 .attr( "aria-pressed", "false" ); 7291 }); 7292 } else { 7293 this.buttonElement 7294 .bind( "mousedown" + this.eventNamespace, function() { 7295 if ( options.disabled ) { 7296 return false; 7297 } 7298 $( this ).addClass( "ui-state-active" ); 7299 lastActive = this; 7300 that.document.one( "mouseup", function() { 7301 lastActive = null; 7302 }); 7303 }) 7304 .bind( "mouseup" + this.eventNamespace, function() { 7305 if ( options.disabled ) { 7306 return false; 7307 } 7308 $( this ).removeClass( "ui-state-active" ); 7309 }) 7310 .bind( "keydown" + this.eventNamespace, function(event) { 7311 if ( options.disabled ) { 7312 return false; 7313 } 7314 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7315 $( this ).addClass( "ui-state-active" ); 7316 } 7317 }) 7318 // see #8559, we bind to blur here in case the button element loses 7319 // focus between keydown and keyup, it would be left in an "active" state 7320 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7321 $( this ).removeClass( "ui-state-active" ); 7322 }); 7323 7324 if ( this.buttonElement.is("a") ) { 7325 this.buttonElement.keyup(function(event) { 7326 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7327 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7328 $( this ).click(); 7329 } 7330 }); 7331 } 7332 } 7333 7334 // TODO: pull out $.Widget's handling for the disabled option into 7335 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7336 // be overridden by individual plugins 7337 this._setOption( "disabled", options.disabled ); 7338 this._resetButton(); 7339 }, 7340 7341 _determineButtonType: function() { 7342 var ancestor, labelSelector, checked; 7343 7344 if ( this.element.is("[type=checkbox]") ) { 7345 this.type = "checkbox"; 7346 } else if ( this.element.is("[type=radio]") ) { 7347 this.type = "radio"; 7348 } else if ( this.element.is("input") ) { 7349 this.type = "input"; 7350 } else { 7351 this.type = "button"; 7352 } 7353 7354 if ( this.type === "checkbox" || this.type === "radio" ) { 7355 // we don't search against the document in case the element 7356 // is disconnected from the DOM 7357 ancestor = this.element.parents().last(); 7358 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7359 this.buttonElement = ancestor.find( labelSelector ); 7360 if ( !this.buttonElement.length ) { 7361 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7362 this.buttonElement = ancestor.filter( labelSelector ); 7363 if ( !this.buttonElement.length ) { 7364 this.buttonElement = ancestor.find( labelSelector ); 7365 } 7366 } 7367 this.element.addClass( "ui-helper-hidden-accessible" ); 7368 7369 checked = this.element.is( ":checked" ); 7370 if ( checked ) { 7371 this.buttonElement.addClass( "ui-state-active" ); 7372 } 7373 this.buttonElement.prop( "aria-pressed", checked ); 7374 } else { 7375 this.buttonElement = this.element; 7376 } 7377 }, 7378 7379 widget: function() { 7380 return this.buttonElement; 7381 }, 7382 7383 _destroy: function() { 7384 this.element 7385 .removeClass( "ui-helper-hidden-accessible" ); 7386 this.buttonElement 7387 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7388 .removeAttr( "role" ) 7389 .removeAttr( "aria-pressed" ) 7390 .html( this.buttonElement.find(".ui-button-text").html() ); 7391 7392 if ( !this.hasTitle ) { 7393 this.buttonElement.removeAttr( "title" ); 7394 } 7395 }, 7396 7397 _setOption: function( key, value ) { 7398 this._super( key, value ); 7399 if ( key === "disabled" ) { 7400 if ( value ) { 7401 this.element.prop( "disabled", true ); 7402 } else { 7403 this.element.prop( "disabled", false ); 7404 } 7405 return; 7406 } 7407 this._resetButton(); 7408 }, 7409 7410 refresh: function() { 7411 //See #8237 & #8828 7412 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7413 7414 if ( isDisabled !== this.options.disabled ) { 7415 this._setOption( "disabled", isDisabled ); 7416 } 7417 if ( this.type === "radio" ) { 7418 radioGroup( this.element[0] ).each(function() { 7419 if ( $( this ).is( ":checked" ) ) { 7420 $( this ).button( "widget" ) 7421 .addClass( "ui-state-active" ) 7422 .attr( "aria-pressed", "true" ); 7423 } else { 7424 $( this ).button( "widget" ) 7425 .removeClass( "ui-state-active" ) 7426 .attr( "aria-pressed", "false" ); 7427 } 7428 }); 7429 } else if ( this.type === "checkbox" ) { 7430 if ( this.element.is( ":checked" ) ) { 7431 this.buttonElement 7432 .addClass( "ui-state-active" ) 7433 .attr( "aria-pressed", "true" ); 7434 } else { 7435 this.buttonElement 7436 .removeClass( "ui-state-active" ) 7437 .attr( "aria-pressed", "false" ); 7438 } 7439 } 7440 }, 7441 7442 _resetButton: function() { 7443 if ( this.type === "input" ) { 7444 if ( this.options.label ) { 7445 this.element.val( this.options.label ); 7446 } 7447 return; 7448 } 7449 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7450 buttonText = $( "<span></span>", this.document[0] ) 7451 .addClass( "ui-button-text" ) 7452 .html( this.options.label ) 7453 .appendTo( buttonElement.empty() ) 7454 .text(), 7455 icons = this.options.icons, 7456 multipleIcons = icons.primary && icons.secondary, 7457 buttonClasses = []; 7458 7459 if ( icons.primary || icons.secondary ) { 7460 if ( this.options.text ) { 7461 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7462 } 7463 7464 if ( icons.primary ) { 7465 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7466 } 7467 7468 if ( icons.secondary ) { 7469 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7470 } 7471 7472 if ( !this.options.text ) { 7473 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7474 7475 if ( !this.hasTitle ) { 7476 buttonElement.attr( "title", $.trim( buttonText ) ); 7477 } 7478 } 7479 } else { 7480 buttonClasses.push( "ui-button-text-only" ); 7481 } 7482 buttonElement.addClass( buttonClasses.join( " " ) ); 7483 } 7484}); 7485 7486$.widget( "ui.buttonset", { 7487 version: "1.10.1", 7488 options: { 7489 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7490 }, 7491 7492 _create: function() { 7493 this.element.addClass( "ui-buttonset" ); 7494 }, 7495 7496 _init: function() { 7497 this.refresh(); 7498 }, 7499 7500 _setOption: function( key, value ) { 7501 if ( key === "disabled" ) { 7502 this.buttons.button( "option", key, value ); 7503 } 7504 7505 this._super( key, value ); 7506 }, 7507 7508 refresh: function() { 7509 var rtl = this.element.css( "direction" ) === "rtl"; 7510 7511 this.buttons = this.element.find( this.options.items ) 7512 .filter( ":ui-button" ) 7513 .button( "refresh" ) 7514 .end() 7515 .not( ":ui-button" ) 7516 .button() 7517 .end() 7518 .map(function() { 7519 return $( this ).button( "widget" )[ 0 ]; 7520 }) 7521 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7522 .filter( ":first" ) 7523 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7524 .end() 7525 .filter( ":last" ) 7526 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7527 .end() 7528 .end(); 7529 }, 7530 7531 _destroy: function() { 7532 this.element.removeClass( "ui-buttonset" ); 7533 this.buttons 7534 .map(function() { 7535 return $( this ).button( "widget" )[ 0 ]; 7536 }) 7537 .removeClass( "ui-corner-left ui-corner-right" ) 7538 .end() 7539 .button( "destroy" ); 7540 } 7541}); 7542 7543}( jQuery ) ); 7544 7545(function( $, undefined ) { 7546 7547$.extend($.ui, { datepicker: { version: "1.10.1" } }); 7548 7549var PROP_NAME = "datepicker", 7550 dpuuid = new Date().getTime(), 7551 instActive; 7552 7553/* Date picker manager. 7554 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7555 Settings for (groups of) date pickers are maintained in an instance object, 7556 allowing multiple different settings on the same page. */ 7557 7558function Datepicker() { 7559 this._curInst = null; // The current instance in use 7560 this._keyEvent = false; // If the last event was a key event 7561 this._disabledInputs = []; // List of date picker inputs that have been disabled 7562 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7563 this._inDialog = false; // True if showing within a "dialog", false if not 7564 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7565 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7566 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7567 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7568 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7569 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7570 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7571 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7572 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7573 this.regional = []; // Available regional settings, indexed by language code 7574 this.regional[""] = { // Default regional settings 7575 closeText: "Done", // Display text for close link 7576 prevText: "Prev", // Display text for previous month link 7577 nextText: "Next", // Display text for next month link 7578 currentText: "Today", // Display text for current month link 7579 monthNames: ["January","February","March","April","May","June", 7580 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7581 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7582 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7583 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7584 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7585 weekHeader: "Wk", // Column header for week of the year 7586 dateFormat: "mm/dd/yy", // See format options on parseDate 7587 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7588 isRTL: false, // True if right-to-left language, false if left-to-right 7589 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7590 yearSuffix: "" // Additional text to append to the year in the month headers 7591 }; 7592 this._defaults = { // Global defaults for all the date picker instances 7593 showOn: "focus", // "focus" for popup on focus, 7594 // "button" for trigger button, or "both" for either
vendor: 6,360 bytes, lines 7595-7724
7595 showAnim: "fadeIn", // Name of jQuery animation for popup 7596 showOptions: {}, // Options for enhanced animations 7597 defaultDate: null, // Used when field is blank: actual date, 7598 // +/-number for offset from today, null for today 7599 appendText: "", // Display text following the input box, e.g. showing the format 7600 buttonText: "...", // Text for trigger button 7601 buttonImage: "", // URL for trigger button image 7602 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7603 hideIfNoPrevNext: false, // True to hide next/previous month links 7604 // if not applicable, false to just disable them 7605 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7606 gotoCurrent: false, // True if today link goes back to current selection instead 7607 changeMonth: false, // True if month can be selected directly, false if only prev/next 7608 changeYear: false, // True if year can be selected directly, false if only prev/next 7609 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7610 // either relative to today's year (-nn:+nn), relative to currently displayed year 7611 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7612 showOtherMonths: false, // True to show dates in other months, false to leave blank 7613 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7614 showWeek: false, // True to show week of the year, false to not show it 7615 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7616 // takes a Date and returns the number of the week for it 7617 shortYearCutoff: "+10", // Short year values < this are in the current century, 7618 // > this are in the previous century, 7619 // string value starting with "+" for current year + value 7620 minDate: null, // The earliest selectable date, or null for no limit 7621 maxDate: null, // The latest selectable date, or null for no limit 7622 duration: "fast", // Duration of display/closure 7623 beforeShowDay: null, // Function that takes a date and returns an array with 7624 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7625 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7626 beforeShow: null, // Function that takes an input field and 7627 // returns a set of custom settings for the date picker 7628 onSelect: null, // Define a callback function when a date is selected 7629 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7630 onClose: null, // Define a callback function when the datepicker is closed 7631 numberOfMonths: 1, // Number of months to show at a time 7632 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7633 stepMonths: 1, // Number of months to step back/forward 7634 stepBigMonths: 12, // Number of months to step back/forward for the big links 7635 altField: "", // Selector for an alternate field to store selected dates into 7636 altFormat: "", // The date format to use for the alternate field 7637 constrainInput: true, // The input is constrained by the current date format 7638 showButtonPanel: false, // True to show button panel, false to not show it 7639 autoSize: false, // True to size the input for the date format, false to leave as is 7640 disabled: false // The initial disabled state 7641 }; 7642 $.extend(this._defaults, this.regional[""]); 7643 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7644} 7645 7646$.extend(Datepicker.prototype, { 7647 /* Class name added to elements to indicate already configured with a date picker. */ 7648 markerClassName: "hasDatepicker", 7649 7650 //Keep track of the maximum number of rows displayed (see #7043) 7651 maxRows: 4, 7652 7653 // TODO rename to "widget" when switching to widget factory 7654 _widgetDatepicker: function() { 7655 return this.dpDiv; 7656 }, 7657 7658 /* Override the default settings for all instances of the date picker. 7659 * @param settings object - the new settings to use as defaults (anonymous object) 7660 * @return the manager object 7661 */ 7662 setDefaults: function(settings) { 7663 extendRemove(this._defaults, settings || {}); 7664 return this; 7665 }, 7666 7667 /* Attach the date picker to a jQuery selection. 7668 * @param target element - the target input field or division or span 7669 * @param settings object - the new settings to use for this date picker instance (anonymous) 7670 */ 7671 _attachDatepicker: function(target, settings) { 7672 var nodeName, inline, inst; 7673 nodeName = target.nodeName.toLowerCase(); 7674 inline = (nodeName === "div" || nodeName === "span"); 7675 if (!target.id) { 7676 this.uuid += 1; 7677 target.id = "dp" + this.uuid; 7678 } 7679 inst = this._newInst($(target), inline); 7680 inst.settings = $.extend({}, settings || {}); 7681 if (nodeName === "input") { 7682 this._connectDatepicker(target, inst); 7683 } else if (inline) { 7684 this._inlineDatepicker(target, inst); 7685 } 7686 }, 7687 7688 /* Create a new instance object. */ 7689 _newInst: function(target, inline) { 7690 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 7691 return {id: id, input: target, // associated target 7692 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7693 drawMonth: 0, drawYear: 0, // month being drawn 7694 inline: inline, // is datepicker inline or not 7695 dpDiv: (!inline ? this.dpDiv : // presentation div 7696 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7697 }, 7698 7699 /* Attach the date picker to an input field. */ 7700 _connectDatepicker: function(target, inst) { 7701 var input = $(target); 7702 inst.append = $([]); 7703 inst.trigger = $([]); 7704 if (input.hasClass(this.markerClassName)) { 7705 return; 7706 } 7707 this._attachments(input, inst); 7708 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7709 keypress(this._doKeyPress).keyup(this._doKeyUp); 7710 this._autoSize(inst); 7711 $.data(target, PROP_NAME, inst); 7712 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7713 if( inst.settings.disabled ) { 7714 this._disableDatepicker( target ); 7715 } 7716 }, 7717 7718 /* Make attachments based on settings. */ 7719 _attachments: function(input, inst) { 7720 var showOn, buttonText, buttonImage, 7721 appendText = this._get(inst, "appendText"), 7722 isRTL = this._get(inst, "isRTL"); 7723 7724 if (inst.append) {
vendor: 5,777 bytes, lines 7725-7880
7725 inst.append.remove(); 7726 } 7727 if (appendText) { 7728 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7729 input[isRTL ? "before" : "after"](inst.append); 7730 } 7731 7732 input.unbind("focus", this._showDatepicker); 7733 7734 if (inst.trigger) { 7735 inst.trigger.remove(); 7736 } 7737 7738 showOn = this._get(inst, "showOn"); 7739 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7740 input.focus(this._showDatepicker); 7741 } 7742 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7743 buttonText = this._get(inst, "buttonText"); 7744 buttonImage = this._get(inst, "buttonImage"); 7745 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7746 $("<img/>").addClass(this._triggerClass). 7747 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7748 $("<button type='button'></button>").addClass(this._triggerClass). 7749 html(!buttonImage ? buttonText : $("<img/>").attr( 7750 { src:buttonImage, alt:buttonText, title:buttonText }))); 7751 input[isRTL ? "before" : "after"](inst.trigger); 7752 inst.trigger.click(function() { 7753 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7754 $.datepicker._hideDatepicker(); 7755 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7756 $.datepicker._hideDatepicker(); 7757 $.datepicker._showDatepicker(input[0]); 7758 } else { 7759 $.datepicker._showDatepicker(input[0]); 7760 } 7761 return false; 7762 }); 7763 } 7764 }, 7765 7766 /* Apply the maximum length for the date format. */ 7767 _autoSize: function(inst) { 7768 if (this._get(inst, "autoSize") && !inst.inline) { 7769 var findMax, max, maxI, i, 7770 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7771 dateFormat = this._get(inst, "dateFormat"); 7772 7773 if (dateFormat.match(/[DM]/)) { 7774 findMax = function(names) { 7775 max = 0; 7776 maxI = 0; 7777 for (i = 0; i < names.length; i++) { 7778 if (names[i].length > max) { 7779 max = names[i].length; 7780 maxI = i; 7781 } 7782 } 7783 return maxI; 7784 }; 7785 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7786 "monthNames" : "monthNamesShort")))); 7787 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7788 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7789 } 7790 inst.input.attr("size", this._formatDate(inst, date).length); 7791 } 7792 }, 7793 7794 /* Attach an inline date picker to a div. */ 7795 _inlineDatepicker: function(target, inst) { 7796 var divSpan = $(target); 7797 if (divSpan.hasClass(this.markerClassName)) { 7798 return; 7799 } 7800 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7801 $.data(target, PROP_NAME, inst); 7802 this._setDate(inst, this._getDefaultDate(inst), true); 7803 this._updateDatepicker(inst); 7804 this._updateAlternate(inst); 7805 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7806 if( inst.settings.disabled ) { 7807 this._disableDatepicker( target ); 7808 } 7809 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7810 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7811 inst.dpDiv.css( "display", "block" ); 7812 }, 7813 7814 /* Pop-up the date picker in a "dialog" box. 7815 * @param input element - ignored 7816 * @param date string or Date - the initial date to display 7817 * @param onSelect function - the function to call when a date is selected 7818 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7819 * @param pos int[2] - coordinates for the dialog's position within the screen or 7820 * event - with x/y coordinates or 7821 * leave empty for default (screen centre) 7822 * @return the manager object 7823 */ 7824 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7825 var id, browserWidth, browserHeight, scrollX, scrollY, 7826 inst = this._dialogInst; // internal instance 7827 7828 if (!inst) { 7829 this.uuid += 1; 7830 id = "dp" + this.uuid; 7831 this._dialogInput = $("<input type='text' id='" + id + 7832 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7833 this._dialogInput.keydown(this._doKeyDown); 7834 $("body").append(this._dialogInput); 7835 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7836 inst.settings = {}; 7837 $.data(this._dialogInput[0], PROP_NAME, inst); 7838 } 7839 extendRemove(inst.settings, settings || {}); 7840 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7841 this._dialogInput.val(date); 7842 7843 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7844 if (!this._pos) { 7845 browserWidth = document.documentElement.clientWidth; 7846 browserHeight = document.documentElement.clientHeight; 7847 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7848 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7849 this._pos = // should use actual width/height below 7850 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7851 } 7852 7853 // move input on screen for focus, but hidden behind dialog 7854 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7855 inst.settings.onSelect = onSelect; 7856 this._inDialog = true; 7857 this.dpDiv.addClass(this._dialogClass); 7858 this._showDatepicker(this._dialogInput[0]); 7859 if ($.blockUI) { 7860 $.blockUI(this.dpDiv); 7861 } 7862 $.data(this._dialogInput[0], PROP_NAME, inst); 7863 return this; 7864 }, 7865 7866 /* Detach a datepicker from its control. 7867 * @param target element - the target input field or division or span 7868 */ 7869 _destroyDatepicker: function(target) { 7870 var nodeName, 7871 $target = $(target), 7872 inst = $.data(target, PROP_NAME); 7873 7874 if (!$target.hasClass(this.markerClassName)) { 7875 return; 7876 } 7877 7878 nodeName = target.nodeName.toLowerCase(); 7879 $.removeData(target, PROP_NAME); 7880 if (nodeName === "input") {
vendor: 4,434 bytes, lines 7881-8013
7881 inst.append.remove(); 7882 inst.trigger.remove(); 7883 $target.removeClass(this.markerClassName). 7884 unbind("focus", this._showDatepicker). 7885 unbind("keydown", this._doKeyDown). 7886 unbind("keypress", this._doKeyPress). 7887 unbind("keyup", this._doKeyUp); 7888 } else if (nodeName === "div" || nodeName === "span") { 7889 $target.removeClass(this.markerClassName).empty(); 7890 } 7891 }, 7892 7893 /* Enable the date picker to a jQuery selection. 7894 * @param target element - the target input field or division or span 7895 */ 7896 _enableDatepicker: function(target) { 7897 var nodeName, inline, 7898 $target = $(target), 7899 inst = $.data(target, PROP_NAME); 7900 7901 if (!$target.hasClass(this.markerClassName)) { 7902 return; 7903 } 7904 7905 nodeName = target.nodeName.toLowerCase(); 7906 if (nodeName === "input") { 7907 target.disabled = false; 7908 inst.trigger.filter("button"). 7909 each(function() { this.disabled = false; }).end(). 7910 filter("img").css({opacity: "1.0", cursor: ""}); 7911 } else if (nodeName === "div" || nodeName === "span") { 7912 inline = $target.children("." + this._inlineClass); 7913 inline.children().removeClass("ui-state-disabled"); 7914 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7915 prop("disabled", false); 7916 } 7917 this._disabledInputs = $.map(this._disabledInputs, 7918 function(value) { return (value === target ? null : value); }); // delete entry 7919 }, 7920 7921 /* Disable the date picker to a jQuery selection. 7922 * @param target element - the target input field or division or span 7923 */ 7924 _disableDatepicker: function(target) { 7925 var nodeName, inline, 7926 $target = $(target), 7927 inst = $.data(target, PROP_NAME); 7928 7929 if (!$target.hasClass(this.markerClassName)) { 7930 return; 7931 } 7932 7933 nodeName = target.nodeName.toLowerCase(); 7934 if (nodeName === "input") { 7935 target.disabled = true; 7936 inst.trigger.filter("button"). 7937 each(function() { this.disabled = true; }).end(). 7938 filter("img").css({opacity: "0.5", cursor: "default"}); 7939 } else if (nodeName === "div" || nodeName === "span") { 7940 inline = $target.children("." + this._inlineClass); 7941 inline.children().addClass("ui-state-disabled"); 7942 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7943 prop("disabled", true); 7944 } 7945 this._disabledInputs = $.map(this._disabledInputs, 7946 function(value) { return (value === target ? null : value); }); // delete entry 7947 this._disabledInputs[this._disabledInputs.length] = target; 7948 }, 7949 7950 /* Is the first field in a jQuery collection disabled as a datepicker? 7951 * @param target element - the target input field or division or span 7952 * @return boolean - true if disabled, false if enabled 7953 */ 7954 _isDisabledDatepicker: function(target) { 7955 if (!target) { 7956 return false; 7957 } 7958 for (var i = 0; i < this._disabledInputs.length; i++) { 7959 if (this._disabledInputs[i] === target) { 7960 return true; 7961 } 7962 } 7963 return false; 7964 }, 7965 7966 /* Retrieve the instance data for the target control. 7967 * @param target element - the target input field or division or span 7968 * @return object - the associated instance data 7969 * @throws error if a jQuery problem getting data 7970 */ 7971 _getInst: function(target) { 7972 try { 7973 return $.data(target, PROP_NAME); 7974 } 7975 catch (err) { 7976 throw "Missing instance data for this datepicker"; 7977 } 7978 }, 7979 7980 /* Update or retrieve the settings for a date picker attached to an input field or division. 7981 * @param target element - the target input field or division or span 7982 * @param name object - the new settings to update or 7983 * string - the name of the setting to change or retrieve, 7984 * when retrieving also "all" for all instance settings or 7985 * "defaults" for all global defaults 7986 * @param value any - the new value for the setting 7987 * (omit if above is an object or to retrieve a value) 7988 */ 7989 _optionDatepicker: function(target, name, value) { 7990 var settings, date, minDate, maxDate, 7991 inst = this._getInst(target); 7992 7993 if (arguments.length === 2 && typeof name === "string") { 7994 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 7995 (inst ? (name === "all" ? $.extend({}, inst.settings) : 7996 this._get(inst, name)) : null)); 7997 } 7998 7999 settings = name || {}; 8000 if (typeof name === "string") { 8001 settings = {}; 8002 settings[name] = value; 8003 } 8004 8005 if (inst) { 8006 if (this._curInst === inst) { 8007 this._hideDatepicker(); 8008 } 8009 8010 date = this._getDateDatepicker(target, true); 8011 minDate = this._getMinMaxDate(inst, "min"); 8012 maxDate = this._getMinMaxDate(inst, "max"); 8013
vendor: 7,816 bytes, lines 8013-8241
8013extendRemove(inst.settings, settings); 8014 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8015 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8016 inst.settings.minDate = this._formatDate(inst, minDate); 8017 } 8018 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8019 inst.settings.maxDate = this._formatDate(inst, maxDate); 8020 } 8021 if ( "disabled" in settings ) { 8022 if ( settings.disabled ) { 8023 this._disableDatepicker(target); 8024 } else { 8025 this._enableDatepicker(target); 8026 } 8027 } 8028 this._attachments($(target), inst); 8029 this._autoSize(inst); 8030 this._setDate(inst, date); 8031 this._updateAlternate(inst); 8032 this._updateDatepicker(inst); 8033 } 8034 }, 8035 8036 // change method deprecated 8037 _changeDatepicker: function(target, name, value) { 8038 this._optionDatepicker(target, name, value); 8039 }, 8040 8041 /* Redraw the date picker attached to an input field or division. 8042 * @param target element - the target input field or division or span 8043 */ 8044 _refreshDatepicker: function(target) { 8045 var inst = this._getInst(target); 8046 if (inst) { 8047 this._updateDatepicker(inst); 8048 } 8049 }, 8050 8051 /* Set the dates for a jQuery selection. 8052 * @param target element - the target input field or division or span 8053 * @param date Date - the new date 8054 */ 8055 _setDateDatepicker: function(target, date) { 8056 var inst = this._getInst(target); 8057 if (inst) { 8058 this._setDate(inst, date); 8059 this._updateDatepicker(inst); 8060 this._updateAlternate(inst); 8061 } 8062 }, 8063 8064 /* Get the date(s) for the first entry in a jQuery selection. 8065 * @param target element - the target input field or division or span 8066 * @param noDefault boolean - true if no default date is to be used 8067 * @return Date - the current date 8068 */ 8069 _getDateDatepicker: function(target, noDefault) { 8070 var inst = this._getInst(target); 8071 if (inst && !inst.inline) { 8072 this._setDateFromField(inst, noDefault); 8073 } 8074 return (inst ? this._getDate(inst) : null); 8075 }, 8076 8077 /* Handle keystrokes. */ 8078 _doKeyDown: function(event) { 8079 var onSelect, dateStr, sel, 8080 inst = $.datepicker._getInst(event.target), 8081 handled = true, 8082 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8083 8084 inst._keyEvent = true; 8085 if ($.datepicker._datepickerShowing) { 8086 switch (event.keyCode) { 8087 case 9: $.datepicker._hideDatepicker(); 8088 handled = false; 8089 break; // hide on tab out 8090 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8091 $.datepicker._currentClass + ")", inst.dpDiv); 8092 if (sel[0]) { 8093 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8094 } 8095 8096 onSelect = $.datepicker._get(inst, "onSelect"); 8097 if (onSelect) { 8098 dateStr = $.datepicker._formatDate(inst); 8099 8100 // trigger custom callback 8101 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8102 } else { 8103 $.datepicker._hideDatepicker(); 8104 } 8105 8106 return false; // don't submit the form 8107 case 27: $.datepicker._hideDatepicker(); 8108 break; // hide on escape 8109 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8110 -$.datepicker._get(inst, "stepBigMonths") : 8111 -$.datepicker._get(inst, "stepMonths")), "M"); 8112 break; // previous month/year on page up/+ ctrl 8113 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8114 +$.datepicker._get(inst, "stepBigMonths") : 8115 +$.datepicker._get(inst, "stepMonths")), "M"); 8116 break; // next month/year on page down/+ ctrl 8117 case 35: if (event.ctrlKey || event.metaKey) { 8118 $.datepicker._clearDate(event.target); 8119 } 8120 handled = event.ctrlKey || event.metaKey; 8121 break; // clear on ctrl or command +end 8122 case 36: if (event.ctrlKey || event.metaKey) { 8123 $.datepicker._gotoToday(event.target); 8124 } 8125 handled = event.ctrlKey || event.metaKey; 8126 break; // current on ctrl or command +home 8127 case 37: if (event.ctrlKey || event.metaKey) { 8128 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8129 } 8130 handled = event.ctrlKey || event.metaKey; 8131 // -1 day on ctrl or command +left 8132 if (event.originalEvent.altKey) { 8133 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8134 -$.datepicker._get(inst, "stepBigMonths") : 8135 -$.datepicker._get(inst, "stepMonths")), "M"); 8136 } 8137 // next month/year on alt +left on Mac 8138 break; 8139 case 38: if (event.ctrlKey || event.metaKey) { 8140 $.datepicker._adjustDate(event.target, -7, "D"); 8141 } 8142 handled = event.ctrlKey || event.metaKey; 8143 break; // -1 week on ctrl or command +up 8144 case 39: if (event.ctrlKey || event.metaKey) { 8145 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8146 } 8147 handled = event.ctrlKey || event.metaKey; 8148 // +1 day on ctrl or command +right 8149 if (event.originalEvent.altKey) { 8150 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8151 +$.datepicker._get(inst, "stepBigMonths") : 8152 +$.datepicker._get(inst, "stepMonths")), "M"); 8153 } 8154 // next month/year on alt +right 8155 break; 8156 case 40: if (event.ctrlKey || event.metaKey) { 8157 $.datepicker._adjustDate(event.target, +7, "D"); 8158 } 8159 handled = event.ctrlKey || event.metaKey; 8160 break; // +1 week on ctrl or command +down 8161 default: handled = false; 8162 } 8163 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8164 $.datepicker._showDatepicker(this); 8165 } else { 8166 handled = false; 8167 } 8168 8169 if (handled) { 8170 event.preventDefault(); 8171 event.stopPropagation(); 8172 } 8173 }, 8174 8175 /* Filter entered characters - based on date format. */ 8176 _doKeyPress: function(event) { 8177 var chars, chr, 8178 inst = $.datepicker._getInst(event.target); 8179 8180 if ($.datepicker._get(inst, "constrainInput")) { 8181 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8182 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8183 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8184 } 8185 }, 8186 8187 /* Synchronise manual entry and field/alternate field. */ 8188 _doKeyUp: function(event) { 8189 var date, 8190 inst = $.datepicker._getInst(event.target); 8191 8192 if (inst.input.val() !== inst.lastVal) { 8193 try { 8194 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8195 (inst.input ? inst.input.val() : null), 8196 $.datepicker._getFormatConfig(inst)); 8197 8198 if (date) { // only if valid 8199 $.datepicker._setDateFromField(inst); 8200 $.datepicker._updateAlternate(inst); 8201 $.datepicker._updateDatepicker(inst); 8202 } 8203 } 8204 catch (err) { 8205 } 8206 } 8207 return true; 8208 }, 8209 8210 /* Pop-up the date picker for a given input field. 8211 * If false returned from beforeShow event handler do not show. 8212 * @param input element - the input field attached to the date picker or 8213 * event - if triggered by focus 8214 */ 8215 _showDatepicker: function(input) { 8216 input = input.target || input; 8217 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8218 input = $("input", input.parentNode)[0]; 8219 } 8220 8221 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8222 return; 8223 } 8224 8225 var inst, beforeShow, beforeShowSettings, isFixed, 8226 offset, showAnim, duration; 8227 8228 inst = $.datepicker._getInst(input); 8229 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8230 $.datepicker._curInst.dpDiv.stop(true, true); 8231 if ( inst && $.datepicker._datepickerShowing ) { 8232 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8233 } 8234 } 8235 8236 beforeShow = $.datepicker._get(inst, "beforeShow"); 8237 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8238 if(beforeShowSettings === false){ 8239 return; 8240 } 8241
vendor: 5,662 bytes, lines 8241-8391
8241extendRemove(inst.settings, beforeShowSettings); 8242 8243 inst.lastVal = null; 8244 $.datepicker._lastInput = input; 8245 $.datepicker._setDateFromField(inst); 8246 8247 if ($.datepicker._inDialog) { // hide cursor 8248 input.value = ""; 8249 } 8250 if (!$.datepicker._pos) { // position below input 8251 $.datepicker._pos = $.datepicker._findPos(input); 8252 $.datepicker._pos[1] += input.offsetHeight; // add the height 8253 } 8254 8255 isFixed = false; 8256 $(input).parents().each(function() { 8257 isFixed |= $(this).css("position") === "fixed"; 8258 return !isFixed; 8259 }); 8260 8261 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8262 $.datepicker._pos = null; 8263 //to avoid flashes on Firefox 8264 inst.dpDiv.empty(); 8265 // determine sizing offscreen 8266 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8267 $.datepicker._updateDatepicker(inst); 8268 // fix width for dynamic number of date pickers 8269 // and adjust position before showing 8270 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8271 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8272 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8273 left: offset.left + "px", top: offset.top + "px"}); 8274 8275 if (!inst.inline) { 8276 showAnim = $.datepicker._get(inst, "showAnim"); 8277 duration = $.datepicker._get(inst, "duration"); 8278 inst.dpDiv.zIndex($(input).zIndex()+1); 8279 $.datepicker._datepickerShowing = true; 8280 8281 if ( $.effects && $.effects.effect[ showAnim ] ) { 8282 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8283 } else { 8284 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8285 } 8286 8287 if (inst.input.is(":visible") && !inst.input.is(":disabled")) { 8288 inst.input.focus(); 8289 } 8290 $.datepicker._curInst = inst; 8291 } 8292 }, 8293 8294 /* Generate the date picker content. */ 8295 _updateDatepicker: function(inst) { 8296 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8297 instActive = inst; // for delegate hover events 8298 inst.dpDiv.empty().append(this._generateHTML(inst)); 8299 this._attachHandlers(inst); 8300 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8301 8302 var origyearshtml, 8303 numMonths = this._getNumberOfMonths(inst), 8304 cols = numMonths[1], 8305 width = 17; 8306 8307 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8308 if (cols > 1) { 8309 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8310 } 8311 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8312 "Class"]("ui-datepicker-multi"); 8313 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8314 "Class"]("ui-datepicker-rtl"); 8315 8316 // #6694 - don't focus the input if it's already focused 8317 // this breaks the change event in IE 8318 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 8319 inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) { 8320 inst.input.focus(); 8321 } 8322 8323 // deffered render of the years select (to avoid flashes on Firefox) 8324 if( inst.yearshtml ){ 8325 origyearshtml = inst.yearshtml; 8326 setTimeout(function(){ 8327 //assure that inst.yearshtml didn't change. 8328 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8329 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8330 } 8331 origyearshtml = inst.yearshtml = null; 8332 }, 0); 8333 } 8334 }, 8335 8336 /* Retrieve the size of left and top borders for an element. 8337 * @param elem (jQuery object) the element of interest 8338 * @return (number[2]) the left and top borders 8339 */ 8340 _getBorders: function(elem) { 8341 var convert = function(value) { 8342 return {thin: 1, medium: 2, thick: 3}[value] || value; 8343 }; 8344 return [parseFloat(convert(elem.css("border-left-width"))), 8345 parseFloat(convert(elem.css("border-top-width")))]; 8346 }, 8347 8348 /* Check positioning to remain on screen. */ 8349 _checkOffset: function(inst, offset, isFixed) { 8350 var dpWidth = inst.dpDiv.outerWidth(), 8351 dpHeight = inst.dpDiv.outerHeight(), 8352 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8353 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8354 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8355 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8356 8357 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8358 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8359 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8360 8361 // now check if datepicker is showing outside window viewport - move to a better place if so. 8362 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8363 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8364 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8365 Math.abs(dpHeight + inputHeight) : 0); 8366 8367 return offset; 8368 }, 8369 8370 /* Find an object's position on the screen. */ 8371 _findPos: function(obj) { 8372 var position, 8373 inst = this._getInst(obj), 8374 isRTL = this._get(inst, "isRTL"); 8375 8376 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8377 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8378 } 8379 8380 position = $(obj).offset(); 8381 return [position.left, position.top]; 8382 }, 8383 8384 /* Hide the date picker from view. 8385 * @param input element - the input field attached to the date picker 8386 */ 8387 _hideDatepicker: function(input) { 8388 var showAnim, duration, postProcess, onClose, 8389 inst = this._curInst; 8390 8391 if (!inst || (input && inst !== $.data(input, PROP_NAME
vendor: 8,428 bytes, lines 8391-8647
8391))) { 8392 return; 8393 } 8394 8395 if (this._datepickerShowing) { 8396 showAnim = this._get(inst, "showAnim"); 8397 duration = this._get(inst, "duration"); 8398 postProcess = function() { 8399 $.datepicker._tidyDialog(inst); 8400 }; 8401 8402 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8403 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8404 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8405 } else { 8406 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8407 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8408 } 8409 8410 if (!showAnim) { 8411 postProcess(); 8412 } 8413 this._datepickerShowing = false; 8414 8415 onClose = this._get(inst, "onClose"); 8416 if (onClose) { 8417 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8418 } 8419 8420 this._lastInput = null; 8421 if (this._inDialog) { 8422 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8423 if ($.blockUI) { 8424 $.unblockUI(); 8425 $("body").append(this.dpDiv); 8426 } 8427 } 8428 this._inDialog = false; 8429 } 8430 }, 8431 8432 /* Tidy up after a dialog display. */ 8433 _tidyDialog: function(inst) { 8434 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8435 }, 8436 8437 /* Close date picker if clicked elsewhere. */ 8438 _checkExternalClick: function(event) { 8439 if (!$.datepicker._curInst) { 8440 return; 8441 } 8442 8443 var $target = $(event.target), 8444 inst = $.datepicker._getInst($target[0]); 8445 8446 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8447 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8448 !$target.hasClass($.datepicker.markerClassName) && 8449 !$target.closest("." + $.datepicker._triggerClass).length && 8450 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8451 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8452 $.datepicker._hideDatepicker(); 8453 } 8454 }, 8455 8456 /* Adjust one of the date sub-fields. */ 8457 _adjustDate: function(id, offset, period) { 8458 var target = $(id), 8459 inst = this._getInst(target[0]); 8460 8461 if (this._isDisabledDatepicker(target[0])) { 8462 return; 8463 } 8464 this._adjustInstDate(inst, offset + 8465 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8466 period); 8467 this._updateDatepicker(inst); 8468 }, 8469 8470 /* Action for current link. */ 8471 _gotoToday: function(id) { 8472 var date, 8473 target = $(id), 8474 inst = this._getInst(target[0]); 8475 8476 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8477 inst.selectedDay = inst.currentDay; 8478 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8479 inst.drawYear = inst.selectedYear = inst.currentYear; 8480 } else { 8481 date = new Date(); 8482 inst.selectedDay = date.getDate(); 8483 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8484 inst.drawYear = inst.selectedYear = date.getFullYear(); 8485 } 8486 this._notifyChange(inst); 8487 this._adjustDate(target); 8488 }, 8489 8490 /* Action for selecting a new month/year. */ 8491 _selectMonthYear: function(id, select, period) { 8492 var target = $(id), 8493 inst = this._getInst(target[0]); 8494 8495 inst["selected" + (period === "M" ? "Month" : "Year")] = 8496 inst["draw" + (period === "M" ? "Month" : "Year")] = 8497 parseInt(select.options[select.selectedIndex].value,10); 8498 8499 this._notifyChange(inst); 8500 this._adjustDate(target); 8501 }, 8502 8503 /* Action for selecting a day. */ 8504 _selectDay: function(id, month, year, td) { 8505 var inst, 8506 target = $(id); 8507 8508 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8509 return; 8510 } 8511 8512 inst = this._getInst(target[0]); 8513 inst.selectedDay = inst.currentDay = $("a", td).html(); 8514 inst.selectedMonth = inst.currentMonth = month; 8515 inst.selectedYear = inst.currentYear = year; 8516 this._selectDate(id, this._formatDate(inst, 8517 inst.currentDay, inst.currentMonth, inst.currentYear)); 8518 }, 8519 8520 /* Erase the input field and hide the date picker. */ 8521 _clearDate: function(id) { 8522 var target = $(id); 8523 this._selectDate(target, ""); 8524 }, 8525 8526 /* Update the input field with the selected date. */ 8527 _selectDate: function(id, dateStr) { 8528 var onSelect, 8529 target = $(id), 8530 inst = this._getInst(target[0]); 8531 8532 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8533 if (inst.input) { 8534 inst.input.val(dateStr); 8535 } 8536 this._updateAlternate(inst); 8537 8538 onSelect = this._get(inst, "onSelect"); 8539 if (onSelect) { 8540 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8541 } else if (inst.input) { 8542 inst.input.trigger("change"); // fire the change event 8543 } 8544 8545 if (inst.inline){ 8546 this._updateDatepicker(inst); 8547 } else { 8548 this._hideDatepicker(); 8549 this._lastInput = inst.input[0]; 8550 if (typeof(inst.input[0]) !== "object") { 8551 inst.input.focus(); // restore focus 8552 } 8553 this._lastInput = null; 8554 } 8555 }, 8556 8557 /* Update any alternate field to synchronise with the main field. */ 8558 _updateAlternate: function(inst) { 8559 var altFormat, date, dateStr, 8560 altField = this._get(inst, "altField"); 8561 8562 if (altField) { // update alternate field too 8563 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8564 date = this._getDate(inst); 8565 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8566 $(altField).each(function() { $(this).val(dateStr); }); 8567 } 8568 }, 8569 8570 /* Set as beforeShowDay function to prevent selection of weekends. 8571 * @param date Date - the date to customise 8572 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8573 */ 8574 noWeekends: function(date) { 8575 var day = date.getDay(); 8576 return [(day > 0 && day < 6), ""]; 8577 }, 8578 8579 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8580 * @param date Date - the date to get the week for 8581 * @return number - the number of the week within the year that contains this date 8582 */ 8583 iso8601Week: function(date) { 8584 var time, 8585 checkDate = new Date(date.getTime()); 8586 8587 // Find Thursday of this week starting on Monday 8588 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8589 8590 time = checkDate.getTime(); 8591 checkDate.setMonth(0); // Compare with Jan 1 8592 checkDate.setDate(1); 8593 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8594 }, 8595 8596 /* Parse a string value into a date object. 8597 * See formatDate below for the possible formats. 8598 * 8599 * @param format string - the expected format of the date 8600 * @param value string - the date in the above format 8601 * @param settings Object - attributes include: 8602 * shortYearCutoff number - the cutoff year for determining the century (optional) 8603 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8604 * dayNames string[7] - names of the days from Sunday (optional) 8605 * monthNamesShort string[12] - abbreviated names of the months (optional) 8606 * monthNames string[12] - names of the months (optional) 8607 * @return Date - the extracted date value or null if value is blank 8608 */ 8609 parseDate: function (format, value, settings) { 8610 if (format == null || value == null) { 8611 throw "Invalid arguments"; 8612 } 8613 8614 value = (typeof value === "object" ? value.toString() : value + ""); 8615 if (value === "") { 8616 return null; 8617 } 8618 8619 var iFormat, dim, extra, 8620 iValue = 0, 8621 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8622 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 8623 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8624 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8625 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8626 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8627 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8628 year = -1, 8629 month = -1, 8630 day = -1, 8631 doy = -1, 8632 literal = false, 8633 date, 8634 // Check whether a format character is doubled 8635 lookAhead = function(match) { 8636 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8637 if (matches) { 8638 iFormat++; 8639 } 8640 return matches; 8641 }, 8642 // Extract a number from the string value 8643 getNumber = function(match) { 8644 var isDoubled = lookAhead(match), 8645 size = (match === "@" ? 14 : (match === "!" ? 20 : 8646 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8647
8647digits = new RegExp("^\\d{1
vendor: 13,244 bytes, lines 8647-9092
8647," + size + "}"), 8648 num = value.substring(iValue).match(digits); 8649 if (!num) { 8650 throw "Missing number at position " + iValue; 8651 } 8652 iValue += num[0].length; 8653 return parseInt(num[0], 10); 8654 }, 8655 // Extract a name from the string value and convert to an index 8656 getName = function(match, shortNames, longNames) { 8657 var index = -1, 8658 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8659 return [ [k, v] ]; 8660 }).sort(function (a, b) { 8661 return -(a[1].length - b[1].length); 8662 }); 8663 8664 $.each(names, function (i, pair) { 8665 var name = pair[1]; 8666 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8667 index = pair[0]; 8668 iValue += name.length; 8669 return false; 8670 } 8671 }); 8672 if (index !== -1) { 8673 return index + 1; 8674 } else { 8675 throw "Unknown name at position " + iValue; 8676 } 8677 }, 8678 // Confirm that a literal character matches the string value 8679 checkLiteral = function() { 8680 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8681 throw "Unexpected literal at position " + iValue; 8682 } 8683 iValue++; 8684 }; 8685 8686 for (iFormat = 0; iFormat < format.length; iFormat++) { 8687 if (literal) { 8688 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8689 literal = false; 8690 } else { 8691 checkLiteral(); 8692 } 8693 } else { 8694 switch (format.charAt(iFormat)) { 8695 case "d": 8696 day = getNumber("d"); 8697 break; 8698 case "D": 8699 getName("D", dayNamesShort, dayNames); 8700 break; 8701 case "o": 8702 doy = getNumber("o"); 8703 break; 8704 case "m": 8705 month = getNumber("m"); 8706 break; 8707 case "M": 8708 month = getName("M", monthNamesShort, monthNames); 8709 break; 8710 case "y": 8711 year = getNumber("y"); 8712 break; 8713 case "@": 8714 date = new Date(getNumber("@")); 8715 year = date.getFullYear(); 8716 month = date.getMonth() + 1; 8717 day = date.getDate(); 8718 break; 8719 case "!": 8720 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8721 year = date.getFullYear(); 8722 month = date.getMonth() + 1; 8723 day = date.getDate(); 8724 break; 8725 case "'": 8726 if (lookAhead("'")){ 8727 checkLiteral(); 8728 } else { 8729 literal = true; 8730 } 8731 break; 8732 default: 8733 checkLiteral(); 8734 } 8735 } 8736 } 8737 8738 if (iValue < value.length){ 8739 extra = value.substr(iValue); 8740 if (!/^\s+/.test(extra)) { 8741 throw "Extra/unparsed characters found in date: " + extra; 8742 } 8743 } 8744 8745 if (year === -1) { 8746 year = new Date().getFullYear(); 8747 } else if (year < 100) { 8748 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8749 (year <= shortYearCutoff ? 0 : -100); 8750 } 8751 8752 if (doy > -1) { 8753 month = 1; 8754 day = doy; 8755 do { 8756 dim = this._getDaysInMonth(year, month - 1); 8757 if (day <= dim) { 8758 break; 8759 } 8760 month++; 8761 day -= dim; 8762 } while (true); 8763 } 8764 8765 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8766 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8767 throw "Invalid date"; // E.g. 31/02/00 8768 } 8769 return date; 8770 }, 8771 8772 /* Standard date formats. */ 8773 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8774 COOKIE: "D, dd M yy", 8775 ISO_8601: "yy-mm-dd", 8776 RFC_822: "D, d M y", 8777 RFC_850: "DD, dd-M-y", 8778 RFC_1036: "D, d M y", 8779 RFC_1123: "D, d M yy", 8780 RFC_2822: "D, d M yy", 8781 RSS: "D, d M y", // RFC 822 8782 TICKS: "!", 8783 TIMESTAMP: "@", 8784 W3C: "yy-mm-dd", // ISO 8601 8785 8786 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8787 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8788 8789 /* Format a date object into a string value. 8790 * The format can be combinations of the following: 8791 * d - day of month (no leading zero) 8792 * dd - day of month (two digit) 8793 * o - day of year (no leading zeros) 8794 * oo - day of year (three digit) 8795 * D - day name short 8796 * DD - day name long 8797 * m - month of year (no leading zero) 8798 * mm - month of year (two digit) 8799 * M - month name short 8800 * MM - month name long 8801 * y - year (two digit) 8802 * yy - year (four digit) 8803 * @ - Unix timestamp (ms since 01/01/1970) 8804 * ! - Windows ticks (100ns since 01/01/0001) 8805 * "..." - literal text 8806 * '' - single quote 8807 * 8808 * @param format string - the desired format of the date 8809 * @param date Date - the date value to format 8810 * @param settings Object - attributes include: 8811 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8812 * dayNames string[7] - names of the days from Sunday (optional) 8813 * monthNamesShort string[12] - abbreviated names of the months (optional) 8814 * monthNames string[12] - names of the months (optional) 8815 * @return string - the date in the above format 8816 */ 8817 formatDate: function (format, date, settings) { 8818 if (!date) { 8819 return ""; 8820 } 8821 8822 var iFormat, 8823 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8824 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8825 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8826 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8827 // Check whether a format character is doubled 8828 lookAhead = function(match) { 8829 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8830 if (matches) { 8831 iFormat++; 8832 } 8833 return matches; 8834 }, 8835 // Format a number, with leading zero if necessary 8836 formatNumber = function(match, value, len) { 8837 var num = "" + value; 8838 if (lookAhead(match)) { 8839 while (num.length < len) { 8840 num = "0" + num; 8841 } 8842 } 8843 return num; 8844 }, 8845 // Format a name, short or long as requested 8846 formatName = function(match, value, shortNames, longNames) { 8847 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8848 }, 8849 output = "", 8850 literal = false; 8851 8852 if (date) { 8853 for (iFormat = 0; iFormat < format.length; iFormat++) { 8854 if (literal) { 8855 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8856 literal = false; 8857 } else { 8858 output += format.charAt(iFormat); 8859 } 8860 } else { 8861 switch (format.charAt(iFormat)) { 8862 case "d": 8863 output += formatNumber("d", date.getDate(), 2); 8864 break; 8865 case "D": 8866 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8867 break; 8868 case "o": 8869 output += formatNumber("o", 8870 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8871 break; 8872 case "m": 8873 output += formatNumber("m", date.getMonth() + 1, 2); 8874 break; 8875 case "M": 8876 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8877 break; 8878 case "y": 8879 output += (lookAhead("y") ? date.getFullYear() : 8880 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8881 break; 8882 case "@": 8883 output += date.getTime(); 8884 break; 8885 case "!": 8886 output += date.getTime() * 10000 + this._ticksTo1970; 8887 break; 8888 case "'": 8889 if (lookAhead("'")) { 8890 output += "'"; 8891 } else { 8892 literal = true; 8893 } 8894 break; 8895 default: 8896 output += format.charAt(iFormat); 8897 } 8898 } 8899 } 8900 } 8901 return output; 8902 }, 8903 8904 /* Extract all possible characters from the date format. */ 8905 _possibleChars: function (format) { 8906 var iFormat, 8907 chars = "", 8908 literal = false, 8909 // Check whether a format character is doubled 8910 lookAhead = function(match) { 8911 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8912 if (matches) { 8913 iFormat++; 8914 } 8915 return matches; 8916 }; 8917 8918 for (iFormat = 0; iFormat < format.length; iFormat++) { 8919 if (literal) { 8920 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8921 literal = false; 8922 } else { 8923 chars += format.charAt(iFormat); 8924 } 8925 } else { 8926 switch (format.charAt(iFormat)) { 8927 case "d": case "m": case "y": case "@": 8928 chars += "0123456789"; 8929 break; 8930 case "D": case "M": 8931 return null; // Accept anything 8932 case "'": 8933 if (lookAhead("'")) { 8934 chars += "'"; 8935 } else { 8936 literal = true; 8937 } 8938 break; 8939 default: 8940 chars += format.charAt(iFormat); 8941 } 8942 } 8943 } 8944 return chars; 8945 }, 8946 8947 /* Get a setting value, defaulting if necessary. */ 8948 _get: function(inst, name) { 8949 return inst.settings[name] !== undefined ? 8950 inst.settings[name] : this._defaults[name]; 8951 }, 8952 8953 /* Parse existing date and initialise date picker. */ 8954 _setDateFromField: function(inst, noDefault) { 8955 if (inst.input.val() === inst.lastVal) { 8956 return; 8957 } 8958 8959 var dateFormat = this._get(inst, "dateFormat"), 8960 dates = inst.lastVal = inst.input ? inst.input.val() : null, 8961 defaultDate = this._getDefaultDate(inst), 8962 date = defaultDate, 8963 settings = this._getFormatConfig(inst); 8964 8965 try { 8966 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8967 } catch (event) { 8968 dates = (noDefault ? "" : dates); 8969 } 8970 inst.selectedDay = date.getDate(); 8971 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8972 inst.drawYear = inst.selectedYear = date.getFullYear(); 8973 inst.currentDay = (dates ? date.getDate() : 0); 8974 inst.currentMonth = (dates ? date.getMonth() : 0); 8975 inst.currentYear = (dates ? date.getFullYear() : 0); 8976 this._adjustInstDate(inst); 8977 }, 8978 8979 /* Retrieve the default date shown on opening. */ 8980 _getDefaultDate: function(inst) { 8981 return this._restrictMinMax(inst, 8982 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 8983 }, 8984 8985 /* A date may be specified as an exact value or a relative one. */ 8986 _determineDate: function(inst, date, defaultDate) { 8987 var offsetNumeric = function(offset) { 8988 var date = new Date(); 8989 date.setDate(date.getDate() + offset); 8990 return date; 8991 }, 8992 offsetString = function(offset) { 8993 try { 8994 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8995 offset, $.datepicker._getFormatConfig(inst)); 8996 } 8997 catch (e) { 8998 // Ignore 8999 } 9000 9001 var date = (offset.toLowerCase().match(/^c/) ? 9002 $.datepicker._getDate(inst) : null) || new Date(), 9003 year = date.getFullYear(), 9004 month = date.getMonth(), 9005 day = date.getDate(), 9006 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9007 matches = pattern.exec(offset); 9008 9009 while (matches) { 9010 switch (matches[2] || "d") { 9011 case "d" : case "D" : 9012 day += parseInt(matches[1],10); break; 9013 case "w" : case "W" : 9014 day += parseInt(matches[1],10) * 7; break; 9015 case "m" : case "M" : 9016 month += parseInt(matches[1],10); 9017 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9018 break; 9019 case "y": case "Y" : 9020 year += parseInt(matches[1],10); 9021 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9022 break; 9023 } 9024 matches = pattern.exec(offset); 9025 } 9026 return new Date(year, month, day); 9027 }, 9028 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9029 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9030 9031 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9032 if (newDate) { 9033 newDate.setHours(0); 9034 newDate.setMinutes(0); 9035 newDate.setSeconds(0); 9036 newDate.setMilliseconds(0); 9037 } 9038 return this._daylightSavingAdjust(newDate); 9039 }, 9040 9041 /* Handle switch to/from daylight saving. 9042 * Hours may be non-zero on daylight saving cut-over: 9043 * > 12 when midnight changeover, but then cannot generate 9044 * midnight datetime, so jump to 1AM, otherwise reset. 9045 * @param date (Date) the date to check 9046 * @return (Date) the corrected date 9047 */ 9048 _daylightSavingAdjust: function(date) { 9049 if (!date) { 9050 return null; 9051 } 9052 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9053 return date; 9054 }, 9055 9056 /* Set the date(s) directly. */ 9057 _setDate: function(inst, date, noChange) { 9058 var clear = !date, 9059 origMonth = inst.selectedMonth, 9060 origYear = inst.selectedYear, 9061 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9062 9063 inst.selectedDay = inst.currentDay = newDate.getDate(); 9064 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9065 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9066 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9067 this._notifyChange(inst); 9068 } 9069 this._adjustInstDate(inst); 9070 if (inst.input) { 9071 inst.input.val(clear ? "" : this._formatDate(inst)); 9072 } 9073 }, 9074 9075 /* Retrieve the date(s) directly. */ 9076 _getDate: function(inst) { 9077 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9078 this._daylightSavingAdjust(new Date( 9079 inst.currentYear, inst.currentMonth, inst.currentDay))); 9080 return startDate; 9081 }, 9082 9083 /* Attach the onxxx handlers. These are declared statically so 9084 * they work with static code transformers like Caja. 9085 */ 9086 _attachHandlers: function(inst) { 9087 var stepMonths = this._get(inst, "stepMonths"), 9088 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9089 inst.dpDiv.find("[data-handler]").map(function () { 9090 var handler = { 9091 prev: function () { 9092
vendor: 2,282 bytes, lines 9092-9141
9092window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M"); 9093 }, 9094 next: function () { 9095 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M"); 9096 }, 9097 hide: function () { 9098 window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker(); 9099 }, 9100 today: function () { 9101 window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id); 9102 }, 9103 selectDay: function () { 9104 window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9105 return false; 9106 }, 9107 selectMonth: function () { 9108 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M"); 9109 return false; 9110 }, 9111 selectYear: function () { 9112 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y"); 9113 return false; 9114 } 9115 }; 9116 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9117 }); 9118 }, 9119 9120 /* Generate the HTML for the current state of the date picker. */ 9121 _generateHTML: function(inst) { 9122 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 9123 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9124 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9125 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9126 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9127 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9128 tempDate = new Date(), 9129 today = this._daylightSavingAdjust( 9130 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9131 isRTL = this._get(inst, "isRTL"), 9132 showButtonPanel = this._get(inst, "showButtonPanel"), 9133 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9134 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9135 numMonths = this._getNumberOfMonths(inst), 9136 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9137 stepMonths = this._get(inst, "stepMonths"), 9138 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9139 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9140 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9141 minDate = this._getMinMaxDate(inst, "min"),
vendor: 5,135 bytes, lines 9142-9241
9142 maxDate = this._getMinMaxDate(inst, "max"), 9143 drawMonth = inst.drawMonth - showCurrentAtPos, 9144 drawYear = inst.drawYear; 9145 9146 if (drawMonth < 0) { 9147 drawMonth += 12; 9148 drawYear--; 9149 } 9150 if (maxDate) { 9151 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9152 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9153 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9154 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9155 drawMonth--; 9156 if (drawMonth < 0) { 9157 drawMonth = 11; 9158 drawYear--; 9159 } 9160 } 9161 } 9162 inst.drawMonth = drawMonth; 9163 inst.drawYear = drawYear; 9164 9165 prevText = this._get(inst, "prevText"); 9166 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9167 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9168 this._getFormatConfig(inst))); 9169 9170 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9171 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9172 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9173 (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>")); 9174 9175 nextText = this._get(inst, "nextText"); 9176 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9177 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9178 this._getFormatConfig(inst))); 9179 9180 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9181 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9182 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9183 (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>")); 9184 9185 currentText = this._get(inst, "currentText"); 9186 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9187 currentText = (!navigationAsDateFormat ? currentText : 9188 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9189 9190 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'>" + 9191 this._get(inst, "closeText") + "</button>" : ""); 9192 9193 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9194 (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'" + 9195 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9196 9197 firstDay = parseInt(this._get(inst, "firstDay"),10); 9198 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9199 9200 showWeek = this._get(inst, "showWeek"); 9201 dayNames = this._get(inst, "dayNames"); 9202 dayNamesMin = this._get(inst, "dayNamesMin"); 9203 monthNames = this._get(inst, "monthNames"); 9204 monthNamesShort = this._get(inst, "monthNamesShort"); 9205 beforeShowDay = this._get(inst, "beforeShowDay"); 9206 showOtherMonths = this._get(inst, "showOtherMonths"); 9207 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9208 defaultDate = this._getDefaultDate(inst); 9209 html = ""; 9210 dow; 9211 for (row = 0; row < numMonths[0]; row++) { 9212 group = ""; 9213 this.maxRows = 4; 9214 for (col = 0; col < numMonths[1]; col++) { 9215 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9216 cornerClass = " ui-corner-all"; 9217 calender = ""; 9218 if (isMultiMonth) { 9219 calender += "<div class='ui-datepicker-group"; 9220 if (numMonths[1] > 1) { 9221 switch (col) { 9222 case 0: calender += " ui-datepicker-group-first"; 9223 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9224 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9225 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9226 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9227 } 9228 } 9229 calender += "'>"; 9230 } 9231 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9232 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9233 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9234 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9235 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9236 "</div><table class='ui-datepicker-calendar'><thead>" + 9237 "<tr>"; 9238 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9239 for (dow = 0; dow < 7; dow++) { // days of the week 9240 day = (dow + firstDay) % 7; 9241 thead += "<th
vendor: 11,347 bytes, lines 9241-9495
9241" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9242 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9243 } 9244 calender += thead + "</tr></thead><tbody>"; 9245 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9246 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9247 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9248 } 9249 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9250 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9251 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9252 this.maxRows = numRows; 9253 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9254 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9255 calender += "<tr>"; 9256 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9257 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9258 for (dow = 0; dow < 7; dow++) { // create date picker days 9259 daySettings = (beforeShowDay ? 9260 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9261 otherMonth = (printDate.getMonth() !== drawMonth); 9262 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9263 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9264 tbody += "<td class='" + 9265 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9266 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9267 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9268 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9269 // or defaultDate is current printedDate and defaultDate is selectedDate 9270 " " + this._dayOverClass : "") + // highlight selected day 9271 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9272 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9273 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9274 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9275 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9276 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9277 (otherMonth && !showOtherMonths ? " " : // display for other months 9278 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9279 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9280 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9281 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9282 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9283 printDate.setDate(printDate.getDate() + 1); 9284 printDate = this._daylightSavingAdjust(printDate); 9285 } 9286 calender += tbody + "</tr>"; 9287 } 9288 drawMonth++; 9289 if (drawMonth > 11) { 9290 drawMonth = 0; 9291 drawYear++; 9292 } 9293 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9294 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9295 group += calender; 9296 } 9297 html += group; 9298 } 9299 html += buttonPanel; 9300 inst._keyEvent = false; 9301 return html; 9302 }, 9303 9304 /* Generate the month and year header. */ 9305 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9306 secondary, monthNames, monthNamesShort) { 9307 9308 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9309 changeMonth = this._get(inst, "changeMonth"), 9310 changeYear = this._get(inst, "changeYear"), 9311 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9312 html = "<div class='ui-datepicker-title'>", 9313 monthHtml = ""; 9314 9315 // month selection 9316 if (secondary || !changeMonth) { 9317 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9318 } else { 9319 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9320 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9321 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9322 for ( month = 0; month < 12; month++) { 9323 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9324 monthHtml += "<option value='" + month + "'" + 9325 (month === drawMonth ? " selected='selected'" : "") + 9326 ">" + monthNamesShort[month] + "</option>"; 9327 } 9328 } 9329 monthHtml += "</select>"; 9330 } 9331 9332 if (!showMonthAfterYear) { 9333 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9334 } 9335 9336 // year selection 9337 if ( !inst.yearshtml ) { 9338 inst.yearshtml = ""; 9339 if (secondary || !changeYear) { 9340 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9341 } else { 9342 // determine range of years to display 9343 years = this._get(inst, "yearRange").split(":"); 9344 thisYear = new Date().getFullYear(); 9345 determineYear = function(value) { 9346 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9347 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9348 parseInt(value, 10))); 9349 return (isNaN(year) ? thisYear : year); 9350 }; 9351 year = determineYear(years[0]); 9352 endYear = Math.max(year, determineYear(years[1] || "")); 9353 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9354 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9355 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9356 for (; year <= endYear; year++) { 9357 inst.yearshtml += "<option value='" + year + "'" + 9358 (year === drawYear ? " selected='selected'" : "") + 9359 ">" + year + "</option>"; 9360 } 9361 inst.yearshtml += "</select>"; 9362 9363 html += inst.yearshtml; 9364 inst.yearshtml = null; 9365 } 9366 } 9367 9368 html += this._get(inst, "yearSuffix"); 9369 if (showMonthAfterYear) { 9370 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9371 } 9372 html += "</div>"; // Close datepicker_header 9373 return html; 9374 }, 9375 9376 /* Adjust one of the date sub-fields. */ 9377 _adjustInstDate: function(inst, offset, period) { 9378 var year = inst.drawYear + (period === "Y" ? offset : 0), 9379 month = inst.drawMonth + (period === "M" ? offset : 0), 9380 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9381 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9382 9383 inst.selectedDay = date.getDate(); 9384 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9385 inst.drawYear = inst.selectedYear = date.getFullYear(); 9386 if (period === "M" || period === "Y") { 9387 this._notifyChange(inst); 9388 } 9389 }, 9390 9391 /* Ensure a date is within any min/max bounds. */ 9392 _restrictMinMax: function(inst, date) { 9393 var minDate = this._getMinMaxDate(inst, "min"), 9394 maxDate = this._getMinMaxDate(inst, "max"), 9395 newDate = (minDate && date < minDate ? minDate : date); 9396 return (maxDate && newDate > maxDate ? maxDate : newDate); 9397 }, 9398 9399 /* Notify change of month/year. */ 9400 _notifyChange: function(inst) { 9401 var onChange = this._get(inst, "onChangeMonthYear"); 9402 if (onChange) { 9403 onChange.apply((inst.input ? inst.input[0] : null), 9404 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9405 } 9406 }, 9407 9408 /* Determine the number of months to show. */ 9409 _getNumberOfMonths: function(inst) { 9410 var numMonths = this._get(inst, "numberOfMonths"); 9411 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9412 }, 9413 9414 /* Determine the current maximum date - ensure no time components are set. */ 9415 _getMinMaxDate: function(inst, minMax) { 9416 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9417 }, 9418 9419 /* Find the number of days in a given month. */ 9420 _getDaysInMonth: function(year, month) { 9421 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9422 }, 9423 9424 /* Find the day of the week of the first of a month. */ 9425 _getFirstDayOfMonth: function(year, month) { 9426 return new Date(year, month, 1).getDay(); 9427 }, 9428 9429 /* Determines if we should allow a "next/prev" month display change. */ 9430 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9431 var numMonths = this._getNumberOfMonths(inst), 9432 date = this._daylightSavingAdjust(new Date(curYear, 9433 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9434 9435 if (offset < 0) { 9436 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9437 } 9438 return this._isInRange(inst, date); 9439 }, 9440 9441 /* Is the given date in the accepted range? */ 9442 _isInRange: function(inst, date) { 9443 var yearSplit, currentYear, 9444 minDate = this._getMinMaxDate(inst, "min"), 9445 maxDate = this._getMinMaxDate(inst, "max"), 9446 minYear = null, 9447 maxYear = null, 9448 years = this._get(inst, "yearRange"); 9449 if (years){ 9450 yearSplit = years.split(":"); 9451 currentYear = new Date().getFullYear(); 9452 minYear = parseInt(yearSplit[0], 10); 9453 maxYear = parseInt(yearSplit[1], 10); 9454 if ( yearSplit[0].match(/[+\-].*/) ) { 9455 minYear += currentYear; 9456 } 9457 if ( yearSplit[1].match(/[+\-].*/) ) { 9458 maxYear += currentYear; 9459 } 9460 } 9461 9462 return ((!minDate || date.getTime() >= minDate.getTime()) && 9463 (!maxDate || date.getTime() <= maxDate.getTime()) && 9464 (!minYear || date.getFullYear() >= minYear) && 9465 (!maxYear || date.getFullYear() <= maxYear)); 9466 }, 9467 9468 /* Provide the configuration settings for formatting/parsing. */ 9469 _getFormatConfig: function(inst) { 9470 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9471 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9472 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9473 return {shortYearCutoff: shortYearCutoff, 9474 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9475 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9476 }, 9477 9478 /* Format the given date for display. */ 9479 _formatDate: function(inst, day, month, year) { 9480 if (!day) { 9481 inst.currentDay = inst.selectedDay; 9482 inst.currentMonth = inst.selectedMonth; 9483 inst.currentYear = inst.selectedYear; 9484 } 9485 var date = (day ? (typeof day === "object" ? day : 9486 this._daylightSavingAdjust(new Date(year, month, day))) : 9487 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9488 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9489 } 9490}); 9491 9492/* 9493 * Bind hover events for datepicker elements. 9494 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9495 * Global
vendor: 143,406 bytes, lines 9495-14936
9495instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9496 */ 9497function bindHover(dpDiv) { 9498 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9499 return dpDiv.delegate(selector, "mouseout", function() { 9500 $(this).removeClass("ui-state-hover"); 9501 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9502 $(this).removeClass("ui-datepicker-prev-hover"); 9503 } 9504 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9505 $(this).removeClass("ui-datepicker-next-hover"); 9506 } 9507 }) 9508 .delegate(selector, "mouseover", function(){ 9509 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9510 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9511 $(this).addClass("ui-state-hover"); 9512 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9513 $(this).addClass("ui-datepicker-prev-hover"); 9514 } 9515 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9516 $(this).addClass("ui-datepicker-next-hover"); 9517 } 9518 } 9519 }); 9520} 9521 9522/* jQuery extend now ignores nulls! */ 9523function extendRemove(target, props) { 9524 $.extend(target, props); 9525 for (var name in props) { 9526 if (props[name] == null) { 9527 target[name] = props[name]; 9528 } 9529 } 9530 return target; 9531} 9532 9533/* Invoke the datepicker functionality. 9534 @param options string - a command, optionally followed by additional parameters or 9535 Object - settings for attaching new datepicker functionality 9536 @return jQuery object */ 9537$.fn.datepicker = function(options){ 9538 9539 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9540 if ( !this.length ) { 9541 return this; 9542 } 9543 9544 /* Initialise the date picker. */ 9545 if (!$.datepicker.initialized) { 9546 $(document).mousedown($.datepicker._checkExternalClick); 9547 $.datepicker.initialized = true; 9548 } 9549 9550 /* Append datepicker main container to body if not exist. */ 9551 if ($("#"+$.datepicker._mainDivId).length === 0) { 9552 $("body").append($.datepicker.dpDiv); 9553 } 9554 9555 var otherArgs = Array.prototype.slice.call(arguments, 1); 9556 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9557 return $.datepicker["_" + options + "Datepicker"]. 9558 apply($.datepicker, [this[0]].concat(otherArgs)); 9559 } 9560 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9561 return $.datepicker["_" + options + "Datepicker"]. 9562 apply($.datepicker, [this[0]].concat(otherArgs)); 9563 } 9564 return this.each(function() { 9565 typeof options === "string" ? 9566 $.datepicker["_" + options + "Datepicker"]. 9567 apply($.datepicker, [this].concat(otherArgs)) : 9568 $.datepicker._attachDatepicker(this, options); 9569 }); 9570}; 9571 9572$.datepicker = new Datepicker(); // singleton instance 9573$.datepicker.initialized = false; 9574$.datepicker.uuid = new Date().getTime(); 9575$.datepicker.version = "1.10.1"; 9576 9577// Workaround for #4055 9578// Add another global to avoid noConflict issues with inline event handlers 9579window["DP_jQuery_" + dpuuid] = $; 9580 9581})(jQuery); 9582 9583(function( $, undefined ) { 9584 9585var sizeRelatedOptions = { 9586 buttons: true, 9587 height: true, 9588 maxHeight: true, 9589 maxWidth: true, 9590 minHeight: true, 9591 minWidth: true, 9592 width: true 9593 }, 9594 resizableRelatedOptions = { 9595 maxHeight: true, 9596 maxWidth: true, 9597 minHeight: true, 9598 minWidth: true 9599 }; 9600 9601$.widget( "ui.dialog", { 9602 version: "1.10.1", 9603 options: { 9604 appendTo: "body", 9605 autoOpen: true, 9606 buttons: [], 9607 closeOnEscape: true, 9608 closeText: "close", 9609 dialogClass: "", 9610 draggable: true, 9611 hide: null, 9612 height: "auto", 9613 maxHeight: null, 9614 maxWidth: null, 9615 minHeight: 150, 9616 minWidth: 150, 9617 modal: false, 9618 position: { 9619 my: "center", 9620 at: "center", 9621 of: window, 9622 collision: "fit", 9623 // Ensure the titlebar is always visible 9624 using: function( pos ) { 9625 var topOffset = $( this ).css( pos ).offset().top; 9626 if ( topOffset < 0 ) { 9627 $( this ).css( "top", pos.top - topOffset ); 9628 } 9629 } 9630 }, 9631 resizable: true, 9632 show: null, 9633 title: null, 9634 width: 300, 9635 9636 // callbacks 9637 beforeClose: null, 9638 close: null, 9639 drag: null, 9640 dragStart: null, 9641 dragStop: null, 9642 focus: null, 9643 open: null, 9644 resize: null, 9645 resizeStart: null, 9646 resizeStop: null 9647 }, 9648 9649 _create: function() { 9650 this.originalCss = { 9651 display: this.element[0].style.display, 9652 width: this.element[0].style.width, 9653 minHeight: this.element[0].style.minHeight, 9654 maxHeight: this.element[0].style.maxHeight, 9655 height: this.element[0].style.height 9656 }; 9657 this.originalPosition = { 9658 parent: this.element.parent(), 9659 index: this.element.parent().children().index( this.element ) 9660 }; 9661 this.originalTitle = this.element.attr("title"); 9662 this.options.title = this.options.title || this.originalTitle; 9663 9664 this._createWrapper(); 9665 9666 this.element 9667 .show() 9668 .removeAttr("title") 9669 .addClass("ui-dialog-content ui-widget-content") 9670 .appendTo( this.uiDialog ); 9671 9672 this._createTitlebar(); 9673 this._createButtonPane(); 9674 9675 if ( this.options.draggable && $.fn.draggable ) { 9676 this._makeDraggable(); 9677 } 9678 if ( this.options.resizable && $.fn.resizable ) { 9679 this._makeResizable(); 9680 } 9681 9682 this._isOpen = false; 9683 }, 9684 9685 _init: function() { 9686 if ( this.options.autoOpen ) { 9687 this.open(); 9688 } 9689 }, 9690 9691 _appendTo: function() { 9692 var element = this.options.appendTo; 9693 if ( element && (element.jquery || element.nodeType) ) { 9694 return $( element ); 9695 } 9696 return this.document.find( element || "body" ).eq( 0 ); 9697 }, 9698 9699 _destroy: function() { 9700 var next, 9701 originalPosition = this.originalPosition; 9702 9703 this._destroyOverlay(); 9704 9705 this.element 9706 .removeUniqueId() 9707 .removeClass("ui-dialog-content ui-widget-content") 9708 .css( this.originalCss ) 9709 // Without detaching first, the following becomes really slow 9710 .detach(); 9711 9712 this.uiDialog.stop( true, true ).remove(); 9713 9714 if ( this.originalTitle ) { 9715 this.element.attr( "title", this.originalTitle ); 9716 } 9717 9718 next = originalPosition.parent.children().eq( originalPosition.index ); 9719 // Don't try to place the dialog next to itself (#8613) 9720 if ( next.length && next[0] !== this.element[0] ) { 9721 next.before( this.element ); 9722 } else { 9723 originalPosition.parent.append( this.element ); 9724 } 9725 }, 9726 9727 widget: function() { 9728 return this.uiDialog; 9729 }, 9730 9731 disable: $.noop, 9732 enable: $.noop, 9733 9734 close: function( event ) { 9735 var that = this; 9736 9737 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9738 return; 9739 } 9740 9741 this._isOpen = false; 9742 this._destroyOverlay(); 9743 9744 if ( !this.opener.filter(":focusable").focus().length ) { 9745 // Hiding a focused element doesn't trigger blur in WebKit 9746 // so in case we have nothing to focus on, explicitly blur the active element 9747 // https://bugs.webkit.org/show_bug.cgi?id=47182 9748 $( this.document[0].activeElement ).blur(); 9749 } 9750 9751 this._hide( this.uiDialog, this.options.hide, function() { 9752 that._trigger( "close", event ); 9753 }); 9754 }, 9755 9756 isOpen: function() { 9757 return this._isOpen; 9758 }, 9759 9760 moveToTop: function() { 9761 this._moveToTop(); 9762 }, 9763 9764 _moveToTop: function( event, silent ) { 9765 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9766 if ( moved && !silent ) { 9767 this._trigger( "focus", event ); 9768 } 9769 return moved; 9770 }, 9771 9772 open: function() { 9773 var that = this; 9774 if ( this._isOpen ) { 9775 if ( this._moveToTop() ) { 9776 this._focusTabbable(); 9777 } 9778 return; 9779 } 9780 9781 this._isOpen = true; 9782 this.opener = $( this.document[0].activeElement ); 9783 9784 this._size(); 9785 this._position(); 9786 this._createOverlay(); 9787 this._moveToTop( null, true ); 9788 this._show( this.uiDialog, this.options.show, function() { 9789 that._focusTabbable(); 9790 that._trigger("focus"); 9791 }); 9792 9793 this._trigger("open"); 9794 }, 9795 9796 _focusTabbable: function() { 9797 // Set focus to the first match: 9798 // 1. First element inside the dialog matching [autofocus] 9799 // 2. Tabbable element inside the content element 9800 // 3. Tabbable element inside the buttonpane 9801 // 4. The close button 9802 // 5. The dialog itself 9803 var hasFocus = this.element.find("[autofocus]"); 9804 if ( !hasFocus.length ) { 9805 hasFocus = this.element.find(":tabbable"); 9806 } 9807 if ( !hasFocus.length ) { 9808 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9809 } 9810 if ( !hasFocus.length ) { 9811 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9812 } 9813 if ( !hasFocus.length ) { 9814 hasFocus = this.uiDialog; 9815 } 9816 hasFocus.eq( 0 ).focus(); 9817 }, 9818 9819 _keepFocus: function( event ) { 9820 function checkFocus() { 9821 var activeElement = this.document[0].activeElement, 9822 isActive = this.uiDialog[0] === activeElement || 9823 $.contains( this.uiDialog[0], activeElement ); 9824 if ( !isActive ) { 9825 this._focusTabbable(); 9826 } 9827 } 9828 event.preventDefault(); 9829 checkFocus.call( this ); 9830 // support: IE 9831 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9832 // so we check again later 9833 this._delay( checkFocus ); 9834 }, 9835 9836 _createWrapper: function() { 9837 this.uiDialog = $("<div>") 9838 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9839 this.options.dialogClass ) 9840 .hide() 9841 .attr({ 9842 // Setting tabIndex makes the div focusable 9843 tabIndex: -1, 9844 role: "dialog" 9845 }) 9846 .appendTo( this._appendTo() ); 9847 9848 this._on( this.uiDialog, { 9849 keydown: function( event ) { 9850 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9851 event.keyCode === $.ui.keyCode.ESCAPE ) { 9852 event.preventDefault(); 9853 this.close( event ); 9854 return; 9855 } 9856 9857 // prevent tabbing out of dialogs 9858 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9859 return; 9860 } 9861 var tabbables = this.uiDialog.find(":tabbable"), 9862 first = tabbables.filter(":first"), 9863 last = tabbables.filter(":last"); 9864 9865 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9866 first.focus( 1 ); 9867 event.preventDefault(); 9868 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9869 last.focus( 1 ); 9870 event.preventDefault(); 9871 } 9872 }, 9873 mousedown: function( event ) { 9874 if ( this._moveToTop( event ) ) { 9875 this._focusTabbable(); 9876 } 9877 } 9878 }); 9879 9880 // We assume that any existing aria-describedby attribute means 9881 // that the dialog content is marked up properly 9882 // otherwise we brute force the content as the description 9883 if ( !this.element.find("[aria-describedby]").length ) { 9884 this.uiDialog.attr({ 9885 "aria-describedby": this.element.uniqueId().attr("id") 9886 }); 9887 } 9888 }, 9889 9890 _createTitlebar: function() { 9891 var uiDialogTitle; 9892 9893 this.uiDialogTitlebar = $("<div>") 9894 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9895 .prependTo( this.uiDialog ); 9896 this._on( this.uiDialogTitlebar, { 9897 mousedown: function( event ) { 9898 // Don't prevent click on close button (#8838) 9899 // Focusing a dialog that is partially scrolled out of view 9900 // causes the browser to scroll it into view, preventing the click event 9901 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9902 // Dialog isn't getting focus when dragging (#8063) 9903 this.uiDialog.focus(); 9904 } 9905 } 9906 }); 9907 9908 this.uiDialogTitlebarClose = $("<button></button>") 9909 .button({ 9910 label: this.options.closeText, 9911 icons: { 9912 primary: "ui-icon-closethick" 9913 }, 9914 text: false 9915 }) 9916 .addClass("ui-dialog-titlebar-close") 9917 .appendTo( this.uiDialogTitlebar ); 9918 this._on( this.uiDialogTitlebarClose, { 9919 click: function( event ) { 9920 event.preventDefault(); 9921 this.close( event ); 9922 } 9923 }); 9924 9925 uiDialogTitle = $("<span>") 9926 .uniqueId() 9927 .addClass("ui-dialog-title") 9928 .prependTo( this.uiDialogTitlebar ); 9929 this._title( uiDialogTitle ); 9930 9931 this.uiDialog.attr({ 9932 "aria-labelledby": uiDialogTitle.attr("id") 9933 }); 9934 }, 9935 9936 _title: function( title ) { 9937 if ( !this.options.title ) { 9938 title.html(" "); 9939 } 9940 title.text( this.options.title ); 9941 }, 9942 9943 _createButtonPane: function() { 9944 this.uiDialogButtonPane = $("<div>") 9945 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9946 9947 this.uiButtonSet = $("<div>") 9948 .addClass("ui-dialog-buttonset") 9949 .appendTo( this.uiDialogButtonPane ); 9950 9951 this._createButtons(); 9952 }, 9953 9954 _createButtons: function() { 9955 var that = this, 9956 buttons = this.options.buttons; 9957 9958 // if we already have a button pane, remove it 9959 this.uiDialogButtonPane.remove(); 9960 this.uiButtonSet.empty(); 9961 9962 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 9963 this.uiDialog.removeClass("ui-dialog-buttons"); 9964 return; 9965 } 9966 9967 $.each( buttons, function( name, props ) { 9968 var click, buttonOptions; 9969 props = $.isFunction( props ) ? 9970 { click: props, text: name } : 9971 props; 9972 // Default to a non-submitting button 9973 props = $.extend( { type: "button" }, props ); 9974 // Change the context for the click callback to be the main element 9975 click = props.click; 9976 props.click = function() { 9977 click.apply( that.element[0], arguments ); 9978 }; 9979 buttonOptions = { 9980 icons: props.icons, 9981 text: props.showText 9982 }; 9983 delete props.icons; 9984 delete props.showText; 9985 $( "<button></button>", props ) 9986 .button( buttonOptions ) 9987 .appendTo( that.uiButtonSet ); 9988 }); 9989 this.uiDialog.addClass("ui-dialog-buttons"); 9990 this.uiDialogButtonPane.appendTo( this.uiDialog ); 9991 }, 9992 9993 _makeDraggable: function() { 9994 var that = this, 9995 options = this.options; 9996 9997 function filteredUi( ui ) { 9998 return { 9999 position: ui.position, 10000 offset: ui.offset 10001 }; 10002 } 10003 10004 this.uiDialog.draggable({ 10005 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10006 handle: ".ui-dialog-titlebar", 10007 containment: "document", 10008 start: function( event, ui ) { 10009 $( this ).addClass("ui-dialog-dragging"); 10010 that._blockFrames(); 10011 that._trigger( "dragStart", event, filteredUi( ui ) ); 10012 }, 10013 drag: function( event, ui ) { 10014 that._trigger( "drag", event, filteredUi( ui ) ); 10015 }, 10016 stop: function( event, ui ) { 10017 options.position = [ 10018 ui.position.left - that.document.scrollLeft(), 10019 ui.position.top - that.document.scrollTop() 10020 ]; 10021 $( this ).removeClass("ui-dialog-dragging"); 10022 that._unblockFrames(); 10023 that._trigger( "dragStop", event, filteredUi( ui ) ); 10024 } 10025 }); 10026 }, 10027 10028 _makeResizable: function() { 10029 var that = this, 10030 options = this.options, 10031 handles = options.resizable, 10032 // .ui-resizable has position: relative defined in the stylesheet 10033 // but dialogs have to use absolute or fixed positioning 10034 position = this.uiDialog.css("position"), 10035 resizeHandles = typeof handles === "string" ? 10036 handles : 10037 "n,e,s,w,se,sw,ne,nw"; 10038 10039 function filteredUi( ui ) { 10040 return { 10041 originalPosition: ui.originalPosition, 10042 originalSize: ui.originalSize, 10043 position: ui.position, 10044 size: ui.size 10045 }; 10046 } 10047 10048 this.uiDialog.resizable({ 10049 cancel: ".ui-dialog-content", 10050 containment: "document", 10051 alsoResize: this.element, 10052 maxWidth: options.maxWidth, 10053 maxHeight: options.maxHeight, 10054 minWidth: options.minWidth, 10055 minHeight: this._minHeight(), 10056 handles: resizeHandles, 10057 start: function( event, ui ) { 10058 $( this ).addClass("ui-dialog-resizing"); 10059 that._blockFrames(); 10060 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10061 }, 10062 resize: function( event, ui ) { 10063 that._trigger( "resize", event, filteredUi( ui ) ); 10064 }, 10065 stop: function( event, ui ) { 10066 options.height = $( this ).height(); 10067 options.width = $( this ).width(); 10068 $( this ).removeClass("ui-dialog-resizing"); 10069 that._unblockFrames(); 10070 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10071 } 10072 }) 10073 .css( "position", position ); 10074 }, 10075 10076 _minHeight: function() { 10077 var options = this.options; 10078 10079 return options.height === "auto" ? 10080 options.minHeight : 10081 Math.min( options.minHeight, options.height ); 10082 }, 10083 10084 _position: function() { 10085 // Need to show the dialog to get the actual offset in the position plugin 10086 var isVisible = this.uiDialog.is(":visible"); 10087 if ( !isVisible ) { 10088 this.uiDialog.show(); 10089 } 10090 this.uiDialog.position( this.options.position ); 10091 if ( !isVisible ) { 10092 this.uiDialog.hide(); 10093 } 10094 }, 10095 10096 _setOptions: function( options ) { 10097 var that = this, 10098 resize = false, 10099 resizableOptions = {}; 10100 10101 $.each( options, function( key, value ) { 10102 that._setOption( key, value ); 10103 10104 if ( key in sizeRelatedOptions ) { 10105 resize = true; 10106 } 10107 if ( key in resizableRelatedOptions ) { 10108 resizableOptions[ key ] = value; 10109 } 10110 }); 10111 10112 if ( resize ) { 10113 this._size(); 10114 this._position(); 10115 } 10116 if ( this.uiDialog.is(":data(ui-resizable)") ) { 10117 this.uiDialog.resizable( "option", resizableOptions ); 10118 } 10119 }, 10120 10121 _setOption: function( key, value ) { 10122 /*jshint maxcomplexity:15*/ 10123 var isDraggable, isResizable, 10124 uiDialog = this.uiDialog; 10125 10126 if ( key === "dialogClass" ) { 10127 uiDialog 10128 .removeClass( this.options.dialogClass ) 10129 .addClass( value ); 10130 } 10131 10132 if ( key === "disabled" ) { 10133 return; 10134 } 10135 10136 this._super( key, value ); 10137 10138 if ( key === "appendTo" ) { 10139 this.uiDialog.appendTo( this._appendTo() ); 10140 } 10141 10142 if ( key === "buttons" ) { 10143 this._createButtons(); 10144 } 10145 10146 if ( key === "closeText" ) { 10147 this.uiDialogTitlebarClose.button({ 10148 // Ensure that we always pass a string 10149 label: "" + value 10150 }); 10151 } 10152 10153 if ( key === "draggable" ) { 10154 isDraggable = uiDialog.is(":data(ui-draggable)"); 10155 if ( isDraggable && !value ) { 10156 uiDialog.draggable("destroy"); 10157 } 10158 10159 if ( !isDraggable && value ) { 10160 this._makeDraggable(); 10161 } 10162 } 10163 10164 if ( key === "position" ) { 10165 this._position(); 10166 } 10167 10168 if ( key === "resizable" ) { 10169 // currently resizable, becoming non-resizable 10170 isResizable = uiDialog.is(":data(ui-resizable)"); 10171 if ( isResizable && !value ) { 10172 uiDialog.resizable("destroy"); 10173 } 10174 10175 // currently resizable, changing handles 10176 if ( isResizable && typeof value === "string" ) { 10177 uiDialog.resizable( "option", "handles", value ); 10178 } 10179 10180 // currently non-resizable, becoming resizable 10181 if ( !isResizable && value !== false ) { 10182 this._makeResizable(); 10183 } 10184 } 10185 10186 if ( key === "title" ) { 10187 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 10188 } 10189 }, 10190 10191 _size: function() { 10192 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10193 // divs will both have width and height set, so we need to reset them 10194 var nonContentHeight, minContentHeight, maxContentHeight, 10195 options = this.options; 10196 10197 // Reset content sizing 10198 this.element.show().css({ 10199 width: "auto", 10200 minHeight: 0, 10201 maxHeight: "none", 10202 height: 0 10203 }); 10204 10205 if ( options.minWidth > options.width ) { 10206 options.width = options.minWidth; 10207 } 10208 10209 // reset wrapper sizing 10210 // determine the height of all the non-content elements 10211 nonContentHeight = this.uiDialog.css({ 10212 height: "auto", 10213 width: options.width 10214 }) 10215 .outerHeight(); 10216 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10217 maxContentHeight = typeof options.maxHeight === "number" ? 10218 Math.max( 0, options.maxHeight - nonContentHeight ) : 10219 "none"; 10220 10221 if ( options.height === "auto" ) { 10222 this.element.css({ 10223 minHeight: minContentHeight, 10224 maxHeight: maxContentHeight, 10225 height: "auto" 10226 }); 10227 } else { 10228 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10229 } 10230 10231 if (this.uiDialog.is(":data(ui-resizable)") ) { 10232 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10233 } 10234 }, 10235 10236 _blockFrames: function() { 10237 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10238 var iframe = $( this ); 10239 10240 return $( "<div>" ) 10241 .css({ 10242 position: "absolute", 10243 width: iframe.outerWidth(), 10244 height: iframe.outerHeight() 10245 }) 10246 .appendTo( iframe.parent() ) 10247 .offset( iframe.offset() )[0]; 10248 }); 10249 }, 10250 10251 _unblockFrames: function() { 10252 if ( this.iframeBlocks ) { 10253 this.iframeBlocks.remove(); 10254 delete this.iframeBlocks; 10255 } 10256 }, 10257 10258 _createOverlay: function() { 10259 if ( !this.options.modal ) { 10260 return; 10261 } 10262 10263 if ( !$.ui.dialog.overlayInstances ) { 10264 // Prevent use of anchors and inputs. 10265 // We use a delay in case the overlay is created from an 10266 // event that we're going to be cancelling. (#2804) 10267 this._delay(function() { 10268 // Handle .dialog().dialog("close") (#4065) 10269 if ( $.ui.dialog.overlayInstances ) { 10270 this.document.bind( "focusin.dialog", function( event ) { 10271 if ( !$( event.target ).closest(".ui-dialog").length && 10272 // TODO: Remove hack when datepicker implements 10273 // the .ui-front logic (#8989) 10274 !$( event.target ).closest(".ui-datepicker").length ) { 10275 event.preventDefault(); 10276 $(".ui-dialog:visible:last .ui-dialog-content") 10277 .data("ui-dialog")._focusTabbable(); 10278 } 10279 }); 10280 } 10281 }); 10282 } 10283 10284 this.overlay = $("<div>") 10285 .addClass("ui-widget-overlay ui-front") 10286 .appendTo( this._appendTo() ); 10287 this._on( this.overlay, { 10288 mousedown: "_keepFocus" 10289 }); 10290 $.ui.dialog.overlayInstances++; 10291 }, 10292 10293 _destroyOverlay: function() { 10294 if ( !this.options.modal ) { 10295 return; 10296 } 10297 10298 if ( this.overlay ) { 10299 $.ui.dialog.overlayInstances--; 10300 10301 if ( !$.ui.dialog.overlayInstances ) { 10302 this.document.unbind( "focusin.dialog" ); 10303 } 10304 this.overlay.remove(); 10305 this.overlay = null; 10306 } 10307 } 10308}); 10309 10310$.ui.dialog.overlayInstances = 0; 10311 10312// DEPRECATED 10313if ( $.uiBackCompat !== false ) { 10314 // position option with array notation 10315 // just override with old implementation 10316 $.widget( "ui.dialog", $.ui.dialog, { 10317 _position: function() { 10318 var position = this.options.position, 10319 myAt = [], 10320 offset = [ 0, 0 ], 10321 isVisible; 10322 10323 if ( position ) { 10324 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10325 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10326 if ( myAt.length === 1 ) { 10327 myAt[1] = myAt[0]; 10328 } 10329 10330 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10331 if ( +myAt[ i ] === myAt[ i ] ) { 10332 offset[ i ] = myAt[ i ]; 10333 myAt[ i ] = offsetPosition; 10334 } 10335 }); 10336 10337 position = { 10338 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10339 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10340 at: myAt.join(" ") 10341 }; 10342 } 10343 10344 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10345 } else { 10346 position = $.ui.dialog.prototype.options.position; 10347 } 10348 10349 // need to show the dialog to get the actual offset in the position plugin 10350 isVisible = this.uiDialog.is(":visible"); 10351 if ( !isVisible ) { 10352 this.uiDialog.show(); 10353 } 10354 this.uiDialog.position( position ); 10355 if ( !isVisible ) { 10356 this.uiDialog.hide(); 10357 } 10358 } 10359 }); 10360} 10361 10362}( jQuery ) ); 10363 10364(function( $, undefined ) { 10365 10366var rvertical = /up|down|vertical/, 10367 rpositivemotion = /up|left|vertical|horizontal/; 10368 10369$.effects.effect.blind = function( o, done ) { 10370 // Create element 10371 var el = $( this ), 10372 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10373 mode = $.effects.setMode( el, o.mode || "hide" ), 10374 direction = o.direction || "up", 10375 vertical = rvertical.test( direction ), 10376 ref = vertical ? "height" : "width", 10377 ref2 = vertical ? "top" : "left", 10378 motion = rpositivemotion.test( direction ), 10379 animation = {}, 10380 show = mode === "show", 10381 wrapper, distance, margin; 10382 10383 // if already wrapped, the wrapper's properties are my property. #6245 10384 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10385 $.effects.save( el.parent(), props ); 10386 } else { 10387 $.effects.save( el, props ); 10388 } 10389 el.show(); 10390 wrapper = $.effects.createWrapper( el ).css({ 10391 overflow: "hidden" 10392 }); 10393 10394 distance = wrapper[ ref ](); 10395 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10396 10397 animation[ ref ] = show ? distance : 0; 10398 if ( !motion ) { 10399 el 10400 .css( vertical ? "bottom" : "right", 0 ) 10401 .css( vertical ? "top" : "left", "auto" ) 10402 .css({ position: "absolute" }); 10403 10404 animation[ ref2 ] = show ? margin : distance + margin; 10405 } 10406 10407 // start at 0 if we are showing 10408 if ( show ) { 10409 wrapper.css( ref, 0 ); 10410 if ( ! motion ) { 10411 wrapper.css( ref2, margin + distance ); 10412 } 10413 } 10414 10415 // Animate 10416 wrapper.animate( animation, { 10417 duration: o.duration, 10418 easing: o.easing, 10419 queue: false, 10420 complete: function() { 10421 if ( mode === "hide" ) { 10422 el.hide(); 10423 } 10424 $.effects.restore( el, props ); 10425 $.effects.removeWrapper( el ); 10426 done(); 10427 } 10428 }); 10429 10430}; 10431 10432})(jQuery); 10433 10434(function( $, undefined ) { 10435 10436$.effects.effect.bounce = function( o, done ) { 10437 var el = $( this ), 10438 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10439 10440 // defaults: 10441 mode = $.effects.setMode( el, o.mode || "effect" ), 10442 hide = mode === "hide", 10443 show = mode === "show", 10444 direction = o.direction || "up", 10445 distance = o.distance, 10446 times = o.times || 5, 10447 10448 // number of internal animations 10449 anims = times * 2 + ( show || hide ? 1 : 0 ), 10450 speed = o.duration / anims, 10451 easing = o.easing, 10452 10453 // utility: 10454 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10455 motion = ( direction === "up" || direction === "left" ), 10456 i, 10457 upAnim, 10458 downAnim, 10459 10460 // we will need to re-assemble the queue to stack our animations in place 10461 queue = el.queue(), 10462 queuelen = queue.length; 10463 10464 // Avoid touching opacity to prevent clearType and PNG issues in IE 10465 if ( show || hide ) { 10466 props.push( "opacity" ); 10467 } 10468 10469 $.effects.save( el, props ); 10470 el.show(); 10471 $.effects.createWrapper( el ); // Create Wrapper 10472 10473 // default distance for the BIGGEST bounce is the outer Distance / 3 10474 if ( !distance ) { 10475 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10476 } 10477 10478 if ( show ) { 10479 downAnim = { opacity: 1 }; 10480 downAnim[ ref ] = 0; 10481 10482 // if we are showing, force opacity 0 and set the initial position 10483 // then do the "first" animation 10484 el.css( "opacity", 0 ) 10485 .css( ref, motion ? -distance * 2 : distance * 2 ) 10486 .animate( downAnim, speed, easing ); 10487 } 10488 10489 // start at the smallest distance if we are hiding 10490 if ( hide ) { 10491 distance = distance / Math.pow( 2, times - 1 ); 10492 } 10493 10494 downAnim = {}; 10495 downAnim[ ref ] = 0; 10496 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10497 for ( i = 0; i < times; i++ ) { 10498 upAnim = {}; 10499 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10500 10501 el.animate( upAnim, speed, easing ) 10502 .animate( downAnim, speed, easing ); 10503 10504 distance = hide ? distance * 2 : distance / 2; 10505 } 10506 10507 // Last Bounce when Hiding 10508 if ( hide ) { 10509 upAnim = { opacity: 0 }; 10510 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10511 10512 el.animate( upAnim, speed, easing ); 10513 } 10514 10515 el.queue(function() { 10516 if ( hide ) { 10517 el.hide(); 10518 } 10519 $.effects.restore( el, props ); 10520 $.effects.removeWrapper( el ); 10521 done(); 10522 }); 10523 10524 // inject all the animations we just queued to be first in line (after "inprogress") 10525 if ( queuelen > 1) { 10526 queue.splice.apply( queue, 10527 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10528 } 10529 el.dequeue(); 10530 10531}; 10532 10533})(jQuery); 10534 10535(function( $, undefined ) { 10536 10537$.effects.effect.clip = function( o, done ) { 10538 // Create element 10539 var el = $( this ), 10540 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10541 mode = $.effects.setMode( el, o.mode || "hide" ), 10542 show = mode === "show", 10543 direction = o.direction || "vertical", 10544 vert = direction === "vertical", 10545 size = vert ? "height" : "width", 10546 position = vert ? "top" : "left", 10547 animation = {}, 10548 wrapper, animate, distance; 10549 10550 // Save & Show 10551 $.effects.save( el, props ); 10552 el.show(); 10553 10554 // Create Wrapper 10555 wrapper = $.effects.createWrapper( el ).css({ 10556 overflow: "hidden" 10557 }); 10558 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10559 distance = animate[ size ](); 10560 10561 // Shift 10562 if ( show ) { 10563 animate.css( size, 0 ); 10564 animate.css( position, distance / 2 ); 10565 } 10566 10567 // Create Animation Object: 10568 animation[ size ] = show ? distance : 0; 10569 animation[ position ] = show ? 0 : distance / 2; 10570 10571 // Animate 10572 animate.animate( animation, { 10573 queue: false, 10574 duration: o.duration, 10575 easing: o.easing, 10576 complete: function() { 10577 if ( !show ) { 10578 el.hide(); 10579 } 10580 $.effects.restore( el, props ); 10581 $.effects.removeWrapper( el ); 10582 done(); 10583 } 10584 }); 10585 10586}; 10587 10588})(jQuery); 10589 10590(function( $, undefined ) { 10591 10592$.effects.effect.drop = function( o, done ) { 10593 10594 var el = $( this ), 10595 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10596 mode = $.effects.setMode( el, o.mode || "hide" ), 10597 show = mode === "show", 10598 direction = o.direction || "left", 10599 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10600 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10601 animation = { 10602 opacity: show ? 1 : 0 10603 }, 10604 distance; 10605 10606 // Adjust 10607 $.effects.save( el, props ); 10608 el.show(); 10609 $.effects.createWrapper( el ); 10610 10611 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10612 10613 if ( show ) { 10614 el 10615 .css( "opacity", 0 ) 10616 .css( ref, motion === "pos" ? -distance : distance ); 10617 } 10618 10619 // Animation 10620 animation[ ref ] = ( show ? 10621 ( motion === "pos" ? "+=" : "-=" ) : 10622 ( motion === "pos" ? "-=" : "+=" ) ) + 10623 distance; 10624 10625 // Animate 10626 el.animate( animation, { 10627 queue: false, 10628 duration: o.duration, 10629 easing: o.easing, 10630 complete: function() { 10631 if ( mode === "hide" ) { 10632 el.hide(); 10633 } 10634 $.effects.restore( el, props ); 10635 $.effects.removeWrapper( el ); 10636 done(); 10637 } 10638 }); 10639}; 10640 10641})(jQuery); 10642 10643(function( $, undefined ) { 10644 10645$.effects.effect.explode = function( o, done ) { 10646 10647 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10648 cells = rows, 10649 el = $( this ), 10650 mode = $.effects.setMode( el, o.mode || "hide" ), 10651 show = mode === "show", 10652 10653 // show and then visibility:hidden the element before calculating offset 10654 offset = el.show().css( "visibility", "hidden" ).offset(), 10655 10656 // width and height of a piece 10657 width = Math.ceil( el.outerWidth() / cells ), 10658 height = Math.ceil( el.outerHeight() / rows ), 10659 pieces = [], 10660 10661 // loop 10662 i, j, left, top, mx, my; 10663 10664 // children animate complete: 10665 function childComplete() { 10666 pieces.push( this ); 10667 if ( pieces.length === rows * cells ) { 10668 animComplete(); 10669 } 10670 } 10671 10672 // clone the element for each row and cell. 10673 for( i = 0; i < rows ; i++ ) { // ===> 10674 top = offset.top + i * height; 10675 my = i - ( rows - 1 ) / 2 ; 10676 10677 for( j = 0; j < cells ; j++ ) { // ||| 10678 left = offset.left + j * width; 10679 mx = j - ( cells - 1 ) / 2 ; 10680 10681 // Create a clone of the now hidden main element that will be absolute positioned 10682 // within a wrapper div off the -left and -top equal to size of our pieces 10683 el 10684 .clone() 10685 .appendTo( "body" ) 10686 .wrap( "<div></div>" ) 10687 .css({ 10688 position: "absolute", 10689 visibility: "visible", 10690 left: -j * width, 10691 top: -i * height 10692 }) 10693 10694 // select the wrapper - make it overflow: hidden and absolute positioned based on 10695 // where the original was located +left and +top equal to the size of pieces 10696 .parent() 10697 .addClass( "ui-effects-explode" ) 10698 .css({ 10699 position: "absolute", 10700 overflow: "hidden", 10701 width: width, 10702 height: height, 10703 left: left + ( show ? mx * width : 0 ), 10704 top: top + ( show ? my * height : 0 ), 10705 opacity: show ? 0 : 1 10706 }).animate({ 10707 left: left + ( show ? 0 : mx * width ), 10708 top: top + ( show ? 0 : my * height ), 10709 opacity: show ? 1 : 0 10710 }, o.duration || 500, o.easing, childComplete ); 10711 } 10712 } 10713 10714 function animComplete() { 10715 el.css({ 10716 visibility: "visible" 10717 }); 10718 $( pieces ).remove(); 10719 if ( !show ) { 10720 el.hide(); 10721 } 10722 done(); 10723 } 10724}; 10725 10726})(jQuery); 10727 10728(function( $, undefined ) { 10729 10730$.effects.effect.fade = function( o, done ) { 10731 var el = $( this ), 10732 mode = $.effects.setMode( el, o.mode || "toggle" ); 10733 10734 el.animate({ 10735 opacity: mode 10736 }, { 10737 queue: false, 10738 duration: o.duration, 10739 easing: o.easing, 10740 complete: done 10741 }); 10742}; 10743 10744})( jQuery ); 10745 10746(function( $, undefined ) { 10747 10748$.effects.effect.fold = function( o, done ) { 10749 10750 // Create element 10751 var el = $( this ), 10752 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10753 mode = $.effects.setMode( el, o.mode || "hide" ), 10754 show = mode === "show", 10755 hide = mode === "hide", 10756 size = o.size || 15, 10757 percent = /([0-9]+)%/.exec( size ), 10758 horizFirst = !!o.horizFirst, 10759 widthFirst = show !== horizFirst, 10760 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10761 duration = o.duration / 2, 10762 wrapper, distance, 10763 animation1 = {}, 10764 animation2 = {}; 10765 10766 $.effects.save( el, props ); 10767 el.show(); 10768 10769 // Create Wrapper 10770 wrapper = $.effects.createWrapper( el ).css({ 10771 overflow: "hidden" 10772 }); 10773 distance = widthFirst ? 10774 [ wrapper.width(), wrapper.height() ] : 10775 [ wrapper.height(), wrapper.width() ]; 10776 10777 if ( percent ) { 10778 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10779 } 10780 if ( show ) { 10781 wrapper.css( horizFirst ? { 10782 height: 0, 10783 width: size 10784 } : { 10785 height: size, 10786 width: 0 10787 }); 10788 } 10789 10790 // Animation 10791 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10792 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10793 10794 // Animate 10795 wrapper 10796 .animate( animation1, duration, o.easing ) 10797 .animate( animation2, duration, o.easing, function() { 10798 if ( hide ) { 10799 el.hide(); 10800 } 10801 $.effects.restore( el, props ); 10802 $.effects.removeWrapper( el ); 10803 done(); 10804 }); 10805 10806}; 10807 10808})(jQuery); 10809 10810(function( $, undefined ) { 10811 10812$.effects.effect.highlight = function( o, done ) { 10813 var elem = $( this ), 10814 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10815 mode = $.effects.setMode( elem, o.mode || "show" ), 10816 animation = { 10817 backgroundColor: elem.css( "backgroundColor" ) 10818 }; 10819 10820 if (mode === "hide") { 10821 animation.opacity = 0; 10822 } 10823 10824 $.effects.save( elem, props ); 10825 10826 elem 10827 .show() 10828 .css({ 10829 backgroundImage: "none", 10830 backgroundColor: o.color || "#ffff99" 10831 }) 10832 .animate( animation, { 10833 queue: false, 10834 duration: o.duration, 10835 easing: o.easing, 10836 complete: function() { 10837 if ( mode === "hide" ) { 10838 elem.hide(); 10839 } 10840 $.effects.restore( elem, props ); 10841 done(); 10842 } 10843 }); 10844}; 10845 10846})(jQuery); 10847 10848(function( $, undefined ) { 10849 10850$.effects.effect.pulsate = function( o, done ) { 10851 var elem = $( this ), 10852 mode = $.effects.setMode( elem, o.mode || "show" ), 10853 show = mode === "show", 10854 hide = mode === "hide", 10855 showhide = ( show || mode === "hide" ), 10856 10857 // showing or hiding leaves of the "last" animation 10858 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10859 duration = o.duration / anims, 10860 animateTo = 0, 10861 queue = elem.queue(), 10862 queuelen = queue.length, 10863 i; 10864 10865 if ( show || !elem.is(":visible")) { 10866 elem.css( "opacity", 0 ).show(); 10867 animateTo = 1; 10868 } 10869 10870 // anims - 1 opacity "toggles" 10871 for ( i = 1; i < anims; i++ ) { 10872 elem.animate({ 10873 opacity: animateTo 10874 }, duration, o.easing ); 10875 animateTo = 1 - animateTo; 10876 } 10877 10878 elem.animate({ 10879 opacity: animateTo 10880 }, duration, o.easing); 10881 10882 elem.queue(function() { 10883 if ( hide ) { 10884 elem.hide(); 10885 } 10886 done(); 10887 }); 10888 10889 // We just queued up "anims" animations, we need to put them next in the queue 10890 if ( queuelen > 1 ) { 10891 queue.splice.apply( queue, 10892 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10893 } 10894 elem.dequeue(); 10895}; 10896 10897})(jQuery); 10898 10899(function( $, undefined ) { 10900 10901$.effects.effect.puff = function( o, done ) { 10902 var elem = $( this ), 10903 mode = $.effects.setMode( elem, o.mode || "hide" ), 10904 hide = mode === "hide", 10905 percent = parseInt( o.percent, 10 ) || 150, 10906 factor = percent / 100, 10907 original = { 10908 height: elem.height(), 10909 width: elem.width(), 10910 outerHeight: elem.outerHeight(), 10911 outerWidth: elem.outerWidth() 10912 }; 10913 10914 $.extend( o, { 10915 effect: "scale", 10916 queue: false, 10917 fade: true, 10918 mode: mode, 10919 complete: done, 10920 percent: hide ? percent : 100, 10921 from: hide ? 10922 original : 10923 { 10924 height: original.height * factor, 10925 width: original.width * factor, 10926 outerHeight: original.outerHeight * factor, 10927 outerWidth: original.outerWidth * factor 10928 } 10929 }); 10930 10931 elem.effect( o ); 10932}; 10933 10934$.effects.effect.scale = function( o, done ) { 10935 10936 // Create element 10937 var el = $( this ), 10938 options = $.extend( true, {}, o ), 10939 mode = $.effects.setMode( el, o.mode || "effect" ), 10940 percent = parseInt( o.percent, 10 ) || 10941 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 10942 direction = o.direction || "both", 10943 origin = o.origin, 10944 original = { 10945 height: el.height(), 10946 width: el.width(), 10947 outerHeight: el.outerHeight(), 10948 outerWidth: el.outerWidth() 10949 }, 10950 factor = { 10951 y: direction !== "horizontal" ? (percent / 100) : 1, 10952 x: direction !== "vertical" ? (percent / 100) : 1 10953 }; 10954 10955 // We are going to pass this effect to the size effect: 10956 options.effect = "size"; 10957 options.queue = false; 10958 options.complete = done; 10959 10960 // Set default origin and restore for show/hide 10961 if ( mode !== "effect" ) { 10962 options.origin = origin || ["middle","center"]; 10963 options.restore = true; 10964 } 10965 10966 options.from = o.from || ( mode === "show" ? { 10967 height: 0, 10968 width: 0, 10969 outerHeight: 0, 10970 outerWidth: 0 10971 } : original ); 10972 options.to = { 10973 height: original.height * factor.y, 10974 width: original.width * factor.x, 10975 outerHeight: original.outerHeight * factor.y, 10976 outerWidth: original.outerWidth * factor.x 10977 }; 10978 10979 // Fade option to support puff 10980 if ( options.fade ) { 10981 if ( mode === "show" ) { 10982 options.from.opacity = 0; 10983 options.to.opacity = 1; 10984 } 10985 if ( mode === "hide" ) { 10986 options.from.opacity = 1; 10987 options.to.opacity = 0; 10988 } 10989 } 10990 10991 // Animate 10992 el.effect( options ); 10993 10994}; 10995 10996$.effects.effect.size = function( o, done ) { 10997 10998 // Create element 10999 var original, baseline, factor, 11000 el = $( this ), 11001 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11002 11003 // Always restore 11004 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11005 11006 // Copy for children 11007 props2 = [ "width", "height", "overflow" ], 11008 cProps = [ "fontSize" ], 11009 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11010 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11011 11012 // Set options 11013 mode = $.effects.setMode( el, o.mode || "effect" ), 11014 restore = o.restore || mode !== "effect", 11015 scale = o.scale || "both", 11016 origin = o.origin || [ "middle", "center" ], 11017 position = el.css( "position" ), 11018 props = restore ? props0 : props1, 11019 zero = { 11020 height: 0, 11021 width: 0, 11022 outerHeight: 0, 11023 outerWidth: 0 11024 }; 11025 11026 if ( mode === "show" ) { 11027 el.show(); 11028 } 11029 original = { 11030 height: el.height(), 11031 width: el.width(), 11032 outerHeight: el.outerHeight(), 11033 outerWidth: el.outerWidth() 11034 }; 11035 11036 if ( o.mode === "toggle" && mode === "show" ) { 11037 el.from = o.to || zero; 11038 el.to = o.from || original; 11039 } else { 11040 el.from = o.from || ( mode === "show" ? zero : original ); 11041 el.to = o.to || ( mode === "hide" ? zero : original ); 11042 } 11043 11044 // Set scaling factor 11045 factor = { 11046 from: { 11047 y: el.from.height / original.height, 11048 x: el.from.width / original.width 11049 }, 11050 to: { 11051 y: el.to.height / original.height, 11052 x: el.to.width / original.width 11053 } 11054 }; 11055 11056 // Scale the css box 11057 if ( scale === "box" || scale === "both" ) { 11058 11059 // Vertical props scaling 11060 if ( factor.from.y !== factor.to.y ) { 11061 props = props.concat( vProps ); 11062 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11063 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11064 } 11065 11066 // Horizontal props scaling 11067 if ( factor.from.x !== factor.to.x ) { 11068 props = props.concat( hProps ); 11069 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11070 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11071 } 11072 } 11073 11074 // Scale the content 11075 if ( scale === "content" || scale === "both" ) { 11076 11077 // Vertical props scaling 11078 if ( factor.from.y !== factor.to.y ) { 11079 props = props.concat( cProps ).concat( props2 ); 11080 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11081 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11082 } 11083 } 11084 11085 $.effects.save( el, props ); 11086 el.show(); 11087 $.effects.createWrapper( el ); 11088 el.css( "overflow", "hidden" ).css( el.from ); 11089 11090 // Adjust 11091 if (origin) { // Calculate baseline shifts 11092 baseline = $.effects.getBaseline( origin, original ); 11093 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11094 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11095 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11096 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11097 } 11098 el.css( el.from ); // set top & left 11099 11100 // Animate 11101 if ( scale === "content" || scale === "both" ) { // Scale the children 11102 11103 // Add margins/font-size 11104 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11105 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11106 props2 = props0.concat(vProps).concat(hProps); 11107 11108 el.find( "*[width]" ).each( function(){ 11109 var child = $( this ), 11110 c_original = { 11111 height: child.height(), 11112 width: child.width(), 11113 outerHeight: child.outerHeight(), 11114 outerWidth: child.outerWidth() 11115 }; 11116 if (restore) { 11117 $.effects.save(child, props2); 11118 } 11119 11120 child.from = { 11121 height: c_original.height * factor.from.y, 11122 width: c_original.width * factor.from.x, 11123 outerHeight: c_original.outerHeight * factor.from.y, 11124 outerWidth: c_original.outerWidth * factor.from.x 11125 }; 11126 child.to = { 11127 height: c_original.height * factor.to.y, 11128 width: c_original.width * factor.to.x, 11129 outerHeight: c_original.height * factor.to.y, 11130 outerWidth: c_original.width * factor.to.x 11131 }; 11132 11133 // Vertical props scaling 11134 if ( factor.from.y !== factor.to.y ) { 11135 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11136 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11137 } 11138 11139 // Horizontal props scaling 11140 if ( factor.from.x !== factor.to.x ) { 11141 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11142 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11143 } 11144 11145 // Animate children 11146 child.css( child.from ); 11147 child.animate( child.to, o.duration, o.easing, function() { 11148 11149 // Restore children 11150 if ( restore ) { 11151 $.effects.restore( child, props2 ); 11152 } 11153 }); 11154 }); 11155 } 11156 11157 // Animate 11158 el.animate( el.to, { 11159 queue: false, 11160 duration: o.duration, 11161 easing: o.easing, 11162 complete: function() { 11163 if ( el.to.opacity === 0 ) { 11164 el.css( "opacity", el.from.opacity ); 11165 } 11166 if( mode === "hide" ) { 11167 el.hide(); 11168 } 11169 $.effects.restore( el, props ); 11170 if ( !restore ) { 11171 11172 // we need to calculate our new positioning based on the scaling 11173 if ( position === "static" ) { 11174 el.css({ 11175 position: "relative", 11176 top: el.to.top, 11177 left: el.to.left 11178 }); 11179 } else { 11180 $.each([ "top", "left" ], function( idx, pos ) { 11181 el.css( pos, function( _, str ) { 11182 var val = parseInt( str, 10 ), 11183 toRef = idx ? el.to.left : el.to.top; 11184 11185 // if original was "auto", recalculate the new value from wrapper 11186 if ( str === "auto" ) { 11187 return toRef + "px"; 11188 } 11189 11190 return val + toRef + "px"; 11191 }); 11192 }); 11193 } 11194 } 11195 11196 $.effects.removeWrapper( el ); 11197 done(); 11198 } 11199 }); 11200 11201}; 11202 11203})(jQuery); 11204 11205(function( $, undefined ) { 11206 11207$.effects.effect.shake = function( o, done ) { 11208 11209 var el = $( this ), 11210 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11211 mode = $.effects.setMode( el, o.mode || "effect" ), 11212 direction = o.direction || "left", 11213 distance = o.distance || 20, 11214 times = o.times || 3, 11215 anims = times * 2 + 1, 11216 speed = Math.round(o.duration/anims), 11217 ref = (direction === "up" || direction === "down") ? "top" : "left", 11218 positiveMotion = (direction === "up" || direction === "left"), 11219 animation = {}, 11220 animation1 = {}, 11221 animation2 = {}, 11222 i, 11223 11224 // we will need to re-assemble the queue to stack our animations in place 11225 queue = el.queue(), 11226 queuelen = queue.length; 11227 11228 $.effects.save( el, props ); 11229 el.show(); 11230 $.effects.createWrapper( el ); 11231 11232 // Animation 11233 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11234 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11235 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11236 11237 // Animate 11238 el.animate( animation, speed, o.easing ); 11239 11240 // Shakes 11241 for ( i = 1; i < times; i++ ) { 11242 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11243 } 11244 el 11245 .animate( animation1, speed, o.easing ) 11246 .animate( animation, speed / 2, o.easing ) 11247 .queue(function() { 11248 if ( mode === "hide" ) { 11249 el.hide(); 11250 } 11251 $.effects.restore( el, props ); 11252 $.effects.removeWrapper( el ); 11253 done(); 11254 }); 11255 11256 // inject all the animations we just queued to be first in line (after "inprogress") 11257 if ( queuelen > 1) { 11258 queue.splice.apply( queue, 11259 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11260 } 11261 el.dequeue(); 11262 11263}; 11264 11265})(jQuery); 11266 11267(function( $, undefined ) { 11268 11269$.effects.effect.slide = function( o, done ) { 11270 11271 // Create element 11272 var el = $( this ), 11273 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11274 mode = $.effects.setMode( el, o.mode || "show" ), 11275 show = mode === "show", 11276 direction = o.direction || "left", 11277 ref = (direction === "up" || direction === "down") ? "top" : "left", 11278 positiveMotion = (direction === "up" || direction === "left"), 11279 distance, 11280 animation = {}; 11281 11282 // Adjust 11283 $.effects.save( el, props ); 11284 el.show(); 11285 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11286 11287 $.effects.createWrapper( el ).css({ 11288 overflow: "hidden" 11289 }); 11290 11291 if ( show ) { 11292 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11293 } 11294 11295 // Animation 11296 animation[ ref ] = ( show ? 11297 ( positiveMotion ? "+=" : "-=") : 11298 ( positiveMotion ? "-=" : "+=")) + 11299 distance; 11300 11301 // Animate 11302 el.animate( animation, { 11303 queue: false, 11304 duration: o.duration, 11305 easing: o.easing, 11306 complete: function() { 11307 if ( mode === "hide" ) { 11308 el.hide(); 11309 } 11310 $.effects.restore( el, props ); 11311 $.effects.removeWrapper( el ); 11312 done(); 11313 } 11314 }); 11315}; 11316 11317})(jQuery); 11318 11319(function( $, undefined ) { 11320 11321$.effects.effect.transfer = function( o, done ) { 11322 var elem = $( this ), 11323 target = $( o.to ), 11324 targetFixed = target.css( "position" ) === "fixed", 11325 body = $("body"), 11326 fixTop = targetFixed ? body.scrollTop() : 0, 11327 fixLeft = targetFixed ? body.scrollLeft() : 0, 11328 endPosition = target.offset(), 11329 animation = { 11330 top: endPosition.top - fixTop , 11331 left: endPosition.left - fixLeft , 11332 height: target.innerHeight(), 11333 width: target.innerWidth() 11334 }, 11335 startPosition = elem.offset(), 11336 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11337 .appendTo( document.body ) 11338 .addClass( o.className ) 11339 .css({ 11340 top: startPosition.top - fixTop , 11341 left: startPosition.left - fixLeft , 11342 height: elem.innerHeight(), 11343 width: elem.innerWidth(), 11344 position: targetFixed ? "fixed" : "absolute" 11345 }) 11346 .animate( animation, o.duration, o.easing, function() { 11347 transfer.remove(); 11348 done(); 11349 }); 11350}; 11351 11352})(jQuery); 11353 11354(function( $, undefined ) { 11355 11356$.widget( "ui.menu", { 11357 version: "1.10.1", 11358 defaultElement: "<ul>", 11359 delay: 300, 11360 options: { 11361 icons: { 11362 submenu: "ui-icon-carat-1-e" 11363 }, 11364 menus: "ul", 11365 position: { 11366 my: "left top", 11367 at: "right top" 11368 }, 11369 role: "menu", 11370 11371 // callbacks 11372 blur: null, 11373 focus: null, 11374 select: null 11375 }, 11376 11377 _create: function() { 11378 this.activeMenu = this.element; 11379 // flag used to prevent firing of the click handler 11380 // as the event bubbles up through nested menus 11381 this.mouseHandled = false; 11382 this.element 11383 .uniqueId() 11384 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11385 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 11386 .attr({ 11387 role: this.options.role, 11388 tabIndex: 0 11389 }) 11390 // need to catch all clicks on disabled menu 11391 // not possible through _on 11392 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 11393 if ( this.options.disabled ) { 11394 event.preventDefault(); 11395 } 11396 }, this )); 11397 11398 if ( this.options.disabled ) { 11399 this.element 11400 .addClass( "ui-state-disabled" ) 11401 .attr( "aria-disabled", "true" ); 11402 } 11403 11404 this._on({ 11405 // Prevent focus from sticking to links inside menu after clicking 11406 // them (focus should always stay on UL during navigation). 11407 "mousedown .ui-menu-item > a": function( event ) { 11408 event.preventDefault(); 11409 }, 11410 "click .ui-state-disabled > a": function( event ) { 11411 event.preventDefault(); 11412 }, 11413 "click .ui-menu-item:has(a)": function( event ) { 11414 var target = $( event.target ).closest( ".ui-menu-item" ); 11415 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 11416 this.mouseHandled = true; 11417 11418 this.select( event ); 11419 // Open submenu on click 11420 if ( target.has( ".ui-menu" ).length ) { 11421 this.expand( event ); 11422 } else if ( !this.element.is( ":focus" ) ) { 11423 // Redirect focus to the menu 11424 this.element.trigger( "focus", [ true ] ); 11425 11426 // If the active item is on the top level, let it stay active. 11427 // Otherwise, blur the active item since it is no longer visible. 11428 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 11429 clearTimeout( this.timer ); 11430 } 11431 } 11432 } 11433 }, 11434 "mouseenter .ui-menu-item": function( event ) { 11435 var target = $( event.currentTarget ); 11436 // Remove ui-state-active class from siblings of the newly focused menu item 11437 // to avoid a jump caused by adjacent elements both having a class with a border 11438 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 11439 this.focus( event, target ); 11440 }, 11441 mouseleave: "collapseAll", 11442 "mouseleave .ui-menu": "collapseAll", 11443 focus: function( event, keepActiveItem ) { 11444 // If there's already an active item, keep it active 11445 // If not, activate the first item 11446 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 11447 11448 if ( !keepActiveItem ) { 11449 this.focus( event, item ); 11450 } 11451 }, 11452 blur: function( event ) { 11453 this._delay(function() { 11454 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 11455 this.collapseAll( event ); 11456 } 11457 }); 11458 }, 11459 keydown: "_keydown" 11460 }); 11461 11462 this.refresh(); 11463 11464 // Clicks outside of a menu collapse any open menus 11465 this._on( this.document, { 11466 click: function( event ) { 11467 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11468 this.collapseAll( event ); 11469 } 11470 11471 // Reset the mouseHandled flag 11472 this.mouseHandled = false; 11473 } 11474 }); 11475 }, 11476 11477 _destroy: function() { 11478 // Destroy (sub)menus 11479 this.element 11480 .removeAttr( "aria-activedescendant" ) 11481 .find( ".ui-menu" ).addBack() 11482 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11483 .removeAttr( "role" ) 11484 .removeAttr( "tabIndex" ) 11485 .removeAttr( "aria-labelledby" ) 11486 .removeAttr( "aria-expanded" ) 11487 .removeAttr( "aria-hidden" ) 11488 .removeAttr( "aria-disabled" ) 11489 .removeUniqueId() 11490 .show(); 11491 11492 // Destroy menu items 11493 this.element.find( ".ui-menu-item" ) 11494 .removeClass( "ui-menu-item" ) 11495 .removeAttr( "role" ) 11496 .removeAttr( "aria-disabled" ) 11497 .children( "a" ) 11498 .removeUniqueId() 11499 .removeClass( "ui-corner-all ui-state-hover" ) 11500 .removeAttr( "tabIndex" ) 11501 .removeAttr( "role" ) 11502 .removeAttr( "aria-haspopup" ) 11503 .children().each( function() { 11504 var elem = $( this ); 11505 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11506 elem.remove(); 11507 } 11508 }); 11509 11510 // Destroy menu dividers 11511 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11512 }, 11513 11514 _keydown: function( event ) { 11515 /*jshint maxcomplexity:20*/ 11516 var match, prev, character, skip, regex, 11517 preventDefault = true; 11518 11519 function escape( value ) { 11520 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11521 } 11522 11523 switch ( event.keyCode ) { 11524 case $.ui.keyCode.PAGE_UP: 11525 this.previousPage( event ); 11526 break; 11527 case $.ui.keyCode.PAGE_DOWN: 11528 this.nextPage( event ); 11529 break; 11530 case $.ui.keyCode.HOME: 11531 this._move( "first", "first", event ); 11532 break; 11533 case $.ui.keyCode.END: 11534 this._move( "last", "last", event ); 11535 break; 11536 case $.ui.keyCode.UP: 11537 this.previous( event ); 11538 break; 11539 case $.ui.keyCode.DOWN: 11540 this.next( event ); 11541 break; 11542 case $.ui.keyCode.LEFT: 11543 this.collapse( event ); 11544 break; 11545 case $.ui.keyCode.RIGHT: 11546 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11547 this.expand( event ); 11548 } 11549 break; 11550 case $.ui.keyCode.ENTER: 11551 case $.ui.keyCode.SPACE: 11552 this._activate( event ); 11553 break; 11554 case $.ui.keyCode.ESCAPE: 11555 this.collapse( event ); 11556 break; 11557 default: 11558 preventDefault = false; 11559 prev = this.previousFilter || ""; 11560 character = String.fromCharCode( event.keyCode ); 11561 skip = false; 11562 11563 clearTimeout( this.filterTimer ); 11564 11565 if ( character === prev ) { 11566 skip = true; 11567 } else { 11568 character = prev + character; 11569 } 11570 11571 regex = new RegExp( "^" + escape( character ), "i" ); 11572 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11573 return regex.test( $( this ).children( "a" ).text() ); 11574 }); 11575 match = skip && match.index( this.active.next() ) !== -1 ? 11576 this.active.nextAll( ".ui-menu-item" ) : 11577 match; 11578 11579 // If no matches on the current filter, reset to the last character pressed 11580 // to move down the menu to the first item that starts with that character 11581 if ( !match.length ) { 11582 character = String.fromCharCode( event.keyCode ); 11583 regex = new RegExp( "^" + escape( character ), "i" ); 11584 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11585 return regex.test( $( this ).children( "a" ).text() ); 11586 }); 11587 } 11588 11589 if ( match.length ) { 11590 this.focus( event, match ); 11591 if ( match.length > 1 ) { 11592 this.previousFilter = character; 11593 this.filterTimer = this._delay(function() { 11594 delete this.previousFilter; 11595 }, 1000 ); 11596 } else { 11597 delete this.previousFilter; 11598 } 11599 } else { 11600 delete this.previousFilter; 11601 } 11602 } 11603 11604 if ( preventDefault ) { 11605 event.preventDefault(); 11606 } 11607 }, 11608 11609 _activate: function( event ) { 11610 if ( !this.active.is( ".ui-state-disabled" ) ) { 11611 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11612 this.expand( event ); 11613 } else { 11614 this.select( event ); 11615 } 11616 } 11617 }, 11618 11619 refresh: function() { 11620 var menus, 11621 icon = this.options.icons.submenu, 11622 submenus = this.element.find( this.options.menus ); 11623 11624 // Initialize nested menus 11625 submenus.filter( ":not(.ui-menu)" ) 11626 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11627 .hide() 11628 .attr({ 11629 role: this.options.role, 11630 "aria-hidden": "true", 11631 "aria-expanded": "false" 11632 }) 11633 .each(function() { 11634 var menu = $( this ), 11635 item = menu.prev( "a" ), 11636 submenuCarat = $( "<span>" ) 11637 .addClass( "ui-menu-icon ui-icon " + icon ) 11638 .data( "ui-menu-submenu-carat", true ); 11639 11640 item 11641 .attr( "aria-haspopup", "true" ) 11642 .prepend( submenuCarat ); 11643 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11644 }); 11645 11646 menus = submenus.add( this.element ); 11647 11648 // Don't refresh list items that are already adapted 11649 menus.children( ":not(.ui-menu-item):has(a)" ) 11650 .addClass( "ui-menu-item" ) 11651 .attr( "role", "presentation" ) 11652 .children( "a" ) 11653 .uniqueId() 11654 .addClass( "ui-corner-all" ) 11655 .attr({ 11656 tabIndex: -1, 11657 role: this._itemRole() 11658 }); 11659 11660 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11661 menus.children( ":not(.ui-menu-item)" ).each(function() { 11662 var item = $( this ); 11663 // hyphen, em dash, en dash 11664 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 11665 item.addClass( "ui-widget-content ui-menu-divider" ); 11666 } 11667 }); 11668 11669 // Add aria-disabled attribute to any disabled menu item 11670 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11671 11672 // If the active item has been removed, blur the menu 11673 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11674 this.blur(); 11675 } 11676 }, 11677 11678 _itemRole: function() { 11679 return { 11680 menu: "menuitem", 11681 listbox: "option" 11682 }[ this.options.role ]; 11683 }, 11684 11685 _setOption: function( key, value ) { 11686 if ( key === "icons" ) { 11687 this.element.find( ".ui-menu-icon" ) 11688 .removeClass( this.options.icons.submenu ) 11689 .addClass( value.submenu ); 11690 } 11691 this._super( key, value ); 11692 }, 11693 11694 focus: function( event, item ) { 11695 var nested, focused; 11696 this.blur( event, event && event.type === "focus" ); 11697 11698 this._scrollIntoView( item ); 11699 11700 this.active = item.first(); 11701 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11702 // Only update aria-activedescendant if there's a role 11703 // otherwise we assume focus is managed elsewhere 11704 if ( this.options.role ) { 11705 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11706 } 11707 11708 // Highlight active parent menu item, if any 11709 this.active 11710 .parent() 11711 .closest( ".ui-menu-item" ) 11712 .children( "a:first" ) 11713 .addClass( "ui-state-active" ); 11714 11715 if ( event && event.type === "keydown" ) { 11716 this._close(); 11717 } else { 11718 this.timer = this._delay(function() { 11719 this._close(); 11720 }, this.delay ); 11721 } 11722 11723 nested = item.children( ".ui-menu" ); 11724 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11725 this._startOpening(nested); 11726 } 11727 this.activeMenu = item.parent(); 11728 11729 this._trigger( "focus", event, { item: item } ); 11730 }, 11731 11732 _scrollIntoView: function( item ) { 11733 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11734 if ( this._hasScroll() ) { 11735 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11736 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11737 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11738 scroll = this.activeMenu.scrollTop(); 11739 elementHeight = this.activeMenu.height(); 11740 itemHeight = item.height(); 11741 11742 if ( offset < 0 ) { 11743 this.activeMenu.scrollTop( scroll + offset ); 11744 } else if ( offset + itemHeight > elementHeight ) { 11745 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11746 } 11747 } 11748 }, 11749 11750 blur: function( event, fromFocus ) { 11751 if ( !fromFocus ) { 11752 clearTimeout( this.timer ); 11753 } 11754 11755 if ( !this.active ) { 11756 return; 11757 } 11758 11759 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11760 this.active = null; 11761 11762 this._trigger( "blur", event, { item: this.active } ); 11763 }, 11764 11765 _startOpening: function( submenu ) { 11766 clearTimeout( this.timer ); 11767 11768 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11769 // shift in the submenu position when mousing over the carat icon 11770 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11771 return; 11772 } 11773 11774 this.timer = this._delay(function() { 11775 this._close(); 11776 this._open( submenu ); 11777 }, this.delay ); 11778 }, 11779 11780 _open: function( submenu ) { 11781 var position = $.extend({ 11782 of: this.active 11783 }, this.options.position ); 11784 11785 clearTimeout( this.timer ); 11786 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11787 .hide() 11788 .attr( "aria-hidden", "true" ); 11789 11790 submenu 11791 .show() 11792 .removeAttr( "aria-hidden" ) 11793 .attr( "aria-expanded", "true" ) 11794 .position( position ); 11795 }, 11796 11797 collapseAll: function( event, all ) { 11798 clearTimeout( this.timer ); 11799 this.timer = this._delay(function() { 11800 // If we were passed an event, look for the submenu that contains the event 11801 var currentMenu = all ? this.element : 11802 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11803 11804 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11805 if ( !currentMenu.length ) { 11806 currentMenu = this.element; 11807 } 11808 11809 this._close( currentMenu ); 11810 11811 this.blur( event ); 11812 this.activeMenu = currentMenu; 11813 }, this.delay ); 11814 }, 11815 11816 // With no arguments, closes the currently active menu - if nothing is active 11817 // it closes all menus. If passed an argument, it will search for menus BELOW 11818 _close: function( startMenu ) { 11819 if ( !startMenu ) { 11820 startMenu = this.active ? this.active.parent() : this.element; 11821 } 11822 11823 startMenu 11824 .find( ".ui-menu" ) 11825 .hide() 11826 .attr( "aria-hidden", "true" ) 11827 .attr( "aria-expanded", "false" ) 11828 .end() 11829 .find( "a.ui-state-active" ) 11830 .removeClass( "ui-state-active" ); 11831 }, 11832 11833 collapse: function( event ) { 11834 var newItem = this.active && 11835 this.active.parent().closest( ".ui-menu-item", this.element ); 11836 if ( newItem && newItem.length ) { 11837 this._close(); 11838 this.focus( event, newItem ); 11839 } 11840 }, 11841 11842 expand: function( event ) { 11843 var newItem = this.active && 11844 this.active 11845 .children( ".ui-menu " ) 11846 .children( ".ui-menu-item" ) 11847 .first(); 11848 11849 if ( newItem && newItem.length ) { 11850 this._open( newItem.parent() ); 11851 11852 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11853 this._delay(function() { 11854 this.focus( event, newItem ); 11855 }); 11856 } 11857 }, 11858 11859 next: function( event ) { 11860 this._move( "next", "first", event ); 11861 }, 11862 11863 previous: function( event ) { 11864 this._move( "prev", "last", event ); 11865 }, 11866 11867 isFirstItem: function() { 11868 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11869 }, 11870 11871 isLastItem: function() { 11872 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11873 }, 11874 11875 _move: function( direction, filter, event ) { 11876 var next; 11877 if ( this.active ) { 11878 if ( direction === "first" || direction === "last" ) { 11879 next = this.active 11880 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11881 .eq( -1 ); 11882 } else { 11883 next = this.active 11884 [ direction + "All" ]( ".ui-menu-item" ) 11885 .eq( 0 ); 11886 } 11887 } 11888 if ( !next || !next.length || !this.active ) { 11889 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11890 } 11891 11892 this.focus( event, next ); 11893 }, 11894 11895 nextPage: function( event ) { 11896 var item, base, height; 11897 11898 if ( !this.active ) { 11899 this.next( event ); 11900 return; 11901 } 11902 if ( this.isLastItem() ) { 11903 return; 11904 } 11905 if ( this._hasScroll() ) { 11906 base = this.active.offset().top; 11907 height = this.element.height(); 11908 this.active.nextAll( ".ui-menu-item" ).each(function() { 11909 item = $( this ); 11910 return item.offset().top - base - height < 0; 11911 }); 11912 11913 this.focus( event, item ); 11914 } else { 11915 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11916 [ !this.active ? "first" : "last" ]() ); 11917 } 11918 }, 11919 11920 previousPage: function( event ) { 11921 var item, base, height; 11922 if ( !this.active ) { 11923 this.next( event ); 11924 return; 11925 } 11926 if ( this.isFirstItem() ) { 11927 return; 11928 } 11929 if ( this._hasScroll() ) { 11930 base = this.active.offset().top; 11931 height = this.element.height(); 11932 this.active.prevAll( ".ui-menu-item" ).each(function() { 11933 item = $( this ); 11934 return item.offset().top - base + height > 0; 11935 }); 11936 11937 this.focus( event, item ); 11938 } else { 11939 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 11940 } 11941 }, 11942 11943 _hasScroll: function() { 11944 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 11945 }, 11946 11947 select: function( event ) { 11948 // TODO: It should never be possible to not have an active item at this 11949 // point, but the tests don't trigger mouseenter before click. 11950 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 11951 var ui = { item: this.active }; 11952 if ( !this.active.has( ".ui-menu" ).length ) { 11953 this.collapseAll( event, true ); 11954 } 11955 this._trigger( "select", event, ui ); 11956 } 11957}); 11958 11959}( jQuery )); 11960 11961(function( $, undefined ) { 11962 11963$.ui = $.ui || {}; 11964 11965var cachedScrollbarWidth, 11966 max = Math.max, 11967 abs = Math.abs, 11968 round = Math.round, 11969 rhorizontal = /left|center|right/, 11970 rvertical = /top|center|bottom/, 11971 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 11972 rposition = /^\w+/, 11973 rpercent = /%$/, 11974 _position = $.fn.position; 11975 11976function getOffsets( offsets, width, height ) { 11977 return [ 11978 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 11979 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 11980 ]; 11981} 11982 11983function parseCss( element, property ) { 11984 return parseInt( $.css( element, property ), 10 ) || 0; 11985} 11986 11987function getDimensions( elem ) { 11988 var raw = elem[0]; 11989 if ( raw.nodeType === 9 ) { 11990 return { 11991 width: elem.width(), 11992 height: elem.height(), 11993 offset: { top: 0, left: 0 } 11994 }; 11995 } 11996 if ( $.isWindow( raw ) ) { 11997 return { 11998 width: elem.width(), 11999 height: elem.height(), 12000 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 12001 }; 12002 } 12003 if ( raw.preventDefault ) { 12004 return { 12005 width: 0, 12006 height: 0, 12007 offset: { top: raw.pageY, left: raw.pageX } 12008 }; 12009 } 12010 return { 12011 width: elem.outerWidth(), 12012 height: elem.outerHeight(), 12013 offset: elem.offset() 12014 }; 12015} 12016 12017$.position = { 12018 scrollbarWidth: function() { 12019 if ( cachedScrollbarWidth !== undefined ) { 12020 return cachedScrollbarWidth; 12021 } 12022 var w1, w2, 12023 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 12024 innerDiv = div.children()[0]; 12025 12026 $( "body" ).append( div ); 12027 w1 = innerDiv.offsetWidth; 12028 div.css( "overflow", "scroll" ); 12029 12030 w2 = innerDiv.offsetWidth; 12031 12032 if ( w1 === w2 ) { 12033 w2 = div[0].clientWidth; 12034 } 12035 12036 div.remove(); 12037 12038 return (cachedScrollbarWidth = w1 - w2); 12039 }, 12040 getScrollInfo: function( within ) { 12041 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 12042 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 12043 hasOverflowX = overflowX === "scroll" || 12044 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 12045 hasOverflowY = overflowY === "scroll" || 12046 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 12047 return { 12048 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 12049 height: hasOverflowY ? $.position.scrollbarWidth() : 0 12050 }; 12051 }, 12052 getWithinInfo: function( element ) { 12053 var withinElement = $( element || window ), 12054 isWindow = $.isWindow( withinElement[0] ); 12055 return { 12056 element: withinElement, 12057 isWindow: isWindow, 12058 offset: withinElement.offset() || { left: 0, top: 0 }, 12059 scrollLeft: withinElement.scrollLeft(), 12060 scrollTop: withinElement.scrollTop(), 12061 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 12062 height: isWindow ? withinElement.height() : withinElement.outerHeight() 12063 }; 12064 } 12065}; 12066 12067$.fn.position = function( options ) { 12068 if ( !options || !options.of ) { 12069 return _position.apply( this, arguments ); 12070 } 12071 12072 // make a copy, we don't want to modify arguments 12073 options = $.extend( {}, options ); 12074 12075 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 12076 target = $( options.of ), 12077 within = $.position.getWithinInfo( options.within ), 12078 scrollInfo = $.position.getScrollInfo( within ), 12079 collision = ( options.collision || "flip" ).split( " " ), 12080 offsets = {}; 12081 12082 dimensions = getDimensions( target ); 12083 if ( target[0].preventDefault ) { 12084 // force left top to allow flipping 12085 options.at = "left top"; 12086 } 12087 targetWidth = dimensions.width; 12088 targetHeight = dimensions.height; 12089 targetOffset = dimensions.offset; 12090 // clone to reuse original targetOffset later 12091 basePosition = $.extend( {}, targetOffset ); 12092 12093 // force my and at to have valid horizontal and vertical positions 12094 // if a value is missing or invalid, it will be converted to center 12095 $.each( [ "my", "at" ], function() { 12096 var pos = ( options[ this ] || "" ).split( " " ), 12097 horizontalOffset, 12098 verticalOffset; 12099 12100 if ( pos.length === 1) { 12101 pos = rhorizontal.test( pos[ 0 ] ) ? 12102 pos.concat( [ "center" ] ) : 12103 rvertical.test( pos[ 0 ] ) ? 12104 [ "center" ].concat( pos ) : 12105 [ "center", "center" ]; 12106 } 12107 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 12108 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 12109 12110 // calculate offsets 12111 horizontalOffset = roffset.exec( pos[ 0 ] ); 12112 verticalOffset = roffset.exec( pos[ 1 ] ); 12113 offsets[ this ] = [ 12114 horizontalOffset ? horizontalOffset[ 0 ] : 0, 12115 verticalOffset ? verticalOffset[ 0 ] : 0 12116 ]; 12117 12118 // reduce to just the positions without the offsets 12119 options[ this ] = [ 12120 rposition.exec( pos[ 0 ] )[ 0 ], 12121 rposition.exec( pos[ 1 ] )[ 0 ] 12122 ]; 12123 }); 12124 12125 // normalize collision option 12126 if ( collision.length === 1 ) { 12127 collision[ 1 ] = collision[ 0 ]; 12128 } 12129 12130 if ( options.at[ 0 ] === "right" ) { 12131 basePosition.left += targetWidth; 12132 } else if ( options.at[ 0 ] === "center" ) { 12133 basePosition.left += targetWidth / 2; 12134 } 12135 12136 if ( options.at[ 1 ] === "bottom" ) { 12137 basePosition.top += targetHeight; 12138 } else if ( options.at[ 1 ] === "center" ) { 12139 basePosition.top += targetHeight / 2; 12140 } 12141 12142 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 12143 basePosition.left += atOffset[ 0 ]; 12144 basePosition.top += atOffset[ 1 ]; 12145 12146 return this.each(function() { 12147 var collisionPosition, using, 12148 elem = $( this ), 12149 elemWidth = elem.outerWidth(), 12150 elemHeight = elem.outerHeight(), 12151 marginLeft = parseCss( this, "marginLeft" ), 12152 marginTop = parseCss( this, "marginTop" ), 12153 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 12154 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 12155 position = $.extend( {}, basePosition ), 12156 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 12157 12158 if ( options.my[ 0 ] === "right" ) { 12159 position.left -= elemWidth; 12160 } else if ( options.my[ 0 ] === "center" ) { 12161 position.left -= elemWidth / 2; 12162 } 12163 12164 if ( options.my[ 1 ] === "bottom" ) { 12165 position.top -= elemHeight; 12166 } else if ( options.my[ 1 ] === "center" ) { 12167 position.top -= elemHeight / 2; 12168 } 12169 12170 position.left += myOffset[ 0 ]; 12171 position.top += myOffset[ 1 ]; 12172 12173 // if the browser doesn't support fractions, then round for consistent results 12174 if ( !$.support.offsetFractions ) { 12175 position.left = round( position.left ); 12176 position.top = round( position.top ); 12177 } 12178 12179 collisionPosition = { 12180 marginLeft: marginLeft, 12181 marginTop: marginTop 12182 }; 12183 12184 $.each( [ "left", "top" ], function( i, dir ) { 12185 if ( $.ui.position[ collision[ i ] ] ) { 12186 $.ui.position[ collision[ i ] ][ dir ]( position, { 12187 targetWidth: targetWidth, 12188 targetHeight: targetHeight, 12189 elemWidth: elemWidth, 12190 elemHeight: elemHeight, 12191 collisionPosition: collisionPosition, 12192 collisionWidth: collisionWidth, 12193 collisionHeight: collisionHeight, 12194 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 12195 my: options.my, 12196 at: options.at, 12197 within: within, 12198 elem : elem 12199 }); 12200 } 12201 }); 12202 12203 if ( options.using ) { 12204 // adds feedback as second argument to using callback, if present 12205 using = function( props ) { 12206 var left = targetOffset.left - position.left, 12207 right = left + targetWidth - elemWidth, 12208 top = targetOffset.top - position.top, 12209 bottom = top + targetHeight - elemHeight, 12210 feedback = { 12211 target: { 12212 element: target, 12213 left: targetOffset.left, 12214 top: targetOffset.top, 12215 width: targetWidth, 12216 height: targetHeight 12217 }, 12218 element: { 12219 element: elem, 12220 left: position.left, 12221 top: position.top, 12222 width: elemWidth, 12223 height: elemHeight 12224 }, 12225 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 12226 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 12227 }; 12228 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 12229 feedback.horizontal = "center"; 12230 } 12231 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 12232 feedback.vertical = "middle"; 12233 } 12234 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 12235 feedback.important = "horizontal"; 12236 } else { 12237 feedback.important = "vertical"; 12238 } 12239 options.using.call( this, props, feedback ); 12240 }; 12241 } 12242 12243 elem.offset( $.extend( position, { using: using } ) ); 12244 }); 12245}; 12246 12247$.ui.position = { 12248 fit: { 12249 left: function( position, data ) { 12250 var within = data.within, 12251 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 12252 outerWidth = within.width, 12253 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12254 overLeft = withinOffset - collisionPosLeft, 12255 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 12256 newOverRight; 12257 12258 // element is wider than within 12259 if ( data.collisionWidth > outerWidth ) { 12260 // element is initially over the left side of within 12261 if ( overLeft > 0 && overRight <= 0 ) { 12262 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 12263 position.left += overLeft - newOverRight; 12264 // element is initially over right side of within 12265 } else if ( overRight > 0 && overLeft <= 0 ) { 12266 position.left = withinOffset; 12267 // element is initially over both left and right sides of within 12268 } else { 12269 if ( overLeft > overRight ) { 12270 position.left = withinOffset + outerWidth - data.collisionWidth; 12271 } else { 12272 position.left = withinOffset; 12273 } 12274 } 12275 // too far left -> align with left edge 12276 } else if ( overLeft > 0 ) { 12277 position.left += overLeft; 12278 // too far right -> align with right edge 12279 } else if ( overRight > 0 ) { 12280 position.left -= overRight; 12281 // adjust based on position and margin 12282 } else { 12283 position.left = max( position.left - collisionPosLeft, position.left ); 12284 } 12285 }, 12286 top: function( position, data ) { 12287 var within = data.within, 12288 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 12289 outerHeight = data.within.height, 12290 collisionPosTop = position.top - data.collisionPosition.marginTop, 12291 overTop = withinOffset - collisionPosTop, 12292 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 12293 newOverBottom; 12294 12295 // element is taller than within 12296 if ( data.collisionHeight > outerHeight ) { 12297 // element is initially over the top of within 12298 if ( overTop > 0 && overBottom <= 0 ) { 12299 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 12300 position.top += overTop - newOverBottom; 12301 // element is initially over bottom of within 12302 } else if ( overBottom > 0 && overTop <= 0 ) { 12303 position.top = withinOffset; 12304 // element is initially over both top and bottom of within 12305 } else { 12306 if ( overTop > overBottom ) { 12307 position.top = withinOffset + outerHeight - data.collisionHeight; 12308 } else { 12309 position.top = withinOffset; 12310 } 12311 } 12312 // too far up -> align with top 12313 } else if ( overTop > 0 ) { 12314 position.top += overTop; 12315 // too far down -> align with bottom edge 12316 } else if ( overBottom > 0 ) { 12317 position.top -= overBottom; 12318 // adjust based on position and margin 12319 } else { 12320 position.top = max( position.top - collisionPosTop, position.top ); 12321 } 12322 } 12323 }, 12324 flip: { 12325 left: function( position, data ) { 12326 var within = data.within, 12327 withinOffset = within.offset.left + within.scrollLeft, 12328 outerWidth = within.width, 12329 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12330 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12331 overLeft = collisionPosLeft - offsetLeft, 12332 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12333 myOffset = data.my[ 0 ] === "left" ? 12334 -data.elemWidth : 12335 data.my[ 0 ] === "right" ? 12336 data.elemWidth : 12337 0, 12338 atOffset = data.at[ 0 ] === "left" ? 12339 data.targetWidth : 12340 data.at[ 0 ] === "right" ? 12341 -data.targetWidth : 12342 0, 12343 offset = -2 * data.offset[ 0 ], 12344 newOverRight, 12345 newOverLeft; 12346 12347 if ( overLeft < 0 ) { 12348 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 12349 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12350 position.left += myOffset + atOffset + offset; 12351 } 12352 } 12353 else if ( overRight > 0 ) { 12354 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 12355 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12356 position.left += myOffset + atOffset + offset; 12357 } 12358 } 12359 }, 12360 top: function( position, data ) { 12361 var within = data.within, 12362 withinOffset = within.offset.top + within.scrollTop, 12363 outerHeight = within.height, 12364 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12365 collisionPosTop = position.top - data.collisionPosition.marginTop, 12366 overTop = collisionPosTop - offsetTop, 12367 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12368 top = data.my[ 1 ] === "top", 12369 myOffset = top ? 12370 -data.elemHeight : 12371 data.my[ 1 ] === "bottom" ? 12372 data.elemHeight : 12373 0, 12374 atOffset = data.at[ 1 ] === "top" ? 12375 data.targetHeight : 12376 data.at[ 1 ] === "bottom" ? 12377 -data.targetHeight : 12378 0, 12379 offset = -2 * data.offset[ 1 ], 12380 newOverTop, 12381 newOverBottom; 12382 if ( overTop < 0 ) { 12383 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 12384 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 12385 position.top += myOffset + atOffset + offset; 12386 } 12387 } 12388 else if ( overBottom > 0 ) { 12389 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 12390 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 12391 position.top += myOffset + atOffset + offset; 12392 } 12393 } 12394 } 12395 }, 12396 flipfit: { 12397 left: function() { 12398 $.ui.position.flip.left.apply( this, arguments ); 12399 $.ui.position.fit.left.apply( this, arguments ); 12400 }, 12401 top: function() { 12402 $.ui.position.flip.top.apply( this, arguments ); 12403 $.ui.position.fit.top.apply( this, arguments ); 12404 } 12405 } 12406}; 12407 12408// fraction support test 12409(function () { 12410 var testElement, testElementParent, testElementStyle, offsetLeft, i, 12411 body = document.getElementsByTagName( "body" )[ 0 ], 12412 div = document.createElement( "div" ); 12413 12414 //Create a "fake body" for testing based on method used in jQuery.support 12415 testElement = document.createElement( body ? "div" : "body" ); 12416 testElementStyle = { 12417 visibility: "hidden", 12418 width: 0, 12419 height: 0, 12420 border: 0, 12421 margin: 0, 12422 background: "none" 12423 }; 12424 if ( body ) { 12425 $.extend( testElementStyle, { 12426 position: "absolute", 12427 left: "-1000px", 12428 top: "-1000px" 12429 }); 12430 } 12431 for ( i in testElementStyle ) { 12432 testElement.style[ i ] = testElementStyle[ i ]; 12433 } 12434 testElement.appendChild( div ); 12435 testElementParent = body || document.documentElement; 12436 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 12437 12438 div.style.cssText = "position: absolute; left: 10.7432222px;"; 12439 12440 offsetLeft = $( div ).offset().left; 12441 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 12442 12443 testElement.innerHTML = ""; 12444 testElementParent.removeChild( testElement ); 12445})(); 12446 12447}( jQuery ) ); 12448 12449(function( $, undefined ) { 12450 12451$.widget( "ui.progressbar", { 12452 version: "1.10.1", 12453 options: { 12454 max: 100, 12455 value: 0, 12456 12457 change: null, 12458 complete: null 12459 }, 12460 12461 min: 0, 12462 12463 _create: function() { 12464 // Constrain initial value 12465 this.oldValue = this.options.value = this._constrainedValue(); 12466 12467 this.element 12468 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12469 .attr({ 12470 // Only set static values, aria-valuenow and aria-valuemax are 12471 // set inside _refreshValue() 12472 role: "progressbar", 12473 "aria-valuemin": this.min 12474 }); 12475 12476 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12477 .appendTo( this.element ); 12478 12479 this._refreshValue(); 12480 }, 12481 12482 _destroy: function() { 12483 this.element 12484 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12485 .removeAttr( "role" ) 12486 .removeAttr( "aria-valuemin" ) 12487 .removeAttr( "aria-valuemax" ) 12488 .removeAttr( "aria-valuenow" ); 12489 12490 this.valueDiv.remove(); 12491 }, 12492 12493 value: function( newValue ) { 12494 if ( newValue === undefined ) { 12495 return this.options.value; 12496 } 12497 12498 this.options.value = this._constrainedValue( newValue ); 12499 this._refreshValue(); 12500 }, 12501 12502 _constrainedValue: function( newValue ) { 12503 if ( newValue === undefined ) { 12504 newValue = this.options.value; 12505 } 12506 12507 this.indeterminate = newValue === false; 12508 12509 // sanitize value 12510 if ( typeof newValue !== "number" ) { 12511 newValue = 0; 12512 } 12513 12514 return this.indeterminate ? false : 12515 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12516 }, 12517 12518 _setOptions: function( options ) { 12519 // Ensure "value" option is set after other values (like max) 12520 var value = options.value; 12521 delete options.value; 12522 12523 this._super( options ); 12524 12525 this.options.value = this._constrainedValue( value ); 12526 this._refreshValue(); 12527 }, 12528 12529 _setOption: function( key, value ) { 12530 if ( key === "max" ) { 12531 // Don't allow a max less than min 12532 value = Math.max( this.min, value ); 12533 } 12534 12535 this._super( key, value ); 12536 }, 12537 12538 _percentage: function() { 12539 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12540 }, 12541 12542 _refreshValue: function() { 12543 var value = this.options.value, 12544 percentage = this._percentage(); 12545 12546 this.valueDiv 12547 .toggle( this.indeterminate || value > this.min ) 12548 .toggleClass( "ui-corner-right", value === this.options.max ) 12549 .width( percentage.toFixed(0) + "%" ); 12550 12551 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12552 12553 if ( this.indeterminate ) { 12554 this.element.removeAttr( "aria-valuenow" ); 12555 if ( !this.overlayDiv ) { 12556 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12557 } 12558 } else { 12559 this.element.attr({ 12560 "aria-valuemax": this.options.max, 12561 "aria-valuenow": value 12562 }); 12563 if ( this.overlayDiv ) { 12564 this.overlayDiv.remove(); 12565 this.overlayDiv = null; 12566 } 12567 } 12568 12569 if ( this.oldValue !== value ) { 12570 this.oldValue = value; 12571 this._trigger( "change" ); 12572 } 12573 if ( value === this.options.max ) { 12574 this._trigger( "complete" ); 12575 } 12576 } 12577}); 12578 12579})( jQuery ); 12580 12581(function( $, undefined ) { 12582 12583// number of pages in a slider 12584// (how many times can you page up/down to go through the whole range) 12585var numPages = 5; 12586 12587$.widget( "ui.slider", $.ui.mouse, { 12588 version: "1.10.1", 12589 widgetEventPrefix: "slide", 12590 12591 options: { 12592 animate: false, 12593 distance: 0, 12594 max: 100, 12595 min: 0, 12596 orientation: "horizontal", 12597 range: false, 12598 step: 1, 12599 value: 0, 12600 values: null, 12601 12602 // callbacks 12603 change: null, 12604 slide: null, 12605 start: null, 12606 stop: null 12607 }, 12608 12609 _create: function() { 12610 this._keySliding = false; 12611 this._mouseSliding = false; 12612 this._animateOff = true; 12613 this._handleIndex = null; 12614 this._detectOrientation(); 12615 this._mouseInit(); 12616 12617 this.element 12618 .addClass( "ui-slider" + 12619 " ui-slider-" + this.orientation + 12620 " ui-widget" + 12621 " ui-widget-content" + 12622 " ui-corner-all"); 12623 12624 this._refresh(); 12625 this._setOption( "disabled", this.options.disabled ); 12626 12627 this._animateOff = false; 12628 }, 12629 12630 _refresh: function() { 12631 this._createRange(); 12632 this._createHandles(); 12633 this._setupEvents(); 12634 this._refreshValue(); 12635 }, 12636 12637 _createHandles: function() { 12638 var i, handleCount, 12639 options = this.options, 12640 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12641 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12642 handles = []; 12643 12644 handleCount = ( options.values && options.values.length ) || 1; 12645 12646 if ( existingHandles.length > handleCount ) { 12647 existingHandles.slice( handleCount ).remove(); 12648 existingHandles = existingHandles.slice( 0, handleCount ); 12649 } 12650 12651 for ( i = existingHandles.length; i < handleCount; i++ ) { 12652 handles.push( handle ); 12653 } 12654 12655 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12656 12657 this.handle = this.handles.eq( 0 ); 12658 12659 this.handles.each(function( i ) { 12660 $( this ).data( "ui-slider-handle-index", i ); 12661 }); 12662 }, 12663 12664 _createRange: function() { 12665 var options = this.options, 12666 classes = ""; 12667 12668 if ( options.range ) { 12669 if ( options.range === true ) { 12670 if ( !options.values ) { 12671 options.values = [ this._valueMin(), this._valueMin() ]; 12672 } else if ( options.values.length && options.values.length !== 2 ) { 12673 options.values = [ options.values[0], options.values[0] ]; 12674 } else if ( $.isArray( options.values ) ) { 12675 options.values = options.values.slice(0); 12676 } 12677 } 12678 12679 if ( !this.range || !this.range.length ) { 12680 this.range = $( "<div></div>" ) 12681 .appendTo( this.element ); 12682 12683 classes = "ui-slider-range" + 12684 // note: this isn't the most fittingly semantic framework class for this element, 12685 // but worked best visually with a variety of themes 12686 " ui-widget-header ui-corner-all"; 12687 } else { 12688 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12689 // Handle range switching from true to min/max 12690 .css({ 12691 "left": "", 12692 "bottom": "" 12693 }); 12694 } 12695 12696 this.range.addClass( classes + 12697 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12698 } else { 12699 this.range = $([]); 12700 } 12701 }, 12702 12703 _setupEvents: function() { 12704 var elements = this.handles.add( this.range ).filter( "a" ); 12705 this._off( elements ); 12706 this._on( elements, this._handleEvents ); 12707 this._hoverable( elements ); 12708 this._focusable( elements ); 12709 }, 12710 12711 _destroy: function() { 12712 this.handles.remove(); 12713 this.range.remove(); 12714 12715 this.element 12716 .removeClass( "ui-slider" + 12717 " ui-slider-horizontal" + 12718 " ui-slider-vertical" + 12719 " ui-widget" + 12720 " ui-widget-content" + 12721 " ui-corner-all" ); 12722 12723 this._mouseDestroy(); 12724 }, 12725 12726 _mouseCapture: function( event ) { 12727 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12728 that = this, 12729 o = this.options; 12730 12731 if ( o.disabled ) { 12732 return false; 12733 } 12734 12735 this.elementSize = { 12736 width: this.element.outerWidth(), 12737 height: this.element.outerHeight() 12738 }; 12739 this.elementOffset = this.element.offset(); 12740 12741 position = { x: event.pageX, y: event.pageY }; 12742 normValue = this._normValueFromMouse( position ); 12743 distance = this._valueMax() - this._valueMin() + 1; 12744 this.handles.each(function( i ) { 12745 var thisDistance = Math.abs( normValue - that.values(i) ); 12746 if (( distance > thisDistance ) || 12747 ( distance === thisDistance && 12748 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12749 distance = thisDistance; 12750 closestHandle = $( this ); 12751 index = i; 12752 } 12753 }); 12754 12755 allowed = this._start( event, index ); 12756 if ( allowed === false ) { 12757 return false; 12758 } 12759 this._mouseSliding = true; 12760 12761 this._handleIndex = index; 12762 12763 closestHandle 12764 .addClass( "ui-state-active" ) 12765 .focus(); 12766 12767 offset = closestHandle.offset(); 12768 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12769 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12770 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12771 top: event.pageY - offset.top - 12772 ( closestHandle.height() / 2 ) - 12773 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12774 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12775 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12776 }; 12777 12778 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12779 this._slide( event, index, normValue ); 12780 } 12781 this._animateOff = true; 12782 return true; 12783 }, 12784 12785 _mouseStart: function() { 12786 return true; 12787 }, 12788 12789 _mouseDrag: function( event ) { 12790 var position = { x: event.pageX, y: event.pageY }, 12791 normValue = this._normValueFromMouse( position ); 12792 12793 this._slide( event, this._handleIndex, normValue ); 12794 12795 return false; 12796 }, 12797 12798 _mouseStop: function( event ) { 12799 this.handles.removeClass( "ui-state-active" ); 12800 this._mouseSliding = false; 12801 12802 this._stop( event, this._handleIndex ); 12803 this._change( event, this._handleIndex ); 12804 12805 this._handleIndex = null; 12806 this._clickOffset = null; 12807 this._animateOff = false; 12808 12809 return false; 12810 }, 12811 12812 _detectOrientation: function() { 12813 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12814 }, 12815 12816 _normValueFromMouse: function( position ) { 12817 var pixelTotal, 12818 pixelMouse, 12819 percentMouse, 12820 valueTotal, 12821 valueMouse; 12822 12823 if ( this.orientation === "horizontal" ) { 12824 pixelTotal = this.elementSize.width; 12825 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12826 } else { 12827 pixelTotal = this.elementSize.height; 12828 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12829 } 12830 12831 percentMouse = ( pixelMouse / pixelTotal ); 12832 if ( percentMouse > 1 ) { 12833 percentMouse = 1; 12834 } 12835 if ( percentMouse < 0 ) { 12836 percentMouse = 0; 12837 } 12838 if ( this.orientation === "vertical" ) { 12839 percentMouse = 1 - percentMouse; 12840 } 12841 12842 valueTotal = this._valueMax() - this._valueMin(); 12843 valueMouse = this._valueMin() + percentMouse * valueTotal; 12844 12845 return this._trimAlignValue( valueMouse ); 12846 }, 12847 12848 _start: function( event, index ) { 12849 var uiHash = { 12850 handle: this.handles[ index ], 12851 value: this.value() 12852 }; 12853 if ( this.options.values && this.options.values.length ) { 12854 uiHash.value = this.values( index ); 12855 uiHash.values = this.values(); 12856 } 12857 return this._trigger( "start", event, uiHash ); 12858 }, 12859 12860 _slide: function( event, index, newVal ) { 12861 var otherVal, 12862 newValues, 12863 allowed; 12864 12865 if ( this.options.values && this.options.values.length ) { 12866 otherVal = this.values( index ? 0 : 1 ); 12867 12868 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12869 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12870 ) { 12871 newVal = otherVal; 12872 } 12873 12874 if ( newVal !== this.values( index ) ) { 12875 newValues = this.values(); 12876 newValues[ index ] = newVal; 12877 // A slide can be canceled by returning false from the slide callback 12878 allowed = this._trigger( "slide", event, { 12879 handle: this.handles[ index ], 12880 value: newVal, 12881 values: newValues 12882 } ); 12883 otherVal = this.values( index ? 0 : 1 ); 12884 if ( allowed !== false ) { 12885 this.values( index, newVal, true ); 12886 } 12887 } 12888 } else { 12889 if ( newVal !== this.value() ) { 12890 // A slide can be canceled by returning false from the slide callback 12891 allowed = this._trigger( "slide", event, { 12892 handle: this.handles[ index ], 12893 value: newVal 12894 } ); 12895 if ( allowed !== false ) { 12896 this.value( newVal ); 12897 } 12898 } 12899 } 12900 }, 12901 12902 _stop: function( event, index ) { 12903 var uiHash = { 12904 handle: this.handles[ index ], 12905 value: this.value() 12906 }; 12907 if ( this.options.values && this.options.values.length ) { 12908 uiHash.value = this.values( index ); 12909 uiHash.values = this.values(); 12910 } 12911 12912 this._trigger( "stop", event, uiHash ); 12913 }, 12914 12915 _change: function( event, index ) { 12916 if ( !this._keySliding && !this._mouseSliding ) { 12917 var uiHash = { 12918 handle: this.handles[ index ], 12919 value: this.value() 12920 }; 12921 if ( this.options.values && this.options.values.length ) { 12922 uiHash.value = this.values( index ); 12923 uiHash.values = this.values(); 12924 } 12925 12926 //store the last changed value index for reference when handles overlap 12927 this._lastChangedValue = index; 12928 12929 this._trigger( "change", event, uiHash ); 12930 } 12931 }, 12932 12933 value: function( newValue ) { 12934 if ( arguments.length ) { 12935 this.options.value = this._trimAlignValue( newValue ); 12936 this._refreshValue(); 12937 this._change( null, 0 ); 12938 return; 12939 } 12940 12941 return this._value(); 12942 }, 12943 12944 values: function( index, newValue ) { 12945 var vals, 12946 newValues, 12947 i; 12948 12949 if ( arguments.length > 1 ) { 12950 this.options.values[ index ] = this._trimAlignValue( newValue ); 12951 this._refreshValue(); 12952 this._change( null, index ); 12953 return; 12954 } 12955 12956 if ( arguments.length ) { 12957 if ( $.isArray( arguments[ 0 ] ) ) { 12958 vals = this.options.values; 12959 newValues = arguments[ 0 ]; 12960 for ( i = 0; i < vals.length; i += 1 ) { 12961 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 12962 this._change( null, i ); 12963 } 12964 this._refreshValue(); 12965 } else { 12966 if ( this.options.values && this.options.values.length ) { 12967 return this._values( index ); 12968 } else { 12969 return this.value(); 12970 } 12971 } 12972 } else { 12973 return this._values(); 12974 } 12975 }, 12976 12977 _setOption: function( key, value ) { 12978 var i, 12979 valsLength = 0; 12980 12981 if ( key === "range" && this.options.range === true ) { 12982 if ( value === "min" ) { 12983 this.options.value = this._values( 0 ); 12984 this.options.values = null; 12985 } else if ( value === "max" ) { 12986 this.options.value = this._values( this.options.values.length-1 ); 12987 this.options.values = null; 12988 } 12989 } 12990 12991 if ( $.isArray( this.options.values ) ) { 12992 valsLength = this.options.values.length; 12993 } 12994 12995 $.Widget.prototype._setOption.apply( this, arguments ); 12996 12997 switch ( key ) { 12998 case "orientation": 12999 this._detectOrientation(); 13000 this.element 13001 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13002 .addClass( "ui-slider-" + this.orientation ); 13003 this._refreshValue(); 13004 break; 13005 case "value": 13006 this._animateOff = true; 13007 this._refreshValue(); 13008 this._change( null, 0 ); 13009 this._animateOff = false; 13010 break; 13011 case "values": 13012 this._animateOff = true; 13013 this._refreshValue(); 13014 for ( i = 0; i < valsLength; i += 1 ) { 13015 this._change( null, i ); 13016 } 13017 this._animateOff = false; 13018 break; 13019 case "min": 13020 case "max": 13021 this._animateOff = true; 13022 this._refreshValue(); 13023 this._animateOff = false; 13024 break; 13025 case "range": 13026 this._animateOff = true; 13027 this._refresh(); 13028 this._animateOff = false; 13029 break; 13030 } 13031 }, 13032 13033 //internal value getter 13034 // _value() returns value trimmed by min and max, aligned by step 13035 _value: function() { 13036 var val = this.options.value; 13037 val = this._trimAlignValue( val ); 13038 13039 return val; 13040 }, 13041 13042 //internal values getter 13043 // _values() returns array of values trimmed by min and max, aligned by step 13044 // _values( index ) returns single value trimmed by min and max, aligned by step 13045 _values: function( index ) { 13046 var val, 13047 vals, 13048 i; 13049 13050 if ( arguments.length ) { 13051 val = this.options.values[ index ]; 13052 val = this._trimAlignValue( val ); 13053 13054 return val; 13055 } else if ( this.options.values && this.options.values.length ) { 13056 // .slice() creates a copy of the array 13057 // this copy gets trimmed by min and max and then returned 13058 vals = this.options.values.slice(); 13059 for ( i = 0; i < vals.length; i+= 1) { 13060 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13061 } 13062 13063 return vals; 13064 } else { 13065 return []; 13066 } 13067 }, 13068 13069 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13070 _trimAlignValue: function( val ) { 13071 if ( val <= this._valueMin() ) { 13072 return this._valueMin(); 13073 } 13074 if ( val >= this._valueMax() ) { 13075 return this._valueMax(); 13076 } 13077 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13078 valModStep = (val - this._valueMin()) % step, 13079 alignValue = val - valModStep; 13080 13081 if ( Math.abs(valModStep) * 2 >= step ) { 13082 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13083 } 13084 13085 // Since JavaScript has problems with large floats, round 13086 // the final value to 5 digits after the decimal point (see #4124) 13087 return parseFloat( alignValue.toFixed(5) ); 13088 }, 13089 13090 _valueMin: function() { 13091 return this.options.min; 13092 }, 13093 13094 _valueMax: function() { 13095 return this.options.max; 13096 }, 13097 13098 _refreshValue: function() { 13099 var lastValPercent, valPercent, value, valueMin, valueMax, 13100 oRange = this.options.range, 13101 o = this.options, 13102 that = this, 13103 animate = ( !this._animateOff ) ? o.animate : false, 13104 _set = {}; 13105 13106 if ( this.options.values && this.options.values.length ) { 13107 this.handles.each(function( i ) { 13108 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13109 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13110 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13111 if ( that.options.range === true ) { 13112 if ( that.orientation === "horizontal" ) { 13113 if ( i === 0 ) { 13114 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13115 } 13116 if ( i === 1 ) { 13117 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13118 } 13119 } else { 13120 if ( i === 0 ) { 13121 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13122 } 13123 if ( i === 1 ) { 13124 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13125 } 13126 } 13127 } 13128 lastValPercent = valPercent; 13129 }); 13130 } else { 13131 value = this.value(); 13132 valueMin = this._valueMin(); 13133 valueMax = this._valueMax(); 13134 valPercent = ( valueMax !== valueMin ) ? 13135 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13136 0; 13137 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13138 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13139 13140 if ( oRange === "min" && this.orientation === "horizontal" ) { 13141 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13142 } 13143 if ( oRange === "max" && this.orientation === "horizontal" ) { 13144 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13145 } 13146 if ( oRange === "min" && this.orientation === "vertical" ) { 13147 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13148 } 13149 if ( oRange === "max" && this.orientation === "vertical" ) { 13150 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13151 } 13152 } 13153 }, 13154 13155 _handleEvents: { 13156 keydown: function( event ) { 13157 /*jshint maxcomplexity:25*/ 13158 var allowed, curVal, newVal, step, 13159 index = $( event.target ).data( "ui-slider-handle-index" ); 13160 13161 switch ( event.keyCode ) { 13162 case $.ui.keyCode.HOME: 13163 case $.ui.keyCode.END: 13164 case $.ui.keyCode.PAGE_UP: 13165 case $.ui.keyCode.PAGE_DOWN: 13166 case $.ui.keyCode.UP: 13167 case $.ui.keyCode.RIGHT: 13168 case $.ui.keyCode.DOWN: 13169 case $.ui.keyCode.LEFT: 13170 event.preventDefault(); 13171 if ( !this._keySliding ) { 13172 this._keySliding = true; 13173 $( event.target ).addClass( "ui-state-active" ); 13174 allowed = this._start( event, index ); 13175 if ( allowed === false ) { 13176 return; 13177 } 13178 } 13179 break; 13180 } 13181 13182 step = this.options.step; 13183 if ( this.options.values && this.options.values.length ) { 13184 curVal = newVal = this.values( index ); 13185 } else { 13186 curVal = newVal = this.value(); 13187 } 13188 13189 switch ( event.keyCode ) { 13190 case $.ui.keyCode.HOME: 13191 newVal = this._valueMin(); 13192 break; 13193 case $.ui.keyCode.END: 13194 newVal = this._valueMax(); 13195 break; 13196 case $.ui.keyCode.PAGE_UP: 13197 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13198 break; 13199 case $.ui.keyCode.PAGE_DOWN: 13200 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13201 break; 13202 case $.ui.keyCode.UP: 13203 case $.ui.keyCode.RIGHT: 13204 if ( curVal === this._valueMax() ) { 13205 return; 13206 } 13207 newVal = this._trimAlignValue( curVal + step ); 13208 break; 13209 case $.ui.keyCode.DOWN: 13210 case $.ui.keyCode.LEFT: 13211 if ( curVal === this._valueMin() ) { 13212 return; 13213 } 13214 newVal = this._trimAlignValue( curVal - step ); 13215 break; 13216 } 13217 13218 this._slide( event, index, newVal ); 13219 }, 13220 click: function( event ) { 13221 event.preventDefault(); 13222 }, 13223 keyup: function( event ) { 13224 var index = $( event.target ).data( "ui-slider-handle-index" ); 13225 13226 if ( this._keySliding ) { 13227 this._keySliding = false; 13228 this._stop( event, index ); 13229 this._change( event, index ); 13230 $( event.target ).removeClass( "ui-state-active" ); 13231 } 13232 } 13233 } 13234 13235}); 13236 13237}(jQuery)); 13238 13239(function( $ ) { 13240 13241function modifier( fn ) { 13242 return function() { 13243 var previous = this.element.val(); 13244 fn.apply( this, arguments ); 13245 this._refresh(); 13246 if ( previous !== this.element.val() ) { 13247 this._trigger( "change" ); 13248 } 13249 }; 13250} 13251 13252$.widget( "ui.spinner", { 13253 version: "1.10.1", 13254 defaultElement: "<input>", 13255 widgetEventPrefix: "spin", 13256 options: { 13257 culture: null, 13258 icons: { 13259 down: "ui-icon-triangle-1-s", 13260 up: "ui-icon-triangle-1-n" 13261 }, 13262 incremental: true, 13263 max: null, 13264 min: null, 13265 numberFormat: null, 13266 page: 10, 13267 step: 1, 13268 13269 change: null, 13270 spin: null, 13271 start: null, 13272 stop: null 13273 }, 13274 13275 _create: function() { 13276 // handle string values that need to be parsed 13277 this._setOption( "max", this.options.max ); 13278 this._setOption( "min", this.options.min ); 13279 this._setOption( "step", this.options.step ); 13280 13281 // format the value, but don't constrain 13282 this._value( this.element.val(), true ); 13283 13284 this._draw(); 13285 this._on( this._events ); 13286 this._refresh(); 13287 13288 // turning off autocomplete prevents the browser from remembering the 13289 // value when navigating through history, so we re-enable autocomplete 13290 // if the page is unloaded before the widget is destroyed. #7790 13291 this._on( this.window, { 13292 beforeunload: function() { 13293 this.element.removeAttr( "autocomplete" ); 13294 } 13295 }); 13296 }, 13297 13298 _getCreateOptions: function() { 13299 var options = {}, 13300 element = this.element; 13301 13302 $.each( [ "min", "max", "step" ], function( i, option ) { 13303 var value = element.attr( option ); 13304 if ( value !== undefined && value.length ) { 13305 options[ option ] = value; 13306 } 13307 }); 13308 13309 return options; 13310 }, 13311 13312 _events: { 13313 keydown: function( event ) { 13314 if ( this._start( event ) && this._keydown( event ) ) { 13315 event.preventDefault(); 13316 } 13317 }, 13318 keyup: "_stop", 13319 focus: function() { 13320 this.previous = this.element.val(); 13321 }, 13322 blur: function( event ) { 13323 if ( this.cancelBlur ) { 13324 delete this.cancelBlur; 13325 return; 13326 } 13327 13328 this._refresh(); 13329 if ( this.previous !== this.element.val() ) { 13330 this._trigger( "change", event ); 13331 } 13332 }, 13333 mousewheel: function( event, delta ) { 13334 if ( !delta ) { 13335 return; 13336 } 13337 if ( !this.spinning && !this._start( event ) ) { 13338 return false; 13339 } 13340 13341 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13342 clearTimeout( this.mousewheelTimer ); 13343 this.mousewheelTimer = this._delay(function() { 13344 if ( this.spinning ) { 13345 this._stop( event ); 13346 } 13347 }, 100 ); 13348 event.preventDefault(); 13349 }, 13350 "mousedown .ui-spinner-button": function( event ) { 13351 var previous; 13352 13353 // We never want the buttons to have focus; whenever the user is 13354 // interacting with the spinner, the focus should be on the input. 13355 // If the input is focused then this.previous is properly set from 13356 // when the input first received focus. If the input is not focused 13357 // then we need to set this.previous based on the value before spinning. 13358 previous = this.element[0] === this.document[0].activeElement ? 13359 this.previous : this.element.val(); 13360 function checkFocus() { 13361 var isActive = this.element[0] === this.document[0].activeElement; 13362 if ( !isActive ) { 13363 this.element.focus(); 13364 this.previous = previous; 13365 // support: IE 13366 // IE sets focus asynchronously, so we need to check if focus 13367 // moved off of the input because the user clicked on the button. 13368 this._delay(function() { 13369 this.previous = previous; 13370 }); 13371 } 13372 } 13373 13374 // ensure focus is on (or stays on) the text field 13375 event.preventDefault(); 13376 checkFocus.call( this ); 13377 13378 // support: IE 13379 // IE doesn't prevent moving focus even with event.preventDefault() 13380 // so we set a flag to know when we should ignore the blur event 13381 // and check (again) if focus moved off of the input. 13382 this.cancelBlur = true; 13383 this._delay(function() { 13384 delete this.cancelBlur; 13385 checkFocus.call( this ); 13386 }); 13387 13388 if ( this._start( event ) === false ) { 13389 return; 13390 } 13391 13392 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13393 }, 13394 "mouseup .ui-spinner-button": "_stop", 13395 "mouseenter .ui-spinner-button": function( event ) { 13396 // button will add ui-state-active if mouse was down while mouseleave and kept down 13397 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13398 return; 13399 } 13400 13401 if ( this._start( event ) === false ) { 13402 return false; 13403 } 13404 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13405 }, 13406 // TODO: do we really want to consider this a stop? 13407 // shouldn't we just stop the repeater and wait until mouseup before 13408 // we trigger the stop event? 13409 "mouseleave .ui-spinner-button": "_stop" 13410 }, 13411 13412 _draw: function() { 13413 var uiSpinner = this.uiSpinner = this.element 13414 .addClass( "ui-spinner-input" ) 13415 .attr( "autocomplete", "off" ) 13416 .wrap( this._uiSpinnerHtml() ) 13417 .parent() 13418 // add buttons 13419 .append( this._buttonHtml() ); 13420 13421 this.element.attr( "role", "spinbutton" ); 13422 13423 // button bindings 13424 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13425 .attr( "tabIndex", -1 ) 13426 .button() 13427 .removeClass( "ui-corner-all" ); 13428 13429 // IE 6 doesn't understand height: 50% for the buttons 13430 // unless the wrapper has an explicit height 13431 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13432 uiSpinner.height() > 0 ) { 13433 uiSpinner.height( uiSpinner.height() ); 13434 } 13435 13436 // disable spinner if element was already disabled 13437 if ( this.options.disabled ) { 13438 this.disable(); 13439 } 13440 }, 13441 13442 _keydown: function( event ) { 13443 var options = this.options, 13444 keyCode = $.ui.keyCode; 13445 13446 switch ( event.keyCode ) { 13447 case keyCode.UP: 13448 this._repeat( null, 1, event ); 13449 return true; 13450 case keyCode.DOWN: 13451 this._repeat( null, -1, event ); 13452 return true; 13453 case keyCode.PAGE_UP: 13454 this._repeat( null, options.page, event ); 13455 return true; 13456 case keyCode.PAGE_DOWN: 13457 this._repeat( null, -options.page, event ); 13458 return true; 13459 } 13460 13461 return false; 13462 }, 13463 13464 _uiSpinnerHtml: function() { 13465 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13466 }, 13467 13468 _buttonHtml: function() { 13469 return "" + 13470 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13471 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13472 "</a>" + 13473 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13474 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13475 "</a>"; 13476 }, 13477 13478 _start: function( event ) { 13479 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13480 return false; 13481 } 13482 13483 if ( !this.counter ) { 13484 this.counter = 1; 13485 } 13486 this.spinning = true; 13487 return true; 13488 }, 13489 13490 _repeat: function( i, steps, event ) { 13491 i = i || 500; 13492 13493 clearTimeout( this.timer ); 13494 this.timer = this._delay(function() { 13495 this._repeat( 40, steps, event ); 13496 }, i ); 13497 13498 this._spin( steps * this.options.step, event ); 13499 }, 13500 13501 _spin: function( step, event ) { 13502 var value = this.value() || 0; 13503 13504 if ( !this.counter ) { 13505 this.counter = 1; 13506 } 13507 13508 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13509 13510 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13511 this._value( value ); 13512 this.counter++; 13513 } 13514 }, 13515 13516 _increment: function( i ) { 13517 var incremental = this.options.incremental; 13518 13519 if ( incremental ) { 13520 return $.isFunction( incremental ) ? 13521 incremental( i ) : 13522 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13523 } 13524 13525 return 1; 13526 }, 13527 13528 _precision: function() { 13529 var precision = this._precisionOf( this.options.step ); 13530 if ( this.options.min !== null ) { 13531 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13532 } 13533 return precision; 13534 }, 13535 13536 _precisionOf: function( num ) { 13537 var str = num.toString(), 13538 decimal = str.indexOf( "." ); 13539 return decimal === -1 ? 0 : str.length - decimal - 1; 13540 }, 13541 13542 _adjustValue: function( value ) { 13543 var base, aboveMin, 13544 options = this.options; 13545 13546 // make sure we're at a valid step 13547 // - find out where we are relative to the base (min or 0) 13548 base = options.min !== null ? options.min : 0; 13549 aboveMin = value - base; 13550 // - round to the nearest step 13551 aboveMin = Math.round(aboveMin / options.step) * options.step; 13552 // - rounding is based on 0, so adjust back to our base 13553 value = base + aboveMin; 13554 13555 // fix precision from bad JS floating point math 13556 value = parseFloat( value.toFixed( this._precision() ) ); 13557 13558 // clamp the value 13559 if ( options.max !== null && value > options.max) { 13560 return options.max; 13561 } 13562 if ( options.min !== null && value < options.min ) { 13563 return options.min; 13564 } 13565 13566 return value; 13567 }, 13568 13569 _stop: function( event ) { 13570 if ( !this.spinning ) { 13571 return; 13572 } 13573 13574 clearTimeout( this.timer ); 13575 clearTimeout( this.mousewheelTimer ); 13576 this.counter = 0; 13577 this.spinning = false; 13578 this._trigger( "stop", event ); 13579 }, 13580 13581 _setOption: function( key, value ) { 13582 if ( key === "culture" || key === "numberFormat" ) { 13583 var prevValue = this._parse( this.element.val() ); 13584 this.options[ key ] = value; 13585 this.element.val( this._format( prevValue ) ); 13586 return; 13587 } 13588 13589 if ( key === "max" || key === "min" || key === "step" ) { 13590 if ( typeof value === "string" ) { 13591 value = this._parse( value ); 13592 } 13593 } 13594 if ( key === "icons" ) { 13595 this.buttons.first().find( ".ui-icon" ) 13596 .removeClass( this.options.icons.up ) 13597 .addClass( value.up ); 13598 this.buttons.last().find( ".ui-icon" ) 13599 .removeClass( this.options.icons.down ) 13600 .addClass( value.down ); 13601 } 13602 13603 this._super( key, value ); 13604 13605 if ( key === "disabled" ) { 13606 if ( value ) { 13607 this.element.prop( "disabled", true ); 13608 this.buttons.button( "disable" ); 13609 } else { 13610 this.element.prop( "disabled", false ); 13611 this.buttons.button( "enable" ); 13612 } 13613 } 13614 }, 13615 13616 _setOptions: modifier(function( options ) { 13617 this._super( options ); 13618 this._value( this.element.val() ); 13619 }), 13620 13621 _parse: function( val ) { 13622 if ( typeof val === "string" && val !== "" ) { 13623 val = window.Globalize && this.options.numberFormat ? 13624 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13625 } 13626 return val === "" || isNaN( val ) ? null : val; 13627 }, 13628 13629 _format: function( value ) { 13630 if ( value === "" ) { 13631 return ""; 13632 } 13633 return window.Globalize && this.options.numberFormat ? 13634 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13635 value; 13636 }, 13637 13638 _refresh: function() { 13639 this.element.attr({ 13640 "aria-valuemin": this.options.min, 13641 "aria-valuemax": this.options.max, 13642 // TODO: what should we do with values that can't be parsed? 13643 "aria-valuenow": this._parse( this.element.val() ) 13644 }); 13645 }, 13646 13647 // update the value without triggering change 13648 _value: function( value, allowAny ) { 13649 var parsed; 13650 if ( value !== "" ) { 13651 parsed = this._parse( value ); 13652 if ( parsed !== null ) { 13653 if ( !allowAny ) { 13654 parsed = this._adjustValue( parsed ); 13655 } 13656 value = this._format( parsed ); 13657 } 13658 } 13659 this.element.val( value ); 13660 this._refresh(); 13661 }, 13662 13663 _destroy: function() { 13664 this.element 13665 .removeClass( "ui-spinner-input" ) 13666 .prop( "disabled", false ) 13667 .removeAttr( "autocomplete" ) 13668 .removeAttr( "role" ) 13669 .removeAttr( "aria-valuemin" ) 13670 .removeAttr( "aria-valuemax" ) 13671 .removeAttr( "aria-valuenow" ); 13672 this.uiSpinner.replaceWith( this.element ); 13673 }, 13674 13675 stepUp: modifier(function( steps ) { 13676 this._stepUp( steps ); 13677 }), 13678 _stepUp: function( steps ) { 13679 if ( this._start() ) { 13680 this._spin( (steps || 1) * this.options.step ); 13681 this._stop(); 13682 } 13683 }, 13684 13685 stepDown: modifier(function( steps ) { 13686 this._stepDown( steps ); 13687 }), 13688 _stepDown: function( steps ) { 13689 if ( this._start() ) { 13690 this._spin( (steps || 1) * -this.options.step ); 13691 this._stop(); 13692 } 13693 }, 13694 13695 pageUp: modifier(function( pages ) { 13696 this._stepUp( (pages || 1) * this.options.page ); 13697 }), 13698 13699 pageDown: modifier(function( pages ) { 13700 this._stepDown( (pages || 1) * this.options.page ); 13701 }), 13702 13703 value: function( newVal ) { 13704 if ( !arguments.length ) { 13705 return this._parse( this.element.val() ); 13706 } 13707 modifier( this._value ).call( this, newVal ); 13708 }, 13709 13710 widget: function() { 13711 return this.uiSpinner; 13712 } 13713}); 13714 13715}( jQuery ) ); 13716 13717(function( $, undefined ) { 13718 13719var tabId = 0, 13720 rhash = /#.*$/; 13721 13722function getNextTabId() { 13723 return ++tabId; 13724} 13725 13726function isLocal( anchor ) { 13727 return anchor.hash.length > 1 && 13728 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13729 decodeURIComponent( location.href.replace( rhash, "" ) ); 13730} 13731 13732$.widget( "ui.tabs", { 13733 version: "1.10.1", 13734 delay: 300, 13735 options: { 13736 active: null, 13737 collapsible: false, 13738 event: "click", 13739 heightStyle: "content", 13740 hide: null, 13741 show: null, 13742 13743 // callbacks 13744 activate: null, 13745 beforeActivate: null, 13746 beforeLoad: null, 13747 load: null 13748 }, 13749 13750 _create: function() { 13751 var that = this, 13752 options = this.options; 13753 13754 this.running = false; 13755 13756 this.element 13757 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13758 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13759 // Prevent users from focusing disabled tabs via click 13760 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13761 if ( $( this ).is( ".ui-state-disabled" ) ) { 13762 event.preventDefault(); 13763 } 13764 }) 13765 // support: IE <9 13766 // Preventing the default action in mousedown doesn't prevent IE 13767 // from focusing the element, so if the anchor gets focused, blur. 13768 // We don't have to worry about focusing the previously focused 13769 // element since clicking on a non-focusable element should focus 13770 // the body anyway. 13771 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13772 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13773 this.blur(); 13774 } 13775 }); 13776 13777 this._processTabs(); 13778 options.active = this._initialActive(); 13779 13780 // Take disabling tabs via class attribute from HTML 13781 // into account and update option properly. 13782 if ( $.isArray( options.disabled ) ) { 13783 options.disabled = $.unique( options.disabled.concat( 13784 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13785 return that.tabs.index( li ); 13786 }) 13787 ) ).sort(); 13788 } 13789 13790 // check for length avoids error when initializing empty list 13791 if ( this.options.active !== false && this.anchors.length ) { 13792 this.active = this._findActive( options.active ); 13793 } else { 13794 this.active = $(); 13795 } 13796 13797 this._refresh(); 13798 13799 if ( this.active.length ) { 13800 this.load( options.active ); 13801 } 13802 }, 13803 13804 _initialActive: function() { 13805 var active = this.options.active, 13806 collapsible = this.options.collapsible, 13807 locationHash = location.hash.substring( 1 ); 13808 13809 if ( active === null ) { 13810 // check the fragment identifier in the URL 13811 if ( locationHash ) { 13812 this.tabs.each(function( i, tab ) { 13813 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13814 active = i; 13815 return false; 13816 } 13817 }); 13818 } 13819 13820 // check for a tab marked active via a class 13821 if ( active === null ) { 13822 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13823 } 13824 13825 // no active tab, set to false 13826 if ( active === null || active === -1 ) { 13827 active = this.tabs.length ? 0 : false; 13828 } 13829 } 13830 13831 // handle numbers: negative, out of range 13832 if ( active !== false ) { 13833 active = this.tabs.index( this.tabs.eq( active ) ); 13834 if ( active === -1 ) { 13835 active = collapsible ? false : 0; 13836 } 13837 } 13838 13839 // don't allow collapsible: false and active: false 13840 if ( !collapsible && active === false && this.anchors.length ) { 13841 active = 0; 13842 } 13843 13844 return active; 13845 }, 13846 13847 _getCreateEventData: function() { 13848 return { 13849 tab: this.active, 13850 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13851 }; 13852 }, 13853 13854 _tabKeydown: function( event ) { 13855 /*jshint maxcomplexity:15*/ 13856 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13857 selectedIndex = this.tabs.index( focusedTab ), 13858 goingForward = true; 13859 13860 if ( this._handlePageNav( event ) ) { 13861 return; 13862 } 13863 13864 switch ( event.keyCode ) { 13865 case $.ui.keyCode.RIGHT: 13866 case $.ui.keyCode.DOWN: 13867 selectedIndex++; 13868 break; 13869 case $.ui.keyCode.UP: 13870 case $.ui.keyCode.LEFT: 13871 goingForward = false; 13872 selectedIndex--; 13873 break; 13874 case $.ui.keyCode.END: 13875 selectedIndex = this.anchors.length - 1; 13876 break; 13877 case $.ui.keyCode.HOME: 13878 selectedIndex = 0; 13879 break; 13880 case $.ui.keyCode.SPACE: 13881 // Activate only, no collapsing 13882 event.preventDefault(); 13883 clearTimeout( this.activating ); 13884 this._activate( selectedIndex ); 13885 return; 13886 case $.ui.keyCode.ENTER: 13887 // Toggle (cancel delayed activation, allow collapsing) 13888 event.preventDefault(); 13889 clearTimeout( this.activating ); 13890 // Determine if we should collapse or activate 13891 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13892 return; 13893 default: 13894 return; 13895 } 13896 13897 // Focus the appropriate tab, based on which key was pressed 13898 event.preventDefault(); 13899 clearTimeout( this.activating ); 13900 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13901 13902 // Navigating with control key will prevent automatic activation 13903 if ( !event.ctrlKey ) { 13904 // Update aria-selected immediately so that AT think the tab is already selected. 13905 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13906 // but the tab will already be activated by the time the announcement finishes. 13907 focusedTab.attr( "aria-selected", "false" ); 13908 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13909 13910 this.activating = this._delay(function() { 13911 this.option( "active", selectedIndex ); 13912 }, this.delay ); 13913 } 13914 }, 13915 13916 _panelKeydown: function( event ) { 13917 if ( this._handlePageNav( event ) ) { 13918 return; 13919 } 13920 13921 // Ctrl+up moves focus to the current tab 13922 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13923 event.preventDefault(); 13924 this.active.focus(); 13925 } 13926 }, 13927 13928 // Alt+page up/down moves focus to the previous/next tab (and activates) 13929 _handlePageNav: function( event ) { 13930 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13931 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13932 return true; 13933 } 13934 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 13935 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 13936 return true; 13937 } 13938 }, 13939 13940 _findNextTab: function( index, goingForward ) { 13941 var lastTabIndex = this.tabs.length - 1; 13942 13943 function constrain() { 13944 if ( index > lastTabIndex ) { 13945 index = 0; 13946 } 13947 if ( index < 0 ) { 13948 index = lastTabIndex; 13949 } 13950 return index; 13951 } 13952 13953 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 13954 index = goingForward ? index + 1 : index - 1; 13955 } 13956 13957 return index; 13958 }, 13959 13960 _focusNextTab: function( index, goingForward ) { 13961 index = this._findNextTab( index, goingForward ); 13962 this.tabs.eq( index ).focus(); 13963 return index; 13964 }, 13965 13966 _setOption: function( key, value ) { 13967 if ( key === "active" ) { 13968 // _activate() will handle invalid values and update this.options 13969 this._activate( value ); 13970 return; 13971 } 13972 13973 if ( key === "disabled" ) { 13974 // don't use the widget factory's disabled handling 13975 this._setupDisabled( value ); 13976 return; 13977 } 13978 13979 this._super( key, value); 13980 13981 if ( key === "collapsible" ) { 13982 this.element.toggleClass( "ui-tabs-collapsible", value ); 13983 // Setting collapsible: false while collapsed; open first panel 13984 if ( !value && this.options.active === false ) { 13985 this._activate( 0 ); 13986 } 13987 } 13988 13989 if ( key === "event" ) { 13990 this._setupEvents( value ); 13991 } 13992 13993 if ( key === "heightStyle" ) { 13994 this._setupHeightStyle( value ); 13995 } 13996 }, 13997 13998 _tabId: function( tab ) { 13999 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14000 }, 14001 14002 _sanitizeSelector: function( hash ) { 14003 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14004 }, 14005 14006 refresh: function() { 14007 var options = this.options, 14008 lis = this.tablist.children( ":has(a[href])" ); 14009 14010 // get disabled tabs from class attribute from HTML 14011 // this will get converted to a boolean if needed in _refresh() 14012 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14013 return lis.index( tab ); 14014 }); 14015 14016 this._processTabs(); 14017 14018 // was collapsed or no tabs 14019 if ( options.active === false || !this.anchors.length ) { 14020 options.active = false; 14021 this.active = $(); 14022 // was active, but active tab is gone 14023 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14024 // all remaining tabs are disabled 14025 if ( this.tabs.length === options.disabled.length ) { 14026 options.active = false; 14027 this.active = $(); 14028 // activate previous tab 14029 } else { 14030 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14031 } 14032 // was active, active tab still exists 14033 } else { 14034 // make sure active index is correct 14035 options.active = this.tabs.index( this.active ); 14036 } 14037 14038 this._refresh(); 14039 }, 14040 14041 _refresh: function() { 14042 this._setupDisabled( this.options.disabled ); 14043 this._setupEvents( this.options.event ); 14044 this._setupHeightStyle( this.options.heightStyle ); 14045 14046 this.tabs.not( this.active ).attr({ 14047 "aria-selected": "false", 14048 tabIndex: -1 14049 }); 14050 this.panels.not( this._getPanelForTab( this.active ) ) 14051 .hide() 14052 .attr({ 14053 "aria-expanded": "false", 14054 "aria-hidden": "true" 14055 }); 14056 14057 // Make sure one tab is in the tab order 14058 if ( !this.active.length ) { 14059 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14060 } else { 14061 this.active 14062 .addClass( "ui-tabs-active ui-state-active" ) 14063 .attr({ 14064 "aria-selected": "true", 14065 tabIndex: 0 14066 }); 14067 this._getPanelForTab( this.active ) 14068 .show() 14069 .attr({ 14070 "aria-expanded": "true", 14071 "aria-hidden": "false" 14072 }); 14073 } 14074 }, 14075 14076 _processTabs: function() { 14077 var that = this; 14078 14079 this.tablist = this._getList() 14080 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14081 .attr( "role", "tablist" ); 14082 14083 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14084 .addClass( "ui-state-default ui-corner-top" ) 14085 .attr({ 14086 role: "tab", 14087 tabIndex: -1 14088 }); 14089 14090 this.anchors = this.tabs.map(function() { 14091 return $( "a", this )[ 0 ]; 14092 }) 14093 .addClass( "ui-tabs-anchor" ) 14094 .attr({ 14095 role: "presentation", 14096 tabIndex: -1 14097 }); 14098 14099 this.panels = $(); 14100 14101 this.anchors.each(function( i, anchor ) { 14102 var selector, panel, panelId, 14103 anchorId = $( anchor ).uniqueId().attr( "id" ), 14104 tab = $( anchor ).closest( "li" ), 14105 originalAriaControls = tab.attr( "aria-controls" ); 14106 14107 // inline tab 14108 if ( isLocal( anchor ) ) { 14109 selector = anchor.hash; 14110 panel = that.element.find( that._sanitizeSelector( selector ) ); 14111 // remote tab 14112 } else { 14113 panelId = that._tabId( tab ); 14114 selector = "#" + panelId; 14115 panel = that.element.find( selector ); 14116 if ( !panel.length ) { 14117 panel = that._createPanel( panelId ); 14118 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14119 } 14120 panel.attr( "aria-live", "polite" ); 14121 } 14122 14123 if ( panel.length) { 14124 that.panels = that.panels.add( panel ); 14125 } 14126 if ( originalAriaControls ) { 14127 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14128 } 14129 tab.attr({ 14130 "aria-controls": selector.substring( 1 ), 14131 "aria-labelledby": anchorId 14132 }); 14133 panel.attr( "aria-labelledby", anchorId ); 14134 }); 14135 14136 this.panels 14137 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14138 .attr( "role", "tabpanel" ); 14139 }, 14140 14141 // allow overriding how to find the list for rare usage scenarios (#7715) 14142 _getList: function() { 14143 return this.element.find( "ol,ul" ).eq( 0 ); 14144 }, 14145 14146 _createPanel: function( id ) { 14147 return $( "<div>" ) 14148 .attr( "id", id ) 14149 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14150 .data( "ui-tabs-destroy", true ); 14151 }, 14152 14153 _setupDisabled: function( disabled ) { 14154 if ( $.isArray( disabled ) ) { 14155 if ( !disabled.length ) { 14156 disabled = false; 14157 } else if ( disabled.length === this.anchors.length ) { 14158 disabled = true; 14159 } 14160 } 14161 14162 // disable tabs 14163 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14164 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14165 $( li ) 14166 .addClass( "ui-state-disabled" ) 14167 .attr( "aria-disabled", "true" ); 14168 } else { 14169 $( li ) 14170 .removeClass( "ui-state-disabled" ) 14171 .removeAttr( "aria-disabled" ); 14172 } 14173 } 14174 14175 this.options.disabled = disabled; 14176 }, 14177 14178 _setupEvents: function( event ) { 14179 var events = { 14180 click: function( event ) { 14181 event.preventDefault(); 14182 } 14183 }; 14184 if ( event ) { 14185 $.each( event.split(" "), function( index, eventName ) { 14186 events[ eventName ] = "_eventHandler"; 14187 }); 14188 } 14189 14190 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14191 this._on( this.anchors, events ); 14192 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14193 this._on( this.panels, { keydown: "_panelKeydown" } ); 14194 14195 this._focusable( this.tabs ); 14196 this._hoverable( this.tabs ); 14197 }, 14198 14199 _setupHeightStyle: function( heightStyle ) { 14200 var maxHeight, 14201 parent = this.element.parent(); 14202 14203 if ( heightStyle === "fill" ) { 14204 maxHeight = parent.height(); 14205 maxHeight -= this.element.outerHeight() - this.element.height(); 14206 14207 this.element.siblings( ":visible" ).each(function() { 14208 var elem = $( this ), 14209 position = elem.css( "position" ); 14210 14211 if ( position === "absolute" || position === "fixed" ) { 14212 return; 14213 } 14214 maxHeight -= elem.outerHeight( true ); 14215 }); 14216 14217 this.element.children().not( this.panels ).each(function() { 14218 maxHeight -= $( this ).outerHeight( true ); 14219 }); 14220 14221 this.panels.each(function() { 14222 $( this ).height( Math.max( 0, maxHeight - 14223 $( this ).innerHeight() + $( this ).height() ) ); 14224 }) 14225 .css( "overflow", "auto" ); 14226 } else if ( heightStyle === "auto" ) { 14227 maxHeight = 0; 14228 this.panels.each(function() { 14229 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14230 }).height( maxHeight ); 14231 } 14232 }, 14233 14234 _eventHandler: function( event ) { 14235 var options = this.options, 14236 active = this.active, 14237 anchor = $( event.currentTarget ), 14238 tab = anchor.closest( "li" ), 14239 clickedIsActive = tab[ 0 ] === active[ 0 ], 14240 collapsing = clickedIsActive && options.collapsible, 14241 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14242 toHide = !active.length ? $() : this._getPanelForTab( active ), 14243 eventData = { 14244 oldTab: active, 14245 oldPanel: toHide, 14246 newTab: collapsing ? $() : tab, 14247 newPanel: toShow 14248 }; 14249 14250 event.preventDefault(); 14251 14252 if ( tab.hasClass( "ui-state-disabled" ) || 14253 // tab is already loading 14254 tab.hasClass( "ui-tabs-loading" ) || 14255 // can't switch durning an animation 14256 this.running || 14257 // click on active header, but not collapsible 14258 ( clickedIsActive && !options.collapsible ) || 14259 // allow canceling activation 14260 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14261 return; 14262 } 14263 14264 options.active = collapsing ? false : this.tabs.index( tab ); 14265 14266 this.active = clickedIsActive ? $() : tab; 14267 if ( this.xhr ) { 14268 this.xhr.abort(); 14269 } 14270 14271 if ( !toHide.length && !toShow.length ) { 14272 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14273 } 14274 14275 if ( toShow.length ) { 14276 this.load( this.tabs.index( tab ), event ); 14277 } 14278 this._toggle( event, eventData ); 14279 }, 14280 14281 // handles show/hide for selecting tabs 14282 _toggle: function( event, eventData ) { 14283 var that = this, 14284 toShow = eventData.newPanel, 14285 toHide = eventData.oldPanel; 14286 14287 this.running = true; 14288 14289 function complete() { 14290 that.running = false; 14291 that._trigger( "activate", event, eventData ); 14292 } 14293 14294 function show() { 14295 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14296 14297 if ( toShow.length && that.options.show ) { 14298 that._show( toShow, that.options.show, complete ); 14299 } else { 14300 toShow.show(); 14301 complete(); 14302 } 14303 } 14304 14305 // start out by hiding, then showing, then completing 14306 if ( toHide.length && this.options.hide ) { 14307 this._hide( toHide, this.options.hide, function() { 14308 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14309 show(); 14310 }); 14311 } else { 14312 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14313 toHide.hide(); 14314 show(); 14315 } 14316 14317 toHide.attr({ 14318 "aria-expanded": "false", 14319 "aria-hidden": "true" 14320 }); 14321 eventData.oldTab.attr( "aria-selected", "false" ); 14322 // If we're switching tabs, remove the old tab from the tab order. 14323 // If we're opening from collapsed state, remove the previous tab from the tab order. 14324 // If we're collapsing, then keep the collapsing tab in the tab order. 14325 if ( toShow.length && toHide.length ) { 14326 eventData.oldTab.attr( "tabIndex", -1 ); 14327 } else if ( toShow.length ) { 14328 this.tabs.filter(function() { 14329 return $( this ).attr( "tabIndex" ) === 0; 14330 }) 14331 .attr( "tabIndex", -1 ); 14332 } 14333 14334 toShow.attr({ 14335 "aria-expanded": "true", 14336 "aria-hidden": "false" 14337 }); 14338 eventData.newTab.attr({ 14339 "aria-selected": "true", 14340 tabIndex: 0 14341 }); 14342 }, 14343 14344 _activate: function( index ) { 14345 var anchor, 14346 active = this._findActive( index ); 14347 14348 // trying to activate the already active panel 14349 if ( active[ 0 ] === this.active[ 0 ] ) { 14350 return; 14351 } 14352 14353 // trying to collapse, simulate a click on the current active header 14354 if ( !active.length ) { 14355 active = this.active; 14356 } 14357 14358 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14359 this._eventHandler({ 14360 target: anchor, 14361 currentTarget: anchor, 14362 preventDefault: $.noop 14363 }); 14364 }, 14365 14366 _findActive: function( index ) { 14367 return index === false ? $() : this.tabs.eq( index ); 14368 }, 14369 14370 _getIndex: function( index ) { 14371 // meta-function to give users option to provide a href string instead of a numerical index. 14372 if ( typeof index === "string" ) { 14373 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14374 } 14375 14376 return index; 14377 }, 14378 14379 _destroy: function() { 14380 if ( this.xhr ) { 14381 this.xhr.abort(); 14382 } 14383 14384 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14385 14386 this.tablist 14387 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14388 .removeAttr( "role" ); 14389 14390 this.anchors 14391 .removeClass( "ui-tabs-anchor" ) 14392 .removeAttr( "role" ) 14393 .removeAttr( "tabIndex" ) 14394 .removeUniqueId(); 14395 14396 this.tabs.add( this.panels ).each(function() { 14397 if ( $.data( this, "ui-tabs-destroy" ) ) { 14398 $( this ).remove(); 14399 } else { 14400 $( this ) 14401 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14402 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14403 .removeAttr( "tabIndex" ) 14404 .removeAttr( "aria-live" ) 14405 .removeAttr( "aria-busy" ) 14406 .removeAttr( "aria-selected" ) 14407 .removeAttr( "aria-labelledby" ) 14408 .removeAttr( "aria-hidden" ) 14409 .removeAttr( "aria-expanded" ) 14410 .removeAttr( "role" ); 14411 } 14412 }); 14413 14414 this.tabs.each(function() { 14415 var li = $( this ), 14416 prev = li.data( "ui-tabs-aria-controls" ); 14417 if ( prev ) { 14418 li 14419 .attr( "aria-controls", prev ) 14420 .removeData( "ui-tabs-aria-controls" ); 14421 } else { 14422 li.removeAttr( "aria-controls" ); 14423 } 14424 }); 14425 14426 this.panels.show(); 14427 14428 if ( this.options.heightStyle !== "content" ) { 14429 this.panels.css( "height", "" ); 14430 } 14431 }, 14432 14433 enable: function( index ) { 14434 var disabled = this.options.disabled; 14435 if ( disabled === false ) { 14436 return; 14437 } 14438 14439 if ( index === undefined ) { 14440 disabled = false; 14441 } else { 14442 index = this._getIndex( index ); 14443 if ( $.isArray( disabled ) ) { 14444 disabled = $.map( disabled, function( num ) { 14445 return num !== index ? num : null; 14446 }); 14447 } else { 14448 disabled = $.map( this.tabs, function( li, num ) { 14449 return num !== index ? num : null; 14450 }); 14451 } 14452 } 14453 this._setupDisabled( disabled ); 14454 }, 14455 14456 disable: function( index ) { 14457 var disabled = this.options.disabled; 14458 if ( disabled === true ) { 14459 return; 14460 } 14461 14462 if ( index === undefined ) { 14463 disabled = true; 14464 } else { 14465 index = this._getIndex( index ); 14466 if ( $.inArray( index, disabled ) !== -1 ) { 14467 return; 14468 } 14469 if ( $.isArray( disabled ) ) { 14470 disabled = $.merge( [ index ], disabled ).sort(); 14471 } else { 14472 disabled = [ index ]; 14473 } 14474 } 14475 this._setupDisabled( disabled ); 14476 }, 14477 14478 load: function( index, event ) { 14479 index = this._getIndex( index ); 14480 var that = this, 14481 tab = this.tabs.eq( index ), 14482 anchor = tab.find( ".ui-tabs-anchor" ), 14483 panel = this._getPanelForTab( tab ), 14484 eventData = { 14485 tab: tab, 14486 panel: panel 14487 }; 14488 14489 // not remote 14490 if ( isLocal( anchor[ 0 ] ) ) { 14491 return; 14492 } 14493 14494 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14495 14496 // support: jQuery <1.8 14497 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14498 // but as of 1.8, $.ajax() always returns a jqXHR object. 14499 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14500 tab.addClass( "ui-tabs-loading" ); 14501 panel.attr( "aria-busy", "true" ); 14502 14503 this.xhr 14504 .success(function( response ) { 14505 // support: jQuery <1.8 14506 // http://bugs.jquery.com/ticket/11778 14507 setTimeout(function() { 14508 panel.html( response ); 14509 that._trigger( "load", event, eventData ); 14510 }, 1 ); 14511 }) 14512 .complete(function( jqXHR, status ) { 14513 // support: jQuery <1.8 14514 // http://bugs.jquery.com/ticket/11778 14515 setTimeout(function() { 14516 if ( status === "abort" ) { 14517 that.panels.stop( false, true ); 14518 } 14519 14520 tab.removeClass( "ui-tabs-loading" ); 14521 panel.removeAttr( "aria-busy" ); 14522 14523 if ( jqXHR === that.xhr ) { 14524 delete that.xhr; 14525 } 14526 }, 1 ); 14527 }); 14528 } 14529 }, 14530 14531 _ajaxSettings: function( anchor, event, eventData ) { 14532 var that = this; 14533 return { 14534 url: anchor.attr( "href" ), 14535 beforeSend: function( jqXHR, settings ) { 14536 return that._trigger( "beforeLoad", event, 14537 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14538 } 14539 }; 14540 }, 14541 14542 _getPanelForTab: function( tab ) { 14543 var id = $( tab ).attr( "aria-controls" ); 14544 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14545 } 14546}); 14547 14548})( jQuery ); 14549 14550(function( $ ) { 14551 14552var increments = 0; 14553 14554function addDescribedBy( elem, id ) { 14555 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14556 describedby.push( id ); 14557 elem 14558 .data( "ui-tooltip-id", id ) 14559 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14560} 14561 14562function removeDescribedBy( elem ) { 14563 var id = elem.data( "ui-tooltip-id" ), 14564 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14565 index = $.inArray( id, describedby ); 14566 if ( index !== -1 ) { 14567 describedby.splice( index, 1 ); 14568 } 14569 14570 elem.removeData( "ui-tooltip-id" ); 14571 describedby = $.trim( describedby.join( " " ) ); 14572 if ( describedby ) { 14573 elem.attr( "aria-describedby", describedby ); 14574 } else { 14575 elem.removeAttr( "aria-describedby" ); 14576 } 14577} 14578 14579$.widget( "ui.tooltip", { 14580 version: "1.10.1", 14581 options: { 14582 content: function() { 14583 // support: IE<9, Opera in jQuery <1.7 14584 // .text() can't accept undefined, so coerce to a string 14585 var title = $( this ).attr( "title" ) || ""; 14586 // Escape title, since we're going from an attribute to raw HTML 14587 return $( "<a>" ).text( title ).html(); 14588 }, 14589 hide: true, 14590 // Disabled elements have inconsistent behavior across browsers (#8661) 14591 items: "[title]:not([disabled])", 14592 position: { 14593 my: "left top+15", 14594 at: "left bottom", 14595 collision: "flipfit flip" 14596 }, 14597 show: true, 14598 tooltipClass: null, 14599 track: false, 14600 14601 // callbacks 14602 close: null, 14603 open: null 14604 }, 14605 14606 _create: function() { 14607 this._on({ 14608 mouseover: "open", 14609 focusin: "open" 14610 }); 14611 14612 // IDs of generated tooltips, needed for destroy 14613 this.tooltips = {}; 14614 // IDs of parent tooltips where we removed the title attribute 14615 this.parents = {}; 14616 14617 if ( this.options.disabled ) { 14618 this._disable(); 14619 } 14620 }, 14621 14622 _setOption: function( key, value ) { 14623 var that = this; 14624 14625 if ( key === "disabled" ) { 14626 this[ value ? "_disable" : "_enable" ](); 14627 this.options[ key ] = value; 14628 // disable element style changes 14629 return; 14630 } 14631 14632 this._super( key, value ); 14633 14634 if ( key === "content" ) { 14635 $.each( this.tooltips, function( id, element ) { 14636 that._updateContent( element ); 14637 }); 14638 } 14639 }, 14640 14641 _disable: function() { 14642 var that = this; 14643 14644 // close open tooltips 14645 $.each( this.tooltips, function( id, element ) { 14646 var event = $.Event( "blur" ); 14647 event.target = event.currentTarget = element[0]; 14648 that.close( event, true ); 14649 }); 14650 14651 // remove title attributes to prevent native tooltips 14652 this.element.find( this.options.items ).addBack().each(function() { 14653 var element = $( this ); 14654 if ( element.is( "[title]" ) ) { 14655 element 14656 .data( "ui-tooltip-title", element.attr( "title" ) ) 14657 .attr( "title", "" ); 14658 } 14659 }); 14660 }, 14661 14662 _enable: function() { 14663 // restore title attributes 14664 this.element.find( this.options.items ).addBack().each(function() { 14665 var element = $( this ); 14666 if ( element.data( "ui-tooltip-title" ) ) { 14667 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14668 } 14669 }); 14670 }, 14671 14672 open: function( event ) { 14673 var that = this, 14674 target = $( event ? event.target : this.element ) 14675 // we need closest here due to mouseover bubbling, 14676 // but always pointing at the same event target 14677 .closest( this.options.items ); 14678 14679 // No element to show a tooltip for or the tooltip is already open 14680 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14681 return; 14682 } 14683 14684 if ( target.attr( "title" ) ) { 14685 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14686 } 14687 14688 target.data( "ui-tooltip-open", true ); 14689 14690 // kill parent tooltips, custom or native, for hover 14691 if ( event && event.type === "mouseover" ) { 14692 target.parents().each(function() { 14693 var parent = $( this ), 14694 blurEvent; 14695 if ( parent.data( "ui-tooltip-open" ) ) { 14696 blurEvent = $.Event( "blur" ); 14697 blurEvent.target = blurEvent.currentTarget = this; 14698 that.close( blurEvent, true ); 14699 } 14700 if ( parent.attr( "title" ) ) { 14701 parent.uniqueId(); 14702 that.parents[ this.id ] = { 14703 element: this, 14704 title: parent.attr( "title" ) 14705 }; 14706 parent.attr( "title", "" ); 14707 } 14708 }); 14709 } 14710 14711 this._updateContent( target, event ); 14712 }, 14713 14714 _updateContent: function( target, event ) { 14715 var content, 14716 contentOption = this.options.content, 14717 that = this, 14718 eventType = event ? event.type : null; 14719 14720 if ( typeof contentOption === "string" ) { 14721 return this._open( event, target, contentOption ); 14722 } 14723 14724 content = contentOption.call( target[0], function( response ) { 14725 // ignore async response if tooltip was closed already 14726 if ( !target.data( "ui-tooltip-open" ) ) { 14727 return; 14728 } 14729 // IE may instantly serve a cached response for ajax requests 14730 // delay this call to _open so the other call to _open runs first 14731 that._delay(function() { 14732 // jQuery creates a special event for focusin when it doesn't 14733 // exist natively. To improve performance, the native event 14734 // object is reused and the type is changed. Therefore, we can't 14735 // rely on the type being correct after the event finished 14736 // bubbling, so we set it back to the previous value. (#8740) 14737 if ( event ) { 14738 event.type = eventType; 14739 } 14740 this._open( event, target, response ); 14741 }); 14742 }); 14743 if ( content ) { 14744 this._open( event, target, content ); 14745 } 14746 }, 14747 14748 _open: function( event, target, content ) { 14749 var tooltip, events, delayedShow, 14750 positionOption = $.extend( {}, this.options.position ); 14751 14752 if ( !content ) { 14753 return; 14754 } 14755 14756 // Content can be updated multiple times. If the tooltip already 14757 // exists, then just update the content and bail. 14758 tooltip = this._find( target ); 14759 if ( tooltip.length ) { 14760 tooltip.find( ".ui-tooltip-content" ).html( content ); 14761 return; 14762 } 14763 14764 // if we have a title, clear it to prevent the native tooltip 14765 // we have to check first to avoid defining a title if none exists 14766 // (we don't want to cause an element to start matching [title]) 14767 // 14768 // We use removeAttr only for key events, to allow IE to export the correct 14769 // accessible attributes. For mouse events, set to empty string to avoid 14770 // native tooltip showing up (happens only when removing inside mouseover). 14771 if ( target.is( "[title]" ) ) { 14772 if ( event && event.type === "mouseover" ) { 14773 target.attr( "title", "" ); 14774 } else { 14775 target.removeAttr( "title" ); 14776 } 14777 } 14778 14779 tooltip = this._tooltip( target ); 14780 addDescribedBy( target, tooltip.attr( "id" ) ); 14781 tooltip.find( ".ui-tooltip-content" ).html( content ); 14782 14783 function position( event ) { 14784 positionOption.of = event; 14785 if ( tooltip.is( ":hidden" ) ) { 14786 return; 14787 } 14788 tooltip.position( positionOption ); 14789 } 14790 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14791 this._on( this.document, { 14792 mousemove: position 14793 }); 14794 // trigger once to override element-relative positioning 14795 position( event ); 14796 } else { 14797 tooltip.position( $.extend({ 14798 of: target 14799 }, this.options.position ) ); 14800 } 14801 14802 tooltip.hide(); 14803 14804 this._show( tooltip, this.options.show ); 14805 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14806 // as the tooltip is visible, position the tooltip using the most recent 14807 // event. 14808 if ( this.options.show && this.options.show.delay ) { 14809 delayedShow = this.delayedShow = setInterval(function() { 14810 if ( tooltip.is( ":visible" ) ) { 14811 position( positionOption.of ); 14812 clearInterval( delayedShow ); 14813 } 14814 }, $.fx.interval ); 14815 } 14816 14817 this._trigger( "open", event, { tooltip: tooltip } ); 14818 14819 events = { 14820 keyup: function( event ) { 14821 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14822 var fakeEvent = $.Event(event); 14823 fakeEvent.currentTarget = target[0]; 14824 this.close( fakeEvent, true ); 14825 } 14826 }, 14827 remove: function() { 14828 this._removeTooltip( tooltip ); 14829 } 14830 }; 14831 if ( !event || event.type === "mouseover" ) { 14832 events.mouseleave = "close"; 14833 } 14834 if ( !event || event.type === "focusin" ) { 14835 events.focusout = "close"; 14836 } 14837 this._on( true, target, events ); 14838 }, 14839 14840 close: function( event ) { 14841 var that = this, 14842 target = $( event ? event.currentTarget : this.element ), 14843 tooltip = this._find( target ); 14844 14845 // disabling closes the tooltip, so we need to track when we're closing 14846 // to avoid an infinite loop in case the tooltip becomes disabled on close 14847 if ( this.closing ) { 14848 return; 14849 } 14850 14851 // Clear the interval for delayed tracking tooltips 14852 clearInterval( this.delayedShow ); 14853 14854 // only set title if we had one before (see comment in _open()) 14855 if ( target.data( "ui-tooltip-title" ) ) { 14856 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14857 } 14858 14859 removeDescribedBy( target ); 14860 14861 tooltip.stop( true ); 14862 this._hide( tooltip, this.options.hide, function() { 14863 that._removeTooltip( $( this ) ); 14864 }); 14865 14866 target.removeData( "ui-tooltip-open" ); 14867 this._off( target, "mouseleave focusout keyup" ); 14868 // Remove 'remove' binding only on delegated targets 14869 if ( target[0] !== this.element[0] ) { 14870 this._off( target, "remove" ); 14871 } 14872 this._off( this.document, "mousemove" ); 14873 14874 if ( event && event.type === "mouseleave" ) { 14875 $.each( this.parents, function( id, parent ) { 14876 $( parent.element ).attr( "title", parent.title ); 14877 delete that.parents[ id ]; 14878 }); 14879 } 14880 14881 this.closing = true; 14882 this._trigger( "close", event, { tooltip: tooltip } ); 14883 this.closing = false; 14884 }, 14885 14886 _tooltip: function( element ) { 14887 var id = "ui-tooltip-" + increments++, 14888 tooltip = $( "<div>" ) 14889 .attr({ 14890 id: id, 14891 role: "tooltip" 14892 }) 14893 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14894 ( this.options.tooltipClass || "" ) ); 14895 $( "<div>" ) 14896 .addClass( "ui-tooltip-content" ) 14897 .appendTo( tooltip ); 14898 tooltip.appendTo( this.document[0].body ); 14899 this.tooltips[ id ] = element; 14900 return tooltip; 14901 }, 14902 14903 _find: function( target ) { 14904 var id = target.data( "ui-tooltip-id" ); 14905 return id ? $( "#" + id ) : $(); 14906 }, 14907 14908 _removeTooltip: function( tooltip ) { 14909 tooltip.remove(); 14910 delete this.tooltips[ tooltip.attr( "id" ) ]; 14911 }, 14912 14913 _destroy: function() { 14914 var that = this; 14915 14916 // close open tooltips 14917 $.each( this.tooltips, function( id, element ) { 14918 // Delegate to close method to handle common cleanup 14919 var event = $.Event( "blur" ); 14920 event.target = event.currentTarget = element[0]; 14921 that.close( event, true ); 14922 14923 // Remove immediately; destroying an open tooltip doesn't use the 14924 // hide animation 14925 $( "#" + id ).remove(); 14926 14927 // Restore the title 14928 if ( element.data( "ui-tooltip-title" ) ) { 14929 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14930 element.removeData( "ui-tooltip-title" ); 14931 } 14932 }); 14933 } 14934}); 14935 14936}( 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.