vendor: 9,149 bytes, lines 1-321
1/*! jQuery UI - v1.9.2 - 2012-11-23 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 2012 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.9.2", 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; 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().andSelf().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 179$(function() { 180 var body = document.body, 181 div = body.appendChild( div = document.createElement( "div" ) ); 182 183 // access offsetHeight before setting the style to prevent a layout bug 184 // in IE 9 which causes the element to continue to take up space even 185 // after it is removed from the DOM (#8026) 186 div.offsetHeight; 187 188 $.extend( div.style, { 189 minHeight: "100px", 190 height: "auto", 191 padding: 0, 192 borderWidth: 0 193 }); 194 195 $.support.minHeight = div.offsetHeight === 100; 196 $.support.selectstart = "onselectstart" in div; 197 198 // set display to none to avoid a layout bug in IE 199 // http://dev.jquery.com/ticket/4014 200 body.removeChild( div ).style.display = "none"; 201}); 202 203// support: jQuery <1.8 204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 205 $.each( [ "Width", "Height" ], function( i, name ) { 206 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 207 type = name.toLowerCase(), 208 orig = { 209 innerWidth: $.fn.innerWidth, 210 innerHeight: $.fn.innerHeight, 211 outerWidth: $.fn.outerWidth, 212 outerHeight: $.fn.outerHeight 213 }; 214 215 function reduce( elem, size, border, margin ) { 216 $.each( side, function() { 217 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 218 if ( border ) { 219 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 220 } 221 if ( margin ) { 222 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 223 } 224 }); 225 return size; 226 } 227 228 $.fn[ "inner" + name ] = function( size ) { 229 if ( size === undefined ) { 230 return orig[ "inner" + name ].call( this ); 231 } 232 233 return this.each(function() { 234 $( this ).css( type, reduce( this, size ) + "px" ); 235 }); 236 }; 237 238 $.fn[ "outer" + name] = function( size, margin ) { 239 if ( typeof size !== "number" ) { 240 return orig[ "outer" + name ].call( this, size ); 241 } 242 243 return this.each(function() { 244 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 245 }); 246 }; 247 }); 248} 249 250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 252 $.fn.removeData = (function( removeData ) { 253 return function( key ) { 254 if ( arguments.length ) { 255 return removeData.call( this, $.camelCase( key ) ); 256 } else { 257 return removeData.call( this ); 258 } 259 }; 260 })( $.fn.removeData ); 261} 262 263 264 265 266 267// deprecated 268 269(function() { 270 var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || []; 271 $.ui.ie = uaMatch.length ? true : false; 272 $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6; 273})(); 274 275$.fn.extend({ 276 disableSelection: function() { 277 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 278 ".ui-disableSelection", function( event ) { 279 event.preventDefault(); 280 }); 281 }, 282 283 enableSelection: function() { 284 return this.unbind( ".ui-disableSelection" ); 285 } 286}); 287 288$.extend( $.ui, { 289 // $.ui.plugin is deprecated. Use the proxy pattern instead. 290 plugin: { 291 add: function( module, option, set ) { 292 var i, 293 proto = $.ui[ module ].prototype; 294 for ( i in set ) { 295 proto.plugins[ i ] = proto.plugins[ i ] || []; 296 proto.plugins[ i ].push( [ option, set[ i ] ] ); 297 } 298 }, 299 call: function( instance, name, args ) { 300 var i, 301 set = instance.plugins[ name ]; 302 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 303 return; 304 } 305 306 for ( i = 0; i < set.length; i++ ) { 307 if ( instance.options[ set[ i ][ 0 ] ] ) { 308 set[ i ][ 1 ].apply( instance.element, args ); 309 } 310 } 311 } 312 }, 313 314 contains: $.contains, 315 316 // only used by resizable 317 hasScroll: function( el, a ) { 318 319 //If overflow is hidden, the element might have extra content, but the user wants to hide it 320 if ( $( el ).css( "overflow" ) === "hidden") { 321 return false;
vendor: 4,238 bytes, lines 322-459
322 } 323 324 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 325 has = false; 326 327 if ( el[ scroll ] > 0 ) { 328 return true; 329 } 330 331 // TODO: determine which cases actually cause this to happen 332 // if the element doesn't have the scroll set, see if it's possible to 333 // set the scroll 334 el[ scroll ] = 1; 335 has = ( el[ scroll ] > 0 ); 336 el[ scroll ] = 0; 337 return has; 338 }, 339 340 // these are odd functions, fix the API or move into individual plugins 341 isOverAxis: function( x, reference, size ) { 342 //Determines when x coordinate is over "b" element axis 343 return ( x > reference ) && ( x < ( reference + size ) ); 344 }, 345 isOver: function( y, x, top, left, height, width ) { 346 //Determines when x, y coordinates is over "b" element 347 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); 348 } 349}); 350 351})( jQuery ); 352 353(function( $, undefined ) { 354 355var uuid = 0, 356 slice = Array.prototype.slice, 357 _cleanData = $.cleanData; 358$.cleanData = function( elems ) { 359 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 360 try { 361 $( elem ).triggerHandler( "remove" ); 362 // http://bugs.jquery.com/ticket/8235 363 } catch( e ) {} 364 } 365 _cleanData( elems ); 366}; 367 368$.widget = function( name, base, prototype ) { 369 var fullName, existingConstructor, constructor, basePrototype, 370 namespace = name.split( "." )[ 0 ]; 371 372 name = name.split( "." )[ 1 ]; 373 fullName = namespace + "-" + name; 374 375 if ( !prototype ) { 376 prototype = base; 377 base = $.Widget; 378 } 379 380 // create selector for plugin 381 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 382 return !!$.data( elem, fullName ); 383 }; 384 385 $[ namespace ] = $[ namespace ] || {}; 386 existingConstructor = $[ namespace ][ name ]; 387 constructor = $[ namespace ][ name ] = function( options, element ) { 388 // allow instantiation without "new" keyword 389 if ( !this._createWidget ) { 390 return new constructor( options, element ); 391 } 392 393 // allow instantiation without initializing for simple inheritance 394 // must use "new" keyword (the code above always passes args) 395 if ( arguments.length ) { 396 this._createWidget( options, element ); 397 } 398 }; 399 // extend with the existing constructor to carry over any static properties 400 $.extend( constructor, existingConstructor, { 401 version: prototype.version, 402 // copy the object used to create the prototype in case we need to 403 // redefine the widget later 404 _proto: $.extend( {}, prototype ), 405 // track widgets that inherit from this widget in case this widget is 406 // redefined after a widget inherits from it 407 _childConstructors: [] 408 }); 409 410 basePrototype = new base(); 411 // we need to make the options hash a property directly on the new instance 412 // otherwise we'll modify the options hash on the prototype that we're 413 // inheriting from 414 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 415 $.each( prototype, function( prop, value ) { 416 if ( $.isFunction( value ) ) { 417 prototype[ prop ] = (function() { 418 var _super = function() { 419 return base.prototype[ prop ].apply( this, arguments ); 420 }, 421 _superApply = function( args ) { 422 return base.prototype[ prop ].apply( this, args ); 423 }; 424 return function() { 425 var __super = this._super, 426 __superApply = this._superApply, 427 returnValue; 428 429 this._super = _super; 430 this._superApply = _superApply; 431 432 returnValue = value.apply( this, arguments ); 433 434 this._super = __super; 435 this._superApply = __superApply; 436 437 return returnValue; 438 }; 439 })(); 440 } 441 }); 442 constructor.prototype = $.widget.extend( basePrototype, { 443 // TODO: remove support for widgetEventPrefix 444 // always use the name + a colon as the prefix, e.g., draggable:start 445 // don't prefix for widgets that aren't DOM-based 446 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 447 }, prototype, { 448 constructor: constructor, 449 namespace: namespace, 450 widgetName: name, 451 // TODO remove widgetBaseClass, see #8155 452 widgetBaseClass: fullName, 453 widgetFullName: fullName 454 }); 455 456 // If this widget is being redefined then we need to find all widgets that 457 // are inheriting from it and redefine all of them so that they inherit from 458 // the new version of this widget. We're essentially trying to replace one 459 // level in the prototype chain.
vendor: 11,206 bytes, lines 460-849
460 if ( existingConstructor ) { 461 $.each( existingConstructor._childConstructors, function( i, child ) { 462 var childPrototype = child.prototype; 463 464 // redefine the child widget using the same prototype that was 465 // originally used, but inherit from the new version of the base 466 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 467 }); 468 // remove the list of existing child constructors from the old constructor 469 // so the old child constructors can be garbage collected 470 delete existingConstructor._childConstructors; 471 } else { 472 base._childConstructors.push( constructor ); 473 } 474 475 $.widget.bridge( name, constructor ); 476}; 477 478$.widget.extend = function( target ) { 479 var input = slice.call( arguments, 1 ), 480 inputIndex = 0, 481 inputLength = input.length, 482 key, 483 value; 484 for ( ; inputIndex < inputLength; inputIndex++ ) { 485 for ( key in input[ inputIndex ] ) { 486 value = input[ inputIndex ][ key ]; 487 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 488 // Clone objects 489 if ( $.isPlainObject( value ) ) { 490 target[ key ] = $.isPlainObject( target[ key ] ) ? 491 $.widget.extend( {}, target[ key ], value ) : 492 // Don't extend strings, arrays, etc. with objects 493 $.widget.extend( {}, value ); 494 // Copy everything else by reference 495 } else { 496 target[ key ] = value; 497 } 498 } 499 } 500 } 501 return target; 502}; 503 504$.widget.bridge = function( name, object ) { 505 var fullName = object.prototype.widgetFullName || name; 506 $.fn[ name ] = function( options ) { 507 var isMethodCall = typeof options === "string", 508 args = slice.call( arguments, 1 ), 509 returnValue = this; 510 511 // allow multiple hashes to be passed on init 512 options = !isMethodCall && args.length ? 513 $.widget.extend.apply( null, [ options ].concat(args) ) : 514 options; 515 516 if ( isMethodCall ) { 517 this.each(function() { 518 var methodValue, 519 instance = $.data( this, fullName ); 520 if ( !instance ) { 521 return $.error( "cannot call methods on " + name + " prior to initialization; " + 522 "attempted to call method '" + options + "'" ); 523 } 524 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 525 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 526 } 527 methodValue = instance[ options ].apply( instance, args ); 528 if ( methodValue !== instance && methodValue !== undefined ) { 529 returnValue = methodValue && methodValue.jquery ? 530 returnValue.pushStack( methodValue.get() ) : 531 methodValue; 532 return false; 533 } 534 }); 535 } else { 536 this.each(function() { 537 var instance = $.data( this, fullName ); 538 if ( instance ) { 539 instance.option( options || {} )._init(); 540 } else { 541 $.data( this, fullName, new object( options, this ) ); 542 } 543 }); 544 } 545 546 return returnValue; 547 }; 548}; 549 550$.Widget = function( /* options, element */ ) {}; 551$.Widget._childConstructors = []; 552 553$.Widget.prototype = { 554 widgetName: "widget", 555 widgetEventPrefix: "", 556 defaultElement: "<div>", 557 options: { 558 disabled: false, 559 560 // callbacks 561 create: null 562 }, 563 _createWidget: function( options, element ) { 564 element = $( element || this.defaultElement || this )[ 0 ]; 565 this.element = $( element ); 566 this.uuid = uuid++; 567 this.eventNamespace = "." + this.widgetName + this.uuid; 568 this.options = $.widget.extend( {}, 569 this.options, 570 this._getCreateOptions(), 571 options ); 572 573 this.bindings = $(); 574 this.hoverable = $(); 575 this.focusable = $(); 576 577 if ( element !== this ) { 578 // 1.9 BC for #7810 579 // TODO remove dual storage 580 $.data( element, this.widgetName, this ); 581 $.data( element, this.widgetFullName, this ); 582 this._on( true, this.element, { 583 remove: function( event ) { 584 if ( event.target === element ) { 585 this.destroy(); 586 } 587 } 588 }); 589 this.document = $( element.style ? 590 // element within the document 591 element.ownerDocument : 592 // element is window or document 593 element.document || element ); 594 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 595 } 596 597 this._create(); 598 this._trigger( "create", null, this._getCreateEventData() ); 599 this._init(); 600 }, 601 _getCreateOptions: $.noop, 602 _getCreateEventData: $.noop, 603 _create: $.noop, 604 _init: $.noop, 605 606 destroy: function() { 607 this._destroy(); 608 // we can probably remove the unbind calls in 2.0 609 // all event bindings should go through this._on() 610 this.element 611 .unbind( this.eventNamespace ) 612 // 1.9 BC for #7810 613 // TODO remove dual storage 614 .removeData( this.widgetName ) 615 .removeData( this.widgetFullName ) 616 // support: jquery <1.6.3 617 // http://bugs.jquery.com/ticket/9413 618 .removeData( $.camelCase( this.widgetFullName ) ); 619 this.widget() 620 .unbind( this.eventNamespace ) 621 .removeAttr( "aria-disabled" ) 622 .removeClass( 623 this.widgetFullName + "-disabled " + 624 "ui-state-disabled" ); 625 626 // clean up events and states 627 this.bindings.unbind( this.eventNamespace ); 628 this.hoverable.removeClass( "ui-state-hover" ); 629 this.focusable.removeClass( "ui-state-focus" ); 630 }, 631 _destroy: $.noop, 632 633 widget: function() { 634 return this.element; 635 }, 636 637 option: function( key, value ) { 638 var options = key, 639 parts, 640 curOption, 641 i; 642 643 if ( arguments.length === 0 ) { 644 // don't return a reference to the internal hash 645 return $.widget.extend( {}, this.options ); 646 } 647 648 if ( typeof key === "string" ) { 649 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 650 options = {}; 651 parts = key.split( "." ); 652 key = parts.shift(); 653 if ( parts.length ) { 654 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 655 for ( i = 0; i < parts.length - 1; i++ ) { 656 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 657 curOption = curOption[ parts[ i ] ]; 658 } 659 key = parts.pop(); 660 if ( value === undefined ) { 661 return curOption[ key ] === undefined ? null : curOption[ key ]; 662 } 663 curOption[ key ] = value; 664 } else { 665 if ( value === undefined ) { 666 return this.options[ key ] === undefined ? null : this.options[ key ]; 667 } 668 options[ key ] = value; 669 } 670 } 671 672 this._setOptions( options ); 673 674 return this; 675 }, 676 _setOptions: function( options ) { 677 var key; 678 679 for ( key in options ) { 680 this._setOption( key, options[ key ] ); 681 } 682 683 return this; 684 }, 685 _setOption: function( key, value ) { 686 this.options[ key ] = value; 687 688 if ( key === "disabled" ) { 689 this.widget() 690 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 691 .attr( "aria-disabled", value ); 692 this.hoverable.removeClass( "ui-state-hover" ); 693 this.focusable.removeClass( "ui-state-focus" ); 694 } 695 696 return this; 697 }, 698 699 enable: function() { 700 return this._setOption( "disabled", false ); 701 }, 702 disable: function() { 703 return this._setOption( "disabled", true ); 704 }, 705 706 _on: function( suppressDisabledCheck, element, handlers ) { 707 var delegateElement, 708 instance = this; 709 710 // no suppressDisabledCheck flag, shuffle arguments 711 if ( typeof suppressDisabledCheck !== "boolean" ) { 712 handlers = element; 713 element = suppressDisabledCheck; 714 suppressDisabledCheck = false; 715 } 716 717 // no element argument, shuffle and use this.element 718 if ( !handlers ) { 719 handlers = element; 720 element = this.element; 721 delegateElement = this.widget(); 722 } else { 723 // accept selectors, DOM elements 724 element = delegateElement = $( element ); 725 this.bindings = this.bindings.add( element ); 726 } 727 728 $.each( handlers, function( event, handler ) { 729 function handlerProxy() { 730 // allow widgets to customize the disabled handling 731 // - disabled as an array instead of boolean 732 // - disabled class as method for disabling individual parts 733 if ( !suppressDisabledCheck && 734 ( instance.options.disabled === true || 735 $( this ).hasClass( "ui-state-disabled" ) ) ) { 736 return; 737 } 738 return ( typeof handler === "string" ? instance[ handler ] : handler ) 739 .apply( instance, arguments ); 740 } 741 742 // copy the guid so direct unbinding works 743 if ( typeof handler !== "string" ) { 744 handlerProxy.guid = handler.guid = 745 handler.guid || handlerProxy.guid || $.guid++; 746 } 747 748 var match = event.match( /^(\w+)\s*(.*)$/ ), 749 eventName = match[1] + instance.eventNamespace, 750 selector = match[2]; 751 if ( selector ) { 752 delegateElement.delegate( selector, eventName, handlerProxy ); 753 } else { 754 element.bind( eventName, handlerProxy ); 755 } 756 }); 757 }, 758 759 _off: function( element, eventName ) { 760 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 761 element.unbind( eventName ).undelegate( eventName ); 762 }, 763 764 _delay: function( handler, delay ) { 765 function handlerProxy() { 766 return ( typeof handler === "string" ? instance[ handler ] : handler ) 767 .apply( instance, arguments ); 768 } 769 var instance = this; 770 return setTimeout( handlerProxy, delay || 0 ); 771 }, 772 773 _hoverable: function( element ) { 774 this.hoverable = this.hoverable.add( element ); 775 this._on( element, { 776 mouseenter: function( event ) { 777 $( event.currentTarget ).addClass( "ui-state-hover" ); 778 }, 779 mouseleave: function( event ) { 780 $( event.currentTarget ).removeClass( "ui-state-hover" ); 781 } 782 }); 783 }, 784 785 _focusable: function( element ) { 786 this.focusable = this.focusable.add( element ); 787 this._on( element, { 788 focusin: function( event ) { 789 $( event.currentTarget ).addClass( "ui-state-focus" ); 790 }, 791 focusout: function( event ) { 792 $( event.currentTarget ).removeClass( "ui-state-focus" ); 793 } 794 }); 795 }, 796 797 _trigger: function( type, event, data ) { 798 var prop, orig, 799 callback = this.options[ type ]; 800 801 data = data || {}; 802 event = $.Event( event ); 803 event.type = ( type === this.widgetEventPrefix ? 804 type : 805 this.widgetEventPrefix + type ).toLowerCase(); 806 // the original event may come from any element 807 // so we need to reset the target on the new event 808 event.target = this.element[ 0 ]; 809 810 // copy original event properties over to the new event 811 orig = event.originalEvent; 812 if ( orig ) { 813 for ( prop in orig ) { 814 if ( !( prop in event ) ) { 815 event[ prop ] = orig[ prop ]; 816 } 817 } 818 } 819 820 this.element.trigger( event, data ); 821 return !( $.isFunction( callback ) && 822 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 823 event.isDefaultPrevented() ); 824 } 825}; 826 827$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 828 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 829 if ( typeof options === "string" ) { 830 options = { effect: options }; 831 } 832 var hasOptions, 833 effectName = !options ? 834 method : 835 options === true || typeof options === "number" ? 836 defaultEffect : 837 options.effect || defaultEffect; 838 options = options || {}; 839 if ( typeof options === "number" ) { 840 options = { duration: options }; 841 } 842 hasOptions = !$.isEmptyObject( options ); 843 options.complete = callback; 844 if ( options.delay ) { 845 element.delay( options.delay ); 846 } 847 if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { 848 element[ method ]( options ); 849 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,171 bytes, lines 850-1005
850 element[ effectName ]( options.duration, options.easing, callback ); 851 } else { 852 element.queue(function( next ) { 853 $( this )[ method ](); 854 if ( callback ) { 855 callback.call( element[ 0 ] ); 856 } 857 next(); 858 }); 859 } 860 }; 861}); 862 863// DEPRECATED 864if ( $.uiBackCompat !== false ) { 865 $.Widget.prototype._getCreateOptions = function() { 866 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; 867 }; 868} 869 870})( jQuery ); 871 872(function( $, undefined ) { 873 874var mouseHandled = false; 875$( document ).mouseup( function( e ) { 876 mouseHandled = false; 877}); 878 879$.widget("ui.mouse", { 880 version: "1.9.2", 881 options: { 882 cancel: 'input,textarea,button,select,option', 883 distance: 1, 884 delay: 0 885 }, 886 _mouseInit: function() { 887 var that = this; 888 889 this.element 890 .bind('mousedown.'+this.widgetName, function(event) { 891 return that._mouseDown(event); 892 }) 893 .bind('click.'+this.widgetName, function(event) { 894 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { 895 $.removeData(event.target, that.widgetName + '.preventClickEvent'); 896 event.stopImmediatePropagation(); 897 return false; 898 } 899 }); 900 901 this.started = false; 902 }, 903 904 // TODO: make sure destroying one instance of mouse doesn't mess with 905 // other instances of mouse 906 _mouseDestroy: function() { 907 this.element.unbind('.'+this.widgetName); 908 if ( this._mouseMoveDelegate ) { 909 $(document) 910 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 911 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 912 } 913 }, 914 915 _mouseDown: function(event) { 916 // don't let more than one widget handle mouseStart 917 if( mouseHandled ) { return; } 918 919 // we may have missed mouseup (out of window) 920 (this._mouseStarted && this._mouseUp(event)); 921 922 this._mouseDownEvent = event; 923 924 var that = this, 925 btnIsLeft = (event.which === 1), 926 // event.target.nodeName works around a bug in IE 8 with 927 // disabled inputs (#7620) 928 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 929 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 930 return true; 931 } 932 933 this.mouseDelayMet = !this.options.delay; 934 if (!this.mouseDelayMet) { 935 this._mouseDelayTimer = setTimeout(function() { 936 that.mouseDelayMet = true; 937 }, this.options.delay); 938 } 939 940 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 941 this._mouseStarted = (this._mouseStart(event) !== false); 942 if (!this._mouseStarted) { 943 event.preventDefault(); 944 return true; 945 } 946 } 947 948 // Click event may never have fired (Gecko & Opera) 949 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { 950 $.removeData(event.target, this.widgetName + '.preventClickEvent'); 951 } 952 953 // these delegates are required to keep context 954 this._mouseMoveDelegate = function(event) { 955 return that._mouseMove(event); 956 }; 957 this._mouseUpDelegate = function(event) { 958 return that._mouseUp(event); 959 }; 960 $(document) 961 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 962 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); 963 964 event.preventDefault(); 965 966 mouseHandled = true; 967 return true; 968 }, 969 970 _mouseMove: function(event) { 971 // IE mouseup check - mouseup happened when mouse was out of window 972 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { 973 return this._mouseUp(event); 974 } 975 976 if (this._mouseStarted) { 977 this._mouseDrag(event); 978 return event.preventDefault(); 979 } 980 981 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 982 this._mouseStarted = 983 (this._mouseStart(this._mouseDownEvent, event) !== false); 984 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 985 } 986 987 return !this._mouseStarted; 988 }, 989 990 _mouseUp: function(event) { 991 $(document) 992 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 993 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 994 995 if (this._mouseStarted) { 996 this._mouseStarted = false; 997 998 if (event.target === this._mouseDownEvent.target) { 999 $.data(event.target, this.widgetName + '.preventClickEvent', true); 1000 } 1001 1002 this._mouseStop(event); 1003 } 1004 1005 return false;
1006 }, 1007 1008 _mouseDistanceMet: function(event) { 1009 return (Math.max( 1010 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1011 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1012 ) >= this.options.distance 1013 ); 1014 }, 1015 1016 _mouseDelayMet: function(event) { 1017 return this.mouseDelayMet; 1018 }, 1019 1020 // These are placeholder methods, to be overriden by extending plugin 1021 _mouseStart: function(event) {}, 1022 _mouseDrag: function(event) {}, 1023 _mouseStop: function(event) {}, 1024 _mouseCapture: function(event) { return true; } 1025}); 1026 1027})(jQuery); 1028 1029(function( $, undefined ) { 1030 1031$.widget("ui.draggable", $.ui.mouse, { 1032 version: "1.9.2", 1033 widgetEventPrefix: "drag", 1034 options: { 1035 addClasses: true, 1036 appendTo: "parent", 1037 axis: false, 1038 connectToSortable: false, 1039 containment: false, 1040 cursor: "auto", 1041 cursorAt: false, 1042 grid: false, 1043 handle: false, 1044 helper: "original", 1045 iframeFix: false, 1046 opacity: false, 1047 refreshPositions: false, 1048 revert: false, 1049 revertDuration: 500, 1050 scope: "default", 1051 scroll: true, 1052 scrollSensitivity: 20, 1053 scrollSpeed: 20, 1054 snap: false, 1055 snapMode: "both", 1056 snapTolerance: 20, 1057 stack: false, 1058 zIndex: false 1059 }, 1060 _create: function() { 1061 1062 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 1063 this.element[0].style.position = 'relative'; 1064 1065 (this.options.addClasses && this.element.addClass("ui-draggable")); 1066 (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 1067 1068 this._mouseInit(); 1069 1070 }, 1071 1072 _destroy: function() { 1073 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1074 this._mouseDestroy(); 1075 }, 1076 1077 _mouseCapture: function(event) { 1078 1079 var o = this.options; 1080 1081 // among others, prevent a drag on a resizable-handle 1082 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 1083 return false; 1084 1085 //Quit if we're not on a valid handle 1086 this.handle = this._getHandle(event); 1087 if (!this.handle) 1088 return false; 1089 1090 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1091 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 1092 .css({ 1093 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1094 position: "absolute", opacity: "0.001", zIndex: 1000 1095 }) 1096 .css($(this).offset()) 1097 .appendTo("body"); 1098 }); 1099 1100 return true; 1101 1102 }, 1103 1104 _mouseStart: function(event) { 1105 1106 var o = this.options; 1107 1108 //Create and append the visible helper 1109 this.helper = this._createHelper(event); 1110 1111 this.helper.addClass("ui-draggable-dragging"); 1112 1113 //Cache the helper size 1114 this._cacheHelperProportions(); 1115 1116 //If ddmanager is used for droppables, set the global draggable 1117 if($.ui.ddmanager) 1118 $.ui.ddmanager.current = this; 1119 1120 /* 1121 * - Position generation - 1122 * This block generates everything position related - it's the core of draggables. 1123 */ 1124 1125 //Cache the margins of the original element 1126 this._cacheMargins(); 1127 1128 //Store the helper's css position 1129 this.cssPosition = this.helper.css("position"); 1130 this.scrollParent = this.helper.scrollParent(); 1131 1132 //The element's absolute position on the page minus margins 1133 this.offset = this.positionAbs = this.element.offset(); 1134 this.offset = { 1135 top: this.offset.top - this.margins.top, 1136 left: this.offset.left - this.margins.left 1137 }; 1138 1139 $.extend(this.offset, { 1140 click: { //Where the click happened, relative to the element 1141 left: event.pageX - this.offset.left, 1142 top: event.pageY - this.offset.top 1143 }, 1144 parent: this._getParentOffset(), 1145 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1146 }); 1147 1148 //Generate the original position 1149 this.originalPosition = this.position = this._generatePosition(event); 1150 this.originalPageX = event.pageX; 1151 this.originalPageY = event.pageY; 1152 1153 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 1154 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1155 1156 //Set a containment if given in the options 1157 if(o.containment) 1158 this._setContainment(); 1159 1160 //Trigger event + callbacks 1161 if(this._trigger("start", event) === false) { 1162 this._clear(); 1163 return false;
1164 } 1165 1166 //Recache the helper size 1167 this._cacheHelperProportions(); 1168 1169 //Prepare the droppable offsets 1170 if ($.ui.ddmanager && !o.dropBehaviour) 1171 $.ui.ddmanager.prepareOffsets(this, event); 1172 1173 1174 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1175 1176 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1177 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); 1178 1179 return true; 1180 }, 1181 1182 _mouseDrag: function(event, noPropagation) { 1183 1184 //Compute the helpers position 1185 this.position = this._generatePosition(event); 1186 this.positionAbs = this._convertPositionTo("absolute"); 1187 1188 //Call plugins and callbacks and use the resulting position if something is returned 1189 if (!noPropagation) { 1190 var ui = this._uiHash(); 1191 if(this._trigger('drag', event, ui) === false) { 1192 this._mouseUp({}); 1193 return false; 1194 } 1195 this.position = ui.position; 1196 } 1197 1198 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 1199 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 1200 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 1201 1202 return false; 1203 }, 1204 1205 _mouseStop: function(event) { 1206 1207 //If we are using droppables, inform the manager about the drop 1208 var dropped = false; 1209 if ($.ui.ddmanager && !this.options.dropBehaviour) 1210 dropped = $.ui.ddmanager.drop(this, event); 1211 1212 //if a drop comes from outside (a sortable) 1213 if(this.dropped) { 1214 dropped = this.dropped; 1215 this.dropped = false; 1216 } 1217 1218 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1219 var element = this.element[0], elementInDom = false;
1220 while ( element && (element = element.parentNode) ) { 1221 if (element == document ) { 1222 elementInDom = true; 1223 } 1224 } 1225 if ( !elementInDom && this.options.helper === "original" ) 1226 return false; 1227 1228 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))) { 1229 var that = this; 1230 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1231 if(that._trigger("stop", event) !== false) { 1232 that._clear(); 1233 } 1234 }); 1235 } else { 1236 if(this._trigger("stop", event) !== false) { 1237 this._clear(); 1238 } 1239 } 1240 1241 return false; 1242 }, 1243 1244 _mouseUp: function(event) { 1245 //Remove frame helpers 1246 $("div.ui-draggable-iframeFix").each(function() { 1247 this.parentNode.removeChild(this); 1248 }); 1249 1250 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1251 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); 1252 1253 return $.ui.mouse.prototype._mouseUp.call(this, event); 1254 }, 1255 1256 cancel: function() { 1257 1258 if(this.helper.is(".ui-draggable-dragging")) { 1259 this._mouseUp({}); 1260 } else { 1261 this._clear(); 1262 } 1263 1264 return this; 1265 1266 }, 1267 1268 _getHandle: function(event) { 1269 1270 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1271 $(this.options.handle, this.element) 1272 .find("*") 1273 .andSelf() 1274 .each(function() { 1275 if(this == event.target) handle = true; 1276 }); 1277 1278 return handle; 1279 1280 }, 1281 1282 _createHelper: function(event) { 1283 1284 var o = this.options; 1285 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); 1286 1287 if(!helper.parents('body').length) 1288 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 1289 1290 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 1291 helper.css("position", "absolute"); 1292 1293 return helper; 1294 1295 }, 1296 1297 _adjustOffsetFromHelper: function(obj) { 1298 if (typeof obj == 'string') { 1299 obj = obj.split(' '); 1300 } 1301 if ($.isArray(obj)) { 1302 obj = {left: +obj[0], top: +obj[1] || 0}; 1303 } 1304 if ('left' in obj) { 1305 this.offset.click.left = obj.left + this.margins.left; 1306 } 1307 if ('right' in obj) { 1308 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1309 } 1310 if ('top' in obj) { 1311 this.offset.click.top = obj.top + this.margins.top; 1312 } 1313 if ('bottom' in obj) { 1314 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1315 } 1316 }, 1317 1318 _getParentOffset: function() { 1319 1320 //Get the offsetParent and cache its position 1321 this.offsetParent = this.helper.offsetParent(); 1322 var po = this.offsetParent.offset(); 1323 1324 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1325 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1326 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1327 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1328 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1329 po.left += this.scrollParent.scrollLeft(); 1330 po.top += this.scrollParent.scrollTop(); 1331 } 1332 1333 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 1334 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 1335 po = { top: 0, left: 0 }; 1336 1337 return { 1338 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 1339 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1340 }; 1341 1342 }, 1343 1344 _getRelativeOffset: function() { 1345 1346 if(this.cssPosition == "relative") { 1347 var p = this.element.position(); 1348 return { 1349 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1350 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1351 }; 1352 } else { 1353 return { top: 0, left: 0 }; 1354 } 1355 1356 }, 1357 1358 _cacheMargins: function() { 1359 this.margins = { 1360 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1361 top: (parseInt(this.element.css("marginTop"),10) || 0), 1362 right: (parseInt(this.element.css("marginRight"),10) || 0), 1363 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1364 }; 1365 }, 1366 1367 _cacheHelperProportions: function() { 1368 this.helperProportions = { 1369 width: this.helper.outerWidth(), 1370 height: this.helper.outerHeight() 1371 }; 1372 }, 1373 1374 _setContainment: function() { 1375 1376 var o = this.options; 1377 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 1378 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 1379 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1380 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1381 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 1382 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1383 ]; 1384 1385 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { 1386 var c = $(o.containment); 1387 var ce = c[0]; if(!ce) return; 1388 var co = c.offset(); 1389 var over = ($(ce).css("overflow") != 'hidden'); 1390 1391 this.containment = [ 1392 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1393 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1394 (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, 1395 (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 1396 ]; 1397 this.relative_container = c; 1398 1399 } else if(o.containment.constructor == Array) { 1400 this.containment = o.containment; 1401 } 1402 1403 }, 1404 1405 _convertPositionTo: function(d, pos) { 1406 1407 if(!pos) pos = this.position; 1408 var mod = d == "absolute" ? 1 : -1; 1409 var o = this.options, 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); 1410 1411 return { 1412 top: ( 1413 pos.top // The absolute mouse position 1414 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1415 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 1416 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1417 ), 1418 left: ( 1419 pos.left // The absolute mouse position 1420 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1421 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 1422 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1423 ) 1424 }; 1425 1426 }, 1427 1428 _generatePosition: function(event) { 1429 1430 var o = this.options, 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); 1431 var pageX = event.pageX; 1432 var pageY = event.pageY; 1433 1434 /* 1435 * - Position constraining - 1436 * Constrain the position to a mix of grid, containment. 1437 */ 1438 1439 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1440 var containment; 1441 if(this.containment) { 1442 if (this.relative_container){ 1443 var co = this.relative_container.offset(); 1444 containment = [ this.containment[0] + co.left, 1445 this.containment[1] + co.top, 1446 this.containment[2] + co.left, 1447 this.containment[3] + co.top ]; 1448 } 1449 else { 1450 containment = this.containment; 1451 } 1452 1453 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; 1454 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; 1455 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; 1456 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; 1457 } 1458 1459 if(o.grid) { 1460 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1461 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1462 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; 1463 1464 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1465 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; 1466 } 1467 1468 } 1469 1470 return { 1471 top: ( 1472 pageY // The absolute mouse position 1473 - this.offset.click.top // Click offset (relative to the element) 1474 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 1475 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 1476 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1477 ), 1478 left: ( 1479 pageX // The absolute mouse position 1480 - this.offset.click.left // Click offset (relative to the element) 1481 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 1482 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 1483 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1484 ) 1485 }; 1486 1487 }, 1488 1489 _clear: function() { 1490 this.helper.removeClass("ui-draggable-dragging"); 1491 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 1492 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 1493 this.helper = null; 1494 this.cancelHelperRemoval = false;
1495 }, 1496 1497 // From now on bulk stuff - mainly helpers 1498 1499 _trigger: function(type, event, ui) { 1500 ui = ui || this._uiHash(); 1501 $.ui.plugin.call(this, type, [event, ui]); 1502 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 1503 return $.Widget.prototype._trigger.call(this, type, event, ui); 1504 }, 1505 1506 plugins: {}, 1507 1508 _uiHash: function(event) { 1509 return { 1510 helper: this.helper, 1511 position: this.position, 1512 originalPosition: this.originalPosition, 1513 offset: this.positionAbs 1514 }; 1515 } 1516 1517}); 1518 1519$.ui.plugin.add("draggable", "connectToSortable", { 1520 start: function(event, ui) { 1521 1522 var inst = $(this).data("draggable"), o = inst.options, 1523 uiSortable = $.extend({}, ui, { item: inst.element }); 1524 inst.sortables = []; 1525 $(o.connectToSortable).each(function() { 1526 var sortable = $.data(this, 'sortable'); 1527 if (sortable && !sortable.options.disabled) { 1528 inst.sortables.push({ 1529 instance: sortable, 1530 shouldRevert: sortable.options.revert 1531 }); 1532 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). 1533 sortable._trigger("activate", event, uiSortable); 1534 } 1535 }); 1536 1537 }, 1538 stop: function(event, ui) { 1539 1540 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1541 var inst = $(this).data("draggable"), 1542 uiSortable = $.extend({}, ui, { item: inst.element }); 1543 1544 $.each(inst.sortables, function() { 1545 if(this.instance.isOver) { 1546 1547 this.instance.isOver = 0; 1548 1549 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1550 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1551 1552 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' 1553 if(this.shouldRevert) this.instance.options.revert = true; 1554 1555 //Trigger the stop of the sortable 1556 this.instance._mouseStop(event); 1557 1558 this.instance.options.helper = this.instance.options._helper; 1559 1560 //If the helper has been the original item, restore properties in the sortable 1561 if(inst.options.helper == 'original') 1562 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 1563 1564 } else { 1565 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1566 this.instance._trigger("deactivate", event, uiSortable); 1567 } 1568 1569 }); 1570 1571 }, 1572 drag: function(event, ui) { 1573 1574 var inst = $(this).data("draggable"), that = this; 1575 1576 var checkPos = function(o) { 1577 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 1578 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 1579 var itemHeight = o.height, itemWidth = o.width; 1580 var itemTop = o.top, itemLeft = o.left; 1581 1582 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 1583 }; 1584 1585 $.each(inst.sortables, function(i) { 1586 1587 var innermostIntersecting = false; 1588 var thisSortable = this; 1589 //Copy over some variables to allow calling the sortable's native _intersectsWith 1590 this.instance.positionAbs = inst.positionAbs; 1591 this.instance.helperProportions = inst.helperProportions; 1592 this.instance.offset.click = inst.offset.click; 1593 1594 if(this.instance._intersectsWith(this.instance.containerCache)) { 1595 innermostIntersecting = true; 1596 $.each(inst.sortables, function () { 1597 this.instance.positionAbs = inst.positionAbs; 1598 this.instance.helperProportions = inst.helperProportions; 1599 this.instance.offset.click = inst.offset.click; 1600 if (this != thisSortable 1601 && this.instance._intersectsWith(this.instance.containerCache) 1602 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) 1603 innermostIntersecting = false; 1604 return innermostIntersecting; 1605 }); 1606 } 1607 1608 1609 if(innermostIntersecting) { 1610 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1611 if(!this.instance.isOver) { 1612 1613 this.instance.isOver = 1; 1614 //Now we fake the start of dragging for the sortable instance, 1615 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1616 //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) 1617 this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); 1618 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1619 this.instance.options.helper = function() { return ui.helper[0]; }; 1620 1621 event.target = this.instance.currentItem[0]; 1622 this.instance._mouseCapture(event, true); 1623 this.instance._mouseStart(event, true, true); 1624
1625 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1626 this.instance.offset.click.top = inst.offset.click.top; 1627 this.instance.offset.click.left = inst.offset.click.left; 1628 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1629 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1630 1631 inst._trigger("toSortable", event); 1632 inst.dropped = this.instance.element; //draggable revert needs that 1633 //hack so receive/update callbacks work (mostly) 1634 inst.currentItem = inst.element; 1635 this.instance.fromOutside = inst; 1636 1637 } 1638 1639 //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 1640 if(this.instance.currentItem) this.instance._mouseDrag(event); 1641 1642 } else { 1643 1644 //If it doesn't intersect with the sortable, and it intersected before, 1645 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1646 if(this.instance.isOver) { 1647 1648 this.instance.isOver = 0; 1649 this.instance.cancelHelperRemoval = true; 1650 1651 //Prevent reverting on this forced stop 1652 this.instance.options.revert = false; 1653 1654 // The out event needs to be triggered independently 1655 this.instance._trigger('out', event, this.instance._uiHash(this.instance)); 1656 1657 this.instance._mouseStop(event, true); 1658 this.instance.options.helper = this.instance.options._helper; 1659 1660 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1661 this.instance.currentItem.remove(); 1662 if(this.instance.placeholder) this.instance.placeholder.remove(); 1663 1664 inst._trigger("fromSortable", event); 1665 inst.dropped = false; //draggable revert needs that 1666 } 1667 1668 }; 1669 1670 }); 1671 1672 } 1673}); 1674 1675$.ui.plugin.add("draggable", "cursor", { 1676 start: function(event, ui) { 1677 var t = $('body'), o = $(this).data('draggable').options; 1678 if (t.css("cursor")) o._cursor = t.css("cursor"); 1679 t.css("cursor", o.cursor); 1680 }, 1681 stop: function(event, ui) { 1682 var o = $(this).data('draggable').options; 1683 if (o._cursor) $('body').css("cursor", o._cursor); 1684 } 1685}); 1686 1687$.ui.plugin.add("draggable", "opacity", { 1688 start: function(event, ui) { 1689 var t = $(ui.helper), o = $(this).data('draggable').options; 1690 if(t.css("opacity")) o._opacity = t.css("opacity"); 1691 t.css('opacity', o.opacity); 1692 }, 1693 stop: function(event, ui) { 1694 var o = $(this).data('draggable').options; 1695 if(o._opacity) $(ui.helper).css('opacity', o._opacity); 1696 } 1697}); 1698 1699$.ui.plugin.add("draggable", "scroll", { 1700 start: function(event, ui) { 1701 var i = $(this).data("draggable"); 1702 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 1703 }, 1704 drag: function(event, ui) { 1705 1706 var i = $(this).data("draggable"), o = i.options, scrolled = false; 1707 1708 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 1709 1710 if(!o.axis || o.axis != 'x') { 1711 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 1712 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1713 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 1714 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1715 } 1716 1717 if(!o.axis || o.axis != 'y') { 1718 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 1719 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1720 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 1721 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1722 } 1723 1724 } else { 1725 1726 if(!o.axis || o.axis != 'x') { 1727 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 1728 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1729 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 1730 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1731 } 1732 1733 if(!o.axis || o.axis != 'y') { 1734 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 1735 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1736 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 1737 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1738 } 1739 1740 } 1741 1742 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 1743 $.ui.ddmanager.prepareOffsets(i, event); 1744 1745 } 1746}); 1747 1748$.ui.plugin.add("draggable", "snap", { 1749 start: function(event, ui) { 1750 1751 var i = $(this).data("draggable"), o = i.options; 1752 i.snapElements = []; 1753 1754 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { 1755 var $t = $(this); var $o = $t.offset(); 1756 if(this != i.element[0]) i.snapElements.push({ 1757 item: this, 1758 width: $t.outerWidth(), height: $t.outerHeight(), 1759 top: $o.top, left: $o.left 1760 }); 1761 }); 1762 1763 }, 1764 drag: function(event, ui) { 1765 1766 var inst = $(this).data("draggable"), o = inst.options; 1767 var d = o.snapTolerance; 1768 1769 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1770 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1771 1772 for (var i = inst.snapElements.length - 1; i >= 0; i--){ 1773 1774 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 1775 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 1776 1777 //Yes, I know, this is insane ;) 1778 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))) { 1779 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1780 inst.snapElements[i].snapping = false;
1781 continue; 1782 } 1783 1784 if(o.snapMode != 'inner') { 1785 var ts = Math.abs(t - y2) <= d; 1786 var bs = Math.abs(b - y1) <= d; 1787 var ls = Math.abs(l - x2) <= d; 1788 var rs = Math.abs(r - x1) <= d; 1789 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1790 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1791 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1792 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1793 } 1794 1795 var first = (ts || bs || ls || rs); 1796 1797 if(o.snapMode != 'outer') { 1798 var ts = Math.abs(t - y1) <= d; 1799 var bs = Math.abs(b - y2) <= d; 1800 var ls = Math.abs(l - x1) <= d; 1801 var rs = Math.abs(r - x2) <= d; 1802 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1803 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1804 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1805 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1806 } 1807 1808 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 1809 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1810 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1811 1812 }; 1813 1814 } 1815}); 1816 1817$.ui.plugin.add("draggable", "stack", { 1818 start: function(event, ui) { 1819 1820 var o = $(this).data("draggable").options; 1821 1822 var group = $.makeArray($(o.stack)).sort(function(a,b) { 1823 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1824 }); 1825 if (!group.length) { return; } 1826 1827 var min = parseInt(group[0].style.zIndex) || 0; 1828 $(group).each(function(i) { 1829 this.style.zIndex = min + i; 1830 }); 1831 1832 this[0].style.zIndex = min + group.length; 1833 1834 } 1835}); 1836 1837$.ui.plugin.add("draggable", "zIndex", { 1838 start: function(event, ui) { 1839 var t = $(ui.helper), o = $(this).data("draggable").options; 1840 if(t.css("zIndex")) o._zIndex = t.css("zIndex"); 1841 t.css('zIndex', o.zIndex); 1842 }, 1843 stop: function(event, ui) { 1844 var o = $(this).data("draggable").options; 1845 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); 1846 } 1847}); 1848 1849})(jQuery); 1850 1851(function( $, undefined ) { 1852 1853$.widget("ui.droppable", { 1854 version: "1.9.2", 1855 widgetEventPrefix: "drop", 1856 options: { 1857 accept: '*', 1858 activeClass: false, 1859 addClasses: true, 1860 greedy: false, 1861 hoverClass: false, 1862 scope: 'default', 1863 tolerance: 'intersect' 1864 }, 1865 _create: function() { 1866 1867 var o = this.options, accept = o.accept; 1868 this.isover = 0; this.isout = 1; 1869 1870 this.accept = $.isFunction(accept) ? accept : function(d) { 1871 return d.is(accept); 1872 }; 1873 1874 //Store the droppable's proportions 1875 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1876 1877 // Add the reference and positions to the manager 1878 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1879 $.ui.ddmanager.droppables[o.scope].push(this); 1880 1881 (o.addClasses && this.element.addClass("ui-droppable")); 1882 1883 }, 1884 1885 _destroy: function() { 1886 var drop = $.ui.ddmanager.droppables[this.options.scope]; 1887 for ( var i = 0; i < drop.length; i++ ) 1888 if ( drop[i] == this ) 1889 drop.splice(i, 1); 1890 1891 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1892 }, 1893 1894 _setOption: function(key, value) { 1895 1896 if(key == 'accept') { 1897 this.accept = $.isFunction(value) ? value : function(d) { 1898 return d.is(value); 1899 }; 1900 } 1901 $.Widget.prototype._setOption.apply(this, arguments); 1902 }, 1903 1904 _activate: function(event) { 1905 var draggable = $.ui.ddmanager.current; 1906 if(this.options.activeClass) this.element.addClass(this.options.activeClass); 1907 (draggable && this._trigger('activate', event, this.ui(draggable))); 1908 }, 1909 1910 _deactivate: function(event) { 1911 var draggable = $.ui.ddmanager.current; 1912 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 1913 (draggable && this._trigger('deactivate', event, this.ui(draggable))); 1914 }, 1915 1916 _over: function(event) { 1917 1918 var draggable = $.ui.ddmanager.current; 1919 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1920 1921 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 1922 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); 1923 this._trigger('over', event, this.ui(draggable)); 1924 } 1925 1926 }, 1927 1928 _out: function(event) { 1929 1930 var draggable = $.ui.ddmanager.current; 1931 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 1932 1933 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 1934 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 1935 this._trigger('out', event, this.ui(draggable)); 1936 } 1937 1938 }, 1939 1940 _drop: function(event,custom) { 1941 1942 var draggable = custom || $.ui.ddmanager.current; 1943 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 1944 1945 var childrenIntersection = false;
1946 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 1947 var inst = $.data(this, 'droppable'); 1948 if( 1949 inst.options.greedy 1950 && !inst.options.disabled 1951 && inst.options.scope == draggable.options.scope 1952 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) 1953 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 1954 ) { childrenIntersection = true; return false; } 1955 }); 1956 if(childrenIntersection) return false; 1957 1958 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 1959 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 1960 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 1961 this._trigger('drop', event, this.ui(draggable)); 1962 return this.element; 1963 } 1964 1965 return false; 1966 1967 }, 1968 1969 ui: function(c) { 1970 return { 1971 draggable: (c.currentItem || c.element), 1972 helper: c.helper, 1973 position: c.position, 1974 offset: c.positionAbs 1975 }; 1976 } 1977 1978}); 1979 1980$.ui.intersect = function(draggable, droppable, toleranceMode) { 1981 1982 if (!droppable.offset) return false; 1983 1984 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 1985 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 1986 var l = droppable.offset.left, r = l + droppable.proportions.width, 1987 t = droppable.offset.top, b = t + droppable.proportions.height; 1988 1989 switch (toleranceMode) { 1990 case 'fit': 1991 return (l <= x1 && x2 <= r 1992 && t <= y1 && y2 <= b); 1993 break; 1994 case 'intersect': 1995 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 1996 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 1997 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 1998 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 1999 break; 2000 case 'pointer': 2001 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 2002 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 2003 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 2004 return isOver; 2005 break; 2006 case 'touch': 2007 return ( 2008 (y1 >= t && y1 <= b) || // Top edge touching 2009 (y2 >= t && y2 <= b) || // Bottom edge touching 2010 (y1 < t && y2 > b) // Surrounded vertically 2011 ) && ( 2012 (x1 >= l && x1 <= r) || // Left edge touching 2013 (x2 >= l && x2 <= r) || // Right edge touching 2014 (x1 < l && x2 > r) // Surrounded horizontally 2015 ); 2016 break; 2017 default: 2018 return false; 2019 break; 2020 } 2021 2022}; 2023 2024/* 2025 This manager tracks offsets of draggables and droppables 2026*/ 2027$.ui.ddmanager = { 2028 current: null, 2029 droppables: { 'default': [] }, 2030 prepareOffsets: function(t, event) { 2031 2032 var m = $.ui.ddmanager.droppables[t.options.scope] || []; 2033 var type = event ? event.type : null; // workaround for #2317 2034 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 2035 2036 droppablesLoop: for (var i = 0; i < m.length; i++) { 2037 2038 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted 2039 for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item 2040 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue 2041 2042 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 2043 2044 m[i].offset = m[i].element.offset(); 2045 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2046 2047 } 2048 2049 }, 2050 drop: function(draggable, event) { 2051 2052 var dropped = false; 2053 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2054 2055 if(!this.options) return; 2056 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 2057 dropped = this._drop.call(this, event) || dropped; 2058 2059 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2060 this.isout = 1; this.isover = 0; 2061 this._deactivate.call(this, event); 2062 } 2063 2064 }); 2065 return dropped; 2066 2067 }, 2068 dragStart: function( draggable, event ) { 2069 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2070 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2071 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2072 }); 2073 }, 2074 drag: function(draggable, event) { 2075 2076 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2077 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2078 2079 //Run through all droppables and check their positions based on specific tolerance options 2080 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2081 2082 if(this.options.disabled || this.greedyChild || !this.visible) return; 2083 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 2084 2085 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 2086 if(!c) return; 2087 2088 var parentInstance; 2089 if (this.options.greedy) { 2090 // find droppable parents with same scope 2091 var scope = this.options.scope; 2092 var parent = this.element.parents(':data(droppable)').filter(function () { 2093 return $.data(this, 'droppable').options.scope === scope; 2094 }); 2095 2096 if (parent.length) { 2097 parentInstance = $.data(parent[0], 'droppable'); 2098 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 2099 } 2100 } 2101 2102 // we just moved into a greedy child 2103 if (parentInstance && c == 'isover') { 2104 parentInstance['isover'] = 0; 2105 parentInstance['isout'] = 1; 2106 parentInstance._out.call(parentInstance, event); 2107 } 2108 2109 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 2110 this[c == "isover" ? "_over" : "_out"].call(this, event); 2111 2112 // we just moved out of a greedy child 2113 if (parentInstance && c == 'isout') { 2114 parentInstance['isout'] = 0; 2115 parentInstance['isover'] = 1; 2116 parentInstance._over.call(parentInstance, event); 2117 } 2118 }); 2119 2120 }, 2121 dragStop: function( draggable, event ) { 2122 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2123 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2124 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2125 } 2126}; 2127 2128})(jQuery); 2129 2130(function( $, undefined ) { 2131 2132$.widget("ui.resizable", $.ui.mouse, { 2133 version: "1.9.2", 2134 widgetEventPrefix: "resize", 2135 options: { 2136 alsoResize: false, 2137 animate: false, 2138 animateDuration: "slow", 2139 animateEasing: "swing", 2140 aspectRatio: false, 2141 autoHide: false, 2142 containment: false, 2143 ghost: false, 2144 grid: false, 2145 handles: "e,s,se", 2146 helper: false, 2147 maxHeight: null, 2148 maxWidth: null, 2149 minHeight: 10, 2150 minWidth: 10, 2151 zIndex: 1000 2152 }, 2153 _create: function() { 2154 2155 var that = this, o = this.options; 2156 this.element.addClass("ui-resizable"); 2157 2158 $.extend(this, { 2159 _aspectRatio: !!(o.aspectRatio), 2160 aspectRatio: o.aspectRatio, 2161 originalElement: this.element, 2162 _proportionallyResizeElements: [], 2163 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null 2164 }); 2165 2166 //Wrap the element if it cannot hold child nodes 2167 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2168 2169 //Create a wrapper element and set the wrapper to the new current internal element 2170 this.element.wrap( 2171 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ 2172 position: this.element.css('position'), 2173 width: this.element.outerWidth(), 2174 height: this.element.outerHeight(), 2175 top: this.element.css('top'), 2176 left: this.element.css('left') 2177 }) 2178 ); 2179 2180 //Overwrite the original this.element 2181 this.element = this.element.parent().data( 2182 "resizable", this.element.data('resizable') 2183 ); 2184 2185 this.elementIsWrapper = true; 2186 2187 //Move margins to the wrapper 2188 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2189 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2190 2191 //Prevent Safari textarea resize 2192 this.originalResizeStyle = this.originalElement.css('resize'); 2193 this.originalElement.css('resize', 'none'); 2194 2195 //Push the actual element to our proportionallyResize internal array 2196 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 2197 2198 // avoid IE jump (hard set the margin) 2199 this.originalElement.css({ margin: this.originalElement.css('margin') }); 2200 2201 // fix handlers offset 2202 this._proportionallyResize(); 2203 2204 } 2205 2206 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' }); 2207 if(this.handles.constructor == String) { 2208 2209 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; 2210 var n = this.handles.split(","); this.handles = {}; 2211 2212 for(var i = 0; i < n.length; i++) { 2213 2214 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; 2215 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 2216 2217 // Apply zIndex to all handles - see #7960 2218 axis.css({ zIndex: o.zIndex }); 2219 2220 //TODO : What's going on here? 2221 if ('se' == handle) { 2222 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); 2223 }; 2224 2225 //Insert into internal handles object and append to element 2226 this.handles[handle] = '.ui-resizable-'+handle; 2227 this.element.append(axis); 2228 } 2229 2230 } 2231 2232 this._renderAxis = function(target) { 2233 2234 target = target || this.element; 2235 2236 for(var i in this.handles) { 2237 2238 if(this.handles[i].constructor == String) 2239 this.handles[i] = $(this.handles[i], this.element).show(); 2240 2241 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2242 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2243 2244 var axis = $(this.handles[i], this.element), padWrapper = 0; 2245 2246 //Checking the correct pad and border 2247 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2248 2249 //The padding type i have to apply... 2250 var padPos = [ 'padding',
2251 /ne|nw|n/.test(i) ? 'Top' : 2252 /se|sw|s/.test(i) ? 'Bottom' : 2253 /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 2254 2255 target.css(padPos, padWrapper); 2256 2257 this._proportionallyResize(); 2258 2259 } 2260 2261 //TODO: What's that good for? There's not anything to be executed left 2262 if(!$(this.handles[i]).length) 2263 continue; 2264 2265 } 2266 }; 2267 2268 //TODO: make renderAxis a prototype function 2269 this._renderAxis(this.element); 2270 2271 this._handles = $('.ui-resizable-handle', this.element) 2272 .disableSelection(); 2273 2274 //Matching axis name 2275 this._handles.mouseover(function() { 2276 if (!that.resizing) { 2277 if (this.className) 2278 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2279 //Axis, default = se 2280 that.axis = axis && axis[1] ? axis[1] : 'se'; 2281 } 2282 }); 2283 2284 //If we want to auto hide the elements 2285 if (o.autoHide) { 2286 this._handles.hide(); 2287 $(this.element) 2288 .addClass("ui-resizable-autohide") 2289 .mouseenter(function() { 2290 if (o.disabled) return; 2291 $(this).removeClass("ui-resizable-autohide"); 2292 that._handles.show(); 2293 }) 2294 .mouseleave(function(){ 2295 if (o.disabled) return; 2296 if (!that.resizing) { 2297 $(this).addClass("ui-resizable-autohide"); 2298 that._handles.hide(); 2299 } 2300 }); 2301 } 2302 2303 //Initialize the mouse interaction 2304 this._mouseInit(); 2305 2306 }, 2307 2308 _destroy: function() { 2309 2310 this._mouseDestroy(); 2311 2312 var _destroy = function(exp) { 2313 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2314 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 2315 }; 2316 2317 //TODO: Unwrap at same DOM position 2318 if (this.elementIsWrapper) { 2319 _destroy(this.element); 2320 var wrapper = this.element; 2321 this.originalElement.css({ 2322 position: wrapper.css('position'), 2323 width: wrapper.outerWidth(), 2324 height: wrapper.outerHeight(), 2325 top: wrapper.css('top'), 2326 left: wrapper.css('left') 2327 }).insertAfter( wrapper ); 2328 wrapper.remove(); 2329 } 2330 2331 this.originalElement.css('resize', this.originalResizeStyle); 2332 _destroy(this.originalElement); 2333 2334 return this; 2335 }, 2336 2337 _mouseCapture: function(event) { 2338 var handle = false; 2339 for (var i in this.handles) { 2340 if ($(this.handles[i])[0] == event.target) { 2341 handle = true; 2342 } 2343 } 2344 2345 return !this.options.disabled && handle; 2346 }, 2347 2348 _mouseStart: function(event) { 2349 2350 var o = this.options, iniPos = this.element.position(), el = this.element; 2351 2352 this.resizing = true; 2353 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 2354 2355 // bugfix for http://dev.jquery.com/ticket/1749 2356 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 2357 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); 2358 } 2359 2360 this._renderProxy(); 2361 2362 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 2363 2364 if (o.containment) { 2365 curleft += $(o.containment).scrollLeft() || 0; 2366 curtop += $(o.containment).scrollTop() || 0; 2367 } 2368 2369 //Store needed variables 2370 this.offset = this.helper.offset(); 2371 this.position = { left: curleft, top: curtop }; 2372 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2373 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2374 this.originalPosition = { left: curleft, top: curtop }; 2375 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2376 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2377 2378 //Aspect Ratio 2379 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2380 2381 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 2382 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 2383 2384 el.addClass("ui-resizable-resizing"); 2385 this._propagate("start", event); 2386 return true; 2387 }, 2388 2389 _mouseDrag: function(event) { 2390 2391 //Increase performance, avoid regex 2392 var el = this.helper, o = this.options, props = {}, 2393 that = this, smp = this.originalMousePosition, a = this.axis; 2394 2395 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; 2396 var trigger = this._change[a]; 2397 if (!trigger) return false;
2398 2399 // Calculate the attrs that will be change 2400 var data = trigger.apply(this, [event, dx, dy]); 2401 2402 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2403 this._updateVirtualBoundaries(event.shiftKey); 2404 if (this._aspectRatio || event.shiftKey) 2405 data = this._updateRatio(data, event); 2406 2407 data = this._respectSize(data, event); 2408 2409 // plugins callbacks need to be called first 2410 this._propagate("resize", event); 2411 2412 el.css({ 2413 top: this.position.top + "px", left: this.position.left + "px", 2414 width: this.size.width + "px", height: this.size.height + "px" 2415 }); 2416 2417 if (!this._helper && this._proportionallyResizeElements.length) 2418 this._proportionallyResize(); 2419 2420 this._updateCache(data); 2421 2422 // calling the user callback at the end 2423 this._trigger('resize', event, this.ui()); 2424 2425 return false; 2426 }, 2427 2428 _mouseStop: function(event) { 2429 2430 this.resizing = false; 2431 var o = this.options, that = this; 2432 2433 if(this._helper) { 2434 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2435 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2436 soffsetw = ista ? 0 : that.sizeDiff.width; 2437 2438 var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, 2439 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2440 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2441 2442 if (!o.animate) 2443 this.element.css($.extend(s, { top: top, left: left })); 2444 2445 that.helper.height(that.size.height); 2446 that.helper.width(that.size.width); 2447 2448 if (this._helper && !o.animate) this._proportionallyResize(); 2449 } 2450 2451 $('body').css('cursor', 'auto'); 2452 2453 this.element.removeClass("ui-resizable-resizing"); 2454 2455 this._propagate("stop", event); 2456 2457 if (this._helper) this.helper.remove(); 2458 return false; 2459 2460 }, 2461 2462 _updateVirtualBoundaries: function(forceAspectRatio) { 2463 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; 2464 2465 b = { 2466 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2467 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2468 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2469 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2470 }; 2471 2472 if(this._aspectRatio || forceAspectRatio) { 2473 // We want to create an enclosing box whose aspect ration is the requested one 2474 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2475 pMinWidth = b.minHeight * this.aspectRatio; 2476 pMinHeight = b.minWidth / this.aspectRatio; 2477 pMaxWidth = b.maxHeight * this.aspectRatio; 2478 pMaxHeight = b.maxWidth / this.aspectRatio; 2479 2480 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; 2481 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; 2482 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; 2483 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; 2484 } 2485 this._vBoundaries = b; 2486 }, 2487 2488 _updateCache: function(data) { 2489 var o = this.options; 2490 this.offset = this.helper.offset(); 2491 if (isNumber(data.left)) this.position.left = data.left; 2492 if (isNumber(data.top)) this.position.top = data.top; 2493 if (isNumber(data.height)) this.size.height = data.height; 2494 if (isNumber(data.width)) this.size.width = data.width; 2495 }, 2496 2497 _updateRatio: function(data, event) { 2498 2499 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 2500 2501 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); 2502 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); 2503 2504 if (a == 'sw') { 2505 data.left = cpos.left + (csize.width - data.width); 2506 data.top = null; 2507 } 2508 if (a == 'nw') { 2509 data.top = cpos.top + (csize.height - data.height); 2510 data.left = cpos.left + (csize.width - data.width); 2511 } 2512 2513 return data; 2514 }, 2515 2516 _respectSize: function(data, event) { 2517 2518 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, 2519 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2520 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 2521 2522 if (isminw) data.width = o.minWidth; 2523 if (isminh) data.height = o.minHeight; 2524 if (ismaxw) data.width = o.maxWidth; 2525 if (ismaxh) data.height = o.maxHeight; 2526 2527 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 2528 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2529 2530 if (isminw && cw) data.left = dw - o.minWidth; 2531 if (ismaxw && cw) data.left = dw - o.maxWidth; 2532 if (isminh && ch) data.top = dh - o.minHeight; 2533 if (ismaxh && ch) data.top = dh - o.maxHeight; 2534 2535 // fixing jump error on top/left - bug #2330 2536 var isNotwh = !data.width && !data.height; 2537 if (isNotwh && !data.left && data.top) data.top = null; 2538 else if (isNotwh && !data.top && data.left) data.left = null; 2539 2540 return data; 2541 }, 2542 2543 _proportionallyResize: function() { 2544 2545 var o = this.options; 2546 if (!this._proportionallyResizeElements.length) return; 2547 var element = this.helper || this.element; 2548 2549 for (var i=0; i < this._proportionallyResizeElements.length; i++) { 2550 2551 var prel = this._proportionallyResizeElements[i]; 2552 2553 if (!this.borderDif) { 2554 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 2555 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 2556 2557 this.borderDif = $.map(b, function(v, i) { 2558 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; 2559 return border + padding; 2560 }); 2561 } 2562 2563 prel.css({ 2564 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2565 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2566 }); 2567 2568 }; 2569 2570 }, 2571 2572 _renderProxy: function() { 2573 2574 var el = this.element, o = this.options; 2575 this.elementOffset = el.offset(); 2576 2577 if(this._helper) { 2578 2579 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 2580 2581 // fix ie6 offset TODO: This seems broken 2582 var ie6offset = ($.ui.ie6 ? 1 : 0), 2583 pxyoffset = ( $.ui.ie6 ? 2 : -1 ); 2584 2585 this.helper.addClass(this._helper).css({ 2586 width: this.element.outerWidth() + pxyoffset, 2587 height: this.element.outerHeight() + pxyoffset, 2588 position: 'absolute', 2589 left: this.elementOffset.left - ie6offset +'px', 2590 top: this.elementOffset.top - ie6offset +'px', 2591 zIndex: ++o.zIndex //TODO: Don't modify option 2592 }); 2593 2594 this.helper 2595 .appendTo("body") 2596 .disableSelection(); 2597 2598 } else { 2599 this.helper = this.element; 2600 } 2601 2602 }, 2603 2604 _change: { 2605 e: function(event, dx, dy) { 2606 return { width: this.originalSize.width + dx }; 2607 }, 2608 w: function(event, dx, dy) { 2609 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2610 return { left: sp.left + dx, width: cs.width - dx }; 2611 }, 2612 n: function(event, dx, dy) { 2613 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 2614 return { top: sp.top + dy, height: cs.height - dy }; 2615 }, 2616 s: function(event, dx, dy) { 2617 return { height: this.originalSize.height + dy }; 2618 }, 2619 se: function(event, dx, dy) { 2620 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2621 }, 2622 sw: function(event, dx, dy) { 2623 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2624 }, 2625 ne: function(event, dx, dy) { 2626 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2627 }, 2628 nw: function(event, dx, dy) { 2629 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2630 } 2631 }, 2632 2633 _propagate: function(n, event) { 2634 $.ui.plugin.call(this, n, [event, this.ui()]); 2635 (n != "resize" && this._trigger(n, event, this.ui())); 2636 }, 2637 2638 plugins: {}, 2639 2640 ui: function() { 2641 return { 2642 originalElement: this.originalElement, 2643 element: this.element, 2644 helper: this.helper, 2645 position: this.position, 2646 size: this.size, 2647 originalSize: this.originalSize, 2648 originalPosition: this.originalPosition 2649 }; 2650 } 2651 2652}); 2653 2654/* 2655 * Resizable Extensions 2656 */ 2657 2658$.ui.plugin.add("resizable", "alsoResize", { 2659 2660 start: function (event, ui) { 2661 var that = $(this).data("resizable"), o = that.options; 2662 2663 var _store = function (exp) { 2664 $(exp).each(function() { 2665 var el = $(this); 2666 el.data("resizable-alsoresize", { 2667 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 2668 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) 2669 }); 2670 }); 2671 }; 2672 2673 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 2674 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 2675 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 2676 }else{ 2677 _store(o.alsoResize); 2678 } 2679 }, 2680 2681 resize: function (event, ui) { 2682 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; 2683 2684 var delta = { 2685 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 2686 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 2687 }, 2688 2689 _alsoResize = function (exp, c) { 2690 $(exp).each(function() { 2691 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 2692 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; 2693
2694 $.each(css, function (i, prop) { 2695 var sum = (start[prop]||0) + (delta[prop]||0); 2696 if (sum && sum >= 0) 2697 style[prop] = sum || null; 2698 }); 2699 2700 el.css(style); 2701 }); 2702 }; 2703 2704 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { 2705 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 2706 }else{ 2707 _alsoResize(o.alsoResize); 2708 } 2709 }, 2710 2711 stop: function (event, ui) { 2712 $(this).removeData("resizable-alsoresize"); 2713 } 2714}); 2715 2716$.ui.plugin.add("resizable", "animate", { 2717 2718 stop: function(event, ui) { 2719 var that = $(this).data("resizable"), o = that.options; 2720 2721 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2722 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2723 soffsetw = ista ? 0 : that.sizeDiff.width; 2724 2725 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2726 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2727 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2728 2729 that.element.animate( 2730 $.extend(style, top && left ? { top: top, left: left } : {}), { 2731 duration: o.animateDuration, 2732 easing: o.animateEasing, 2733 step: function() { 2734 2735 var data = { 2736 width: parseInt(that.element.css('width'), 10), 2737 height: parseInt(that.element.css('height'), 10), 2738 top: parseInt(that.element.css('top'), 10), 2739 left: parseInt(that.element.css('left'), 10) 2740 }; 2741 2742 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); 2743 2744 // propagating resize, and updating values for each animation step 2745 that._updateCache(data); 2746 that._propagate("resize", event); 2747 2748 } 2749 } 2750 ); 2751 } 2752 2753}); 2754 2755$.ui.plugin.add("resizable", "containment", { 2756 2757 start: function(event, ui) { 2758 var that = $(this).data("resizable"), o = that.options, el = that.element; 2759 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2760 if (!ce) return; 2761 2762 that.containerElement = $(ce); 2763 2764 if (/document/.test(oc) || oc == document) { 2765 that.containerOffset = { left: 0, top: 0 }; 2766 that.containerPosition = { left: 0, top: 0 }; 2767 2768 that.parentData = { 2769 element: $(document), left: 0, top: 0, 2770 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2771 }; 2772 } 2773 2774 // i'm a node, so compute top, left, right, bottom 2775 else { 2776 var element = $(ce), p = []; 2777 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2778 2779 that.containerOffset = element.offset(); 2780 that.containerPosition = element.position(); 2781 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2782 2783 var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, 2784 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2785 2786 that.parentData = { 2787 element: ce, left: co.left, top: co.top, width: width, height: height 2788 }; 2789 } 2790 }, 2791 2792 resize: function(event, ui) { 2793 var that = $(this).data("resizable"), o = that.options, 2794 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, 2795 pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; 2796 2797 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 2798 2799 if (cp.left < (that._helper ? co.left : 0)) { 2800 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 2801 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 2802 that.position.left = o.helper ? co.left : 0; 2803 } 2804 2805 if (cp.top < (that._helper ? co.top : 0)) { 2806 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 2807 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 2808 that.position.top = that._helper ? co.top : 0; 2809 } 2810 2811 that.offset.left = that.parentData.left+that.position.left; 2812 that.offset.top = that.parentData.top+that.position.top; 2813 2814 var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), 2815 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 2816 2817 var isParent = that.containerElement.get(0) == that.element.parent().get(0), 2818 isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); 2819 2820 if(isParent && isOffsetRelative) woset -= that.parentData.left; 2821 2822 if (woset + that.size.width >= that.parentData.width) { 2823 that.size.width = that.parentData.width - woset; 2824 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 2825 } 2826 2827 if (hoset + that.size.height >= that.parentData.height) { 2828 that.size.height = that.parentData.height - hoset; 2829 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 2830 } 2831 }, 2832 2833 stop: function(event, ui){ 2834 var that = $(this).data("resizable"), o = that.options, cp = that.position, 2835 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; 2836 2837 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; 2838
2839 if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) 2840 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2841 2842 if (that._helper && !o.animate && (/static/).test(ce.css('position'))) 2843 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 2844 2845 } 2846}); 2847 2848$.ui.plugin.add("resizable", "ghost", { 2849 2850 start: function(event, ui) { 2851 2852 var that = $(this).data("resizable"), o = that.options, cs = that.size; 2853 2854 that.ghost = that.originalElement.clone(); 2855 that.ghost 2856 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 2857 .addClass('ui-resizable-ghost') 2858 .addClass(typeof o.ghost == 'string' ? o.ghost : ''); 2859 2860 that.ghost.appendTo(that.helper); 2861 2862 }, 2863 2864 resize: function(event, ui){ 2865 var that = $(this).data("resizable"), o = that.options; 2866 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); 2867 }, 2868 2869 stop: function(event, ui){ 2870 var that = $(this).data("resizable"), o = that.options; 2871 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); 2872 } 2873 2874}); 2875 2876$.ui.plugin.add("resizable", "grid", { 2877 2878 resize: function(event, ui) { 2879 var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey; 2880 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 2881 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); 2882 2883 if (/^(se|s|e)$/.test(a)) { 2884 that.size.width = os.width + ox; 2885 that.size.height = os.height + oy; 2886 } 2887 else if (/^(ne)$/.test(a)) { 2888 that.size.width = os.width + ox; 2889 that.size.height = os.height + oy; 2890 that.position.top = op.top - oy; 2891 } 2892 else if (/^(sw)$/.test(a)) { 2893 that.size.width = os.width + ox; 2894 that.size.height = os.height + oy; 2895 that.position.left = op.left - ox; 2896 } 2897 else { 2898 that.size.width = os.width + ox; 2899 that.size.height = os.height + oy; 2900 that.position.top = op.top - oy; 2901 that.position.left = op.left - ox; 2902 } 2903 } 2904 2905}); 2906 2907var num = function(v) { 2908 return parseInt(v, 10) || 0; 2909}; 2910 2911var isNumber = function(value) { 2912 return !isNaN(parseInt(value, 10)); 2913}; 2914 2915})(jQuery); 2916 2917(function( $, undefined ) { 2918 2919$.widget("ui.selectable", $.ui.mouse, { 2920 version: "1.9.2", 2921 options: { 2922 appendTo: 'body', 2923 autoRefresh: true, 2924 distance: 0, 2925 filter: '*', 2926 tolerance: 'touch' 2927 }, 2928 _create: function() { 2929 var that = this; 2930 2931 this.element.addClass("ui-selectable"); 2932 2933 this.dragged = false; 2934 2935 // cache selectee children based on filter 2936 var selectees; 2937 this.refresh = function() { 2938 selectees = $(that.options.filter, that.element[0]); 2939 selectees.addClass("ui-selectee"); 2940 selectees.each(function() { 2941 var $this = $(this); 2942 var pos = $this.offset(); 2943 $.data(this, "selectable-item", { 2944 element: this, 2945 $element: $this, 2946 left: pos.left, 2947 top: pos.top, 2948 right: pos.left + $this.outerWidth(), 2949 bottom: pos.top + $this.outerHeight(), 2950 startselected: false, 2951 selected: $this.hasClass('ui-selected'), 2952 selecting: $this.hasClass('ui-selecting'), 2953 unselecting: $this.hasClass('ui-unselecting') 2954 }); 2955 }); 2956 }; 2957 this.refresh(); 2958 2959 this.selectees = selectees.addClass("ui-selectee"); 2960 2961 this._mouseInit(); 2962 2963 this.helper = $("<div class='ui-selectable-helper'></div>"); 2964 }, 2965 2966 _destroy: function() { 2967 this.selectees 2968 .removeClass("ui-selectee") 2969 .removeData("selectable-item"); 2970 this.element 2971 .removeClass("ui-selectable ui-selectable-disabled"); 2972 this._mouseDestroy(); 2973 }, 2974 2975 _mouseStart: function(event) { 2976 var that = this; 2977 2978 this.opos = [event.pageX, event.pageY]; 2979 2980 if (this.options.disabled) 2981 return; 2982 2983 var options = this.options; 2984 2985 this.selectees = $(options.filter, this.element[0]); 2986 2987 this._trigger("start", event); 2988 2989 $(options.appendTo).append(this.helper); 2990 // position helper (lasso) 2991 this.helper.css({ 2992 "left": event.clientX, 2993 "top": event.clientY, 2994 "width": 0, 2995 "height": 0 2996 }); 2997 2998 if (options.autoRefresh) { 2999 this.refresh(); 3000 } 3001 3002 this.selectees.filter('.ui-selected').each(function() { 3003 var selectee = $.data(this, "selectable-item"); 3004 selectee.startselected = true; 3005 if (!event.metaKey && !event.ctrlKey) { 3006 selectee.$element.removeClass('ui-selected'); 3007 selectee.selected = false;
vendor: 4,195 bytes, lines 3008-3146
3008 selectee.$element.addClass('ui-unselecting'); 3009 selectee.unselecting = true; 3010 // selectable UNSELECTING callback 3011 that._trigger("unselecting", event, { 3012 unselecting: selectee.element 3013 }); 3014 } 3015 }); 3016 3017 $(event.target).parents().andSelf().each(function() { 3018 var selectee = $.data(this, "selectable-item"); 3019 if (selectee) { 3020 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); 3021 selectee.$element 3022 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3023 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3024 selectee.unselecting = !doSelect; 3025 selectee.selecting = doSelect; 3026 selectee.selected = doSelect; 3027 // selectable (UN)SELECTING callback 3028 if (doSelect) { 3029 that._trigger("selecting", event, { 3030 selecting: selectee.element 3031 }); 3032 } else { 3033 that._trigger("unselecting", event, { 3034 unselecting: selectee.element 3035 }); 3036 } 3037 return false; 3038 } 3039 }); 3040 3041 }, 3042 3043 _mouseDrag: function(event) { 3044 var that = this; 3045 this.dragged = true; 3046 3047 if (this.options.disabled) 3048 return; 3049 3050 var options = this.options; 3051 3052 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 3053 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 3054 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 3055 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3056 3057 this.selectees.each(function() { 3058 var selectee = $.data(this, "selectable-item"); 3059 //prevent helper from being selected if appendTo: selectable 3060 if (!selectee || selectee.element == that.element[0]) 3061 return; 3062 var hit = false; 3063 if (options.tolerance == 'touch') { 3064 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3065 } else if (options.tolerance == 'fit') { 3066 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3067 } 3068 3069 if (hit) { 3070 // SELECT 3071 if (selectee.selected) { 3072 selectee.$element.removeClass('ui-selected'); 3073 selectee.selected = false; 3074 } 3075 if (selectee.unselecting) { 3076 selectee.$element.removeClass('ui-unselecting'); 3077 selectee.unselecting = false; 3078 } 3079 if (!selectee.selecting) { 3080 selectee.$element.addClass('ui-selecting'); 3081 selectee.selecting = true; 3082 // selectable SELECTING callback 3083 that._trigger("selecting", event, { 3084 selecting: selectee.element 3085 }); 3086 } 3087 } else { 3088 // UNSELECT 3089 if (selectee.selecting) { 3090 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3091 selectee.$element.removeClass('ui-selecting'); 3092 selectee.selecting = false; 3093 selectee.$element.addClass('ui-selected'); 3094 selectee.selected = true; 3095 } else { 3096 selectee.$element.removeClass('ui-selecting'); 3097 selectee.selecting = false; 3098 if (selectee.startselected) { 3099 selectee.$element.addClass('ui-unselecting'); 3100 selectee.unselecting = true; 3101 } 3102 // selectable UNSELECTING callback 3103 that._trigger("unselecting", event, { 3104 unselecting: selectee.element 3105 }); 3106 } 3107 } 3108 if (selectee.selected) { 3109 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3110 selectee.$element.removeClass('ui-selected'); 3111 selectee.selected = false; 3112 3113 selectee.$element.addClass('ui-unselecting'); 3114 selectee.unselecting = true; 3115 // selectable UNSELECTING callback 3116 that._trigger("unselecting", event, { 3117 unselecting: selectee.element 3118 }); 3119 } 3120 } 3121 } 3122 }); 3123 3124 return false; 3125 }, 3126 3127 _mouseStop: function(event) { 3128 var that = this; 3129 3130 this.dragged = false; 3131 3132 var options = this.options; 3133 3134 $('.ui-unselecting', this.element[0]).each(function() { 3135 var selectee = $.data(this, "selectable-item"); 3136 selectee.$element.removeClass('ui-unselecting'); 3137 selectee.unselecting = false; 3138 selectee.startselected = false; 3139 that._trigger("unselected", event, { 3140 unselected: selectee.element 3141 }); 3142 }); 3143 $('.ui-selecting', this.element[0]).each(function() { 3144 var selectee = $.data(this, "selectable-item"); 3145 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 3146 selectee.selecting = false;
3147 selectee.selected = true; 3148 selectee.startselected = true; 3149 that._trigger("selected", event, { 3150 selected: selectee.element 3151 }); 3152 }); 3153 this._trigger("stop", event); 3154 3155 this.helper.remove(); 3156 3157 return false; 3158 } 3159 3160}); 3161 3162})(jQuery); 3163 3164(function( $, undefined ) { 3165 3166$.widget("ui.sortable", $.ui.mouse, { 3167 version: "1.9.2", 3168 widgetEventPrefix: "sort", 3169 ready: false, 3170 options: { 3171 appendTo: "parent", 3172 axis: false, 3173 connectWith: false, 3174 containment: false, 3175 cursor: 'auto', 3176 cursorAt: false, 3177 dropOnEmpty: true, 3178 forcePlaceholderSize: false, 3179 forceHelperSize: false, 3180 grid: false, 3181 handle: false, 3182 helper: "original", 3183 items: '> *', 3184 opacity: false, 3185 placeholder: false, 3186 revert: false, 3187 scroll: true, 3188 scrollSensitivity: 20, 3189 scrollSpeed: 20, 3190 scope: "default", 3191 tolerance: "intersect", 3192 zIndex: 1000 3193 }, 3194 _create: function() { 3195 3196 var o = this.options; 3197 this.containerCache = {}; 3198 this.element.addClass("ui-sortable"); 3199 3200 //Get the items 3201 this.refresh(); 3202 3203 //Let's determine if the items are being displayed horizontally 3204 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; 3205 3206 //Let's determine the parent's offset 3207 this.offset = this.element.offset(); 3208 3209 //Initialize mouse events for interaction 3210 this._mouseInit(); 3211 3212 //We're ready to go 3213 this.ready = true 3214 3215 }, 3216 3217 _destroy: function() { 3218 this.element 3219 .removeClass("ui-sortable ui-sortable-disabled"); 3220 this._mouseDestroy(); 3221 3222 for ( var i = this.items.length - 1; i >= 0; i-- ) 3223 this.items[i].item.removeData(this.widgetName + "-item"); 3224 3225 return this; 3226 }, 3227 3228 _setOption: function(key, value){ 3229 if ( key === "disabled" ) { 3230 this.options[ key ] = value; 3231 3232 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3233 } else { 3234 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3235 $.Widget.prototype._setOption.apply(this, arguments); 3236 } 3237 }, 3238 3239 _mouseCapture: function(event, overrideHandle) { 3240 var that = this; 3241 3242 if (this.reverting) { 3243 return false; 3244 } 3245 3246 if(this.options.disabled || this.options.type == 'static') return false; 3247 3248 //We have to refresh the items data once first 3249 this._refreshItems(event); 3250 3251 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3252 var currentItem = null, nodes = $(event.target).parents().each(function() { 3253 if($.data(this, that.widgetName + '-item') == that) { 3254 currentItem = $(this); 3255 return false; 3256 } 3257 }); 3258 if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); 3259 3260 if(!currentItem) return false; 3261 if(this.options.handle && !overrideHandle) { 3262 var validHandle = false; 3263 3264 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); 3265 if(!validHandle) return false; 3266 } 3267 3268 this.currentItem = currentItem; 3269 this._removeCurrentsFromItems(); 3270 return true; 3271 3272 }, 3273 3274 _mouseStart: function(event, overrideHandle, noActivation) { 3275 3276 var o = this.options; 3277 this.currentContainer = this; 3278 3279 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3280 this.refreshPositions(); 3281 3282 //Create and append the visible helper 3283 this.helper = this._createHelper(event); 3284 3285 //Cache the helper size 3286 this._cacheHelperProportions(); 3287 3288 /* 3289 * - Position generation - 3290 * This block generates everything position related - it's the core of draggables. 3291 */ 3292 3293 //Cache the margins of the original element 3294 this._cacheMargins(); 3295 3296 //Get the next scrolling parent 3297 this.scrollParent = this.helper.scrollParent(); 3298 3299 //The element's absolute position on the page minus margins 3300 this.offset = this.currentItem.offset(); 3301 this.offset = { 3302 top: this.offset.top - this.margins.top, 3303 left: this.offset.left - this.margins.left 3304 }; 3305 3306 $.extend(this.offset, { 3307 click: { //Where the click happened, relative to the element 3308 left: event.pageX - this.offset.left, 3309 top: event.pageY - this.offset.top 3310 }, 3311 parent: this._getParentOffset(), 3312 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3313 }); 3314 3315 // Only after we got the offset, we can change the helper's position to absolute 3316 // TODO: Still need to figure out a way to make relative sorting possible 3317 this.helper.css("position", "absolute"); 3318 this.cssPosition = this.helper.css("position"); 3319 3320 //Generate the original position 3321 this.originalPosition = this._generatePosition(event); 3322 this.originalPageX = event.pageX; 3323 this.originalPageY = event.pageY; 3324 3325 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 3326 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3327 3328 //Cache the former DOM position 3329 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3330 3331 //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 3332 if(this.helper[0] != this.currentItem[0]) { 3333 this.currentItem.hide(); 3334 } 3335 3336 //Create the placeholder 3337 this._createPlaceholder(); 3338 3339 //Set a containment if given in the options 3340 if(o.containment) 3341 this._setContainment(); 3342 3343 if(o.cursor) { // cursor option 3344 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); 3345 $('body').css("cursor", o.cursor); 3346 } 3347 3348 if(o.opacity) { // opacity option 3349 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); 3350 this.helper.css("opacity", o.opacity); 3351 } 3352 3353 if(o.zIndex) { // zIndex option 3354 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); 3355 this.helper.css("zIndex", o.zIndex); 3356 } 3357 3358 //Prepare scrolling 3359 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') 3360 this.overflowOffset = this.scrollParent.offset(); 3361 3362 //Call callbacks 3363 this._trigger("start", event, this._uiHash()); 3364 3365 //Recache the helper size 3366 if(!this._preserveHelperProportions) 3367 this._cacheHelperProportions(); 3368 3369 3370 //Post 'activate' events to possible containers 3371 if(!noActivation) { 3372 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } 3373 } 3374 3375 //Prepare possible droppables 3376 if($.ui.ddmanager) 3377 $.ui.ddmanager.current = this; 3378 3379 if ($.ui.ddmanager && !o.dropBehaviour) 3380 $.ui.ddmanager.prepareOffsets(this, event); 3381 3382 this.dragging = true; 3383 3384 this.helper.addClass("ui-sortable-helper"); 3385 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3386 return true; 3387 3388 }, 3389 3390 _mouseDrag: function(event) { 3391 3392 //Compute the helpers position 3393 this.position = this._generatePosition(event); 3394 this.positionAbs = this._convertPositionTo("absolute"); 3395 3396 if (!this.lastPositionAbs) { 3397 this.lastPositionAbs = this.positionAbs; 3398 } 3399 3400 //Do scrolling 3401 if(this.options.scroll) { 3402 var o = this.options, scrolled = false;
3403 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { 3404 3405 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 3406 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3407 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) 3408 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3409 3410 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 3411 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3412 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) 3413 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3414 3415 } else { 3416 3417 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 3418 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3419 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 3420 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3421 3422 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 3423 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3424 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 3425 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3426 3427 } 3428 3429 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 3430 $.ui.ddmanager.prepareOffsets(this, event); 3431 } 3432 3433 //Regenerate the absolute position used for position checks 3434 this.positionAbs = this._convertPositionTo("absolute"); 3435 3436 //Set the helper position 3437 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 3438 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 3439 3440 //Rearrange 3441 for (var i = this.items.length - 1; i >= 0; i--) { 3442 3443 //Cache variables and intersection, continue if no intersection 3444 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 3445 if (!intersection) continue; 3446 3447 // Only put the placeholder inside the current Container, skip all 3448 // items form other containers. This works because when moving 3449 // an item from one container to another the 3450 // currentContainer is switched before the placeholder is moved. 3451 // 3452 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3453 // beetween the outer and inner container. 3454 if (item.instance !== this.currentContainer) continue; 3455 3456 if (itemElement != this.currentItem[0] //cannot intersect with itself 3457 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 3458 && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 3459 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) 3460 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container 3461 ) { 3462 3463 this.direction = intersection == 1 ? "down" : "up"; 3464 3465 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 3466 this._rearrange(event, item); 3467 } else { 3468 break; 3469 } 3470 3471 this._trigger("change", event, this._uiHash()); 3472 break; 3473 } 3474 } 3475 3476 //Post events to containers 3477 this._contactContainers(event); 3478 3479 //Interconnect with droppables 3480 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 3481 3482 //Call callbacks 3483 this._trigger('sort', event, this._uiHash()); 3484 3485 this.lastPositionAbs = this.positionAbs; 3486 return false; 3487 3488 }, 3489 3490 _mouseStop: function(event, noPropagation) { 3491 3492 if(!event) return; 3493 3494 //If we are using droppables, inform the manager about the drop 3495 if ($.ui.ddmanager && !this.options.dropBehaviour) 3496 $.ui.ddmanager.drop(this, event); 3497 3498 if(this.options.revert) { 3499 var that = this; 3500 var cur = this.placeholder.offset(); 3501 3502 this.reverting = true; 3503 3504 $(this.helper).animate({ 3505 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 3506 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 3507 }, parseInt(this.options.revert, 10) || 500, function() { 3508 that._clear(event); 3509 }); 3510 } else { 3511 this._clear(event, noPropagation); 3512 } 3513 3514 return false;
3515 3516 }, 3517 3518 cancel: function() { 3519 3520 if(this.dragging) { 3521 3522 this._mouseUp({ target: null }); 3523 3524 if(this.options.helper == "original") 3525 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3526 else 3527 this.currentItem.show(); 3528 3529 //Post deactivating events to containers 3530 for (var i = this.containers.length - 1; i >= 0; i--){ 3531 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3532 if(this.containers[i].containerCache.over) { 3533 this.containers[i]._trigger("out", null, this._uiHash(this)); 3534 this.containers[i].containerCache.over = 0; 3535 } 3536 } 3537 3538 } 3539 3540 if (this.placeholder) { 3541 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3542 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3543 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 3544 3545 $.extend(this, { 3546 helper: null, 3547 dragging: false, 3548 reverting: false, 3549 _noFinalSort: null 3550 }); 3551 3552 if(this.domPosition.prev) { 3553 $(this.domPosition.prev).after(this.currentItem); 3554 } else { 3555 $(this.domPosition.parent).prepend(this.currentItem); 3556 } 3557 } 3558 3559 return this; 3560 3561 }, 3562 3563 serialize: function(o) { 3564 3565 var items = this._getItemsAsjQuery(o && o.connected); 3566 var str = []; o = o || {}; 3567 3568 $(items).each(function() { 3569 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 3570 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); 3571 }); 3572 3573 if(!str.length && o.key) { 3574 str.push(o.key + '='); 3575 } 3576 3577 return str.join('&'); 3578 3579 }, 3580 3581 toArray: function(o) { 3582 3583 var items = this._getItemsAsjQuery(o && o.connected); 3584 var ret = []; o = o || {}; 3585 3586 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 3587 return ret; 3588 3589 }, 3590 3591 /* Be careful with the following core functions */ 3592 _intersectsWith: function(item) { 3593 3594 var x1 = this.positionAbs.left, 3595 x2 = x1 + this.helperProportions.width, 3596 y1 = this.positionAbs.top, 3597 y2 = y1 + this.helperProportions.height; 3598 3599 var l = item.left, 3600 r = l + item.width, 3601 t = item.top, 3602 b = t + item.height; 3603 3604 var dyClick = this.offset.click.top, 3605 dxClick = this.offset.click.left; 3606 3607 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 3608 3609 if( this.options.tolerance == "pointer" 3610 || this.options.forcePointerForContainers 3611 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 3612 ) { 3613 return isOverElement; 3614 } else { 3615 3616 return (l < x1 + (this.helperProportions.width / 2) // Right Half 3617 && x2 - (this.helperProportions.width / 2) < r // Left Half 3618 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 3619 && y2 - (this.helperProportions.height / 2) < b ); // Top Half 3620 3621 } 3622 }, 3623 3624 _intersectsWithPointer: function(item) { 3625 3626 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 3627 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 3628 isOverElement = isOverElementHeight && isOverElementWidth, 3629 verticalDirection = this._getDragVerticalDirection(), 3630 horizontalDirection = this._getDragHorizontalDirection(); 3631 3632 if (!isOverElement) 3633 return false; 3634 3635 return this.floating ? 3636 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) 3637 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); 3638 3639 }, 3640 3641 _intersectsWithSides: function(item) { 3642 3643 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 3644 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 3645 verticalDirection = this._getDragVerticalDirection(), 3646 horizontalDirection = this._getDragHorizontalDirection(); 3647 3648 if (this.floating && horizontalDirection) { 3649 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 3650 } else { 3651 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 3652 } 3653 3654 }, 3655 3656 _getDragVerticalDirection: function() { 3657 var delta = this.positionAbs.top - this.lastPositionAbs.top; 3658 return delta != 0 && (delta > 0 ? "down" : "up"); 3659 }, 3660 3661 _getDragHorizontalDirection: function() { 3662 var delta = this.positionAbs.left - this.lastPositionAbs.left; 3663 return delta != 0 && (delta > 0 ? "right" : "left"); 3664 }, 3665 3666 refresh: function(event) { 3667 this._refreshItems(event); 3668 this.refreshPositions(); 3669 return this; 3670 }, 3671 3672 _connectWith: function() { 3673 var options = this.options; 3674 return options.connectWith.constructor == String
3675 ? [options.connectWith] 3676 : options.connectWith; 3677 }, 3678 3679 _getItemsAsjQuery: function(connected) { 3680 3681 var items = []; 3682 var queries = []; 3683 var connectWith = this._connectWith(); 3684 3685 if(connectWith && connected) { 3686 for (var i = connectWith.length - 1; i >= 0; i--){ 3687 var cur = $(connectWith[i]); 3688 for (var j = cur.length - 1; j >= 0; j--){ 3689 var inst = $.data(cur[j], this.widgetName); 3690 if(inst && inst != this && !inst.options.disabled) { 3691 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]); 3692 } 3693 }; 3694 }; 3695 } 3696 3697 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]); 3698 3699 for (var i = queries.length - 1; i >= 0; i--){ 3700 queries[i][0].each(function() { 3701 items.push(this); 3702 }); 3703 }; 3704 3705 return $(items); 3706 3707 }, 3708 3709 _removeCurrentsFromItems: function() { 3710 3711 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 3712 3713 this.items = $.grep(this.items, function (item) { 3714 for (var j=0; j < list.length; j++) { 3715 if(list[j] == item.item[0]) 3716 return false; 3717 }; 3718 return true; 3719 }); 3720 3721 }, 3722 3723 _refreshItems: function(event) { 3724 3725 this.items = []; 3726 this.containers = [this]; 3727 var items = this.items; 3728 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 3729 var connectWith = this._connectWith(); 3730 3731 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 3732 for (var i = connectWith.length - 1; i >= 0; i--){ 3733 var cur = $(connectWith[i]); 3734 for (var j = cur.length - 1; j >= 0; j--){ 3735 var inst = $.data(cur[j], this.widgetName); 3736 if(inst && inst != this && !inst.options.disabled) { 3737 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 3738 this.containers.push(inst); 3739 } 3740 }; 3741 }; 3742 } 3743 3744 for (var i = queries.length - 1; i >= 0; i--) { 3745 var targetData = queries[i][1]; 3746 var _queries = queries[i][0]; 3747 3748 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { 3749 var item = $(_queries[j]); 3750 3751 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) 3752 3753 items.push({ 3754 item: item, 3755 instance: targetData, 3756 width: 0, height: 0, 3757 left: 0, top: 0 3758 }); 3759 }; 3760 }; 3761 3762 }, 3763 3764 refreshPositions: function(fast) { 3765 3766 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 3767 if(this.offsetParent && this.helper) { 3768 this.offset.parent = this._getParentOffset(); 3769 } 3770 3771 for (var i = this.items.length - 1; i >= 0; i--){ 3772 var item = this.items[i]; 3773 3774 //We ignore calculating positions of all connected containers when we're not over them 3775 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 3776 continue; 3777 3778 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 3779 3780 if (!fast) { 3781 item.width = t.outerWidth(); 3782 item.height = t.outerHeight(); 3783 } 3784 3785 var p = t.offset(); 3786 item.left = p.left; 3787 item.top = p.top; 3788 }; 3789 3790 if(this.options.custom && this.options.custom.refreshContainers
3790) { 3791 this.options.custom.refreshContainers.call(this); 3792 } else { 3793 for (var i = this.containers.length - 1; i >= 0; i--){ 3794 var p = this.containers[i].element.offset(); 3795 this.containers[i].containerCache.left = p.left; 3796 this.containers[i].containerCache.top = p.top; 3797 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 3798 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 3799 }; 3800 } 3801 3802 return this; 3803 }, 3804 3805 _createPlaceholder: function(that) { 3806 that = that || this; 3807 var o = that.options; 3808 3809 if(!o.placeholder || o.placeholder.constructor == String) { 3810 var className = o.placeholder; 3811 o.placeholder = { 3812 element: function() { 3813 3814 var el = $(document.createElement(that.currentItem[0].nodeName)) 3815 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 3816 .removeClass("ui-sortable-helper")[0]; 3817 3818 if(!className) 3819 el.style.visibility = "hidden"; 3820 3821 return el; 3822 }, 3823 update: function(container, p) { 3824 3825 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 3826 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 3827 if(className && !o.forcePlaceholderSize) return; 3828 3829 //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
3830 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; 3831 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; 3832 } 3833 }; 3834 } 3835 3836 //Create the placeholder 3837 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 3838 3839 //Append it after the actual current item 3840 that.currentItem.after(that.placeholder); 3841 3842 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 3843 o.placeholder.update(that, that.placeholder); 3844 3845 }, 3846 3847 _contactContainers: function(event) { 3848 3849 // get innermost container that intersects with item 3850 var innermostContainer = null, innermostIndex = null; 3851 3852 3853 for (var i = this.containers.length - 1; i >= 0; i--){ 3854 3855 // never consider a container that's located within the item itself 3856 if($.contains(this.currentItem[0], this.containers[i].element[0])) 3857 continue; 3858 3859 if(this._intersectsWith(this.containers[i].containerCache)) { 3860 3861 // if we've already found a container and it's more "inner" than this, then continue 3862 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) 3863 continue; 3864 3865 innermostContainer = this.containers[i]; 3866 innermostIndex = i; 3867 3868 } else { 3869 // container doesn't intersect. trigger "out" event if necessary 3870 if(this.containers[i].containerCache.over) { 3871 this.containers[i]._trigger("out", event, this._uiHash(this)); 3872 this.containers[i].containerCache.over = 0; 3873 } 3874 } 3875 3876 } 3877 3878 // if no intersecting containers found, return 3879 if(!innermostContainer) return; 3880 3881 // move the item into the container if it's not there already 3882 if(this.containers.length === 1) { 3883 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 3884 this.containers[innermostIndex].containerCache.over = 1; 3885 } else { 3886 3887 //When entering a new container, we will find the item with the least distance and append our item near it 3888 var dist = 10000; var itemWithLeastDistance = null; 3889 var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; 3890 var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; 3891 var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 3892 for (var j = this.items.length - 1; j >= 0; j--) { 3893 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 3894 if(this.items[j].item[0] == this.currentItem[0]) continue; 3895 var cur = this.items[j].item.offset()[posProperty]; 3896 var nearBottom = false; 3897 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 3898 nearBottom = true; 3899 cur += this.items[j][sizeProperty]; 3900 } 3901 3902 if(Math.abs(cur - base) < dist) { 3903 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 3904 this.direction = nearBottom ? "up": "down"; 3905 } 3906 } 3907 3908 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 3909 return; 3910 3911 this.currentContainer = this.containers[innermostIndex]; 3912 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 3913 this._trigger("change", event, this._uiHash()); 3914 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 3915 3916 //Update the placeholder 3917 this.options.placeholder.update(this.currentContainer, this.placeholder); 3918 3919 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 3920 this.containers[innermostIndex].containerCache.over = 1; 3921 } 3922 3923 3924 }, 3925 3926 _createHelper: function(event) { 3927 3928 var o = this.options; 3929 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 3930 3931 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 3932 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 3933 3934 if(helper[0] == this.currentItem[0]) 3935 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
3935: this.currentItem.css("left") }; 3936 3937 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 3938 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 3939 3940 return helper; 3941 3942 }, 3943 3944 _adjustOffsetFromHelper: function(obj) { 3945 if (typeof obj == 'string') { 3946 obj = obj.split(' '); 3947 } 3948 if ($.isArray(obj)) { 3949 obj = {left: +obj[0], top: +obj[1] || 0}; 3950 } 3951 if ('left' in obj) { 3952 this.offset.click.left = obj.left + this.margins.left; 3953 } 3954 if ('right' in obj) { 3955 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 3956 } 3957 if ('top' in obj) { 3958 this.offset.click.top = obj.top + this.margins.top; 3959 } 3960 if ('bottom' in obj) { 3961 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 3962 } 3963 }, 3964 3965 _getParentOffset: function() { 3966 3967 3968 //Get the offsetParent and cache its position 3969 this.offsetParent = this.helper.offsetParent(); 3970 var po = this.offsetParent.offset(); 3971 3972 // This is a special case where we need to modify a offset calculated on start, since the following happened: 3973 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 3974 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 3975 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 3976 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 3977 po.left += this.scrollParent.scrollLeft(); 3978 po.top += this.scrollParent.scrollTop(); 3979 } 3980 3981 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 3982 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 3983 po = { top: 0, left: 0 }; 3984 3985 return { 3986 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 3987 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 3988 }; 3989 3990 }, 3991 3992 _getRelativeOffset: function() { 3993 3994 if(this.cssPosition == "relative") { 3995 var p = this.currentItem.position(); 3996 return { 3997 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 3998 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 3999 }; 4000 } else { 4001 return { top: 0, left: 0 }; 4002 } 4003 4004 }, 4005 4006 _cacheMargins: function() { 4007 this.margins = { 4008 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4009 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4010 }; 4011 }, 4012 4013 _cacheHelperProportions: function() { 4014 this.helperProportions = { 4015 width: this.helper.outerWidth(), 4016 height: this.helper.outerHeight() 4017 }; 4018 }, 4019 4020 _setContainment: function() { 4021 4022 var o = this.options; 4023 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 4024 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 4025 0 - this.offset.relative.left - this.offset.parent.left, 4026 0 - this.offset.relative.top - this.offset.parent.top, 4027 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 4028 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4029 ]; 4030 4031 if(!(/^(document|window|parent)$/).test(o.containment)) { 4032 var ce = $(o.containment)[0]; 4033 var co = $(o.containment).offset(); 4034 var over = ($(ce).css("overflow") != 'hidden'); 4035 4036 this.containment = [ 4037 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4038 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4039 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, 4040 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
404010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4041 ]; 4042 } 4043 4044 }, 4045 4046 _convertPositionTo: function(d, pos) { 4047 4048 if(!pos) pos = this.position; 4049 var mod = d == "absolute" ? 1 : -1; 4050 var o = this.options, 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); 4051 4052 return { 4053 top: ( 4054 pos.top // The absolute mouse position 4055 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4056 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 4057 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4058 ), 4059 left: ( 4060 pos.left // The absolute mouse position 4061 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4062 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 4063 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4064 ) 4065 }; 4066 4067 }, 4068 4069 _generatePosition: function(event) { 4070 4071 var o = this.options, 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); 4072 4073 // This is another very weird special case that only happens for relative elements: 4074 // 1. If the css position is relative 4075 // 2. and the scroll parent is the document or similar to the offset parent 4076 // we have to refresh the relative offset during the scroll so there are no jumps 4077 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { 4078 this.offset.relative = this._getRelativeOffset(); 4079 } 4080 4081 var pageX = event.pageX; 4082 var pageY = event.pageY; 4083 4084 /* 4085 * - Position constraining - 4086 * Constrain the position to a mix of grid, containment. 4087 */ 4088 4089 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4090 4091 if(this.containment) { 4092 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; 4093 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; 4094 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; 4095 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; 4096 } 4097 4098 if(o.grid) { 4099 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4100 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; 4101 4102 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4103 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; 4104 } 4105 4106 } 4107 4108 return { 4109 top: ( 4110 pageY // The absolute mouse position 4111 - this.offset.click.top // Click offset (relative to the element) 4112 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 4113 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 4114 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4115 ), 4116 left: ( 4117 pageX // The absolute mouse position 4118 - this.offset.click.left // Click offset (relative to the element) 4119 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 4120 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 4121 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4122 ) 4123 }; 4124 4125 }, 4126 4127 _rearrange: function(event, i, a, hardRefresh) { 4128 4129 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)); 4130 4131 //Various things done here to improve the performance: 4132 // 1. we create a setTimeout, that calls refreshPositions 4133 // 2. on the instance, we have a counter variable, that get's higher after every append 4134 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4135 // 4. this lets only the last addition to the timeout stack through 4136 this.counter = this.counter ? ++this.counter : 1; 4137 var counter = this.counter; 4138 4139 this._delay(function() {
4140 if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4141 }); 4142 4143 }, 4144 4145 _clear: function(event, noPropagation) { 4146 4147 this.reverting = false; 4148 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4149 // everything else normalized again 4150 var delayedTriggers = []; 4151 4152 // We first have to update the dom position of the actual currentItem 4153 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4154 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); 4155 this._noFinalSort = null; 4156 4157 if(this.helper[0] == this.currentItem[0]) { 4158 for(var i in this._storedCSS) { 4159 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 4160 } 4161 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4162 } else { 4163 this.currentItem.show(); 4164 } 4165 4166 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4167 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4168 4169 // Check if the items Container has Changed and trigger appropriate 4170 // events. 4171 if (this !== this.currentContainer) { 4172 if(!noPropagation) { 4173 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4174 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4175 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4176 } 4177 } 4178 4179 4180 //Post events to containers 4181 for (var i = this.containers.length - 1; i >= 0; i--){ 4182 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4183 if(this.containers[i].containerCache.over) { 4184 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4185 this.containers[i].containerCache.over = 0; 4186 } 4187 } 4188 4189 //Do what was originally in plugins 4190 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor 4191 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity 4192 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index 4193 4194 this.dragging = false; 4195 if(this.cancelHelperRemoval) { 4196 if(!noPropagation) { 4197 this._trigger("beforeStop", event, this._uiHash()); 4198 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4199 this._trigger("stop", event, this._uiHash()); 4200 } 4201 4202 this.fromOutside = false;
vendor: 32,198 bytes, lines 4203-5501
4203 return false; 4204 } 4205 4206 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); 4207 4208 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4209 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4210 4211 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; 4212 4213 if(!noPropagation) { 4214 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4215 this._trigger("stop", event, this._uiHash()); 4216 } 4217 4218 this.fromOutside = false; 4219 return true; 4220 4221 }, 4222 4223 _trigger: function() { 4224 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4225 this.cancel(); 4226 } 4227 }, 4228 4229 _uiHash: function(_inst) { 4230 var inst = _inst || this; 4231 return { 4232 helper: inst.helper, 4233 placeholder: inst.placeholder || $([]), 4234 position: inst.position, 4235 originalPosition: inst.originalPosition, 4236 offset: inst.positionAbs, 4237 item: inst.currentItem, 4238 sender: _inst ? _inst.element : null 4239 }; 4240 } 4241 4242}); 4243 4244})(jQuery); 4245 4246;(jQuery.effects || (function($, undefined) { 4247 4248var backCompat = $.uiBackCompat !== false, 4249 // prefix used for storing data on .data() 4250 dataSpace = "ui-effects-"; 4251 4252$.effects = { 4253 effect: {} 4254}; 4255 4256/*! 4257 * jQuery Color Animations v2.0.0 4258 * http://jquery.com/ 4259 * 4260 * Copyright 2012 jQuery Foundation and other contributors 4261 * Released under the MIT license. 4262 * http://jquery.org/license 4263 * 4264 * Date: Mon Aug 13 13:41:02 2012 -0500 4265 */ 4266(function( jQuery, undefined ) { 4267 4268 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), 4269 4270 // plusequals test for += 100 -= 100 4271 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4272 // a set of RE's that can match strings and generate color tuples. 4273 stringParsers = [{ 4274 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4275 parse: function( execResult ) { 4276 return [ 4277 execResult[ 1 ], 4278 execResult[ 2 ], 4279 execResult[ 3 ], 4280 execResult[ 4 ] 4281 ]; 4282 } 4283 }, { 4284 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4285 parse: function( execResult ) { 4286 return [ 4287 execResult[ 1 ] * 2.55, 4288 execResult[ 2 ] * 2.55, 4289 execResult[ 3 ] * 2.55, 4290 execResult[ 4 ] 4291 ]; 4292 } 4293 }, { 4294 // this regex ignores A-F because it's compared against an already lowercased string 4295 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4296 parse: function( execResult ) { 4297 return [ 4298 parseInt( execResult[ 1 ], 16 ), 4299 parseInt( execResult[ 2 ], 16 ), 4300 parseInt( execResult[ 3 ], 16 ) 4301 ]; 4302 } 4303 }, { 4304 // this regex ignores A-F because it's compared against an already lowercased string 4305 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4306 parse: function( execResult ) { 4307 return [ 4308 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4309 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4310 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4311 ]; 4312 } 4313 }, { 4314 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 4315 space: "hsla", 4316 parse: function( execResult ) { 4317 return [ 4318 execResult[ 1 ], 4319 execResult[ 2 ] / 100, 4320 execResult[ 3 ] / 100, 4321 execResult[ 4 ] 4322 ]; 4323 } 4324 }], 4325 4326 // jQuery.Color( ) 4327 color = jQuery.Color = function( color, green, blue, alpha ) { 4328 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4329 }, 4330 spaces = { 4331 rgba: { 4332 props: { 4333 red: { 4334 idx: 0, 4335 type: "byte" 4336 }, 4337 green: { 4338 idx: 1, 4339 type: "byte" 4340 }, 4341 blue: { 4342 idx: 2, 4343 type: "byte" 4344 } 4345 } 4346 }, 4347 4348 hsla: { 4349 props: { 4350 hue: { 4351 idx: 0, 4352 type: "degrees" 4353 }, 4354 saturation: { 4355 idx: 1, 4356 type: "percent" 4357 }, 4358 lightness: { 4359 idx: 2, 4360 type: "percent" 4361 } 4362 } 4363 } 4364 }, 4365 propTypes = { 4366 "byte": { 4367 floor: true, 4368 max: 255 4369 }, 4370 "percent": { 4371 max: 1 4372 }, 4373 "degrees": { 4374 mod: 360, 4375 floor: true 4376 } 4377 }, 4378 support = color.support = {}, 4379 4380 // element for support tests 4381 supportElem = jQuery( "<p>" )[ 0 ], 4382 4383 // colors = jQuery.Color.names 4384 colors, 4385 4386 // local aliases of functions called often 4387 each = jQuery.each; 4388 4389// determine rgba support immediately 4390supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4391support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4392 4393// define cache name and alpha properties 4394// for rgba and hsla spaces 4395each( spaces, function( spaceName, space ) { 4396 space.cache = "_" + spaceName; 4397 space.props.alpha = { 4398 idx: 3, 4399 type: "percent", 4400 def: 1 4401 }; 4402}); 4403 4404function clamp( value, prop, allowEmpty ) { 4405 var type = propTypes[ prop.type ] || {}; 4406 4407 if ( value == null ) { 4408 return (allowEmpty || !prop.def) ? null : prop.def; 4409 } 4410 4411 // ~~ is an short way of doing floor for positive numbers 4412 value = type.floor ? ~~value : parseFloat( value ); 4413 4414 // IE will pass in empty strings as value for alpha, 4415 // which will hit this case 4416 if ( isNaN( value ) ) { 4417 return prop.def; 4418 } 4419 4420 if ( type.mod ) { 4421 // we add mod before modding to make sure that negatives values 4422 // get converted properly: -10 -> 350 4423 return (value + type.mod) % type.mod; 4424 } 4425 4426 // for now all property types without mod have min and max 4427 return 0 > value ? 0 : type.max < value ? type.max : value; 4428} 4429 4430function stringParse( string ) { 4431 var inst = color(), 4432 rgba = inst._rgba = []; 4433 4434 string = string.toLowerCase(); 4435 4436 each( stringParsers, function( i, parser ) { 4437 var parsed, 4438 match = parser.re.exec( string ), 4439 values = match && parser.parse( match ), 4440 spaceName = parser.space || "rgba"; 4441 4442 if ( values ) { 4443 parsed = inst[ spaceName ]( values ); 4444 4445 // if this was an rgba parse the assignment might happen twice 4446 // oh well.... 4447 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4448 rgba = inst._rgba = parsed._rgba; 4449 4450 // exit each( stringParsers ) here because we matched 4451 return false; 4452 } 4453 }); 4454 4455 // Found a stringParser that handled it 4456 if ( rgba.length ) { 4457 4458 // if this came from a parsed string, force "transparent" when alpha is 0 4459 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4460 if ( rgba.join() === "0,0,0,0" ) { 4461 jQuery.extend( rgba, colors.transparent ); 4462 } 4463 return inst; 4464 } 4465 4466 // named colors 4467 return colors[ string ]; 4468} 4469 4470color.fn = jQuery.extend( color.prototype, { 4471 parse: function( red, green, blue, alpha ) { 4472 if ( red === undefined ) { 4473 this._rgba = [ null, null, null, null ]; 4474 return this; 4475 } 4476 if ( red.jquery || red.nodeType ) { 4477 red = jQuery( red ).css( green ); 4478 green = undefined; 4479 } 4480 4481 var inst = this, 4482 type = jQuery.type( red ), 4483 rgba = this._rgba = []; 4484 4485 // more than 1 argument specified - assume ( red, green, blue, alpha ) 4486 if ( green !== undefined ) { 4487 red = [ red, green, blue, alpha ]; 4488 type = "array"; 4489 } 4490 4491 if ( type === "string" ) { 4492 return this.parse( stringParse( red ) || colors._default ); 4493 } 4494 4495 if ( type === "array" ) { 4496 each( spaces.rgba.props, function( key, prop ) { 4497 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 4498 }); 4499 return this; 4500 } 4501 4502 if ( type === "object" ) { 4503 if ( red instanceof color ) { 4504 each( spaces, function( spaceName, space ) { 4505 if ( red[ space.cache ] ) { 4506 inst[ space.cache ] = red[ space.cache ].slice(); 4507 } 4508 }); 4509 } else { 4510 each( spaces, function( spaceName, space ) { 4511 var cache = space.cache; 4512 each( space.props, function( key, prop ) { 4513 4514 // if the cache doesn't exist, and we know how to convert 4515 if ( !inst[ cache ] && space.to ) { 4516 4517 // if the value was null, we don't need to copy it 4518 // if the key was alpha, we don't need to copy it either 4519 if ( key === "alpha" || red[ key ] == null ) { 4520 return; 4521 } 4522 inst[ cache ] = space.to( inst._rgba ); 4523 } 4524 4525 // this is the only case where we allow nulls for ALL properties. 4526 // call clamp with alwaysAllowEmpty 4527 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 4528 }); 4529 4530 // everything defined but alpha? 4531 if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 4532 // use the default of 1 4533 inst[ cache ][ 3 ] = 1; 4534 if ( space.from ) { 4535 inst._rgba = space.from( inst[ cache ] ); 4536 } 4537 } 4538 }); 4539 } 4540 return this; 4541 } 4542 }, 4543 is: function( compare ) { 4544 var is = color( compare ), 4545 same = true, 4546 inst = this; 4547 4548 each( spaces, function( _, space ) { 4549 var localCache, 4550 isCache = is[ space.cache ]; 4551 if (isCache) { 4552 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 4553 each( space.props, function( _, prop ) { 4554 if ( isCache[ prop.idx ] != null ) { 4555 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 4556 return same; 4557 } 4558 }); 4559 } 4560 return same; 4561 }); 4562 return same; 4563 }, 4564 _space: function() { 4565 var used = [], 4566 inst = this; 4567 each( spaces, function( spaceName, space ) { 4568 if ( inst[ space.cache ] ) { 4569 used.push( spaceName ); 4570 } 4571 }); 4572 return used.pop(); 4573 }, 4574 transition: function( other, distance ) { 4575 var end = color( other ), 4576 spaceName = end._space(), 4577 space = spaces[ spaceName ], 4578 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 4579 start = startColor[ space.cache ] || space.to( startColor._rgba ), 4580 result = start.slice(); 4581 4582 end = end[ space.cache ]; 4583 each( space.props, function( key, prop ) { 4584 var index = prop.idx, 4585 startValue = start[ index ], 4586 endValue = end[ index ], 4587 type = propTypes[ prop.type ] || {}; 4588 4589 // if null, don't override start value 4590 if ( endValue === null ) { 4591 return; 4592 } 4593 // if null - use end 4594 if ( startValue === null ) { 4595 result[ index ] = endValue; 4596 } else { 4597 if ( type.mod ) { 4598 if ( endValue - startValue > type.mod / 2 ) { 4599 startValue += type.mod; 4600 } else if ( startValue - endValue > type.mod / 2 ) { 4601 startValue -= type.mod; 4602 } 4603 } 4604 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 4605 } 4606 }); 4607 return this[ spaceName ]( result ); 4608 }, 4609 blend: function( opaque ) { 4610 // if we are already opaque - return ourself 4611 if ( this._rgba[ 3 ] === 1 ) { 4612 return this; 4613 } 4614 4615 var rgb = this._rgba.slice(), 4616 a = rgb.pop(), 4617 blend = color( opaque )._rgba; 4618 4619 return color( jQuery.map( rgb, function( v, i ) { 4620 return ( 1 - a ) * blend[ i ] + a * v; 4621 })); 4622 }, 4623 toRgbaString: function() { 4624 var prefix = "rgba(", 4625 rgba = jQuery.map( this._rgba, function( v, i ) { 4626 return v == null ? ( i > 2 ? 1 : 0 ) : v; 4627 }); 4628 4629 if ( rgba[ 3 ] === 1 ) { 4630 rgba.pop(); 4631 prefix = "rgb("; 4632 } 4633 4634 return prefix + rgba.join() + ")"; 4635 }, 4636 toHslaString: function() { 4637 var prefix = "hsla(", 4638 hsla = jQuery.map( this.hsla(), function( v, i ) { 4639 if ( v == null ) { 4640 v = i > 2 ? 1 : 0; 4641 } 4642 4643 // catch 1 and 2 4644 if ( i && i < 3 ) { 4645 v = Math.round( v * 100 ) + "%"; 4646 } 4647 return v; 4648 }); 4649 4650 if ( hsla[ 3 ] === 1 ) { 4651 hsla.pop(); 4652 prefix = "hsl("; 4653 } 4654 return prefix + hsla.join() + ")"; 4655 }, 4656 toHexString: function( includeAlpha ) { 4657 var rgba = this._rgba.slice(), 4658 alpha = rgba.pop(); 4659 4660 if ( includeAlpha ) { 4661 rgba.push( ~~( alpha * 255 ) ); 4662 } 4663 4664 return "#" + jQuery.map( rgba, function( v ) { 4665 4666 // default to 0 when nulls exist 4667 v = ( v || 0 ).toString( 16 ); 4668 return v.length === 1 ? "0" + v : v; 4669 }).join(""); 4670 }, 4671 toString: function() { 4672 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 4673 } 4674}); 4675color.fn.parse.prototype = color.fn; 4676 4677// hsla conversions adapted from: 4678// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 4679 4680function hue2rgb( p, q, h ) { 4681 h = ( h + 1 ) % 1; 4682 if ( h * 6 < 1 ) { 4683 return p + (q - p) * h * 6; 4684 } 4685 if ( h * 2 < 1) { 4686 return q; 4687 } 4688 if ( h * 3 < 2 ) { 4689 return p + (q - p) * ((2/3) - h) * 6; 4690 } 4691 return p; 4692} 4693 4694spaces.hsla.to = function ( rgba ) { 4695 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 4696 return [ null, null, null, rgba[ 3 ] ]; 4697 } 4698 var r = rgba[ 0 ] / 255, 4699 g = rgba[ 1 ] / 255, 4700 b = rgba[ 2 ] / 255, 4701 a = rgba[ 3 ], 4702 max = Math.max( r, g, b ), 4703 min = Math.min( r, g, b ), 4704 diff = max - min, 4705 add = max + min, 4706 l = add * 0.5, 4707 h, s; 4708 4709 if ( min === max ) { 4710 h = 0; 4711 } else if ( r === max ) { 4712 h = ( 60 * ( g - b ) / diff ) + 360; 4713 } else if ( g === max ) { 4714 h = ( 60 * ( b - r ) / diff ) + 120; 4715 } else { 4716 h = ( 60 * ( r - g ) / diff ) + 240; 4717 } 4718 4719 if ( l === 0 || l === 1 ) { 4720 s = l; 4721 } else if ( l <= 0.5 ) { 4722 s = diff / add; 4723 } else { 4724 s = diff / ( 2 - add ); 4725 } 4726 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 4727}; 4728 4729spaces.hsla.from = function ( hsla ) { 4730 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 4731 return [ null, null, null, hsla[ 3 ] ]; 4732 } 4733 var h = hsla[ 0 ] / 360, 4734 s = hsla[ 1 ], 4735 l = hsla[ 2 ], 4736 a = hsla[ 3 ], 4737 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 4738 p = 2 * l - q; 4739 4740 return [ 4741 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 4742 Math.round( hue2rgb( p, q, h ) * 255 ), 4743 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 4744 a 4745 ]; 4746}; 4747 4748 4749each( spaces, function( spaceName, space ) { 4750 var props = space.props, 4751 cache = space.cache, 4752 to = space.to, 4753 from = space.from; 4754 4755 // makes rgba() and hsla() 4756 color.fn[ spaceName ] = function( value ) { 4757 4758 // generate a cache for this space if it doesn't exist 4759 if ( to && !this[ cache ] ) { 4760 this[ cache ] = to( this._rgba ); 4761 } 4762 if ( value === undefined ) { 4763 return this[ cache ].slice(); 4764 } 4765 4766 var ret, 4767 type = jQuery.type( value ), 4768 arr = ( type === "array" || type === "object" ) ? value : arguments, 4769 local = this[ cache ].slice(); 4770 4771 each( props, function( key, prop ) { 4772 var val = arr[ type === "object" ? key : prop.idx ]; 4773 if ( val == null ) { 4774 val = local[ prop.idx ]; 4775 } 4776 local[ prop.idx ] = clamp( val, prop ); 4777 }); 4778 4779 if ( from ) { 4780 ret = color( from( local ) ); 4781 ret[ cache ] = local; 4782 return ret; 4783 } else { 4784 return color( local ); 4785 } 4786 }; 4787 4788 // makes red() green() blue() alpha() hue() saturation() lightness() 4789 each( props, function( key, prop ) { 4790 // alpha is included in more than one space 4791 if ( color.fn[ key ] ) { 4792 return; 4793 } 4794 color.fn[ key ] = function( value ) { 4795 var vtype = jQuery.type( value ), 4796 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 4797 local = this[ fn ](), 4798 cur = local[ prop.idx ], 4799 match; 4800 4801 if ( vtype === "undefined" ) { 4802 return cur; 4803 } 4804 4805 if ( vtype === "function" ) { 4806 value = value.call( this, cur ); 4807 vtype = jQuery.type( value ); 4808 } 4809 if ( value == null && prop.empty ) { 4810 return this; 4811 } 4812 if ( vtype === "string" ) { 4813 match = rplusequals.exec( value ); 4814 if ( match ) { 4815 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 4816 } 4817 } 4818 local[ prop.idx ] = value; 4819 return this[ fn ]( local ); 4820 }; 4821 }); 4822}); 4823 4824// add .fx.step functions 4825each( stepHooks, function( i, hook ) { 4826 jQuery.cssHooks[ hook ] = { 4827 set: function( elem, value ) { 4828 var parsed, curElem, 4829 backgroundColor = ""; 4830 4831 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 4832 value = color( parsed || value ); 4833 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 4834 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 4835 while ( 4836 (backgroundColor === "" || backgroundColor === "transparent") && 4837 curElem && curElem.style 4838 ) { 4839 try { 4840 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 4841 curElem = curElem.parentNode; 4842 } catch ( e ) { 4843 } 4844 } 4845 4846 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 4847 backgroundColor : 4848 "_default" ); 4849 } 4850 4851 value = value.toRgbaString(); 4852 } 4853 try { 4854 elem.style[ hook ] = value; 4855 } catch( error ) { 4856 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 4857 } 4858 } 4859 }; 4860 jQuery.fx.step[ hook ] = function( fx ) { 4861 if ( !fx.colorInit ) { 4862 fx.start = color( fx.elem, hook ); 4863 fx.end = color( fx.end ); 4864 fx.colorInit = true; 4865 } 4866 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 4867 }; 4868}); 4869 4870jQuery.cssHooks.borderColor = { 4871 expand: function( value ) { 4872 var expanded = {}; 4873 4874 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 4875 expanded[ "border" + part + "Color" ] = value; 4876 }); 4877 return expanded; 4878 } 4879}; 4880 4881// Basic color names only. 4882// Usage of any of the other color names requires adding yourself or including 4883// jquery.color.svg-names.js. 4884colors = jQuery.Color.names = { 4885 // 4.1. Basic color keywords 4886 aqua: "#00ffff", 4887 black: "#000000", 4888 blue: "#0000ff", 4889 fuchsia: "#ff00ff", 4890 gray: "#808080", 4891 green: "#008000", 4892 lime: "#00ff00", 4893 maroon: "#800000", 4894 navy: "#000080", 4895 olive: "#808000", 4896 purple: "#800080", 4897 red: "#ff0000", 4898 silver: "#c0c0c0", 4899 teal: "#008080", 4900 white: "#ffffff", 4901 yellow: "#ffff00", 4902 4903 // 4.2.3. "transparent" color keyword 4904 transparent: [ null, null, null, 0 ], 4905 4906 _default: "#ffffff" 4907}; 4908 4909})( jQuery ); 4910 4911 4912 4913/******************************************************************************/ 4914/****************************** CLASS ANIMATIONS ******************************/ 4915/******************************************************************************/ 4916(function() { 4917 4918var classAnimationActions = [ "add", "remove", "toggle" ], 4919 shorthandStyles = { 4920 border: 1, 4921 borderBottom: 1, 4922 borderColor: 1, 4923 borderLeft: 1, 4924 borderRight: 1, 4925 borderTop: 1, 4926 borderWidth: 1, 4927 margin: 1, 4928 padding: 1 4929 }; 4930 4931$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 4932 $.fx.step[ prop ] = function( fx ) { 4933 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 4934 jQuery.style( fx.elem, prop, fx.end ); 4935 fx.setAttr = true; 4936 } 4937 }; 4938}); 4939 4940function getElementStyles() { 4941 var style = this.ownerDocument.defaultView ? 4942 this.ownerDocument.defaultView.getComputedStyle( this, null ) : 4943 this.currentStyle, 4944 newStyle = {}, 4945 key, 4946 len; 4947 4948 // webkit enumerates style porperties 4949 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 4950 len = style.length; 4951 while ( len-- ) { 4952 key = style[ len ]; 4953 if ( typeof style[ key ] === "string" ) { 4954 newStyle[ $.camelCase( key ) ] = style[ key ]; 4955 } 4956 } 4957 } else { 4958 for ( key in style ) { 4959 if ( typeof style[ key ] === "string" ) { 4960 newStyle[ key ] = style[ key ]; 4961 } 4962 } 4963 } 4964 4965 return newStyle; 4966} 4967 4968 4969function styleDifference( oldStyle, newStyle ) { 4970 var diff = {}, 4971 name, value; 4972 4973 for ( name in newStyle ) { 4974 value = newStyle[ name ]; 4975 if ( oldStyle[ name ] !== value ) { 4976 if ( !shorthandStyles[ name ] ) { 4977 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 4978 diff[ name ] = value; 4979 } 4980 } 4981 } 4982 } 4983 4984 return diff; 4985} 4986 4987$.effects.animateClass = function( value, duration, easing, callback ) { 4988 var o = $.speed( duration, easing, callback ); 4989 4990 return this.queue( function() { 4991 var animated = $( this ), 4992 baseClass = animated.attr( "class" ) || "", 4993 applyClassChange, 4994 allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; 4995 4996 // map the animated objects to store the original styles. 4997 allAnimations = allAnimations.map(function() { 4998 var el = $( this ); 4999 return { 5000 el: el, 5001 start: getElementStyles.call( this ) 5002 }; 5003 }); 5004 5005 // apply class change 5006 applyClassChange = function() { 5007 $.each( classAnimationActions, function(i, action) { 5008 if ( value[ action ] ) { 5009 animated[ action + "Class" ]( value[ action ] ); 5010 } 5011 }); 5012 }; 5013 applyClassChange(); 5014 5015 // map all animated objects again - calculate new styles and diff 5016 allAnimations = allAnimations.map(function() { 5017 this.end = getElementStyles.call( this.el[ 0 ] ); 5018 this.diff = styleDifference( this.start, this.end ); 5019 return this; 5020 }); 5021 5022 // apply original class 5023 animated.attr( "class", baseClass ); 5024 5025 // map all animated objects again - this time collecting a promise 5026 allAnimations = allAnimations.map(function() { 5027 var styleInfo = this, 5028 dfd = $.Deferred(), 5029 opts = jQuery.extend({}, o, { 5030 queue: false, 5031 complete: function() { 5032 dfd.resolve( styleInfo ); 5033 } 5034 }); 5035 5036 this.el.animate( this.diff, opts ); 5037 return dfd.promise(); 5038 }); 5039 5040 // once all animations have completed: 5041 $.when.apply( $, allAnimations.get() ).done(function() { 5042 5043 // set the final class 5044 applyClassChange(); 5045 5046 // for each animated element, 5047 // clear all css properties that were animated 5048 $.each( arguments, function() { 5049 var el = this.el; 5050 $.each( this.diff, function(key) { 5051 el.css( key, '' ); 5052 }); 5053 }); 5054 5055 // this is guarnteed to be there if you use jQuery.speed() 5056 // it also handles dequeuing the next anim... 5057 o.complete.call( animated[ 0 ] ); 5058 }); 5059 }); 5060}; 5061 5062$.fn.extend({ 5063 _addClass: $.fn.addClass, 5064 addClass: function( classNames, speed, easing, callback ) { 5065 return speed ? 5066 $.effects.animateClass.call( this, 5067 { add: classNames }, speed, easing, callback ) : 5068 this._addClass( classNames ); 5069 }, 5070 5071 _removeClass: $.fn.removeClass, 5072 removeClass: function( classNames, speed, easing, callback ) { 5073 return speed ? 5074 $.effects.animateClass.call( this, 5075 { remove: classNames }, speed, easing, callback ) : 5076 this._removeClass( classNames ); 5077 }, 5078 5079 _toggleClass: $.fn.toggleClass, 5080 toggleClass: function( classNames, force, speed, easing, callback ) { 5081 if ( typeof force === "boolean" || force === undefined ) { 5082 if ( !speed ) { 5083 // without speed parameter 5084 return this._toggleClass( classNames, force ); 5085 } else { 5086 return $.effects.animateClass.call( this, 5087 (force ? { add: classNames } : { remove: classNames }), 5088 speed, easing, callback ); 5089 } 5090 } else { 5091 // without force parameter 5092 return $.effects.animateClass.call( this, 5093 { toggle: classNames }, force, speed, easing ); 5094 } 5095 }, 5096 5097 switchClass: function( remove, add, speed, easing, callback) { 5098 return $.effects.animateClass.call( this, { 5099 add: add, 5100 remove: remove 5101 }, speed, easing, callback ); 5102 } 5103}); 5104 5105})(); 5106 5107/******************************************************************************/ 5108/*********************************** EFFECTS **********************************/ 5109/******************************************************************************/ 5110 5111(function() { 5112 5113$.extend( $.effects, { 5114 version: "1.9.2", 5115 5116 // Saves a set of properties in a data storage 5117 save: function( element, set ) { 5118 for( var i=0; i < set.length; i++ ) { 5119 if ( set[ i ] !== null ) { 5120 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5121 } 5122 } 5123 }, 5124 5125 // Restores a set of previously saved properties from a data storage 5126 restore: function( element, set ) { 5127 var val, i; 5128 for( i=0; i < set.length; i++ ) { 5129 if ( set[ i ] !== null ) { 5130 val = element.data( dataSpace + set[ i ] ); 5131 // support: jQuery 1.6.2 5132 // http://bugs.jquery.com/ticket/9917 5133 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5134 // We can't differentiate between "" and 0 here, so we just assume 5135 // empty string since it's likely to be a more common value... 5136 if ( val === undefined ) { 5137 val = ""; 5138 } 5139 element.css( set[ i ], val ); 5140 } 5141 } 5142 }, 5143 5144 setMode: function( el, mode ) { 5145 if (mode === "toggle") { 5146 mode = el.is( ":hidden" ) ? "show" : "hide"; 5147 } 5148 return mode; 5149 }, 5150 5151 // Translates a [top,left] array into a baseline value 5152 // this should be a little more flexible in the future to handle a string & hash 5153 getBaseline: function( origin, original ) { 5154 var y, x; 5155 switch ( origin[ 0 ] ) { 5156 case "top": y = 0; break; 5157 case "middle": y = 0.5; break; 5158 case "bottom": y = 1; break; 5159 default: y = origin[ 0 ] / original.height; 5160 } 5161 switch ( origin[ 1 ] ) { 5162 case "left": x = 0; break; 5163 case "center": x = 0.5; break; 5164 case "right": x = 1; break; 5165 default: x = origin[ 1 ] / original.width; 5166 } 5167 return { 5168 x: x, 5169 y: y 5170 }; 5171 }, 5172 5173 // Wraps the element around a wrapper that copies position properties 5174 createWrapper: function( element ) { 5175 5176 // if the element is already wrapped, return it 5177 if ( element.parent().is( ".ui-effects-wrapper" )) { 5178 return element.parent(); 5179 } 5180 5181 // wrap the element 5182 var props = { 5183 width: element.outerWidth(true), 5184 height: element.outerHeight(true), 5185 "float": element.css( "float" ) 5186 }, 5187 wrapper = $( "<div></div>" ) 5188 .addClass( "ui-effects-wrapper" ) 5189 .css({ 5190 fontSize: "100%", 5191 background: "transparent", 5192 border: "none", 5193 margin: 0, 5194 padding: 0 5195 }), 5196 // Store the size in case width/height are defined in % - Fixes #5245 5197 size = { 5198 width: element.width(), 5199 height: element.height() 5200 }, 5201 active = document.activeElement; 5202 5203 // support: Firefox 5204 // Firefox incorrectly exposes anonymous content 5205 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5206 try { 5207 active.id; 5208 } catch( e ) { 5209 active = document.body; 5210 } 5211 5212 element.wrap( wrapper ); 5213 5214 // Fixes #7595 - Elements lose focus when wrapped. 5215 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5216 $( active ).focus(); 5217 } 5218 5219 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5220 5221 // transfer positioning properties to the wrapper 5222 if ( element.css( "position" ) === "static" ) { 5223 wrapper.css({ position: "relative" }); 5224 element.css({ position: "relative" }); 5225 } else { 5226 $.extend( props, { 5227 position: element.css( "position" ), 5228 zIndex: element.css( "z-index" ) 5229 }); 5230 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5231 props[ pos ] = element.css( pos ); 5232 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5233 props[ pos ] = "auto"; 5234 } 5235 }); 5236 element.css({ 5237 position: "relative", 5238 top: 0, 5239 left: 0, 5240 right: "auto", 5241 bottom: "auto" 5242 }); 5243 } 5244 element.css(size); 5245 5246 return wrapper.css( props ).show(); 5247 }, 5248 5249 removeWrapper: function( element ) { 5250 var active = document.activeElement; 5251 5252 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5253 element.parent().replaceWith( element ); 5254 5255 // Fixes #7595 - Elements lose focus when wrapped. 5256 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5257 $( active ).focus(); 5258 } 5259 } 5260 5261 5262 return element; 5263 }, 5264 5265 setTransition: function( element, list, factor, value ) { 5266 value = value || {}; 5267 $.each( list, function( i, x ) { 5268 var unit = element.cssUnit( x ); 5269 if ( unit[ 0 ] > 0 ) { 5270 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5271 } 5272 }); 5273 return value; 5274 } 5275}); 5276 5277// return an effect options object for the given parameters: 5278function _normalizeArguments( effect, options, speed, callback ) { 5279 5280 // allow passing all options as the first parameter 5281 if ( $.isPlainObject( effect ) ) { 5282 options = effect; 5283 effect = effect.effect; 5284 } 5285 5286 // convert to an object 5287 effect = { effect: effect }; 5288 5289 // catch (effect, null, ...) 5290 if ( options == null ) { 5291 options = {}; 5292 } 5293 5294 // catch (effect, callback) 5295 if ( $.isFunction( options ) ) { 5296 callback = options; 5297 speed = null; 5298 options = {}; 5299 } 5300 5301 // catch (effect, speed, ?) 5302 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5303 callback = speed; 5304 speed = options; 5305 options = {}; 5306 } 5307 5308 // catch (effect, options, callback) 5309 if ( $.isFunction( speed ) ) { 5310 callback = speed; 5311 speed = null; 5312 } 5313 5314 // add options to effect 5315 if ( options ) { 5316 $.extend( effect, options ); 5317 } 5318 5319 speed = speed || options.duration; 5320 effect.duration = $.fx.off ? 0 : 5321 typeof speed === "number" ? speed : 5322 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5323 $.fx.speeds._default; 5324 5325 effect.complete = callback || options.complete; 5326 5327 return effect; 5328} 5329 5330function standardSpeed( speed ) { 5331 // valid standard speeds 5332 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 5333 return true; 5334 } 5335 5336 // invalid strings - treat as "normal" speed 5337 if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { 5338 // TODO: remove in 2.0 (#7115) 5339 if ( backCompat && $.effects[ speed ] ) { 5340 return false; 5341 } 5342 return true; 5343 } 5344 5345 return false; 5346} 5347 5348$.fn.extend({ 5349 effect: function( /* effect, options, speed, callback */ ) { 5350 var args = _normalizeArguments.apply( this, arguments ), 5351 mode = args.mode, 5352 queue = args.queue, 5353 effectMethod = $.effects.effect[ args.effect ], 5354 5355 // DEPRECATED: remove in 2.0 (#7115) 5356 oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; 5357 5358 if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { 5359 // delegate to the original method (e.g., .show()) if possible 5360 if ( mode ) { 5361 return this[ mode ]( args.duration, args.complete ); 5362 } else { 5363 return this.each( function() { 5364 if ( args.complete ) { 5365 args.complete.call( this ); 5366 } 5367 }); 5368 } 5369 } 5370 5371 function run( next ) { 5372 var elem = $( this ), 5373 complete = args.complete, 5374 mode = args.mode; 5375 5376 function done() { 5377 if ( $.isFunction( complete ) ) { 5378 complete.call( elem[0] ); 5379 } 5380 if ( $.isFunction( next ) ) { 5381 next(); 5382 } 5383 } 5384 5385 // if the element is hiddden and mode is hide, 5386 // or element is visible and mode is show 5387 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5388 done(); 5389 } else { 5390 effectMethod.call( elem[0], args, done ); 5391 } 5392 } 5393 5394 // TODO: remove this check in 2.0, effectMethod will always be true 5395 if ( effectMethod ) { 5396 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5397 } else { 5398 // DEPRECATED: remove in 2.0 (#7115) 5399 return oldEffectMethod.call(this, { 5400 options: args, 5401 duration: args.duration, 5402 callback: args.complete, 5403 mode: args.mode 5404 }); 5405 } 5406 }, 5407 5408 _show: $.fn.show, 5409 show: function( speed ) { 5410 if ( standardSpeed( speed ) ) { 5411 return this._show.apply( this, arguments ); 5412 } else { 5413 var args = _normalizeArguments.apply( this, arguments ); 5414 args.mode = "show"; 5415 return this.effect.call( this, args ); 5416 } 5417 }, 5418 5419 _hide: $.fn.hide, 5420 hide: function( speed ) { 5421 if ( standardSpeed( speed ) ) { 5422 return this._hide.apply( this, arguments ); 5423 } else { 5424 var args = _normalizeArguments.apply( this, arguments ); 5425 args.mode = "hide"; 5426 return this.effect.call( this, args ); 5427 } 5428 }, 5429 5430 // jQuery core overloads toggle and creates _toggle 5431 __toggle: $.fn.toggle, 5432 toggle: function( speed ) { 5433 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 5434 return this.__toggle.apply( this, arguments ); 5435 } else { 5436 var args = _normalizeArguments.apply( this, arguments ); 5437 args.mode = "toggle"; 5438 return this.effect.call( this, args ); 5439 } 5440 }, 5441 5442 // helper functions 5443 cssUnit: function(key) { 5444 var style = this.css( key ), 5445 val = []; 5446 5447 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5448 if ( style.indexOf( unit ) > 0 ) { 5449 val = [ parseFloat( style ), unit ]; 5450 } 5451 }); 5452 return val; 5453 } 5454}); 5455 5456})(); 5457 5458/******************************************************************************/ 5459/*********************************** EASING ***********************************/ 5460/******************************************************************************/ 5461 5462(function() { 5463 5464// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 5465 5466var baseEasings = {}; 5467 5468$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 5469 baseEasings[ name ] = function( p ) { 5470 return Math.pow( p, i + 2 ); 5471 }; 5472}); 5473 5474$.extend( baseEasings, { 5475 Sine: function ( p ) { 5476 return 1 - Math.cos( p * Math.PI / 2 ); 5477 }, 5478 Circ: function ( p ) { 5479 return 1 - Math.sqrt( 1 - p * p ); 5480 }, 5481 Elastic: function( p ) { 5482 return p === 0 || p === 1 ? p : 5483 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 5484 }, 5485 Back: function( p ) { 5486 return p * p * ( 3 * p - 2 ); 5487 }, 5488 Bounce: function ( p ) { 5489 var pow2, 5490 bounce = 4; 5491 5492 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 5493 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 5494 } 5495}); 5496 5497$.each( baseEasings, function( name, easeIn ) { 5498 $.easing[ "easeIn" + name ] = easeIn; 5499 $.easing[ "easeOut" + name ] = function( p ) { 5500 return 1 - easeIn( 1 - p ); 5501 };
vendor: 6,279 bytes, lines 5502-5746
5502 $.easing[ "easeInOut" + name ] = function( p ) { 5503 return p < 0.5 ? 5504 easeIn( p * 2 ) / 2 : 5505 1 - easeIn( p * -2 + 2 ) / 2; 5506 }; 5507}); 5508 5509})(); 5510 5511})(jQuery)); 5512 5513(function( $, undefined ) { 5514 5515var uid = 0, 5516 hideProps = {}, 5517 showProps = {}; 5518 5519hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5520 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5521showProps.height = showProps.paddingTop = showProps.paddingBottom = 5522 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5523 5524$.widget( "ui.accordion", { 5525 version: "1.9.2", 5526 options: { 5527 active: 0, 5528 animate: {}, 5529 collapsible: false, 5530 event: "click", 5531 header: "> li > :first-child,> :not(li):even", 5532 heightStyle: "auto", 5533 icons: { 5534 activeHeader: "ui-icon-triangle-1-s", 5535 header: "ui-icon-triangle-1-e" 5536 }, 5537 5538 // callbacks 5539 activate: null, 5540 beforeActivate: null 5541 }, 5542 5543 _create: function() { 5544 var accordionId = this.accordionId = "ui-accordion-" + 5545 (this.element.attr( "id" ) || ++uid), 5546 options = this.options; 5547 5548 this.prevShow = this.prevHide = $(); 5549 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); 5550 5551 this.headers = this.element.find( options.header ) 5552 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 5553 this._hoverable( this.headers ); 5554 this._focusable( this.headers ); 5555 5556 this.headers.next() 5557 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 5558 .hide(); 5559 5560 // don't allow collapsible: false and active: false / null 5561 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5562 options.active = 0; 5563 } 5564 // handle negative values 5565 if ( options.active < 0 ) { 5566 options.active += this.headers.length; 5567 } 5568 this.active = this._findActive( options.active ) 5569 .addClass( "ui-accordion-header-active ui-state-active" ) 5570 .toggleClass( "ui-corner-all ui-corner-top" ); 5571 this.active.next() 5572 .addClass( "ui-accordion-content-active" ) 5573 .show(); 5574 5575 this._createIcons(); 5576 this.refresh(); 5577 5578 // ARIA 5579 this.element.attr( "role", "tablist" ); 5580 5581 this.headers 5582 .attr( "role", "tab" ) 5583 .each(function( i ) { 5584 var header = $( this ), 5585 headerId = header.attr( "id" ), 5586 panel = header.next(), 5587 panelId = panel.attr( "id" ); 5588 if ( !headerId ) { 5589 headerId = accordionId + "-header-" + i; 5590 header.attr( "id", headerId ); 5591 } 5592 if ( !panelId ) { 5593 panelId = accordionId + "-panel-" + i; 5594 panel.attr( "id", panelId ); 5595 } 5596 header.attr( "aria-controls", panelId ); 5597 panel.attr( "aria-labelledby", headerId ); 5598 }) 5599 .next() 5600 .attr( "role", "tabpanel" ); 5601 5602 this.headers 5603 .not( this.active ) 5604 .attr({ 5605 "aria-selected": "false", 5606 tabIndex: -1 5607 }) 5608 .next() 5609 .attr({ 5610 "aria-expanded": "false", 5611 "aria-hidden": "true" 5612 }) 5613 .hide(); 5614 5615 // make sure at least one header is in the tab order 5616 if ( !this.active.length ) { 5617 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5618 } else { 5619 this.active.attr({ 5620 "aria-selected": "true", 5621 tabIndex: 0 5622 }) 5623 .next() 5624 .attr({ 5625 "aria-expanded": "true", 5626 "aria-hidden": "false" 5627 }); 5628 } 5629 5630 this._on( this.headers, { keydown: "_keydown" }); 5631 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 5632 this._setupEvents( options.event ); 5633 }, 5634 5635 _getCreateEventData: function() { 5636 return { 5637 header: this.active, 5638 content: !this.active.length ? $() : this.active.next() 5639 }; 5640 }, 5641 5642 _createIcons: function() { 5643 var icons = this.options.icons; 5644 if ( icons ) { 5645 $( "<span>" ) 5646 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5647 .prependTo( this.headers ); 5648 this.active.children( ".ui-accordion-header-icon" ) 5649 .removeClass( icons.header ) 5650 .addClass( icons.activeHeader ); 5651 this.headers.addClass( "ui-accordion-icons" ); 5652 } 5653 }, 5654 5655 _destroyIcons: function() { 5656 this.headers 5657 .removeClass( "ui-accordion-icons" ) 5658 .children( ".ui-accordion-header-icon" ) 5659 .remove(); 5660 }, 5661 5662 _destroy: function() { 5663 var contents; 5664 5665 // clean up main element 5666 this.element 5667 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5668 .removeAttr( "role" ); 5669 5670 // clean up headers 5671 this.headers 5672 .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" ) 5673 .removeAttr( "role" ) 5674 .removeAttr( "aria-selected" ) 5675 .removeAttr( "aria-controls" ) 5676 .removeAttr( "tabIndex" ) 5677 .each(function() { 5678 if ( /^ui-accordion/.test( this.id ) ) { 5679 this.removeAttribute( "id" ); 5680 } 5681 }); 5682 this._destroyIcons(); 5683 5684 // clean up content panels 5685 contents = this.headers.next() 5686 .css( "display", "" ) 5687 .removeAttr( "role" ) 5688 .removeAttr( "aria-expanded" ) 5689 .removeAttr( "aria-hidden" ) 5690 .removeAttr( "aria-labelledby" ) 5691 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5692 .each(function() { 5693 if ( /^ui-accordion/.test( this.id ) ) { 5694 this.removeAttribute( "id" ); 5695 } 5696 }); 5697 if ( this.options.heightStyle !== "content" ) { 5698 contents.css( "height", "" ); 5699 } 5700 }, 5701 5702 _setOption: function( key, value ) { 5703 if ( key === "active" ) { 5704 // _activate() will handle invalid values and update this.options 5705 this._activate( value ); 5706 return; 5707 } 5708 5709 if ( key === "event" ) { 5710 if ( this.options.event ) { 5711 this._off( this.headers, this.options.event ); 5712 } 5713 this._setupEvents( value ); 5714 } 5715 5716 this._super( key, value ); 5717 5718 // setting collapsible: false while collapsed; open first panel 5719 if ( key === "collapsible" && !value && this.options.active === false ) { 5720 this._activate( 0 ); 5721 } 5722 5723 if ( key === "icons" ) { 5724 this._destroyIcons(); 5725 if ( value ) { 5726 this._createIcons(); 5727 } 5728 } 5729 5730 // #5332 - opacity doesn't cascade to positioned elements in IE 5731 // so we need to add the disabled class to the headers and panels 5732 if ( key === "disabled" ) { 5733 this.headers.add( this.headers.next() ) 5734 .toggleClass( "ui-state-disabled", !!value ); 5735 } 5736 }, 5737 5738 _keydown: function( event ) { 5739 if ( event.altKey || event.ctrlKey ) { 5740 return; 5741 } 5742 5743 var keyCode = $.ui.keyCode, 5744 length = this.headers.length, 5745 currentIndex = this.headers.index( event.target ), 5746 toFocus = false;
vendor: 4,224 bytes, lines 5747-5902
5747 5748 switch ( event.keyCode ) { 5749 case keyCode.RIGHT: 5750 case keyCode.DOWN: 5751 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5752 break; 5753 case keyCode.LEFT: 5754 case keyCode.UP: 5755 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5756 break; 5757 case keyCode.SPACE: 5758 case keyCode.ENTER: 5759 this._eventHandler( event ); 5760 break; 5761 case keyCode.HOME: 5762 toFocus = this.headers[ 0 ]; 5763 break; 5764 case keyCode.END: 5765 toFocus = this.headers[ length - 1 ]; 5766 break; 5767 } 5768 5769 if ( toFocus ) { 5770 $( event.target ).attr( "tabIndex", -1 ); 5771 $( toFocus ).attr( "tabIndex", 0 ); 5772 toFocus.focus(); 5773 event.preventDefault(); 5774 } 5775 }, 5776 5777 _panelKeyDown : function( event ) { 5778 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5779 $( event.currentTarget ).prev().focus(); 5780 } 5781 }, 5782 5783 refresh: function() { 5784 var maxHeight, overflow, 5785 heightStyle = this.options.heightStyle, 5786 parent = this.element.parent(); 5787 5788 5789 if ( heightStyle === "fill" ) { 5790 // IE 6 treats height like minHeight, so we need to turn off overflow 5791 // in order to get a reliable height 5792 // we use the minHeight support test because we assume that only 5793 // browsers that don't support minHeight will treat height as minHeight 5794 if ( !$.support.minHeight ) { 5795 overflow = parent.css( "overflow" ); 5796 parent.css( "overflow", "hidden"); 5797 } 5798 maxHeight = parent.height(); 5799 this.element.siblings( ":visible" ).each(function() { 5800 var elem = $( this ), 5801 position = elem.css( "position" ); 5802 5803 if ( position === "absolute" || position === "fixed" ) { 5804 return; 5805 } 5806 maxHeight -= elem.outerHeight( true ); 5807 }); 5808 if ( overflow ) { 5809 parent.css( "overflow", overflow ); 5810 } 5811 5812 this.headers.each(function() { 5813 maxHeight -= $( this ).outerHeight( true ); 5814 }); 5815 5816 this.headers.next() 5817 .each(function() { 5818 $( this ).height( Math.max( 0, maxHeight - 5819 $( this ).innerHeight() + $( this ).height() ) ); 5820 }) 5821 .css( "overflow", "auto" ); 5822 } else if ( heightStyle === "auto" ) { 5823 maxHeight = 0; 5824 this.headers.next() 5825 .each(function() { 5826 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5827 }) 5828 .height( maxHeight ); 5829 } 5830 }, 5831 5832 _activate: function( index ) { 5833 var active = this._findActive( index )[ 0 ]; 5834 5835 // trying to activate the already active panel 5836 if ( active === this.active[ 0 ] ) { 5837 return; 5838 } 5839 5840 // trying to collapse, simulate a click on the currently active header 5841 active = active || this.active[ 0 ]; 5842 5843 this._eventHandler({ 5844 target: active, 5845 currentTarget: active, 5846 preventDefault: $.noop 5847 }); 5848 }, 5849 5850 _findActive: function( selector ) { 5851 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5852 }, 5853 5854 _setupEvents: function( event ) { 5855 var events = {}; 5856 if ( !event ) { 5857 return; 5858 } 5859 $.each( event.split(" "), function( index, eventName ) { 5860 events[ eventName ] = "_eventHandler"; 5861 }); 5862 this._on( this.headers, events ); 5863 }, 5864 5865 _eventHandler: function( event ) { 5866 var options = this.options, 5867 active = this.active, 5868 clicked = $( event.currentTarget ), 5869 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5870 collapsing = clickedIsActive && options.collapsible, 5871 toShow = collapsing ? $() : clicked.next(), 5872 toHide = active.next(), 5873 eventData = { 5874 oldHeader: active, 5875 oldPanel: toHide, 5876 newHeader: collapsing ? $() : clicked, 5877 newPanel: toShow 5878 }; 5879 5880 event.preventDefault(); 5881 5882 if ( 5883 // click on active header, but not collapsible 5884 ( clickedIsActive && !options.collapsible ) || 5885 // allow canceling activation 5886 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5887 return; 5888 } 5889 5890 options.active = collapsing ? false : this.headers.index( clicked ); 5891 5892 // when the call to ._toggle() comes after the class changes 5893 // it causes a very odd bug in IE 8 (see #6720) 5894 this.active = clickedIsActive ? $() : clicked; 5895 this._toggle( eventData ); 5896 5897 // switch classes 5898 // corner classes on the previously active header stay after the animation 5899 active.removeClass( "ui-accordion-header-active ui-state-active" ); 5900 if ( options.icons ) { 5901 active.children( ".ui-accordion-header-icon" ) 5902 .removeClass( options.icons.activeHeader )
5903 .addClass( options.icons.header ); 5904 } 5905 5906 if ( !clickedIsActive ) { 5907 clicked 5908 .removeClass( "ui-corner-all" ) 5909 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 5910 if ( options.icons ) { 5911 clicked.children( ".ui-accordion-header-icon" ) 5912 .removeClass( options.icons.header ) 5913 .addClass( options.icons.activeHeader ); 5914 } 5915 5916 clicked 5917 .next() 5918 .addClass( "ui-accordion-content-active" ); 5919 } 5920 }, 5921 5922 _toggle: function( data ) { 5923 var toShow = data.newPanel, 5924 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5925 5926 // handle activating a panel during the animation for another activation 5927 this.prevShow.add( this.prevHide ).stop( true, true ); 5928 this.prevShow = toShow; 5929 this.prevHide = toHide; 5930 5931 if ( this.options.animate ) { 5932 this._animate( toShow, toHide, data ); 5933 } else { 5934 toHide.hide(); 5935 toShow.show(); 5936 this._toggleComplete( data ); 5937 } 5938 5939 toHide.attr({ 5940 "aria-expanded": "false", 5941 "aria-hidden": "true" 5942 }); 5943 toHide.prev().attr( "aria-selected", "false" ); 5944 // if we're switching panels, remove the old header from the tab order 5945 // if we're opening from collapsed state, remove the previous header from the tab order 5946 // if we're collapsing, then keep the collapsing header in the tab order 5947 if ( toShow.length && toHide.length ) { 5948 toHide.prev().attr( "tabIndex", -1 ); 5949 } else if ( toShow.length ) { 5950 this.headers.filter(function() { 5951 return $( this ).attr( "tabIndex" ) === 0; 5952 }) 5953 .attr( "tabIndex", -1 ); 5954 } 5955 5956 toShow 5957 .attr({ 5958 "aria-expanded": "true", 5959 "aria-hidden": "false" 5960 }) 5961 .prev() 5962 .attr({ 5963 "aria-selected": "true", 5964 tabIndex: 0 5965 }); 5966 }, 5967 5968 _animate: function( toShow, toHide, data ) { 5969 var total, easing, duration, 5970 that = this, 5971 adjust = 0, 5972 down = toShow.length && 5973 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5974 animate = this.options.animate || {}, 5975 options = down && animate.down || animate, 5976 complete = function() { 5977 that._toggleComplete( data ); 5978 }; 5979 5980 if ( typeof options === "number" ) { 5981 duration = options; 5982 } 5983 if ( typeof options === "string" ) { 5984 easing = options; 5985 } 5986 // fall back from options to animation in case of partial down settings 5987 easing = easing || options.easing || animate.easing; 5988 duration = duration || options.duration || animate.duration; 5989 5990 if ( !toHide.length ) { 5991 return toShow.animate( showProps, duration, easing, complete ); 5992 } 5993 if ( !toShow.length ) { 5994 return toHide.animate( hideProps, duration, easing, complete ); 5995 } 5996 5997 total = toShow.show().outerHeight(); 5998 toHide.animate( hideProps, { 5999 duration: duration, 6000 easing: easing, 6001 step: function( now, fx ) { 6002 fx.now = Math.round( now ); 6003 } 6004 }); 6005 toShow 6006 .hide() 6007 .animate( showProps, { 6008 duration: duration, 6009 easing: easing, 6010 complete: complete, 6011 step: function( now, fx ) { 6012 fx.now = Math.round( now ); 6013 if ( fx.prop !== "height" ) { 6014 adjust += fx.now; 6015 } else if ( that.options.heightStyle !== "content" ) { 6016 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6017 adjust = 0; 6018 } 6019 } 6020 }); 6021 }, 6022 6023 _toggleComplete: function( data ) { 6024 var toHide = data.oldPanel; 6025 6026 toHide 6027 .removeClass( "ui-accordion-content-active" ) 6028 .prev() 6029 .removeClass( "ui-corner-top" ) 6030 .addClass( "ui-corner-all" ); 6031 6032 // Work around for rendering bug in IE (#5421) 6033 if ( toHide.length ) { 6034 toHide.parent()[0].className = toHide.parent()[0].className; 6035 } 6036 6037 this._trigger( "activate", null, data ); 6038 } 6039}); 6040 6041 6042 6043// DEPRECATED 6044if ( $.uiBackCompat !== false ) { 6045 // navigation options 6046 (function( $, prototype ) { 6047 $.extend( prototype.options, { 6048 navigation: false, 6049 navigationFilter: function() { 6050 return this.href.toLowerCase() === location.href.toLowerCase(); 6051 } 6052 }); 6053 6054 var _create = prototype._create; 6055 prototype._create = function() { 6056 if ( this.options.navigation ) { 6057 var that = this, 6058 headers = this.element.find( this.options.header ), 6059 content = headers.next(), 6060 current = headers.add( content ) 6061 .find( "a" ) 6062 .filter( this.options.navigationFilter ) 6063 [ 0 ]; 6064 if ( current ) { 6065 headers.add( content ).each( function( index ) { 6066 if ( $.contains( this, current ) ) { 6067 that.options.active = Math.floor( index / 2 ); 6068 return false;
6069 } 6070 }); 6071 } 6072 } 6073 _create.call( this ); 6074 }; 6075 }( jQuery, jQuery.ui.accordion.prototype ) ); 6076 6077 // height options 6078 (function( $, prototype ) { 6079 $.extend( prototype.options, { 6080 heightStyle: null, // remove default so we fall back to old values 6081 autoHeight: true, // use heightStyle: "auto" 6082 clearStyle: false, // use heightStyle: "content" 6083 fillSpace: false // use heightStyle: "fill" 6084 }); 6085 6086 var _create = prototype._create, 6087 _setOption = prototype._setOption; 6088 6089 $.extend( prototype, { 6090 _create: function() { 6091 this.options.heightStyle = this.options.heightStyle || 6092 this._mergeHeightStyle(); 6093 6094 _create.call( this ); 6095 }, 6096 6097 _setOption: function( key ) { 6098 if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { 6099 this.options.heightStyle = this._mergeHeightStyle(); 6100 } 6101 _setOption.apply( this, arguments ); 6102 }, 6103 6104 _mergeHeightStyle: function() { 6105 var options = this.options; 6106 6107 if ( options.fillSpace ) { 6108 return "fill"; 6109 } 6110 6111 if ( options.clearStyle ) { 6112 return "content"; 6113 } 6114 6115 if ( options.autoHeight ) { 6116 return "auto"; 6117 } 6118 } 6119 }); 6120 }( jQuery, jQuery.ui.accordion.prototype ) ); 6121 6122 // icon options 6123 (function( $, prototype ) { 6124 $.extend( prototype.options.icons, { 6125 activeHeader: null, // remove default so we fall back to old values 6126 headerSelected: "ui-icon-triangle-1-s" 6127 }); 6128 6129 var _createIcons = prototype._createIcons; 6130 prototype._createIcons = function() { 6131 if ( this.options.icons ) { 6132 this.options.icons.activeHeader = this.options.icons.activeHeader || 6133 this.options.icons.headerSelected; 6134 } 6135 _createIcons.call( this ); 6136 }; 6137 }( jQuery, jQuery.ui.accordion.prototype ) ); 6138 6139 // expanded active option, activate method 6140 (function( $, prototype ) { 6141 prototype.activate = prototype._activate; 6142 6143 var _findActive = prototype._findActive; 6144 prototype._findActive = function( index ) { 6145 if ( index === -1 ) { 6146 index = false; 6147 } 6148 if ( index && typeof index !== "number" ) { 6149 index = this.headers.index( this.headers.filter( index ) ); 6150 if ( index === -1 ) { 6151 index = false; 6152 } 6153 } 6154 return _findActive.call( this, index ); 6155 }; 6156 }( jQuery, jQuery.ui.accordion.prototype ) ); 6157 6158 // resize method 6159 jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; 6160 6161 // change events 6162 (function( $, prototype ) { 6163 $.extend( prototype.options, { 6164 change: null, 6165 changestart: null 6166 }); 6167 6168 var _trigger = prototype._trigger; 6169 prototype._trigger = function( type, event, data ) { 6170 var ret = _trigger.apply( this, arguments ); 6171 if ( !ret ) { 6172 return false; 6173 } 6174 6175 if ( type === "beforeActivate" ) { 6176 ret = _trigger.call( this, "changestart", event, { 6177 oldHeader: data.oldHeader, 6178 oldContent: data.oldPanel, 6179 newHeader: data.newHeader, 6180 newContent: data.newPanel 6181 }); 6182 } else if ( type === "activate" ) { 6183 ret = _trigger.call( this, "change", event, { 6184 oldHeader: data.oldHeader, 6185 oldContent: data.oldPanel, 6186 newHeader: data.newHeader, 6187 newContent: data.newPanel 6188 }); 6189 } 6190 return ret; 6191 }; 6192 }( jQuery, jQuery.ui.accordion.prototype ) ); 6193 6194 // animated option 6195 // NOTE: this only provides support for "slide", "bounceslide", and easings 6196 // not the full $.ui.accordion.animations API 6197 (function( $, prototype ) { 6198 $.extend( prototype.options, { 6199 animate: null, 6200 animated: "slide" 6201 }); 6202 6203 var _create = prototype._create; 6204 prototype._create = function() { 6205 var options = this.options; 6206 if ( options.animate === null ) { 6207 if ( !options.animated ) { 6208 options.animate = false; 6209 } else if ( options.animated === "slide" ) { 6210 options.animate = 300; 6211 } else if ( options.animated === "bounceslide" ) { 6212 options.animate = { 6213 duration: 200, 6214 down: { 6215 easing: "easeOutBounce", 6216 duration: 1000 6217 } 6218 }; 6219 } else { 6220 options.animate = options.animated; 6221 } 6222 } 6223 6224 _create.call( this ); 6225 }; 6226 }( jQuery, jQuery.ui.accordion.prototype ) ); 6227} 6228 6229})( jQuery ); 6230 6231(function( $, undefined ) { 6232 6233// used to prevent race conditions with remote data sources 6234var requestIndex = 0; 6235 6236$.widget( "ui.autocomplete", { 6237 version: "1.9.2", 6238 defaultElement: "<input>", 6239 options: { 6240 appendTo: "body", 6241 autoFocus: false, 6242 delay: 300, 6243 minLength: 1, 6244 position: { 6245 my: "left top", 6246 at: "left bottom", 6247 collision: "none" 6248 }, 6249 source: null, 6250 6251 // callbacks 6252 change: null, 6253 close: null, 6254 focus: null, 6255 open: null, 6256 response: null, 6257 search: null, 6258 select: null 6259 }, 6260 6261 pending: 0, 6262 6263 _create: function() { 6264 // Some browsers only repeat keydown events, not keypress events, 6265 // so we use the suppressKeyPress flag to determine if we've already 6266 // handled the keydown event. #7269 6267 // Unfortunately the code for & in keypress is the same as the up arrow, 6268 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6269 // events when we know the keydown event was used to modify the 6270 // search term. #7799 6271 var suppressKeyPress, suppressKeyPressRepeat, suppressInput; 6272 6273 this.isMultiLine = this._isMultiLine(); 6274 this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; 6275 this.isNewMenu = true; 6276 6277 this.element 6278 .addClass( "ui-autocomplete-input" ) 6279 .attr( "autocomplete", "off" ); 6280 6281 this._on( this.element, { 6282 keydown: function( event ) { 6283 if ( this.element.prop( "readOnly" ) ) { 6284 suppressKeyPress = true; 6285 suppressInput = true; 6286 suppressKeyPressRepeat = true; 6287 return; 6288 } 6289 6290 suppressKeyPress = false;
vendor: 21,657 bytes, lines 6291-7070
6291 suppressInput = false; 6292 suppressKeyPressRepeat = false; 6293 var keyCode = $.ui.keyCode; 6294 switch( event.keyCode ) { 6295 case keyCode.PAGE_UP: 6296 suppressKeyPress = true; 6297 this._move( "previousPage", event ); 6298 break; 6299 case keyCode.PAGE_DOWN: 6300 suppressKeyPress = true; 6301 this._move( "nextPage", event ); 6302 break; 6303 case keyCode.UP: 6304 suppressKeyPress = true; 6305 this._keyEvent( "previous", event ); 6306 break; 6307 case keyCode.DOWN: 6308 suppressKeyPress = true; 6309 this._keyEvent( "next", event ); 6310 break; 6311 case keyCode.ENTER: 6312 case keyCode.NUMPAD_ENTER: 6313 // when menu is open and has focus 6314 if ( this.menu.active ) { 6315 // #6055 - Opera still allows the keypress to occur 6316 // which causes forms to submit 6317 suppressKeyPress = true; 6318 event.preventDefault(); 6319 this.menu.select( event ); 6320 } 6321 break; 6322 case keyCode.TAB: 6323 if ( this.menu.active ) { 6324 this.menu.select( event ); 6325 } 6326 break; 6327 case keyCode.ESCAPE: 6328 if ( this.menu.element.is( ":visible" ) ) { 6329 this._value( this.term ); 6330 this.close( event ); 6331 // Different browsers have different default behavior for escape 6332 // Single press can mean undo or clear 6333 // Double press in IE means clear the whole form 6334 event.preventDefault(); 6335 } 6336 break; 6337 default: 6338 suppressKeyPressRepeat = true; 6339 // search timeout should be triggered before the input value is changed 6340 this._searchTimeout( event ); 6341 break; 6342 } 6343 }, 6344 keypress: function( event ) { 6345 if ( suppressKeyPress ) { 6346 suppressKeyPress = false; 6347 event.preventDefault(); 6348 return; 6349 } 6350 if ( suppressKeyPressRepeat ) { 6351 return; 6352 } 6353 6354 // replicate some key handlers to allow them to repeat in Firefox and Opera 6355 var keyCode = $.ui.keyCode; 6356 switch( event.keyCode ) { 6357 case keyCode.PAGE_UP: 6358 this._move( "previousPage", event ); 6359 break; 6360 case keyCode.PAGE_DOWN: 6361 this._move( "nextPage", event ); 6362 break; 6363 case keyCode.UP: 6364 this._keyEvent( "previous", event ); 6365 break; 6366 case keyCode.DOWN: 6367 this._keyEvent( "next", event ); 6368 break; 6369 } 6370 }, 6371 input: function( event ) { 6372 if ( suppressInput ) { 6373 suppressInput = false; 6374 event.preventDefault(); 6375 return; 6376 } 6377 this._searchTimeout( event ); 6378 }, 6379 focus: function() { 6380 this.selectedItem = null; 6381 this.previous = this._value(); 6382 }, 6383 blur: function( event ) { 6384 if ( this.cancelBlur ) { 6385 delete this.cancelBlur; 6386 return; 6387 } 6388 6389 clearTimeout( this.searching ); 6390 this.close( event ); 6391 this._change( event ); 6392 } 6393 }); 6394 6395 this._initSource(); 6396 this.menu = $( "<ul>" ) 6397 .addClass( "ui-autocomplete" ) 6398 .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] ) 6399 .menu({ 6400 // custom key handling for now 6401 input: $(), 6402 // disable ARIA support, the live region takes care of that 6403 role: null 6404 }) 6405 .zIndex( this.element.zIndex() + 1 ) 6406 .hide() 6407 .data( "menu" ); 6408 6409 this._on( this.menu.element, { 6410 mousedown: function( event ) { 6411 // prevent moving focus out of the text field 6412 event.preventDefault(); 6413 6414 // IE doesn't prevent moving focus even with event.preventDefault() 6415 // so we set a flag to know when we should ignore the blur event 6416 this.cancelBlur = true; 6417 this._delay(function() { 6418 delete this.cancelBlur; 6419 }); 6420 6421 // clicking on the scrollbar causes focus to shift to the body 6422 // but we can't detect a mouseup or a click immediately afterward 6423 // so we have to track the next mousedown and close the menu if 6424 // the user clicks somewhere outside of the autocomplete 6425 var menuElement = this.menu.element[ 0 ]; 6426 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6427 this._delay(function() { 6428 var that = this; 6429 this.document.one( "mousedown", function( event ) { 6430 if ( event.target !== that.element[ 0 ] && 6431 event.target !== menuElement && 6432 !$.contains( menuElement, event.target ) ) { 6433 that.close(); 6434 } 6435 }); 6436 }); 6437 } 6438 }, 6439 menufocus: function( event, ui ) { 6440 // #7024 - Prevent accidental activation of menu items in Firefox 6441 if ( this.isNewMenu ) { 6442 this.isNewMenu = false; 6443 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6444 this.menu.blur(); 6445 6446 this.document.one( "mousemove", function() { 6447 $( event.target ).trigger( event.originalEvent ); 6448 }); 6449 6450 return; 6451 } 6452 } 6453 6454 // back compat for _renderItem using item.autocomplete, via #7810 6455 // TODO remove the fallback, see #8156 6456 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ); 6457 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6458 // use value to match what will end up in the input, if it was a key event 6459 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6460 this._value( item.value ); 6461 } 6462 } else { 6463 // Normally the input is populated with the item's value as the 6464 // menu is navigated, causing screen readers to notice a change and 6465 // announce the item. Since the focus event was canceled, this doesn't 6466 // happen, so we update the live region so that screen readers can 6467 // still notice the change and announce it. 6468 this.liveRegion.text( item.value ); 6469 } 6470 }, 6471 menuselect: function( event, ui ) { 6472 // back compat for _renderItem using item.autocomplete, via #7810 6473 // TODO remove the fallback, see #8156 6474 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ), 6475 previous = this.previous; 6476 6477 // only trigger when focus was lost (click on menu) 6478 if ( this.element[0] !== this.document[0].activeElement ) { 6479 this.element.focus(); 6480 this.previous = previous; 6481 // #6109 - IE triggers two focus events and the second 6482 // is asynchronous, so we need to reset the previous 6483 // term synchronously and asynchronously :-( 6484 this._delay(function() { 6485 this.previous = previous; 6486 this.selectedItem = item; 6487 }); 6488 } 6489 6490 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6491 this._value( item.value ); 6492 } 6493 // reset the term after the select event 6494 // this allows custom select handling to work properly 6495 this.term = this._value(); 6496 6497 this.close( event ); 6498 this.selectedItem = item; 6499 } 6500 }); 6501 6502 this.liveRegion = $( "<span>", { 6503 role: "status", 6504 "aria-live": "polite" 6505 }) 6506 .addClass( "ui-helper-hidden-accessible" ) 6507 .insertAfter( this.element ); 6508 6509 if ( $.fn.bgiframe ) { 6510 this.menu.element.bgiframe(); 6511 } 6512 6513 // turning off autocomplete prevents the browser from remembering the 6514 // value when navigating through history, so we re-enable autocomplete 6515 // if the page is unloaded before the widget is destroyed. #7790 6516 this._on( this.window, { 6517 beforeunload: function() { 6518 this.element.removeAttr( "autocomplete" ); 6519 } 6520 }); 6521 }, 6522 6523 _destroy: function() { 6524 clearTimeout( this.searching ); 6525 this.element 6526 .removeClass( "ui-autocomplete-input" ) 6527 .removeAttr( "autocomplete" ); 6528 this.menu.element.remove(); 6529 this.liveRegion.remove(); 6530 }, 6531 6532 _setOption: function( key, value ) { 6533 this._super( key, value ); 6534 if ( key === "source" ) { 6535 this._initSource(); 6536 } 6537 if ( key === "appendTo" ) { 6538 this.menu.element.appendTo( this.document.find( value || "body" )[0] ); 6539 } 6540 if ( key === "disabled" && value && this.xhr ) { 6541 this.xhr.abort(); 6542 } 6543 }, 6544 6545 _isMultiLine: function() { 6546 // Textareas are always multi-line 6547 if ( this.element.is( "textarea" ) ) { 6548 return true; 6549 } 6550 // Inputs are always single-line, even if inside a contentEditable element 6551 // IE also treats inputs as contentEditable 6552 if ( this.element.is( "input" ) ) { 6553 return false; 6554 } 6555 // All other element types are determined by whether or not they're contentEditable 6556 return this.element.prop( "isContentEditable" ); 6557 }, 6558 6559 _initSource: function() { 6560 var array, url, 6561 that = this; 6562 if ( $.isArray(this.options.source) ) { 6563 array = this.options.source; 6564 this.source = function( request, response ) { 6565 response( $.ui.autocomplete.filter( array, request.term ) ); 6566 }; 6567 } else if ( typeof this.options.source === "string" ) { 6568 url = this.options.source; 6569 this.source = function( request, response ) { 6570 if ( that.xhr ) { 6571 that.xhr.abort(); 6572 } 6573 that.xhr = $.ajax({ 6574 url: url, 6575 data: request, 6576 dataType: "json", 6577 success: function( data ) { 6578 response( data ); 6579 }, 6580 error: function() { 6581 response( [] ); 6582 } 6583 }); 6584 }; 6585 } else { 6586 this.source = this.options.source; 6587 } 6588 }, 6589 6590 _searchTimeout: function( event ) { 6591 clearTimeout( this.searching ); 6592 this.searching = this._delay(function() { 6593 // only search if the value has changed 6594 if ( this.term !== this._value() ) { 6595 this.selectedItem = null; 6596 this.search( null, event ); 6597 } 6598 }, this.options.delay ); 6599 }, 6600 6601 search: function( value, event ) { 6602 value = value != null ? value : this._value(); 6603 6604 // always save the actual value, not the one passed as an argument 6605 this.term = this._value(); 6606 6607 if ( value.length < this.options.minLength ) { 6608 return this.close( event ); 6609 } 6610 6611 if ( this._trigger( "search", event ) === false ) { 6612 return; 6613 } 6614 6615 return this._search( value ); 6616 }, 6617 6618 _search: function( value ) { 6619 this.pending++; 6620 this.element.addClass( "ui-autocomplete-loading" ); 6621 this.cancelSearch = false; 6622 6623 this.source( { term: value }, this._response() ); 6624 }, 6625 6626 _response: function() { 6627 var that = this, 6628 index = ++requestIndex; 6629 6630 return function( content ) { 6631 if ( index === requestIndex ) { 6632 that.__response( content ); 6633 } 6634 6635 that.pending--; 6636 if ( !that.pending ) { 6637 that.element.removeClass( "ui-autocomplete-loading" ); 6638 } 6639 }; 6640 }, 6641 6642 __response: function( content ) { 6643 if ( content ) { 6644 content = this._normalize( content ); 6645 } 6646 this._trigger( "response", null, { content: content } ); 6647 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6648 this._suggest( content ); 6649 this._trigger( "open" ); 6650 } else { 6651 // use ._close() instead of .close() so we don't cancel future searches 6652 this._close(); 6653 } 6654 }, 6655 6656 close: function( event ) { 6657 this.cancelSearch = true; 6658 this._close( event ); 6659 }, 6660 6661 _close: function( event ) { 6662 if ( this.menu.element.is( ":visible" ) ) { 6663 this.menu.element.hide(); 6664 this.menu.blur(); 6665 this.isNewMenu = true; 6666 this._trigger( "close", event ); 6667 } 6668 }, 6669 6670 _change: function( event ) { 6671 if ( this.previous !== this._value() ) { 6672 this._trigger( "change", event, { item: this.selectedItem } ); 6673 } 6674 }, 6675 6676 _normalize: function( items ) { 6677 // assume all items have the right format when the first item is complete 6678 if ( items.length && items[0].label && items[0].value ) { 6679 return items; 6680 } 6681 return $.map( items, function( item ) { 6682 if ( typeof item === "string" ) { 6683 return { 6684 label: item, 6685 value: item 6686 }; 6687 } 6688 return $.extend({ 6689 label: item.label || item.value, 6690 value: item.value || item.label 6691 }, item ); 6692 }); 6693 }, 6694 6695 _suggest: function( items ) { 6696 var ul = this.menu.element 6697 .empty() 6698 .zIndex( this.element.zIndex() + 1 ); 6699 this._renderMenu( ul, items ); 6700 this.menu.refresh(); 6701 6702 // size and position menu 6703 ul.show(); 6704 this._resizeMenu(); 6705 ul.position( $.extend({ 6706 of: this.element 6707 }, this.options.position )); 6708 6709 if ( this.options.autoFocus ) { 6710 this.menu.next(); 6711 } 6712 }, 6713 6714 _resizeMenu: function() { 6715 var ul = this.menu.element; 6716 ul.outerWidth( Math.max( 6717 // Firefox wraps long text (possibly a rounding bug) 6718 // so we add 1px to avoid the wrapping (#7513) 6719 ul.width( "" ).outerWidth() + 1, 6720 this.element.outerWidth() 6721 ) ); 6722 }, 6723 6724 _renderMenu: function( ul, items ) { 6725 var that = this; 6726 $.each( items, function( index, item ) { 6727 that._renderItemData( ul, item ); 6728 }); 6729 }, 6730 6731 _renderItemData: function( ul, item ) { 6732 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6733 }, 6734 6735 _renderItem: function( ul, item ) { 6736 return $( "<li>" ) 6737 .append( $( "<a>" ).text( item.label ) ) 6738 .appendTo( ul ); 6739 }, 6740 6741 _move: function( direction, event ) { 6742 if ( !this.menu.element.is( ":visible" ) ) { 6743 this.search( null, event ); 6744 return; 6745 } 6746 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6747 this.menu.isLastItem() && /^next/.test( direction ) ) { 6748 this._value( this.term ); 6749 this.menu.blur(); 6750 return; 6751 } 6752 this.menu[ direction ]( event ); 6753 }, 6754 6755 widget: function() { 6756 return this.menu.element; 6757 }, 6758 6759 _value: function() { 6760 return this.valueMethod.apply( this.element, arguments ); 6761 }, 6762 6763 _keyEvent: function( keyEvent, event ) { 6764 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6765 this._move( keyEvent, event ); 6766 6767 // prevents moving cursor to beginning/end of the text field in some browsers 6768 event.preventDefault(); 6769 } 6770 } 6771}); 6772 6773$.extend( $.ui.autocomplete, { 6774 escapeRegex: function( value ) { 6775 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6776 }, 6777 filter: function(array, term) { 6778 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 6779 return $.grep( array, function(value) { 6780 return matcher.test( value.label || value.value || value ); 6781 }); 6782 } 6783}); 6784 6785 6786// live region extension, adding a `messages` option 6787// NOTE: This is an experimental API. We are still investigating 6788// a full solution for string manipulation and internationalization. 6789$.widget( "ui.autocomplete", $.ui.autocomplete, { 6790 options: { 6791 messages: { 6792 noResults: "No search results.", 6793 results: function( amount ) { 6794 return amount + ( amount > 1 ? " results are" : " result is" ) + 6795 " available, use up and down arrow keys to navigate."; 6796 } 6797 } 6798 }, 6799 6800 __response: function( content ) { 6801 var message; 6802 this._superApply( arguments ); 6803 if ( this.options.disabled || this.cancelSearch ) { 6804 return; 6805 } 6806 if ( content && content.length ) { 6807 message = this.options.messages.results( content.length ); 6808 } else { 6809 message = this.options.messages.noResults; 6810 } 6811 this.liveRegion.text( message ); 6812 } 6813}); 6814 6815 6816}( jQuery )); 6817 6818(function( $, undefined ) { 6819 6820var lastActive, startXPos, startYPos, clickDragged, 6821 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6822 stateClasses = "ui-state-hover ui-state-active ", 6823 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", 6824 formResetHandler = function() { 6825 var buttons = $( this ).find( ":ui-button" ); 6826 setTimeout(function() { 6827 buttons.button( "refresh" ); 6828 }, 1 ); 6829 }, 6830 radioGroup = function( radio ) { 6831 var name = radio.name, 6832 form = radio.form, 6833 radios = $( [] ); 6834 if ( name ) { 6835 if ( form ) { 6836 radios = $( form ).find( "[name='" + name + "']" ); 6837 } else { 6838 radios = $( "[name='" + name + "']", radio.ownerDocument ) 6839 .filter(function() { 6840 return !this.form; 6841 }); 6842 } 6843 } 6844 return radios; 6845 }; 6846 6847$.widget( "ui.button", { 6848 version: "1.9.2", 6849 defaultElement: "<button>", 6850 options: { 6851 disabled: null, 6852 text: true, 6853 label: null, 6854 icons: { 6855 primary: null, 6856 secondary: null 6857 } 6858 }, 6859 _create: function() { 6860 this.element.closest( "form" ) 6861 .unbind( "reset" + this.eventNamespace ) 6862 .bind( "reset" + this.eventNamespace, formResetHandler ); 6863 6864 if ( typeof this.options.disabled !== "boolean" ) { 6865 this.options.disabled = !!this.element.prop( "disabled" ); 6866 } else { 6867 this.element.prop( "disabled", this.options.disabled ); 6868 } 6869 6870 this._determineButtonType(); 6871 this.hasTitle = !!this.buttonElement.attr( "title" ); 6872 6873 var that = this, 6874 options = this.options, 6875 toggleButton = this.type === "checkbox" || this.type === "radio", 6876 activeClass = !toggleButton ? "ui-state-active" : "", 6877 focusClass = "ui-state-focus"; 6878 6879 if ( options.label === null ) { 6880 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6881 } 6882 6883 this._hoverable( this.buttonElement ); 6884 6885 this.buttonElement 6886 .addClass( baseClasses ) 6887 .attr( "role", "button" ) 6888 .bind( "mouseenter" + this.eventNamespace, function() { 6889 if ( options.disabled ) { 6890 return; 6891 } 6892 if ( this === lastActive ) { 6893 $( this ).addClass( "ui-state-active" ); 6894 } 6895 }) 6896 .bind( "mouseleave" + this.eventNamespace, function() { 6897 if ( options.disabled ) { 6898 return; 6899 } 6900 $( this ).removeClass( activeClass ); 6901 }) 6902 .bind( "click" + this.eventNamespace, function( event ) { 6903 if ( options.disabled ) { 6904 event.preventDefault(); 6905 event.stopImmediatePropagation(); 6906 } 6907 }); 6908 6909 this.element 6910 .bind( "focus" + this.eventNamespace, function() { 6911 // no need to check disabled, focus won't be triggered anyway 6912 that.buttonElement.addClass( focusClass ); 6913 }) 6914 .bind( "blur" + this.eventNamespace, function() { 6915 that.buttonElement.removeClass( focusClass ); 6916 }); 6917 6918 if ( toggleButton ) { 6919 this.element.bind( "change" + this.eventNamespace, function() { 6920 if ( clickDragged ) { 6921 return; 6922 } 6923 that.refresh(); 6924 }); 6925 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 6926 // prevents issue where button state changes but checkbox/radio checked state 6927 // does not in Firefox (see ticket #6970) 6928 this.buttonElement 6929 .bind( "mousedown" + this.eventNamespace, function( event ) { 6930 if ( options.disabled ) { 6931 return; 6932 } 6933 clickDragged = false; 6934 startXPos = event.pageX; 6935 startYPos = event.pageY; 6936 }) 6937 .bind( "mouseup" + this.eventNamespace, function( event ) { 6938 if ( options.disabled ) { 6939 return; 6940 } 6941 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 6942 clickDragged = true; 6943 } 6944 }); 6945 } 6946 6947 if ( this.type === "checkbox" ) { 6948 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6949 if ( options.disabled || clickDragged ) { 6950 return false; 6951 } 6952 $( this ).toggleClass( "ui-state-active" ); 6953 that.buttonElement.attr( "aria-pressed", that.element[0].checked ); 6954 }); 6955 } else if ( this.type === "radio" ) { 6956 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6957 if ( options.disabled || clickDragged ) { 6958 return false; 6959 } 6960 $( this ).addClass( "ui-state-active" ); 6961 that.buttonElement.attr( "aria-pressed", "true" ); 6962 6963 var radio = that.element[ 0 ]; 6964 radioGroup( radio ) 6965 .not( radio ) 6966 .map(function() { 6967 return $( this ).button( "widget" )[ 0 ]; 6968 }) 6969 .removeClass( "ui-state-active" ) 6970 .attr( "aria-pressed", "false" ); 6971 }); 6972 } else { 6973 this.buttonElement 6974 .bind( "mousedown" + this.eventNamespace, function() { 6975 if ( options.disabled ) { 6976 return false; 6977 } 6978 $( this ).addClass( "ui-state-active" ); 6979 lastActive = this; 6980 that.document.one( "mouseup", function() { 6981 lastActive = null; 6982 }); 6983 }) 6984 .bind( "mouseup" + this.eventNamespace, function() { 6985 if ( options.disabled ) { 6986 return false; 6987 } 6988 $( this ).removeClass( "ui-state-active" ); 6989 }) 6990 .bind( "keydown" + this.eventNamespace, function(event) { 6991 if ( options.disabled ) { 6992 return false; 6993 } 6994 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 6995 $( this ).addClass( "ui-state-active" ); 6996 } 6997 }) 6998 .bind( "keyup" + this.eventNamespace, function() { 6999 $( this ).removeClass( "ui-state-active" ); 7000 }); 7001 7002 if ( this.buttonElement.is("a") ) { 7003 this.buttonElement.keyup(function(event) { 7004 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7005 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7006 $( this ).click(); 7007 } 7008 }); 7009 } 7010 } 7011 7012 // TODO: pull out $.Widget's handling for the disabled option into 7013 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7014 // be overridden by individual plugins 7015 this._setOption( "disabled", options.disabled ); 7016 this._resetButton(); 7017 }, 7018 7019 _determineButtonType: function() { 7020 var ancestor, labelSelector, checked; 7021 7022 if ( this.element.is("[type=checkbox]") ) { 7023 this.type = "checkbox"; 7024 } else if ( this.element.is("[type=radio]") ) { 7025 this.type = "radio"; 7026 } else if ( this.element.is("input") ) { 7027 this.type = "input"; 7028 } else { 7029 this.type = "button"; 7030 } 7031 7032 if ( this.type === "checkbox" || this.type === "radio" ) { 7033 // we don't search against the document in case the element 7034 // is disconnected from the DOM 7035 ancestor = this.element.parents().last(); 7036 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7037 this.buttonElement = ancestor.find( labelSelector ); 7038 if ( !this.buttonElement.length ) { 7039 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7040 this.buttonElement = ancestor.filter( labelSelector ); 7041 if ( !this.buttonElement.length ) { 7042 this.buttonElement = ancestor.find( labelSelector ); 7043 } 7044 } 7045 this.element.addClass( "ui-helper-hidden-accessible" ); 7046 7047 checked = this.element.is( ":checked" ); 7048 if ( checked ) { 7049 this.buttonElement.addClass( "ui-state-active" ); 7050 } 7051 this.buttonElement.prop( "aria-pressed", checked ); 7052 } else { 7053 this.buttonElement = this.element; 7054 } 7055 }, 7056 7057 widget: function() { 7058 return this.buttonElement; 7059 }, 7060 7061 _destroy: function() { 7062 this.element 7063 .removeClass( "ui-helper-hidden-accessible" ); 7064 this.buttonElement 7065 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7066 .removeAttr( "role" ) 7067 .removeAttr( "aria-pressed" ) 7068 .html( this.buttonElement.find(".ui-button-text").html() ); 7069 7070 if ( !this.hasTitle ) {
vendor: 6,498 bytes, lines 7071-7262
7071 this.buttonElement.removeAttr( "title" ); 7072 } 7073 }, 7074 7075 _setOption: function( key, value ) { 7076 this._super( key, value ); 7077 if ( key === "disabled" ) { 7078 if ( value ) { 7079 this.element.prop( "disabled", true ); 7080 } else { 7081 this.element.prop( "disabled", false ); 7082 } 7083 return; 7084 } 7085 this._resetButton(); 7086 }, 7087 7088 refresh: function() { 7089 //See #8237 & #8828 7090 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7091 7092 if ( isDisabled !== this.options.disabled ) { 7093 this._setOption( "disabled", isDisabled ); 7094 } 7095 if ( this.type === "radio" ) { 7096 radioGroup( this.element[0] ).each(function() { 7097 if ( $( this ).is( ":checked" ) ) { 7098 $( this ).button( "widget" ) 7099 .addClass( "ui-state-active" ) 7100 .attr( "aria-pressed", "true" ); 7101 } else { 7102 $( this ).button( "widget" ) 7103 .removeClass( "ui-state-active" ) 7104 .attr( "aria-pressed", "false" ); 7105 } 7106 }); 7107 } else if ( this.type === "checkbox" ) { 7108 if ( this.element.is( ":checked" ) ) { 7109 this.buttonElement 7110 .addClass( "ui-state-active" ) 7111 .attr( "aria-pressed", "true" ); 7112 } else { 7113 this.buttonElement 7114 .removeClass( "ui-state-active" ) 7115 .attr( "aria-pressed", "false" ); 7116 } 7117 } 7118 }, 7119 7120 _resetButton: function() { 7121 if ( this.type === "input" ) { 7122 if ( this.options.label ) { 7123 this.element.val( this.options.label ); 7124 } 7125 return; 7126 } 7127 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7128 buttonText = $( "<span></span>", this.document[0] ) 7129 .addClass( "ui-button-text" ) 7130 .html( this.options.label ) 7131 .appendTo( buttonElement.empty() ) 7132 .text(), 7133 icons = this.options.icons, 7134 multipleIcons = icons.primary && icons.secondary, 7135 buttonClasses = []; 7136 7137 if ( icons.primary || icons.secondary ) { 7138 if ( this.options.text ) { 7139 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7140 } 7141 7142 if ( icons.primary ) { 7143 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7144 } 7145 7146 if ( icons.secondary ) { 7147 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7148 } 7149 7150 if ( !this.options.text ) { 7151 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7152 7153 if ( !this.hasTitle ) { 7154 buttonElement.attr( "title", $.trim( buttonText ) ); 7155 } 7156 } 7157 } else { 7158 buttonClasses.push( "ui-button-text-only" ); 7159 } 7160 buttonElement.addClass( buttonClasses.join( " " ) ); 7161 } 7162}); 7163 7164$.widget( "ui.buttonset", { 7165 version: "1.9.2", 7166 options: { 7167 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)" 7168 }, 7169 7170 _create: function() { 7171 this.element.addClass( "ui-buttonset" ); 7172 }, 7173 7174 _init: function() { 7175 this.refresh(); 7176 }, 7177 7178 _setOption: function( key, value ) { 7179 if ( key === "disabled" ) { 7180 this.buttons.button( "option", key, value ); 7181 } 7182 7183 this._super( key, value ); 7184 }, 7185 7186 refresh: function() { 7187 var rtl = this.element.css( "direction" ) === "rtl"; 7188 7189 this.buttons = this.element.find( this.options.items ) 7190 .filter( ":ui-button" ) 7191 .button( "refresh" ) 7192 .end() 7193 .not( ":ui-button" ) 7194 .button() 7195 .end() 7196 .map(function() { 7197 return $( this ).button( "widget" )[ 0 ]; 7198 }) 7199 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7200 .filter( ":first" ) 7201 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7202 .end() 7203 .filter( ":last" ) 7204 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7205 .end() 7206 .end(); 7207 }, 7208 7209 _destroy: function() { 7210 this.element.removeClass( "ui-buttonset" ); 7211 this.buttons 7212 .map(function() { 7213 return $( this ).button( "widget" )[ 0 ]; 7214 }) 7215 .removeClass( "ui-corner-left ui-corner-right" ) 7216 .end() 7217 .button( "destroy" ); 7218 } 7219}); 7220 7221}( jQuery ) ); 7222 7223(function( $, undefined ) { 7224 7225$.extend($.ui, { datepicker: { version: "1.9.2" } }); 7226 7227var PROP_NAME = 'datepicker'; 7228var dpuuid = new Date().getTime(); 7229var instActive; 7230 7231/* Date picker manager. 7232 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7233 Settings for (groups of) date pickers are maintained in an instance object, 7234 allowing multiple different settings on the same page. */ 7235 7236function Datepicker() { 7237 this.debug = false; // Change this to true to start debugging 7238 this._curInst = null; // The current instance in use 7239 this._keyEvent = false; // If the last event was a key event 7240 this._disabledInputs = []; // List of date picker inputs that have been disabled 7241 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7242 this._inDialog = false; // True if showing within a "dialog", false if not 7243 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 7244 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 7245 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 7246 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 7247 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 7248 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 7249 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 7250 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 7251 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 7252 this.regional = []; // Available regional settings, indexed by language code 7253 this.regional[''] = { // Default regional settings 7254 closeText: 'Done', // Display text for close link 7255 prevText: 'Prev', // Display text for previous month link 7256 nextText: 'Next', // Display text for next month link 7257 currentText: 'Today', // Display text for current month link 7258 monthNames: ['January','February','March','April','May','June', 7259 'July','August','September','October','November','December'], // Names of months for drop-down and formatting 7260 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 7261 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 7262 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
vendor: 5,556 bytes, lines 7263-7360
7263 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday 7264 weekHeader: 'Wk', // Column header for week of the year 7265 dateFormat: 'mm/dd/yy', // See format options on parseDate 7266 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7267 isRTL: false, // True if right-to-left language, false if left-to-right 7268 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7269 yearSuffix: '' // Additional text to append to the year in the month headers 7270 }; 7271 this._defaults = { // Global defaults for all the date picker instances 7272 showOn: 'focus', // 'focus' for popup on focus, 7273 // 'button' for trigger button, or 'both' for either 7274 showAnim: 'fadeIn', // Name of jQuery animation for popup 7275 showOptions: {}, // Options for enhanced animations 7276 defaultDate: null, // Used when field is blank: actual date, 7277 // +/-number for offset from today, null for today 7278 appendText: '', // Display text following the input box, e.g. showing the format 7279 buttonText: '...', // Text for trigger button 7280 buttonImage: '', // URL for trigger button image 7281 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7282 hideIfNoPrevNext: false, // True to hide next/previous month links 7283 // if not applicable, false to just disable them 7284 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7285 gotoCurrent: false, // True if today link goes back to current selection instead 7286 changeMonth: false, // True if month can be selected directly, false if only prev/next 7287 changeYear: false, // True if year can be selected directly, false if only prev/next 7288 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 7289 // either relative to today's year (-nn:+nn), relative to currently displayed year 7290 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7291 showOtherMonths: false, // True to show dates in other months, false to leave blank 7292 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7293 showWeek: false, // True to show week of the year, false to not show it 7294 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7295 // takes a Date and returns the number of the week for it 7296 shortYearCutoff: '+10', // Short year values < this are in the current century, 7297 // > this are in the previous century, 7298 // string value starting with '+' for current year + value 7299 minDate: null, // The earliest selectable date, or null for no limit 7300 maxDate: null, // The latest selectable date, or null for no limit 7301 duration: 'fast', // Duration of display/closure 7302 beforeShowDay: null, // Function that takes a date and returns an array with 7303 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 7304 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7305 beforeShow: null, // Function that takes an input field and 7306 // returns a set of custom settings for the date picker 7307 onSelect: null, // Define a callback function when a date is selected 7308 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7309 onClose: null, // Define a callback function when the datepicker is closed 7310 numberOfMonths: 1, // Number of months to show at a time 7311 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7312 stepMonths: 1, // Number of months to step back/forward 7313 stepBigMonths: 12, // Number of months to step back/forward for the big links 7314 altField: '', // Selector for an alternate field to store selected dates into 7315 altFormat: '', // The date format to use for the alternate field 7316 constrainInput: true, // The input is constrained by the current date format 7317 showButtonPanel: false, // True to show button panel, false to not show it 7318 autoSize: false, // True to size the input for the date format, false to leave as is 7319 disabled: false // The initial disabled state 7320 }; 7321 $.extend(this._defaults, this.regional['']); 7322 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 7323} 7324 7325$.extend(Datepicker.prototype, { 7326 /* Class name added to elements to indicate already configured with a date picker. */ 7327 markerClassName: 'hasDatepicker', 7328 7329 //Keep track of the maximum number of rows displayed (see #7043) 7330 maxRows: 4, 7331 7332 /* Debug logging (if enabled). */ 7333 log: function () { 7334 if (this.debug) 7335 console.log.apply('', arguments); 7336 }, 7337 7338 // TODO rename to "widget" when switching to widget factory 7339 _widgetDatepicker: function() { 7340 return this.dpDiv; 7341 }, 7342 7343 /* Override the default settings for all instances of the date picker. 7344 @param settings object - the new settings to use as defaults (anonymous object) 7345 @return the manager object */ 7346 setDefaults: function(settings) { 7347 extendRemove(this._defaults, settings || {}); 7348 return this; 7349 }, 7350 7351 /* Attach the date picker to a jQuery selection. 7352 @param target element - the target input field or division or span 7353 @param settings object - the new settings to use for this date picker instance (anonymous) */ 7354 _attachDatepicker: function(target, settings) { 7355 // check for settings on the control itself - in namespace 'date:' 7356 var inlineSettings = null; 7357 for (var attrName in this._defaults) { 7358 var attrValue = target.getAttribute('date:' + attrName); 7359 if (attrValue) { 7360 inlineSettings = inlineSettings || {};
7361 try { 7362 inlineSettings[attrName] = eval(attrValue); 7363 } catch (err) { 7364 inlineSettings[attrName] = attrValue; 7365 } 7366 } 7367 } 7368 var nodeName = target.nodeName.toLowerCase(); 7369 var inline = (nodeName == 'div' || nodeName == 'span'); 7370 if (!target.id) { 7371 this.uuid += 1; 7372 target.id = 'dp' + this.uuid; 7373 } 7374 var inst = this._newInst($(target), inline); 7375 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 7376 if (nodeName == 'input') { 7377 this._connectDatepicker(target, inst); 7378 } else if (inline) { 7379 this._inlineDatepicker(target, inst); 7380 } 7381 }, 7382 7383 /* Create a new instance object. */ 7384 _newInst: function(target, inline) { 7385 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars 7386 return {id: id, input: target, // associated target 7387 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7388 drawMonth: 0, drawYear: 0, // month being drawn 7389 inline: inline, // is datepicker inline or not 7390 dpDiv: (!inline ? this.dpDiv : // presentation div 7391 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; 7392 }, 7393 7394 /* Attach the date picker to an input field. */ 7395 _connectDatepicker: function(target, inst) { 7396 var input = $(target); 7397 inst.append = $([]); 7398 inst.trigger = $([]); 7399 if (input.hasClass(this.markerClassName)) 7400 return; 7401 this._attachments(input, inst); 7402 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7403 keypress(this._doKeyPress).keyup(this._doKeyUp). 7404 bind("setData.datepicker", function(event, key, value) { 7405 inst.settings[key] = value; 7406 }).bind("getData.datepicker", function(event, key) { 7407 return this._get(inst, key); 7408 }); 7409 this._autoSize(inst); 7410 $.data(target, PROP_NAME, inst); 7411 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7412 if( inst.settings.disabled ) { 7413 this._disableDatepicker( target ); 7414 } 7415 }, 7416 7417 /* Make attachments based on settings. */ 7418 _attachments: function(input, inst) { 7419 var appendText = this._get(inst, 'appendText'); 7420 var isRTL = this._get(inst, 'isRTL'); 7421 if (inst.append) 7422 inst.append.remove(); 7423 if (appendText) { 7424 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); 7425 input[isRTL ? 'before' : 'after'](inst.append); 7426 } 7427 input.unbind('focus', this._showDatepicker); 7428 if (inst.trigger) 7429 inst.trigger.remove(); 7430 var showOn = this._get(inst, 'showOn'); 7431 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 7432 input.focus(this._showDatepicker); 7433 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 7434 var buttonText = this._get(inst, 'buttonText'); 7435 var buttonImage = this._get(inst, 'buttonImage'); 7436 inst.trigger = $(this._get(inst, 'buttonImageOnly') ? 7437 $('<img/>').addClass(this._triggerClass). 7438 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7439 $('<button type="button"></button>').addClass(this._triggerClass). 7440 html(buttonImage == '' ? buttonText : $('<img/>').attr( 7441 { src:buttonImage, alt:buttonText, title:buttonText }))); 7442 input[isRTL ? 'before' : 'after'](inst.trigger); 7443 inst.trigger.click(function() { 7444 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) 7445 $.datepicker._hideDatepicker(); 7446 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { 7447 $.datepicker._hideDatepicker(); 7448 $.datepicker._showDatepicker(input[0]); 7449 } else 7450 $.datepicker._showDatepicker(input[0]); 7451 return false; 7452 }); 7453 } 7454 }, 7455 7456 /* Apply the maximum length for the date format. */ 7457 _autoSize: function(inst) { 7458 if (this._get(inst, 'autoSize') && !inst.inline) { 7459 var date = new Date(2009, 12 - 1, 20); // Ensure double digits 7460 var dateFormat = this._get(inst, 'dateFormat'); 7461 if (dateFormat.match(/[DM]/)) { 7462 var findMax = function(names) { 7463 var max = 0; 7464 var maxI = 0; 7465 for (var i = 0; i < names.length; i++) { 7466 if (names[i].length > max) { 7467 max = names[i].length; 7468 maxI = i; 7469 } 7470 }
vendor: 4,711 bytes, lines 7471-7586
7471 return maxI; 7472 }; 7473 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7474 'monthNames' : 'monthNamesShort')))); 7475 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7476 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); 7477 } 7478 inst.input.attr('size', this._formatDate(inst, date).length); 7479 } 7480 }, 7481 7482 /* Attach an inline date picker to a div. */ 7483 _inlineDatepicker: function(target, inst) { 7484 var divSpan = $(target); 7485 if (divSpan.hasClass(this.markerClassName)) 7486 return; 7487 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 7488 bind("setData.datepicker", function(event, key, value){ 7489 inst.settings[key] = value; 7490 }).bind("getData.datepicker", function(event, key){ 7491 return this._get(inst, key); 7492 }); 7493 $.data(target, PROP_NAME, inst); 7494 this._setDate(inst, this._getDefaultDate(inst), true); 7495 this._updateDatepicker(inst); 7496 this._updateAlternate(inst); 7497 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7498 if( inst.settings.disabled ) { 7499 this._disableDatepicker( target ); 7500 } 7501 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7502 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7503 inst.dpDiv.css( "display", "block" ); 7504 }, 7505 7506 /* Pop-up the date picker in a "dialog" box. 7507 @param input element - ignored 7508 @param date string or Date - the initial date to display 7509 @param onSelect function - the function to call when a date is selected 7510 @param settings object - update the dialog date picker instance's settings (anonymous object) 7511 @param pos int[2] - coordinates for the dialog's position within the screen or 7512 event - with x/y coordinates or 7513 leave empty for default (screen centre) 7514 @return the manager object */ 7515 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7516 var inst = this._dialogInst; // internal instance 7517 if (!inst) { 7518 this.uuid += 1; 7519 var id = 'dp' + this.uuid; 7520 this._dialogInput = $('<input type="text" id="' + id + 7521 '" style="position: absolute; top: -100px; width: 0px;"/>'); 7522 this._dialogInput.keydown(this._doKeyDown); 7523 $('body').append(this._dialogInput); 7524 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7525 inst.settings = {}; 7526 $.data(this._dialogInput[0], PROP_NAME, inst); 7527 } 7528 extendRemove(inst.settings, settings || {}); 7529 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); 7530 this._dialogInput.val(date); 7531 7532 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7533 if (!this._pos) { 7534 var browserWidth = document.documentElement.clientWidth; 7535 var browserHeight = document.documentElement.clientHeight; 7536 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7537 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7538 this._pos = // should use actual width/height below 7539 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7540 } 7541 7542 // move input on screen for focus, but hidden behind dialog 7543 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); 7544 inst.settings.onSelect = onSelect; 7545 this._inDialog = true; 7546 this.dpDiv.addClass(this._dialogClass); 7547 this._showDatepicker(this._dialogInput[0]); 7548 if ($.blockUI) 7549 $.blockUI(this.dpDiv); 7550 $.data(this._dialogInput[0], PROP_NAME, inst); 7551 return this; 7552 }, 7553 7554 /* Detach a datepicker from its control. 7555 @param target element - the target input field or division or span */ 7556 _destroyDatepicker: function(target) { 7557 var $target = $(target); 7558 var inst = $.data(target, PROP_NAME); 7559 if (!$target.hasClass(this.markerClassName)) { 7560 return; 7561 } 7562 var nodeName = target.nodeName.toLowerCase(); 7563 $.removeData(target, PROP_NAME); 7564 if (nodeName == 'input') { 7565 inst.append.remove(); 7566 inst.trigger.remove(); 7567 $target.removeClass(this.markerClassName). 7568 unbind('focus', this._showDatepicker). 7569 unbind('keydown', this._doKeyDown). 7570 unbind('keypress', this._doKeyPress). 7571 unbind('keyup', this._doKeyUp); 7572 } else if (nodeName == 'div' || nodeName == 'span') 7573 $target.removeClass(this.markerClassName).empty(); 7574 }, 7575 7576 /* Enable the date picker to a jQuery selection. 7577 @param target element - the target input field or division or span */ 7578 _enableDatepicker: function(target) { 7579 var $target = $(target); 7580 var inst = $.data(target, PROP_NAME); 7581 if (!$target.hasClass(this.markerClassName)) { 7582 return; 7583 } 7584 var nodeName = target.nodeName.toLowerCase(); 7585 if (nodeName == 'input') { 7586 target.disabled = false;
7587 inst.trigger.filter('button'). 7588 each(function() { this.disabled = false; }).end(). 7589 filter('img').css({opacity: '1.0', cursor: ''}); 7590 } 7591 else if (nodeName == 'div' || nodeName == 'span') { 7592 var inline = $target.children('.' + this._inlineClass); 7593 inline.children().removeClass('ui-state-disabled'); 7594 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7595 prop("disabled", false); 7596 } 7597 this._disabledInputs = $.map(this._disabledInputs, 7598 function(value) { return (value == target ? null : value); }); // delete entry 7599 }, 7600 7601 /* Disable the date picker to a jQuery selection. 7602 @param target element - the target input field or division or span */ 7603 _disableDatepicker: function(target) { 7604 var $target = $(target); 7605 var inst = $.data(target, PROP_NAME); 7606 if (!$target.hasClass(this.markerClassName)) { 7607 return; 7608 } 7609 var nodeName = target.nodeName.toLowerCase(); 7610 if (nodeName == 'input') { 7611 target.disabled = true; 7612 inst.trigger.filter('button'). 7613 each(function() { this.disabled = true; }).end(). 7614 filter('img').css({opacity: '0.5', cursor: 'default'}); 7615 } 7616 else if (nodeName == 'div' || nodeName == 'span') { 7617 var inline = $target.children('.' + this._inlineClass); 7618 inline.children().addClass('ui-state-disabled'); 7619 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7620 prop("disabled", true); 7621 } 7622 this._disabledInputs = $.map(this._disabledInputs, 7623 function(value) { return (value == target ? null : value); }); // delete entry 7624 this._disabledInputs[this._disabledInputs.length] = target; 7625 }, 7626 7627 /* Is the first field in a jQuery collection disabled as a datepicker? 7628 @param target element - the target input field or division or span 7629 @return boolean - true if disabled, false if enabled */ 7630 _isDisabledDatepicker: function(target) { 7631 if (!target) { 7632 return false; 7633 } 7634 for (var i = 0; i < this._disabledInputs.length; i++) { 7635 if (this._disabledInputs[i] == target) 7636 return true; 7637 } 7638 return false; 7639 }, 7640 7641 /* Retrieve the instance data for the target control. 7642 @param target element - the target input field or division or span 7643 @return object - the associated instance data 7644 @throws error if a jQuery problem getting data */ 7645 _getInst: function(target) { 7646 try { 7647 return $.data(target, PROP_NAME); 7648 } 7649 catch (err) { 7650 throw 'Missing instance data for this datepicker'; 7651 } 7652 }, 7653 7654 /* Update or retrieve the settings for a date picker attached to an input field or division. 7655 @param target element - the target input field or division or span 7656 @param name object - the new settings to update or 7657 string - the name of the setting to change or retrieve, 7658 when retrieving also 'all' for all instance settings or 7659 'defaults' for all global defaults 7660 @param value any - the new value for the setting 7661 (omit if above is an object or to retrieve a value) */ 7662 _optionDatepicker: function(target, name, value) { 7663 var inst = this._getInst(target); 7664 if (arguments.length == 2 && typeof name == 'string') { 7665 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : 7666 (inst ? (name == 'all' ? $.extend({}, inst.settings) : 7667 this._get(inst, name)) : null)); 7668 } 7669 var settings = name || {}; 7670 if (typeof name == 'string') { 7671 settings = {}; 7672 settings[name] = value; 7673 } 7674 if (inst) { 7675 if (this._curInst == inst) { 7676 this._hideDatepicker(); 7677 } 7678 var date = this._getDateDatepicker(target, true); 7679 var minDate = this._getMinMaxDate(inst, 'min'); 7680 var maxDate = this._getMinMaxDate(inst, 'max'); 7681 extendRemove(inst.settings, settings); 7682 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7683 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 7684 inst.settings.minDate = this._formatDate(inst, minDate); 7685 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 7686 inst.settings.maxDate = this._formatDate(inst, maxDate); 7687 this._attachments($(target), inst); 7688 this._autoSize(inst); 7689 this._setDate(inst, date); 7690 this._updateAlternate(inst); 7691 this._updateDatepicker(inst); 7692 } 7693 }, 7694 7695 // change method deprecated 7696 _changeDatepicker: function(target, name, value) { 7697 this._optionDatepicker(target, name, value); 7698 }, 7699 7700 /* Redraw the date picker attached to an input field or division. 7701 @param target element - the target input field or division or span */ 7702 _refreshDatepicker: function(target) { 7703 var inst = this._getInst(target); 7704 if (inst) { 7705 this._updateDatepicker(inst); 7706 } 7707 }, 7708 7709 /* Set the dates for a jQuery selection. 7710 @param target element - the target input field or division or span 7711 @param date Date - the new date */ 7712 _setDateDatepicker: function(target, date) { 7713 var inst = this._getInst(target); 7714 if (inst) { 7715 this._setDate(inst, date); 7716 this._updateDatepicker(inst); 7717 this._updateAlternate(inst); 7718 } 7719 }, 7720 7721 /* Get the date(s) for the first entry in a jQuery selection. 7722 @param target element - the target input field or division or span 7723 @param noDefault boolean - true if no default date is to be used 7724 @return Date - the current date */ 7725 _getDateDatepicker: function(target, noDefault) { 7726 var inst = this._getInst(target); 7727 if (inst && !inst.inline) 7728 this._setDateFromField(inst, noDefault); 7729 return (inst ? this._getDate(inst) : null); 7730 }, 7731 7732 /* Handle keystrokes. */ 7733 _doKeyDown: function(event) { 7734 var inst = $.datepicker._getInst(event.target); 7735 var handled = true; 7736 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); 7737 inst._keyEvent = true; 7738 if ($.datepicker._datepickerShowing) 7739 switch (event.keyCode) { 7740 case 9: $.datepicker._hideDatepicker(); 7741 handled = false;
7742 break; // hide on tab out 7743 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 7744 $.datepicker._currentClass + ')', inst.dpDiv); 7745 if (sel[0]) 7746 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 7747 var onSelect = $.datepicker._get(inst, 'onSelect'); 7748 if (onSelect) { 7749 var dateStr = $.datepicker._formatDate(inst); 7750 7751 // trigger custom callback 7752 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 7753 } 7754 else 7755 $.datepicker._hideDatepicker(); 7756 return false; // don't submit the form 7757 break; // select the value on enter 7758 case 27: $.datepicker._hideDatepicker(); 7759 break; // hide on escape 7760 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7761 -$.datepicker._get(inst, 'stepBigMonths') : 7762 -$.datepicker._get(inst, 'stepMonths')), 'M'); 7763 break; // previous month/year on page up/+ ctrl 7764 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7765 +$.datepicker._get(inst, 'stepBigMonths') : 7766 +$.datepicker._get(inst, 'stepMonths')), 'M'); 7767 break; // next month/year on page down/+ ctrl 7768 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 7769 handled = event.ctrlKey || event.metaKey; 7770 break; // clear on ctrl or command +end 7771 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 7772 handled = event.ctrlKey || event.metaKey; 7773 break; // current on ctrl or command +home 7774 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); 7775 handled = event.ctrlKey || event.metaKey; 7776 // -1 day on ctrl or command +left 7777 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7778 -$.datepicker._get(inst, 'stepBigMonths') : 7779 -$.datepicker._get(inst, 'stepMonths')), 'M'); 7780 // next month/year on alt +left on Mac 7781 break; 7782 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 7783 handled = event.ctrlKey || event.metaKey; 7784 break; // -1 week on ctrl or command +up 7785 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); 7786 handled = event.ctrlKey || event.metaKey; 7787 // +1 day on ctrl or command +right 7788 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7789 +$.datepicker._get(inst, 'stepBigMonths') : 7790 +$.datepicker._get(inst, 'stepMonths')), 'M'); 7791 // next month/year on alt +right 7792 break; 7793 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 7794 handled = event.ctrlKey || event.metaKey; 7795 break; // +1 week on ctrl or command +down 7796 default: handled = false; 7797 } 7798 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 7799 $.datepicker._showDatepicker(this); 7800 else { 7801 handled = false; 7802 } 7803 if (handled) { 7804 event.preventDefault(); 7805 event.stopPropagation(); 7806 } 7807 }, 7808 7809 /* Filter entered characters - based on date format. */ 7810 _doKeyPress: function(event) { 7811 var inst = $.datepicker._getInst(event.target); 7812 if ($.datepicker._get(inst, 'constrainInput')) { 7813 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); 7814 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 7815 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 7816 } 7817 }, 7818 7819 /* Synchronise manual entry and field/alternate field. */ 7820 _doKeyUp: function(event) { 7821 var inst = $.datepicker._getInst(event.target);
vendor: 8,608 bytes, lines 7822-8023
7822 if (inst.input.val() != inst.lastVal) { 7823 try { 7824 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 7825 (inst.input ? inst.input.val() : null), 7826 $.datepicker._getFormatConfig(inst)); 7827 if (date) { // only if valid 7828 $.datepicker._setDateFromField(inst); 7829 $.datepicker._updateAlternate(inst); 7830 $.datepicker._updateDatepicker(inst); 7831 } 7832 } 7833 catch (err) { 7834 $.datepicker.log(err); 7835 } 7836 } 7837 return true; 7838 }, 7839 7840 /* Pop-up the date picker for a given input field. 7841 If false returned from beforeShow event handler do not show. 7842 @param input element - the input field attached to the date picker or 7843 event - if triggered by focus */ 7844 _showDatepicker: function(input) { 7845 input = input.target || input; 7846 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 7847 input = $('input', input.parentNode)[0]; 7848 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 7849 return; 7850 var inst = $.datepicker._getInst(input); 7851 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 7852 $.datepicker._curInst.dpDiv.stop(true, true); 7853 if ( inst && $.datepicker._datepickerShowing ) { 7854 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 7855 } 7856 } 7857 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 7858 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7859 if(beforeShowSettings === false){ 7860 //false 7861 return; 7862 } 7863 extendRemove(inst.settings, beforeShowSettings); 7864 inst.lastVal = null; 7865 $.datepicker._lastInput = input; 7866 $.datepicker._setDateFromField(inst); 7867 if ($.datepicker._inDialog) // hide cursor 7868 input.value = ''; 7869 if (!$.datepicker._pos) { // position below input 7870 $.datepicker._pos = $.datepicker._findPos(input); 7871 $.datepicker._pos[1] += input.offsetHeight; // add the height 7872 } 7873 var isFixed = false; 7874 $(input).parents().each(function() { 7875 isFixed |= $(this).css('position') == 'fixed'; 7876 return !isFixed; 7877 }); 7878 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 7879 $.datepicker._pos = null; 7880 //to avoid flashes on Firefox 7881 inst.dpDiv.empty(); 7882 // determine sizing offscreen 7883 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); 7884 $.datepicker._updateDatepicker(inst); 7885 // fix width for dynamic number of date pickers 7886 // and adjust position before showing 7887 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7888 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 7889 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 7890 left: offset.left + 'px', top: offset.top + 'px'}); 7891 if (!inst.inline) { 7892 var showAnim = $.datepicker._get(inst, 'showAnim'); 7893 var duration = $.datepicker._get(inst, 'duration'); 7894 var postProcess = function() { 7895 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7896 if( !! cover.length ){ 7897 var borders = $.datepicker._getBorders(inst.dpDiv); 7898 cover.css({left: -borders[0], top: -borders[1], 7899 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); 7900 } 7901 }; 7902 inst.dpDiv.zIndex($(input).zIndex()+1); 7903 $.datepicker._datepickerShowing = true; 7904 7905 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7906 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 7907 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 7908 else 7909 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); 7910 if (!showAnim || !duration) 7911 postProcess(); 7912 if (inst.input.is(':visible') && !inst.input.is(':disabled')) 7913 inst.input.focus(); 7914 $.datepicker._curInst = inst; 7915 } 7916 }, 7917 7918 /* Generate the date picker content. */ 7919 _updateDatepicker: function(inst) { 7920 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 7921 var borders = $.datepicker._getBorders(inst.dpDiv); 7922 instActive = inst; // for delegate hover events 7923 inst.dpDiv.empty().append(this._generateHTML(inst)); 7924 this._attachHandlers(inst); 7925 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7926 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 7927 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) 7928 } 7929 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 7930 var numMonths = this._getNumberOfMonths(inst); 7931 var cols = numMonths[1]; 7932 var width = 17; 7933 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 7934 if (cols > 1) 7935 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 7936 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 7937 'Class']('ui-datepicker-multi'); 7938 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 7939 'Class']('ui-datepicker-rtl'); 7940 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 7941 // #6694 - don't focus the input if it's already focused 7942 // this breaks the change event in IE 7943 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) 7944 inst.input.focus(); 7945 // deffered render of the years select (to avoid flashes on Firefox) 7946 if( inst.yearshtml ){ 7947 var origyearshtml = inst.yearshtml; 7948 setTimeout(function(){ 7949 //assure that inst.yearshtml didn't change. 7950 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 7951 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 7952 } 7953 origyearshtml = inst.yearshtml = null; 7954 }, 0); 7955 } 7956 }, 7957 7958 /* Retrieve the size of left and top borders for an element. 7959 @param elem (jQuery object) the element of interest 7960 @return (number[2]) the left and top borders */ 7961 _getBorders: function(elem) { 7962 var convert = function(value) { 7963 return {thin: 1, medium: 2, thick: 3}[value] || value; 7964 }; 7965 return [parseFloat(convert(elem.css('border-left-width'))), 7966 parseFloat(convert(elem.css('border-top-width')))]; 7967 }, 7968 7969 /* Check positioning to remain on screen. */ 7970 _checkOffset: function(inst, offset, isFixed) { 7971 var dpWidth = inst.dpDiv.outerWidth(); 7972 var dpHeight = inst.dpDiv.outerHeight(); 7973 var inputWidth = inst.input ? inst.input.outerWidth() : 0; 7974 var inputHeight = inst.input ? inst.input.outerHeight() : 0; 7975 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); 7976 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 7977 7978 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); 7979 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; 7980 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 7981 7982 // now check if datepicker is showing outside window viewport - move to a better place if so. 7983 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 7984 Math.abs(offset.left + dpWidth - viewWidth) : 0); 7985 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 7986 Math.abs(dpHeight + inputHeight) : 0); 7987 7988 return offset; 7989 }, 7990 7991 /* Find an object's position on the screen. */ 7992 _findPos: function(obj) { 7993 var inst = this._getInst(obj); 7994 var isRTL = this._get(inst, 'isRTL'); 7995 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { 7996 obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; 7997 } 7998 var position = $(obj).offset(); 7999 return [position.left, position.top]; 8000 }, 8001 8002 /* Hide the date picker from view. 8003 @param input element - the input field attached to the date picker */ 8004 _hideDatepicker: function(input) { 8005 var inst = this._curInst; 8006 if (!inst || (input && inst != $.data(input, PROP_NAME))) 8007 return; 8008 if (this._datepickerShowing) { 8009 var showAnim = this._get(inst, 'showAnim'); 8010 var duration = this._get(inst, 'duration'); 8011 var postProcess = function() { 8012 $.datepicker._tidyDialog(inst); 8013 }; 8014 8015 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8016 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 8017 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 8018 else 8019 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : 8020 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); 8021 if (!showAnim) 8022 postProcess(); 8023 this._datepickerShowing = false;
8024 var onClose = this._get(inst, 'onClose'); 8025 if (onClose) 8026 onClose.apply((inst.input ? inst.input[0] : null), 8027 [(inst.input ? inst.input.val() : ''), inst]); 8028 this._lastInput = null; 8029 if (this._inDialog) { 8030 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 8031 if ($.blockUI) { 8032 $.unblockUI(); 8033 $('body').append(this.dpDiv); 8034 } 8035 } 8036 this._inDialog = false; 8037 } 8038 }, 8039 8040 /* Tidy up after a dialog display. */ 8041 _tidyDialog: function(inst) { 8042 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); 8043 }, 8044 8045 /* Close date picker if clicked elsewhere. */ 8046 _checkExternalClick: function(event) { 8047 if (!$.datepicker._curInst) 8048 return; 8049 8050 var $target = $(event.target), 8051 inst = $.datepicker._getInst($target[0]); 8052 8053 if ( ( ( $target[0].id != $.datepicker._mainDivId && 8054 $target.parents('#' + $.datepicker._mainDivId).length == 0 && 8055 !$target.hasClass($.datepicker.markerClassName) && 8056 !$target.closest("." + $.datepicker._triggerClass).length && 8057 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8058 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) 8059 $.datepicker._hideDatepicker(); 8060 }, 8061 8062 /* Adjust one of the date sub-fields. */ 8063 _adjustDate: function(id, offset, period) { 8064 var target = $(id); 8065 var inst = this._getInst(target[0]); 8066 if (this._isDisabledDatepicker(target[0])) { 8067 return; 8068 } 8069 this._adjustInstDate(inst, offset + 8070 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning 8071 period); 8072 this._updateDatepicker(inst); 8073 }, 8074 8075 /* Action for current link. */ 8076 _gotoToday: function(id) { 8077 var target = $(id); 8078 var inst = this._getInst(target[0]); 8079 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 8080 inst.selectedDay = inst.currentDay; 8081 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8082 inst.drawYear = inst.selectedYear = inst.currentYear; 8083 } 8084 else { 8085 var date = new Date(); 8086 inst.selectedDay = date.getDate(); 8087 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8088 inst.drawYear = inst.selectedYear = date.getFullYear(); 8089 } 8090 this._notifyChange(inst); 8091 this._adjustDate(target); 8092 }, 8093 8094 /* Action for selecting a new month/year. */ 8095 _selectMonthYear: function(id, select, period) { 8096 var target = $(id); 8097 var inst = this._getInst(target[0]); 8098 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 8099 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 8100 parseInt(select.options[select.selectedIndex].value,10); 8101 this._notifyChange(inst); 8102 this._adjustDate(target); 8103 }, 8104 8105 /* Action for selecting a day. */ 8106 _selectDay: function(id, month, year, td) { 8107 var target = $(id); 8108 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8109 return; 8110 } 8111 var inst = this._getInst(target[0]); 8112 inst.selectedDay = inst.currentDay = $('a', td).html(); 8113 inst.selectedMonth = inst.currentMonth = month; 8114 inst.selectedYear = inst.currentYear = year; 8115 this._selectDate(id, this._formatDate(inst, 8116 inst.currentDay, inst.currentMonth, inst.currentYear)); 8117 }, 8118 8119 /* Erase the input field and hide the date picker. */ 8120 _clearDate: function(id) { 8121 var target = $(id); 8122 var inst = this._getInst(target[0]); 8123 this._selectDate(target, ''); 8124 }, 8125 8126 /* Update the input field with the selected date. */ 8127 _selectDate: function(id, dateStr) { 8128 var target = $(id); 8129 var inst = this._getInst(target[0]); 8130 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8131 if (inst.input) 8132 inst.input.val(dateStr); 8133 this._updateAlternate(inst); 8134 var onSelect = this._get(inst, 'onSelect'); 8135 if (onSelect) 8136 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8137 else if (inst.input) 8138 inst.input.trigger('change'); // fire the change event 8139 if (inst.inline) 8140 this._updateDatepicker(inst); 8141 else { 8142 this._hideDatepicker(); 8143 this._lastInput = inst.input[0]; 8144 if (typeof(inst.input[0]) != 'object') 8145 inst.input.focus(); // restore focus 8146 this._lastInput = null; 8147 } 8148 }, 8149 8150 /* Update any alternate field to synchronise with the main field. */ 8151 _updateAlternate: function(inst) { 8152 var altField = this._get(inst, 'altField'); 8153 if (altField) { // update alternate field too 8154 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 8155 var date = this._getDate(inst); 8156 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8157 $(altField).each(function() { $(this).val(dateStr); }); 8158 } 8159 }, 8160 8161 /* Set as beforeShowDay function to prevent selection of weekends. 8162 @param date Date - the date to customise 8163 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 8164 noWeekends: function(date) { 8165 var day = date.getDay(); 8166 return [(day > 0 && day < 6), '']; 8167 }, 8168 8169 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8170 @param date Date - the date to get the week for 8171 @return number - the number of the week within the year that contains this date */ 8172 iso8601Week: function(date) { 8173 var checkDate = new Date(date.getTime()); 8174 // Find Thursday of this week starting on Monday 8175 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8176 var time = checkDate.getTime(); 8177 checkDate.setMonth(0); // Compare with Jan 1 8178 checkDate.setDate(1); 8179 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8180 }, 8181 8182 /* Parse a string value into a date object. 8183 See formatDate below for the possible formats. 8184
vendor: 4,158 bytes, lines 8185-8293
8185 @param format string - the expected format of the date 8186 @param value string - the date in the above format 8187 @param settings Object - attributes include: 8188 shortYearCutoff number - the cutoff year for determining the century (optional) 8189 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8190 dayNames string[7] - names of the days from Sunday (optional) 8191 monthNamesShort string[12] - abbreviated names of the months (optional) 8192 monthNames string[12] - names of the months (optional) 8193 @return Date - the extracted date value or null if value is blank */ 8194 parseDate: function (format, value, settings) { 8195 if (format == null || value == null) 8196 throw 'Invalid arguments'; 8197 value = (typeof value == 'object' ? value.toString() : value + ''); 8198 if (value == '') 8199 return null; 8200 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 8201 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8202 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8203 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 8204 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 8205 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 8206 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 8207 var year = -1; 8208 var month = -1; 8209 var day = -1; 8210 var doy = -1; 8211 var literal = false; 8212 // Check whether a format character is doubled 8213 var lookAhead = function(match) { 8214 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8215 if (matches) 8216 iFormat++; 8217 return matches; 8218 }; 8219 // Extract a number from the string value 8220 var getNumber = function(match) { 8221 var isDoubled = lookAhead(match); 8222 var size = (match == '@' ? 14 : (match == '!' ? 20 : 8223 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); 8224 var digits = new RegExp('^\\d{1,' + size + '}'); 8225 var num = value.substring(iValue).match(digits); 8226 if (!num) 8227 throw 'Missing number at position ' + iValue; 8228 iValue += num[0].length; 8229 return parseInt(num[0], 10); 8230 }; 8231 // Extract a name from the string value and convert to an index 8232 var getName = function(match, shortNames, longNames) { 8233 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8234 return [ [k, v] ]; 8235 }).sort(function (a, b) { 8236 return -(a[1].length - b[1].length); 8237 }); 8238 var index = -1; 8239 $.each(names, function (i, pair) { 8240 var name = pair[1]; 8241 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 8242 index = pair[0]; 8243 iValue += name.length; 8244 return false; 8245 } 8246 }); 8247 if (index != -1) 8248 return index + 1; 8249 else 8250 throw 'Unknown name at position ' + iValue; 8251 }; 8252 // Confirm that a literal character matches the string value 8253 var checkLiteral = function() { 8254 if (value.charAt(iValue) != format.charAt(iFormat)) 8255 throw 'Unexpected literal at position ' + iValue; 8256 iValue++; 8257 }; 8258 var iValue = 0; 8259 for (var iFormat = 0; iFormat < format.length; iFormat++) { 8260 if (literal) 8261 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8262 literal = false; 8263 else 8264 checkLiteral(); 8265 else 8266 switch (format.charAt(iFormat)) { 8267 case 'd': 8268 day = getNumber('d'); 8269 break; 8270 case 'D': 8271 getName('D', dayNamesShort, dayNames); 8272 break; 8273 case 'o': 8274 doy = getNumber('o'); 8275 break; 8276 case 'm': 8277 month = getNumber('m'); 8278 break; 8279 case 'M': 8280 month = getName('M', monthNamesShort, monthNames); 8281 break; 8282 case 'y': 8283 year = getNumber('y'); 8284 break; 8285 case '@': 8286 var date = new Date(getNumber('@')); 8287 year = date.getFullYear(); 8288 month = date.getMonth() + 1; 8289 day = date.getDate(); 8290 break; 8291 case '!': 8292 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); 8293 year = date.getFullYear();
8294 month = date.getMonth() + 1; 8295 day = date.getDate(); 8296 break; 8297 case "'": 8298 if (lookAhead("'")) 8299 checkLiteral(); 8300 else 8301 literal = true; 8302 break; 8303 default: 8304 checkLiteral(); 8305 } 8306 } 8307 if (iValue < value.length){ 8308 var extra = value.substr(iValue); 8309 if (!/^\s+/.test(extra)) { 8310 throw "Extra/unparsed characters found in date: " + extra; 8311 } 8312 } 8313 if (year == -1) 8314 year = new Date().getFullYear(); 8315 else if (year < 100) 8316 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8317 (year <= shortYearCutoff ? 0 : -100); 8318 if (doy > -1) { 8319 month = 1; 8320 day = doy; 8321 do { 8322 var dim = this._getDaysInMonth(year, month - 1); 8323 if (day <= dim) 8324 break; 8325 month++; 8326 day -= dim; 8327 } while (true); 8328 } 8329 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8330 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 8331 throw 'Invalid date'; // E.g. 31/02/00 8332 return date; 8333 }, 8334 8335 /* Standard date formats. */ 8336 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 8337 COOKIE: 'D, dd M yy', 8338 ISO_8601: 'yy-mm-dd', 8339 RFC_822: 'D, d M y', 8340 RFC_850: 'DD, dd-M-y', 8341 RFC_1036: 'D, d M y', 8342 RFC_1123: 'D, d M yy', 8343 RFC_2822: 'D, d M yy', 8344 RSS: 'D, d M y', // RFC 822 8345 TICKS: '!', 8346 TIMESTAMP: '@', 8347 W3C: 'yy-mm-dd', // ISO 8601 8348 8349 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8350 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8351 8352 /* Format a date object into a string value. 8353 The format can be combinations of the following: 8354 d - day of month (no leading zero) 8355 dd - day of month (two digit) 8356 o - day of year (no leading zeros) 8357 oo - day of year (three digit) 8358 D - day name short 8359 DD - day name long 8360 m - month of year (no leading zero) 8361 mm - month of year (two digit) 8362 M - month name short 8363 MM - month name long 8364 y - year (two digit) 8365 yy - year (four digit) 8366 @ - Unix timestamp (ms since 01/01/1970) 8367 ! - Windows ticks (100ns since 01/01/0001) 8368 '...' - literal text 8369 '' - single quote 8370 8371 @param format string - the desired format of the date 8372 @param date Date - the date value to format 8373 @param settings Object - attributes include: 8374 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8375 dayNames string[7] - names of the days from Sunday (optional) 8376 monthNamesShort string[12] - abbreviated names of the months (optional) 8377 monthNames string[12] - names of the months (optional) 8378 @return string - the date in the above format */ 8379 formatDate: function (format, date, settings) { 8380 if (!date) 8381 return ''; 8382 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 8383 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 8384 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 8385 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 8386 // Check whether a format character is doubled 8387 var lookAhead = function(match) { 8388 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8389 if (matches) 8390 iFormat++; 8391 return matches; 8392 }; 8393 // Format a number, with leading zero if necessary 8394 var formatNumber = function(match, value, len) { 8395 var num = '' + value; 8396 if (lookAhead(match)) 8397 while (num.length < len) 8398 num = '0' + num; 8399 return num; 8400 }; 8401 // Format a name, short or long as requested 8402 var formatName = function(match, value, shortNames, longNames) { 8403 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8404 }; 8405 var output = ''; 8406 var literal = false; 8407 if (date) 8408 for (var iFormat = 0; iFormat < format.length; iFormat++) { 8409 if (literal) 8410 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8411 literal = false; 8412 else 8413 output += format.charAt(iFormat); 8414 else 8415 switch (format.charAt(iFormat)) { 8416 case 'd': 8417 output += formatNumber('d', date.getDate(), 2); 8418 break; 8419 case 'D': 8420 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 8421 break; 8422 case 'o': 8423 output += formatNumber('o', 8424 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8425 break; 8426 case 'm': 8427 output += formatNumber('m', date.getMonth() + 1, 2); 8428 break; 8429 case 'M': 8430 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 8431 break; 8432 case 'y': 8433 output += (lookAhead('y') ? date.getFullYear() : 8434 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 8435 break; 8436 case '@': 8437 output += date.getTime(); 8438 break; 8439 case '!': 8440 output += date.getTime() * 10000 + this._ticksTo1970; 8441 break;
vendor: 5,981 bytes, lines 8442-8623
8442 case "'": 8443 if (lookAhead("'")) 8444 output += "'"; 8445 else 8446 literal = true; 8447 break; 8448 default: 8449 output += format.charAt(iFormat); 8450 } 8451 } 8452 return output; 8453 }, 8454 8455 /* Extract all possible characters from the date format. */ 8456 _possibleChars: function (format) { 8457 var chars = ''; 8458 var literal = false; 8459 // Check whether a format character is doubled 8460 var lookAhead = function(match) { 8461 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 8462 if (matches) 8463 iFormat++; 8464 return matches; 8465 }; 8466 for (var iFormat = 0; iFormat < format.length; iFormat++) 8467 if (literal) 8468 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 8469 literal = false; 8470 else 8471 chars += format.charAt(iFormat); 8472 else 8473 switch (format.charAt(iFormat)) { 8474 case 'd': case 'm': case 'y': case '@': 8475 chars += '0123456789'; 8476 break; 8477 case 'D': case 'M': 8478 return null; // Accept anything 8479 case "'": 8480 if (lookAhead("'")) 8481 chars += "'"; 8482 else 8483 literal = true; 8484 break; 8485 default: 8486 chars += format.charAt(iFormat); 8487 } 8488 return chars; 8489 }, 8490 8491 /* Get a setting value, defaulting if necessary. */ 8492 _get: function(inst, name) { 8493 return inst.settings[name] !== undefined ? 8494 inst.settings[name] : this._defaults[name]; 8495 }, 8496 8497 /* Parse existing date and initialise date picker. */ 8498 _setDateFromField: function(inst, noDefault) { 8499 if (inst.input.val() == inst.lastVal) { 8500 return; 8501 } 8502 var dateFormat = this._get(inst, 'dateFormat'); 8503 var dates = inst.lastVal = inst.input ? inst.input.val() : null; 8504 var date, defaultDate; 8505 date = defaultDate = this._getDefaultDate(inst); 8506 var settings = this._getFormatConfig(inst); 8507 try { 8508 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8509 } catch (event) { 8510 this.log(event); 8511 dates = (noDefault ? '' : dates); 8512 } 8513 inst.selectedDay = date.getDate(); 8514 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8515 inst.drawYear = inst.selectedYear = date.getFullYear(); 8516 inst.currentDay = (dates ? date.getDate() : 0); 8517 inst.currentMonth = (dates ? date.getMonth() : 0); 8518 inst.currentYear = (dates ? date.getFullYear() : 0); 8519 this._adjustInstDate(inst); 8520 }, 8521 8522 /* Retrieve the default date shown on opening. */ 8523 _getDefaultDate: function(inst) { 8524 return this._restrictMinMax(inst, 8525 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); 8526 }, 8527 8528 /* A date may be specified as an exact value or a relative one. */ 8529 _determineDate: function(inst, date, defaultDate) { 8530 var offsetNumeric = function(offset) { 8531 var date = new Date(); 8532 date.setDate(date.getDate() + offset); 8533 return date; 8534 }; 8535 var offsetString = function(offset) { 8536 try { 8537 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 8538 offset, $.datepicker._getFormatConfig(inst)); 8539 } 8540 catch (e) { 8541 // Ignore 8542 } 8543 var date = (offset.toLowerCase().match(/^c/) ? 8544 $.datepicker._getDate(inst) : null) || new Date(); 8545 var year = date.getFullYear(); 8546 var month = date.getMonth(); 8547 var day = date.getDate(); 8548 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 8549 var matches = pattern.exec(offset); 8550 while (matches) { 8551 switch (matches[2] || 'd') { 8552 case 'd' : case 'D' : 8553 day += parseInt(matches[1],10); break; 8554 case 'w' : case 'W' : 8555 day += parseInt(matches[1],10) * 7; break; 8556 case 'm' : case 'M' : 8557 month += parseInt(matches[1],10); 8558 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8559 break; 8560 case 'y': case 'Y' : 8561 year += parseInt(matches[1],10); 8562 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8563 break; 8564 } 8565 matches = pattern.exec(offset); 8566 } 8567 return new Date(year, month, day); 8568 }; 8569 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : 8570 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 8571 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); 8572 if (newDate) { 8573 newDate.setHours(0); 8574 newDate.setMinutes(0); 8575 newDate.setSeconds(0); 8576 newDate.setMilliseconds(0); 8577 } 8578 return this._daylightSavingAdjust(newDate); 8579 }, 8580 8581 /* Handle switch to/from daylight saving. 8582 Hours may be non-zero on daylight saving cut-over: 8583 > 12 when midnight changeover, but then cannot generate 8584 midnight datetime, so jump to 1AM, otherwise reset. 8585 @param date (Date) the date to check 8586 @return (Date) the corrected date */ 8587 _daylightSavingAdjust: function(date) { 8588 if (!date) return null; 8589 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 8590 return date; 8591 }, 8592 8593 /* Set the date(s) directly. */ 8594 _setDate: function(inst, date, noChange) { 8595 var clear = !date; 8596 var origMonth = inst.selectedMonth; 8597 var origYear = inst.selectedYear; 8598 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 8599 inst.selectedDay = inst.currentDay = newDate.getDate(); 8600 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8601 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8602 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) 8603 this._notifyChange(inst); 8604 this._adjustInstDate(inst); 8605 if (inst.input) { 8606 inst.input.val(clear ? '' : this._formatDate(inst)); 8607 } 8608 }, 8609 8610 /* Retrieve the date(s) directly. */ 8611 _getDate: function(inst) { 8612 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 8613 this._daylightSavingAdjust(new Date( 8614 inst.currentYear, inst.currentMonth, inst.currentDay))); 8615 return startDate; 8616 }, 8617 8618 /* Attach the onxxx handlers. These are declared statically so 8619 * they work with static code transformers like Caja. 8620 */ 8621 _attachHandlers: function(inst) { 8622 var stepMonths = this._get(inst, 'stepMonths'); 8623 var id = '#' + inst.id.replace( /\\\\/g, "\\" );
8624 inst.dpDiv.find('[data-handler]').map(function () { 8625 var handler = { 8626 prev: function () { 8627 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); 8628 }, 8629 next: function () { 8630 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); 8631 }, 8632 hide: function () { 8633 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); 8634 }, 8635 today: function () { 8636 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); 8637 }, 8638 selectDay: function () { 8639 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); 8640 return false; 8641 }, 8642 selectMonth: function () { 8643 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); 8644 return false; 8645 }, 8646 selectYear: function () { 8647 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); 8648 return false; 8649 } 8650 }; 8651 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); 8652 }); 8653 }, 8654 8655 /* Generate the HTML for the current state of the date picker. */ 8656 _generateHTML: function(inst) { 8657 var today = new Date(); 8658 today = this._daylightSavingAdjust( 8659 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 8660 var isRTL = this._get(inst, 'isRTL'); 8661 var showButtonPanel = this._get(inst, 'showButtonPanel'); 8662 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 8663 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 8664 var numMonths = this._getNumberOfMonths(inst); 8665 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 8666 var stepMonths = this._get(inst, 'stepMonths'); 8667 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 8668 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 8669 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8670 var minDate = this._getMinMaxDate(inst, 'min'); 8671 var maxDate = this._getMinMaxDate(inst, 'max'); 8672 var drawMonth = inst.drawMonth - showCurrentAtPos; 8673 var drawYear = inst.drawYear; 8674 if (drawMonth < 0) { 8675 drawMonth += 12; 8676 drawYear--; 8677 } 8678 if (maxDate) { 8679 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 8680 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 8681 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 8682 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 8683 drawMonth--; 8684 if (drawMonth < 0) { 8685 drawMonth = 11; 8686 drawYear--; 8687 } 8688 } 8689 } 8690 inst.drawMonth = drawMonth; 8691 inst.drawYear = drawYear; 8692 var prevText = this._get(inst, 'prevText'); 8693 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 8694 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 8695 this._getFormatConfig(inst))); 8696 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 8697 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + 8698 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : 8699 (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>')); 8700 var nextText = this._get(inst, 'nextText'); 8701 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 8702 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 8703 this._getFormatConfig(inst))); 8704 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 8705 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + 8706 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : 8707 (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>')); 8708 var currentText = this._get(inst, 'currentText'); 8709 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 8710 currentText = (!navigationAsDateFormat ? currentText : 8711 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 8712 var 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">' + 8713 this._get(inst, 'closeText') + '</button>' : ''); 8714 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + 8715 (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"' + 8716 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; 8717 var firstDay = parseInt(this._get(inst, 'firstDay'),10); 8718 firstDay = (isNaN(firstDay) ? 0 : firstDay); 8719 var showWeek = this._get(inst, 'showWeek'); 8720 var dayNames = this._get(inst, 'dayNames'); 8721 var dayNamesShort = this._get(inst, 'dayNamesShort'); 8722 var dayNamesMin = this._get(inst, 'dayNamesMin'); 8723 var monthNames = this._get(inst, 'monthNames'); 8724 var monthNamesShort = this._get(inst, 'monthNamesShort'); 8725 var beforeShowDay = this._get(inst, 'beforeShowDay'); 8726 var showOtherMonths = this._get(inst, 'showOtherMonths'); 8727 var selectOtherMonths = this._get(inst, 'selectOtherMonths'); 8728 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 8729 var defaultDate = this._getDefaultDate(inst); 8730 var html = ''; 8731 for (var row = 0; row < numMonths[0]; row++) { 8732 var group = ''; 8733 this.maxRows = 4; 8734 for (var col = 0; col < numMonths[1]; col++) { 8735 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 8736 var cornerClass = ' ui-corner-all'; 8737 var calender = ''; 8738 if (isMultiMonth) { 8739 calender += '<div class="ui-datepicker-group'; 8740 if (numMonths[1] > 1) 8741 switch (col) { 8742 case 0: calender += ' ui-datepicker-group-first'; 8743 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; 8744 case numMonths[1]-1: calender += ' ui-datepicker-group-last'; 8745 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; 8746 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; 8747 } 8748 calender += '">'; 8749 } 8750 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + 8751 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + 8752 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + 8753 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 8754 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 8755 '</div><table class="ui-datepicker-calendar"><thead>' + 8756 '<tr>'; 8757 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); 8758 for (var dow = 0; dow < 7; dow++) { // days of the week 8759 var day = (dow + firstDay) % 7; 8760 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
8760' + 8761 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; 8762 } 8763 calender += thead + '</tr></thead><tbody>'; 8764 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 8765 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 8766 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 8767 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 8768 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 8769 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 8770 this.maxRows = numRows; 8771 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8772 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 8773 calender += '<tr>'; 8774 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + 8775 this._get(inst, 'calculateWeek')(printDate) + '</td>'); 8776 for (var dow = 0; dow < 7; dow++) { // create date picker days 8777 var daySettings = (beforeShowDay ? 8778 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 8779 var otherMonth = (printDate.getMonth() != drawMonth); 8780 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 8781 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 8782 tbody += '<td class="' + 8783 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends 8784 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 8785 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 8786 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 8787 // or defaultDate is current printedDate and defaultDate is selectedDate 8788 ' ' + this._dayOverClass : '') + // highlight selected day 8789 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days 8790 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 8791 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day 8792 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 8793 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 8794 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions 8795 (otherMonth && !showOtherMonths ? ' ' : // display for other months 8796 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + 8797 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + 8798 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day 8799 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months 8800 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date 8801 printDate.setDate(printDate.getDate() + 1); 8802 printDate = this._daylightSavingAdjust(printDate); 8803 } 8804 calender += tbody + '</tr>'; 8805 } 8806 drawMonth++; 8807 if (drawMonth > 11) { 8808 drawMonth = 0; 8809 drawYear++; 8810 } 8811 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 8812 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); 8813 group += calender; 8814 } 8815 html += group; 8816 } 8817 html += buttonPanel + ($.ui.ie6 && !inst.inline ? 8818 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); 8819 inst._keyEvent = false; 8820 return html; 8821 }, 8822 8823 /* Generate the month and year header. */ 8824 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 8825 secondary, monthNames, monthNamesShort) { 8826 var changeMonth = this._get(inst, 'changeMonth'); 8827 var changeYear = this._get(inst, 'changeYear'); 8828 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 8829 var html = '<div class="ui-datepicker-title">'; 8830 var monthHtml = ''; 8831 // month selection 8832 if (secondary || !changeMonth) 8833 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 8834 else { 8835 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 8836 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 8837 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8838 for (var month = 0; month < 12; month++) { 8839 if ((!inMinYear || month >= minDate.getMonth()) && 8840 (!inMaxYear || month <= maxDate.getMonth())) 8841 monthHtml += '<option value="' + month + '"' + 8842 (month == drawMonth ? ' selected="selected"' : '') + 8843 '>' + monthNamesShort[month] + '</option>'; 8844 } 8845 monthHtml += '</select>'; 8846 } 8847 if (!showMonthAfterYear) 8848 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 8849 // year selection 8850 if ( !inst.yearshtml ) { 8851 inst.yearshtml = ''; 8852 if (secondary || !changeYear) 8853 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 8854 else { 8855 // determine range of years to display 8856 var years = this._get(inst, 'yearRange').split(':'); 8857 var thisYear = new Date().getFullYear(); 8858 var determineYear = function(value) { 8859 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8860 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 8861 parseInt(value, 10))); 8862 return (isNaN(year) ? thisYear : year); 8863 }; 8864 var year = determineYear(years[0]); 8865 var endYear = Math.max(year, determineYear(years[1] || '')); 8866 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8867 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8868 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 8869 for (; year <= endYear; year++) { 8870 inst.yearshtml += '<option value="' + year + '"' + 8871 (year == drawYear ? ' selected="selected"' : '') + 8872 '>' + year + '</option>'; 8873 } 8874 inst.yearshtml += '</select>'; 8875 8876 html += inst.yearshtml; 8877 inst.yearshtml = null; 8878 } 8879 } 8880 html += this._get(inst, 'yearSuffix'); 8881 if (showMonthAfterYear) 8882 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 8883 html += '</div>'; // Close datepicker_header 8884 return html; 8885 }, 8886 8887 /* Adjust one of the date sub-fields. */ 8888 _adjustInstDate: function(inst, offset, period) { 8889 var year = inst.drawYear + (period == 'Y' ? offset : 0); 8890 var month = inst.drawMonth + (period == 'M' ? offset : 0); 8891 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 8892 (period == 'D' ? offset : 0); 8893 var date = this._restrictMinMax(inst, 8894 this._daylightSavingAdjust(new Date(year, month, day))); 8895 inst.selectedDay = date.getDate(); 8896 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8897 inst.drawYear = inst.selectedYear = date.getFullYear(); 8898 if (period == 'M' || period == 'Y') 8899 this._notifyChange(inst); 8900 }, 8901 8902 /* Ensure a date is within any min/max bounds. */ 8903 _restrictMinMax: function(inst, date) { 8904 var minDate = this._getMinMaxDate(inst, 'min'); 8905 var maxDate = this._getMinMaxDate(inst, 'max'); 8906 var newDate = (minDate && date < minDate ? minDate : date); 8907 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 8908 return newDate; 8909 }, 8910 8911 /* Notify change of month/year. */ 8912 _notifyChange: function(inst) { 8913 var onChange = this._get(inst, 'onChangeMonthYear'); 8914 if (onChange) 8915 onChange.apply((inst.input ? inst.input[0] : null), 8916 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8917 }, 8918 8919 /* Determine the number of months to show. */ 8920 _getNumberOfMonths: function(inst) { 8921 var numMonths = this._get(inst, 'numberOfMonths'); 8922 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 8923 }, 8924 8925 /* Determine the current maximum date - ensure no time components are set. */ 8926 _getMinMaxDate: function(inst, minMax) { 8927 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 8928 }, 8929 8930 /* Find the number of days in a given month. */ 8931 _getDaysInMonth: function(year, month) { 8932 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8933 }, 8934 8935 /* Find the day of the week of the first of a month. */ 8936 _getFirstDayOfMonth: function(year, month) { 8937 return new Date(year, month, 1).getDay(); 8938 }, 8939 8940 /* Determines if we should allow a "next/prev" month display change. */ 8941 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 8942 var numMonths = this._getNumberOfMonths(inst); 8943 var date = this._daylightSavingAdjust(new Date(curYear, 8944 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8945 if (offset < 0) 8946 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8947 return this._isInRange(inst, date); 8948 }, 8949 8950 /* Is the given date in the accepted range? */ 8951 _isInRange: function(inst, date) { 8952 var minDate = this._getMinMaxDate(inst, 'min'); 8953 var maxDate = this._getMinMaxDate(inst, 'max'); 8954 return ((!minDate || date.getTime() >= minDate.getTime()) && 8955 (!maxDate || date.getTime() <= maxDate.getTime())); 8956 }, 8957 8958 /* Provide the configuration settings for formatting/parsing. */ 8959 _getFormatConfig: function(inst) { 8960 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 8961 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8962 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8963 return {shortYearCutoff: shortYearCutoff, 8964 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 8965 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 8966 }, 8967 8968 /* Format the given date for display. */ 8969 _formatDate: function(inst, day, month, year) { 8970 if (!day) { 8971 inst.currentDay = inst.selectedDay; 8972 inst.currentMonth = inst.selectedMonth; 8973 inst.currentYear = inst.selectedYear; 8974 } 8975 var date = (day ? (typeof day == 'object' ? day : 8976 this._daylightSavingAdjust(new Date(year, month, day))) : 8977 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8978 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 8979 } 8980}); 8981 8982/* 8983 * Bind hover events for datepicker elements. 8984 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8985 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8986 */ 8987function bindHover(dpDiv) { 8988 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 8989 return dpDiv.delegate(selector, 'mouseout', function() { 8990 $(this).removeClass('ui-state-hover'); 8991 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 8992 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 8993 }) 8994 .delegate(selector, 'mouseover', function(){ 8995 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 8996 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 8997 $(this).addClass('ui-state-hover'); 8998 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 8999 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 9000 } 9001 }); 9002} 9003 9004/* jQuery extend now ignores nulls! */ 9005function extendRemove(target, props) { 9006 $.extend(target, props); 9007 for (var name in props) 9008 if (props[name] == null || props[name] == undefined) 9009 target[name] = props[name]; 9010 return target; 9011}; 9012 9013/* Invoke the datepicker functionality. 9014 @param options string - a command, optionally followed by additional parameters or 9015 Object - settings for attaching new datepicker functionality 9016 @return jQuery object */ 9017$.fn.datepicker = function(options){ 9018 9019 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9020 if ( !this.length ) { 9021 return this; 9022 } 9023 9024 /* Initialise the date picker. */ 9025 if (!$.datepicker.initialized) { 9026 $(document).mousedown($.datepicker._checkExternalClick). 9027 find(document.body).append($.datepicker.dpDiv); 9028 $.datepicker.initialized = true; 9029 } 9030 9031 var otherArgs = Array.prototype.slice.call(arguments, 1); 9032 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 9033 return $.datepicker['_' + options + 'Datepicker']. 9034 apply($.datepicker, [this[0]].concat(otherArgs)); 9035 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 9036 return $.datepicker['_' + options + 'Datepicker']. 9037 apply($.datepicker, [this[0]].concat(otherArgs)); 9038 return this.each(function() { 9039 typeof options == 'string' ? 9040 $.datepicker['_' + options + 'Datepicker']. 9041 apply($.datepicker, [this].concat(otherArgs)) : 9042 $.datepicker._attachDatepicker(this, options); 9043 }); 9044}; 9045 9046$.datepicker = new Datepicker(); // singleton instance 9047$.datepicker.initialized = false;
9048$.datepicker.uuid = new Date().getTime(); 9049$.datepicker.version = "1.9.2"; 9050 9051// Workaround for #4055 9052// Add another global to avoid noConflict issues with inline event handlers 9053window['DP_jQuery_' + dpuuid] = $; 9054 9055})(jQuery); 9056 9057(function( $, undefined ) { 9058 9059var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", 9060 sizeRelatedOptions = { 9061 buttons: true, 9062 height: true, 9063 maxHeight: true, 9064 maxWidth: true, 9065 minHeight: true, 9066 minWidth: true, 9067 width: true 9068 }, 9069 resizableRelatedOptions = { 9070 maxHeight: true, 9071 maxWidth: true, 9072 minHeight: true, 9073 minWidth: true 9074 }; 9075 9076$.widget("ui.dialog", { 9077 version: "1.9.2", 9078 options: { 9079 autoOpen: true, 9080 buttons: {}, 9081 closeOnEscape: true, 9082 closeText: "close", 9083 dialogClass: "", 9084 draggable: true, 9085 hide: null, 9086 height: "auto", 9087 maxHeight: false, 9088 maxWidth: false, 9089 minHeight: 150, 9090 minWidth: 150, 9091 modal: false, 9092 position: { 9093 my: "center", 9094 at: "center", 9095 of: window, 9096 collision: "fit", 9097 // ensure that the titlebar is never outside the document 9098 using: function( pos ) { 9099 var topOffset = $( this ).css( pos ).offset().top; 9100 if ( topOffset < 0 ) { 9101 $( this ).css( "top", pos.top - topOffset ); 9102 } 9103 } 9104 }, 9105 resizable: true, 9106 show: null, 9107 stack: true, 9108 title: "", 9109 width: 300, 9110 zIndex: 1000 9111 }, 9112 9113 _create: function() { 9114 this.originalTitle = this.element.attr( "title" ); 9115 // #5742 - .attr() might return a DOMElement 9116 if ( typeof this.originalTitle !== "string" ) { 9117 this.originalTitle = ""; 9118 } 9119 this.oldPosition = { 9120 parent: this.element.parent(), 9121 index: this.element.parent().children().index( this.element ) 9122 }; 9123 this.options.title = this.options.title || this.originalTitle; 9124 var that = this, 9125 options = this.options, 9126 9127 title = options.title || " ", 9128 uiDialog, 9129 uiDialogTitlebar, 9130 uiDialogTitlebarClose, 9131 uiDialogTitle, 9132 uiDialogButtonPane; 9133 9134 uiDialog = ( this.uiDialog = $( "<div>" ) ) 9135 .addClass( uiDialogClasses + options.dialogClass ) 9136 .css({ 9137 display: "none", 9138 outline: 0, // TODO: move to stylesheet 9139 zIndex: options.zIndex 9140 }) 9141 // setting tabIndex makes the div focusable 9142 .attr( "tabIndex", -1) 9143 .keydown(function( event ) { 9144 if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9145 event.keyCode === $.ui.keyCode.ESCAPE ) { 9146 that.close( event ); 9147 event.preventDefault(); 9148 } 9149 }) 9150 .mousedown(function( event ) { 9151 that.moveToTop( false, event ); 9152 }) 9153 .appendTo( "body" ); 9154 9155 this.element 9156 .show() 9157 .removeAttr( "title" ) 9158 .addClass( "ui-dialog-content ui-widget-content" ) 9159 .appendTo( uiDialog ); 9160 9161 uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) ) 9162 .addClass( "ui-dialog-titlebar ui-widget-header " + 9163 "ui-corner-all ui-helper-clearfix" ) 9164 .bind( "mousedown", function() { 9165 // Dialog isn't getting focus when dragging (#8063) 9166 uiDialog.focus(); 9167 }) 9168 .prependTo( uiDialog ); 9169 9170 uiDialogTitlebarClose = $( "<a href='#'></a>" ) 9171 .addClass( "ui-dialog-titlebar-close ui-corner-all" ) 9172 .attr( "role", "button" ) 9173 .click(function( event ) { 9174 event.preventDefault(); 9175 that.close( event ); 9176 }) 9177 .appendTo( uiDialogTitlebar ); 9178 9179 ( this.uiDialogTitlebarCloseText = $( "<span>" ) ) 9180 .addClass( "ui-icon ui-icon-closethick" ) 9181 .text( options.closeText ) 9182 .appendTo( uiDialogTitlebarClose ); 9183 9184 uiDialogTitle = $( "<span>" ) 9185 .uniqueId() 9186 .addClass( "ui-dialog-title" ) 9187 .html( title ) 9188 .prependTo( uiDialogTitlebar ); 9189 9190 uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) 9191 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 9192 9193 ( this.uiButtonSet = $( "<div>" ) ) 9194 .addClass( "ui-dialog-buttonset" ) 9195 .appendTo( uiDialogButtonPane ); 9196 9197 uiDialog.attr({ 9198 role: "dialog", 9199 "aria-labelledby": uiDialogTitle.attr( "id" ) 9200 }); 9201 9202 uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); 9203 this._hoverable( uiDialogTitlebarClose ); 9204 this._focusable( uiDialogTitlebarClose ); 9205 9206 if ( options.draggable && $.fn.draggable ) { 9207 this._makeDraggable(); 9208 } 9209 if ( options.resizable && $.fn.resizable ) { 9210 this._makeResizable(); 9211 } 9212
9213 this._createButtons( options.buttons ); 9214 this._isOpen = false; 9215 9216 if ( $.fn.bgiframe ) { 9217 uiDialog.bgiframe(); 9218 } 9219 9220 // prevent tabbing out of modal dialogs 9221 this._on( uiDialog, { keydown: function( event ) { 9222 if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { 9223 return; 9224 } 9225 9226 var tabbables = $( ":tabbable", uiDialog ), 9227 first = tabbables.filter( ":first" ), 9228 last = tabbables.filter( ":last" ); 9229 9230 if ( event.target === last[0] && !event.shiftKey ) { 9231 first.focus( 1 ); 9232 return false; 9233 } else if ( event.target === first[0] && event.shiftKey ) { 9234 last.focus( 1 ); 9235 return false; 9236 } 9237 }}); 9238 }, 9239 9240 _init: function() { 9241 if ( this.options.autoOpen ) { 9242 this.open(); 9243 } 9244 }, 9245 9246 _destroy: function() { 9247 var next, 9248 oldPosition = this.oldPosition; 9249 9250 if ( this.overlay ) { 9251 this.overlay.destroy(); 9252 } 9253 this.uiDialog.hide(); 9254 this.element 9255 .removeClass( "ui-dialog-content ui-widget-content" ) 9256 .hide() 9257 .appendTo( "body" ); 9258 this.uiDialog.remove(); 9259 9260 if ( this.originalTitle ) { 9261 this.element.attr( "title", this.originalTitle ); 9262 } 9263 9264 next = oldPosition.parent.children().eq( oldPosition.index ); 9265 // Don't try to place the dialog next to itself (#8613) 9266 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 9267 next.before( this.element ); 9268 } else { 9269 oldPosition.parent.append( this.element ); 9270 } 9271 }, 9272 9273 widget: function() { 9274 return this.uiDialog; 9275 }, 9276 9277 close: function( event ) { 9278 var that = this, 9279 maxZ, thisZ; 9280 9281 if ( !this._isOpen ) { 9282 return; 9283 } 9284 9285 if ( false === this._trigger( "beforeClose", event ) ) { 9286 return; 9287 } 9288 9289 this._isOpen = false; 9290 9291 if ( this.overlay ) { 9292 this.overlay.destroy(); 9293 } 9294 9295 if ( this.options.hide ) { 9296 this._hide( this.uiDialog, this.options.hide, function() { 9297 that._trigger( "close", event ); 9298 }); 9299 } else { 9300 this.uiDialog.hide(); 9301 this._trigger( "close", event ); 9302 } 9303 9304 $.ui.dialog.overlay.resize(); 9305 9306 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9307 if ( this.options.modal ) { 9308 maxZ = 0; 9309 $( ".ui-dialog" ).each(function() { 9310 if ( this !== that.uiDialog[0] ) { 9311 thisZ = $( this ).css( "z-index" ); 9312 if ( !isNaN( thisZ ) ) { 9313 maxZ = Math.max( maxZ, thisZ ); 9314 } 9315 } 9316 }); 9317 $.ui.dialog.maxZ = maxZ; 9318 } 9319 9320 return this; 9321 }, 9322 9323 isOpen: function() { 9324 return this._isOpen; 9325 }, 9326 9327 // the force parameter allows us to move modal dialogs to their correct 9328 // position on open 9329 moveToTop: function( force, event ) { 9330 var options = this.options, 9331 saveScroll; 9332 9333 if ( ( options.modal && !force ) || 9334 ( !options.stack && !options.modal ) ) { 9335 return this._trigger( "focus", event ); 9336 } 9337 9338 if ( options.zIndex > $.ui.dialog.maxZ ) { 9339 $.ui.dialog.maxZ = options.zIndex; 9340 } 9341 if ( this.overlay ) { 9342 $.ui.dialog.maxZ += 1; 9343 $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; 9344 this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); 9345 } 9346 9347 // Save and then restore scroll 9348 // Opera 9.5+ resets when parent z-index is changed. 9349 // http://bugs.jqueryui.com/ticket/3193 9350 saveScroll = { 9351 scrollTop: this.element.scrollTop(), 9352 scrollLeft: this.element.scrollLeft() 9353 }; 9354 $.ui.dialog.maxZ += 1; 9355 this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); 9356 this.element.attr( saveScroll ); 9357 this._trigger( "focus", event ); 9358 9359 return this; 9360 }, 9361 9362 open: function() { 9363 if ( this._isOpen ) { 9364 return; 9365 } 9366 9367 var hasFocus, 9368 options = this.options, 9369 uiDialog = this.uiDialog; 9370 9371 this._size(); 9372 this._position( options.position ); 9373 uiDialog.show( options.show ); 9374 this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; 9375 this.moveToTop( true ); 9376 9377 // set focus to the first tabbable element in the content area or the first button 9378 // if there are no tabbable elements, set focus on the dialog itself 9379 hasFocus = this.element.find( ":tabbable" ); 9380 if ( !hasFocus.length ) { 9381 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 9382 if ( !hasFocus.length ) { 9383 hasFocus = uiDialog; 9384 } 9385 } 9386 hasFocus.eq( 0 ).focus(); 9387 9388 this._isOpen = true; 9389 this._trigger( "open" ); 9390 9391 return this; 9392 }, 9393 9394 _createButtons: function( buttons ) { 9395 var that = this, 9396 hasButtons = false;
9397 9398 // if we already have a button pane, remove it 9399 this.uiDialogButtonPane.remove(); 9400 this.uiButtonSet.empty(); 9401 9402 if ( typeof buttons === "object" && buttons !== null ) { 9403 $.each( buttons, function() { 9404 return !(hasButtons = true); 9405 }); 9406 } 9407 if ( hasButtons ) { 9408 $.each( buttons, function( name, props ) { 9409 var button, click; 9410 props = $.isFunction( props ) ? 9411 { click: props, text: name } : 9412 props; 9413 // Default to a non-submitting button 9414 props = $.extend( { type: "button" }, props ); 9415 // Change the context for the click callback to be the main element 9416 click = props.click; 9417 props.click = function() { 9418 click.apply( that.element[0], arguments ); 9419 }; 9420 button = $( "<button></button>", props ) 9421 .appendTo( that.uiButtonSet ); 9422 if ( $.fn.button ) { 9423 button.button(); 9424 } 9425 }); 9426 this.uiDialog.addClass( "ui-dialog-buttons" ); 9427 this.uiDialogButtonPane.appendTo( this.uiDialog ); 9428 } else { 9429 this.uiDialog.removeClass( "ui-dialog-buttons" ); 9430 } 9431 }, 9432 9433 _makeDraggable: function() { 9434 var that = this, 9435 options = this.options; 9436 9437 function filteredUi( ui ) { 9438 return { 9439 position: ui.position, 9440 offset: ui.offset 9441 }; 9442 } 9443 9444 this.uiDialog.draggable({ 9445 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 9446 handle: ".ui-dialog-titlebar", 9447 containment: "document", 9448 start: function( event, ui ) { 9449 $( this ) 9450 .addClass( "ui-dialog-dragging" ); 9451 that._trigger( "dragStart", event, filteredUi( ui ) ); 9452 }, 9453 drag: function( event, ui ) { 9454 that._trigger( "drag", event, filteredUi( ui ) ); 9455 }, 9456 stop: function( event, ui ) { 9457 options.position = [ 9458 ui.position.left - that.document.scrollLeft(), 9459 ui.position.top - that.document.scrollTop() 9460 ]; 9461 $( this ) 9462 .removeClass( "ui-dialog-dragging" ); 9463 that._trigger( "dragStop", event, filteredUi( ui ) ); 9464 $.ui.dialog.overlay.resize(); 9465 } 9466 }); 9467 }, 9468 9469 _makeResizable: function( handles ) { 9470 handles = (handles === undefined ? this.options.resizable : handles); 9471 var that = this, 9472 options = this.options, 9473 // .ui-resizable has position: relative defined in the stylesheet 9474 // but dialogs have to use absolute or fixed positioning 9475 position = this.uiDialog.css( "position" ), 9476 resizeHandles = typeof handles === 'string' ? 9477 handles : 9478 "n,e,s,w,se,sw,ne,nw"; 9479 9480 function filteredUi( ui ) { 9481 return { 9482 originalPosition: ui.originalPosition, 9483 originalSize: ui.originalSize, 9484 position: ui.position, 9485 size: ui.size 9486 }; 9487 } 9488 9489 this.uiDialog.resizable({ 9490 cancel: ".ui-dialog-content", 9491 containment: "document", 9492 alsoResize: this.element, 9493 maxWidth: options.maxWidth, 9494 maxHeight: options.maxHeight, 9495 minWidth: options.minWidth, 9496 minHeight: this._minHeight(), 9497 handles: resizeHandles, 9498 start: function( event, ui ) { 9499 $( this ).addClass( "ui-dialog-resizing" ); 9500 that._trigger( "resizeStart", event, filteredUi( ui ) ); 9501 }, 9502 resize: function( event, ui ) { 9503 that._trigger( "resize", event, filteredUi( ui ) ); 9504 }, 9505 stop: function( event, ui ) { 9506 $( this ).removeClass( "ui-dialog-resizing" ); 9507 options.height = $( this ).height(); 9508 options.width = $( this ).width(); 9509 that._trigger( "resizeStop", event, filteredUi( ui ) ); 9510 $.ui.dialog.overlay.resize(); 9511 } 9512 }) 9513 .css( "position", position ) 9514 .find( ".ui-resizable-se" ) 9515 .addClass( "ui-icon ui-icon-grip-diagonal-se" ); 9516 }, 9517 9518 _minHeight: function() { 9519 var options = this.options; 9520 9521 if ( options.height === "auto" ) { 9522 return options.minHeight; 9523 } else { 9524 return Math.min( options.minHeight, options.height ); 9525 } 9526 }, 9527 9528 _position: function( position ) { 9529 var myAt = [], 9530 offset = [ 0, 0 ], 9531 isVisible; 9532 9533 if ( position ) { 9534 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( 9535 // if (typeof position == 'string' || $.isArray(position)) { 9536 // myAt = $.isArray(position) ? position : position.split(' '); 9537 9538 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 9539 myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; 9540 if ( myAt.length === 1 ) { 9541 myAt[ 1 ] = myAt[ 0 ]; 9542 } 9543 9544 $.each( [ "left", "top" ], function( i, offsetPosition ) { 9545 if ( +myAt[ i ] === myAt[ i ] ) { 9546 offset[ i ] = myAt[ i ]; 9547 myAt[ i ] = offsetPosition; 9548 } 9549 }); 9550 9551 position = { 9552 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 9553 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 9554 at: myAt.join( " " ) 9555 }; 9556 } 9557 9558 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 9559 } else { 9560 position = $.ui.dialog.prototype.options.position; 9561 } 9562 9563 // need to show the dialog to get the actual offset in the position plugin 9564 isVisible = this.uiDialog.is( ":visible" ); 9565 if ( !isVisible ) { 9566 this.uiDialog.show(); 9567 } 9568 this.uiDialog.position( position ); 9569 if ( !isVisible ) { 9570 this.uiDialog.hide(); 9571 } 9572 }, 9573 9574 _setOptions: function( options ) { 9575 var that = this, 9576 resizableOptions = {}, 9577 resize = false;
9578 9579 $.each( options, function( key, value ) { 9580 that._setOption( key, value ); 9581 9582 if ( key in sizeRelatedOptions ) { 9583 resize = true; 9584 } 9585 if ( key in resizableRelatedOptions ) { 9586 resizableOptions[ key ] = value; 9587 } 9588 }); 9589 9590 if ( resize ) { 9591 this._size(); 9592 } 9593 if ( this.uiDialog.is( ":data(resizable)" ) ) { 9594 this.uiDialog.resizable( "option", resizableOptions ); 9595 } 9596 }, 9597 9598 _setOption: function( key, value ) { 9599 var isDraggable, isResizable, 9600 uiDialog = this.uiDialog; 9601 9602 switch ( key ) { 9603 case "buttons": 9604 this._createButtons( value ); 9605 break; 9606 case "closeText": 9607 // ensure that we always pass a string 9608 this.uiDialogTitlebarCloseText.text( "" + value ); 9609 break; 9610 case "dialogClass": 9611 uiDialog 9612 .removeClass( this.options.dialogClass ) 9613 .addClass( uiDialogClasses + value ); 9614 break; 9615 case "disabled": 9616 if ( value ) { 9617 uiDialog.addClass( "ui-dialog-disabled" ); 9618 } else { 9619 uiDialog.removeClass( "ui-dialog-disabled" ); 9620 } 9621 break; 9622 case "draggable": 9623 isDraggable = uiDialog.is( ":data(draggable)" ); 9624 if ( isDraggable && !value ) { 9625 uiDialog.draggable( "destroy" ); 9626 } 9627 9628 if ( !isDraggable && value ) { 9629 this._makeDraggable(); 9630 } 9631 break; 9632 case "position": 9633 this._position( value ); 9634 break; 9635 case "resizable": 9636 // currently resizable, becoming non-resizable 9637 isResizable = uiDialog.is( ":data(resizable)" ); 9638 if ( isResizable && !value ) { 9639 uiDialog.resizable( "destroy" ); 9640 } 9641 9642 // currently resizable, changing handles 9643 if ( isResizable && typeof value === "string" ) { 9644 uiDialog.resizable( "option", "handles", value ); 9645 } 9646 9647 // currently non-resizable, becoming resizable 9648 if ( !isResizable && value !== false ) { 9649 this._makeResizable( value ); 9650 } 9651 break; 9652 case "title": 9653 // convert whatever was passed in o a string, for html() to not throw up 9654 $( ".ui-dialog-title", this.uiDialogTitlebar ) 9655 .html( "" + ( value || " " ) ); 9656 break; 9657 } 9658 9659 this._super( key, value ); 9660 }, 9661 9662 _size: function() { 9663 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9664 * divs will both have width and height set, so we need to reset them 9665 */ 9666 var nonContentHeight, minContentHeight, autoHeight, 9667 options = this.options, 9668 isVisible = this.uiDialog.is( ":visible" ); 9669 9670 // reset content sizing 9671 this.element.show().css({ 9672 width: "auto", 9673 minHeight: 0, 9674 height: 0 9675 }); 9676 9677 if ( options.minWidth > options.width ) { 9678 options.width = options.minWidth; 9679 } 9680 9681 // reset wrapper sizing 9682 // determine the height of all the non-content elements 9683 nonContentHeight = this.uiDialog.css({ 9684 height: "auto", 9685 width: options.width 9686 }) 9687 .outerHeight(); 9688 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 9689 9690 if ( options.height === "auto" ) { 9691 // only needed for IE6 support 9692 if ( $.support.minHeight ) { 9693 this.element.css({ 9694 minHeight: minContentHeight, 9695 height: "auto" 9696 }); 9697 } else { 9698 this.uiDialog.show(); 9699 autoHeight = this.element.css( "height", "auto" ).height(); 9700 if ( !isVisible ) { 9701 this.uiDialog.hide(); 9702 } 9703 this.element.height( Math.max( autoHeight, minContentHeight ) ); 9704 } 9705 } else { 9706 this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); 9707 } 9708 9709 if (this.uiDialog.is( ":data(resizable)" ) ) { 9710 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 9711 } 9712 } 9713}); 9714 9715$.extend($.ui.dialog, { 9716 uuid: 0, 9717 maxZ: 0, 9718 9719 getTitleId: function($el) { 9720 var id = $el.attr( "id" ); 9721 if ( !id ) { 9722 this.uuid += 1; 9723 id = this.uuid; 9724 } 9725 return "ui-dialog-title-" + id; 9726 }, 9727 9728 overlay: function( dialog ) { 9729 this.$el = $.ui.dialog.overlay.create( dialog ); 9730 } 9731}); 9732 9733$.extend( $.ui.dialog.overlay, { 9734 instances: [], 9735 // reuse old instances due to IE memory leak with alpha transparency (see #5185) 9736 oldInstances: [], 9737 maxZ: 0, 9738 events: $.map( 9739 "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), 9740 function( event ) { 9741 return event + ".dialog-overlay"; 9742 } 9743 ).join( " " ), 9744 create: function( dialog ) { 9745 if ( this.instances.length === 0 ) { 9746 // prevent use of anchors and inputs 9747 // we use a setTimeout in case the overlay is created from an 9748 // event that we're going to be cancelling (see #2804) 9749 setTimeout(function() { 9750 // handle $(el).dialog().dialog('close') (see #4065) 9751 if ( $.ui.dialog.overlay.instances.length ) { 9752 $( document ).bind( $.ui.dialog.overlay.events, function( event ) { 9753 // stop events if the z-index of the target is < the z-index of the overlay 9754 // we cannot return true when we don't want to cancel the event (#3523) 9755 if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { 9756 return false;
9757 } 9758 }); 9759 } 9760 }, 1 ); 9761 9762 // handle window resize 9763 $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); 9764 } 9765 9766 var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); 9767 9768 // allow closing by pressing the escape key 9769 $( document ).bind( "keydown.dialog-overlay", function( event ) { 9770 var instances = $.ui.dialog.overlay.instances; 9771 // only react to the event if we're the top overlay 9772 if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && 9773 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9774 event.keyCode === $.ui.keyCode.ESCAPE ) { 9775 9776 dialog.close( event ); 9777 event.preventDefault(); 9778 } 9779 }); 9780 9781 $el.appendTo( document.body ).css({ 9782 width: this.width(), 9783 height: this.height() 9784 }); 9785 9786 if ( $.fn.bgiframe ) { 9787 $el.bgiframe(); 9788 } 9789 9790 this.instances.push( $el ); 9791 return $el; 9792 }, 9793 9794 destroy: function( $el ) { 9795 var indexOf = $.inArray( $el, this.instances ), 9796 maxZ = 0; 9797 9798 if ( indexOf !== -1 ) { 9799 this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); 9800 } 9801 9802 if ( this.instances.length === 0 ) { 9803 $( [ document, window ] ).unbind( ".dialog-overlay" ); 9804 } 9805 9806 $el.height( 0 ).width( 0 ).remove(); 9807 9808 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9809 $.each( this.instances, function() { 9810 maxZ = Math.max( maxZ, this.css( "z-index" ) ); 9811 }); 9812 this.maxZ = maxZ; 9813 }, 9814 9815 height: function() { 9816 var scrollHeight, 9817 offsetHeight; 9818 // handle IE 9819 if ( $.ui.ie ) { 9820 scrollHeight = Math.max( 9821 document.documentElement.scrollHeight, 9822 document.body.scrollHeight 9823 ); 9824 offsetHeight = Math.max( 9825 document.documentElement.offsetHeight, 9826 document.body.offsetHeight 9827 ); 9828 9829 if ( scrollHeight < offsetHeight ) { 9830 return $( window ).height() + "px"; 9831 } else { 9832 return scrollHeight + "px"; 9833 } 9834 // handle "good" browsers 9835 } else { 9836 return $( document ).height() + "px"; 9837 } 9838 }, 9839 9840 width: function() { 9841 var scrollWidth, 9842 offsetWidth; 9843 // handle IE 9844 if ( $.ui.ie ) { 9845 scrollWidth = Math.max( 9846 document.documentElement.scrollWidth, 9847 document.body.scrollWidth 9848 ); 9849 offsetWidth = Math.max( 9850 document.documentElement.offsetWidth, 9851 document.body.offsetWidth 9852 ); 9853 9854 if ( scrollWidth < offsetWidth ) { 9855 return $( window ).width() + "px"; 9856 } else { 9857 return scrollWidth + "px"; 9858 } 9859 // handle "good" browsers 9860 } else { 9861 return $( document ).width() + "px"; 9862 } 9863 }, 9864 9865 resize: function() { 9866 /* If the dialog is draggable and the user drags it past the 9867 * right edge of the window, the document becomes wider so we 9868 * need to stretch the overlay. If the user then drags the 9869 * dialog back to the left, the document will become narrower, 9870 * so we need to shrink the overlay to the appropriate size. 9871 * This is handled by shrinking the overlay before setting it 9872 * to the full document size. 9873 */ 9874 var $overlays = $( [] ); 9875 $.each( $.ui.dialog.overlay.instances, function() { 9876 $overlays = $overlays.add( this ); 9877 }); 9878 9879 $overlays.css({ 9880 width: 0, 9881 height: 0 9882 }).css({ 9883 width: $.ui.dialog.overlay.width(), 9884 height: $.ui.dialog.overlay.height() 9885 }); 9886 } 9887}); 9888 9889$.extend( $.ui.dialog.overlay.prototype, { 9890 destroy: function() { 9891 $.ui.dialog.overlay.destroy( this.$el ); 9892 } 9893}); 9894 9895}( jQuery ) ); 9896 9897(function( $, undefined ) { 9898 9899var rvertical = /up|down|vertical/, 9900 rpositivemotion = /up|left|vertical|horizontal/; 9901 9902$.effects.effect.blind = function( o, done ) { 9903 // Create element 9904 var el = $( this ), 9905 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 9906 mode = $.effects.setMode( el, o.mode || "hide" ), 9907 direction = o.direction || "up", 9908 vertical = rvertical.test( direction ), 9909 ref = vertical ? "height" : "width", 9910 ref2 = vertical ? "top" : "left", 9911 motion = rpositivemotion.test( direction ), 9912 animation = {}, 9913 show = mode === "show", 9914 wrapper, distance, margin; 9915 9916 // if already wrapped, the wrapper's properties are my property. #6245 9917 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 9918 $.effects.save( el.parent(), props ); 9919 } else { 9920 $.effects.save( el, props ); 9921 } 9922 el.show(); 9923 wrapper = $.effects.createWrapper( el ).css({ 9924 overflow: "hidden" 9925 }); 9926 9927 distance = wrapper[ ref ](); 9928 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 9929 9930 animation[ ref ] = show ? distance : 0; 9931 if ( !motion ) { 9932 el 9933 .css( vertical ? "bottom" : "right", 0 ) 9934 .css( vertical ? "top" : "left", "auto" ) 9935 .css({ position: "absolute" }); 9936 9937 animation[ ref2 ] = show ? margin : distance + margin; 9938 } 9939 9940 // start at 0 if we are showing 9941 if ( show ) { 9942 wrapper.css( ref, 0 ); 9943 if ( ! motion ) { 9944 wrapper.css( ref2, margin + distance ); 9945 } 9946 } 9947 9948 // Animate 9949 wrapper.animate( animation, { 9950 duration: o.duration, 9951 easing: o.easing, 9952 queue: false, 9953 complete: function() { 9954 if ( mode === "hide" ) { 9955 el.hide(); 9956 } 9957 $.effects.restore( el, props ); 9958 $.effects.removeWrapper( el ); 9959 done(); 9960 } 9961 }); 9962 9963}; 9964 9965})(jQuery); 9966 9967(function( $, undefined ) { 9968 9969$.effects.effect.bounce = function( o, done ) { 9970 var el = $( this ), 9971 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 9972 9973 // defaults: 9974 mode = $.effects.setMode( el, o.mode || "effect" ), 9975 hide = mode === "hide", 9976 show = mode === "show", 9977 direction = o.direction || "up", 9978 distance = o.distance, 9979 times = o.times || 5, 9980 9981 // number of internal animations 9982 anims = times * 2 + ( show || hide ? 1 : 0 ), 9983 speed = o.duration / anims, 9984 easing = o.easing, 9985 9986 // utility: 9987 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 9988 motion = ( direction === "up" || direction === "left" ), 9989 i, 9990 upAnim, 9991 downAnim, 9992 9993 // we will need to re-assemble the queue to stack our animations in place 9994 queue = el.queue(), 9995 queuelen = queue.length; 9996 9997 // Avoid touching opacity to prevent clearType and PNG issues in IE 9998 if ( show || hide ) { 9999 props.push( "opacity" ); 10000 } 10001 10002 $.effects.save( el, props ); 10003 el.show(); 10004 $.effects.createWrapper( el ); // Create Wrapper 10005 10006 // default distance for the BIGGEST bounce is the outer Distance / 3 10007 if ( !distance ) { 10008 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10009 } 10010 10011 if ( show ) { 10012 downAnim = { opacity: 1 }; 10013 downAnim[ ref ] = 0; 10014 10015 // if we are showing, force opacity 0 and set the initial position 10016 // then do the "first" animation 10017 el.css( "opacity", 0 ) 10018 .css( ref, motion ? -distance * 2 : distance * 2 ) 10019 .animate( downAnim, speed, easing ); 10020 } 10021 10022 // start at the smallest distance if we are hiding 10023 if ( hide ) { 10024 distance = distance / Math.pow( 2, times - 1 ); 10025 } 10026 10027 downAnim = {}; 10028 downAnim[ ref ] = 0; 10029 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10030 for ( i = 0; i < times; i++ ) { 10031 upAnim = {}; 10032 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10033 10034 el.animate( upAnim, speed, easing ) 10035 .animate( downAnim, speed, easing ); 10036 10037 distance = hide ? distance * 2 : distance / 2; 10038 } 10039 10040 // Last Bounce when Hiding 10041 if ( hide ) { 10042 upAnim = { opacity: 0 }; 10043 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10044 10045 el.animate( upAnim, speed, easing ); 10046 } 10047 10048 el.queue(function() { 10049 if ( hide ) { 10050 el.hide(); 10051 } 10052 $.effects.restore( el, props ); 10053 $.effects.removeWrapper( el ); 10054 done(); 10055 }); 10056 10057 // inject all the animations we just queued to be first in line (after "inprogress") 10058 if ( queuelen > 1) { 10059 queue.splice.apply( queue, 10060 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10061 } 10062 el.dequeue(); 10063 10064}; 10065 10066})(jQuery); 10067 10068(function( $, undefined ) { 10069 10070$.effects.effect.clip = function( o, done ) { 10071 // Create element 10072 var el = $( this ), 10073 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10074 mode = $.effects.setMode( el, o.mode || "hide" ), 10075 show = mode === "show", 10076 direction = o.direction || "vertical", 10077 vert = direction === "vertical", 10078 size = vert ? "height" : "width", 10079 position = vert ? "top" : "left", 10080 animation = {}, 10081 wrapper, animate, distance; 10082 10083 // Save & Show 10084 $.effects.save( el, props ); 10085 el.show(); 10086 10087 // Create Wrapper 10088 wrapper = $.effects.createWrapper( el ).css({ 10089 overflow: "hidden" 10090 }); 10091 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10092 distance = animate[ size ](); 10093 10094 // Shift 10095 if ( show ) { 10096 animate.css( size, 0 ); 10097 animate.css( position, distance / 2 ); 10098 } 10099 10100 // Create Animation Object: 10101 animation[ size ] = show ? distance : 0; 10102 animation[ position ] = show ? 0 : distance / 2; 10103 10104 // Animate 10105 animate.animate( animation, { 10106 queue: false, 10107 duration: o.duration, 10108 easing: o.easing,
vendor: 78,927 bytes, lines 10109-13051
10109 complete: function() { 10110 if ( !show ) { 10111 el.hide(); 10112 } 10113 $.effects.restore( el, props ); 10114 $.effects.removeWrapper( el ); 10115 done(); 10116 } 10117 }); 10118 10119}; 10120 10121})(jQuery); 10122 10123(function( $, undefined ) { 10124 10125$.effects.effect.drop = function( o, done ) { 10126 10127 var el = $( this ), 10128 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10129 mode = $.effects.setMode( el, o.mode || "hide" ), 10130 show = mode === "show", 10131 direction = o.direction || "left", 10132 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10133 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10134 animation = { 10135 opacity: show ? 1 : 0 10136 }, 10137 distance; 10138 10139 // Adjust 10140 $.effects.save( el, props ); 10141 el.show(); 10142 $.effects.createWrapper( el ); 10143 10144 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10145 10146 if ( show ) { 10147 el 10148 .css( "opacity", 0 ) 10149 .css( ref, motion === "pos" ? -distance : distance ); 10150 } 10151 10152 // Animation 10153 animation[ ref ] = ( show ? 10154 ( motion === "pos" ? "+=" : "-=" ) : 10155 ( motion === "pos" ? "-=" : "+=" ) ) + 10156 distance; 10157 10158 // Animate 10159 el.animate( animation, { 10160 queue: false, 10161 duration: o.duration, 10162 easing: o.easing, 10163 complete: function() { 10164 if ( mode === "hide" ) { 10165 el.hide(); 10166 } 10167 $.effects.restore( el, props ); 10168 $.effects.removeWrapper( el ); 10169 done(); 10170 } 10171 }); 10172}; 10173 10174})(jQuery); 10175 10176(function( $, undefined ) { 10177 10178$.effects.effect.explode = function( o, done ) { 10179 10180 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10181 cells = rows, 10182 el = $( this ), 10183 mode = $.effects.setMode( el, o.mode || "hide" ), 10184 show = mode === "show", 10185 10186 // show and then visibility:hidden the element before calculating offset 10187 offset = el.show().css( "visibility", "hidden" ).offset(), 10188 10189 // width and height of a piece 10190 width = Math.ceil( el.outerWidth() / cells ), 10191 height = Math.ceil( el.outerHeight() / rows ), 10192 pieces = [], 10193 10194 // loop 10195 i, j, left, top, mx, my; 10196 10197 // children animate complete: 10198 function childComplete() { 10199 pieces.push( this ); 10200 if ( pieces.length === rows * cells ) { 10201 animComplete(); 10202 } 10203 } 10204 10205 // clone the element for each row and cell. 10206 for( i = 0; i < rows ; i++ ) { // ===> 10207 top = offset.top + i * height; 10208 my = i - ( rows - 1 ) / 2 ; 10209 10210 for( j = 0; j < cells ; j++ ) { // ||| 10211 left = offset.left + j * width; 10212 mx = j - ( cells - 1 ) / 2 ; 10213 10214 // Create a clone of the now hidden main element that will be absolute positioned 10215 // within a wrapper div off the -left and -top equal to size of our pieces 10216 el 10217 .clone() 10218 .appendTo( "body" ) 10219 .wrap( "<div></div>" ) 10220 .css({ 10221 position: "absolute", 10222 visibility: "visible", 10223 left: -j * width, 10224 top: -i * height 10225 }) 10226 10227 // select the wrapper - make it overflow: hidden and absolute positioned based on 10228 // where the original was located +left and +top equal to the size of pieces 10229 .parent() 10230 .addClass( "ui-effects-explode" ) 10231 .css({ 10232 position: "absolute", 10233 overflow: "hidden", 10234 width: width, 10235 height: height, 10236 left: left + ( show ? mx * width : 0 ), 10237 top: top + ( show ? my * height : 0 ), 10238 opacity: show ? 0 : 1 10239 }).animate({ 10240 left: left + ( show ? 0 : mx * width ), 10241 top: top + ( show ? 0 : my * height ), 10242 opacity: show ? 1 : 0 10243 }, o.duration || 500, o.easing, childComplete ); 10244 } 10245 } 10246 10247 function animComplete() { 10248 el.css({ 10249 visibility: "visible" 10250 }); 10251 $( pieces ).remove(); 10252 if ( !show ) { 10253 el.hide(); 10254 } 10255 done(); 10256 } 10257}; 10258 10259})(jQuery); 10260 10261(function( $, undefined ) { 10262 10263$.effects.effect.fade = function( o, done ) { 10264 var el = $( this ), 10265 mode = $.effects.setMode( el, o.mode || "toggle" ); 10266 10267 el.animate({ 10268 opacity: mode 10269 }, { 10270 queue: false, 10271 duration: o.duration, 10272 easing: o.easing, 10273 complete: done 10274 }); 10275}; 10276 10277})( jQuery ); 10278 10279(function( $, undefined ) { 10280 10281$.effects.effect.fold = function( o, done ) { 10282 10283 // Create element 10284 var el = $( this ), 10285 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10286 mode = $.effects.setMode( el, o.mode || "hide" ), 10287 show = mode === "show", 10288 hide = mode === "hide", 10289 size = o.size || 15, 10290 percent = /([0-9]+)%/.exec( size ), 10291 horizFirst = !!o.horizFirst, 10292 widthFirst = show !== horizFirst, 10293 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10294 duration = o.duration / 2, 10295 wrapper, distance, 10296 animation1 = {}, 10297 animation2 = {}; 10298 10299 $.effects.save( el, props ); 10300 el.show(); 10301 10302 // Create Wrapper 10303 wrapper = $.effects.createWrapper( el ).css({ 10304 overflow: "hidden" 10305 }); 10306 distance = widthFirst ? 10307 [ wrapper.width(), wrapper.height() ] : 10308 [ wrapper.height(), wrapper.width() ]; 10309 10310 if ( percent ) { 10311 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10312 } 10313 if ( show ) { 10314 wrapper.css( horizFirst ? { 10315 height: 0, 10316 width: size 10317 } : { 10318 height: size, 10319 width: 0 10320 }); 10321 } 10322 10323 // Animation 10324 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10325 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10326 10327 // Animate 10328 wrapper 10329 .animate( animation1, duration, o.easing ) 10330 .animate( animation2, duration, o.easing, function() { 10331 if ( hide ) { 10332 el.hide(); 10333 } 10334 $.effects.restore( el, props ); 10335 $.effects.removeWrapper( el ); 10336 done(); 10337 }); 10338 10339}; 10340 10341})(jQuery); 10342 10343(function( $, undefined ) { 10344 10345$.effects.effect.highlight = function( o, done ) { 10346 var elem = $( this ), 10347 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10348 mode = $.effects.setMode( elem, o.mode || "show" ), 10349 animation = { 10350 backgroundColor: elem.css( "backgroundColor" ) 10351 }; 10352 10353 if (mode === "hide") { 10354 animation.opacity = 0; 10355 } 10356 10357 $.effects.save( elem, props ); 10358 10359 elem 10360 .show() 10361 .css({ 10362 backgroundImage: "none", 10363 backgroundColor: o.color || "#ffff99" 10364 }) 10365 .animate( animation, { 10366 queue: false, 10367 duration: o.duration, 10368 easing: o.easing, 10369 complete: function() { 10370 if ( mode === "hide" ) { 10371 elem.hide(); 10372 } 10373 $.effects.restore( elem, props ); 10374 done(); 10375 } 10376 }); 10377}; 10378 10379})(jQuery); 10380 10381(function( $, undefined ) { 10382 10383$.effects.effect.pulsate = function( o, done ) { 10384 var elem = $( this ), 10385 mode = $.effects.setMode( elem, o.mode || "show" ), 10386 show = mode === "show", 10387 hide = mode === "hide", 10388 showhide = ( show || mode === "hide" ), 10389 10390 // showing or hiding leaves of the "last" animation 10391 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10392 duration = o.duration / anims, 10393 animateTo = 0, 10394 queue = elem.queue(), 10395 queuelen = queue.length, 10396 i; 10397 10398 if ( show || !elem.is(":visible")) { 10399 elem.css( "opacity", 0 ).show(); 10400 animateTo = 1; 10401 } 10402 10403 // anims - 1 opacity "toggles" 10404 for ( i = 1; i < anims; i++ ) { 10405 elem.animate({ 10406 opacity: animateTo 10407 }, duration, o.easing ); 10408 animateTo = 1 - animateTo; 10409 } 10410 10411 elem.animate({ 10412 opacity: animateTo 10413 }, duration, o.easing); 10414 10415 elem.queue(function() { 10416 if ( hide ) { 10417 elem.hide(); 10418 } 10419 done(); 10420 }); 10421 10422 // We just queued up "anims" animations, we need to put them next in the queue 10423 if ( queuelen > 1 ) { 10424 queue.splice.apply( queue, 10425 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10426 } 10427 elem.dequeue(); 10428}; 10429 10430})(jQuery); 10431 10432(function( $, undefined ) { 10433 10434$.effects.effect.puff = function( o, done ) { 10435 var elem = $( this ), 10436 mode = $.effects.setMode( elem, o.mode || "hide" ), 10437 hide = mode === "hide", 10438 percent = parseInt( o.percent, 10 ) || 150, 10439 factor = percent / 100, 10440 original = { 10441 height: elem.height(), 10442 width: elem.width(), 10443 outerHeight: elem.outerHeight(), 10444 outerWidth: elem.outerWidth() 10445 }; 10446 10447 $.extend( o, { 10448 effect: "scale", 10449 queue: false, 10450 fade: true, 10451 mode: mode, 10452 complete: done, 10453 percent: hide ? percent : 100, 10454 from: hide ? 10455 original : 10456 { 10457 height: original.height * factor, 10458 width: original.width * factor, 10459 outerHeight: original.outerHeight * factor, 10460 outerWidth: original.outerWidth * factor 10461 } 10462 }); 10463 10464 elem.effect( o ); 10465}; 10466 10467$.effects.effect.scale = function( o, done ) { 10468 10469 // Create element 10470 var el = $( this ), 10471 options = $.extend( true, {}, o ), 10472 mode = $.effects.setMode( el, o.mode || "effect" ), 10473 percent = parseInt( o.percent, 10 ) || 10474 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 10475 direction = o.direction || "both", 10476 origin = o.origin, 10477 original = { 10478 height: el.height(), 10479 width: el.width(), 10480 outerHeight: el.outerHeight(), 10481 outerWidth: el.outerWidth() 10482 }, 10483 factor = { 10484 y: direction !== "horizontal" ? (percent / 100) : 1, 10485 x: direction !== "vertical" ? (percent / 100) : 1 10486 }; 10487 10488 // We are going to pass this effect to the size effect: 10489 options.effect = "size"; 10490 options.queue = false; 10491 options.complete = done; 10492 10493 // Set default origin and restore for show/hide 10494 if ( mode !== "effect" ) { 10495 options.origin = origin || ["middle","center"]; 10496 options.restore = true; 10497 } 10498 10499 options.from = o.from || ( mode === "show" ? { 10500 height: 0, 10501 width: 0, 10502 outerHeight: 0, 10503 outerWidth: 0 10504 } : original ); 10505 options.to = { 10506 height: original.height * factor.y, 10507 width: original.width * factor.x, 10508 outerHeight: original.outerHeight * factor.y, 10509 outerWidth: original.outerWidth * factor.x 10510 }; 10511 10512 // Fade option to support puff 10513 if ( options.fade ) { 10514 if ( mode === "show" ) { 10515 options.from.opacity = 0; 10516 options.to.opacity = 1; 10517 } 10518 if ( mode === "hide" ) { 10519 options.from.opacity = 1; 10520 options.to.opacity = 0; 10521 } 10522 } 10523 10524 // Animate 10525 el.effect( options ); 10526 10527}; 10528 10529$.effects.effect.size = function( o, done ) { 10530 10531 // Create element 10532 var original, baseline, factor, 10533 el = $( this ), 10534 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 10535 10536 // Always restore 10537 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 10538 10539 // Copy for children 10540 props2 = [ "width", "height", "overflow" ], 10541 cProps = [ "fontSize" ], 10542 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 10543 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 10544 10545 // Set options 10546 mode = $.effects.setMode( el, o.mode || "effect" ), 10547 restore = o.restore || mode !== "effect", 10548 scale = o.scale || "both", 10549 origin = o.origin || [ "middle", "center" ], 10550 position = el.css( "position" ), 10551 props = restore ? props0 : props1, 10552 zero = { 10553 height: 0, 10554 width: 0, 10555 outerHeight: 0, 10556 outerWidth: 0 10557 }; 10558 10559 if ( mode === "show" ) { 10560 el.show(); 10561 } 10562 original = { 10563 height: el.height(), 10564 width: el.width(), 10565 outerHeight: el.outerHeight(), 10566 outerWidth: el.outerWidth() 10567 }; 10568 10569 if ( o.mode === "toggle" && mode === "show" ) { 10570 el.from = o.to || zero; 10571 el.to = o.from || original; 10572 } else { 10573 el.from = o.from || ( mode === "show" ? zero : original ); 10574 el.to = o.to || ( mode === "hide" ? zero : original ); 10575 } 10576 10577 // Set scaling factor 10578 factor = { 10579 from: { 10580 y: el.from.height / original.height, 10581 x: el.from.width / original.width 10582 }, 10583 to: { 10584 y: el.to.height / original.height, 10585 x: el.to.width / original.width 10586 } 10587 }; 10588 10589 // Scale the css box 10590 if ( scale === "box" || scale === "both" ) { 10591 10592 // Vertical props scaling 10593 if ( factor.from.y !== factor.to.y ) { 10594 props = props.concat( vProps ); 10595 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 10596 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 10597 } 10598 10599 // Horizontal props scaling 10600 if ( factor.from.x !== factor.to.x ) { 10601 props = props.concat( hProps ); 10602 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 10603 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 10604 } 10605 } 10606 10607 // Scale the content 10608 if ( scale === "content" || scale === "both" ) { 10609 10610 // Vertical props scaling 10611 if ( factor.from.y !== factor.to.y ) { 10612 props = props.concat( cProps ).concat( props2 ); 10613 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 10614 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 10615 } 10616 } 10617 10618 $.effects.save( el, props ); 10619 el.show(); 10620 $.effects.createWrapper( el ); 10621 el.css( "overflow", "hidden" ).css( el.from ); 10622 10623 // Adjust 10624 if (origin) { // Calculate baseline shifts 10625 baseline = $.effects.getBaseline( origin, original ); 10626 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 10627 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 10628 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 10629 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 10630 } 10631 el.css( el.from ); // set top & left 10632 10633 // Animate 10634 if ( scale === "content" || scale === "both" ) { // Scale the children 10635 10636 // Add margins/font-size 10637 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 10638 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 10639 props2 = props0.concat(vProps).concat(hProps); 10640 10641 el.find( "*[width]" ).each( function(){ 10642 var child = $( this ), 10643 c_original = { 10644 height: child.height(), 10645 width: child.width(), 10646 outerHeight: child.outerHeight(), 10647 outerWidth: child.outerWidth() 10648 }; 10649 if (restore) { 10650 $.effects.save(child, props2); 10651 } 10652 10653 child.from = { 10654 height: c_original.height * factor.from.y, 10655 width: c_original.width * factor.from.x, 10656 outerHeight: c_original.outerHeight * factor.from.y, 10657 outerWidth: c_original.outerWidth * factor.from.x 10658 }; 10659 child.to = { 10660 height: c_original.height * factor.to.y, 10661 width: c_original.width * factor.to.x, 10662 outerHeight: c_original.height * factor.to.y, 10663 outerWidth: c_original.width * factor.to.x 10664 }; 10665 10666 // Vertical props scaling 10667 if ( factor.from.y !== factor.to.y ) { 10668 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 10669 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 10670 } 10671 10672 // Horizontal props scaling 10673 if ( factor.from.x !== factor.to.x ) { 10674 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 10675 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 10676 } 10677 10678 // Animate children 10679 child.css( child.from ); 10680 child.animate( child.to, o.duration, o.easing, function() { 10681 10682 // Restore children 10683 if ( restore ) { 10684 $.effects.restore( child, props2 ); 10685 } 10686 }); 10687 }); 10688 } 10689 10690 // Animate 10691 el.animate( el.to, { 10692 queue: false, 10693 duration: o.duration, 10694 easing: o.easing, 10695 complete: function() { 10696 if ( el.to.opacity === 0 ) { 10697 el.css( "opacity", el.from.opacity ); 10698 } 10699 if( mode === "hide" ) { 10700 el.hide(); 10701 } 10702 $.effects.restore( el, props ); 10703 if ( !restore ) { 10704 10705 // we need to calculate our new positioning based on the scaling 10706 if ( position === "static" ) { 10707 el.css({ 10708 position: "relative", 10709 top: el.to.top, 10710 left: el.to.left 10711 }); 10712 } else { 10713 $.each([ "top", "left" ], function( idx, pos ) { 10714 el.css( pos, function( _, str ) { 10715 var val = parseInt( str, 10 ), 10716 toRef = idx ? el.to.left : el.to.top; 10717 10718 // if original was "auto", recalculate the new value from wrapper 10719 if ( str === "auto" ) { 10720 return toRef + "px"; 10721 } 10722 10723 return val + toRef + "px"; 10724 }); 10725 }); 10726 } 10727 } 10728 10729 $.effects.removeWrapper( el ); 10730 done(); 10731 } 10732 }); 10733 10734}; 10735 10736})(jQuery); 10737 10738(function( $, undefined ) { 10739 10740$.effects.effect.shake = function( o, done ) { 10741 10742 var el = $( this ), 10743 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10744 mode = $.effects.setMode( el, o.mode || "effect" ), 10745 direction = o.direction || "left", 10746 distance = o.distance || 20, 10747 times = o.times || 3, 10748 anims = times * 2 + 1, 10749 speed = Math.round(o.duration/anims), 10750 ref = (direction === "up" || direction === "down") ? "top" : "left", 10751 positiveMotion = (direction === "up" || direction === "left"), 10752 animation = {}, 10753 animation1 = {}, 10754 animation2 = {}, 10755 i, 10756 10757 // we will need to re-assemble the queue to stack our animations in place 10758 queue = el.queue(), 10759 queuelen = queue.length; 10760 10761 $.effects.save( el, props ); 10762 el.show(); 10763 $.effects.createWrapper( el ); 10764 10765 // Animation 10766 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 10767 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 10768 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 10769 10770 // Animate 10771 el.animate( animation, speed, o.easing ); 10772 10773 // Shakes 10774 for ( i = 1; i < times; i++ ) { 10775 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 10776 } 10777 el 10778 .animate( animation1, speed, o.easing ) 10779 .animate( animation, speed / 2, o.easing ) 10780 .queue(function() { 10781 if ( mode === "hide" ) { 10782 el.hide(); 10783 } 10784 $.effects.restore( el, props ); 10785 $.effects.removeWrapper( el ); 10786 done(); 10787 }); 10788 10789 // inject all the animations we just queued to be first in line (after "inprogress") 10790 if ( queuelen > 1) { 10791 queue.splice.apply( queue, 10792 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10793 } 10794 el.dequeue(); 10795 10796}; 10797 10798})(jQuery); 10799 10800(function( $, undefined ) { 10801 10802$.effects.effect.slide = function( o, done ) { 10803 10804 // Create element 10805 var el = $( this ), 10806 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 10807 mode = $.effects.setMode( el, o.mode || "show" ), 10808 show = mode === "show", 10809 direction = o.direction || "left", 10810 ref = (direction === "up" || direction === "down") ? "top" : "left", 10811 positiveMotion = (direction === "up" || direction === "left"), 10812 distance, 10813 animation = {}; 10814 10815 // Adjust 10816 $.effects.save( el, props ); 10817 el.show(); 10818 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 10819 10820 $.effects.createWrapper( el ).css({ 10821 overflow: "hidden" 10822 }); 10823 10824 if ( show ) { 10825 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 10826 } 10827 10828 // Animation 10829 animation[ ref ] = ( show ? 10830 ( positiveMotion ? "+=" : "-=") : 10831 ( positiveMotion ? "-=" : "+=")) + 10832 distance; 10833 10834 // Animate 10835 el.animate( animation, { 10836 queue: false, 10837 duration: o.duration, 10838 easing: o.easing, 10839 complete: function() { 10840 if ( mode === "hide" ) { 10841 el.hide(); 10842 } 10843 $.effects.restore( el, props ); 10844 $.effects.removeWrapper( el ); 10845 done(); 10846 } 10847 }); 10848}; 10849 10850})(jQuery); 10851 10852(function( $, undefined ) { 10853 10854$.effects.effect.transfer = function( o, done ) { 10855 var elem = $( this ), 10856 target = $( o.to ), 10857 targetFixed = target.css( "position" ) === "fixed", 10858 body = $("body"), 10859 fixTop = targetFixed ? body.scrollTop() : 0, 10860 fixLeft = targetFixed ? body.scrollLeft() : 0, 10861 endPosition = target.offset(), 10862 animation = { 10863 top: endPosition.top - fixTop , 10864 left: endPosition.left - fixLeft , 10865 height: target.innerHeight(), 10866 width: target.innerWidth() 10867 }, 10868 startPosition = elem.offset(), 10869 transfer = $( '<div class="ui-effects-transfer"></div>' ) 10870 .appendTo( document.body ) 10871 .addClass( o.className ) 10872 .css({ 10873 top: startPosition.top - fixTop , 10874 left: startPosition.left - fixLeft , 10875 height: elem.innerHeight(), 10876 width: elem.innerWidth(), 10877 position: targetFixed ? "fixed" : "absolute" 10878 }) 10879 .animate( animation, o.duration, o.easing, function() { 10880 transfer.remove(); 10881 done(); 10882 }); 10883}; 10884 10885})(jQuery); 10886 10887(function( $, undefined ) { 10888 10889var mouseHandled = false; 10890 10891$.widget( "ui.menu", { 10892 version: "1.9.2", 10893 defaultElement: "<ul>", 10894 delay: 300, 10895 options: { 10896 icons: { 10897 submenu: "ui-icon-carat-1-e" 10898 }, 10899 menus: "ul", 10900 position: { 10901 my: "left top", 10902 at: "right top" 10903 }, 10904 role: "menu", 10905 10906 // callbacks 10907 blur: null, 10908 focus: null, 10909 select: null 10910 }, 10911 10912 _create: function() { 10913 this.activeMenu = this.element; 10914 this.element 10915 .uniqueId() 10916 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 10917 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 10918 .attr({ 10919 role: this.options.role, 10920 tabIndex: 0 10921 }) 10922 // need to catch all clicks on disabled menu 10923 // not possible through _on 10924 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 10925 if ( this.options.disabled ) { 10926 event.preventDefault(); 10927 } 10928 }, this )); 10929 10930 if ( this.options.disabled ) { 10931 this.element 10932 .addClass( "ui-state-disabled" ) 10933 .attr( "aria-disabled", "true" ); 10934 } 10935 10936 this._on({ 10937 // Prevent focus from sticking to links inside menu after clicking 10938 // them (focus should always stay on UL during navigation). 10939 "mousedown .ui-menu-item > a": function( event ) { 10940 event.preventDefault(); 10941 }, 10942 "click .ui-state-disabled > a": function( event ) { 10943 event.preventDefault(); 10944 }, 10945 "click .ui-menu-item:has(a)": function( event ) { 10946 var target = $( event.target ).closest( ".ui-menu-item" ); 10947 if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { 10948 mouseHandled = true; 10949 10950 this.select( event ); 10951 // Open submenu on click 10952 if ( target.has( ".ui-menu" ).length ) { 10953 this.expand( event ); 10954 } else if ( !this.element.is( ":focus" ) ) { 10955 // Redirect focus to the menu 10956 this.element.trigger( "focus", [ true ] ); 10957 10958 // If the active item is on the top level, let it stay active. 10959 // Otherwise, blur the active item since it is no longer visible. 10960 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 10961 clearTimeout( this.timer ); 10962 } 10963 } 10964 } 10965 }, 10966 "mouseenter .ui-menu-item": function( event ) { 10967 var target = $( event.currentTarget ); 10968 // Remove ui-state-active class from siblings of the newly focused menu item 10969 // to avoid a jump caused by adjacent elements both having a class with a border 10970 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 10971 this.focus( event, target ); 10972 }, 10973 mouseleave: "collapseAll", 10974 "mouseleave .ui-menu": "collapseAll", 10975 focus: function( event, keepActiveItem ) { 10976 // If there's already an active item, keep it active 10977 // If not, activate the first item 10978 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 10979 10980 if ( !keepActiveItem ) { 10981 this.focus( event, item ); 10982 } 10983 }, 10984 blur: function( event ) { 10985 this._delay(function() { 10986 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 10987 this.collapseAll( event ); 10988 } 10989 }); 10990 }, 10991 keydown: "_keydown" 10992 }); 10993 10994 this.refresh(); 10995 10996 // Clicks outside of a menu collapse any open menus 10997 this._on( this.document, { 10998 click: function( event ) { 10999 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11000 this.collapseAll( event ); 11001 } 11002 11003 // Reset the mouseHandled flag 11004 mouseHandled = false; 11005 } 11006 }); 11007 }, 11008 11009 _destroy: function() { 11010 // Destroy (sub)menus 11011 this.element 11012 .removeAttr( "aria-activedescendant" ) 11013 .find( ".ui-menu" ).andSelf() 11014 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11015 .removeAttr( "role" ) 11016 .removeAttr( "tabIndex" ) 11017 .removeAttr( "aria-labelledby" ) 11018 .removeAttr( "aria-expanded" ) 11019 .removeAttr( "aria-hidden" ) 11020 .removeAttr( "aria-disabled" ) 11021 .removeUniqueId() 11022 .show(); 11023 11024 // Destroy menu items 11025 this.element.find( ".ui-menu-item" ) 11026 .removeClass( "ui-menu-item" ) 11027 .removeAttr( "role" ) 11028 .removeAttr( "aria-disabled" ) 11029 .children( "a" ) 11030 .removeUniqueId() 11031 .removeClass( "ui-corner-all ui-state-hover" ) 11032 .removeAttr( "tabIndex" ) 11033 .removeAttr( "role" ) 11034 .removeAttr( "aria-haspopup" ) 11035 .children().each( function() { 11036 var elem = $( this ); 11037 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11038 elem.remove(); 11039 } 11040 }); 11041 11042 // Destroy menu dividers 11043 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11044 }, 11045 11046 _keydown: function( event ) { 11047 var match, prev, character, skip, regex, 11048 preventDefault = true; 11049 11050 function escape( value ) { 11051 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11052 } 11053 11054 switch ( event.keyCode ) { 11055 case $.ui.keyCode.PAGE_UP: 11056 this.previousPage( event ); 11057 break; 11058 case $.ui.keyCode.PAGE_DOWN: 11059 this.nextPage( event ); 11060 break; 11061 case $.ui.keyCode.HOME: 11062 this._move( "first", "first", event ); 11063 break; 11064 case $.ui.keyCode.END: 11065 this._move( "last", "last", event ); 11066 break; 11067 case $.ui.keyCode.UP: 11068 this.previous( event ); 11069 break; 11070 case $.ui.keyCode.DOWN: 11071 this.next( event ); 11072 break; 11073 case $.ui.keyCode.LEFT: 11074 this.collapse( event ); 11075 break; 11076 case $.ui.keyCode.RIGHT: 11077 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11078 this.expand( event ); 11079 } 11080 break; 11081 case $.ui.keyCode.ENTER: 11082 case $.ui.keyCode.SPACE: 11083 this._activate( event ); 11084 break; 11085 case $.ui.keyCode.ESCAPE: 11086 this.collapse( event ); 11087 break; 11088 default: 11089 preventDefault = false; 11090 prev = this.previousFilter || ""; 11091 character = String.fromCharCode( event.keyCode ); 11092 skip = false; 11093 11094 clearTimeout( this.filterTimer ); 11095 11096 if ( character === prev ) { 11097 skip = true; 11098 } else { 11099 character = prev + character; 11100 } 11101 11102 regex = new RegExp( "^" + escape( character ), "i" ); 11103 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11104 return regex.test( $( this ).children( "a" ).text() ); 11105 }); 11106 match = skip && match.index( this.active.next() ) !== -1 ? 11107 this.active.nextAll( ".ui-menu-item" ) : 11108 match; 11109 11110 // If no matches on the current filter, reset to the last character pressed 11111 // to move down the menu to the first item that starts with that character 11112 if ( !match.length ) { 11113 character = String.fromCharCode( event.keyCode ); 11114 regex = new RegExp( "^" + escape( character ), "i" ); 11115 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11116 return regex.test( $( this ).children( "a" ).text() ); 11117 }); 11118 } 11119 11120 if ( match.length ) { 11121 this.focus( event, match ); 11122 if ( match.length > 1 ) { 11123 this.previousFilter = character; 11124 this.filterTimer = this._delay(function() { 11125 delete this.previousFilter; 11126 }, 1000 ); 11127 } else { 11128 delete this.previousFilter; 11129 } 11130 } else { 11131 delete this.previousFilter; 11132 } 11133 } 11134 11135 if ( preventDefault ) { 11136 event.preventDefault(); 11137 } 11138 }, 11139 11140 _activate: function( event ) { 11141 if ( !this.active.is( ".ui-state-disabled" ) ) { 11142 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11143 this.expand( event ); 11144 } else { 11145 this.select( event ); 11146 } 11147 } 11148 }, 11149 11150 refresh: function() { 11151 var menus, 11152 icon = this.options.icons.submenu, 11153 submenus = this.element.find( this.options.menus ); 11154 11155 // Initialize nested menus 11156 submenus.filter( ":not(.ui-menu)" ) 11157 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11158 .hide() 11159 .attr({ 11160 role: this.options.role, 11161 "aria-hidden": "true", 11162 "aria-expanded": "false" 11163 }) 11164 .each(function() { 11165 var menu = $( this ), 11166 item = menu.prev( "a" ), 11167 submenuCarat = $( "<span>" ) 11168 .addClass( "ui-menu-icon ui-icon " + icon ) 11169 .data( "ui-menu-submenu-carat", true ); 11170 11171 item 11172 .attr( "aria-haspopup", "true" ) 11173 .prepend( submenuCarat ); 11174 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11175 }); 11176 11177 menus = submenus.add( this.element ); 11178 11179 // Don't refresh list items that are already adapted 11180 menus.children( ":not(.ui-menu-item):has(a)" ) 11181 .addClass( "ui-menu-item" ) 11182 .attr( "role", "presentation" ) 11183 .children( "a" ) 11184 .uniqueId() 11185 .addClass( "ui-corner-all" ) 11186 .attr({ 11187 tabIndex: -1, 11188 role: this._itemRole() 11189 }); 11190 11191 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11192 menus.children( ":not(.ui-menu-item)" ).each(function() { 11193 var item = $( this ); 11194 // hyphen, em dash, en dash 11195 if ( !/[^\-—–\s]/.test( item.text() ) ) { 11196 item.addClass( "ui-widget-content ui-menu-divider" ); 11197 } 11198 }); 11199 11200 // Add aria-disabled attribute to any disabled menu item 11201 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11202 11203 // If the active item has been removed, blur the menu 11204 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11205 this.blur(); 11206 } 11207 }, 11208 11209 _itemRole: function() { 11210 return { 11211 menu: "menuitem", 11212 listbox: "option" 11213 }[ this.options.role ]; 11214 }, 11215 11216 focus: function( event, item ) { 11217 var nested, focused; 11218 this.blur( event, event && event.type === "focus" ); 11219 11220 this._scrollIntoView( item ); 11221 11222 this.active = item.first(); 11223 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11224 // Only update aria-activedescendant if there's a role 11225 // otherwise we assume focus is managed elsewhere 11226 if ( this.options.role ) { 11227 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11228 } 11229 11230 // Highlight active parent menu item, if any 11231 this.active 11232 .parent() 11233 .closest( ".ui-menu-item" ) 11234 .children( "a:first" ) 11235 .addClass( "ui-state-active" ); 11236 11237 if ( event && event.type === "keydown" ) { 11238 this._close(); 11239 } else { 11240 this.timer = this._delay(function() { 11241 this._close(); 11242 }, this.delay ); 11243 } 11244 11245 nested = item.children( ".ui-menu" ); 11246 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11247 this._startOpening(nested); 11248 } 11249 this.activeMenu = item.parent(); 11250 11251 this._trigger( "focus", event, { item: item } ); 11252 }, 11253 11254 _scrollIntoView: function( item ) { 11255 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11256 if ( this._hasScroll() ) { 11257 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11258 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11259 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11260 scroll = this.activeMenu.scrollTop(); 11261 elementHeight = this.activeMenu.height(); 11262 itemHeight = item.height(); 11263 11264 if ( offset < 0 ) { 11265 this.activeMenu.scrollTop( scroll + offset ); 11266 } else if ( offset + itemHeight > elementHeight ) { 11267 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11268 } 11269 } 11270 }, 11271 11272 blur: function( event, fromFocus ) { 11273 if ( !fromFocus ) { 11274 clearTimeout( this.timer ); 11275 } 11276 11277 if ( !this.active ) { 11278 return; 11279 } 11280 11281 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11282 this.active = null; 11283 11284 this._trigger( "blur", event, { item: this.active } ); 11285 }, 11286 11287 _startOpening: function( submenu ) { 11288 clearTimeout( this.timer ); 11289 11290 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11291 // shift in the submenu position when mousing over the carat icon 11292 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11293 return; 11294 } 11295 11296 this.timer = this._delay(function() { 11297 this._close(); 11298 this._open( submenu ); 11299 }, this.delay ); 11300 }, 11301 11302 _open: function( submenu ) { 11303 var position = $.extend({ 11304 of: this.active 11305 }, this.options.position ); 11306 11307 clearTimeout( this.timer ); 11308 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11309 .hide() 11310 .attr( "aria-hidden", "true" ); 11311 11312 submenu 11313 .show() 11314 .removeAttr( "aria-hidden" ) 11315 .attr( "aria-expanded", "true" ) 11316 .position( position ); 11317 }, 11318 11319 collapseAll: function( event, all ) { 11320 clearTimeout( this.timer ); 11321 this.timer = this._delay(function() { 11322 // If we were passed an event, look for the submenu that contains the event 11323 var currentMenu = all ? this.element : 11324 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11325 11326 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11327 if ( !currentMenu.length ) { 11328 currentMenu = this.element; 11329 } 11330 11331 this._close( currentMenu ); 11332 11333 this.blur( event ); 11334 this.activeMenu = currentMenu; 11335 }, this.delay ); 11336 }, 11337 11338 // With no arguments, closes the currently active menu - if nothing is active 11339 // it closes all menus. If passed an argument, it will search for menus BELOW 11340 _close: function( startMenu ) { 11341 if ( !startMenu ) { 11342 startMenu = this.active ? this.active.parent() : this.element; 11343 } 11344 11345 startMenu 11346 .find( ".ui-menu" ) 11347 .hide() 11348 .attr( "aria-hidden", "true" ) 11349 .attr( "aria-expanded", "false" ) 11350 .end() 11351 .find( "a.ui-state-active" ) 11352 .removeClass( "ui-state-active" ); 11353 }, 11354 11355 collapse: function( event ) { 11356 var newItem = this.active && 11357 this.active.parent().closest( ".ui-menu-item", this.element ); 11358 if ( newItem && newItem.length ) { 11359 this._close(); 11360 this.focus( event, newItem ); 11361 } 11362 }, 11363 11364 expand: function( event ) { 11365 var newItem = this.active && 11366 this.active 11367 .children( ".ui-menu " ) 11368 .children( ".ui-menu-item" ) 11369 .first(); 11370 11371 if ( newItem && newItem.length ) { 11372 this._open( newItem.parent() ); 11373 11374 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11375 this._delay(function() { 11376 this.focus( event, newItem ); 11377 }); 11378 } 11379 }, 11380 11381 next: function( event ) { 11382 this._move( "next", "first", event ); 11383 }, 11384 11385 previous: function( event ) { 11386 this._move( "prev", "last", event ); 11387 }, 11388 11389 isFirstItem: function() { 11390 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11391 }, 11392 11393 isLastItem: function() { 11394 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11395 }, 11396 11397 _move: function( direction, filter, event ) { 11398 var next; 11399 if ( this.active ) { 11400 if ( direction === "first" || direction === "last" ) { 11401 next = this.active 11402 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11403 .eq( -1 ); 11404 } else { 11405 next = this.active 11406 [ direction + "All" ]( ".ui-menu-item" ) 11407 .eq( 0 ); 11408 } 11409 } 11410 if ( !next || !next.length || !this.active ) { 11411 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11412 } 11413 11414 this.focus( event, next ); 11415 }, 11416 11417 nextPage: function( event ) { 11418 var item, base, height; 11419 11420 if ( !this.active ) { 11421 this.next( event ); 11422 return; 11423 } 11424 if ( this.isLastItem() ) { 11425 return; 11426 } 11427 if ( this._hasScroll() ) { 11428 base = this.active.offset().top; 11429 height = this.element.height(); 11430 this.active.nextAll( ".ui-menu-item" ).each(function() { 11431 item = $( this ); 11432 return item.offset().top - base - height < 0; 11433 }); 11434 11435 this.focus( event, item ); 11436 } else { 11437 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11438 [ !this.active ? "first" : "last" ]() ); 11439 } 11440 }, 11441 11442 previousPage: function( event ) { 11443 var item, base, height; 11444 if ( !this.active ) { 11445 this.next( event ); 11446 return; 11447 } 11448 if ( this.isFirstItem() ) { 11449 return; 11450 } 11451 if ( this._hasScroll() ) { 11452 base = this.active.offset().top; 11453 height = this.element.height(); 11454 this.active.prevAll( ".ui-menu-item" ).each(function() { 11455 item = $( this ); 11456 return item.offset().top - base + height > 0; 11457 }); 11458 11459 this.focus( event, item ); 11460 } else { 11461 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 11462 } 11463 }, 11464 11465 _hasScroll: function() { 11466 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 11467 }, 11468 11469 select: function( event ) { 11470 // TODO: It should never be possible to not have an active item at this 11471 // point, but the tests don't trigger mouseenter before click. 11472 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 11473 var ui = { item: this.active }; 11474 if ( !this.active.has( ".ui-menu" ).length ) { 11475 this.collapseAll( event, true ); 11476 } 11477 this._trigger( "select", event, ui ); 11478 } 11479}); 11480 11481}( jQuery )); 11482 11483(function( $, undefined ) { 11484 11485$.ui = $.ui || {}; 11486 11487var cachedScrollbarWidth, 11488 max = Math.max, 11489 abs = Math.abs, 11490 round = Math.round, 11491 rhorizontal = /left|center|right/, 11492 rvertical = /top|center|bottom/, 11493 roffset = /[\+\-]\d+%?/, 11494 rposition = /^\w+/, 11495 rpercent = /%$/, 11496 _position = $.fn.position; 11497 11498function getOffsets( offsets, width, height ) { 11499 return [ 11500 parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 11501 parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 11502 ]; 11503} 11504function parseCss( element, property ) { 11505 return parseInt( $.css( element, property ), 10 ) || 0; 11506} 11507 11508$.position = { 11509 scrollbarWidth: function() { 11510 if ( cachedScrollbarWidth !== undefined ) { 11511 return cachedScrollbarWidth; 11512 } 11513 var w1, w2, 11514 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 11515 innerDiv = div.children()[0]; 11516 11517 $( "body" ).append( div ); 11518 w1 = innerDiv.offsetWidth; 11519 div.css( "overflow", "scroll" ); 11520 11521 w2 = innerDiv.offsetWidth; 11522 11523 if ( w1 === w2 ) { 11524 w2 = div[0].clientWidth; 11525 } 11526 11527 div.remove(); 11528 11529 return (cachedScrollbarWidth = w1 - w2); 11530 }, 11531 getScrollInfo: function( within ) { 11532 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 11533 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 11534 hasOverflowX = overflowX === "scroll" || 11535 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 11536 hasOverflowY = overflowY === "scroll" || 11537 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 11538 return { 11539 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 11540 height: hasOverflowY ? $.position.scrollbarWidth() : 0 11541 }; 11542 }, 11543 getWithinInfo: function( element ) { 11544 var withinElement = $( element || window ), 11545 isWindow = $.isWindow( withinElement[0] ); 11546 return { 11547 element: withinElement, 11548 isWindow: isWindow, 11549 offset: withinElement.offset() || { left: 0, top: 0 }, 11550 scrollLeft: withinElement.scrollLeft(), 11551 scrollTop: withinElement.scrollTop(), 11552 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 11553 height: isWindow ? withinElement.height() : withinElement.outerHeight() 11554 }; 11555 } 11556}; 11557 11558$.fn.position = function( options ) { 11559 if ( !options || !options.of ) { 11560 return _position.apply( this, arguments ); 11561 } 11562 11563 // make a copy, we don't want to modify arguments 11564 options = $.extend( {}, options ); 11565 11566 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, 11567 target = $( options.of ), 11568 within = $.position.getWithinInfo( options.within ), 11569 scrollInfo = $.position.getScrollInfo( within ), 11570 targetElem = target[0], 11571 collision = ( options.collision || "flip" ).split( " " ), 11572 offsets = {}; 11573 11574 if ( targetElem.nodeType === 9 ) { 11575 targetWidth = target.width(); 11576 targetHeight = target.height(); 11577 targetOffset = { top: 0, left: 0 }; 11578 } else if ( $.isWindow( targetElem ) ) { 11579 targetWidth = target.width(); 11580 targetHeight = target.height(); 11581 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; 11582 } else if ( targetElem.preventDefault ) { 11583 // force left top to allow flipping 11584 options.at = "left top"; 11585 targetWidth = targetHeight = 0; 11586 targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; 11587 } else { 11588 targetWidth = target.outerWidth(); 11589 targetHeight = target.outerHeight(); 11590 targetOffset = target.offset(); 11591 } 11592 // clone to reuse original targetOffset later 11593 basePosition = $.extend( {}, targetOffset ); 11594 11595 // force my and at to have valid horizontal and vertical positions 11596 // if a value is missing or invalid, it will be converted to center 11597 $.each( [ "my", "at" ], function() { 11598 var pos = ( options[ this ] || "" ).split( " " ), 11599 horizontalOffset, 11600 verticalOffset; 11601 11602 if ( pos.length === 1) { 11603 pos = rhorizontal.test( pos[ 0 ] ) ? 11604 pos.concat( [ "center" ] ) : 11605 rvertical.test( pos[ 0 ] ) ? 11606 [ "center" ].concat( pos ) : 11607 [ "center", "center" ]; 11608 } 11609 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 11610 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 11611 11612 // calculate offsets 11613 horizontalOffset = roffset.exec( pos[ 0 ] ); 11614 verticalOffset = roffset.exec( pos[ 1 ] ); 11615 offsets[ this ] = [ 11616 horizontalOffset ? horizontalOffset[ 0 ] : 0, 11617 verticalOffset ? verticalOffset[ 0 ] : 0 11618 ]; 11619 11620 // reduce to just the positions without the offsets 11621 options[ this ] = [ 11622 rposition.exec( pos[ 0 ] )[ 0 ], 11623 rposition.exec( pos[ 1 ] )[ 0 ] 11624 ]; 11625 }); 11626 11627 // normalize collision option 11628 if ( collision.length === 1 ) { 11629 collision[ 1 ] = collision[ 0 ]; 11630 } 11631 11632 if ( options.at[ 0 ] === "right" ) { 11633 basePosition.left += targetWidth; 11634 } else if ( options.at[ 0 ] === "center" ) { 11635 basePosition.left += targetWidth / 2; 11636 } 11637 11638 if ( options.at[ 1 ] === "bottom" ) { 11639 basePosition.top += targetHeight; 11640 } else if ( options.at[ 1 ] === "center" ) { 11641 basePosition.top += targetHeight / 2; 11642 } 11643 11644 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 11645 basePosition.left += atOffset[ 0 ]; 11646 basePosition.top += atOffset[ 1 ]; 11647 11648 return this.each(function() { 11649 var collisionPosition, using, 11650 elem = $( this ), 11651 elemWidth = elem.outerWidth(), 11652 elemHeight = elem.outerHeight(), 11653 marginLeft = parseCss( this, "marginLeft" ), 11654 marginTop = parseCss( this, "marginTop" ), 11655 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 11656 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 11657 position = $.extend( {}, basePosition ), 11658 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 11659 11660 if ( options.my[ 0 ] === "right" ) { 11661 position.left -= elemWidth; 11662 } else if ( options.my[ 0 ] === "center" ) { 11663 position.left -= elemWidth / 2; 11664 } 11665 11666 if ( options.my[ 1 ] === "bottom" ) { 11667 position.top -= elemHeight; 11668 } else if ( options.my[ 1 ] === "center" ) { 11669 position.top -= elemHeight / 2; 11670 } 11671 11672 position.left += myOffset[ 0 ]; 11673 position.top += myOffset[ 1 ]; 11674 11675 // if the browser doesn't support fractions, then round for consistent results 11676 if ( !$.support.offsetFractions ) { 11677 position.left = round( position.left ); 11678 position.top = round( position.top ); 11679 } 11680 11681 collisionPosition = { 11682 marginLeft: marginLeft, 11683 marginTop: marginTop 11684 }; 11685 11686 $.each( [ "left", "top" ], function( i, dir ) { 11687 if ( $.ui.position[ collision[ i ] ] ) { 11688 $.ui.position[ collision[ i ] ][ dir ]( position, { 11689 targetWidth: targetWidth, 11690 targetHeight: targetHeight, 11691 elemWidth: elemWidth, 11692 elemHeight: elemHeight, 11693 collisionPosition: collisionPosition, 11694 collisionWidth: collisionWidth, 11695 collisionHeight: collisionHeight, 11696 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 11697 my: options.my, 11698 at: options.at, 11699 within: within, 11700 elem : elem 11701 }); 11702 } 11703 }); 11704 11705 if ( $.fn.bgiframe ) { 11706 elem.bgiframe(); 11707 } 11708 11709 if ( options.using ) { 11710 // adds feedback as second argument to using callback, if present 11711 using = function( props ) { 11712 var left = targetOffset.left - position.left, 11713 right = left + targetWidth - elemWidth, 11714 top = targetOffset.top - position.top, 11715 bottom = top + targetHeight - elemHeight, 11716 feedback = { 11717 target: { 11718 element: target, 11719 left: targetOffset.left, 11720 top: targetOffset.top, 11721 width: targetWidth, 11722 height: targetHeight 11723 }, 11724 element: { 11725 element: elem, 11726 left: position.left, 11727 top: position.top, 11728 width: elemWidth, 11729 height: elemHeight 11730 }, 11731 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 11732 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 11733 }; 11734 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 11735 feedback.horizontal = "center"; 11736 } 11737 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 11738 feedback.vertical = "middle"; 11739 } 11740 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 11741 feedback.important = "horizontal"; 11742 } else { 11743 feedback.important = "vertical"; 11744 } 11745 options.using.call( this, props, feedback ); 11746 }; 11747 } 11748 11749 elem.offset( $.extend( position, { using: using } ) ); 11750 }); 11751}; 11752 11753$.ui.position = { 11754 fit: { 11755 left: function( position, data ) { 11756 var within = data.within, 11757 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 11758 outerWidth = within.width, 11759 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 11760 overLeft = withinOffset - collisionPosLeft, 11761 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 11762 newOverRight; 11763 11764 // element is wider than within 11765 if ( data.collisionWidth > outerWidth ) { 11766 // element is initially over the left side of within 11767 if ( overLeft > 0 && overRight <= 0 ) { 11768 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 11769 position.left += overLeft - newOverRight; 11770 // element is initially over right side of within 11771 } else if ( overRight > 0 && overLeft <= 0 ) { 11772 position.left = withinOffset; 11773 // element is initially over both left and right sides of within 11774 } else { 11775 if ( overLeft > overRight ) { 11776 position.left = withinOffset + outerWidth - data.collisionWidth; 11777 } else { 11778 position.left = withinOffset; 11779 } 11780 } 11781 // too far left -> align with left edge 11782 } else if ( overLeft > 0 ) { 11783 position.left += overLeft; 11784 // too far right -> align with right edge 11785 } else if ( overRight > 0 ) { 11786 position.left -= overRight; 11787 // adjust based on position and margin 11788 } else { 11789 position.left = max( position.left - collisionPosLeft, position.left ); 11790 } 11791 }, 11792 top: function( position, data ) { 11793 var within = data.within, 11794 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 11795 outerHeight = data.within.height, 11796 collisionPosTop = position.top - data.collisionPosition.marginTop, 11797 overTop = withinOffset - collisionPosTop, 11798 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 11799 newOverBottom; 11800 11801 // element is taller than within 11802 if ( data.collisionHeight > outerHeight ) { 11803 // element is initially over the top of within 11804 if ( overTop > 0 && overBottom <= 0 ) { 11805 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 11806 position.top += overTop - newOverBottom; 11807 // element is initially over bottom of within 11808 } else if ( overBottom > 0 && overTop <= 0 ) { 11809 position.top = withinOffset; 11810 // element is initially over both top and bottom of within 11811 } else { 11812 if ( overTop > overBottom ) { 11813 position.top = withinOffset + outerHeight - data.collisionHeight; 11814 } else { 11815 position.top = withinOffset; 11816 } 11817 } 11818 // too far up -> align with top 11819 } else if ( overTop > 0 ) { 11820 position.top += overTop; 11821 // too far down -> align with bottom edge 11822 } else if ( overBottom > 0 ) { 11823 position.top -= overBottom; 11824 // adjust based on position and margin 11825 } else { 11826 position.top = max( position.top - collisionPosTop, position.top ); 11827 } 11828 } 11829 }, 11830 flip: { 11831 left: function( position, data ) { 11832 var within = data.within, 11833 withinOffset = within.offset.left + within.scrollLeft, 11834 outerWidth = within.width, 11835 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 11836 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 11837 overLeft = collisionPosLeft - offsetLeft, 11838 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 11839 myOffset = data.my[ 0 ] === "left" ? 11840 -data.elemWidth : 11841 data.my[ 0 ] === "right" ? 11842 data.elemWidth : 11843 0, 11844 atOffset = data.at[ 0 ] === "left" ? 11845 data.targetWidth : 11846 data.at[ 0 ] === "right" ? 11847 -data.targetWidth : 11848 0, 11849 offset = -2 * data.offset[ 0 ], 11850 newOverRight, 11851 newOverLeft; 11852 11853 if ( overLeft < 0 ) { 11854 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 11855 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 11856 position.left += myOffset + atOffset + offset; 11857 } 11858 } 11859 else if ( overRight > 0 ) { 11860 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 11861 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 11862 position.left += myOffset + atOffset + offset; 11863 } 11864 } 11865 }, 11866 top: function( position, data ) { 11867 var within = data.within, 11868 withinOffset = within.offset.top + within.scrollTop, 11869 outerHeight = within.height, 11870 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 11871 collisionPosTop = position.top - data.collisionPosition.marginTop, 11872 overTop = collisionPosTop - offsetTop, 11873 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 11874 top = data.my[ 1 ] === "top", 11875 myOffset = top ? 11876 -data.elemHeight : 11877 data.my[ 1 ] === "bottom" ? 11878 data.elemHeight : 11879 0, 11880 atOffset = data.at[ 1 ] === "top" ? 11881 data.targetHeight : 11882 data.at[ 1 ] === "bottom" ? 11883 -data.targetHeight : 11884 0, 11885 offset = -2 * data.offset[ 1 ], 11886 newOverTop, 11887 newOverBottom; 11888 if ( overTop < 0 ) { 11889 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 11890 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 11891 position.top += myOffset + atOffset + offset; 11892 } 11893 } 11894 else if ( overBottom > 0 ) { 11895 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 11896 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 11897 position.top += myOffset + atOffset + offset; 11898 } 11899 } 11900 } 11901 }, 11902 flipfit: { 11903 left: function() { 11904 $.ui.position.flip.left.apply( this, arguments ); 11905 $.ui.position.fit.left.apply( this, arguments ); 11906 }, 11907 top: function() { 11908 $.ui.position.flip.top.apply( this, arguments ); 11909 $.ui.position.fit.top.apply( this, arguments ); 11910 } 11911 } 11912}; 11913 11914// fraction support test 11915(function () { 11916 var testElement, testElementParent, testElementStyle, offsetLeft, i, 11917 body = document.getElementsByTagName( "body" )[ 0 ], 11918 div = document.createElement( "div" ); 11919 11920 //Create a "fake body" for testing based on method used in jQuery.support 11921 testElement = document.createElement( body ? "div" : "body" ); 11922 testElementStyle = { 11923 visibility: "hidden", 11924 width: 0, 11925 height: 0, 11926 border: 0, 11927 margin: 0, 11928 background: "none" 11929 }; 11930 if ( body ) { 11931 $.extend( testElementStyle, { 11932 position: "absolute", 11933 left: "-1000px", 11934 top: "-1000px" 11935 }); 11936 } 11937 for ( i in testElementStyle ) { 11938 testElement.style[ i ] = testElementStyle[ i ]; 11939 } 11940 testElement.appendChild( div ); 11941 testElementParent = body || document.documentElement; 11942 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 11943 11944 div.style.cssText = "position: absolute; left: 10.7432222px;"; 11945 11946 offsetLeft = $( div ).offset().left; 11947 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 11948 11949 testElement.innerHTML = ""; 11950 testElementParent.removeChild( testElement ); 11951})(); 11952 11953// DEPRECATED 11954if ( $.uiBackCompat !== false ) { 11955 // offset option 11956 (function( $ ) { 11957 var _position = $.fn.position; 11958 $.fn.position = function( options ) { 11959 if ( !options || !options.offset ) { 11960 return _position.call( this, options ); 11961 } 11962 var offset = options.offset.split( " " ), 11963 at = options.at.split( " " ); 11964 if ( offset.length === 1 ) { 11965 offset[ 1 ] = offset[ 0 ]; 11966 } 11967 if ( /^\d/.test( offset[ 0 ] ) ) { 11968 offset[ 0 ] = "+" + offset[ 0 ]; 11969 } 11970 if ( /^\d/.test( offset[ 1 ] ) ) { 11971 offset[ 1 ] = "+" + offset[ 1 ]; 11972 } 11973 if ( at.length === 1 ) { 11974 if ( /left|center|right/.test( at[ 0 ] ) ) { 11975 at[ 1 ] = "center"; 11976 } else { 11977 at[ 1 ] = at[ 0 ]; 11978 at[ 0 ] = "center"; 11979 } 11980 } 11981 return _position.call( this, $.extend( options, { 11982 at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], 11983 offset: undefined 11984 } ) ); 11985 }; 11986 }( jQuery ) ); 11987} 11988 11989}( jQuery ) ); 11990 11991(function( $, undefined ) { 11992 11993$.widget( "ui.progressbar", { 11994 version: "1.9.2", 11995 options: { 11996 value: 0, 11997 max: 100 11998 }, 11999 12000 min: 0, 12001 12002 _create: function() { 12003 this.element 12004 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12005 .attr({ 12006 role: "progressbar", 12007 "aria-valuemin": this.min, 12008 "aria-valuemax": this.options.max, 12009 "aria-valuenow": this._value() 12010 }); 12011 12012 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12013 .appendTo( this.element ); 12014 12015 this.oldValue = this._value(); 12016 this._refreshValue(); 12017 }, 12018 12019 _destroy: function() { 12020 this.element 12021 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12022 .removeAttr( "role" ) 12023 .removeAttr( "aria-valuemin" ) 12024 .removeAttr( "aria-valuemax" ) 12025 .removeAttr( "aria-valuenow" ); 12026 12027 this.valueDiv.remove(); 12028 }, 12029 12030 value: function( newValue ) { 12031 if ( newValue === undefined ) { 12032 return this._value(); 12033 } 12034 12035 this._setOption( "value", newValue ); 12036 return this; 12037 }, 12038 12039 _setOption: function( key, value ) { 12040 if ( key === "value" ) { 12041 this.options.value = value; 12042 this._refreshValue(); 12043 if ( this._value() === this.options.max ) { 12044 this._trigger( "complete" ); 12045 } 12046 } 12047 12048 this._super( key, value ); 12049 }, 12050 12051 _value: function() { 12052 var val = this.options.value; 12053 // normalize invalid value 12054 if ( typeof val !== "number" ) { 12055 val = 0; 12056 } 12057 return Math.min( this.options.max, Math.max( this.min, val ) ); 12058 }, 12059 12060 _percentage: function() { 12061 return 100 * this._value() / this.options.max; 12062 }, 12063 12064 _refreshValue: function() { 12065 var value = this.value(), 12066 percentage = this._percentage(); 12067 12068 if ( this.oldValue !== value ) { 12069 this.oldValue = value; 12070 this._trigger( "change" ); 12071 } 12072 12073 this.valueDiv 12074 .toggle( value > this.min ) 12075 .toggleClass( "ui-corner-right", value === this.options.max ) 12076 .width( percentage.toFixed(0) + "%" ); 12077 this.element.attr( "aria-valuenow", value ); 12078 } 12079}); 12080 12081})( jQuery ); 12082 12083(function( $, undefined ) { 12084 12085// number of pages in a slider 12086// (how many times can you page up/down to go through the whole range) 12087var numPages = 5; 12088 12089$.widget( "ui.slider", $.ui.mouse, { 12090 version: "1.9.2", 12091 widgetEventPrefix: "slide", 12092 12093 options: { 12094 animate: false, 12095 distance: 0, 12096 max: 100, 12097 min: 0, 12098 orientation: "horizontal", 12099 range: false, 12100 step: 1, 12101 value: 0, 12102 values: null 12103 }, 12104 12105 _create: function() { 12106 var i, handleCount, 12107 o = this.options, 12108 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12109 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12110 handles = []; 12111 12112 this._keySliding = false; 12113 this._mouseSliding = false; 12114 this._animateOff = true; 12115 this._handleIndex = null; 12116 this._detectOrientation(); 12117 this._mouseInit(); 12118 12119 this.element 12120 .addClass( "ui-slider" + 12121 " ui-slider-" + this.orientation + 12122 " ui-widget" + 12123 " ui-widget-content" + 12124 " ui-corner-all" + 12125 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); 12126 12127 this.range = $([]); 12128 12129 if ( o.range ) { 12130 if ( o.range === true ) { 12131 if ( !o.values ) { 12132 o.values = [ this._valueMin(), this._valueMin() ]; 12133 } 12134 if ( o.values.length && o.values.length !== 2 ) { 12135 o.values = [ o.values[0], o.values[0] ]; 12136 } 12137 } 12138 12139 this.range = $( "<div></div>" ) 12140 .appendTo( this.element ) 12141 .addClass( "ui-slider-range" + 12142 // note: this isn't the most fittingly semantic framework class for this element, 12143 // but worked best visually with a variety of themes 12144 " ui-widget-header" + 12145 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); 12146 } 12147 12148 handleCount = ( o.values && o.values.length ) || 1; 12149 12150 for ( i = existingHandles.length; i < handleCount; i++ ) { 12151 handles.push( handle ); 12152 } 12153 12154 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12155 12156 this.handle = this.handles.eq( 0 ); 12157 12158 this.handles.add( this.range ).filter( "a" ) 12159 .click(function( event ) { 12160 event.preventDefault(); 12161 }) 12162 .mouseenter(function() { 12163 if ( !o.disabled ) { 12164 $( this ).addClass( "ui-state-hover" ); 12165 } 12166 }) 12167 .mouseleave(function() { 12168 $( this ).removeClass( "ui-state-hover" ); 12169 }) 12170 .focus(function() { 12171 if ( !o.disabled ) { 12172 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); 12173 $( this ).addClass( "ui-state-focus" ); 12174 } else { 12175 $( this ).blur(); 12176 } 12177 }) 12178 .blur(function() { 12179 $( this ).removeClass( "ui-state-focus" ); 12180 }); 12181 12182 this.handles.each(function( i ) { 12183 $( this ).data( "ui-slider-handle-index", i ); 12184 }); 12185 12186 this._on( this.handles, { 12187 keydown: function( event ) { 12188 var allowed, curVal, newVal, step, 12189 index = $( event.target ).data( "ui-slider-handle-index" ); 12190 12191 switch ( event.keyCode ) { 12192 case $.ui.keyCode.HOME: 12193 case $.ui.keyCode.END: 12194 case $.ui.keyCode.PAGE_UP: 12195 case $.ui.keyCode.PAGE_DOWN: 12196 case $.ui.keyCode.UP: 12197 case $.ui.keyCode.RIGHT: 12198 case $.ui.keyCode.DOWN: 12199 case $.ui.keyCode.LEFT: 12200 event.preventDefault(); 12201 if ( !this._keySliding ) { 12202 this._keySliding = true; 12203 $( event.target ).addClass( "ui-state-active" ); 12204 allowed = this._start( event, index ); 12205 if ( allowed === false ) { 12206 return; 12207 } 12208 } 12209 break; 12210 } 12211 12212 step = this.options.step; 12213 if ( this.options.values && this.options.values.length ) { 12214 curVal = newVal = this.values( index ); 12215 } else { 12216 curVal = newVal = this.value(); 12217 } 12218 12219 switch ( event.keyCode ) { 12220 case $.ui.keyCode.HOME: 12221 newVal = this._valueMin(); 12222 break; 12223 case $.ui.keyCode.END: 12224 newVal = this._valueMax(); 12225 break; 12226 case $.ui.keyCode.PAGE_UP: 12227 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 12228 break; 12229 case $.ui.keyCode.PAGE_DOWN: 12230 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 12231 break; 12232 case $.ui.keyCode.UP: 12233 case $.ui.keyCode.RIGHT: 12234 if ( curVal === this._valueMax() ) { 12235 return; 12236 } 12237 newVal = this._trimAlignValue( curVal + step ); 12238 break; 12239 case $.ui.keyCode.DOWN: 12240 case $.ui.keyCode.LEFT: 12241 if ( curVal === this._valueMin() ) { 12242 return; 12243 } 12244 newVal = this._trimAlignValue( curVal - step ); 12245 break; 12246 } 12247 12248 this._slide( event, index, newVal ); 12249 }, 12250 keyup: function( event ) { 12251 var index = $( event.target ).data( "ui-slider-handle-index" ); 12252 12253 if ( this._keySliding ) { 12254 this._keySliding = false; 12255 this._stop( event, index ); 12256 this._change( event, index ); 12257 $( event.target ).removeClass( "ui-state-active" ); 12258 } 12259 } 12260 }); 12261 12262 this._refreshValue(); 12263 12264 this._animateOff = false; 12265 }, 12266 12267 _destroy: function() { 12268 this.handles.remove(); 12269 this.range.remove(); 12270 12271 this.element 12272 .removeClass( "ui-slider" + 12273 " ui-slider-horizontal" + 12274 " ui-slider-vertical" + 12275 " ui-slider-disabled" + 12276 " ui-widget" + 12277 " ui-widget-content" + 12278 " ui-corner-all" ); 12279 12280 this._mouseDestroy(); 12281 }, 12282 12283 _mouseCapture: function( event ) { 12284 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12285 that = this, 12286 o = this.options; 12287 12288 if ( o.disabled ) { 12289 return false; 12290 } 12291 12292 this.elementSize = { 12293 width: this.element.outerWidth(), 12294 height: this.element.outerHeight() 12295 }; 12296 this.elementOffset = this.element.offset(); 12297 12298 position = { x: event.pageX, y: event.pageY }; 12299 normValue = this._normValueFromMouse( position ); 12300 distance = this._valueMax() - this._valueMin() + 1; 12301 this.handles.each(function( i ) { 12302 var thisDistance = Math.abs( normValue - that.values(i) ); 12303 if ( distance > thisDistance ) { 12304 distance = thisDistance; 12305 closestHandle = $( this ); 12306 index = i; 12307 } 12308 }); 12309 12310 // workaround for bug #3736 (if both handles of a range are at 0, 12311 // the first is always used as the one with least distance, 12312 // and moving it is obviously prevented by preventing negative ranges) 12313 if( o.range === true && this.values(1) === o.min ) { 12314 index += 1; 12315 closestHandle = $( this.handles[index] ); 12316 } 12317 12318 allowed = this._start( event, index ); 12319 if ( allowed === false ) { 12320 return false; 12321 } 12322 this._mouseSliding = true; 12323 12324 this._handleIndex = index; 12325 12326 closestHandle 12327 .addClass( "ui-state-active" ) 12328 .focus(); 12329 12330 offset = closestHandle.offset(); 12331 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); 12332 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12333 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12334 top: event.pageY - offset.top - 12335 ( closestHandle.height() / 2 ) - 12336 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12337 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12338 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12339 }; 12340 12341 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12342 this._slide( event, index, normValue ); 12343 } 12344 this._animateOff = true; 12345 return true; 12346 }, 12347 12348 _mouseStart: function() { 12349 return true; 12350 }, 12351 12352 _mouseDrag: function( event ) { 12353 var position = { x: event.pageX, y: event.pageY }, 12354 normValue = this._normValueFromMouse( position ); 12355 12356 this._slide( event, this._handleIndex, normValue ); 12357 12358 return false; 12359 }, 12360 12361 _mouseStop: function( event ) { 12362 this.handles.removeClass( "ui-state-active" ); 12363 this._mouseSliding = false; 12364 12365 this._stop( event, this._handleIndex ); 12366 this._change( event, this._handleIndex ); 12367 12368 this._handleIndex = null; 12369 this._clickOffset = null; 12370 this._animateOff = false; 12371 12372 return false; 12373 }, 12374 12375 _detectOrientation: function() { 12376 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12377 }, 12378 12379 _normValueFromMouse: function( position ) { 12380 var pixelTotal, 12381 pixelMouse, 12382 percentMouse, 12383 valueTotal, 12384 valueMouse; 12385 12386 if ( this.orientation === "horizontal" ) { 12387 pixelTotal = this.elementSize.width; 12388 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12389 } else { 12390 pixelTotal = this.elementSize.height; 12391 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12392 } 12393 12394 percentMouse = ( pixelMouse / pixelTotal ); 12395 if ( percentMouse > 1 ) { 12396 percentMouse = 1; 12397 } 12398 if ( percentMouse < 0 ) { 12399 percentMouse = 0; 12400 } 12401 if ( this.orientation === "vertical" ) { 12402 percentMouse = 1 - percentMouse; 12403 } 12404 12405 valueTotal = this._valueMax() - this._valueMin(); 12406 valueMouse = this._valueMin() + percentMouse * valueTotal; 12407 12408 return this._trimAlignValue( valueMouse ); 12409 }, 12410 12411 _start: function( event, index ) { 12412 var uiHash = { 12413 handle: this.handles[ index ], 12414 value: this.value() 12415 }; 12416 if ( this.options.values && this.options.values.length ) { 12417 uiHash.value = this.values( index ); 12418 uiHash.values = this.values(); 12419 } 12420 return this._trigger( "start", event, uiHash ); 12421 }, 12422 12423 _slide: function( event, index, newVal ) { 12424 var otherVal, 12425 newValues, 12426 allowed; 12427 12428 if ( this.options.values && this.options.values.length ) { 12429 otherVal = this.values( index ? 0 : 1 ); 12430 12431 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12432 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12433 ) { 12434 newVal = otherVal; 12435 } 12436 12437 if ( newVal !== this.values( index ) ) { 12438 newValues = this.values(); 12439 newValues[ index ] = newVal; 12440 // A slide can be canceled by returning false from the slide callback 12441 allowed = this._trigger( "slide", event, { 12442 handle: this.handles[ index ], 12443 value: newVal, 12444 values: newValues 12445 } ); 12446 otherVal = this.values( index ? 0 : 1 ); 12447 if ( allowed !== false ) { 12448 this.values( index, newVal, true ); 12449 } 12450 } 12451 } else { 12452 if ( newVal !== this.value() ) { 12453 // A slide can be canceled by returning false from the slide callback 12454 allowed = this._trigger( "slide", event, { 12455 handle: this.handles[ index ], 12456 value: newVal 12457 } ); 12458 if ( allowed !== false ) { 12459 this.value( newVal ); 12460 } 12461 } 12462 } 12463 }, 12464 12465 _stop: function( event, index ) { 12466 var uiHash = { 12467 handle: this.handles[ index ], 12468 value: this.value() 12469 }; 12470 if ( this.options.values && this.options.values.length ) { 12471 uiHash.value = this.values( index ); 12472 uiHash.values = this.values(); 12473 } 12474 12475 this._trigger( "stop", event, uiHash ); 12476 }, 12477 12478 _change: function( event, index ) { 12479 if ( !this._keySliding && !this._mouseSliding ) { 12480 var uiHash = { 12481 handle: this.handles[ index ], 12482 value: this.value() 12483 }; 12484 if ( this.options.values && this.options.values.length ) { 12485 uiHash.value = this.values( index ); 12486 uiHash.values = this.values(); 12487 } 12488 12489 this._trigger( "change", event, uiHash ); 12490 } 12491 }, 12492 12493 value: function( newValue ) { 12494 if ( arguments.length ) { 12495 this.options.value = this._trimAlignValue( newValue ); 12496 this._refreshValue(); 12497 this._change( null, 0 ); 12498 return; 12499 } 12500 12501 return this._value(); 12502 }, 12503 12504 values: function( index, newValue ) { 12505 var vals, 12506 newValues, 12507 i; 12508 12509 if ( arguments.length > 1 ) { 12510 this.options.values[ index ] = this._trimAlignValue( newValue ); 12511 this._refreshValue(); 12512 this._change( null, index ); 12513 return; 12514 } 12515 12516 if ( arguments.length ) { 12517 if ( $.isArray( arguments[ 0 ] ) ) { 12518 vals = this.options.values; 12519 newValues = arguments[ 0 ]; 12520 for ( i = 0; i < vals.length; i += 1 ) { 12521 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 12522 this._change( null, i ); 12523 } 12524 this._refreshValue(); 12525 } else { 12526 if ( this.options.values && this.options.values.length ) { 12527 return this._values( index ); 12528 } else { 12529 return this.value(); 12530 } 12531 } 12532 } else { 12533 return this._values(); 12534 } 12535 }, 12536 12537 _setOption: function( key, value ) { 12538 var i, 12539 valsLength = 0; 12540 12541 if ( $.isArray( this.options.values ) ) { 12542 valsLength = this.options.values.length; 12543 } 12544 12545 $.Widget.prototype._setOption.apply( this, arguments ); 12546 12547 switch ( key ) { 12548 case "disabled": 12549 if ( value ) { 12550 this.handles.filter( ".ui-state-focus" ).blur(); 12551 this.handles.removeClass( "ui-state-hover" ); 12552 this.handles.prop( "disabled", true ); 12553 this.element.addClass( "ui-disabled" ); 12554 } else { 12555 this.handles.prop( "disabled", false ); 12556 this.element.removeClass( "ui-disabled" ); 12557 } 12558 break; 12559 case "orientation": 12560 this._detectOrientation(); 12561 this.element 12562 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 12563 .addClass( "ui-slider-" + this.orientation ); 12564 this._refreshValue(); 12565 break; 12566 case "value": 12567 this._animateOff = true; 12568 this._refreshValue(); 12569 this._change( null, 0 ); 12570 this._animateOff = false; 12571 break; 12572 case "values": 12573 this._animateOff = true; 12574 this._refreshValue(); 12575 for ( i = 0; i < valsLength; i += 1 ) { 12576 this._change( null, i ); 12577 } 12578 this._animateOff = false; 12579 break; 12580 case "min": 12581 case "max": 12582 this._animateOff = true; 12583 this._refreshValue(); 12584 this._animateOff = false; 12585 break; 12586 } 12587 }, 12588 12589 //internal value getter 12590 // _value() returns value trimmed by min and max, aligned by step 12591 _value: function() { 12592 var val = this.options.value; 12593 val = this._trimAlignValue( val ); 12594 12595 return val; 12596 }, 12597 12598 //internal values getter 12599 // _values() returns array of values trimmed by min and max, aligned by step 12600 // _values( index ) returns single value trimmed by min and max, aligned by step 12601 _values: function( index ) { 12602 var val, 12603 vals, 12604 i; 12605 12606 if ( arguments.length ) { 12607 val = this.options.values[ index ]; 12608 val = this._trimAlignValue( val ); 12609 12610 return val; 12611 } else { 12612 // .slice() creates a copy of the array 12613 // this copy gets trimmed by min and max and then returned 12614 vals = this.options.values.slice(); 12615 for ( i = 0; i < vals.length; i+= 1) { 12616 vals[ i ] = this._trimAlignValue( vals[ i ] ); 12617 } 12618 12619 return vals; 12620 } 12621 }, 12622 12623 // returns the step-aligned value that val is closest to, between (inclusive) min and max 12624 _trimAlignValue: function( val ) { 12625 if ( val <= this._valueMin() ) { 12626 return this._valueMin(); 12627 } 12628 if ( val >= this._valueMax() ) { 12629 return this._valueMax(); 12630 } 12631 var step = ( this.options.step > 0 ) ? this.options.step : 1, 12632 valModStep = (val - this._valueMin()) % step, 12633 alignValue = val - valModStep; 12634 12635 if ( Math.abs(valModStep) * 2 >= step ) { 12636 alignValue += ( valModStep > 0 ) ? step : ( -step ); 12637 } 12638 12639 // Since JavaScript has problems with large floats, round 12640 // the final value to 5 digits after the decimal point (see #4124) 12641 return parseFloat( alignValue.toFixed(5) ); 12642 }, 12643 12644 _valueMin: function() { 12645 return this.options.min; 12646 }, 12647 12648 _valueMax: function() { 12649 return this.options.max; 12650 }, 12651 12652 _refreshValue: function() { 12653 var lastValPercent, valPercent, value, valueMin, valueMax, 12654 oRange = this.options.range, 12655 o = this.options, 12656 that = this, 12657 animate = ( !this._animateOff ) ? o.animate : false, 12658 _set = {}; 12659 12660 if ( this.options.values && this.options.values.length ) { 12661 this.handles.each(function( i ) { 12662 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 12663 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12664 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12665 if ( that.options.range === true ) { 12666 if ( that.orientation === "horizontal" ) { 12667 if ( i === 0 ) { 12668 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 12669 } 12670 if ( i === 1 ) { 12671 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12672 } 12673 } else { 12674 if ( i === 0 ) { 12675 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 12676 } 12677 if ( i === 1 ) { 12678 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 12679 } 12680 } 12681 } 12682 lastValPercent = valPercent; 12683 }); 12684 } else { 12685 value = this.value(); 12686 valueMin = this._valueMin(); 12687 valueMax = this._valueMax(); 12688 valPercent = ( valueMax !== valueMin ) ? 12689 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 12690 0; 12691 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 12692 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 12693 12694 if ( oRange === "min" && this.orientation === "horizontal" ) { 12695 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 12696 } 12697 if ( oRange === "max" && this.orientation === "horizontal" ) { 12698 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12699 } 12700 if ( oRange === "min" && this.orientation === "vertical" ) { 12701 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 12702 } 12703 if ( oRange === "max" && this.orientation === "vertical" ) { 12704 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 12705 } 12706 } 12707 } 12708 12709}); 12710 12711}(jQuery)); 12712 12713(function( $ ) { 12714 12715function modifier( fn ) { 12716 return function() { 12717 var previous = this.element.val(); 12718 fn.apply( this, arguments ); 12719 this._refresh(); 12720 if ( previous !== this.element.val() ) { 12721 this._trigger( "change" ); 12722 } 12723 }; 12724} 12725 12726$.widget( "ui.spinner", { 12727 version: "1.9.2", 12728 defaultElement: "<input>", 12729 widgetEventPrefix: "spin", 12730 options: { 12731 culture: null, 12732 icons: { 12733 down: "ui-icon-triangle-1-s", 12734 up: "ui-icon-triangle-1-n" 12735 }, 12736 incremental: true, 12737 max: null, 12738 min: null, 12739 numberFormat: null, 12740 page: 10, 12741 step: 1, 12742 12743 change: null, 12744 spin: null, 12745 start: null, 12746 stop: null 12747 }, 12748 12749 _create: function() { 12750 // handle string values that need to be parsed 12751 this._setOption( "max", this.options.max ); 12752 this._setOption( "min", this.options.min ); 12753 this._setOption( "step", this.options.step ); 12754 12755 // format the value, but don't constrain 12756 this._value( this.element.val(), true ); 12757 12758 this._draw(); 12759 this._on( this._events ); 12760 this._refresh(); 12761 12762 // turning off autocomplete prevents the browser from remembering the 12763 // value when navigating through history, so we re-enable autocomplete 12764 // if the page is unloaded before the widget is destroyed. #7790 12765 this._on( this.window, { 12766 beforeunload: function() { 12767 this.element.removeAttr( "autocomplete" ); 12768 } 12769 }); 12770 }, 12771 12772 _getCreateOptions: function() { 12773 var options = {}, 12774 element = this.element; 12775 12776 $.each( [ "min", "max", "step" ], function( i, option ) { 12777 var value = element.attr( option ); 12778 if ( value !== undefined && value.length ) { 12779 options[ option ] = value; 12780 } 12781 }); 12782 12783 return options; 12784 }, 12785 12786 _events: { 12787 keydown: function( event ) { 12788 if ( this._start( event ) && this._keydown( event ) ) { 12789 event.preventDefault(); 12790 } 12791 }, 12792 keyup: "_stop", 12793 focus: function() { 12794 this.previous = this.element.val(); 12795 }, 12796 blur: function( event ) { 12797 if ( this.cancelBlur ) { 12798 delete this.cancelBlur; 12799 return; 12800 } 12801 12802 this._refresh(); 12803 if ( this.previous !== this.element.val() ) { 12804 this._trigger( "change", event ); 12805 } 12806 }, 12807 mousewheel: function( event, delta ) { 12808 if ( !delta ) { 12809 return; 12810 } 12811 if ( !this.spinning && !this._start( event ) ) { 12812 return false; 12813 } 12814 12815 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 12816 clearTimeout( this.mousewheelTimer ); 12817 this.mousewheelTimer = this._delay(function() { 12818 if ( this.spinning ) { 12819 this._stop( event ); 12820 } 12821 }, 100 ); 12822 event.preventDefault(); 12823 }, 12824 "mousedown .ui-spinner-button": function( event ) { 12825 var previous; 12826 12827 // We never want the buttons to have focus; whenever the user is 12828 // interacting with the spinner, the focus should be on the input. 12829 // If the input is focused then this.previous is properly set from 12830 // when the input first received focus. If the input is not focused 12831 // then we need to set this.previous based on the value before spinning. 12832 previous = this.element[0] === this.document[0].activeElement ? 12833 this.previous : this.element.val(); 12834 function checkFocus() { 12835 var isActive = this.element[0] === this.document[0].activeElement; 12836 if ( !isActive ) { 12837 this.element.focus(); 12838 this.previous = previous; 12839 // support: IE 12840 // IE sets focus asynchronously, so we need to check if focus 12841 // moved off of the input because the user clicked on the button. 12842 this._delay(function() { 12843 this.previous = previous; 12844 }); 12845 } 12846 } 12847 12848 // ensure focus is on (or stays on) the text field 12849 event.preventDefault(); 12850 checkFocus.call( this ); 12851 12852 // support: IE 12853 // IE doesn't prevent moving focus even with event.preventDefault() 12854 // so we set a flag to know when we should ignore the blur event 12855 // and check (again) if focus moved off of the input. 12856 this.cancelBlur = true; 12857 this._delay(function() { 12858 delete this.cancelBlur; 12859 checkFocus.call( this ); 12860 }); 12861 12862 if ( this._start( event ) === false ) { 12863 return; 12864 } 12865 12866 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12867 }, 12868 "mouseup .ui-spinner-button": "_stop", 12869 "mouseenter .ui-spinner-button": function( event ) { 12870 // button will add ui-state-active if mouse was down while mouseleave and kept down 12871 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 12872 return; 12873 } 12874 12875 if ( this._start( event ) === false ) { 12876 return false; 12877 } 12878 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 12879 }, 12880 // TODO: do we really want to consider this a stop? 12881 // shouldn't we just stop the repeater and wait until mouseup before 12882 // we trigger the stop event? 12883 "mouseleave .ui-spinner-button": "_stop" 12884 }, 12885 12886 _draw: function() { 12887 var uiSpinner = this.uiSpinner = this.element 12888 .addClass( "ui-spinner-input" ) 12889 .attr( "autocomplete", "off" ) 12890 .wrap( this._uiSpinnerHtml() ) 12891 .parent() 12892 // add buttons 12893 .append( this._buttonHtml() ); 12894 12895 this.element.attr( "role", "spinbutton" ); 12896 12897 // button bindings 12898 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 12899 .attr( "tabIndex", -1 ) 12900 .button() 12901 .removeClass( "ui-corner-all" ); 12902 12903 // IE 6 doesn't understand height: 50% for the buttons 12904 // unless the wrapper has an explicit height 12905 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 12906 uiSpinner.height() > 0 ) { 12907 uiSpinner.height( uiSpinner.height() ); 12908 } 12909 12910 // disable spinner if element was already disabled 12911 if ( this.options.disabled ) { 12912 this.disable(); 12913 } 12914 }, 12915 12916 _keydown: function( event ) { 12917 var options = this.options, 12918 keyCode = $.ui.keyCode; 12919 12920 switch ( event.keyCode ) { 12921 case keyCode.UP: 12922 this._repeat( null, 1, event ); 12923 return true; 12924 case keyCode.DOWN: 12925 this._repeat( null, -1, event ); 12926 return true; 12927 case keyCode.PAGE_UP: 12928 this._repeat( null, options.page, event ); 12929 return true; 12930 case keyCode.PAGE_DOWN: 12931 this._repeat( null, -options.page, event ); 12932 return true; 12933 } 12934 12935 return false; 12936 }, 12937 12938 _uiSpinnerHtml: function() { 12939 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 12940 }, 12941 12942 _buttonHtml: function() { 12943 return "" + 12944 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 12945 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 12946 "</a>" + 12947 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 12948 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 12949 "</a>"; 12950 }, 12951 12952 _start: function( event ) { 12953 if ( !this.spinning && this._trigger( "start", event ) === false ) { 12954 return false; 12955 } 12956 12957 if ( !this.counter ) { 12958 this.counter = 1; 12959 } 12960 this.spinning = true; 12961 return true; 12962 }, 12963 12964 _repeat: function( i, steps, event ) { 12965 i = i || 500; 12966 12967 clearTimeout( this.timer ); 12968 this.timer = this._delay(function() { 12969 this._repeat( 40, steps, event ); 12970 }, i ); 12971 12972 this._spin( steps * this.options.step, event ); 12973 }, 12974 12975 _spin: function( step, event ) { 12976 var value = this.value() || 0; 12977 12978 if ( !this.counter ) { 12979 this.counter = 1; 12980 } 12981 12982 value = this._adjustValue( value + step * this._increment( this.counter ) ); 12983 12984 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 12985 this._value( value ); 12986 this.counter++; 12987 } 12988 }, 12989 12990 _increment: function( i ) { 12991 var incremental = this.options.incremental; 12992 12993 if ( incremental ) { 12994 return $.isFunction( incremental ) ? 12995 incremental( i ) : 12996 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 12997 } 12998 12999 return 1; 13000 }, 13001 13002 _precision: function() { 13003 var precision = this._precisionOf( this.options.step ); 13004 if ( this.options.min !== null ) { 13005 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13006 } 13007 return precision; 13008 }, 13009 13010 _precisionOf: function( num ) { 13011 var str = num.toString(), 13012 decimal = str.indexOf( "." ); 13013 return decimal === -1 ? 0 : str.length - decimal - 1; 13014 }, 13015 13016 _adjustValue: function( value ) { 13017 var base, aboveMin, 13018 options = this.options; 13019 13020 // make sure we're at a valid step 13021 // - find out where we are relative to the base (min or 0) 13022 base = options.min !== null ? options.min : 0; 13023 aboveMin = value - base; 13024 // - round to the nearest step 13025 aboveMin = Math.round(aboveMin / options.step) * options.step; 13026 // - rounding is based on 0, so adjust back to our base 13027 value = base + aboveMin; 13028 13029 // fix precision from bad JS floating point math 13030 value = parseFloat( value.toFixed( this._precision() ) ); 13031 13032 // clamp the value 13033 if ( options.max !== null && value > options.max) { 13034 return options.max; 13035 } 13036 if ( options.min !== null && value < options.min ) { 13037 return options.min; 13038 } 13039 13040 return value; 13041 }, 13042 13043 _stop: function( event ) { 13044 if ( !this.spinning ) { 13045 return; 13046 } 13047 13048 clearTimeout( this.timer ); 13049 clearTimeout( this.mousewheelTimer ); 13050 this.counter = 0; 13051 this.spinning = false;
13052 this._trigger( "stop", event ); 13053 }, 13054 13055 _setOption: function( key, value ) { 13056 if ( key === "culture" || key === "numberFormat" ) { 13057 var prevValue = this._parse( this.element.val() ); 13058 this.options[ key ] = value; 13059 this.element.val( this._format( prevValue ) ); 13060 return; 13061 } 13062 13063 if ( key === "max" || key === "min" || key === "step" ) { 13064 if ( typeof value === "string" ) { 13065 value = this._parse( value ); 13066 } 13067 } 13068 13069 this._super( key, value ); 13070 13071 if ( key === "disabled" ) { 13072 if ( value ) { 13073 this.element.prop( "disabled", true ); 13074 this.buttons.button( "disable" ); 13075 } else { 13076 this.element.prop( "disabled", false ); 13077 this.buttons.button( "enable" ); 13078 } 13079 } 13080 }, 13081 13082 _setOptions: modifier(function( options ) { 13083 this._super( options ); 13084 this._value( this.element.val() ); 13085 }), 13086 13087 _parse: function( val ) { 13088 if ( typeof val === "string" && val !== "" ) { 13089 val = window.Globalize && this.options.numberFormat ? 13090 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13091 } 13092 return val === "" || isNaN( val ) ? null : val; 13093 }, 13094 13095 _format: function( value ) { 13096 if ( value === "" ) { 13097 return ""; 13098 } 13099 return window.Globalize && this.options.numberFormat ? 13100 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13101 value; 13102 }, 13103 13104 _refresh: function() { 13105 this.element.attr({ 13106 "aria-valuemin": this.options.min, 13107 "aria-valuemax": this.options.max, 13108 // TODO: what should we do with values that can't be parsed? 13109 "aria-valuenow": this._parse( this.element.val() ) 13110 }); 13111 }, 13112 13113 // update the value without triggering change 13114 _value: function( value, allowAny ) { 13115 var parsed; 13116 if ( value !== "" ) { 13117 parsed = this._parse( value ); 13118 if ( parsed !== null ) { 13119 if ( !allowAny ) { 13120 parsed = this._adjustValue( parsed ); 13121 } 13122 value = this._format( parsed ); 13123 } 13124 } 13125 this.element.val( value ); 13126 this._refresh(); 13127 }, 13128 13129 _destroy: function() { 13130 this.element 13131 .removeClass( "ui-spinner-input" ) 13132 .prop( "disabled", false ) 13133 .removeAttr( "autocomplete" ) 13134 .removeAttr( "role" ) 13135 .removeAttr( "aria-valuemin" ) 13136 .removeAttr( "aria-valuemax" ) 13137 .removeAttr( "aria-valuenow" ); 13138 this.uiSpinner.replaceWith( this.element ); 13139 }, 13140 13141 stepUp: modifier(function( steps ) { 13142 this._stepUp( steps ); 13143 }), 13144 _stepUp: function( steps ) { 13145 this._spin( (steps || 1) * this.options.step ); 13146 }, 13147 13148 stepDown: modifier(function( steps ) { 13149 this._stepDown( steps ); 13150 }), 13151 _stepDown: function( steps ) { 13152 this._spin( (steps || 1) * -this.options.step ); 13153 }, 13154 13155 pageUp: modifier(function( pages ) { 13156 this._stepUp( (pages || 1) * this.options.page ); 13157 }), 13158 13159 pageDown: modifier(function( pages ) { 13160 this._stepDown( (pages || 1) * this.options.page ); 13161 }), 13162 13163 value: function( newVal ) { 13164 if ( !arguments.length ) { 13165 return this._parse( this.element.val() ); 13166 } 13167 modifier( this._value ).call( this, newVal ); 13168 }, 13169 13170 widget: function() { 13171 return this.uiSpinner; 13172 } 13173}); 13174 13175}( jQuery ) ); 13176 13177(function( $, undefined ) { 13178 13179var tabId = 0, 13180 rhash = /#.*$/; 13181 13182function getNextTabId() { 13183 return ++tabId; 13184} 13185 13186function isLocal( anchor ) { 13187 return anchor.hash.length > 1 && 13188 anchor.href.replace( rhash, "" ) === 13189 location.href.replace( rhash, "" ) 13190 // support: Safari 5.1 13191 // Safari 5.1 doesn't encode spaces in window.location 13192 // but it does encode spaces from anchors (#8777) 13193 .replace( /\s/g, "%20" ); 13194} 13195 13196$.widget( "ui.tabs", { 13197 version: "1.9.2", 13198 delay: 300, 13199 options: { 13200 active: null, 13201 collapsible: false, 13202 event: "click", 13203 heightStyle: "content", 13204 hide: null, 13205 show: null, 13206 13207 // callbacks 13208 activate: null, 13209 beforeActivate: null, 13210 beforeLoad: null, 13211 load: null 13212 }, 13213 13214 _create: function() { 13215 var that = this, 13216 options = this.options, 13217 active = options.active, 13218 locationHash = location.hash.substring( 1 ); 13219 13220 this.running = false; 13221 13222 this.element 13223 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13224 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13225 // Prevent users from focusing disabled tabs via click 13226 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13227 if ( $( this ).is( ".ui-state-disabled" ) ) { 13228 event.preventDefault(); 13229 } 13230 }) 13231 // support: IE <9 13232 // Preventing the default action in mousedown doesn't prevent IE
vendor: 18,149 bytes, lines 13233-13906
13233 // from focusing the element, so if the anchor gets focused, blur. 13234 // We don't have to worry about focusing the previously focused 13235 // element since clicking on a non-focusable element should focus 13236 // the body anyway. 13237 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13238 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13239 this.blur(); 13240 } 13241 }); 13242 13243 this._processTabs(); 13244 13245 if ( active === null ) { 13246 // check the fragment identifier in the URL 13247 if ( locationHash ) { 13248 this.tabs.each(function( i, tab ) { 13249 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13250 active = i; 13251 return false; 13252 } 13253 }); 13254 } 13255 13256 // check for a tab marked active via a class 13257 if ( active === null ) { 13258 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13259 } 13260 13261 // no active tab, set to false 13262 if ( active === null || active === -1 ) { 13263 active = this.tabs.length ? 0 : false; 13264 } 13265 } 13266 13267 // handle numbers: negative, out of range 13268 if ( active !== false ) { 13269 active = this.tabs.index( this.tabs.eq( active ) ); 13270 if ( active === -1 ) { 13271 active = options.collapsible ? false : 0; 13272 } 13273 } 13274 options.active = active; 13275 13276 // don't allow collapsible: false and active: false 13277 if ( !options.collapsible && options.active === false && this.anchors.length ) { 13278 options.active = 0; 13279 } 13280 13281 // Take disabling tabs via class attribute from HTML 13282 // into account and update option properly. 13283 if ( $.isArray( options.disabled ) ) { 13284 options.disabled = $.unique( options.disabled.concat( 13285 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13286 return that.tabs.index( li ); 13287 }) 13288 ) ).sort(); 13289 } 13290 13291 // check for length avoids error when initializing empty list 13292 if ( this.options.active !== false && this.anchors.length ) { 13293 this.active = this._findActive( this.options.active ); 13294 } else { 13295 this.active = $(); 13296 } 13297 13298 this._refresh(); 13299 13300 if ( this.active.length ) { 13301 this.load( options.active ); 13302 } 13303 }, 13304 13305 _getCreateEventData: function() { 13306 return { 13307 tab: this.active, 13308 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13309 }; 13310 }, 13311 13312 _tabKeydown: function( event ) { 13313 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13314 selectedIndex = this.tabs.index( focusedTab ), 13315 goingForward = true; 13316 13317 if ( this._handlePageNav( event ) ) { 13318 return; 13319 } 13320 13321 switch ( event.keyCode ) { 13322 case $.ui.keyCode.RIGHT: 13323 case $.ui.keyCode.DOWN: 13324 selectedIndex++; 13325 break; 13326 case $.ui.keyCode.UP: 13327 case $.ui.keyCode.LEFT: 13328 goingForward = false; 13329 selectedIndex--; 13330 break; 13331 case $.ui.keyCode.END: 13332 selectedIndex = this.anchors.length - 1; 13333 break; 13334 case $.ui.keyCode.HOME: 13335 selectedIndex = 0; 13336 break; 13337 case $.ui.keyCode.SPACE: 13338 // Activate only, no collapsing 13339 event.preventDefault(); 13340 clearTimeout( this.activating ); 13341 this._activate( selectedIndex ); 13342 return; 13343 case $.ui.keyCode.ENTER: 13344 // Toggle (cancel delayed activation, allow collapsing) 13345 event.preventDefault(); 13346 clearTimeout( this.activating ); 13347 // Determine if we should collapse or activate 13348 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13349 return; 13350 default: 13351 return; 13352 } 13353 13354 // Focus the appropriate tab, based on which key was pressed 13355 event.preventDefault(); 13356 clearTimeout( this.activating ); 13357 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13358 13359 // Navigating with control key will prevent automatic activation 13360 if ( !event.ctrlKey ) { 13361 // Update aria-selected immediately so that AT think the tab is already selected. 13362 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13363 // but the tab will already be activated by the time the announcement finishes. 13364 focusedTab.attr( "aria-selected", "false" ); 13365 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13366 13367 this.activating = this._delay(function() { 13368 this.option( "active", selectedIndex ); 13369 }, this.delay ); 13370 } 13371 }, 13372 13373 _panelKeydown: function( event ) { 13374 if ( this._handlePageNav( event ) ) { 13375 return; 13376 } 13377 13378 // Ctrl+up moves focus to the current tab 13379 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13380 event.preventDefault(); 13381 this.active.focus(); 13382 } 13383 }, 13384 13385 // Alt+page up/down moves focus to the previous/next tab (and activates) 13386 _handlePageNav: function( event ) { 13387 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13388 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13389 return true; 13390 } 13391 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 13392 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 13393 return true; 13394 } 13395 }, 13396 13397 _findNextTab: function( index, goingForward ) { 13398 var lastTabIndex = this.tabs.length - 1; 13399 13400 function constrain() { 13401 if ( index > lastTabIndex ) { 13402 index = 0; 13403 } 13404 if ( index < 0 ) { 13405 index = lastTabIndex; 13406 } 13407 return index; 13408 } 13409 13410 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 13411 index = goingForward ? index + 1 : index - 1; 13412 } 13413 13414 return index; 13415 }, 13416 13417 _focusNextTab: function( index, goingForward ) { 13418 index = this._findNextTab( index, goingForward ); 13419 this.tabs.eq( index ).focus(); 13420 return index; 13421 }, 13422 13423 _setOption: function( key, value ) { 13424 if ( key === "active" ) { 13425 // _activate() will handle invalid values and update this.options 13426 this._activate( value ); 13427 return; 13428 } 13429 13430 if ( key === "disabled" ) { 13431 // don't use the widget factory's disabled handling 13432 this._setupDisabled( value ); 13433 return; 13434 } 13435 13436 this._super( key, value); 13437 13438 if ( key === "collapsible" ) { 13439 this.element.toggleClass( "ui-tabs-collapsible", value ); 13440 // Setting collapsible: false while collapsed; open first panel 13441 if ( !value && this.options.active === false ) { 13442 this._activate( 0 ); 13443 } 13444 } 13445 13446 if ( key === "event" ) { 13447 this._setupEvents( value ); 13448 } 13449 13450 if ( key === "heightStyle" ) { 13451 this._setupHeightStyle( value ); 13452 } 13453 }, 13454 13455 _tabId: function( tab ) { 13456 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 13457 }, 13458 13459 _sanitizeSelector: function( hash ) { 13460 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 13461 }, 13462 13463 refresh: function() { 13464 var options = this.options, 13465 lis = this.tablist.children( ":has(a[href])" ); 13466 13467 // get disabled tabs from class attribute from HTML 13468 // this will get converted to a boolean if needed in _refresh() 13469 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 13470 return lis.index( tab ); 13471 }); 13472 13473 this._processTabs(); 13474 13475 // was collapsed or no tabs 13476 if ( options.active === false || !this.anchors.length ) { 13477 options.active = false; 13478 this.active = $(); 13479 // was active, but active tab is gone 13480 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 13481 // all remaining tabs are disabled 13482 if ( this.tabs.length === options.disabled.length ) { 13483 options.active = false; 13484 this.active = $(); 13485 // activate previous tab 13486 } else { 13487 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 13488 } 13489 // was active, active tab still exists 13490 } else { 13491 // make sure active index is correct 13492 options.active = this.tabs.index( this.active ); 13493 } 13494 13495 this._refresh(); 13496 }, 13497 13498 _refresh: function() { 13499 this._setupDisabled( this.options.disabled ); 13500 this._setupEvents( this.options.event ); 13501 this._setupHeightStyle( this.options.heightStyle ); 13502 13503 this.tabs.not( this.active ).attr({ 13504 "aria-selected": "false", 13505 tabIndex: -1 13506 }); 13507 this.panels.not( this._getPanelForTab( this.active ) ) 13508 .hide() 13509 .attr({ 13510 "aria-expanded": "false", 13511 "aria-hidden": "true" 13512 }); 13513 13514 // Make sure one tab is in the tab order 13515 if ( !this.active.length ) { 13516 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 13517 } else { 13518 this.active 13519 .addClass( "ui-tabs-active ui-state-active" ) 13520 .attr({ 13521 "aria-selected": "true", 13522 tabIndex: 0 13523 }); 13524 this._getPanelForTab( this.active ) 13525 .show() 13526 .attr({ 13527 "aria-expanded": "true", 13528 "aria-hidden": "false" 13529 }); 13530 } 13531 }, 13532 13533 _processTabs: function() { 13534 var that = this; 13535 13536 this.tablist = this._getList() 13537 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13538 .attr( "role", "tablist" ); 13539 13540 this.tabs = this.tablist.find( "> li:has(a[href])" ) 13541 .addClass( "ui-state-default ui-corner-top" ) 13542 .attr({ 13543 role: "tab", 13544 tabIndex: -1 13545 }); 13546 13547 this.anchors = this.tabs.map(function() { 13548 return $( "a", this )[ 0 ]; 13549 }) 13550 .addClass( "ui-tabs-anchor" ) 13551 .attr({ 13552 role: "presentation", 13553 tabIndex: -1 13554 }); 13555 13556 this.panels = $(); 13557 13558 this.anchors.each(function( i, anchor ) { 13559 var selector, panel, panelId, 13560 anchorId = $( anchor ).uniqueId().attr( "id" ), 13561 tab = $( anchor ).closest( "li" ), 13562 originalAriaControls = tab.attr( "aria-controls" ); 13563 13564 // inline tab 13565 if ( isLocal( anchor ) ) { 13566 selector = anchor.hash; 13567 panel = that.element.find( that._sanitizeSelector( selector ) ); 13568 // remote tab 13569 } else { 13570 panelId = that._tabId( tab ); 13571 selector = "#" + panelId; 13572 panel = that.element.find( selector ); 13573 if ( !panel.length ) { 13574 panel = that._createPanel( panelId ); 13575 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 13576 } 13577 panel.attr( "aria-live", "polite" ); 13578 } 13579 13580 if ( panel.length) { 13581 that.panels = that.panels.add( panel ); 13582 } 13583 if ( originalAriaControls ) { 13584 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 13585 } 13586 tab.attr({ 13587 "aria-controls": selector.substring( 1 ), 13588 "aria-labelledby": anchorId 13589 }); 13590 panel.attr( "aria-labelledby", anchorId ); 13591 }); 13592 13593 this.panels 13594 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13595 .attr( "role", "tabpanel" ); 13596 }, 13597 13598 // allow overriding how to find the list for rare usage scenarios (#7715) 13599 _getList: function() { 13600 return this.element.find( "ol,ul" ).eq( 0 ); 13601 }, 13602 13603 _createPanel: function( id ) { 13604 return $( "<div>" ) 13605 .attr( "id", id ) 13606 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 13607 .data( "ui-tabs-destroy", true ); 13608 }, 13609 13610 _setupDisabled: function( disabled ) { 13611 if ( $.isArray( disabled ) ) { 13612 if ( !disabled.length ) { 13613 disabled = false; 13614 } else if ( disabled.length === this.anchors.length ) { 13615 disabled = true; 13616 } 13617 } 13618 13619 // disable tabs 13620 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 13621 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 13622 $( li ) 13623 .addClass( "ui-state-disabled" ) 13624 .attr( "aria-disabled", "true" ); 13625 } else { 13626 $( li ) 13627 .removeClass( "ui-state-disabled" ) 13628 .removeAttr( "aria-disabled" ); 13629 } 13630 } 13631 13632 this.options.disabled = disabled; 13633 }, 13634 13635 _setupEvents: function( event ) { 13636 var events = { 13637 click: function( event ) { 13638 event.preventDefault(); 13639 } 13640 }; 13641 if ( event ) { 13642 $.each( event.split(" "), function( index, eventName ) { 13643 events[ eventName ] = "_eventHandler"; 13644 }); 13645 } 13646 13647 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 13648 this._on( this.anchors, events ); 13649 this._on( this.tabs, { keydown: "_tabKeydown" } ); 13650 this._on( this.panels, { keydown: "_panelKeydown" } ); 13651 13652 this._focusable( this.tabs ); 13653 this._hoverable( this.tabs ); 13654 }, 13655 13656 _setupHeightStyle: function( heightStyle ) { 13657 var maxHeight, overflow, 13658 parent = this.element.parent(); 13659 13660 if ( heightStyle === "fill" ) { 13661 // IE 6 treats height like minHeight, so we need to turn off overflow 13662 // in order to get a reliable height 13663 // we use the minHeight support test because we assume that only 13664 // browsers that don't support minHeight will treat height as minHeight 13665 if ( !$.support.minHeight ) { 13666 overflow = parent.css( "overflow" ); 13667 parent.css( "overflow", "hidden"); 13668 } 13669 maxHeight = parent.height(); 13670 this.element.siblings( ":visible" ).each(function() { 13671 var elem = $( this ), 13672 position = elem.css( "position" ); 13673 13674 if ( position === "absolute" || position === "fixed" ) { 13675 return; 13676 } 13677 maxHeight -= elem.outerHeight( true ); 13678 }); 13679 if ( overflow ) { 13680 parent.css( "overflow", overflow ); 13681 } 13682 13683 this.element.children().not( this.panels ).each(function() { 13684 maxHeight -= $( this ).outerHeight( true ); 13685 }); 13686 13687 this.panels.each(function() { 13688 $( this ).height( Math.max( 0, maxHeight - 13689 $( this ).innerHeight() + $( this ).height() ) ); 13690 }) 13691 .css( "overflow", "auto" ); 13692 } else if ( heightStyle === "auto" ) { 13693 maxHeight = 0; 13694 this.panels.each(function() { 13695 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 13696 }).height( maxHeight ); 13697 } 13698 }, 13699 13700 _eventHandler: function( event ) { 13701 var options = this.options, 13702 active = this.active, 13703 anchor = $( event.currentTarget ), 13704 tab = anchor.closest( "li" ), 13705 clickedIsActive = tab[ 0 ] === active[ 0 ], 13706 collapsing = clickedIsActive && options.collapsible, 13707 toShow = collapsing ? $() : this._getPanelForTab( tab ), 13708 toHide = !active.length ? $() : this._getPanelForTab( active ), 13709 eventData = { 13710 oldTab: active, 13711 oldPanel: toHide, 13712 newTab: collapsing ? $() : tab, 13713 newPanel: toShow 13714 }; 13715 13716 event.preventDefault(); 13717 13718 if ( tab.hasClass( "ui-state-disabled" ) || 13719 // tab is already loading 13720 tab.hasClass( "ui-tabs-loading" ) || 13721 // can't switch durning an animation 13722 this.running || 13723 // click on active header, but not collapsible 13724 ( clickedIsActive && !options.collapsible ) || 13725 // allow canceling activation 13726 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 13727 return; 13728 } 13729 13730 options.active = collapsing ? false : this.tabs.index( tab ); 13731 13732 this.active = clickedIsActive ? $() : tab; 13733 if ( this.xhr ) { 13734 this.xhr.abort(); 13735 } 13736 13737 if ( !toHide.length && !toShow.length ) { 13738 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 13739 } 13740 13741 if ( toShow.length ) { 13742 this.load( this.tabs.index( tab ), event ); 13743 } 13744 this._toggle( event, eventData ); 13745 }, 13746 13747 // handles show/hide for selecting tabs 13748 _toggle: function( event, eventData ) { 13749 var that = this, 13750 toShow = eventData.newPanel, 13751 toHide = eventData.oldPanel; 13752 13753 this.running = true; 13754 13755 function complete() { 13756 that.running = false; 13757 that._trigger( "activate", event, eventData ); 13758 } 13759 13760 function show() { 13761 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 13762 13763 if ( toShow.length && that.options.show ) { 13764 that._show( toShow, that.options.show, complete ); 13765 } else { 13766 toShow.show(); 13767 complete(); 13768 } 13769 } 13770 13771 // start out by hiding, then showing, then completing 13772 if ( toHide.length && this.options.hide ) { 13773 this._hide( toHide, this.options.hide, function() { 13774 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13775 show(); 13776 }); 13777 } else { 13778 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 13779 toHide.hide(); 13780 show(); 13781 } 13782 13783 toHide.attr({ 13784 "aria-expanded": "false", 13785 "aria-hidden": "true" 13786 }); 13787 eventData.oldTab.attr( "aria-selected", "false" ); 13788 // If we're switching tabs, remove the old tab from the tab order. 13789 // If we're opening from collapsed state, remove the previous tab from the tab order. 13790 // If we're collapsing, then keep the collapsing tab in the tab order. 13791 if ( toShow.length && toHide.length ) { 13792 eventData.oldTab.attr( "tabIndex", -1 ); 13793 } else if ( toShow.length ) { 13794 this.tabs.filter(function() { 13795 return $( this ).attr( "tabIndex" ) === 0; 13796 }) 13797 .attr( "tabIndex", -1 ); 13798 } 13799 13800 toShow.attr({ 13801 "aria-expanded": "true", 13802 "aria-hidden": "false" 13803 }); 13804 eventData.newTab.attr({ 13805 "aria-selected": "true", 13806 tabIndex: 0 13807 }); 13808 }, 13809 13810 _activate: function( index ) { 13811 var anchor, 13812 active = this._findActive( index ); 13813 13814 // trying to activate the already active panel 13815 if ( active[ 0 ] === this.active[ 0 ] ) { 13816 return; 13817 } 13818 13819 // trying to collapse, simulate a click on the current active header 13820 if ( !active.length ) { 13821 active = this.active; 13822 } 13823 13824 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 13825 this._eventHandler({ 13826 target: anchor, 13827 currentTarget: anchor, 13828 preventDefault: $.noop 13829 }); 13830 }, 13831 13832 _findActive: function( index ) { 13833 return index === false ? $() : this.tabs.eq( index ); 13834 }, 13835 13836 _getIndex: function( index ) { 13837 // meta-function to give users option to provide a href string instead of a numerical index. 13838 if ( typeof index === "string" ) { 13839 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 13840 } 13841 13842 return index; 13843 }, 13844 13845 _destroy: function() { 13846 if ( this.xhr ) { 13847 this.xhr.abort(); 13848 } 13849 13850 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 13851 13852 this.tablist 13853 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 13854 .removeAttr( "role" ); 13855 13856 this.anchors 13857 .removeClass( "ui-tabs-anchor" ) 13858 .removeAttr( "role" ) 13859 .removeAttr( "tabIndex" ) 13860 .removeData( "href.tabs" ) 13861 .removeData( "load.tabs" ) 13862 .removeUniqueId(); 13863 13864 this.tabs.add( this.panels ).each(function() { 13865 if ( $.data( this, "ui-tabs-destroy" ) ) { 13866 $( this ).remove(); 13867 } else { 13868 $( this ) 13869 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 13870 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 13871 .removeAttr( "tabIndex" ) 13872 .removeAttr( "aria-live" ) 13873 .removeAttr( "aria-busy" ) 13874 .removeAttr( "aria-selected" ) 13875 .removeAttr( "aria-labelledby" ) 13876 .removeAttr( "aria-hidden" ) 13877 .removeAttr( "aria-expanded" ) 13878 .removeAttr( "role" ); 13879 } 13880 }); 13881 13882 this.tabs.each(function() { 13883 var li = $( this ), 13884 prev = li.data( "ui-tabs-aria-controls" ); 13885 if ( prev ) { 13886 li.attr( "aria-controls", prev ); 13887 } else { 13888 li.removeAttr( "aria-controls" ); 13889 } 13890 }); 13891 13892 this.panels.show(); 13893 13894 if ( this.options.heightStyle !== "content" ) { 13895 this.panels.css( "height", "" ); 13896 } 13897 }, 13898 13899 enable: function( index ) { 13900 var disabled = this.options.disabled; 13901 if ( disabled === false ) { 13902 return; 13903 } 13904 13905 if ( index === undefined ) { 13906 disabled = false;
13907 } else { 13908 index = this._getIndex( index ); 13909 if ( $.isArray( disabled ) ) { 13910 disabled = $.map( disabled, function( num ) { 13911 return num !== index ? num : null; 13912 }); 13913 } else { 13914 disabled = $.map( this.tabs, function( li, num ) { 13915 return num !== index ? num : null; 13916 }); 13917 } 13918 } 13919 this._setupDisabled( disabled ); 13920 }, 13921 13922 disable: function( index ) { 13923 var disabled = this.options.disabled; 13924 if ( disabled === true ) { 13925 return; 13926 } 13927 13928 if ( index === undefined ) { 13929 disabled = true; 13930 } else { 13931 index = this._getIndex( index ); 13932 if ( $.inArray( index, disabled ) !== -1 ) { 13933 return; 13934 } 13935 if ( $.isArray( disabled ) ) { 13936 disabled = $.merge( [ index ], disabled ).sort(); 13937 } else { 13938 disabled = [ index ]; 13939 } 13940 } 13941 this._setupDisabled( disabled ); 13942 }, 13943 13944 load: function( index, event ) { 13945 index = this._getIndex( index ); 13946 var that = this, 13947 tab = this.tabs.eq( index ), 13948 anchor = tab.find( ".ui-tabs-anchor" ), 13949 panel = this._getPanelForTab( tab ), 13950 eventData = { 13951 tab: tab, 13952 panel: panel 13953 }; 13954 13955 // not remote 13956 if ( isLocal( anchor[ 0 ] ) ) { 13957 return; 13958 } 13959 13960 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 13961 13962 // support: jQuery <1.8 13963 // jQuery <1.8 returns false if the request is canceled in beforeSend, 13964 // but as of 1.8, $.ajax() always returns a jqXHR object. 13965 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 13966 tab.addClass( "ui-tabs-loading" ); 13967 panel.attr( "aria-busy", "true" ); 13968 13969 this.xhr 13970 .success(function( response ) { 13971 // support: jQuery <1.8 13972 // http://bugs.jquery.com/ticket/11778 13973 setTimeout(function() { 13974 panel.html( response ); 13975 that._trigger( "load", event, eventData ); 13976 }, 1 ); 13977 }) 13978 .complete(function( jqXHR, status ) { 13979 // support: jQuery <1.8 13980 // http://bugs.jquery.com/ticket/11778 13981 setTimeout(function() { 13982 if ( status === "abort" ) { 13983 that.panels.stop( false, true ); 13984 } 13985 13986 tab.removeClass( "ui-tabs-loading" ); 13987 panel.removeAttr( "aria-busy" ); 13988 13989 if ( jqXHR === that.xhr ) { 13990 delete that.xhr; 13991 } 13992 }, 1 ); 13993 }); 13994 } 13995 }, 13996 13997 // TODO: Remove this function in 1.10 when ajaxOptions is removed 13998 _ajaxSettings: function( anchor, event, eventData ) { 13999 var that = this; 14000 return { 14001 url: anchor.attr( "href" ), 14002 beforeSend: function( jqXHR, settings ) { 14003 return that._trigger( "beforeLoad", event, 14004 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14005 } 14006 }; 14007 }, 14008 14009 _getPanelForTab: function( tab ) { 14010 var id = $( tab ).attr( "aria-controls" ); 14011 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14012 } 14013}); 14014 14015// DEPRECATED 14016if ( $.uiBackCompat !== false ) { 14017 14018 // helper method for a lot of the back compat extensions 14019 $.ui.tabs.prototype._ui = function( tab, panel ) { 14020 return { 14021 tab: tab, 14022 panel: panel, 14023 index: this.anchors.index( tab ) 14024 }; 14025 }; 14026 14027 // url method 14028 $.widget( "ui.tabs", $.ui.tabs, { 14029 url: function( index, url ) { 14030 this.anchors.eq( index ).attr( "href", url ); 14031 } 14032 }); 14033 14034 // TODO: Remove _ajaxSettings() method when removing this extension 14035 // ajaxOptions and cache options 14036 $.widget( "ui.tabs", $.ui.tabs, { 14037 options: { 14038 ajaxOptions: null, 14039 cache: false 14040 }, 14041 14042 _create: function() { 14043 this._super(); 14044 14045 var that = this; 14046 14047 this._on({ tabsbeforeload: function( event, ui ) { 14048 // tab is already cached 14049 if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { 14050 event.preventDefault(); 14051 return; 14052 } 14053 14054 ui.jqXHR.success(function() { 14055 if ( that.options.cache ) { 14056 $.data( ui.tab[ 0 ], "cache.tabs", true ); 14057 } 14058 }); 14059 }}); 14060 }, 14061 14062 _ajaxSettings: function( anchor, event, ui ) { 14063 var ajaxOptions = this.options.ajaxOptions; 14064 return $.extend( {}, ajaxOptions, { 14065 error: function( xhr, status ) { 14066 try { 14067 // Passing index avoid a race condition when this method is 14068 // called after the user has selected another tab. 14069 // Pass the anchor that initiated this request allows 14070 // loadError to manipulate the tab content panel via $(a.hash) 14071 ajaxOptions.error( 14072 xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); 14073 } 14074 catch ( error ) {} 14075 } 14076 }, this._superApply( arguments ) ); 14077 }, 14078 14079 _setOption: function( key, value ) { 14080 // reset cache if switching from cached to not cached 14081 if ( key === "cache" && value === false ) { 14082 this.anchors.removeData( "cache.tabs" ); 14083 } 14084 this._super( key, value ); 14085 }, 14086 14087 _destroy: function() { 14088 this.anchors.removeData( "cache.tabs" ); 14089 this._super(); 14090 }, 14091 14092 url: function( index ){ 14093 this.anchors.eq( index ).removeData( "cache.tabs" ); 14094 this._superApply( arguments ); 14095 } 14096 }); 14097 14098 // abort method 14099 $.widget( "ui.tabs", $.ui.tabs, { 14100 abort: function() { 14101 if ( this.xhr ) { 14102 this.xhr.abort(); 14103 } 14104 } 14105 }); 14106 14107 // spinner 14108 $.widget( "ui.tabs", $.ui.tabs, { 14109 options: { 14110 spinner: "<em>Loading…</em>" 14111 }, 14112 _create: function() { 14113 this._super(); 14114 this._on({ 14115 tabsbeforeload: function( event, ui ) { 14116 // Don't react to nested tabs or tabs that don't use a spinner 14117 if ( event.target !== this.element[ 0 ] || 14118 !this.options.spinner ) { 14119 return; 14120 } 14121 14122 var span = ui.tab.find( "span" ), 14123 html = span.html(); 14124 span.html( this.options.spinner ); 14125 ui.jqXHR.complete(function() { 14126 span.html( html ); 14127 }); 14128 } 14129 }); 14130 } 14131 }); 14132 14133 // enable/disable events 14134 $.widget( "ui.tabs", $.ui.tabs, { 14135 options: { 14136 enable: null, 14137 disable: null 14138 }, 14139 14140 enable: function( index ) { 14141 var options = this.options, 14142 trigger; 14143 14144 if ( index && options.disabled === true || 14145 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { 14146 trigger = true; 14147 } 14148 14149 this._superApply( arguments ); 14150 14151 if ( trigger ) { 14152 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 14153 } 14154 }, 14155 14156 disable: function( index ) { 14157 var options = this.options, 14158 trigger; 14159 14160 if ( index && options.disabled === false || 14161 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { 14162 trigger = true; 14163 } 14164 14165 this._superApply( arguments ); 14166 14167 if ( trigger ) { 14168 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 14169 } 14170 } 14171 }); 14172 14173 // add/remove methods and events 14174 $.widget( "ui.tabs", $.ui.tabs, { 14175 options: { 14176 add: null, 14177 remove: null, 14178 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" 14179 }, 14180 14181 add: function( url, label, index ) { 14182 if ( index === undefined ) { 14183 index = this.anchors.length; 14184 } 14185 14186 var doInsertAfter, panel, 14187 options = this.options, 14188 li = $( options.tabTemplate 14189 .replace( /#\{href\}/g, url ) 14190 .replace( /#\{label\}/g, label ) ), 14191 id = !url.indexOf( "#" ) ? 14192 url.replace( "#", "" ) : 14193 this._tabId( li ); 14194 14195 li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); 14196 li.attr( "aria-controls", id ); 14197 14198 doInsertAfter = index >= this.tabs.length; 14199 14200 // try to find an existing element before creating a new one 14201 panel = this.element.find( "#" + id ); 14202 if ( !panel.length ) { 14203 panel = this._createPanel( id ); 14204 if ( doInsertAfter ) { 14205 if ( index > 0 ) { 14206 panel.insertAfter( this.panels.eq( -1 ) ); 14207 } else { 14208 panel.appendTo( this.element ); 14209 } 14210 } else { 14211 panel.insertBefore( this.panels[ index ] ); 14212 } 14213 } 14214 panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); 14215 14216 if ( doInsertAfter ) { 14217 li.appendTo( this.tablist ); 14218 } else { 14219 li.insertBefore( this.tabs[ index ] ); 14220 } 14221 14222 options.disabled = $.map( options.disabled, function( n ) { 14223 return n >= index ? ++n : n; 14224 }); 14225 14226 this.refresh(); 14227 if ( this.tabs.length === 1 && options.active === false ) { 14228 this.option( "active", 0 ); 14229 } 14230 14231 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 14232 return this; 14233 }, 14234 14235 remove: function( index ) { 14236 index = this._getIndex( index ); 14237 var options = this.options, 14238 tab = this.tabs.eq( index ).remove(), 14239 panel = this._getPanelForTab( tab ).remove(); 14240 14241 // If selected tab was removed focus tab to the right or 14242 // in case the last tab was removed the tab to the left. 14243 // We check for more than 2 tabs, because if there are only 2, 14244 // then when we remove this tab, there will only be one tab left 14245 // so we don't need to detect which tab to activate. 14246 if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { 14247 this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); 14248 } 14249 14250 options.disabled = $.map( 14251 $.grep( options.disabled, function( n ) { 14252 return n !== index; 14253 }), 14254 function( n ) { 14255 return n >= index ? --n : n; 14256 }); 14257 14258 this.refresh(); 14259 14260 this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); 14261 return this; 14262 } 14263 }); 14264 14265 // length method 14266 $.widget( "ui.tabs", $.ui.tabs, { 14267 length: function() { 14268 return this.anchors.length; 14269 } 14270 }); 14271 14272 // panel ids (idPrefix option + title attribute) 14273 $.widget( "ui.tabs", $.ui.tabs, { 14274 options: { 14275 idPrefix: "ui-tabs-" 14276 }, 14277 14278 _tabId: function( tab ) { 14279 var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; 14280 a = a[0]; 14281 return $( a ).closest( "li" ).attr( "aria-controls" ) || 14282 a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || 14283 this.options.idPrefix + getNextTabId(); 14284 } 14285 }); 14286 14287 // _createPanel method 14288 $.widget( "ui.tabs", $.ui.tabs, { 14289 options: { 14290 panelTemplate: "<div></div>" 14291 }, 14292 14293 _createPanel: function( id ) { 14294 return $( this.options.panelTemplate ) 14295 .attr( "id", id ) 14296 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14297 .data( "ui-tabs-destroy", true ); 14298 } 14299 }); 14300 14301 // selected option 14302 $.widget( "ui.tabs", $.ui.tabs, { 14303 _create: function() { 14304 var options = this.options; 14305 if ( options.active === null && options.selected !== undefined ) { 14306 options.active = options.selected === -1 ? false : options.selected; 14307 } 14308 this._super(); 14309 options.selected = options.active; 14310 if ( options.selected === false ) { 14311 options.selected = -1; 14312 } 14313 }, 14314 14315 _setOption: function( key, value ) { 14316 if ( key !== "selected" ) { 14317 return this._super( key, value ); 14318 } 14319 14320 var options = this.options; 14321 this._super( "active", value === -1 ? false : value ); 14322 options.selected = options.active; 14323 if ( options.selected === false ) { 14324 options.selected = -1; 14325 } 14326 }, 14327 14328 _eventHandler: function() { 14329 this._superApply( arguments ); 14330 this.options.selected = this.options.active; 14331 if ( this.options.selected === false ) { 14332 this.options.selected = -1; 14333 } 14334 } 14335 }); 14336 14337 // show and select event 14338 $.widget( "ui.tabs", $.ui.tabs, { 14339 options: { 14340 show: null, 14341 select: null 14342 }, 14343 _create: function() { 14344 this._super(); 14345 if ( this.options.active !== false ) { 14346 this._trigger( "show", null, this._ui( 14347 this.active.find( ".ui-tabs-anchor" )[ 0 ], 14348 this._getPanelForTab( this.active )[ 0 ] ) ); 14349 } 14350 }, 14351 _trigger: function( type, event, data ) { 14352 var tab, panel, 14353 ret = this._superApply( arguments ); 14354 14355 if ( !ret ) { 14356 return false;
14357 } 14358 14359 if ( type === "beforeActivate" ) { 14360 tab = data.newTab.length ? data.newTab : data.oldTab; 14361 panel = data.newPanel.length ? data.newPanel : data.oldPanel; 14362 ret = this._super( "select", event, { 14363 tab: tab.find( ".ui-tabs-anchor" )[ 0], 14364 panel: panel[ 0 ], 14365 index: tab.closest( "li" ).index() 14366 }); 14367 } else if ( type === "activate" && data.newTab.length ) { 14368 ret = this._super( "show", event, { 14369 tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], 14370 panel: data.newPanel[ 0 ], 14371 index: data.newTab.closest( "li" ).index() 14372 }); 14373 } 14374 return ret; 14375 } 14376 }); 14377 14378 // select method 14379 $.widget( "ui.tabs", $.ui.tabs, { 14380 select: function( index ) { 14381 index = this._getIndex( index ); 14382 if ( index === -1 ) { 14383 if ( this.options.collapsible && this.options.selected !== -1 ) { 14384 index = this.options.selected; 14385 } else { 14386 return; 14387 } 14388 } 14389 this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); 14390 } 14391 }); 14392 14393 // cookie option 14394 (function() { 14395 14396 var listId = 0; 14397 14398 $.widget( "ui.tabs", $.ui.tabs, { 14399 options: { 14400 cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 14401 }, 14402 _create: function() { 14403 var options = this.options, 14404 active; 14405 if ( options.active == null && options.cookie ) { 14406 active = parseInt( this._cookie(), 10 ); 14407 if ( active === -1 ) { 14408 active = false; 14409 } 14410 options.active = active; 14411 } 14412 this._super(); 14413 }, 14414 _cookie: function( active ) { 14415 var cookie = [ this.cookie || 14416 ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; 14417 if ( arguments.length ) { 14418 cookie.push( active === false ? -1 : active ); 14419 cookie.push( this.options.cookie ); 14420 } 14421 return $.cookie.apply( null, cookie ); 14422 }, 14423 _refresh: function() { 14424 this._super(); 14425 if ( this.options.cookie ) { 14426 this._cookie( this.options.active, this.options.cookie ); 14427 } 14428 }, 14429 _eventHandler: function() { 14430 this._superApply( arguments ); 14431 if ( this.options.cookie ) { 14432 this._cookie( this.options.active, this.options.cookie ); 14433 } 14434 }, 14435 _destroy: function() { 14436 this._super(); 14437 if ( this.options.cookie ) { 14438 this._cookie( null, this.options.cookie ); 14439 } 14440 } 14441 }); 14442 14443 })(); 14444 14445 // load event 14446 $.widget( "ui.tabs", $.ui.tabs, { 14447 _trigger: function( type, event, data ) { 14448 var _data = $.extend( {}, data ); 14449 if ( type === "load" ) { 14450 _data.panel = _data.panel[ 0 ]; 14451 _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; 14452 } 14453 return this._super( type, event, _data ); 14454 } 14455 }); 14456 14457 // fx option 14458 // The new animation options (show, hide) conflict with the old show callback. 14459 // The old fx option wins over show/hide anyway (always favor back-compat). 14460 // If a user wants to use the new animation API, they must give up the old API. 14461 $.widget( "ui.tabs", $.ui.tabs, { 14462 options: { 14463 fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } 14464 }, 14465 14466 _getFx: function() { 14467 var hide, show, 14468 fx = this.options.fx; 14469 14470 if ( fx ) { 14471 if ( $.isArray( fx ) ) { 14472 hide = fx[ 0 ]; 14473 show = fx[ 1 ]; 14474 } else { 14475 hide = show = fx; 14476 } 14477 } 14478 14479 return fx ? { show: show, hide: hide } : null; 14480 }, 14481 14482 _toggle: function( event, eventData ) { 14483 var that = this, 14484 toShow = eventData.newPanel, 14485 toHide = eventData.oldPanel, 14486 fx = this._getFx(); 14487 14488 if ( !fx ) { 14489 return this._super( event, eventData ); 14490 } 14491 14492 that.running = true; 14493 14494 function complete() { 14495 that.running = false; 14496 that._trigger( "activate", event, eventData ); 14497 } 14498 14499 function show() { 14500 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14501 14502 if ( toShow.length && fx.show ) { 14503 toShow 14504 .animate( fx.show, fx.show.duration, function() { 14505 complete(); 14506 }); 14507 } else { 14508 toShow.show(); 14509 complete(); 14510 } 14511 } 14512 14513 // start out by hiding, then showing, then completing 14514 if ( toHide.length && fx.hide ) { 14515 toHide.animate( fx.hide, fx.hide.duration, function() { 14516 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14517 show(); 14518 }); 14519 } else { 14520 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14521 toHide.hide(); 14522 show(); 14523 } 14524 } 14525 }); 14526} 14527 14528})( jQuery ); 14529 14530(function( $ ) { 14531 14532var increments = 0; 14533 14534function addDescribedBy( elem, id ) { 14535 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14536 describedby.push( id ); 14537 elem 14538 .data( "ui-tooltip-id", id ) 14539 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14540} 14541 14542function removeDescribedBy( elem ) { 14543 var id = elem.data( "ui-tooltip-id" ),
vendor: 9,870 bytes, lines 14544-14912
14544 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14545 index = $.inArray( id, describedby ); 14546 if ( index !== -1 ) { 14547 describedby.splice( index, 1 ); 14548 } 14549 14550 elem.removeData( "ui-tooltip-id" ); 14551 describedby = $.trim( describedby.join( " " ) ); 14552 if ( describedby ) { 14553 elem.attr( "aria-describedby", describedby ); 14554 } else { 14555 elem.removeAttr( "aria-describedby" ); 14556 } 14557} 14558 14559$.widget( "ui.tooltip", { 14560 version: "1.9.2", 14561 options: { 14562 content: function() { 14563 return $( this ).attr( "title" ); 14564 }, 14565 hide: true, 14566 // Disabled elements have inconsistent behavior across browsers (#8661) 14567 items: "[title]:not([disabled])", 14568 position: { 14569 my: "left top+15", 14570 at: "left bottom", 14571 collision: "flipfit flip" 14572 }, 14573 show: true, 14574 tooltipClass: null, 14575 track: false, 14576 14577 // callbacks 14578 close: null, 14579 open: null 14580 }, 14581 14582 _create: function() { 14583 this._on({ 14584 mouseover: "open", 14585 focusin: "open" 14586 }); 14587 14588 // IDs of generated tooltips, needed for destroy 14589 this.tooltips = {}; 14590 // IDs of parent tooltips where we removed the title attribute 14591 this.parents = {}; 14592 14593 if ( this.options.disabled ) { 14594 this._disable(); 14595 } 14596 }, 14597 14598 _setOption: function( key, value ) { 14599 var that = this; 14600 14601 if ( key === "disabled" ) { 14602 this[ value ? "_disable" : "_enable" ](); 14603 this.options[ key ] = value; 14604 // disable element style changes 14605 return; 14606 } 14607 14608 this._super( key, value ); 14609 14610 if ( key === "content" ) { 14611 $.each( this.tooltips, function( id, element ) { 14612 that._updateContent( element ); 14613 }); 14614 } 14615 }, 14616 14617 _disable: function() { 14618 var that = this; 14619 14620 // close open tooltips 14621 $.each( this.tooltips, function( id, element ) { 14622 var event = $.Event( "blur" ); 14623 event.target = event.currentTarget = element[0]; 14624 that.close( event, true ); 14625 }); 14626 14627 // remove title attributes to prevent native tooltips 14628 this.element.find( this.options.items ).andSelf().each(function() { 14629 var element = $( this ); 14630 if ( element.is( "[title]" ) ) { 14631 element 14632 .data( "ui-tooltip-title", element.attr( "title" ) ) 14633 .attr( "title", "" ); 14634 } 14635 }); 14636 }, 14637 14638 _enable: function() { 14639 // restore title attributes 14640 this.element.find( this.options.items ).andSelf().each(function() { 14641 var element = $( this ); 14642 if ( element.data( "ui-tooltip-title" ) ) { 14643 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14644 } 14645 }); 14646 }, 14647 14648 open: function( event ) { 14649 var that = this, 14650 target = $( event ? event.target : this.element ) 14651 // we need closest here due to mouseover bubbling, 14652 // but always pointing at the same event target 14653 .closest( this.options.items ); 14654 14655 // No element to show a tooltip for or the tooltip is already open 14656 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14657 return; 14658 } 14659 14660 if ( target.attr( "title" ) ) { 14661 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14662 } 14663 14664 target.data( "ui-tooltip-open", true ); 14665 14666 // kill parent tooltips, custom or native, for hover 14667 if ( event && event.type === "mouseover" ) { 14668 target.parents().each(function() { 14669 var parent = $( this ), 14670 blurEvent; 14671 if ( parent.data( "ui-tooltip-open" ) ) { 14672 blurEvent = $.Event( "blur" ); 14673 blurEvent.target = blurEvent.currentTarget = this; 14674 that.close( blurEvent, true ); 14675 } 14676 if ( parent.attr( "title" ) ) { 14677 parent.uniqueId(); 14678 that.parents[ this.id ] = { 14679 element: this, 14680 title: parent.attr( "title" ) 14681 }; 14682 parent.attr( "title", "" ); 14683 } 14684 }); 14685 } 14686 14687 this._updateContent( target, event ); 14688 }, 14689 14690 _updateContent: function( target, event ) { 14691 var content, 14692 contentOption = this.options.content, 14693 that = this, 14694 eventType = event ? event.type : null; 14695 14696 if ( typeof contentOption === "string" ) { 14697 return this._open( event, target, contentOption ); 14698 } 14699 14700 content = contentOption.call( target[0], function( response ) { 14701 // ignore async response if tooltip was closed already 14702 if ( !target.data( "ui-tooltip-open" ) ) { 14703 return; 14704 } 14705 // IE may instantly serve a cached response for ajax requests 14706 // delay this call to _open so the other call to _open runs first 14707 that._delay(function() { 14708 // jQuery creates a special event for focusin when it doesn't 14709 // exist natively. To improve performance, the native event 14710 // object is reused and the type is changed. Therefore, we can't 14711 // rely on the type being correct after the event finished 14712 // bubbling, so we set it back to the previous value. (#8740) 14713 if ( event ) { 14714 event.type = eventType; 14715 } 14716 this._open( event, target, response ); 14717 }); 14718 }); 14719 if ( content ) { 14720 this._open( event, target, content ); 14721 } 14722 }, 14723 14724 _open: function( event, target, content ) { 14725 var tooltip, events, delayedShow, 14726 positionOption = $.extend( {}, this.options.position ); 14727 14728 if ( !content ) { 14729 return; 14730 } 14731 14732 // Content can be updated multiple times. If the tooltip already 14733 // exists, then just update the content and bail. 14734 tooltip = this._find( target ); 14735 if ( tooltip.length ) { 14736 tooltip.find( ".ui-tooltip-content" ).html( content ); 14737 return; 14738 } 14739 14740 // if we have a title, clear it to prevent the native tooltip 14741 // we have to check first to avoid defining a title if none exists 14742 // (we don't want to cause an element to start matching [title]) 14743 // 14744 // We use removeAttr only for key events, to allow IE to export the correct 14745 // accessible attributes. For mouse events, set to empty string to avoid 14746 // native tooltip showing up (happens only when removing inside mouseover). 14747 if ( target.is( "[title]" ) ) { 14748 if ( event && event.type === "mouseover" ) { 14749 target.attr( "title", "" ); 14750 } else { 14751 target.removeAttr( "title" ); 14752 } 14753 } 14754 14755 tooltip = this._tooltip( target ); 14756 addDescribedBy( target, tooltip.attr( "id" ) ); 14757 tooltip.find( ".ui-tooltip-content" ).html( content ); 14758 14759 function position( event ) { 14760 positionOption.of = event; 14761 if ( tooltip.is( ":hidden" ) ) { 14762 return; 14763 } 14764 tooltip.position( positionOption ); 14765 } 14766 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14767 this._on( this.document, { 14768 mousemove: position 14769 }); 14770 // trigger once to override element-relative positioning 14771 position( event ); 14772 } else { 14773 tooltip.position( $.extend({ 14774 of: target 14775 }, this.options.position ) ); 14776 } 14777 14778 tooltip.hide(); 14779 14780 this._show( tooltip, this.options.show ); 14781 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14782 // as the tooltip is visible, position the tooltip using the most recent 14783 // event. 14784 if ( this.options.show && this.options.show.delay ) { 14785 delayedShow = setInterval(function() { 14786 if ( tooltip.is( ":visible" ) ) { 14787 position( positionOption.of ); 14788 clearInterval( delayedShow ); 14789 } 14790 }, $.fx.interval ); 14791 } 14792 14793 this._trigger( "open", event, { tooltip: tooltip } ); 14794 14795 events = { 14796 keyup: function( event ) { 14797 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14798 var fakeEvent = $.Event(event); 14799 fakeEvent.currentTarget = target[0]; 14800 this.close( fakeEvent, true ); 14801 } 14802 }, 14803 remove: function() { 14804 this._removeTooltip( tooltip ); 14805 } 14806 }; 14807 if ( !event || event.type === "mouseover" ) { 14808 events.mouseleave = "close"; 14809 } 14810 if ( !event || event.type === "focusin" ) { 14811 events.focusout = "close"; 14812 } 14813 this._on( true, target, events ); 14814 }, 14815 14816 close: function( event ) { 14817 var that = this, 14818 target = $( event ? event.currentTarget : this.element ), 14819 tooltip = this._find( target ); 14820 14821 // disabling closes the tooltip, so we need to track when we're closing 14822 // to avoid an infinite loop in case the tooltip becomes disabled on close 14823 if ( this.closing ) { 14824 return; 14825 } 14826 14827 // only set title if we had one before (see comment in _open()) 14828 if ( target.data( "ui-tooltip-title" ) ) { 14829 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14830 } 14831 14832 removeDescribedBy( target ); 14833 14834 tooltip.stop( true ); 14835 this._hide( tooltip, this.options.hide, function() { 14836 that._removeTooltip( $( this ) ); 14837 }); 14838 14839 target.removeData( "ui-tooltip-open" ); 14840 this._off( target, "mouseleave focusout keyup" ); 14841 // Remove 'remove' binding only on delegated targets 14842 if ( target[0] !== this.element[0] ) { 14843 this._off( target, "remove" ); 14844 } 14845 this._off( this.document, "mousemove" ); 14846 14847 if ( event && event.type === "mouseleave" ) { 14848 $.each( this.parents, function( id, parent ) { 14849 $( parent.element ).attr( "title", parent.title ); 14850 delete that.parents[ id ]; 14851 }); 14852 } 14853 14854 this.closing = true; 14855 this._trigger( "close", event, { tooltip: tooltip } ); 14856 this.closing = false; 14857 }, 14858 14859 _tooltip: function( element ) { 14860 var id = "ui-tooltip-" + increments++, 14861 tooltip = $( "<div>" ) 14862 .attr({ 14863 id: id, 14864 role: "tooltip" 14865 }) 14866 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14867 ( this.options.tooltipClass || "" ) ); 14868 $( "<div>" ) 14869 .addClass( "ui-tooltip-content" ) 14870 .appendTo( tooltip ); 14871 tooltip.appendTo( this.document[0].body ); 14872 if ( $.fn.bgiframe ) { 14873 tooltip.bgiframe(); 14874 } 14875 this.tooltips[ id ] = element; 14876 return tooltip; 14877 }, 14878 14879 _find: function( target ) { 14880 var id = target.data( "ui-tooltip-id" ); 14881 return id ? $( "#" + id ) : $(); 14882 }, 14883 14884 _removeTooltip: function( tooltip ) { 14885 tooltip.remove(); 14886 delete this.tooltips[ tooltip.attr( "id" ) ]; 14887 }, 14888 14889 _destroy: function() { 14890 var that = this; 14891 14892 // close open tooltips 14893 $.each( this.tooltips, function( id, element ) { 14894 // Delegate to close method to handle common cleanup 14895 var event = $.Event( "blur" ); 14896 event.target = event.currentTarget = element[0]; 14897 that.close( event, true ); 14898 14899 // Remove immediately; destroying an open tooltip doesn't use the 14900 // hide animation 14901 $( "#" + id ).remove(); 14902 14903 // Restore the title 14904 if ( element.data( "ui-tooltip-title" ) ) { 14905 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14906 element.removeData( "ui-tooltip-title" ); 14907 } 14908 }); 14909 } 14910}); 14911 14912}( 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.