vendor: 9,870 bytes, lines 1-339
1/*! jQuery UI - v1.9.2 - 2013-06-13 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-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 4* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// prevent duplicate loading 12// this is only a problem because we proxy existing functions 13// and we don't want to double proxy them 14$.ui = $.ui || {}; 15if ( $.ui.version ) { 16 return; 17} 18 19$.extend( $.ui, { 20 version: "1.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; 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
vendor: 15,569 bytes, lines 340-848
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(function( $, undefined ) { 353 354var uuid = 0, 355 slice = Array.prototype.slice, 356 _cleanData = $.cleanData; 357$.cleanData = function( elems ) { 358 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 359 try { 360 $( elem ).triggerHandler( "remove" ); 361 // http://bugs.jquery.com/ticket/8235 362 } catch( e ) {} 363 } 364 _cleanData( elems ); 365}; 366 367$.widget = function( name, base, prototype ) { 368 var fullName, existingConstructor, constructor, basePrototype, 369 namespace = name.split( "." )[ 0 ]; 370 371 name = name.split( "." )[ 1 ]; 372 fullName = namespace + "-" + name; 373 374 if ( !prototype ) { 375 prototype = base; 376 base = $.Widget; 377 } 378 379 // create selector for plugin 380 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 381 return !!$.data( elem, fullName ); 382 }; 383 384 $[ namespace ] = $[ namespace ] || {}; 385 existingConstructor = $[ namespace ][ name ]; 386 constructor = $[ namespace ][ name ] = function( options, element ) { 387 // allow instantiation without "new" keyword 388 if ( !this._createWidget ) { 389 return new constructor( options, element ); 390 } 391 392 // allow instantiation without initializing for simple inheritance 393 // must use "new" keyword (the code above always passes args) 394 if ( arguments.length ) { 395 this._createWidget( options, element ); 396 } 397 }; 398 // extend with the existing constructor to carry over any static properties 399 $.extend( constructor, existingConstructor, { 400 version: prototype.version, 401 // copy the object used to create the prototype in case we need to 402 // redefine the widget later 403 _proto: $.extend( {}, prototype ), 404 // track widgets that inherit from this widget in case this widget is 405 // redefined after a widget inherits from it 406 _childConstructors: [] 407 }); 408 409 basePrototype = new base(); 410 // we need to make the options hash a property directly on the new instance 411 // otherwise we'll modify the options hash on the prototype that we're 412 // inheriting from 413 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 414 $.each( prototype, function( prop, value ) { 415 if ( $.isFunction( value ) ) { 416 prototype[ prop ] = (function() { 417 var _super = function() { 418 return base.prototype[ prop ].apply( this, arguments ); 419 }, 420 _superApply = function( args ) { 421 return base.prototype[ prop ].apply( this, args ); 422 }; 423 return function() { 424 var __super = this._super, 425 __superApply = this._superApply, 426 returnValue; 427 428 this._super = _super; 429 this._superApply = _superApply; 430 431 returnValue = value.apply( this, arguments ); 432 433 this._super = __super; 434 this._superApply = __superApply; 435 436 return returnValue; 437 }; 438 })(); 439 } 440 }); 441 constructor.prototype = $.widget.extend( basePrototype, { 442 // TODO: remove support for widgetEventPrefix 443 // always use the name + a colon as the prefix, e.g., draggable:start 444 // don't prefix for widgets that aren't DOM-based 445 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 446 }, prototype, { 447 constructor: constructor, 448 namespace: namespace, 449 widgetName: name, 450 // TODO remove widgetBaseClass, see #8155 451 widgetBaseClass: fullName, 452 widgetFullName: fullName 453 }); 454 455 // If this widget is being redefined then we need to find all widgets that 456 // are inheriting from it and redefine all of them so that they inherit from 457 // the new version of this widget. We're essentially trying to replace one 458 // level in the prototype chain. 459 if ( existingConstructor ) { 460 $.each( existingConstructor._childConstructors, function( i, child ) { 461 var childPrototype = child.prototype; 462 463 // redefine the child widget using the same prototype that was 464 // originally used, but inherit from the new version of the base 465 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 466 }); 467 // remove the list of existing child constructors from the old constructor 468 // so the old child constructors can be garbage collected 469 delete existingConstructor._childConstructors; 470 } else { 471 base._childConstructors.push( constructor ); 472 } 473 474 $.widget.bridge( name, constructor ); 475}; 476 477$.widget.extend = function( target ) { 478 var input = slice.call( arguments, 1 ), 479 inputIndex = 0, 480 inputLength = input.length, 481 key, 482 value; 483 for ( ; inputIndex < inputLength; inputIndex++ ) { 484 for ( key in input[ inputIndex ] ) { 485 value = input[ inputIndex ][ key ]; 486 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 487 // Clone objects 488 if ( $.isPlainObject( value ) ) { 489 target[ key ] = $.isPlainObject( target[ key ] ) ? 490 $.widget.extend( {}, target[ key ], value ) : 491 // Don't extend strings, arrays, etc. with objects 492 $.widget.extend( {}, value ); 493 // Copy everything else by reference 494 } else { 495 target[ key ] = value; 496 } 497 } 498 } 499 } 500 return target; 501}; 502 503$.widget.bridge = function( name, object ) { 504 var fullName = object.prototype.widgetFullName || name; 505 $.fn[ name ] = function( options ) { 506 var isMethodCall = typeof options === "string", 507 args = slice.call( arguments, 1 ), 508 returnValue = this; 509 510 // allow multiple hashes to be passed on init 511 options = !isMethodCall && args.length ? 512 $.widget.extend.apply( null, [ options ].concat(args) ) : 513 options; 514 515 if ( isMethodCall ) { 516 this.each(function() { 517 var methodValue, 518 instance = $.data( this, fullName ); 519 if ( !instance ) { 520 return $.error( "cannot call methods on " + name + " prior to initialization; " + 521 "attempted to call method '" + options + "'" ); 522 } 523 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 524 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 525 } 526 methodValue = instance[ options ].apply( instance, args ); 527 if ( methodValue !== instance && methodValue !== undefined ) { 528 returnValue = methodValue && methodValue.jquery ? 529 returnValue.pushStack( methodValue.get() ) : 530 methodValue; 531 return false; 532 } 533 }); 534 } else { 535 this.each(function() { 536 var instance = $.data( this, fullName ); 537 if ( instance ) { 538 instance.option( options || {} )._init(); 539 } else { 540 $.data( this, fullName, new object( options, this ) ); 541 } 542 }); 543 } 544 545 return returnValue; 546 }; 547}; 548 549$.Widget = function( /* options, element */ ) {}; 550$.Widget._childConstructors = []; 551 552$.Widget.prototype = { 553 widgetName: "widget", 554 widgetEventPrefix: "", 555 defaultElement: "<div>", 556 options: { 557 disabled: false, 558 559 // callbacks 560 create: null 561 }, 562 _createWidget: function( options, element ) { 563 element = $( element || this.defaultElement || this )[ 0 ]; 564 this.element = $( element ); 565 this.uuid = uuid++; 566 this.eventNamespace = "." + this.widgetName + this.uuid; 567 this.options = $.widget.extend( {}, 568 this.options, 569 this._getCreateOptions(), 570 options ); 571 572 this.bindings = $(); 573 this.hoverable = $(); 574 this.focusable = $(); 575 576 if ( element !== this ) { 577 // 1.9 BC for #7810 578 // TODO remove dual storage 579 $.data( element, this.widgetName, this ); 580 $.data( element, this.widgetFullName, this ); 581 this._on( true, this.element, { 582 remove: function( event ) { 583 if ( event.target === element ) { 584 this.destroy(); 585 } 586 } 587 }); 588 this.document = $( element.style ? 589 // element within the document 590 element.ownerDocument : 591 // element is window or document 592 element.document || element ); 593 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 594 } 595 596 this._create(); 597 this._trigger( "create", null, this._getCreateEventData() ); 598 this._init(); 599 }, 600 _getCreateOptions: $.noop, 601 _getCreateEventData: $.noop, 602 _create: $.noop, 603 _init: $.noop, 604 605 destroy: function() { 606 this._destroy(); 607 // we can probably remove the unbind calls in 2.0 608 // all event bindings should go through this._on() 609 this.element 610 .unbind( this.eventNamespace ) 611 // 1.9 BC for #7810 612 // TODO remove dual storage 613 .removeData( this.widgetName ) 614 .removeData( this.widgetFullName ) 615 // support: jquery <1.6.3 616 // http://bugs.jquery.com/ticket/9413 617 .removeData( $.camelCase( this.widgetFullName ) ); 618 this.widget() 619 .unbind( this.eventNamespace ) 620 .removeAttr( "aria-disabled" ) 621 .removeClass( 622 this.widgetFullName + "-disabled " + 623 "ui-state-disabled" ); 624 625 // clean up events and states 626 this.bindings.unbind( this.eventNamespace ); 627 this.hoverable.removeClass( "ui-state-hover" ); 628 this.focusable.removeClass( "ui-state-focus" ); 629 }, 630 _destroy: $.noop, 631 632 widget: function() { 633 return this.element; 634 }, 635 636 option: function( key, value ) { 637 var options = key, 638 parts, 639 curOption, 640 i; 641 642 if ( arguments.length === 0 ) { 643 // don't return a reference to the internal hash 644 return $.widget.extend( {}, this.options ); 645 } 646 647 if ( typeof key === "string" ) { 648 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 649 options = {}; 650 parts = key.split( "." ); 651 key = parts.shift(); 652 if ( parts.length ) { 653 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 654 for ( i = 0; i < parts.length - 1; i++ ) { 655 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 656 curOption = curOption[ parts[ i ] ]; 657 } 658 key = parts.pop(); 659 if ( value === undefined ) { 660 return curOption[ key ] === undefined ? null : curOption[ key ]; 661 } 662 curOption[ key ] = value; 663 } else { 664 if ( value === undefined ) { 665 return this.options[ key ] === undefined ? null : this.options[ key ]; 666 } 667 options[ key ] = value; 668 } 669 } 670 671 this._setOptions( options ); 672 673 return this; 674 }, 675 _setOptions: function( options ) { 676 var key; 677 678 for ( key in options ) { 679 this._setOption( key, options[ key ] ); 680 } 681 682 return this; 683 }, 684 _setOption: function( key, value ) { 685 this.options[ key ] = value; 686 687 if ( key === "disabled" ) { 688 this.widget() 689 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 690 .attr( "aria-disabled", value ); 691 this.hoverable.removeClass( "ui-state-hover" ); 692 this.focusable.removeClass( "ui-state-focus" ); 693 } 694 695 return this; 696 }, 697 698 enable: function() { 699 return this._setOption( "disabled", false ); 700 }, 701 disable: function() { 702 return this._setOption( "disabled", true ); 703 }, 704 705 _on: function( suppressDisabledCheck, element, handlers ) { 706 var delegateElement, 707 instance = this; 708 709 // no suppressDisabledCheck flag, shuffle arguments 710 if ( typeof suppressDisabledCheck !== "boolean" ) { 711 handlers = element; 712 element = suppressDisabledCheck; 713 suppressDisabledCheck = false; 714 } 715 716 // no element argument, shuffle and use this.element 717 if ( !handlers ) { 718 handlers = element; 719 element = this.element; 720 delegateElement = this.widget(); 721 } else { 722 // accept selectors, DOM elements 723 element = delegateElement = $( element ); 724 this.bindings = this.bindings.add( element ); 725 } 726 727 $.each( handlers, function( event, handler ) { 728 function handlerProxy() { 729 // allow widgets to customize the disabled handling 730 // - disabled as an array instead of boolean 731 // - disabled class as method for disabling individual parts 732 if ( !suppressDisabledCheck && 733 ( instance.options.disabled === true || 734 $( this ).hasClass( "ui-state-disabled" ) ) ) { 735 return; 736 } 737 return ( typeof handler === "string" ? instance[ handler ] : handler ) 738 .apply( instance, arguments ); 739 } 740 741 // copy the guid so direct unbinding works 742 if ( typeof handler !== "string" ) { 743 handlerProxy.guid = handler.guid = 744 handler.guid || handlerProxy.guid || $.guid++; 745 } 746 747 var match = event.match( /^(\w+)\s*(.*)$/ ), 748 eventName = match[1] + instance.eventNamespace, 749 selector = match[2]; 750 if ( selector ) { 751 delegateElement.delegate( selector, eventName, handlerProxy ); 752 } else { 753 element.bind( eventName, handlerProxy ); 754 } 755 }); 756 }, 757 758 _off: function( element, eventName ) { 759 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 760 element.unbind( eventName ).undelegate( eventName ); 761 }, 762 763 _delay: function( handler, delay ) { 764 function handlerProxy() { 765 return ( typeof handler === "string" ? instance[ handler ] : handler ) 766 .apply( instance, arguments ); 767 } 768 var instance = this; 769 return setTimeout( handlerProxy, delay || 0 ); 770 }, 771 772 _hoverable: function( element ) { 773 this.hoverable = this.hoverable.add( element ); 774 this._on( element, { 775 mouseenter: function( event ) { 776 $( event.currentTarget ).addClass( "ui-state-hover" ); 777 }, 778 mouseleave: function( event ) { 779 $( event.currentTarget ).removeClass( "ui-state-hover" ); 780 } 781 }); 782 }, 783 784 _focusable: function( element ) { 785 this.focusable = this.focusable.add( element ); 786 this._on( element, { 787 focusin: function( event ) { 788 $( event.currentTarget ).addClass( "ui-state-focus" ); 789 }, 790 focusout: function( event ) { 791 $( event.currentTarget ).removeClass( "ui-state-focus" ); 792 } 793 }); 794 }, 795 796 _trigger: function( type, event, data ) { 797 var prop, orig, 798 callback = this.options[ type ]; 799 800 data = data || {}; 801 event = $.Event( event ); 802 event.type = ( type === this.widgetEventPrefix ? 803 type : 804 this.widgetEventPrefix + type ).toLowerCase(); 805 // the original event may come from any element 806 // so we need to reset the target on the new event 807 event.target = this.element[ 0 ]; 808 809 // copy original event properties over to the new event 810 orig = event.originalEvent; 811 if ( orig ) { 812 for ( prop in orig ) { 813 if ( !( prop in event ) ) { 814 event[ prop ] = orig[ prop ]; 815 } 816 } 817 } 818 819 this.element.trigger( event, data ); 820 return !( $.isFunction( callback ) && 821 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 822 event.isDefaultPrevented() ); 823 } 824}; 825 826$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 827 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 828 if ( typeof options === "string" ) { 829 options = { effect: options }; 830 } 831 var hasOptions, 832 effectName = !options ? 833 method : 834 options === true || typeof options === "number" ? 835 defaultEffect : 836 options.effect || defaultEffect; 837 options = options || {}; 838 if ( typeof options === "number" ) { 839 options = { duration: options }; 840 } 841 hasOptions = !$.isEmptyObject( options ); 842 options.complete = callback; 843 if ( options.delay ) { 844 element.delay( options.delay ); 845 } 846 if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { 847 element[ method ]( options ); 848 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,729 bytes, lines 849-1019
849 element[ effectName ]( options.duration, options.easing, callback ); 850 } else { 851 element.queue(function( next ) { 852 $( this )[ method ](); 853 if ( callback ) { 854 callback.call( element[ 0 ] ); 855 } 856 next(); 857 }); 858 } 859 }; 860}); 861 862// DEPRECATED 863if ( $.uiBackCompat !== false ) { 864 $.Widget.prototype._getCreateOptions = function() { 865 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; 866 }; 867} 868 869})( jQuery ); 870(function( $, undefined ) { 871 872var mouseHandled = false; 873$( document ).mouseup( function( e ) { 874 mouseHandled = false; 875}); 876 877$.widget("ui.mouse", { 878 version: "1.9.2", 879 options: { 880 cancel: 'input,textarea,button,select,option', 881 distance: 1, 882 delay: 0 883 }, 884 _mouseInit: function() { 885 var that = this; 886 887 this.element 888 .bind('mousedown.'+this.widgetName, function(event) { 889 return that._mouseDown(event); 890 }) 891 .bind('click.'+this.widgetName, function(event) { 892 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { 893 $.removeData(event.target, that.widgetName + '.preventClickEvent'); 894 event.stopImmediatePropagation(); 895 return false; 896 } 897 }); 898 899 this.started = false; 900 }, 901 902 // TODO: make sure destroying one instance of mouse doesn't mess with 903 // other instances of mouse 904 _mouseDestroy: function() { 905 this.element.unbind('.'+this.widgetName); 906 if ( this._mouseMoveDelegate ) { 907 $(document) 908 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 909 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 910 } 911 }, 912 913 _mouseDown: function(event) { 914 // don't let more than one widget handle mouseStart 915 if( mouseHandled ) { return; } 916 917 // we may have missed mouseup (out of window) 918 (this._mouseStarted && this._mouseUp(event)); 919 920 this._mouseDownEvent = event; 921 922 var that = this, 923 btnIsLeft = (event.which === 1), 924 // event.target.nodeName works around a bug in IE 8 with 925 // disabled inputs (#7620) 926 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 927 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 928 return true; 929 } 930 931 this.mouseDelayMet = !this.options.delay; 932 if (!this.mouseDelayMet) { 933 this._mouseDelayTimer = setTimeout(function() { 934 that.mouseDelayMet = true; 935 }, this.options.delay); 936 } 937 938 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 939 this._mouseStarted = (this._mouseStart(event) !== false); 940 if (!this._mouseStarted) { 941 event.preventDefault(); 942 return true; 943 } 944 } 945 946 // Click event may never have fired (Gecko & Opera) 947 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { 948 $.removeData(event.target, this.widgetName + '.preventClickEvent'); 949 } 950 951 // these delegates are required to keep context 952 this._mouseMoveDelegate = function(event) { 953 return that._mouseMove(event); 954 }; 955 this._mouseUpDelegate = function(event) { 956 return that._mouseUp(event); 957 }; 958 $(document) 959 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 960 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); 961 962 event.preventDefault(); 963 964 mouseHandled = true; 965 return true; 966 }, 967 968 _mouseMove: function(event) { 969 // IE mouseup check - mouseup happened when mouse was out of window 970 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { 971 return this._mouseUp(event); 972 } 973 974 if (this._mouseStarted) { 975 this._mouseDrag(event); 976 return event.preventDefault(); 977 } 978 979 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 980 this._mouseStarted = 981 (this._mouseStart(this._mouseDownEvent, event) !== false); 982 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 983 } 984 985 return !this._mouseStarted; 986 }, 987 988 _mouseUp: function(event) { 989 $(document) 990 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 991 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 992 993 if (this._mouseStarted) { 994 this._mouseStarted = false; 995 996 if (event.target === this._mouseDownEvent.target) { 997 $.data(event.target, this.widgetName + '.preventClickEvent', true); 998 } 999 1000 this._mouseStop(event); 1001 } 1002 1003 return false; 1004 }, 1005 1006 _mouseDistanceMet: function(event) { 1007 return (Math.max( 1008 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1009 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1010 ) >= this.options.distance 1011 ); 1012 }, 1013 1014 _mouseDelayMet: function(event) { 1015 return this.mouseDelayMet; 1016 }, 1017 1018 // These are placeholder methods, to be overriden by extending plugin 1019 _mouseStart: function(event) {},
1020 _mouseDrag: function(event) {}, 1021 _mouseStop: function(event) {}, 1022 _mouseCapture: function(event) { return true; } 1023}); 1024 1025})(jQuery); 1026(function( $, undefined ) { 1027 1028$.ui = $.ui || {}; 1029 1030var cachedScrollbarWidth, 1031 max = Math.max, 1032 abs = Math.abs, 1033 round = Math.round, 1034 rhorizontal = /left|center|right/, 1035 rvertical = /top|center|bottom/, 1036 roffset = /[\+\-]\d+%?/, 1037 rposition = /^\w+/, 1038 rpercent = /%$/, 1039 _position = $.fn.position; 1040 1041function getOffsets( offsets, width, height ) { 1042 return [ 1043 parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1044 parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1045 ]; 1046} 1047function parseCss( element, property ) { 1048 return parseInt( $.css( element, property ), 10 ) || 0; 1049} 1050 1051$.position = { 1052 scrollbarWidth: function() { 1053 if ( cachedScrollbarWidth !== undefined ) { 1054 return cachedScrollbarWidth; 1055 } 1056 var w1, w2, 1057 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1058 innerDiv = div.children()[0]; 1059 1060 $( "body" ).append( div ); 1061 w1 = innerDiv.offsetWidth; 1062 div.css( "overflow", "scroll" ); 1063 1064 w2 = innerDiv.offsetWidth; 1065 1066 if ( w1 === w2 ) { 1067 w2 = div[0].clientWidth; 1068 } 1069 1070 div.remove(); 1071 1072 return (cachedScrollbarWidth = w1 - w2); 1073 }, 1074 getScrollInfo: function( within ) { 1075 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 1076 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 1077 hasOverflowX = overflowX === "scroll" || 1078 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1079 hasOverflowY = overflowY === "scroll" || 1080 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1081 return { 1082 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 1083 height: hasOverflowY ? $.position.scrollbarWidth() : 0 1084 }; 1085 }, 1086 getWithinInfo: function( element ) { 1087 var withinElement = $( element || window ), 1088 isWindow = $.isWindow( withinElement[0] ); 1089 return { 1090 element: withinElement, 1091 isWindow: isWindow, 1092 offset: withinElement.offset() || { left: 0, top: 0 }, 1093 scrollLeft: withinElement.scrollLeft(), 1094 scrollTop: withinElement.scrollTop(), 1095 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1096 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1097 }; 1098 } 1099}; 1100 1101$.fn.position = function( options ) { 1102 if ( !options || !options.of ) { 1103 return _position.apply( this, arguments ); 1104 } 1105 1106 // make a copy, we don't want to modify arguments 1107 options = $.extend( {}, options ); 1108 1109 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, 1110 target = $( options.of ), 1111 within = $.position.getWithinInfo( options.within ), 1112 scrollInfo = $.position.getScrollInfo( within ), 1113 targetElem = target[0], 1114 collision = ( options.collision || "flip" ).split( " " ), 1115 offsets = {}; 1116 1117 if ( targetElem.nodeType === 9 ) { 1118 targetWidth = target.width(); 1119 targetHeight = target.height(); 1120 targetOffset = { top: 0, left: 0 }; 1121 } else if ( $.isWindow( targetElem ) ) { 1122 targetWidth = target.width(); 1123 targetHeight = target.height(); 1124 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; 1125 } else if ( targetElem.preventDefault ) { 1126 // force left top to allow flipping 1127 options.at = "left top"; 1128 targetWidth = targetHeight = 0; 1129 targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; 1130 } else { 1131 targetWidth = target.outerWidth(); 1132 targetHeight = target.outerHeight(); 1133 targetOffset = target.offset(); 1134 } 1135 // clone to reuse original targetOffset later 1136 basePosition = $.extend( {}, targetOffset ); 1137 1138 // force my and at to have valid horizontal and vertical positions 1139 // if a value is missing or invalid, it will be converted to center 1140 $.each( [ "my", "at" ], function() { 1141 var pos = ( options[ this ] || "" ).split( " " ), 1142 horizontalOffset, 1143 verticalOffset; 1144 1145 if ( pos.length === 1) { 1146 pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 11,271 bytes, lines 1147-1475
1147 pos.concat( [ "center" ] ) : 1148 rvertical.test( pos[ 0 ] ) ? 1149 [ "center" ].concat( pos ) : 1150 [ "center", "center" ]; 1151 } 1152 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1153 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1154 1155 // calculate offsets 1156 horizontalOffset = roffset.exec( pos[ 0 ] ); 1157 verticalOffset = roffset.exec( pos[ 1 ] ); 1158 offsets[ this ] = [ 1159 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1160 verticalOffset ? verticalOffset[ 0 ] : 0 1161 ]; 1162 1163 // reduce to just the positions without the offsets 1164 options[ this ] = [ 1165 rposition.exec( pos[ 0 ] )[ 0 ], 1166 rposition.exec( pos[ 1 ] )[ 0 ] 1167 ]; 1168 }); 1169 1170 // normalize collision option 1171 if ( collision.length === 1 ) { 1172 collision[ 1 ] = collision[ 0 ]; 1173 } 1174 1175 if ( options.at[ 0 ] === "right" ) { 1176 basePosition.left += targetWidth; 1177 } else if ( options.at[ 0 ] === "center" ) { 1178 basePosition.left += targetWidth / 2; 1179 } 1180 1181 if ( options.at[ 1 ] === "bottom" ) { 1182 basePosition.top += targetHeight; 1183 } else if ( options.at[ 1 ] === "center" ) { 1184 basePosition.top += targetHeight / 2; 1185 } 1186 1187 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1188 basePosition.left += atOffset[ 0 ]; 1189 basePosition.top += atOffset[ 1 ]; 1190 1191 return this.each(function() { 1192 var collisionPosition, using, 1193 elem = $( this ), 1194 elemWidth = elem.outerWidth(), 1195 elemHeight = elem.outerHeight(), 1196 marginLeft = parseCss( this, "marginLeft" ), 1197 marginTop = parseCss( this, "marginTop" ), 1198 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1199 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1200 position = $.extend( {}, basePosition ), 1201 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1202 1203 if ( options.my[ 0 ] === "right" ) { 1204 position.left -= elemWidth; 1205 } else if ( options.my[ 0 ] === "center" ) { 1206 position.left -= elemWidth / 2; 1207 } 1208 1209 if ( options.my[ 1 ] === "bottom" ) { 1210 position.top -= elemHeight; 1211 } else if ( options.my[ 1 ] === "center" ) { 1212 position.top -= elemHeight / 2; 1213 } 1214 1215 position.left += myOffset[ 0 ]; 1216 position.top += myOffset[ 1 ]; 1217 1218 // if the browser doesn't support fractions, then round for consistent results 1219 if ( !$.support.offsetFractions ) { 1220 position.left = round( position.left ); 1221 position.top = round( position.top ); 1222 } 1223 1224 collisionPosition = { 1225 marginLeft: marginLeft, 1226 marginTop: marginTop 1227 }; 1228 1229 $.each( [ "left", "top" ], function( i, dir ) { 1230 if ( $.ui.position[ collision[ i ] ] ) { 1231 $.ui.position[ collision[ i ] ][ dir ]( position, { 1232 targetWidth: targetWidth, 1233 targetHeight: targetHeight, 1234 elemWidth: elemWidth, 1235 elemHeight: elemHeight, 1236 collisionPosition: collisionPosition, 1237 collisionWidth: collisionWidth, 1238 collisionHeight: collisionHeight, 1239 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1240 my: options.my, 1241 at: options.at, 1242 within: within, 1243 elem : elem 1244 }); 1245 } 1246 }); 1247 1248 if ( $.fn.bgiframe ) { 1249 elem.bgiframe(); 1250 } 1251 1252 if ( options.using ) { 1253 // adds feedback as second argument to using callback, if present 1254 using = function( props ) { 1255 var left = targetOffset.left - position.left, 1256 right = left + targetWidth - elemWidth, 1257 top = targetOffset.top - position.top, 1258 bottom = top + targetHeight - elemHeight, 1259 feedback = { 1260 target: { 1261 element: target, 1262 left: targetOffset.left, 1263 top: targetOffset.top, 1264 width: targetWidth, 1265 height: targetHeight 1266 }, 1267 element: { 1268 element: elem, 1269 left: position.left, 1270 top: position.top, 1271 width: elemWidth, 1272 height: elemHeight 1273 }, 1274 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1275 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1276 }; 1277 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1278 feedback.horizontal = "center"; 1279 } 1280 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1281 feedback.vertical = "middle"; 1282 } 1283 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1284 feedback.important = "horizontal"; 1285 } else { 1286 feedback.important = "vertical"; 1287 } 1288 options.using.call( this, props, feedback ); 1289 }; 1290 } 1291 1292 elem.offset( $.extend( position, { using: using } ) ); 1293 }); 1294}; 1295 1296$.ui.position = { 1297 fit: { 1298 left: function( position, data ) { 1299 var within = data.within, 1300 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1301 outerWidth = within.width, 1302 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1303 overLeft = withinOffset - collisionPosLeft, 1304 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1305 newOverRight; 1306 1307 // element is wider than within 1308 if ( data.collisionWidth > outerWidth ) { 1309 // element is initially over the left side of within 1310 if ( overLeft > 0 && overRight <= 0 ) { 1311 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1312 position.left += overLeft - newOverRight; 1313 // element is initially over right side of within 1314 } else if ( overRight > 0 && overLeft <= 0 ) { 1315 position.left = withinOffset; 1316 // element is initially over both left and right sides of within 1317 } else { 1318 if ( overLeft > overRight ) { 1319 position.left = withinOffset + outerWidth - data.collisionWidth; 1320 } else { 1321 position.left = withinOffset; 1322 } 1323 } 1324 // too far left -> align with left edge 1325 } else if ( overLeft > 0 ) { 1326 position.left += overLeft; 1327 // too far right -> align with right edge 1328 } else if ( overRight > 0 ) { 1329 position.left -= overRight; 1330 // adjust based on position and margin 1331 } else { 1332 position.left = max( position.left - collisionPosLeft, position.left ); 1333 } 1334 }, 1335 top: function( position, data ) { 1336 var within = data.within, 1337 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1338 outerHeight = data.within.height, 1339 collisionPosTop = position.top - data.collisionPosition.marginTop, 1340 overTop = withinOffset - collisionPosTop, 1341 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1342 newOverBottom; 1343 1344 // element is taller than within 1345 if ( data.collisionHeight > outerHeight ) { 1346 // element is initially over the top of within 1347 if ( overTop > 0 && overBottom <= 0 ) { 1348 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1349 position.top += overTop - newOverBottom; 1350 // element is initially over bottom of within 1351 } else if ( overBottom > 0 && overTop <= 0 ) { 1352 position.top = withinOffset; 1353 // element is initially over both top and bottom of within 1354 } else { 1355 if ( overTop > overBottom ) { 1356 position.top = withinOffset + outerHeight - data.collisionHeight; 1357 } else { 1358 position.top = withinOffset; 1359 } 1360 } 1361 // too far up -> align with top 1362 } else if ( overTop > 0 ) { 1363 position.top += overTop; 1364 // too far down -> align with bottom edge 1365 } else if ( overBottom > 0 ) { 1366 position.top -= overBottom; 1367 // adjust based on position and margin 1368 } else { 1369 position.top = max( position.top - collisionPosTop, position.top ); 1370 } 1371 } 1372 }, 1373 flip: { 1374 left: function( position, data ) { 1375 var within = data.within, 1376 withinOffset = within.offset.left + within.scrollLeft, 1377 outerWidth = within.width, 1378 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1379 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1380 overLeft = collisionPosLeft - offsetLeft, 1381 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1382 myOffset = data.my[ 0 ] === "left" ? 1383 -data.elemWidth : 1384 data.my[ 0 ] === "right" ? 1385 data.elemWidth : 1386 0, 1387 atOffset = data.at[ 0 ] === "left" ? 1388 data.targetWidth : 1389 data.at[ 0 ] === "right" ? 1390 -data.targetWidth : 1391 0, 1392 offset = -2 * data.offset[ 0 ], 1393 newOverRight, 1394 newOverLeft; 1395 1396 if ( overLeft < 0 ) { 1397 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1398 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1399 position.left += myOffset + atOffset + offset; 1400 } 1401 } 1402 else if ( overRight > 0 ) { 1403 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1404 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1405 position.left += myOffset + atOffset + offset; 1406 } 1407 } 1408 }, 1409 top: function( position, data ) { 1410 var within = data.within, 1411 withinOffset = within.offset.top + within.scrollTop, 1412 outerHeight = within.height, 1413 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1414 collisionPosTop = position.top - data.collisionPosition.marginTop, 1415 overTop = collisionPosTop - offsetTop, 1416 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1417 top = data.my[ 1 ] === "top", 1418 myOffset = top ? 1419 -data.elemHeight : 1420 data.my[ 1 ] === "bottom" ? 1421 data.elemHeight : 1422 0, 1423 atOffset = data.at[ 1 ] === "top" ? 1424 data.targetHeight : 1425 data.at[ 1 ] === "bottom" ? 1426 -data.targetHeight : 1427 0, 1428 offset = -2 * data.offset[ 1 ], 1429 newOverTop, 1430 newOverBottom; 1431 if ( overTop < 0 ) { 1432 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1433 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1434 position.top += myOffset + atOffset + offset; 1435 } 1436 } 1437 else if ( overBottom > 0 ) { 1438 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1439 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1440 position.top += myOffset + atOffset + offset; 1441 } 1442 } 1443 } 1444 }, 1445 flipfit: { 1446 left: function() { 1447 $.ui.position.flip.left.apply( this, arguments ); 1448 $.ui.position.fit.left.apply( this, arguments ); 1449 }, 1450 top: function() { 1451 $.ui.position.flip.top.apply( this, arguments ); 1452 $.ui.position.fit.top.apply( this, arguments ); 1453 } 1454 } 1455}; 1456 1457// fraction support test 1458(function () { 1459 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1460 body = document.getElementsByTagName( "body" )[ 0 ], 1461 div = document.createElement( "div" ); 1462 1463 //Create a "fake body" for testing based on method used in jQuery.support 1464 testElement = document.createElement( body ? "div" : "body" ); 1465 testElementStyle = { 1466 visibility: "hidden", 1467 width: 0, 1468 height: 0, 1469 border: 0, 1470 margin: 0, 1471 background: "none" 1472 }; 1473 if ( body ) { 1474 $.extend( testElementStyle, { 1475 position: "absolute",
1476 left: "-1000px", 1477 top: "-1000px" 1478 }); 1479 } 1480 for ( i in testElementStyle ) { 1481 testElement.style[ i ] = testElementStyle[ i ]; 1482 } 1483 testElement.appendChild( div ); 1484 testElementParent = body || document.documentElement; 1485 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1486 1487 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1488 1489 offsetLeft = $( div ).offset().left; 1490 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1491 1492 testElement.innerHTML = ""; 1493 testElementParent.removeChild( testElement ); 1494})(); 1495 1496// DEPRECATED 1497if ( $.uiBackCompat !== false ) { 1498 // offset option 1499 (function( $ ) { 1500 var _position = $.fn.position; 1501 $.fn.position = function( options ) { 1502 if ( !options || !options.offset ) { 1503 return _position.call( this, options ); 1504 } 1505 var offset = options.offset.split( " " ), 1506 at = options.at.split( " " ); 1507 if ( offset.length === 1 ) { 1508 offset[ 1 ] = offset[ 0 ]; 1509 } 1510 if ( /^\d/.test( offset[ 0 ] ) ) { 1511 offset[ 0 ] = "+" + offset[ 0 ]; 1512 } 1513 if ( /^\d/.test( offset[ 1 ] ) ) { 1514 offset[ 1 ] = "+" + offset[ 1 ]; 1515 } 1516 if ( at.length === 1 ) { 1517 if ( /left|center|right/.test( at[ 0 ] ) ) { 1518 at[ 1 ] = "center"; 1519 } else { 1520 at[ 1 ] = at[ 0 ]; 1521 at[ 0 ] = "center"; 1522 } 1523 } 1524 return _position.call( this, $.extend( options, { 1525 at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], 1526 offset: undefined 1527 } ) ); 1528 }; 1529 }( jQuery ) ); 1530} 1531 1532}( jQuery ) ); 1533(function( $, undefined ) { 1534 1535$.widget("ui.draggable", $.ui.mouse, { 1536 version: "1.9.2", 1537 widgetEventPrefix: "drag", 1538 options: { 1539 addClasses: true, 1540 appendTo: "parent", 1541 axis: false, 1542 connectToSortable: false, 1543 containment: false, 1544 cursor: "auto", 1545 cursorAt: false, 1546 grid: false, 1547 handle: false, 1548 helper: "original", 1549 iframeFix: false, 1550 opacity: false, 1551 refreshPositions: false, 1552 revert: false, 1553 revertDuration: 500, 1554 scope: "default", 1555 scroll: true, 1556 scrollSensitivity: 20, 1557 scrollSpeed: 20, 1558 snap: false, 1559 snapMode: "both", 1560 snapTolerance: 20, 1561 stack: false, 1562 zIndex: false 1563 }, 1564 _create: function() { 1565 1566 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 1567 this.element[0].style.position = 'relative'; 1568 1569 (this.options.addClasses && this.element.addClass("ui-draggable")); 1570 (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 1571 1572 this._mouseInit(); 1573 1574 }, 1575 1576 _destroy: function() { 1577 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1578 this._mouseDestroy(); 1579 }, 1580 1581 _mouseCapture: function(event) { 1582 1583 var o = this.options; 1584 1585 // among others, prevent a drag on a resizable-handle 1586 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 1587 return false; 1588 1589 //Quit if we're not on a valid handle 1590 this.handle = this._getHandle(event); 1591 if (!this.handle) 1592 return false; 1593 1594 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1595 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 1596 .css({ 1597 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1598 position: "absolute", opacity: "0.001", zIndex: 1000 1599 }) 1600 .css($(this).offset()) 1601 .appendTo("body"); 1602 }); 1603 1604 return true; 1605 1606 }, 1607 1608 _mouseStart: function(event) { 1609 1610 var o = this.options; 1611 1612 //Create and append the visible helper 1613 this.helper = this._createHelper(event); 1614 1615 this.helper.addClass("ui-draggable-dragging"); 1616 1617 //Cache the helper size 1618 this._cacheHelperProportions(); 1619 1620 //If ddmanager is used for droppables, set the global draggable 1621 if($.ui.ddmanager) 1622 $.ui.ddmanager.current = this; 1623 1624 /* 1625 * - Position generation - 1626 * This block generates everything position related - it's the core of draggables. 1627 */ 1628 1629 //Cache the margins of the original element 1630 this._cacheMargins(); 1631 1632 //Store the helper's css position 1633 this.cssPosition = this.helper.css("position"); 1634 this.scrollParent = this.helper.scrollParent(); 1635 1636 //The element's absolute position on the page minus margins 1637 this.offset = this.positionAbs = this.element.offset(); 1638 this.offset = { 1639 top: this.offset.top - this.margins.top, 1640 left: this.offset.left - this.margins.left 1641 }; 1642 1643 $.extend(this.offset, { 1644 click: { //Where the click happened, relative to the element 1645 left: event.pageX - this.offset.left, 1646 top: event.pageY - this.offset.top 1647 }, 1648 parent: this._getParentOffset(), 1649 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1650 }); 1651 1652 //Generate the original position 1653 this.originalPosition = this.position = this._generatePosition(event); 1654 this.originalPageX = event.pageX; 1655 this.originalPageY = event.pageY; 1656 1657 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 1658 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1659 1660 //Set a containment if given in the options 1661 if(o.containment) 1662 this._setContainment(); 1663 1664 //Trigger event + callbacks 1665 if(this._trigger("start", event) === false) { 1666 this._clear(); 1667 return false; 1668 } 1669 1670 //Recache the helper size 1671 this._cacheHelperProportions(); 1672 1673 //Prepare the droppable offsets 1674 if ($.ui.ddmanager && !o.dropBehaviour) 1675 $.ui.ddmanager.prepareOffsets(this, event); 1676 1677 1678 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1679 1680 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1681 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); 1682 1683 return true; 1684 }, 1685 1686 _mouseDrag: function(event, noPropagation) { 1687 1688 //Compute the helpers position 1689 this.position = this._generatePosition(event); 1690 this.positionAbs = this._convertPositionTo("absolute"); 1691 1692 //Call plugins and callbacks and use the resulting position if something is returned 1693 if (!noPropagation) { 1694 var ui = this._uiHash(); 1695 if(this._trigger('drag', event, ui) === false) { 1696 this._mouseUp({}); 1697 return false; 1698 } 1699 this.position = ui.position; 1700 } 1701 1702 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 1703 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 1704 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 1705 1706 return false; 1707 }, 1708 1709 _mouseStop: function(event) { 1710 1711 //If we are using droppables, inform the manager about the drop 1712 var dropped = false; 1713 if ($.ui.ddmanager && !this.options.dropBehaviour) 1714 dropped = $.ui.ddmanager.drop(this, event); 1715 1716 //if a drop comes from outside (a sortable) 1717 if(this.dropped) { 1718 dropped = this.dropped; 1719 this.dropped = false; 1720 } 1721 1722 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1723 var element = this.element[0], elementInDom = false; 1724 while ( element && (element = element.parentNode) ) { 1725 if (element == document ) { 1726 elementInDom = true; 1727 } 1728 } 1729 if ( !elementInDom && this.options.helper === "original" ) 1730 return false; 1731 1732 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))) { 1733 var that = this; 1734 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1735 if(that._trigger("stop", event) !== false) { 1736 that._clear(); 1737 } 1738 }); 1739 } else { 1740 if(this._trigger("stop", event) !== false) { 1741 this._clear(); 1742 } 1743 } 1744 1745 return false; 1746 }, 1747 1748 _mouseUp: function(event) { 1749 //Remove frame helpers 1750 $("div.ui-draggable-iframeFix").each(function() { 1751 this.parentNode.removeChild(this); 1752 }); 1753 1754 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1755 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); 1756 1757 return $.ui.mouse.prototype._mouseUp.call(this, event); 1758 }, 1759 1760 cancel: function() { 1761 1762 if(this.helper.is(".ui-draggable-dragging")) { 1763 this._mouseUp({}); 1764 } else { 1765 this._clear(); 1766 } 1767 1768 return this; 1769 1770 }, 1771 1772 _getHandle: function(event) { 1773 1774 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1775 $(this.options.handle, this.element) 1776 .find("*") 1777 .andSelf() 1778 .each(function() { 1779 if(this == event.target) handle = true; 1780 }); 1781 1782 return handle; 1783 1784 }, 1785 1786 _createHelper: function(event) { 1787 1788 var o = this.options; 1789 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); 1790 1791 if(!helper.parents('body').length) 1792 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 1793 1794 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 1795 helper.css("position", "absolute"); 1796 1797 return helper; 1798 1799 }, 1800 1801 _adjustOffsetFromHelper: function(obj) { 1802 if (typeof obj == 'string') { 1803 obj = obj.split(' '); 1804 } 1805 if ($.isArray(obj)) { 1806 obj = {left: +obj[0], top: +obj[1] || 0}; 1807 } 1808 if ('left' in obj) { 1809 this.offset.click.left = obj.left + this.margins.left; 1810 } 1811 if ('right' in obj) { 1812 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1813 } 1814 if ('top' in obj) { 1815 this.offset.click.top = obj.top + this.margins.top; 1816 } 1817 if ('bottom' in obj) { 1818 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1819 } 1820 }, 1821 1822 _getParentOffset: function() { 1823 1824 //Get the offsetParent and cache its position 1825 this.offsetParent = this.helper.offsetParent(); 1826 var po = this.offsetParent.offset(); 1827 1828 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1829 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1830 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1831 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1832 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1833 po.left += this.scrollParent.scrollLeft(); 1834 po.top += this.scrollParent.scrollTop(); 1835 } 1836 1837 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 1838 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 1839 po = { top: 0, left: 0 }; 1840 1841 return { 1842 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
184210) || 0), 1843 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1844 }; 1845 1846 }, 1847 1848 _getRelativeOffset: function() { 1849 1850 if(this.cssPosition == "relative") { 1851 var p = this.element.position(); 1852 return { 1853 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1854 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1855 }; 1856 } else { 1857 return { top: 0, left: 0 }; 1858 } 1859 1860 }, 1861 1862 _cacheMargins: function() { 1863 this.margins = { 1864 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1865 top: (parseInt(this.element.css("marginTop"),10) || 0), 1866 right: (parseInt(this.element.css("marginRight"),10) || 0), 1867 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1868 }; 1869 }, 1870 1871 _cacheHelperProportions: function() { 1872 this.helperProportions = { 1873 width: this.helper.outerWidth(), 1874 height: this.helper.outerHeight() 1875 }; 1876 }, 1877 1878 _setContainment: function() { 1879 1880 var o = this.options; 1881 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 1882 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 1883 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1884 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1885 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 1886 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1887 ]; 1888 1889 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { 1890 var c = $(o.containment); 1891 var ce = c[0]; if(!ce) return; 1892 var co = c.offset(); 1893 var over = ($(ce).css("overflow") != 'hidden'); 1894 1895 this.containment = [ 1896 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1897 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1898 (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, 1899 (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 1900 ]; 1901 this.relative_container = c; 1902 1903 } else if(o.containment.constructor == Array) { 1904 this.containment = o.containment; 1905 } 1906 1907 }, 1908 1909 _convertPositionTo: function(d, pos) { 1910 1911 if(!pos) pos = this.position; 1912 var mod = d == "absolute" ? 1 : -1; 1913 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); 1914 1915 return { 1916 top: ( 1917 pos.top // The absolute mouse position 1918 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1919 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 1920 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1921 ), 1922 left: ( 1923 pos.left // The absolute mouse position 1924 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 1925 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 1926 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1927 ) 1928 }; 1929 1930 }, 1931 1932 _generatePosition: function(event) { 1933 1934 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); 1935 var pageX = event.pageX; 1936 var pageY = event.pageY; 1937 1938 /* 1939 * - Position constraining - 1940 * Constrain the position to a mix of grid, containment. 1941 */ 1942 1943 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1944 var containment; 1945 if(this.containment) { 1946 if (this.relative_container){ 1947 var co = this.relative_container.offset(); 1948 containment = [ this.containment[0] + co.left, 1949 this.containment[1] + co.top, 1950 this.containment[2] + co.left, 1951 this.containment[3] + co.top ]; 1952 } 1953 else { 1954 containment = this.containment; 1955 } 1956 1957 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; 1958 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; 1959 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; 1960 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; 1961 } 1962 1963 if(o.grid) { 1964 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1965 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1966 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; 1967 1968 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1969 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; 1970 } 1971 1972 } 1973 1974 return { 1975 top: ( 1976 pageY // The absolute mouse position 1977 - this.offset.click.top // Click offset (relative to the element) 1978 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 1979 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 1980 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1981 ), 1982 left: ( 1983 pageX // The absolute mouse position 1984 - this.offset.click.left // Click offset (relative to the element) 1985 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 1986 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 1987 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1988 ) 1989 }; 1990 1991 }, 1992 1993 _clear: function() { 1994 this.helper.removeClass("ui-draggable-dragging"); 1995 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 1996 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 1997 this.helper = null; 1998 this.cancelHelperRemoval = false; 1999 }, 2000 2001 // From now on bulk stuff - mainly helpers 2002 2003 _trigger: function(type, event, ui) { 2004 ui = ui || this._uiHash(); 2005 $.ui.plugin.call(this, type, [event, ui]); 2006 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 2007 return $.Widget.prototype._trigger.call(this, type, event, ui); 2008 }, 2009 2010 plugins: {}, 2011 2012 _uiHash: function(event) { 2013 return { 2014 helper: this.helper, 2015 position: this.position, 2016 originalPosition: this.originalPosition, 2017 offset: this.positionAbs 2018 }; 2019 } 2020 2021}); 2022 2023$.ui.plugin.add("draggable", "connectToSortable", { 2024 start: function(event, ui) { 2025 2026 var inst = $(this).data("draggable"), o = inst.options, 2027 uiSortable = $.extend({}, ui, { item: inst.element }); 2028 inst.sortables = []; 2029 $(o.connectToSortable).each(function() { 2030 var sortable = $.data(this, 'sortable');
2031 if (sortable && !sortable.options.disabled) { 2032 inst.sortables.push({ 2033 instance: sortable, 2034 shouldRevert: sortable.options.revert 2035 }); 2036 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). 2037 sortable._trigger("activate", event, uiSortable); 2038 } 2039 }); 2040 2041 }, 2042 stop: function(event, ui) { 2043 2044 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2045 var inst = $(this).data("draggable"), 2046 uiSortable = $.extend({}, ui, { item: inst.element }); 2047 2048 $.each(inst.sortables, function() { 2049 if(this.instance.isOver) { 2050 2051 this.instance.isOver = 0; 2052 2053 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2054 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2055 2056 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' 2057 if(this.shouldRevert) this.instance.options.revert = true; 2058 2059 //Trigger the stop of the sortable 2060 this.instance._mouseStop(event); 2061 2062 this.instance.options.helper = this.instance.options._helper; 2063 2064 //If the helper has been the original item, restore properties in the sortable 2065 if(inst.options.helper == 'original') 2066 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 2067 2068 } else { 2069 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2070 this.instance._trigger("deactivate", event, uiSortable); 2071 } 2072 2073 }); 2074 2075 }, 2076 drag: function(event, ui) { 2077 2078 var inst = $(this).data("draggable"), that = this; 2079 2080 var checkPos = function(o) { 2081 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 2082 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 2083 var itemHeight = o.height, itemWidth = o.width; 2084 var itemTop = o.top, itemLeft = o.left; 2085 2086 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 2087 }; 2088 2089 $.each(inst.sortables, function(i) { 2090 2091 var innermostIntersecting = false; 2092 var thisSortable = this; 2093 //Copy over some variables to allow calling the sortable's native _intersectsWith 2094 this.instance.positionAbs = inst.positionAbs; 2095 this.instance.helperProportions = inst.helperProportions; 2096 this.instance.offset.click = inst.offset.click; 2097 2098 if(this.instance._intersectsWith(this.instance.containerCache)) { 2099 innermostIntersecting = true; 2100 $.each(inst.sortables, function () { 2101 this.instance.positionAbs = inst.positionAbs; 2102 this.instance.helperProportions = inst.helperProportions; 2103 this.instance.offset.click = inst.offset.click; 2104 if (this != thisSortable 2105 && this.instance._intersectsWith(this.instance.containerCache) 2106 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) 2107 innermostIntersecting = false; 2108 return innermostIntersecting; 2109 }); 2110 } 2111 2112 2113 if(innermostIntersecting) { 2114 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 2115 if(!this.instance.isOver) { 2116 2117 this.instance.isOver = 1; 2118 //Now we fake the start of dragging for the sortable instance, 2119 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 2120 //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) 2121 this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); 2122 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 2123 this.instance.options.helper = function() { return ui.helper[0]; }; 2124 2125 event.target = this.instance.currentItem[0]; 2126 this.instance._mouseCapture(event, true); 2127 this.instance._mouseStart(event, true, true); 2128
2129 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 2130 this.instance.offset.click.top = inst.offset.click.top; 2131 this.instance.offset.click.left = inst.offset.click.left; 2132 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 2133 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 2134 2135 inst._trigger("toSortable", event); 2136 inst.dropped = this.instance.element; //draggable revert needs that 2137 //hack so receive/update callbacks work (mostly) 2138 inst.currentItem = inst.element; 2139 this.instance.fromOutside = inst; 2140 2141 } 2142 2143 //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 2144 if(this.instance.currentItem) this.instance._mouseDrag(event); 2145 2146 } else { 2147 2148 //If it doesn't intersect with the sortable, and it intersected before, 2149 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2150 if(this.instance.isOver) { 2151 2152 this.instance.isOver = 0; 2153 this.instance.cancelHelperRemoval = true; 2154 2155 //Prevent reverting on this forced stop 2156 this.instance.options.revert = false; 2157 2158 // The out event needs to be triggered independently 2159 this.instance._trigger('out', event, this.instance._uiHash(this.instance)); 2160 2161 this.instance._mouseStop(event, true); 2162 this.instance.options.helper = this.instance.options._helper; 2163 2164 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2165 this.instance.currentItem.remove(); 2166 if(this.instance.placeholder) this.instance.placeholder.remove(); 2167 2168 inst._trigger("fromSortable", event); 2169 inst.dropped = false; //draggable revert needs that 2170 } 2171 2172 }; 2173 2174 }); 2175 2176 } 2177}); 2178 2179$.ui.plugin.add("draggable", "cursor", { 2180 start: function(event, ui) { 2181 var t = $('body'), o = $(this).data('draggable').options; 2182 if (t.css("cursor")) o._cursor = t.css("cursor"); 2183 t.css("cursor", o.cursor); 2184 }, 2185 stop: function(event, ui) { 2186 var o = $(this).data('draggable').options; 2187 if (o._cursor) $('body').css("cursor", o._cursor); 2188 } 2189}); 2190 2191$.ui.plugin.add("draggable", "opacity", { 2192 start: function(event, ui) { 2193 var t = $(ui.helper), o = $(this).data('draggable').options; 2194 if(t.css("opacity")) o._opacity = t.css("opacity"); 2195 t.css('opacity', o.opacity); 2196 }, 2197 stop: function(event, ui) { 2198 var o = $(this).data('draggable').options; 2199 if(o._opacity) $(ui.helper).css('opacity', o._opacity); 2200 } 2201}); 2202 2203$.ui.plugin.add("draggable", "scroll", { 2204 start: function(event, ui) { 2205 var i = $(this).data("draggable"); 2206 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 2207 }, 2208 drag: function(event, ui) { 2209 2210 var i = $(this).data("draggable"), o = i.options, scrolled = false; 2211 2212 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 2213 2214 if(!o.axis || o.axis != 'x') { 2215 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 2216 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 2217 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 2218 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 2219 } 2220 2221 if(!o.axis || o.axis != 'y') { 2222 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 2223 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 2224 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 2225 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 2226 } 2227 2228 } else { 2229 2230 if(!o.axis || o.axis != 'x') { 2231 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 2232 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2233 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 2234 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2235 } 2236 2237 if(!o.axis || o.axis != 'y') { 2238 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 2239 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2240 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 2241 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2242 } 2243 2244 } 2245 2246 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 2247 $.ui.ddmanager.prepareOffsets(i, event); 2248 2249 } 2250}); 2251 2252$.ui.plugin.add("draggable", "snap", { 2253 start: function(event, ui) { 2254 2255 var i = $(this).data("draggable"), o = i.options; 2256 i.snapElements = []; 2257 2258 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { 2259 var $t = $(this); var $o = $t.offset(); 2260 if(this != i.element[0]) i.snapElements.push({ 2261 item: this, 2262 width: $t.outerWidth(), height: $t.outerHeight(), 2263 top: $o.top, left: $o.left 2264 }); 2265 }); 2266 2267 }, 2268 drag: function(event, ui) { 2269 2270 var inst = $(this).data("draggable"), o = inst.options; 2271 var d = o.snapTolerance; 2272 2273 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2274 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2275 2276 for (var i = inst.snapElements.length - 1; i >= 0; i--){ 2277 2278 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 2279 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 2280 2281 //Yes, I know, this is insane ;) 2282 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))) { 2283 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 }))); 2284 inst.snapElements[i].snapping = false; 2285 continue; 2286 } 2287 2288 if(o.snapMode != 'inner') { 2289 var ts = Math.abs(t - y2) <= d; 2290 var bs = Math.abs(b - y1) <= d; 2291 var ls = Math.abs(l - x2) <= d; 2292 var rs = Math.abs(r - x1) <= d; 2293 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2294 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2295 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2296 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2297 } 2298 2299 var first = (ts || bs || ls || rs); 2300 2301 if(o.snapMode != 'outer') { 2302 var ts = Math.abs(t - y1) <= d; 2303 var bs = Math.abs(b - y2) <= d; 2304 var ls = Math.abs(l - x1) <= d; 2305 var rs = Math.abs(r - x2) <= d; 2306 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2307 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2308 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2309 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2310 } 2311 2312 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 2313 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2314 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2315 2316 }; 2317 2318 } 2319}); 2320 2321$.ui.plugin.add("draggable", "stack", { 2322 start: function(event, ui) { 2323 2324 var o = $(this).data("draggable").options; 2325 2326 var group = $.makeArray($(o.stack)).sort(function(a,b) { 2327 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 2328 }); 2329 if (!group.length) { return; } 2330 2331 var min = parseInt(group[0].style.zIndex) || 0; 2332 $(group).each(function(i) { 2333 this.style.zIndex = min + i; 2334 }); 2335 2336 this[0].style.zIndex = min + group.length; 2337 2338 } 2339}); 2340 2341$.ui.plugin.add("draggable", "zIndex", { 2342 start: function(event, ui) { 2343 var t = $(ui.helper), o = $(this).data("draggable").options; 2344 if(t.css("zIndex")) o._zIndex = t.css("zIndex"); 2345 t.css('zIndex', o.zIndex); 2346 }, 2347 stop: function(event, ui) { 2348 var o = $(this).data("draggable").options; 2349 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); 2350 } 2351}); 2352 2353})(jQuery); 2354(function( $, undefined ) { 2355 2356$.widget("ui.droppable", { 2357 version: "1.9.2", 2358 widgetEventPrefix: "drop", 2359 options: { 2360 accept: '*',
2361 activeClass: false, 2362 addClasses: true, 2363 greedy: false, 2364 hoverClass: false, 2365 scope: 'default', 2366 tolerance: 'intersect' 2367 }, 2368 _create: function() { 2369 2370 var o = this.options, accept = o.accept; 2371 this.isover = 0; this.isout = 1; 2372 2373 this.accept = $.isFunction(accept) ? accept : function(d) { 2374 return d.is(accept); 2375 }; 2376 2377 //Store the droppable's proportions 2378 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 2379 2380 // Add the reference and positions to the manager 2381 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 2382 $.ui.ddmanager.droppables[o.scope].push(this); 2383 2384 (o.addClasses && this.element.addClass("ui-droppable")); 2385 2386 }, 2387 2388 _destroy: function() { 2389 var drop = $.ui.ddmanager.droppables[this.options.scope]; 2390 for ( var i = 0; i < drop.length; i++ ) 2391 if ( drop[i] == this ) 2392 drop.splice(i, 1); 2393 2394 this.element.removeClass("ui-droppable ui-droppable-disabled"); 2395 }, 2396 2397 _setOption: function(key, value) { 2398 2399 if(key == 'accept') { 2400 this.accept = $.isFunction(value) ? value : function(d) { 2401 return d.is(value); 2402 }; 2403 } 2404 $.Widget.prototype._setOption.apply(this, arguments); 2405 }, 2406 2407 _activate: function(event) { 2408 var draggable = $.ui.ddmanager.current; 2409 if(this.options.activeClass) this.element.addClass(this.options.activeClass); 2410 (draggable && this._trigger('activate', event, this.ui(draggable))); 2411 }, 2412 2413 _deactivate: function(event) { 2414 var draggable = $.ui.ddmanager.current; 2415 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 2416 (draggable && this._trigger('deactivate', event, this.ui(draggable))); 2417 }, 2418 2419 _over: function(event) { 2420 2421 var draggable = $.ui.ddmanager.current; 2422 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 2423 2424 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2425 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); 2426 this._trigger('over', event, this.ui(draggable)); 2427 } 2428 2429 }, 2430 2431 _out: function(event) { 2432 2433 var draggable = $.ui.ddmanager.current; 2434 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 2435 2436 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2437 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 2438 this._trigger('out', event, this.ui(draggable)); 2439 } 2440 2441 }, 2442 2443 _drop: function(event,custom) { 2444 2445 var draggable = custom || $.ui.ddmanager.current; 2446 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 2447 2448 var childrenIntersection = false; 2449 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 2450 var inst = $.data(this, 'droppable'); 2451 if( 2452 inst.options.greedy 2453 && !inst.options.disabled 2454 && inst.options.scope == draggable.options.scope 2455 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) 2456 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2457 ) { childrenIntersection = true; return false; } 2458 }); 2459 if(childrenIntersection) return false; 2460 2461 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2462 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 2463 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 2464 this._trigger('drop', event, this.ui(draggable)); 2465 return this.element; 2466 } 2467 2468 return false; 2469 2470 }, 2471 2472 ui: function(c) { 2473 return { 2474 draggable: (c.currentItem || c.element), 2475 helper: c.helper, 2476 position: c.position, 2477 offset: c.positionAbs 2478 }; 2479 } 2480 2481}); 2482 2483$.ui.intersect = function(draggable, droppable, toleranceMode) { 2484 2485 if (!droppable.offset) return false; 2486 2487 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2488 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 2489 var l = droppable.offset.left, r = l + droppable.proportions.width, 2490 t = droppable.offset.top, b = t + droppable.proportions.height; 2491 2492 switch (toleranceMode) { 2493 case 'fit': 2494 return (l <= x1 && x2 <= r 2495 && t <= y1 && y2 <= b); 2496 break; 2497 case 'intersect': 2498 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 2499 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 2500 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 2501 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2502 break; 2503 case 'pointer': 2504 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 2505 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 2506 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 2507 return isOver; 2508 break; 2509 case 'touch': 2510 return ( 2511 (y1 >= t && y1 <= b) || // Top edge touching 2512 (y2 >= t && y2 <= b) || // Bottom edge touching 2513 (y1 < t && y2 > b) // Surrounded vertically 2514 ) && ( 2515 (x1 >= l && x1 <= r) || // Left edge touching 2516 (x2 >= l && x2 <= r) || // Right edge touching 2517 (x1 < l && x2 > r) // Surrounded horizontally 2518 ); 2519 break; 2520 default: 2521 return false; 2522 break; 2523 } 2524 2525}; 2526 2527/* 2528 This manager tracks offsets of draggables and droppables 2529*/ 2530$.ui.ddmanager = { 2531 current: null, 2532 droppables: { 'default': [] }, 2533 prepareOffsets: function(t, event) { 2534 2535 var m = $.ui.ddmanager.droppables[t.options.scope] || []; 2536 var type = event ? event.type : null; // workaround for #2317 2537 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 2538 2539 droppablesLoop: for (var i = 0; i < m.length; i++) { 2540 2541 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted 2542 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 2543 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue 2544 2545 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 2546 2547 m[i].offset = m[i].element.offset(); 2548 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2549 2550 } 2551 2552 }, 2553 drop: function(draggable, event) { 2554 2555 var dropped = false;
2556 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2557 2558 if(!this.options) return; 2559 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 2560 dropped = this._drop.call(this, event) || dropped; 2561 2562 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2563 this.isout = 1; this.isover = 0; 2564 this._deactivate.call(this, event); 2565 } 2566 2567 }); 2568 return dropped; 2569 2570 }, 2571 dragStart: function( draggable, event ) { 2572 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2573 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2574 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2575 }); 2576 }, 2577 drag: function(draggable, event) { 2578 2579 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2580 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 2581 2582 //Run through all droppables and check their positions based on specific tolerance options 2583 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2584 2585 if(this.options.disabled || this.greedyChild || !this.visible) return; 2586 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 2587 2588 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 2589 if(!c) return; 2590 2591 var parentInstance; 2592 if (this.options.greedy) { 2593 // find droppable parents with same scope 2594 var scope = this.options.scope; 2595 var parent = this.element.parents(':data(droppable)').filter(function () { 2596 return $.data(this, 'droppable').options.scope === scope; 2597 }); 2598 2599 if (parent.length) { 2600 parentInstance = $.data(parent[0], 'droppable'); 2601 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 2602 } 2603 } 2604 2605 // we just moved into a greedy child 2606 if (parentInstance && c == 'isover') { 2607 parentInstance['isover'] = 0; 2608 parentInstance['isout'] = 1; 2609 parentInstance._out.call(parentInstance, event); 2610 } 2611 2612 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 2613 this[c == "isover" ? "_over" : "_out"].call(this, event); 2614 2615 // we just moved out of a greedy child 2616 if (parentInstance && c == 'isout') { 2617 parentInstance['isout'] = 0; 2618 parentInstance['isover'] = 1; 2619 parentInstance._over.call(parentInstance, event); 2620 } 2621 }); 2622 2623 }, 2624 dragStop: function( draggable, event ) { 2625 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2626 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2627 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 2628 } 2629}; 2630 2631})(jQuery); 2632(function( $, undefined ) { 2633 2634$.widget("ui.resizable", $.ui.mouse, { 2635 version: "1.9.2", 2636 widgetEventPrefix: "resize", 2637 options: { 2638 alsoResize: false, 2639 animate: false, 2640 animateDuration: "slow", 2641 animateEasing: "swing", 2642 aspectRatio: false, 2643 autoHide: false, 2644 containment: false, 2645 ghost: false, 2646 grid: false, 2647 handles: "e,s,se", 2648 helper: false, 2649 maxHeight: null, 2650 maxWidth: null, 2651 minHeight: 10, 2652 minWidth: 10, 2653 zIndex: 1000 2654 }, 2655 _create: function() { 2656 2657 var that = this, o = this.options; 2658 this.element.addClass("ui-resizable"); 2659 2660 $.extend(this, { 2661 _aspectRatio: !!(o.aspectRatio), 2662 aspectRatio: o.aspectRatio, 2663 originalElement: this.element, 2664 _proportionallyResizeElements: [], 2665 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null 2666 }); 2667 2668 //Wrap the element if it cannot hold child nodes 2669 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2670 2671 //Create a wrapper element and set the wrapper to the new current internal element 2672 this.element.wrap( 2673 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ 2674 position: this.element.css('position'), 2675 width: this.element.outerWidth(), 2676 height: this.element.outerHeight(), 2677 top: this.element.css('top'), 2678 left: this.element.css('left') 2679 }) 2680 ); 2681 2682 //Overwrite the original this.element 2683 this.element = this.element.parent().data( 2684 "resizable", this.element.data('resizable') 2685 ); 2686 2687 this.elementIsWrapper = true; 2688 2689 //Move margins to the wrapper 2690 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2691 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2692 2693 //Prevent Safari textarea resize 2694 this.originalResizeStyle = this.originalElement.css('resize'); 2695 this.originalElement.css('resize', 'none'); 2696 2697 //Push the actual element to our proportionallyResize internal array 2698 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 2699 2700 // avoid IE jump (hard set the margin) 2701 this.originalElement.css({ margin: this.originalElement.css('margin') }); 2702 2703 // fix handlers offset 2704 this._proportionallyResize(); 2705 2706 } 2707 2708 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' });
2709 if(this.handles.constructor == String) { 2710 2711 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; 2712 var n = this.handles.split(","); this.handles = {}; 2713 2714 for(var i = 0; i < n.length; i++) { 2715 2716 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; 2717 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 2718 2719 // Apply zIndex to all handles - see #7960 2720 axis.css({ zIndex: o.zIndex }); 2721 2722 //TODO : What's going on here? 2723 if ('se' == handle) { 2724 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); 2725 }; 2726 2727 //Insert into internal handles object and append to element 2728 this.handles[handle] = '.ui-resizable-'+handle; 2729 this.element.append(axis); 2730 } 2731 2732 } 2733 2734 this._renderAxis = function(target) { 2735 2736 target = target || this.element; 2737 2738 for(var i in this.handles) { 2739 2740 if(this.handles[i].constructor == String) 2741 this.handles[i] = $(this.handles[i], this.element).show(); 2742 2743 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2744 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2745 2746 var axis = $(this.handles[i], this.element), padWrapper = 0; 2747 2748 //Checking the correct pad and border 2749 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2750 2751 //The padding type i have to apply... 2752 var padPos = [ 'padding', 2753 /ne|nw|n/.test(i) ? 'Top' : 2754 /se|sw|s/.test(i) ? 'Bottom' : 2755 /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 2756 2757 target.css(padPos, padWrapper); 2758 2759 this._proportionallyResize(); 2760 2761 } 2762 2763 //TODO: What's that good for? There's not anything to be executed left 2764 if(!$(this.handles[i]).length) 2765 continue; 2766 2767 } 2768 }; 2769 2770 //TODO: make renderAxis a prototype function 2771 this._renderAxis(this.element); 2772 2773 this._handles = $('.ui-resizable-handle', this.element) 2774 .disableSelection(); 2775 2776 //Matching axis name 2777 this._handles.mouseover(function() { 2778 if (!that.resizing) { 2779 if (this.className) 2780 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2781 //Axis, default = se 2782 that.axis = axis && axis[1] ? axis[1] : 'se'; 2783 } 2784 }); 2785 2786 //If we want to auto hide the elements 2787 if (o.autoHide) { 2788 this._handles.hide(); 2789 $(this.element) 2790 .addClass("ui-resizable-autohide") 2791 .mouseenter(function() { 2792 if (o.disabled) return; 2793 $(this).removeClass("ui-resizable-autohide"); 2794 that._handles.show(); 2795 }) 2796 .mouseleave(function(){ 2797 if (o.disabled) return; 2798 if (!that.resizing) { 2799 $(this).addClass("ui-resizable-autohide"); 2800 that._handles.hide(); 2801 } 2802 }); 2803 } 2804 2805 //Initialize the mouse interaction 2806 this._mouseInit(); 2807 2808 }, 2809 2810 _destroy: function() { 2811 2812 this._mouseDestroy(); 2813 2814 var _destroy = function(exp) { 2815 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2816 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 2817 }; 2818 2819 //TODO: Unwrap at same DOM position 2820 if (this.elementIsWrapper) { 2821 _destroy(this.element); 2822 var wrapper = this.element; 2823 this.originalElement.css({ 2824 position: wrapper.css('position'), 2825 width: wrapper.outerWidth(), 2826 height: wrapper.outerHeight(), 2827 top: wrapper.css('top'), 2828 left: wrapper.css('left') 2829 }).insertAfter( wrapper ); 2830 wrapper.remove(); 2831 } 2832 2833 this.originalElement.css('resize', this.originalResizeStyle); 2834 _destroy(this.originalElement); 2835 2836 return this; 2837 }, 2838 2839 _mouseCapture: function(event) { 2840 var handle = false; 2841 for (var i in this.handles) { 2842 if ($(this.handles[i])[0] == event.target) { 2843 handle = true; 2844 } 2845 } 2846 2847 return !this.options.disabled && handle; 2848 }, 2849 2850 _mouseStart: function(event) { 2851 2852 var o = this.options, iniPos = this.element.position(), el = this.element; 2853 2854 this.resizing = true; 2855 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 2856 2857 // bugfix for http://dev.jquery.com/ticket/1749 2858 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 2859 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); 2860 } 2861 2862 this._renderProxy(); 2863 2864 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 2865 2866 if (o.containment) { 2867 curleft += $(o.containment).scrollLeft() || 0; 2868 curtop += $(o.containment).scrollTop() || 0; 2869 } 2870 2871 //Store needed variables 2872 this.offset = this.helper.offset(); 2873 this.position = { left: curleft, top: curtop }; 2874 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2875 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2876 this.originalPosition = { left: curleft, top: curtop }; 2877 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2878 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2879 2880 //Aspect Ratio 2881 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2882 2883 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 2884 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 2885 2886 el.addClass("ui-resizable-resizing"); 2887 this._propagate("start", event); 2888 return true; 2889 }, 2890 2891 _mouseDrag: function(event) { 2892 2893 //Increase performance, avoid regex 2894 var el = this.helper, o = this.options, props = {}, 2895 that = this, smp = this.originalMousePosition, a = this.axis; 2896 2897 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; 2898 var trigger = this._change[a]; 2899 if (!trigger) return false; 2900 2901 // Calculate the attrs that will be change 2902 var data = trigger.apply(this, [event, dx, dy]); 2903 2904 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2905 this._updateVirtualBoundaries(event.shiftKey); 2906 if (this._aspectRatio || event.shiftKey) 2907 data = this._updateRatio(data, event); 2908 2909 data = this._respectSize(data, event); 2910 2911 // plugins callbacks need to be called first 2912 this._propagate("resize", event); 2913 2914 el.css({ 2915 top: this.position.top + "px", left: this.position.left + "px", 2916 width: this.size.width + "px", height: this.size.height + "px" 2917 }); 2918 2919 if (!this._helper && this._proportionallyResizeElements.length) 2920 this._proportionallyResize(); 2921 2922 this._updateCache(data); 2923 2924 // calling the user callback at the end 2925 this._trigger('resize', event, this.ui()); 2926 2927 return false; 2928 }, 2929 2930 _mouseStop: function(event) { 2931 2932 this.resizing = false; 2933 var o = this.options, that = this; 2934 2935 if(this._helper) { 2936 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2937 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2938 soffsetw = ista ? 0 : that.sizeDiff.width; 2939 2940 var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, 2941 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 2942 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 2943 2944 if (!o.animate) 2945 this.element.css($.extend(s, { top: top, left: left })); 2946 2947 that.helper.height(that.size.height); 2948 that.helper.width(that.size.width); 2949
2950 if (this._helper && !o.animate) this._proportionallyResize(); 2951 } 2952 2953 $('body').css('cursor', 'auto'); 2954 2955 this.element.removeClass("ui-resizable-resizing"); 2956 2957 this._propagate("stop", event); 2958 2959 if (this._helper) this.helper.remove(); 2960 return false; 2961 2962 }, 2963 2964 _updateVirtualBoundaries: function(forceAspectRatio) { 2965 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; 2966 2967 b = { 2968 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2969 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2970 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2971 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2972 }; 2973 2974 if(this._aspectRatio || forceAspectRatio) { 2975 // We want to create an enclosing box whose aspect ration is the requested one 2976 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2977 pMinWidth = b.minHeight * this.aspectRatio; 2978 pMinHeight = b.minWidth / this.aspectRatio; 2979 pMaxWidth = b.maxHeight * this.aspectRatio; 2980 pMaxHeight = b.maxWidth / this.aspectRatio; 2981 2982 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; 2983 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; 2984 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; 2985 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; 2986 } 2987 this._vBoundaries = b; 2988 }, 2989 2990 _updateCache: function(data) { 2991 var o = this.options; 2992 this.offset = this.helper.offset(); 2993 if (isNumber(data.left)) this.position.left = data.left; 2994 if (isNumber(data.top)) this.position.top = data.top; 2995 if (isNumber(data.height)) this.size.height = data.height; 2996 if (isNumber(data.width)) this.size.width = data.width; 2997 }, 2998 2999 _updateRatio: function(data, event) { 3000 3001 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 3002 3003 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); 3004 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); 3005 3006 if (a == 'sw') { 3007 data.left = cpos.left + (csize.width - data.width); 3008 data.top = null; 3009 } 3010 if (a == 'nw') { 3011 data.top = cpos.top + (csize.height - data.height); 3012 data.left = cpos.left + (csize.width - data.width); 3013 } 3014 3015 return data; 3016 }, 3017 3018 _respectSize: function(data, event) { 3019 3020 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, 3021 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3022 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 3023 3024 if (isminw) data.width = o.minWidth; 3025 if (isminh) data.height = o.minHeight; 3026 if (ismaxw) data.width = o.maxWidth; 3027 if (ismaxh) data.height = o.maxHeight; 3028 3029 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 3030 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3031 3032 if (isminw && cw) data.left = dw - o.minWidth; 3033 if (ismaxw && cw) data.left = dw - o.maxWidth; 3034 if (isminh && ch) data.top = dh - o.minHeight; 3035 if (ismaxh && ch) data.top = dh - o.maxHeight; 3036 3037 // fixing jump error on top/left - bug #2330 3038 var isNotwh = !data.width && !data.height; 3039 if (isNotwh && !data.left && data.top) data.top = null; 3040 else if (isNotwh && !data.top && data.left) data.left = null; 3041 3042 return data; 3043 }, 3044 3045 _proportionallyResize: function() { 3046 3047 var o = this.options; 3048 if (!this._proportionallyResizeElements.length) return; 3049 var element = this.helper || this.element; 3050 3051 for (var i=0; i < this._proportionallyResizeElements.length; i++) { 3052 3053 var prel = this._proportionallyResizeElements[i]; 3054 3055 if (!this.borderDif) { 3056 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 3057 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 3058 3059 this.borderDif = $.map(b, function(v, i) { 3060 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; 3061 return border + padding; 3062 }); 3063 } 3064 3065 prel.css({ 3066 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 3067 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 3068 }); 3069 3070 }; 3071 3072 }, 3073 3074 _renderProxy: function() { 3075 3076 var el = this.element, o = this.options; 3077 this.elementOffset = el.offset(); 3078 3079 if(this._helper) { 3080 3081 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 3082 3083 // fix ie6 offset TODO: This seems broken 3084 var ie6offset = ($.ui.ie6 ? 1 : 0), 3085 pxyoffset = ( $.ui.ie6 ? 2 : -1 ); 3086 3087 this.helper.addClass(this._helper).css({ 3088 width: this.element.outerWidth() + pxyoffset, 3089 height: this.element.outerHeight() + pxyoffset, 3090 position: 'absolute', 3091 left: this.elementOffset.left - ie6offset +'px', 3092 top: this.elementOffset.top - ie6offset +'px', 3093 zIndex: ++o.zIndex //TODO: Don't modify option 3094 }); 3095 3096 this.helper 3097 .appendTo("body") 3098 .disableSelection(); 3099 3100 } else { 3101 this.helper = this.element; 3102 } 3103 3104 }, 3105 3106 _change: { 3107 e: function(event, dx, dy) { 3108 return { width: this.originalSize.width + dx }; 3109 }, 3110 w: function(event, dx, dy) { 3111 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 3112 return { left: sp.left + dx, width: cs.width - dx }; 3113 }, 3114 n: function(event, dx, dy) { 3115 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 3116 return { top: sp.top + dy, height: cs.height - dy }; 3117 }, 3118 s: function(event, dx, dy) { 3119 return { height: this.originalSize.height + dy }; 3120 }, 3121 se: function(event, dx, dy) { 3122 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3123 }, 3124 sw: function(event, dx, dy) { 3125 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3126 }, 3127 ne: function(event, dx, dy) { 3128 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3129 }, 3130 nw: function(event, dx, dy) { 3131 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3132 } 3133 }, 3134
vendor: 4,218 bytes, lines 3135-3270
3135 _propagate: function(n, event) { 3136 $.ui.plugin.call(this, n, [event, this.ui()]); 3137 (n != "resize" && this._trigger(n, event, this.ui())); 3138 }, 3139 3140 plugins: {}, 3141 3142 ui: function() { 3143 return { 3144 originalElement: this.originalElement, 3145 element: this.element, 3146 helper: this.helper, 3147 position: this.position, 3148 size: this.size, 3149 originalSize: this.originalSize, 3150 originalPosition: this.originalPosition 3151 }; 3152 } 3153 3154}); 3155 3156/* 3157 * Resizable Extensions 3158 */ 3159 3160$.ui.plugin.add("resizable", "alsoResize", { 3161 3162 start: function (event, ui) { 3163 var that = $(this).data("resizable"), o = that.options; 3164 3165 var _store = function (exp) { 3166 $(exp).each(function() { 3167 var el = $(this); 3168 el.data("resizable-alsoresize", { 3169 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3170 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) 3171 }); 3172 }); 3173 }; 3174 3175 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 3176 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3177 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3178 }else{ 3179 _store(o.alsoResize); 3180 } 3181 }, 3182 3183 resize: function (event, ui) { 3184 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; 3185 3186 var delta = { 3187 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3188 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3189 }, 3190 3191 _alsoResize = function (exp, c) { 3192 $(exp).each(function() { 3193 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 3194 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; 3195 3196 $.each(css, function (i, prop) { 3197 var sum = (start[prop]||0) + (delta[prop]||0); 3198 if (sum && sum >= 0) 3199 style[prop] = sum || null; 3200 }); 3201 3202 el.css(style); 3203 }); 3204 }; 3205 3206 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { 3207 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3208 }else{ 3209 _alsoResize(o.alsoResize); 3210 } 3211 }, 3212 3213 stop: function (event, ui) { 3214 $(this).removeData("resizable-alsoresize"); 3215 } 3216}); 3217 3218$.ui.plugin.add("resizable", "animate", { 3219 3220 stop: function(event, ui) { 3221 var that = $(this).data("resizable"), o = that.options; 3222 3223 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3224 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 3225 soffsetw = ista ? 0 : that.sizeDiff.width; 3226 3227 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3228 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 3229 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 3230 3231 that.element.animate( 3232 $.extend(style, top && left ? { top: top, left: left } : {}), { 3233 duration: o.animateDuration, 3234 easing: o.animateEasing, 3235 step: function() { 3236 3237 var data = { 3238 width: parseInt(that.element.css('width'), 10), 3239 height: parseInt(that.element.css('height'), 10), 3240 top: parseInt(that.element.css('top'), 10), 3241 left: parseInt(that.element.css('left'), 10) 3242 }; 3243 3244 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); 3245 3246 // propagating resize, and updating values for each animation step 3247 that._updateCache(data); 3248 that._propagate("resize", event); 3249 3250 } 3251 } 3252 ); 3253 } 3254 3255}); 3256 3257$.ui.plugin.add("resizable", "containment", { 3258 3259 start: function(event, ui) { 3260 var that = $(this).data("resizable"), o = that.options, el = that.element; 3261 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 3262 if (!ce) return; 3263 3264 that.containerElement = $(ce); 3265 3266 if (/document/.test(oc) || oc == document) { 3267 that.containerOffset = { left: 0, top: 0 }; 3268 that.containerPosition = { left: 0, top: 0 }; 3269 3270 that.parentData = {
3271 element: $(document), left: 0, top: 0, 3272 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 3273 }; 3274 } 3275 3276 // i'm a node, so compute top, left, right, bottom 3277 else { 3278 var element = $(ce), p = []; 3279 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 3280 3281 that.containerOffset = element.offset(); 3282 that.containerPosition = element.position(); 3283 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 3284 3285 var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, 3286 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3287 3288 that.parentData = { 3289 element: ce, left: co.left, top: co.top, width: width, height: height 3290 }; 3291 } 3292 }, 3293 3294 resize: function(event, ui) { 3295 var that = $(this).data("resizable"), o = that.options, 3296 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, 3297 pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; 3298 3299 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 3300 3301 if (cp.left < (that._helper ? co.left : 0)) { 3302 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3303 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 3304 that.position.left = o.helper ? co.left : 0; 3305 } 3306 3307 if (cp.top < (that._helper ? co.top : 0)) { 3308 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3309 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 3310 that.position.top = that._helper ? co.top : 0; 3311 } 3312 3313 that.offset.left = that.parentData.left+that.position.left; 3314 that.offset.top = that.parentData.top+that.position.top; 3315 3316 var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), 3317 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3318 3319 var isParent = that.containerElement.get(0) == that.element.parent().get(0), 3320 isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); 3321 3322 if(isParent && isOffsetRelative) woset -= that.parentData.left; 3323 3324 if (woset + that.size.width >= that.parentData.width) { 3325 that.size.width = that.parentData.width - woset; 3326 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 3327 } 3328 3329 if (hoset + that.size.height >= that.parentData.height) { 3330 that.size.height = that.parentData.height - hoset; 3331 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 3332 } 3333 }, 3334 3335 stop: function(event, ui){ 3336 var that = $(this).data("resizable"), o = that.options, cp = that.position, 3337 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; 3338 3339 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; 3340 3341 if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) 3342 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3343 3344 if (that._helper && !o.animate && (/static/).test(ce.css('position'))) 3345 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3346 3347 } 3348}); 3349 3350$.ui.plugin.add("resizable", "ghost", { 3351 3352 start: function(event, ui) { 3353 3354 var that = $(this).data("resizable"), o = that.options, cs = that.size; 3355 3356 that.ghost = that.originalElement.clone(); 3357 that.ghost 3358 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3359 .addClass('ui-resizable-ghost') 3360 .addClass(typeof o.ghost == 'string' ? o.ghost : ''); 3361 3362 that.ghost.appendTo(that.helper); 3363 3364 }, 3365 3366 resize: function(event, ui){ 3367 var that = $(this).data("resizable"), o = that.options; 3368 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.
3368size.width }); 3369 }, 3370 3371 stop: function(event, ui){ 3372 var that = $(this).data("resizable"), o = that.options; 3373 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); 3374 } 3375 3376}); 3377 3378$.ui.plugin.add("resizable", "grid", { 3379 3380 resize: function(event, ui) { 3381 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; 3382 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 3383 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); 3384 3385 if (/^(se|s|e)$/.test(a)) { 3386 that.size.width = os.width + ox; 3387 that.size.height = os.height + oy; 3388 } 3389 else if (/^(ne)$/.test(a)) { 3390 that.size.width = os.width + ox; 3391 that.size.height = os.height + oy; 3392 that.position.top = op.top - oy; 3393 } 3394 else if (/^(sw)$/.test(a)) { 3395 that.size.width = os.width + ox; 3396 that.size.height = os.height + oy; 3397 that.position.left = op.left - ox; 3398 } 3399 else { 3400 that.size.width = os.width + ox; 3401 that.size.height = os.height + oy; 3402 that.position.top = op.top - oy; 3403 that.position.left = op.left - ox; 3404 } 3405 } 3406 3407}); 3408 3409var num = function(v) { 3410 return parseInt(v, 10) || 0; 3411}; 3412 3413var isNumber = function(value) { 3414 return !isNaN(parseInt(value, 10)); 3415}; 3416 3417})(jQuery); 3418(function( $, undefined ) { 3419 3420$.widget("ui.selectable", $.ui.mouse, { 3421 version: "1.9.2", 3422 options: { 3423 appendTo: 'body', 3424 autoRefresh: true, 3425 distance: 0, 3426 filter: '*', 3427 tolerance: 'touch' 3428 }, 3429 _create: function() { 3430 var that = this; 3431 3432 this.element.addClass("ui-selectable"); 3433 3434 this.dragged = false; 3435 3436 // cache selectee children based on filter 3437 var selectees; 3438 this.refresh = function() { 3439 selectees = $(that.options.filter, that.element[0]); 3440 selectees.addClass("ui-selectee"); 3441 selectees.each(function() { 3442 var $this = $(this); 3443 var pos = $this.offset(); 3444 $.data(this, "selectable-item", { 3445 element: this, 3446 $element: $this, 3447 left: pos.left, 3448 top: pos.top, 3449 right: pos.left + $this.outerWidth(), 3450 bottom: pos.top + $this.outerHeight(), 3451 startselected: false, 3452 selected: $this.hasClass('ui-selected'), 3453 selecting: $this.hasClass('ui-selecting'), 3454 unselecting: $this.hasClass('ui-unselecting') 3455 }); 3456 }); 3457 }; 3458 this.refresh(); 3459 3460 this.selectees = selectees.addClass("ui-selectee"); 3461 3462 this._mouseInit(); 3463 3464 this.helper = $("<div class='ui-selectable-helper'></div>"); 3465 }, 3466 3467 _destroy: function() { 3468 this.selectees 3469 .removeClass("ui-selectee") 3470 .removeData("selectable-item"); 3471 this.element 3472 .removeClass("ui-selectable ui-selectable-disabled"); 3473 this._mouseDestroy(); 3474 }, 3475 3476 _mouseStart: function(event) { 3477 var that = this; 3478 3479 this.opos = [event.pageX, event.pageY]; 3480 3481 if (this.options.disabled) 3482 return; 3483 3484 var options = this.options; 3485 3486 this.selectees = $(options.filter, this.element[0]); 3487 3488 this._trigger("start", event); 3489 3490 $(options.appendTo).append(this.helper); 3491 // position helper (lasso) 3492 this.helper.css({ 3493 "left": event.clientX, 3494 "top": event.clientY, 3495 "width": 0, 3496 "height": 0 3497 }); 3498 3499 if (options.autoRefresh) { 3500 this.refresh(); 3501 } 3502 3503 this.selectees.filter('.ui-selected').each(function() { 3504 var selectee = $.data(this, "selectable-item"); 3505 selectee.startselected = true; 3506 if (!event.metaKey && !event.ctrlKey) { 3507 selectee.$element.removeClass('ui-selected'); 3508 selectee.selected = false; 3509 selectee.$element.addClass('ui-unselecting'); 3510 selectee.unselecting = true; 3511 // selectable UNSELECTING callback 3512 that._trigger("unselecting", event, { 3513 unselecting: selectee.element 3514 }); 3515 } 3516 }); 3517 3518 $(event.target).parents().andSelf().each(function() { 3519 var selectee = $.data(this, "selectable-item"); 3520 if (selectee) { 3521 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); 3522 selectee.$element 3523 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3524 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3525 selectee.unselecting = !doSelect; 3526 selectee.selecting = doSelect; 3527 selectee.selected = doSelect; 3528 // selectable (UN)SELECTING callback 3529 if (doSelect) { 3530 that._trigger("selecting", event, { 3531 selecting: selectee.element 3532 });
vendor: 4,501 bytes, lines 3533-3701
3533 } else { 3534 that._trigger("unselecting", event, { 3535 unselecting: selectee.element 3536 }); 3537 } 3538 return false; 3539 } 3540 }); 3541 3542 }, 3543 3544 _mouseDrag: function(event) { 3545 var that = this; 3546 this.dragged = true; 3547 3548 if (this.options.disabled) 3549 return; 3550 3551 var options = this.options; 3552 3553 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 3554 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 3555 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 3556 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3557 3558 this.selectees.each(function() { 3559 var selectee = $.data(this, "selectable-item"); 3560 //prevent helper from being selected if appendTo: selectable 3561 if (!selectee || selectee.element == that.element[0]) 3562 return; 3563 var hit = false; 3564 if (options.tolerance == 'touch') { 3565 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3566 } else if (options.tolerance == 'fit') { 3567 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3568 } 3569 3570 if (hit) { 3571 // SELECT 3572 if (selectee.selected) { 3573 selectee.$element.removeClass('ui-selected'); 3574 selectee.selected = false; 3575 } 3576 if (selectee.unselecting) { 3577 selectee.$element.removeClass('ui-unselecting'); 3578 selectee.unselecting = false; 3579 } 3580 if (!selectee.selecting) { 3581 selectee.$element.addClass('ui-selecting'); 3582 selectee.selecting = true; 3583 // selectable SELECTING callback 3584 that._trigger("selecting", event, { 3585 selecting: selectee.element 3586 }); 3587 } 3588 } else { 3589 // UNSELECT 3590 if (selectee.selecting) { 3591 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3592 selectee.$element.removeClass('ui-selecting'); 3593 selectee.selecting = false; 3594 selectee.$element.addClass('ui-selected'); 3595 selectee.selected = true; 3596 } else { 3597 selectee.$element.removeClass('ui-selecting'); 3598 selectee.selecting = false; 3599 if (selectee.startselected) { 3600 selectee.$element.addClass('ui-unselecting'); 3601 selectee.unselecting = true; 3602 } 3603 // selectable UNSELECTING callback 3604 that._trigger("unselecting", event, { 3605 unselecting: selectee.element 3606 }); 3607 } 3608 } 3609 if (selectee.selected) { 3610 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3611 selectee.$element.removeClass('ui-selected'); 3612 selectee.selected = false; 3613 3614 selectee.$element.addClass('ui-unselecting'); 3615 selectee.unselecting = true; 3616 // selectable UNSELECTING callback 3617 that._trigger("unselecting", event, { 3618 unselecting: selectee.element 3619 }); 3620 } 3621 } 3622 } 3623 }); 3624 3625 return false; 3626 }, 3627 3628 _mouseStop: function(event) { 3629 var that = this; 3630 3631 this.dragged = false; 3632 3633 var options = this.options; 3634 3635 $('.ui-unselecting', this.element[0]).each(function() { 3636 var selectee = $.data(this, "selectable-item"); 3637 selectee.$element.removeClass('ui-unselecting'); 3638 selectee.unselecting = false; 3639 selectee.startselected = false; 3640 that._trigger("unselected", event, { 3641 unselected: selectee.element 3642 }); 3643 }); 3644 $('.ui-selecting', this.element[0]).each(function() { 3645 var selectee = $.data(this, "selectable-item"); 3646 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 3647 selectee.selecting = false; 3648 selectee.selected = true; 3649 selectee.startselected = true; 3650 that._trigger("selected", event, { 3651 selected: selectee.element 3652 }); 3653 }); 3654 this._trigger("stop", event); 3655 3656 this.helper.remove(); 3657 3658 return false; 3659 } 3660 3661}); 3662 3663})(jQuery); 3664(function( $, undefined ) { 3665 3666$.widget("ui.sortable", $.ui.mouse, { 3667 version: "1.9.2", 3668 widgetEventPrefix: "sort", 3669 ready: false, 3670 options: { 3671 appendTo: "parent", 3672 axis: false, 3673 connectWith: false, 3674 containment: false, 3675 cursor: 'auto', 3676 cursorAt: false, 3677 dropOnEmpty: true, 3678 forcePlaceholderSize: false, 3679 forceHelperSize: false, 3680 grid: false, 3681 handle: false, 3682 helper: "original", 3683 items: '> *', 3684 opacity: false, 3685 placeholder: false, 3686 revert: false, 3687 scroll: true, 3688 scrollSensitivity: 20, 3689 scrollSpeed: 20, 3690 scope: "default", 3691 tolerance: "intersect", 3692 zIndex: 1000 3693 }, 3694 _create: function() { 3695 3696 var o = this.options; 3697 this.containerCache = {}; 3698 this.element.addClass("ui-sortable"); 3699 3700 //Get the items 3701 this.refresh();
3702 3703 //Let's determine if the items are being displayed horizontally 3704 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; 3705 3706 //Let's determine the parent's offset 3707 this.offset = this.element.offset(); 3708 3709 //Initialize mouse events for interaction 3710 this._mouseInit(); 3711 3712 //We're ready to go 3713 this.ready = true 3714 3715 }, 3716 3717 _destroy: function() { 3718 this.element 3719 .removeClass("ui-sortable ui-sortable-disabled"); 3720 this._mouseDestroy(); 3721 3722 for ( var i = this.items.length - 1; i >= 0; i-- ) 3723 this.items[i].item.removeData(this.widgetName + "-item"); 3724 3725 return this; 3726 }, 3727 3728 _setOption: function(key, value){ 3729 if ( key === "disabled" ) { 3730 this.options[ key ] = value; 3731 3732 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3733 } else { 3734 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3735 $.Widget.prototype._setOption.apply(this, arguments); 3736 } 3737 }, 3738 3739 _mouseCapture: function(event, overrideHandle) { 3740 var that = this; 3741 3742 if (this.reverting) { 3743 return false; 3744 } 3745 3746 if(this.options.disabled || this.options.type == 'static') return false; 3747 3748 //We have to refresh the items data once first 3749 this._refreshItems(event); 3750 3751 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3752 var currentItem = null, nodes = $(event.target).parents().each(function() { 3753 if($.data(this, that.widgetName + '-item') == that) { 3754 currentItem = $(this); 3755 return false; 3756 } 3757 }); 3758 if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); 3759 3760 if(!currentItem) return false; 3761 if(this.options.handle && !overrideHandle) { 3762 var validHandle = false; 3763 3764 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); 3765 if(!validHandle) return false; 3766 } 3767 3768 this.currentItem = currentItem; 3769 this._removeCurrentsFromItems(); 3770 return true; 3771 3772 }, 3773 3774 _mouseStart: function(event, overrideHandle, noActivation) { 3775 3776 var o = this.options; 3777 this.currentContainer = this; 3778 3779 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3780 this.refreshPositions(); 3781 3782 //Create and append the visible helper 3783 this.helper = this._createHelper(event); 3784 3785 //Cache the helper size 3786 this._cacheHelperProportions(); 3787 3788 /* 3789 * - Position generation - 3790 * This block generates everything position related - it's the core of draggables. 3791 */ 3792 3793 //Cache the margins of the original element 3794 this._cacheMargins(); 3795 3796 //Get the next scrolling parent 3797 this.scrollParent = this.helper.scrollParent(); 3798 3799 //The element's absolute position on the page minus margins 3800 this.offset = this.currentItem.offset(); 3801 this.offset = { 3802 top: this.offset.top - this.margins.top, 3803 left: this.offset.left - this.margins.left 3804 }; 3805 3806 $.extend(this.offset, { 3807 click: { //Where the click happened, relative to the element 3808 left: event.pageX - this.offset.left, 3809 top: event.pageY - this.offset.top 3810 }, 3811 parent: this._getParentOffset(), 3812 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3813 }); 3814 3815 // Only after we got the offset, we can change the helper's position to absolute 3816 // TODO: Still need to figure out a way to make relative sorting possible 3817 this.helper.css("position", "absolute"); 3818 this.cssPosition = this.helper.css("position"); 3819 3820 //Generate the original position 3821 this.originalPosition = this._generatePosition(event); 3822 this.originalPageX = event.pageX; 3823 this.originalPageY = event.pageY; 3824 3825 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 3826 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3827 3828 //Cache the former DOM position 3829 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3830 3831 //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 3832 if(this.helper[0] != this.currentItem[0]) { 3833 this.currentItem.hide(); 3834 } 3835 3836 //Create the placeholder 3837 this._createPlaceholder(); 3838 3839 //Set a containment if given in the options 3840 if(o.containment) 3841 this._setContainment(); 3842 3843 if(o.cursor) { // cursor option 3844 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); 3845 $('body').css("cursor", o.cursor); 3846 } 3847 3848 if(o.opacity) { // opacity option 3849 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); 3850 this.helper.css("opacity", o.opacity); 3851 } 3852 3853 if(o.zIndex) { // zIndex option 3854 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); 3855 this.helper.css("zIndex", o.zIndex); 3856 } 3857 3858 //Prepare scrolling 3859 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') 3860 this.overflowOffset = this.scrollParent.offset(); 3861 3862 //Call callbacks 3863 this._trigger("start", event, this._uiHash()); 3864 3865 //Recache the helper size 3866 if(!this._preserveHelperProportions) 3867 this._cacheHelperProportions(); 3868 3869 3870 //Post 'activate' events to possible containers 3871 if(!noActivation) { 3872 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } 3873 } 3874 3875 //Prepare possible droppables 3876 if($.ui.ddmanager) 3877 $.ui.ddmanager.current = this; 3878 3879 if ($.ui.ddmanager && !o.dropBehaviour) 3880 $.ui.ddmanager.prepareOffsets(this, event); 3881 3882 this.dragging = true; 3883 3884 this.helper.addClass("ui-sortable-helper"); 3885 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3886 return true; 3887 3888 }, 3889 3890 _mouseDrag: function(event) { 3891 3892 //Compute the helpers position 3893 this.position = this._generatePosition(event); 3894 this.positionAbs = this._convertPositionTo("absolute"); 3895 3896 if (!this.lastPositionAbs) { 3897 this.lastPositionAbs = this.positionAbs; 3898 } 3899 3900 //Do scrolling 3901 if(this.options.scroll) { 3902 var o = this.options, scrolled = false; 3903 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { 3904 3905 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 3906 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3907 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) 3908 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3909 3910 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 3911 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3912 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) 3913 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3914 3915 } else { 3916 3917 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 3918 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3919 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 3920 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3921 3922 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 3923 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3924 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 3925 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3926 3927 } 3928 3929 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 3930 $.ui.ddmanager.prepareOffsets(this, event); 3931 } 3932 3933 //Regenerate the absolute position used for position checks 3934 this.positionAbs = this._convertPositionTo("absolute"); 3935 3936 //Set the helper position 3937 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 3938 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 3939 3940 //Rearrange 3941 for (var i = this.items.length - 1; i >= 0; i--) { 3942 3943 //Cache variables and intersection, continue if no intersection 3944 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 3945 if (!intersection) continue; 3946 3947 // Only put the placeholder inside the current Container, skip all 3948 // items form other containers. This works because when moving 3949 // an item from one container to another the 3950 // currentContainer is switched before the placeholder is moved. 3951 // 3952 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3953 // beetween the outer and inner container. 3954 if (item.instance !== this.currentContainer) continue; 3955 3956 if (itemElement != this.currentItem[0] //cannot intersect with itself 3957 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 3958 && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 3959 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) 3960 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container 3961 ) { 3962 3963 this.direction = intersection == 1 ? "down" : "up"; 3964 3965 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 3966 this._rearrange(event, item); 3967 } else { 3968 break; 3969 } 3970 3971 this._trigger("change", event, this._uiHash()); 3972 break; 3973 } 3974 } 3975 3976 //Post events to containers 3977 this._contactContainers(event); 3978 3979 //Interconnect with droppables 3980 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 3981 3982 //Call callbacks 3983 this._trigger('sort', event, this._uiHash()); 3984 3985 this.lastPositionAbs = this.positionAbs; 3986 return false; 3987 3988 }, 3989 3990 _mouseStop: function(event, noPropagation) { 3991 3992 if(!event) return; 3993 3994 //If we are using droppables, inform the manager about the drop 3995 if ($.ui.ddmanager && !this.options.dropBehaviour) 3996 $.ui.ddmanager.drop(this, event); 3997 3998 if(this.options.revert) { 3999 var that = this; 4000 var cur = this.placeholder.offset(); 4001 4002 this.reverting = true; 4003 4004 $(this.helper).animate({ 4005 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 4006 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 4007 }, parseInt(this.options.revert, 10) || 500, function() { 4008 that._clear(event); 4009 }); 4010 } else { 4011 this._clear(event, noPropagation); 4012 } 4013 4014 return false; 4015 4016 }, 4017 4018 cancel: function() { 4019 4020 if(this.dragging) { 4021 4022 this._mouseUp({ target: null });
4023 4024 if(this.options.helper == "original") 4025 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4026 else 4027 this.currentItem.show(); 4028 4029 //Post deactivating events to containers 4030 for (var i = this.containers.length - 1; i >= 0; i--){ 4031 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4032 if(this.containers[i].containerCache.over) { 4033 this.containers[i]._trigger("out", null, this._uiHash(this)); 4034 this.containers[i].containerCache.over = 0; 4035 } 4036 } 4037 4038 } 4039 4040 if (this.placeholder) { 4041 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4042 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4043 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 4044 4045 $.extend(this, { 4046 helper: null, 4047 dragging: false, 4048 reverting: false, 4049 _noFinalSort: null 4050 }); 4051 4052 if(this.domPosition.prev) { 4053 $(this.domPosition.prev).after(this.currentItem); 4054 } else { 4055 $(this.domPosition.parent).prepend(this.currentItem); 4056 } 4057 } 4058 4059 return this; 4060 4061 }, 4062 4063 serialize: function(o) { 4064 4065 var items = this._getItemsAsjQuery(o && o.connected); 4066 var str = []; o = o || {}; 4067 4068 $(items).each(function() { 4069 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 4070 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); 4071 }); 4072 4073 if(!str.length && o.key) { 4074 str.push(o.key + '='); 4075 } 4076 4077 return str.join('&'); 4078 4079 }, 4080 4081 toArray: function(o) { 4082 4083 var items = this._getItemsAsjQuery(o && o.connected); 4084 var ret = []; o = o || {}; 4085 4086 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 4087 return ret; 4088 4089 }, 4090 4091 /* Be careful with the following core functions */ 4092 _intersectsWith: function(item) { 4093 4094 var x1 = this.positionAbs.left, 4095 x2 = x1 + this.helperProportions.width, 4096 y1 = this.positionAbs.top, 4097 y2 = y1 + this.helperProportions.height; 4098 4099 var l = item.left, 4100 r = l + item.width, 4101 t = item.top, 4102 b = t + item.height; 4103 4104 var dyClick = this.offset.click.top, 4105 dxClick = this.offset.click.left; 4106 4107 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4108 4109 if( this.options.tolerance == "pointer" 4110 || this.options.forcePointerForContainers 4111 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 4112 ) { 4113 return isOverElement; 4114 } else { 4115 4116 return (l < x1 + (this.helperProportions.width / 2) // Right Half 4117 && x2 - (this.helperProportions.width / 2) < r // Left Half 4118 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 4119 && y2 - (this.helperProportions.height / 2) < b ); // Top Half 4120 4121 } 4122 }, 4123 4124 _intersectsWithPointer: function(item) { 4125 4126 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4127 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4128 isOverElement = isOverElementHeight && isOverElementWidth, 4129 verticalDirection = this._getDragVerticalDirection(), 4130 horizontalDirection = this._getDragHorizontalDirection(); 4131 4132 if (!isOverElement) 4133 return false; 4134 4135 return this.floating ? 4136 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) 4137 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); 4138 4139 }, 4140 4141 _intersectsWithSides: function(item) { 4142 4143 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4144 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4145 verticalDirection = this._getDragVerticalDirection(), 4146 horizontalDirection = this._getDragHorizontalDirection(); 4147 4148 if (this.floating && horizontalDirection) { 4149 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 4150 } else { 4151 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 4152 } 4153 4154 }, 4155 4156 _getDragVerticalDirection: function() { 4157 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4158 return delta != 0 && (delta > 0 ? "down" : "up"); 4159 }, 4160 4161 _getDragHorizontalDirection: function() { 4162 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4163 return delta != 0 && (delta > 0 ? "right" : "left"); 4164 }, 4165 4166 refresh: function(event) { 4167 this._refreshItems(event); 4168 this.refreshPositions(); 4169 return this; 4170 }, 4171 4172 _connectWith: function() { 4173 var options = this.options; 4174 return options.connectWith.constructor == String
4175 ? [options.connectWith] 4176 : options.connectWith; 4177 }, 4178 4179 _getItemsAsjQuery: function(connected) { 4180 4181 var items = []; 4182 var queries = []; 4183 var connectWith = this._connectWith(); 4184 4185 if(connectWith && connected) { 4186 for (var i = connectWith.length - 1; i >= 0; i--){ 4187 var cur = $(connectWith[i]); 4188 for (var j = cur.length - 1; j >= 0; j--){ 4189 var inst = $.data(cur[j], this.widgetName); 4190 if(inst && inst != this && !inst.options.disabled) { 4191 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]); 4192 } 4193 }; 4194 }; 4195 } 4196 4197 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]); 4198 4199 for (var i = queries.length - 1; i >= 0; i--){ 4200 queries[i][0].each(function() { 4201 items.push(this); 4202 }); 4203 }; 4204 4205 return $(items); 4206 4207 }, 4208 4209 _removeCurrentsFromItems: function() { 4210 4211 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4212 4213 this.items = $.grep(this.items, function (item) { 4214 for (var j=0; j < list.length; j++) { 4215 if(list[j] == item.item[0]) 4216 return false; 4217 }; 4218 return true; 4219 }); 4220 4221 }, 4222 4223 _refreshItems: function(event) { 4224 4225 this.items = []; 4226 this.containers = [this]; 4227 var items = this.items; 4228 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 4229 var connectWith = this._connectWith(); 4230 4231 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4232 for (var i = connectWith.length - 1; i >= 0; i--){ 4233 var cur = $(connectWith[i]); 4234 for (var j = cur.length - 1; j >= 0; j--){ 4235 var inst = $.data(cur[j], this.widgetName); 4236 if(inst && inst != this && !inst.options.disabled) { 4237 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4238 this.containers.push(inst); 4239 } 4240 }; 4241 }; 4242 } 4243 4244 for (var i = queries.length - 1; i >= 0; i--) { 4245 var targetData = queries[i][1]; 4246 var _queries = queries[i][0]; 4247 4248 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4249 var item = $(_queries[j]); 4250 4251 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) 4252 4253 items.push({ 4254 item: item, 4255 instance: targetData, 4256 width: 0, height: 0, 4257 left: 0, top: 0 4258 }); 4259 }; 4260 }; 4261 4262 }, 4263 4264 refreshPositions: function(fast) { 4265 4266 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4267 if(this.offsetParent && this.helper) { 4268 this.offset.parent = this._getParentOffset(); 4269 } 4270 4271 for (var i = this.items.length - 1; i >= 0; i--){ 4272 var item = this.items[i]; 4273 4274 //We ignore calculating positions of all connected containers when we're not over them 4275 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 4276 continue; 4277 4278 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4279 4280 if (!fast) { 4281 item.width = t.outerWidth(); 4282 item.height = t.outerHeight(); 4283 } 4284 4285 var p = t.offset(); 4286 item.left = p.left; 4287 item.top = p.top; 4288 }; 4289 4290 if(this.options.custom && this.options.custom.refreshContainers
4290) { 4291 this.options.custom.refreshContainers.call(this); 4292 } else { 4293 for (var i = this.containers.length - 1; i >= 0; i--){ 4294 var p = this.containers[i].element.offset(); 4295 this.containers[i].containerCache.left = p.left; 4296 this.containers[i].containerCache.top = p.top; 4297 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4298 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4299 }; 4300 } 4301 4302 return this; 4303 }, 4304 4305 _createPlaceholder: function(that) { 4306 that = that || this; 4307 var o = that.options; 4308 4309 if(!o.placeholder || o.placeholder.constructor == String) { 4310 var className = o.placeholder; 4311 o.placeholder = { 4312 element: function() { 4313 4314 var el = $(document.createElement(that.currentItem[0].nodeName)) 4315 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4316 .removeClass("ui-sortable-helper")[0]; 4317 4318 if(!className) 4319 el.style.visibility = "hidden"; 4320 4321 return el; 4322 }, 4323 update: function(container, p) { 4324 4325 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4326 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4327 if(className && !o.forcePlaceholderSize) return; 4328 4329 //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
4330 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; 4331 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; 4332 } 4333 }; 4334 } 4335 4336 //Create the placeholder 4337 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4338 4339 //Append it after the actual current item 4340 that.currentItem.after(that.placeholder); 4341 4342 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4343 o.placeholder.update(that, that.placeholder); 4344 4345 }, 4346 4347 _contactContainers: function(event) { 4348 4349 // get innermost container that intersects with item 4350 var innermostContainer = null, innermostIndex = null; 4351 4352 4353 for (var i = this.containers.length - 1; i >= 0; i--){ 4354 4355 // never consider a container that's located within the item itself 4356 if($.contains(this.currentItem[0], this.containers[i].element[0])) 4357 continue; 4358 4359 if(this._intersectsWith(this.containers[i].containerCache)) { 4360 4361 // if we've already found a container and it's more "inner" than this, then continue 4362 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) 4363 continue; 4364 4365 innermostContainer = this.containers[i]; 4366 innermostIndex = i; 4367 4368 } else { 4369 // container doesn't intersect. trigger "out" event if necessary 4370 if(this.containers[i].containerCache.over) { 4371 this.containers[i]._trigger("out", event, this._uiHash(this)); 4372 this.containers[i].containerCache.over = 0; 4373 } 4374 } 4375 4376 } 4377 4378 // if no intersecting containers found, return 4379 if(!innermostContainer) return; 4380 4381 // move the item into the container if it's not there already 4382 if(this.containers.length === 1) { 4383 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4384 this.containers[innermostIndex].containerCache.over = 1; 4385 } else { 4386 4387 //When entering a new container, we will find the item with the least distance and append our item near it 4388 var dist = 10000; var itemWithLeastDistance = null; 4389 var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; 4390 var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; 4391 var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4392 for (var j = this.items.length - 1; j >= 0; j--) { 4393 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 4394 if(this.items[j].item[0] == this.currentItem[0]) continue; 4395 var cur = this.items[j].item.offset()[posProperty]; 4396 var nearBottom = false; 4397 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4398 nearBottom = true; 4399 cur += this.items[j][sizeProperty]; 4400 } 4401 4402 if(Math.abs(cur - base) < dist) { 4403 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4404 this.direction = nearBottom ? "up": "down"; 4405 } 4406 } 4407 4408 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 4409 return; 4410 4411 this.currentContainer = this.containers[innermostIndex]; 4412 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4413 this._trigger("change", event, this._uiHash()); 4414 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4415 4416 //Update the placeholder 4417 this.options.placeholder.update(this.currentContainer, this.placeholder); 4418 4419 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4420 this.containers[innermostIndex].containerCache.over = 1; 4421 } 4422 4423 4424 }, 4425 4426 _createHelper: function(event) { 4427 4428 var o = this.options; 4429 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 4430 4431 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 4432 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4433 4434 if(helper[0] == this.currentItem[0]) 4435 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
4435: this.currentItem.css("left") }; 4436 4437 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 4438 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 4439 4440 return helper; 4441 4442 }, 4443 4444 _adjustOffsetFromHelper: function(obj) { 4445 if (typeof obj == 'string') { 4446 obj = obj.split(' '); 4447 } 4448 if ($.isArray(obj)) { 4449 obj = {left: +obj[0], top: +obj[1] || 0}; 4450 } 4451 if ('left' in obj) { 4452 this.offset.click.left = obj.left + this.margins.left; 4453 } 4454 if ('right' in obj) { 4455 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4456 } 4457 if ('top' in obj) { 4458 this.offset.click.top = obj.top + this.margins.top; 4459 } 4460 if ('bottom' in obj) { 4461 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4462 } 4463 }, 4464 4465 _getParentOffset: function() { 4466 4467 4468 //Get the offsetParent and cache its position 4469 this.offsetParent = this.helper.offsetParent(); 4470 var po = this.offsetParent.offset(); 4471 4472 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4473 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4474 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4475 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4476 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4477 po.left += this.scrollParent.scrollLeft(); 4478 po.top += this.scrollParent.scrollTop(); 4479 } 4480 4481 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 4482 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 4483 po = { top: 0, left: 0 }; 4484 4485 return { 4486 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4487 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4488 }; 4489 4490 }, 4491 4492 _getRelativeOffset: function() { 4493 4494 if(this.cssPosition == "relative") { 4495 var p = this.currentItem.position(); 4496 return { 4497 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4498 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4499 }; 4500 } else { 4501 return { top: 0, left: 0 }; 4502 } 4503 4504 }, 4505 4506 _cacheMargins: function() { 4507 this.margins = { 4508 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4509 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4510 }; 4511 }, 4512 4513 _cacheHelperProportions: function() { 4514 this.helperProportions = { 4515 width: this.helper.outerWidth(), 4516 height: this.helper.outerHeight() 4517 }; 4518 }, 4519 4520 _setContainment: function() { 4521 4522 var o = this.options; 4523 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 4524 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 4525 0 - this.offset.relative.left - this.offset.parent.left, 4526 0 - this.offset.relative.top - this.offset.parent.top, 4527 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 4528 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4529 ]; 4530 4531 if(!(/^(document|window|parent)$/).test(o.containment)) { 4532 var ce = $(o.containment)[0]; 4533 var co = $(o.containment).offset(); 4534 var over = ($(ce).css("overflow") != 'hidden'); 4535 4536 this.containment = [ 4537 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4538 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4539 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, 4540 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
454010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 4541 ]; 4542 } 4543 4544 }, 4545 4546 _convertPositionTo: function(d, pos) { 4547 4548 if(!pos) pos = this.position; 4549 var mod = d == "absolute" ? 1 : -1; 4550 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); 4551 4552 return { 4553 top: ( 4554 pos.top // The absolute mouse position 4555 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4556 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 4557 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4558 ), 4559 left: ( 4560 pos.left // The absolute mouse position 4561 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4562 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 4563 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4564 ) 4565 }; 4566 4567 }, 4568 4569 _generatePosition: function(event) { 4570 4571 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); 4572 4573 // This is another very weird special case that only happens for relative elements: 4574 // 1. If the css position is relative 4575 // 2. and the scroll parent is the document or similar to the offset parent 4576 // we have to refresh the relative offset during the scroll so there are no jumps 4577 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { 4578 this.offset.relative = this._getRelativeOffset(); 4579 } 4580 4581 var pageX = event.pageX; 4582 var pageY = event.pageY; 4583 4584 /* 4585 * - Position constraining - 4586 * Constrain the position to a mix of grid, containment. 4587 */ 4588 4589 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4590 4591 if(this.containment) { 4592 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; 4593 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; 4594 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; 4595 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; 4596 } 4597 4598 if(o.grid) { 4599 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4600 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; 4601 4602 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4603 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; 4604 } 4605 4606 } 4607 4608 return { 4609 top: ( 4610 pageY // The absolute mouse position 4611 - this.offset.click.top // Click offset (relative to the element) 4612 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 4613 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 4614 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4615 ), 4616 left: ( 4617 pageX // The absolute mouse position 4618 - this.offset.click.left // Click offset (relative to the element) 4619 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 4620 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 4621 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4622 ) 4623 }; 4624 4625 }, 4626 4627 _rearrange: function(event, i, a, hardRefresh) { 4628 4629 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)); 4630 4631 //Various things done here to improve the performance: 4632 // 1. we create a setTimeout, that calls refreshPositions 4633 // 2. on the instance, we have a counter variable, that get's higher after every append 4634 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4635 // 4. this lets only the last addition to the timeout stack through 4636 this.counter = this.counter ? ++this.counter : 1; 4637 var counter = this.counter; 4638 4639 this._delay(function() {
4640 if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4641 }); 4642 4643 }, 4644 4645 _clear: function(event, noPropagation) { 4646 4647 this.reverting = false; 4648 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4649 // everything else normalized again 4650 var delayedTriggers = []; 4651 4652 // We first have to update the dom position of the actual currentItem 4653 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4654 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); 4655 this._noFinalSort = null; 4656 4657 if(this.helper[0] == this.currentItem[0]) { 4658 for(var i in this._storedCSS) { 4659 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 4660 } 4661 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4662 } else { 4663 this.currentItem.show(); 4664 } 4665 4666 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4667 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 4668 4669 // Check if the items Container has Changed and trigger appropriate 4670 // events. 4671 if (this !== this.currentContainer) { 4672 if(!noPropagation) { 4673 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4674 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4675 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4676 } 4677 } 4678 4679 4680 //Post events to containers 4681 for (var i = this.containers.length - 1; i >= 0; i--){ 4682 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4683 if(this.containers[i].containerCache.over) { 4684 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4685 this.containers[i].containerCache.over = 0; 4686 } 4687 } 4688 4689 //Do what was originally in plugins 4690 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor 4691 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity 4692 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index 4693 4694 this.dragging = false; 4695 if(this.cancelHelperRemoval) { 4696 if(!noPropagation) { 4697 this._trigger("beforeStop", event, this._uiHash()); 4698 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4699 this._trigger("stop", event, this._uiHash()); 4700 } 4701 4702 this.fromOutside = false; 4703 return false; 4704 } 4705 4706 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); 4707 4708 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4709 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4710 4711 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; 4712 4713 if(!noPropagation) { 4714 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 4715 this._trigger("stop", event, this._uiHash()); 4716 } 4717 4718 this.fromOutside = false; 4719 return true; 4720 4721 }, 4722 4723 _trigger: function() { 4724 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4725 this.cancel(); 4726 } 4727 }, 4728 4729 _uiHash: function(_inst) { 4730 var inst = _inst || this; 4731 return { 4732 helper: inst.helper, 4733 placeholder: inst.placeholder || $([]), 4734 position: inst.position, 4735 originalPosition: inst.originalPosition, 4736 offset: inst.positionAbs, 4737 item: inst.currentItem, 4738 sender: _inst ? _inst.element : null 4739 }; 4740 } 4741 4742}); 4743 4744})(jQuery); 4745(function( $, undefined ) { 4746 4747var uid = 0, 4748 hideProps = {}, 4749 showProps = {}; 4750 4751hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 4752 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 4753showProps.height = showProps.paddingTop = showProps.paddingBottom = 4754 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 4755 4756$.widget( "ui.accordion", { 4757 version: "1.9.2", 4758 options: { 4759 active: 0, 4760 animate: {}, 4761 collapsible: false, 4762 event: "click", 4763 header: "> li > :first-child,> :not(li):even", 4764 heightStyle: "auto", 4765 icons: { 4766 activeHeader: "ui-icon-triangle-1-s", 4767 header: "ui-icon-triangle-1-e" 4768 }, 4769 4770 // callbacks 4771 activate: null, 4772 beforeActivate: null 4773 }, 4774 4775 _create: function() {
vendor: 5,494 bytes, lines 4776-4975
4776 var accordionId = this.accordionId = "ui-accordion-" + 4777 (this.element.attr( "id" ) || ++uid), 4778 options = this.options; 4779 4780 this.prevShow = this.prevHide = $(); 4781 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); 4782 4783 this.headers = this.element.find( options.header ) 4784 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 4785 this._hoverable( this.headers ); 4786 this._focusable( this.headers ); 4787 4788 this.headers.next() 4789 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 4790 .hide(); 4791 4792 // don't allow collapsible: false and active: false / null 4793 if ( !options.collapsible && (options.active === false || options.active == null) ) { 4794 options.active = 0; 4795 } 4796 // handle negative values 4797 if ( options.active < 0 ) { 4798 options.active += this.headers.length; 4799 } 4800 this.active = this._findActive( options.active ) 4801 .addClass( "ui-accordion-header-active ui-state-active" ) 4802 .toggleClass( "ui-corner-all ui-corner-top" ); 4803 this.active.next() 4804 .addClass( "ui-accordion-content-active" ) 4805 .show(); 4806 4807 this._createIcons(); 4808 this.refresh(); 4809 4810 // ARIA 4811 this.element.attr( "role", "tablist" ); 4812 4813 this.headers 4814 .attr( "role", "tab" ) 4815 .each(function( i ) { 4816 var header = $( this ), 4817 headerId = header.attr( "id" ), 4818 panel = header.next(), 4819 panelId = panel.attr( "id" ); 4820 if ( !headerId ) { 4821 headerId = accordionId + "-header-" + i; 4822 header.attr( "id", headerId ); 4823 } 4824 if ( !panelId ) { 4825 panelId = accordionId + "-panel-" + i; 4826 panel.attr( "id", panelId ); 4827 } 4828 header.attr( "aria-controls", panelId ); 4829 panel.attr( "aria-labelledby", headerId ); 4830 }) 4831 .next() 4832 .attr( "role", "tabpanel" ); 4833 4834 this.headers 4835 .not( this.active ) 4836 .attr({ 4837 "aria-selected": "false", 4838 tabIndex: -1 4839 }) 4840 .next() 4841 .attr({ 4842 "aria-expanded": "false", 4843 "aria-hidden": "true" 4844 }) 4845 .hide(); 4846 4847 // make sure at least one header is in the tab order 4848 if ( !this.active.length ) { 4849 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 4850 } else { 4851 this.active.attr({ 4852 "aria-selected": "true", 4853 tabIndex: 0 4854 }) 4855 .next() 4856 .attr({ 4857 "aria-expanded": "true", 4858 "aria-hidden": "false" 4859 }); 4860 } 4861 4862 this._on( this.headers, { keydown: "_keydown" }); 4863 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 4864 this._setupEvents( options.event ); 4865 }, 4866 4867 _getCreateEventData: function() { 4868 return { 4869 header: this.active, 4870 content: !this.active.length ? $() : this.active.next() 4871 }; 4872 }, 4873 4874 _createIcons: function() { 4875 var icons = this.options.icons; 4876 if ( icons ) { 4877 $( "<span>" ) 4878 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 4879 .prependTo( this.headers ); 4880 this.active.children( ".ui-accordion-header-icon" ) 4881 .removeClass( icons.header ) 4882 .addClass( icons.activeHeader ); 4883 this.headers.addClass( "ui-accordion-icons" ); 4884 } 4885 }, 4886 4887 _destroyIcons: function() { 4888 this.headers 4889 .removeClass( "ui-accordion-icons" ) 4890 .children( ".ui-accordion-header-icon" ) 4891 .remove(); 4892 }, 4893 4894 _destroy: function() { 4895 var contents; 4896 4897 // clean up main element 4898 this.element 4899 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 4900 .removeAttr( "role" ); 4901 4902 // clean up headers 4903 this.headers 4904 .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" ) 4905 .removeAttr( "role" ) 4906 .removeAttr( "aria-selected" ) 4907 .removeAttr( "aria-controls" ) 4908 .removeAttr( "tabIndex" ) 4909 .each(function() { 4910 if ( /^ui-accordion/.test( this.id ) ) { 4911 this.removeAttribute( "id" ); 4912 } 4913 }); 4914 this._destroyIcons(); 4915 4916 // clean up content panels 4917 contents = this.headers.next() 4918 .css( "display", "" ) 4919 .removeAttr( "role" ) 4920 .removeAttr( "aria-expanded" ) 4921 .removeAttr( "aria-hidden" ) 4922 .removeAttr( "aria-labelledby" ) 4923 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 4924 .each(function() { 4925 if ( /^ui-accordion/.test( this.id ) ) { 4926 this.removeAttribute( "id" ); 4927 } 4928 }); 4929 if ( this.options.heightStyle !== "content" ) { 4930 contents.css( "height", "" ); 4931 } 4932 }, 4933 4934 _setOption: function( key, value ) { 4935 if ( key === "active" ) { 4936 // _activate() will handle invalid values and update this.options 4937 this._activate( value ); 4938 return; 4939 } 4940 4941 if ( key === "event" ) { 4942 if ( this.options.event ) { 4943 this._off( this.headers, this.options.event ); 4944 } 4945 this._setupEvents( value ); 4946 } 4947 4948 this._super( key, value ); 4949 4950 // setting collapsible: false while collapsed; open first panel 4951 if ( key === "collapsible" && !value && this.options.active === false ) { 4952 this._activate( 0 ); 4953 } 4954 4955 if ( key === "icons" ) { 4956 this._destroyIcons(); 4957 if ( value ) { 4958 this._createIcons(); 4959 } 4960 } 4961 4962 // #5332 - opacity doesn't cascade to positioned elements in IE 4963 // so we need to add the disabled class to the headers and panels 4964 if ( key === "disabled" ) { 4965 this.headers.add( this.headers.next() ) 4966 .toggleClass( "ui-state-disabled", !!value ); 4967 } 4968 }, 4969 4970 _keydown: function( event ) { 4971 if ( event.altKey || event.ctrlKey ) { 4972 return; 4973 } 4974 4975 var keyCode = $.ui.keyCode,
vendor: 4,490 bytes, lines 4976-5134
4976 length = this.headers.length, 4977 currentIndex = this.headers.index( event.target ), 4978 toFocus = false; 4979 4980 switch ( event.keyCode ) { 4981 case keyCode.RIGHT: 4982 case keyCode.DOWN: 4983 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 4984 break; 4985 case keyCode.LEFT: 4986 case keyCode.UP: 4987 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 4988 break; 4989 case keyCode.SPACE: 4990 case keyCode.ENTER: 4991 this._eventHandler( event ); 4992 break; 4993 case keyCode.HOME: 4994 toFocus = this.headers[ 0 ]; 4995 break; 4996 case keyCode.END: 4997 toFocus = this.headers[ length - 1 ]; 4998 break; 4999 } 5000 5001 if ( toFocus ) { 5002 $( event.target ).attr( "tabIndex", -1 ); 5003 $( toFocus ).attr( "tabIndex", 0 ); 5004 toFocus.focus(); 5005 event.preventDefault(); 5006 } 5007 }, 5008 5009 _panelKeyDown : function( event ) { 5010 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5011 $( event.currentTarget ).prev().focus(); 5012 } 5013 }, 5014 5015 refresh: function() { 5016 var maxHeight, overflow, 5017 heightStyle = this.options.heightStyle, 5018 parent = this.element.parent(); 5019 5020 5021 if ( heightStyle === "fill" ) { 5022 // IE 6 treats height like minHeight, so we need to turn off overflow 5023 // in order to get a reliable height 5024 // we use the minHeight support test because we assume that only 5025 // browsers that don't support minHeight will treat height as minHeight 5026 if ( !$.support.minHeight ) { 5027 overflow = parent.css( "overflow" ); 5028 parent.css( "overflow", "hidden"); 5029 } 5030 maxHeight = parent.height(); 5031 this.element.siblings( ":visible" ).each(function() { 5032 var elem = $( this ), 5033 position = elem.css( "position" ); 5034 5035 if ( position === "absolute" || position === "fixed" ) { 5036 return; 5037 } 5038 maxHeight -= elem.outerHeight( true ); 5039 }); 5040 if ( overflow ) { 5041 parent.css( "overflow", overflow ); 5042 } 5043 5044 this.headers.each(function() { 5045 maxHeight -= $( this ).outerHeight( true ); 5046 }); 5047 5048 this.headers.next() 5049 .each(function() { 5050 $( this ).height( Math.max( 0, maxHeight - 5051 $( this ).innerHeight() + $( this ).height() ) ); 5052 }) 5053 .css( "overflow", "auto" ); 5054 } else if ( heightStyle === "auto" ) { 5055 maxHeight = 0; 5056 this.headers.next() 5057 .each(function() { 5058 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5059 }) 5060 .height( maxHeight ); 5061 } 5062 }, 5063 5064 _activate: function( index ) { 5065 var active = this._findActive( index )[ 0 ]; 5066 5067 // trying to activate the already active panel 5068 if ( active === this.active[ 0 ] ) { 5069 return; 5070 } 5071 5072 // trying to collapse, simulate a click on the currently active header 5073 active = active || this.active[ 0 ]; 5074 5075 this._eventHandler({ 5076 target: active, 5077 currentTarget: active, 5078 preventDefault: $.noop 5079 }); 5080 }, 5081 5082 _findActive: function( selector ) { 5083 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5084 }, 5085 5086 _setupEvents: function( event ) { 5087 var events = {}; 5088 if ( !event ) { 5089 return; 5090 } 5091 $.each( event.split(" "), function( index, eventName ) { 5092 events[ eventName ] = "_eventHandler"; 5093 }); 5094 this._on( this.headers, events ); 5095 }, 5096 5097 _eventHandler: function( event ) { 5098 var options = this.options, 5099 active = this.active, 5100 clicked = $( event.currentTarget ), 5101 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5102 collapsing = clickedIsActive && options.collapsible, 5103 toShow = collapsing ? $() : clicked.next(), 5104 toHide = active.next(), 5105 eventData = { 5106 oldHeader: active, 5107 oldPanel: toHide, 5108 newHeader: collapsing ? $() : clicked, 5109 newPanel: toShow 5110 }; 5111 5112 event.preventDefault(); 5113 5114 if ( 5115 // click on active header, but not collapsible 5116 ( clickedIsActive && !options.collapsible ) || 5117 // allow canceling activation 5118 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5119 return; 5120 } 5121 5122 options.active = collapsing ? false : this.headers.index( clicked ); 5123 5124 // when the call to ._toggle() comes after the class changes 5125 // it causes a very odd bug in IE 8 (see #6720) 5126 this.active = clickedIsActive ? $() : clicked; 5127 this._toggle( eventData ); 5128 5129 // switch classes 5130 // corner classes on the previously active header stay after the animation 5131 active.removeClass( "ui-accordion-header-active ui-state-active" ); 5132 if ( options.icons ) { 5133 active.children( ".ui-accordion-header-icon" ) 5134 .removeClass( options.icons.activeHeader )
5135 .addClass( options.icons.header ); 5136 } 5137 5138 if ( !clickedIsActive ) { 5139 clicked 5140 .removeClass( "ui-corner-all" ) 5141 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 5142 if ( options.icons ) { 5143 clicked.children( ".ui-accordion-header-icon" ) 5144 .removeClass( options.icons.header ) 5145 .addClass( options.icons.activeHeader ); 5146 } 5147 5148 clicked 5149 .next() 5150 .addClass( "ui-accordion-content-active" ); 5151 } 5152 }, 5153 5154 _toggle: function( data ) { 5155 var toShow = data.newPanel, 5156 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5157 5158 // handle activating a panel during the animation for another activation 5159 this.prevShow.add( this.prevHide ).stop( true, true ); 5160 this.prevShow = toShow; 5161 this.prevHide = toHide; 5162 5163 if ( this.options.animate ) { 5164 this._animate( toShow, toHide, data ); 5165 } else { 5166 toHide.hide(); 5167 toShow.show(); 5168 this._toggleComplete( data ); 5169 } 5170 5171 toHide.attr({ 5172 "aria-expanded": "false", 5173 "aria-hidden": "true" 5174 }); 5175 toHide.prev().attr( "aria-selected", "false" ); 5176 // if we're switching panels, remove the old header from the tab order 5177 // if we're opening from collapsed state, remove the previous header from the tab order 5178 // if we're collapsing, then keep the collapsing header in the tab order 5179 if ( toShow.length && toHide.length ) { 5180 toHide.prev().attr( "tabIndex", -1 ); 5181 } else if ( toShow.length ) { 5182 this.headers.filter(function() { 5183 return $( this ).attr( "tabIndex" ) === 0; 5184 }) 5185 .attr( "tabIndex", -1 ); 5186 } 5187 5188 toShow 5189 .attr({ 5190 "aria-expanded": "true", 5191 "aria-hidden": "false" 5192 }) 5193 .prev() 5194 .attr({ 5195 "aria-selected": "true", 5196 tabIndex: 0 5197 }); 5198 }, 5199 5200 _animate: function( toShow, toHide, data ) { 5201 var total, easing, duration, 5202 that = this, 5203 adjust = 0, 5204 down = toShow.length && 5205 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5206 animate = this.options.animate || {}, 5207 options = down && animate.down || animate, 5208 complete = function() { 5209 that._toggleComplete( data ); 5210 }; 5211 5212 if ( typeof options === "number" ) { 5213 duration = options; 5214 } 5215 if ( typeof options === "string" ) { 5216 easing = options; 5217 } 5218 // fall back from options to animation in case of partial down settings 5219 easing = easing || options.easing || animate.easing; 5220 duration = duration || options.duration || animate.duration; 5221 5222 if ( !toHide.length ) { 5223 return toShow.animate( showProps, duration, easing, complete ); 5224 } 5225 if ( !toShow.length ) { 5226 return toHide.animate( hideProps, duration, easing, complete ); 5227 } 5228 5229 total = toShow.show().outerHeight(); 5230 toHide.animate( hideProps, { 5231 duration: duration, 5232 easing: easing, 5233 step: function( now, fx ) { 5234 fx.now = Math.round( now ); 5235 } 5236 }); 5237 toShow 5238 .hide() 5239 .animate( showProps, { 5240 duration: duration, 5241 easing: easing, 5242 complete: complete, 5243 step: function( now, fx ) { 5244 fx.now = Math.round( now ); 5245 if ( fx.prop !== "height" ) { 5246 adjust += fx.now; 5247 } else if ( that.options.heightStyle !== "content" ) { 5248 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 5249 adjust = 0; 5250 } 5251 } 5252 }); 5253 }, 5254 5255 _toggleComplete: function( data ) { 5256 var toHide = data.oldPanel; 5257 5258 toHide 5259 .removeClass( "ui-accordion-content-active" ) 5260 .prev() 5261 .removeClass( "ui-corner-top" ) 5262 .addClass( "ui-corner-all" ); 5263 5264 // Work around for rendering bug in IE (#5421) 5265 if ( toHide.length ) { 5266 toHide.parent()[0].className = toHide.parent()[0].className; 5267 } 5268 5269 this._trigger( "activate", null, data ); 5270 } 5271}); 5272 5273 5274 5275// DEPRECATED 5276if ( $.uiBackCompat !== false ) { 5277 // navigation options 5278 (function( $, prototype ) { 5279 $.extend( prototype.options, { 5280 navigation: false, 5281 navigationFilter: function() { 5282 return this.href.toLowerCase() === location.href.toLowerCase(); 5283 } 5284 }); 5285 5286 var _create = prototype._create; 5287 prototype._create = function() { 5288 if ( this.options.navigation ) { 5289 var that = this, 5290 headers = this.element.find( this.options.header ), 5291 content = headers.next(), 5292 current = headers.add( content ) 5293 .find( "a" ) 5294 .filter( this.options.navigationFilter ) 5295 [ 0 ]; 5296 if ( current ) { 5297 headers.add( content ).each( function( index ) { 5298 if ( $.contains( this, current ) ) { 5299 that.options.active = Math.floor( index / 2 ); 5300 return false; 5301 } 5302 });
5303 } 5304 } 5305 _create.call( this ); 5306 }; 5307 }( jQuery, jQuery.ui.accordion.prototype ) ); 5308 5309 // height options 5310 (function( $, prototype ) { 5311 $.extend( prototype.options, { 5312 heightStyle: null, // remove default so we fall back to old values 5313 autoHeight: true, // use heightStyle: "auto" 5314 clearStyle: false, // use heightStyle: "content" 5315 fillSpace: false // use heightStyle: "fill" 5316 }); 5317 5318 var _create = prototype._create, 5319 _setOption = prototype._setOption; 5320 5321 $.extend( prototype, { 5322 _create: function() { 5323 this.options.heightStyle = this.options.heightStyle || 5324 this._mergeHeightStyle(); 5325 5326 _create.call( this ); 5327 }, 5328 5329 _setOption: function( key ) { 5330 if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { 5331 this.options.heightStyle = this._mergeHeightStyle(); 5332 } 5333 _setOption.apply( this, arguments ); 5334 }, 5335 5336 _mergeHeightStyle: function() { 5337 var options = this.options; 5338 5339 if ( options.fillSpace ) { 5340 return "fill"; 5341 } 5342 5343 if ( options.clearStyle ) { 5344 return "content"; 5345 } 5346 5347 if ( options.autoHeight ) { 5348 return "auto"; 5349 } 5350 } 5351 }); 5352 }( jQuery, jQuery.ui.accordion.prototype ) ); 5353 5354 // icon options 5355 (function( $, prototype ) { 5356 $.extend( prototype.options.icons, { 5357 activeHeader: null, // remove default so we fall back to old values 5358 headerSelected: "ui-icon-triangle-1-s" 5359 }); 5360 5361 var _createIcons = prototype._createIcons; 5362 prototype._createIcons = function() { 5363 if ( this.options.icons ) { 5364 this.options.icons.activeHeader = this.options.icons.activeHeader || 5365 this.options.icons.headerSelected; 5366 } 5367 _createIcons.call( this ); 5368 }; 5369 }( jQuery, jQuery.ui.accordion.prototype ) ); 5370 5371 // expanded active option, activate method 5372 (function( $, prototype ) { 5373 prototype.activate = prototype._activate; 5374 5375 var _findActive = prototype._findActive; 5376 prototype._findActive = function( index ) { 5377 if ( index === -1 ) { 5378 index = false; 5379 } 5380 if ( index && typeof index !== "number" ) { 5381 index = this.headers.index( this.headers.filter( index ) ); 5382 if ( index === -1 ) { 5383 index = false; 5384 } 5385 } 5386 return _findActive.call( this, index ); 5387 }; 5388 }( jQuery, jQuery.ui.accordion.prototype ) ); 5389 5390 // resize method 5391 jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; 5392 5393 // change events 5394 (function( $, prototype ) { 5395 $.extend( prototype.options, { 5396 change: null, 5397 changestart: null 5398 }); 5399 5400 var _trigger = prototype._trigger; 5401 prototype._trigger = function( type, event, data ) { 5402 var ret = _trigger.apply( this, arguments ); 5403 if ( !ret ) { 5404 return false; 5405 } 5406 5407 if ( type === "beforeActivate" ) { 5408 ret = _trigger.call( this, "changestart", event, { 5409 oldHeader: data.oldHeader, 5410 oldContent: data.oldPanel, 5411 newHeader: data.newHeader, 5412 newContent: data.newPanel 5413 }); 5414 } else if ( type === "activate" ) { 5415 ret = _trigger.call( this, "change", event, { 5416 oldHeader: data.oldHeader, 5417 oldContent: data.oldPanel, 5418 newHeader: data.newHeader, 5419 newContent: data.newPanel 5420 }); 5421 } 5422 return ret; 5423 }; 5424 }( jQuery, jQuery.ui.accordion.prototype ) ); 5425 5426 // animated option 5427 // NOTE: this only provides support for "slide", "bounceslide", and easings 5428 // not the full $.ui.accordion.animations API 5429 (function( $, prototype ) { 5430 $.extend( prototype.options, { 5431 animate: null, 5432 animated: "slide" 5433 }); 5434 5435 var _create = prototype._create; 5436 prototype._create = function() { 5437 var options = this.options; 5438 if ( options.animate === null ) { 5439 if ( !options.animated ) { 5440 options.animate = false; 5441 } else if ( options.animated === "slide" ) { 5442 options.animate = 300; 5443 } else if ( options.animated === "bounceslide" ) { 5444 options.animate = { 5445 duration: 200, 5446 down: { 5447 easing: "easeOutBounce", 5448 duration: 1000 5449 } 5450 }; 5451 } else { 5452 options.animate = options.animated; 5453 } 5454 } 5455 5456 _create.call( this ); 5457 }; 5458 }( jQuery, jQuery.ui.accordion.prototype ) ); 5459} 5460 5461})( jQuery ); 5462(function( $, undefined ) { 5463 5464// used to prevent race conditions with remote data sources 5465var requestIndex = 0; 5466 5467$.widget( "ui.autocomplete", { 5468 version: "1.9.2", 5469 defaultElement: "<input>", 5470 options: { 5471 appendTo: "body", 5472 autoFocus: false, 5473 delay: 300, 5474 minLength: 1, 5475 position: { 5476 my: "left top", 5477 at: "left bottom", 5478 collision: "none" 5479 }, 5480 source: null, 5481 5482 // callbacks 5483 change: null, 5484 close: null, 5485 focus: null, 5486 open: null, 5487 response: null, 5488 search: null, 5489 select: null 5490 }, 5491 5492 pending: 0, 5493 5494 _create: function() { 5495 // Some browsers only repeat keydown events, not keypress events, 5496 // so we use the suppressKeyPress flag to determine if we've already 5497 // handled the keydown event. #7269 5498 // Unfortunately the code for & in keypress is the same as the up arrow, 5499 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 5500 // events when we know the keydown event was used to modify the 5501 // search term. #7799 5502 var suppressKeyPress, suppressKeyPressRepeat, suppressInput; 5503 5504 this.isMultiLine = this._isMultiLine(); 5505 this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; 5506 this.isNewMenu = true; 5507 5508 this.element 5509 .addClass( "ui-autocomplete-input" ) 5510 .attr( "autocomplete", "off" ); 5511 5512 this._on( this.element, { 5513 keydown: function( event ) { 5514 if ( this.element.prop( "readOnly" ) ) { 5515 suppressKeyPress = true; 5516 suppressInput = true; 5517 suppressKeyPressRepeat = true; 5518 return; 5519 } 5520 5521 suppressKeyPress = false; 5522 suppressInput = false; 5523 suppressKeyPressRepeat = false; 5524 var keyCode = $.ui.keyCode; 5525 switch( event.keyCode ) { 5526 case keyCode.PAGE_UP: 5527 suppressKeyPress = true; 5528 this._move( "previousPage", event ); 5529 break; 5530 case keyCode.PAGE_DOWN: 5531 suppressKeyPress = true; 5532 this._move( "nextPage", event ); 5533 break; 5534 case keyCode.UP: 5535 suppressKeyPress = true; 5536 this._keyEvent( "previous", event ); 5537 break; 5538 case keyCode.DOWN: 5539 suppressKeyPress = true; 5540 this._keyEvent( "next", event ); 5541 break; 5542 case keyCode.ENTER: 5543 case keyCode.NUMPAD_ENTER: 5544 // when menu is open and has focus 5545 if ( this.menu.active ) { 5546 // #6055 - Opera still allows the keypress to occur 5547 // which causes forms to submit 5548 suppressKeyPress = true; 5549 event.preventDefault(); 5550 this.menu.select( event ); 5551 } 5552 break; 5553 case keyCode.TAB: 5554 if ( this.menu.active ) { 5555 this.menu.select( event ); 5556 } 5557 break; 5558 case keyCode.ESCAPE: 5559 if ( this.menu.element.is( ":visible" ) ) { 5560 this._value( this.term ); 5561 this.close( event ); 5562 // Different browsers have different default behavior for escape 5563 // Single press can mean undo or clear 5564 // Double press in IE means clear the whole form 5565 event.preventDefault(); 5566 } 5567 break; 5568 default: 5569 suppressKeyPressRepeat = true; 5570 // search timeout should be triggered before the input value is changed 5571 this._searchTimeout( event ); 5572 break; 5573 } 5574 }, 5575 keypress: function( event ) { 5576 if ( suppressKeyPress ) { 5577 suppressKeyPress = false; 5578 event.preventDefault(); 5579 return; 5580 } 5581 if ( suppressKeyPressRepeat ) { 5582 return; 5583 } 5584 5585 // replicate some key handlers to allow them to repeat in Firefox and Opera 5586 var keyCode = $.ui.keyCode; 5587 switch( event.keyCode ) { 5588 case keyCode.PAGE_UP: 5589 this._move( "previousPage", event ); 5590 break; 5591 case keyCode.PAGE_DOWN: 5592 this._move( "nextPage", event ); 5593 break; 5594 case keyCode.UP: 5595 this._keyEvent( "previous", event ); 5596 break; 5597 case keyCode.DOWN: 5598 this._keyEvent( "next", event ); 5599 break; 5600 } 5601 },
vendor: 23,199 bytes, lines 5602-6405
5602 input: function( event ) { 5603 if ( suppressInput ) { 5604 suppressInput = false; 5605 event.preventDefault(); 5606 return; 5607 } 5608 this._searchTimeout( event ); 5609 }, 5610 focus: function() { 5611 this.selectedItem = null; 5612 this.previous = this._value(); 5613 }, 5614 blur: function( event ) { 5615 if ( this.cancelBlur ) { 5616 delete this.cancelBlur; 5617 return; 5618 } 5619 5620 clearTimeout( this.searching ); 5621 this.close( event ); 5622 this._change( event ); 5623 } 5624 }); 5625 5626 this._initSource(); 5627 this.menu = $( "<ul>" ) 5628 .addClass( "ui-autocomplete" ) 5629 .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] ) 5630 .menu({ 5631 // custom key handling for now 5632 input: $(), 5633 // disable ARIA support, the live region takes care of that 5634 role: null 5635 }) 5636 .zIndex( this.element.zIndex() + 1 ) 5637 .hide() 5638 .data( "menu" ); 5639 5640 this._on( this.menu.element, { 5641 mousedown: function( event ) { 5642 // prevent moving focus out of the text field 5643 event.preventDefault(); 5644 5645 // IE doesn't prevent moving focus even with event.preventDefault() 5646 // so we set a flag to know when we should ignore the blur event 5647 this.cancelBlur = true; 5648 this._delay(function() { 5649 delete this.cancelBlur; 5650 }); 5651 5652 // clicking on the scrollbar causes focus to shift to the body 5653 // but we can't detect a mouseup or a click immediately afterward 5654 // so we have to track the next mousedown and close the menu if 5655 // the user clicks somewhere outside of the autocomplete 5656 var menuElement = this.menu.element[ 0 ]; 5657 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 5658 this._delay(function() { 5659 var that = this; 5660 this.document.one( "mousedown", function( event ) { 5661 if ( event.target !== that.element[ 0 ] && 5662 event.target !== menuElement && 5663 !$.contains( menuElement, event.target ) ) { 5664 that.close(); 5665 } 5666 }); 5667 }); 5668 } 5669 }, 5670 menufocus: function( event, ui ) { 5671 // #7024 - Prevent accidental activation of menu items in Firefox 5672 if ( this.isNewMenu ) { 5673 this.isNewMenu = false; 5674 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 5675 this.menu.blur(); 5676 5677 this.document.one( "mousemove", function() { 5678 $( event.target ).trigger( event.originalEvent ); 5679 }); 5680 5681 return; 5682 } 5683 } 5684 5685 // back compat for _renderItem using item.autocomplete, via #7810 5686 // TODO remove the fallback, see #8156 5687 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ); 5688 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 5689 // use value to match what will end up in the input, if it was a key event 5690 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 5691 this._value( item.value ); 5692 } 5693 } else { 5694 // Normally the input is populated with the item's value as the 5695 // menu is navigated, causing screen readers to notice a change and 5696 // announce the item. Since the focus event was canceled, this doesn't 5697 // happen, so we update the live region so that screen readers can 5698 // still notice the change and announce it. 5699 this.liveRegion.text( item.value ); 5700 } 5701 }, 5702 menuselect: function( event, ui ) { 5703 // back compat for _renderItem using item.autocomplete, via #7810 5704 // TODO remove the fallback, see #8156 5705 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ), 5706 previous = this.previous; 5707 5708 // only trigger when focus was lost (click on menu) 5709 if ( this.element[0] !== this.document[0].activeElement ) { 5710 this.element.focus(); 5711 this.previous = previous; 5712 // #6109 - IE triggers two focus events and the second 5713 // is asynchronous, so we need to reset the previous 5714 // term synchronously and asynchronously :-( 5715 this._delay(function() { 5716 this.previous = previous; 5717 this.selectedItem = item; 5718 }); 5719 } 5720 5721 if ( false !== this._trigger( "select", event, { item: item } ) ) { 5722 this._value( item.value ); 5723 } 5724 // reset the term after the select event 5725 // this allows custom select handling to work properly 5726 this.term = this._value(); 5727 5728 this.close( event ); 5729 this.selectedItem = item; 5730 } 5731 }); 5732 5733 this.liveRegion = $( "<span>", { 5734 role: "status", 5735 "aria-live": "polite" 5736 }) 5737 .addClass( "ui-helper-hidden-accessible" ) 5738 .insertAfter( this.element ); 5739 5740 if ( $.fn.bgiframe ) { 5741 this.menu.element.bgiframe(); 5742 } 5743 5744 // turning off autocomplete prevents the browser from remembering the 5745 // value when navigating through history, so we re-enable autocomplete 5746 // if the page is unloaded before the widget is destroyed. #7790 5747 this._on( this.window, { 5748 beforeunload: function() { 5749 this.element.removeAttr( "autocomplete" ); 5750 } 5751 }); 5752 }, 5753 5754 _destroy: function() { 5755 clearTimeout( this.searching ); 5756 this.element 5757 .removeClass( "ui-autocomplete-input" ) 5758 .removeAttr( "autocomplete" ); 5759 this.menu.element.remove(); 5760 this.liveRegion.remove(); 5761 }, 5762 5763 _setOption: function( key, value ) { 5764 this._super( key, value ); 5765 if ( key === "source" ) { 5766 this._initSource(); 5767 } 5768 if ( key === "appendTo" ) { 5769 this.menu.element.appendTo( this.document.find( value || "body" )[0] ); 5770 } 5771 if ( key === "disabled" && value && this.xhr ) { 5772 this.xhr.abort(); 5773 } 5774 }, 5775 5776 _isMultiLine: function() { 5777 // Textareas are always multi-line 5778 if ( this.element.is( "textarea" ) ) { 5779 return true; 5780 } 5781 // Inputs are always single-line, even if inside a contentEditable element 5782 // IE also treats inputs as contentEditable 5783 if ( this.element.is( "input" ) ) { 5784 return false; 5785 } 5786 // All other element types are determined by whether or not they're contentEditable 5787 return this.element.prop( "isContentEditable" ); 5788 }, 5789 5790 _initSource: function() { 5791 var array, url, 5792 that = this; 5793 if ( $.isArray(this.options.source) ) { 5794 array = this.options.source; 5795 this.source = function( request, response ) { 5796 response( $.ui.autocomplete.filter( array, request.term ) ); 5797 }; 5798 } else if ( typeof this.options.source === "string" ) { 5799 url = this.options.source; 5800 this.source = function( request, response ) { 5801 if ( that.xhr ) { 5802 that.xhr.abort(); 5803 } 5804 that.xhr = $.ajax({ 5805 url: url, 5806 data: request, 5807 dataType: "json", 5808 success: function( data ) { 5809 response( data ); 5810 }, 5811 error: function() { 5812 response( [] ); 5813 } 5814 }); 5815 }; 5816 } else { 5817 this.source = this.options.source; 5818 } 5819 }, 5820 5821 _searchTimeout: function( event ) { 5822 clearTimeout( this.searching ); 5823 this.searching = this._delay(function() { 5824 // only search if the value has changed 5825 if ( this.term !== this._value() ) { 5826 this.selectedItem = null; 5827 this.search( null, event ); 5828 } 5829 }, this.options.delay ); 5830 }, 5831 5832 search: function( value, event ) { 5833 value = value != null ? value : this._value(); 5834 5835 // always save the actual value, not the one passed as an argument 5836 this.term = this._value(); 5837 5838 if ( value.length < this.options.minLength ) { 5839 return this.close( event ); 5840 } 5841 5842 if ( this._trigger( "search", event ) === false ) { 5843 return; 5844 } 5845 5846 return this._search( value ); 5847 }, 5848 5849 _search: function( value ) { 5850 this.pending++; 5851 this.element.addClass( "ui-autocomplete-loading" ); 5852 this.cancelSearch = false; 5853 5854 this.source( { term: value }, this._response() ); 5855 }, 5856 5857 _response: function() { 5858 var that = this, 5859 index = ++requestIndex; 5860 5861 return function( content ) { 5862 if ( index === requestIndex ) { 5863 that.__response( content ); 5864 } 5865 5866 that.pending--; 5867 if ( !that.pending ) { 5868 that.element.removeClass( "ui-autocomplete-loading" ); 5869 } 5870 }; 5871 }, 5872 5873 __response: function( content ) { 5874 if ( content ) { 5875 content = this._normalize( content ); 5876 } 5877 this._trigger( "response", null, { content: content } ); 5878 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 5879 this._suggest( content ); 5880 this._trigger( "open" ); 5881 } else { 5882 // use ._close() instead of .close() so we don't cancel future searches 5883 this._close(); 5884 } 5885 }, 5886 5887 close: function( event ) { 5888 this.cancelSearch = true; 5889 this._close( event ); 5890 }, 5891 5892 _close: function( event ) { 5893 if ( this.menu.element.is( ":visible" ) ) { 5894 this.menu.element.hide(); 5895 this.menu.blur(); 5896 this.isNewMenu = true; 5897 this._trigger( "close", event ); 5898 } 5899 }, 5900 5901 _change: function( event ) { 5902 if ( this.previous !== this._value() ) { 5903 this._trigger( "change", event, { item: this.selectedItem } ); 5904 } 5905 }, 5906 5907 _normalize: function( items ) { 5908 // assume all items have the right format when the first item is complete 5909 if ( items.length && items[0].label && items[0].value ) { 5910 return items; 5911 } 5912 return $.map( items, function( item ) { 5913 if ( typeof item === "string" ) { 5914 return { 5915 label: item, 5916 value: item 5917 }; 5918 } 5919 return $.extend({ 5920 label: item.label || item.value, 5921 value: item.value || item.label 5922 }, item ); 5923 }); 5924 }, 5925 5926 _suggest: function( items ) { 5927 var ul = this.menu.element 5928 .empty() 5929 .zIndex( this.element.zIndex() + 1 ); 5930 this._renderMenu( ul, items ); 5931 this.menu.refresh(); 5932 5933 // size and position menu 5934 ul.show(); 5935 this._resizeMenu(); 5936 ul.position( $.extend({ 5937 of: this.element 5938 }, this.options.position )); 5939 5940 if ( this.options.autoFocus ) { 5941 this.menu.next(); 5942 } 5943 }, 5944 5945 _resizeMenu: function() { 5946 var ul = this.menu.element; 5947 ul.outerWidth( Math.max( 5948 // Firefox wraps long text (possibly a rounding bug) 5949 // so we add 1px to avoid the wrapping (#7513) 5950 ul.width( "" ).outerWidth() + 1, 5951 this.element.outerWidth() 5952 ) ); 5953 }, 5954 5955 _renderMenu: function( ul, items ) { 5956 var that = this; 5957 $.each( items, function( index, item ) { 5958 that._renderItemData( ul, item ); 5959 }); 5960 }, 5961 5962 _renderItemData: function( ul, item ) { 5963 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 5964 }, 5965 5966 _renderItem: function( ul, item ) { 5967 return $( "<li>" ) 5968 .append( $( "<a>" ).text( item.label ) ) 5969 .appendTo( ul ); 5970 }, 5971 5972 _move: function( direction, event ) { 5973 if ( !this.menu.element.is( ":visible" ) ) { 5974 this.search( null, event ); 5975 return; 5976 } 5977 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 5978 this.menu.isLastItem() && /^next/.test( direction ) ) { 5979 this._value( this.term ); 5980 this.menu.blur(); 5981 return; 5982 } 5983 this.menu[ direction ]( event ); 5984 }, 5985 5986 widget: function() { 5987 return this.menu.element; 5988 }, 5989 5990 _value: function() { 5991 return this.valueMethod.apply( this.element, arguments ); 5992 }, 5993 5994 _keyEvent: function( keyEvent, event ) { 5995 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 5996 this._move( keyEvent, event ); 5997 5998 // prevents moving cursor to beginning/end of the text field in some browsers 5999 event.preventDefault(); 6000 } 6001 } 6002}); 6003 6004$.extend( $.ui.autocomplete, { 6005 escapeRegex: function( value ) { 6006 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6007 }, 6008 filter: function(array, term) { 6009 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 6010 return $.grep( array, function(value) { 6011 return matcher.test( value.label || value.value || value ); 6012 }); 6013 } 6014}); 6015 6016 6017// live region extension, adding a `messages` option 6018// NOTE: This is an experimental API. We are still investigating 6019// a full solution for string manipulation and internationalization. 6020$.widget( "ui.autocomplete", $.ui.autocomplete, { 6021 options: { 6022 messages: { 6023 noResults: "No search results.", 6024 results: function( amount ) { 6025 return amount + ( amount > 1 ? " results are" : " result is" ) + 6026 " available, use up and down arrow keys to navigate."; 6027 } 6028 } 6029 }, 6030 6031 __response: function( content ) { 6032 var message; 6033 this._superApply( arguments ); 6034 if ( this.options.disabled || this.cancelSearch ) { 6035 return; 6036 } 6037 if ( content && content.length ) { 6038 message = this.options.messages.results( content.length ); 6039 } else { 6040 message = this.options.messages.noResults; 6041 } 6042 this.liveRegion.text( message ); 6043 } 6044}); 6045 6046 6047}( jQuery )); 6048(function( $, undefined ) { 6049 6050var lastActive, startXPos, startYPos, clickDragged, 6051 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6052 stateClasses = "ui-state-hover ui-state-active ", 6053 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", 6054 formResetHandler = function() { 6055 var buttons = $( this ).find( ":ui-button" ); 6056 setTimeout(function() { 6057 buttons.button( "refresh" ); 6058 }, 1 ); 6059 }, 6060 radioGroup = function( radio ) { 6061 var name = radio.name, 6062 form = radio.form, 6063 radios = $( [] ); 6064 if ( name ) { 6065 if ( form ) { 6066 radios = $( form ).find( "[name='" + name + "']" ); 6067 } else { 6068 radios = $( "[name='" + name + "']", radio.ownerDocument ) 6069 .filter(function() { 6070 return !this.form; 6071 }); 6072 } 6073 } 6074 return radios; 6075 }; 6076 6077$.widget( "ui.button", { 6078 version: "1.9.2", 6079 defaultElement: "<button>", 6080 options: { 6081 disabled: null, 6082 text: true, 6083 label: null, 6084 icons: { 6085 primary: null, 6086 secondary: null 6087 } 6088 }, 6089 _create: function() { 6090 this.element.closest( "form" ) 6091 .unbind( "reset" + this.eventNamespace ) 6092 .bind( "reset" + this.eventNamespace, formResetHandler ); 6093 6094 if ( typeof this.options.disabled !== "boolean" ) { 6095 this.options.disabled = !!this.element.prop( "disabled" ); 6096 } else { 6097 this.element.prop( "disabled", this.options.disabled ); 6098 } 6099 6100 this._determineButtonType(); 6101 this.hasTitle = !!this.buttonElement.attr( "title" ); 6102 6103 var that = this, 6104 options = this.options, 6105 toggleButton = this.type === "checkbox" || this.type === "radio", 6106 activeClass = !toggleButton ? "ui-state-active" : "", 6107 focusClass = "ui-state-focus"; 6108 6109 if ( options.label === null ) { 6110 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6111 } 6112 6113 this._hoverable( this.buttonElement ); 6114 6115 this.buttonElement 6116 .addClass( baseClasses ) 6117 .attr( "role", "button" ) 6118 .bind( "mouseenter" + this.eventNamespace, function() { 6119 if ( options.disabled ) { 6120 return; 6121 } 6122 if ( this === lastActive ) { 6123 $( this ).addClass( "ui-state-active" ); 6124 } 6125 }) 6126 .bind( "mouseleave" + this.eventNamespace, function() { 6127 if ( options.disabled ) { 6128 return; 6129 } 6130 $( this ).removeClass( activeClass ); 6131 }) 6132 .bind( "click" + this.eventNamespace, function( event ) { 6133 if ( options.disabled ) { 6134 event.preventDefault(); 6135 event.stopImmediatePropagation(); 6136 } 6137 }); 6138 6139 this.element 6140 .bind( "focus" + this.eventNamespace, function() { 6141 // no need to check disabled, focus won't be triggered anyway 6142 that.buttonElement.addClass( focusClass ); 6143 }) 6144 .bind( "blur" + this.eventNamespace, function() { 6145 that.buttonElement.removeClass( focusClass ); 6146 }); 6147 6148 if ( toggleButton ) { 6149 this.element.bind( "change" + this.eventNamespace, function() { 6150 if ( clickDragged ) { 6151 return; 6152 } 6153 that.refresh(); 6154 }); 6155 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 6156 // prevents issue where button state changes but checkbox/radio checked state 6157 // does not in Firefox (see ticket #6970) 6158 this.buttonElement 6159 .bind( "mousedown" + this.eventNamespace, function( event ) { 6160 if ( options.disabled ) { 6161 return; 6162 } 6163 clickDragged = false; 6164 startXPos = event.pageX; 6165 startYPos = event.pageY; 6166 }) 6167 .bind( "mouseup" + this.eventNamespace, function( event ) { 6168 if ( options.disabled ) { 6169 return; 6170 } 6171 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 6172 clickDragged = true; 6173 } 6174 }); 6175 } 6176 6177 if ( this.type === "checkbox" ) { 6178 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6179 if ( options.disabled || clickDragged ) { 6180 return false; 6181 } 6182 $( this ).toggleClass( "ui-state-active" ); 6183 that.buttonElement.attr( "aria-pressed", that.element[0].checked ); 6184 }); 6185 } else if ( this.type === "radio" ) { 6186 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6187 if ( options.disabled || clickDragged ) { 6188 return false; 6189 } 6190 $( this ).addClass( "ui-state-active" ); 6191 that.buttonElement.attr( "aria-pressed", "true" ); 6192 6193 var radio = that.element[ 0 ]; 6194 radioGroup( radio ) 6195 .not( radio ) 6196 .map(function() { 6197 return $( this ).button( "widget" )[ 0 ]; 6198 }) 6199 .removeClass( "ui-state-active" ) 6200 .attr( "aria-pressed", "false" ); 6201 }); 6202 } else { 6203 this.buttonElement 6204 .bind( "mousedown" + this.eventNamespace, function() { 6205 if ( options.disabled ) { 6206 return false; 6207 } 6208 $( this ).addClass( "ui-state-active" ); 6209 lastActive = this; 6210 that.document.one( "mouseup", function() { 6211 lastActive = null; 6212 }); 6213 }) 6214 .bind( "mouseup" + this.eventNamespace, function() { 6215 if ( options.disabled ) { 6216 return false; 6217 } 6218 $( this ).removeClass( "ui-state-active" ); 6219 }) 6220 .bind( "keydown" + this.eventNamespace, function(event) { 6221 if ( options.disabled ) { 6222 return false; 6223 } 6224 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 6225 $( this ).addClass( "ui-state-active" ); 6226 } 6227 }) 6228 .bind( "keyup" + this.eventNamespace, function() { 6229 $( this ).removeClass( "ui-state-active" ); 6230 }); 6231 6232 if ( this.buttonElement.is("a") ) { 6233 this.buttonElement.keyup(function(event) { 6234 if ( event.keyCode === $.ui.keyCode.SPACE ) { 6235 // TODO pass through original event correctly (just as 2nd argument doesn't work) 6236 $( this ).click(); 6237 } 6238 }); 6239 } 6240 } 6241 6242 // TODO: pull out $.Widget's handling for the disabled option into 6243 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 6244 // be overridden by individual plugins 6245 this._setOption( "disabled", options.disabled ); 6246 this._resetButton(); 6247 }, 6248 6249 _determineButtonType: function() { 6250 var ancestor, labelSelector, checked; 6251 6252 if ( this.element.is("[type=checkbox]") ) { 6253 this.type = "checkbox"; 6254 } else if ( this.element.is("[type=radio]") ) { 6255 this.type = "radio"; 6256 } else if ( this.element.is("input") ) { 6257 this.type = "input"; 6258 } else { 6259 this.type = "button"; 6260 } 6261 6262 if ( this.type === "checkbox" || this.type === "radio" ) { 6263 // we don't search against the document in case the element 6264 // is disconnected from the DOM 6265 ancestor = this.element.parents().last(); 6266 labelSelector = "label[for='" + this.element.attr("id") + "']"; 6267 this.buttonElement = ancestor.find( labelSelector ); 6268 if ( !this.buttonElement.length ) { 6269 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 6270 this.buttonElement = ancestor.filter( labelSelector ); 6271 if ( !this.buttonElement.length ) { 6272 this.buttonElement = ancestor.find( labelSelector ); 6273 } 6274 } 6275 this.element.addClass( "ui-helper-hidden-accessible" ); 6276 6277 checked = this.element.is( ":checked" ); 6278 if ( checked ) { 6279 this.buttonElement.addClass( "ui-state-active" ); 6280 } 6281 this.buttonElement.prop( "aria-pressed", checked ); 6282 } else { 6283 this.buttonElement = this.element; 6284 } 6285 }, 6286 6287 widget: function() { 6288 return this.buttonElement; 6289 }, 6290 6291 _destroy: function() { 6292 this.element 6293 .removeClass( "ui-helper-hidden-accessible" ); 6294 this.buttonElement 6295 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 6296 .removeAttr( "role" ) 6297 .removeAttr( "aria-pressed" ) 6298 .html( this.buttonElement.find(".ui-button-text").html() ); 6299 6300 if ( !this.hasTitle ) { 6301 this.buttonElement.removeAttr( "title" ); 6302 } 6303 }, 6304 6305 _setOption: function( key, value ) { 6306 this._super( key, value ); 6307 if ( key === "disabled" ) { 6308 if ( value ) { 6309 this.element.prop( "disabled", true ); 6310 } else { 6311 this.element.prop( "disabled", false ); 6312 } 6313 return; 6314 } 6315 this._resetButton(); 6316 }, 6317 6318 refresh: function() { 6319 //See #8237 & #8828 6320 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 6321 6322 if ( isDisabled !== this.options.disabled ) { 6323 this._setOption( "disabled", isDisabled ); 6324 } 6325 if ( this.type === "radio" ) { 6326 radioGroup( this.element[0] ).each(function() { 6327 if ( $( this ).is( ":checked" ) ) { 6328 $( this ).button( "widget" ) 6329 .addClass( "ui-state-active" ) 6330 .attr( "aria-pressed", "true" ); 6331 } else { 6332 $( this ).button( "widget" ) 6333 .removeClass( "ui-state-active" ) 6334 .attr( "aria-pressed", "false" ); 6335 } 6336 }); 6337 } else if ( this.type === "checkbox" ) { 6338 if ( this.element.is( ":checked" ) ) { 6339 this.buttonElement 6340 .addClass( "ui-state-active" ) 6341 .attr( "aria-pressed", "true" ); 6342 } else { 6343 this.buttonElement 6344 .removeClass( "ui-state-active" ) 6345 .attr( "aria-pressed", "false" ); 6346 } 6347 } 6348 }, 6349 6350 _resetButton: function() { 6351 if ( this.type === "input" ) { 6352 if ( this.options.label ) { 6353 this.element.val( this.options.label ); 6354 } 6355 return; 6356 } 6357 var buttonElement = this.buttonElement.removeClass( typeClasses ), 6358 buttonText = $( "<span></span>", this.document[0] ) 6359 .addClass( "ui-button-text" ) 6360 .html( this.options.label ) 6361 .appendTo( buttonElement.empty() ) 6362 .text(), 6363 icons = this.options.icons, 6364 multipleIcons = icons.primary && icons.secondary, 6365 buttonClasses = []; 6366 6367 if ( icons.primary || icons.secondary ) { 6368 if ( this.options.text ) { 6369 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 6370 } 6371 6372 if ( icons.primary ) { 6373 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 6374 } 6375 6376 if ( icons.secondary ) { 6377 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 6378 } 6379 6380 if ( !this.options.text ) { 6381 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 6382 6383 if ( !this.hasTitle ) { 6384 buttonElement.attr( "title", $.trim( buttonText ) ); 6385 } 6386 } 6387 } else { 6388 buttonClasses.push( "ui-button-text-only" ); 6389 } 6390 buttonElement.addClass( buttonClasses.join( " " ) ); 6391 } 6392}); 6393 6394$.widget( "ui.buttonset", { 6395 version: "1.9.2", 6396 options: { 6397 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)" 6398 }, 6399 6400 _create: function() { 6401 this.element.addClass( "ui-buttonset" ); 6402 }, 6403 6404 _init: function() { 6405 this.refresh();
vendor: 4,388 bytes, lines 6406-6502
6406 }, 6407 6408 _setOption: function( key, value ) { 6409 if ( key === "disabled" ) { 6410 this.buttons.button( "option", key, value ); 6411 } 6412 6413 this._super( key, value ); 6414 }, 6415 6416 refresh: function() { 6417 var rtl = this.element.css( "direction" ) === "rtl"; 6418 6419 this.buttons = this.element.find( this.options.items ) 6420 .filter( ":ui-button" ) 6421 .button( "refresh" ) 6422 .end() 6423 .not( ":ui-button" ) 6424 .button() 6425 .end() 6426 .map(function() { 6427 return $( this ).button( "widget" )[ 0 ]; 6428 }) 6429 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 6430 .filter( ":first" ) 6431 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 6432 .end() 6433 .filter( ":last" ) 6434 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 6435 .end() 6436 .end(); 6437 }, 6438 6439 _destroy: function() { 6440 this.element.removeClass( "ui-buttonset" ); 6441 this.buttons 6442 .map(function() { 6443 return $( this ).button( "widget" )[ 0 ]; 6444 }) 6445 .removeClass( "ui-corner-left ui-corner-right" ) 6446 .end() 6447 .button( "destroy" ); 6448 } 6449}); 6450 6451}( jQuery ) ); 6452(function( $, undefined ) { 6453 6454$.extend($.ui, { datepicker: { version: "1.9.2" } }); 6455 6456var PROP_NAME = 'datepicker'; 6457var dpuuid = new Date().getTime(); 6458var instActive; 6459 6460/* Date picker manager. 6461 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 6462 Settings for (groups of) date pickers are maintained in an instance object, 6463 allowing multiple different settings on the same page. */ 6464 6465function Datepicker() { 6466 this.debug = false; // Change this to true to start debugging 6467 this._curInst = null; // The current instance in use 6468 this._keyEvent = false; // If the last event was a key event 6469 this._disabledInputs = []; // List of date picker inputs that have been disabled 6470 this._datepickerShowing = false; // True if the popup picker is showing , false if not 6471 this._inDialog = false; // True if showing within a "dialog", false if not 6472 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 6473 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 6474 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 6475 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 6476 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 6477 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 6478 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 6479 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 6480 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 6481 this.regional = []; // Available regional settings, indexed by language code 6482 this.regional[''] = { // Default regional settings 6483 closeText: 'Done', // Display text for close link 6484 prevText: 'Prev', // Display text for previous month link 6485 nextText: 'Next', // Display text for next month link 6486 currentText: 'Today', // Display text for current month link 6487 monthNames: ['January','February','March','April','May','June', 6488 'July','August','September','October','November','December'], // Names of months for drop-down and formatting 6489 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 6490 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 6491 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting 6492 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday 6493 weekHeader: 'Wk', // Column header for week of the year 6494 dateFormat: 'mm/dd/yy', // See format options on parseDate 6495 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 6496 isRTL: false, // True if right-to-left language, false if left-to-right 6497 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 6498 yearSuffix: '' // Additional text to append to the year in the month headers 6499 }; 6500 this._defaults = { // Global defaults for all the date picker instances 6501 showOn: 'focus', // 'focus' for popup on focus, 6502 // 'button' for trigger button, or 'both' for either
vendor: 7,167 bytes, lines 6503-6650
6503 showAnim: 'fadeIn', // Name of jQuery animation for popup 6504 showOptions: {}, // Options for enhanced animations 6505 defaultDate: null, // Used when field is blank: actual date, 6506 // +/-number for offset from today, null for today 6507 appendText: '', // Display text following the input box, e.g. showing the format 6508 buttonText: '...', // Text for trigger button 6509 buttonImage: '', // URL for trigger button image 6510 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 6511 hideIfNoPrevNext: false, // True to hide next/previous month links 6512 // if not applicable, false to just disable them 6513 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 6514 gotoCurrent: false, // True if today link goes back to current selection instead 6515 changeMonth: false, // True if month can be selected directly, false if only prev/next 6516 changeYear: false, // True if year can be selected directly, false if only prev/next 6517 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 6518 // either relative to today's year (-nn:+nn), relative to currently displayed year 6519 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 6520 showOtherMonths: false, // True to show dates in other months, false to leave blank 6521 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 6522 showWeek: false, // True to show week of the year, false to not show it 6523 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 6524 // takes a Date and returns the number of the week for it 6525 shortYearCutoff: '+10', // Short year values < this are in the current century, 6526 // > this are in the previous century, 6527 // string value starting with '+' for current year + value 6528 minDate: null, // The earliest selectable date, or null for no limit 6529 maxDate: null, // The latest selectable date, or null for no limit 6530 duration: 'fast', // Duration of display/closure 6531 beforeShowDay: null, // Function that takes a date and returns an array with 6532 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 6533 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 6534 beforeShow: null, // Function that takes an input field and 6535 // returns a set of custom settings for the date picker 6536 onSelect: null, // Define a callback function when a date is selected 6537 onChangeMonthYear: null, // Define a callback function when the month or year is changed 6538 onClose: null, // Define a callback function when the datepicker is closed 6539 numberOfMonths: 1, // Number of months to show at a time 6540 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 6541 stepMonths: 1, // Number of months to step back/forward 6542 stepBigMonths: 12, // Number of months to step back/forward for the big links 6543 altField: '', // Selector for an alternate field to store selected dates into 6544 altFormat: '', // The date format to use for the alternate field 6545 constrainInput: true, // The input is constrained by the current date format 6546 showButtonPanel: false, // True to show button panel, false to not show it 6547 autoSize: false, // True to size the input for the date format, false to leave as is 6548 disabled: false // The initial disabled state 6549 }; 6550 $.extend(this._defaults, this.regional['']); 6551 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 6552} 6553 6554$.extend(Datepicker.prototype, { 6555 /* Class name added to elements to indicate already configured with a date picker. */ 6556 markerClassName: 'hasDatepicker', 6557 6558 //Keep track of the maximum number of rows displayed (see #7043) 6559 maxRows: 4, 6560 6561 /* Debug logging (if enabled). */ 6562 log: function () { 6563 if (this.debug) 6564 console.log.apply('', arguments); 6565 }, 6566 6567 // TODO rename to "widget" when switching to widget factory 6568 _widgetDatepicker: function() { 6569 return this.dpDiv; 6570 }, 6571 6572 /* Override the default settings for all instances of the date picker. 6573 @param settings object - the new settings to use as defaults (anonymous object) 6574 @return the manager object */ 6575 setDefaults: function(settings) { 6576 extendRemove(this._defaults, settings || {}); 6577 return this; 6578 }, 6579 6580 /* Attach the date picker to a jQuery selection. 6581 @param target element - the target input field or division or span 6582 @param settings object - the new settings to use for this date picker instance (anonymous) */ 6583 _attachDatepicker: function(target, settings) { 6584 // check for settings on the control itself - in namespace 'date:' 6585 var inlineSettings = null; 6586 for (var attrName in this._defaults) { 6587 var attrValue = target.getAttribute('date:' + attrName); 6588 if (attrValue) { 6589 inlineSettings = inlineSettings || {}; 6590 try { 6591 inlineSettings[attrName] = eval(attrValue); 6592 } catch (err) { 6593 inlineSettings[attrName] = attrValue; 6594 } 6595 } 6596 } 6597 var nodeName = target.nodeName.toLowerCase(); 6598 var inline = (nodeName == 'div' || nodeName == 'span'); 6599 if (!target.id) { 6600 this.uuid += 1; 6601 target.id = 'dp' + this.uuid; 6602 } 6603 var inst = this._newInst($(target), inline); 6604 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 6605 if (nodeName == 'input') { 6606 this._connectDatepicker(target, inst); 6607 } else if (inline) { 6608 this._inlineDatepicker(target, inst); 6609 } 6610 }, 6611 6612 /* Create a new instance object. */ 6613 _newInst: function(target, inline) { 6614 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars 6615 return {id: id, input: target, // associated target 6616 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 6617 drawMonth: 0, drawYear: 0, // month being drawn 6618 inline: inline, // is datepicker inline or not 6619 dpDiv: (!inline ? this.dpDiv : // presentation div 6620 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; 6621 }, 6622 6623 /* Attach the date picker to an input field. */ 6624 _connectDatepicker: function(target, inst) { 6625 var input = $(target); 6626 inst.append = $([]); 6627 inst.trigger = $([]); 6628 if (input.hasClass(this.markerClassName)) 6629 return; 6630 this._attachments(input, inst); 6631 input.addClass(this.markerClassName).keydown(this._doKeyDown). 6632 keypress(this._doKeyPress).keyup(this._doKeyUp). 6633 bind("setData.datepicker", function(event, key, value) { 6634 inst.settings[key] = value; 6635 }).bind("getData.datepicker", function(event, key) { 6636 return this._get(inst, key); 6637 }); 6638 this._autoSize(inst); 6639 $.data(target, PROP_NAME, inst); 6640 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 6641 if( inst.settings.disabled ) { 6642 this._disableDatepicker( target ); 6643 } 6644 }, 6645 6646 /* Make attachments based on settings. */ 6647 _attachments: function(input, inst) { 6648 var appendText = this._get(inst, 'appendText'); 6649 var isRTL = this._get(inst, 'isRTL'); 6650 if (inst.append)
6651 inst.append.remove(); 6652 if (appendText) { 6653 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); 6654 input[isRTL ? 'before' : 'after'](inst.append); 6655 } 6656 input.unbind('focus', this._showDatepicker); 6657 if (inst.trigger) 6658 inst.trigger.remove(); 6659 var showOn = this._get(inst, 'showOn'); 6660 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 6661 input.focus(this._showDatepicker); 6662 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 6663 var buttonText = this._get(inst, 'buttonText'); 6664 var buttonImage = this._get(inst, 'buttonImage'); 6665 inst.trigger = $(this._get(inst, 'buttonImageOnly') ? 6666 $('<img/>').addClass(this._triggerClass). 6667 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 6668 $('<button type="button"></button>').addClass(this._triggerClass). 6669 html(buttonImage == '' ? buttonText : $('<img/>').attr( 6670 { src:buttonImage, alt:buttonText, title:buttonText }))); 6671 input[isRTL ? 'before' : 'after'](inst.trigger); 6672 inst.trigger.click(function() { 6673 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) 6674 $.datepicker._hideDatepicker(); 6675 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { 6676 $.datepicker._hideDatepicker(); 6677 $.datepicker._showDatepicker(input[0]); 6678 } else 6679 $.datepicker._showDatepicker(input[0]); 6680 return false; 6681 }); 6682 } 6683 }, 6684 6685 /* Apply the maximum length for the date format. */ 6686 _autoSize: function(inst) { 6687 if (this._get(inst, 'autoSize') && !inst.inline) { 6688 var date = new Date(2009, 12 - 1, 20); // Ensure double digits 6689 var dateFormat = this._get(inst, 'dateFormat'); 6690 if (dateFormat.match(/[DM]/)) { 6691 var findMax = function(names) { 6692 var max = 0; 6693 var maxI = 0; 6694 for (var i = 0; i < names.length; i++) { 6695 if (names[i].length > max) { 6696 max = names[i].length; 6697 maxI = i; 6698 } 6699 } 6700 return maxI; 6701 }; 6702 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 6703 'monthNames' : 'monthNamesShort')))); 6704 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 6705 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); 6706 } 6707 inst.input.attr('size', this._formatDate(inst, date).length); 6708 } 6709 }, 6710 6711 /* Attach an inline date picker to a div. */ 6712 _inlineDatepicker: function(target, inst) { 6713 var divSpan = $(target); 6714 if (divSpan.hasClass(this.markerClassName)) 6715 return; 6716 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 6717 bind("setData.datepicker", function(event, key, value){ 6718 inst.settings[key] = value; 6719 }).bind("getData.datepicker", function(event, key){ 6720 return this._get(inst, key); 6721 }); 6722 $.data(target, PROP_NAME, inst); 6723 this._setDate(inst, this._getDefaultDate(inst), true); 6724 this._updateDatepicker(inst); 6725 this._updateAlternate(inst); 6726 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 6727 if( inst.settings.disabled ) { 6728 this._disableDatepicker( target ); 6729 } 6730 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 6731 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 6732 inst.dpDiv.css( "display", "block" ); 6733 }, 6734 6735 /* Pop-up the date picker in a "dialog" box. 6736 @param input element - ignored 6737 @param date string or Date - the initial date to display 6738 @param onSelect function - the function to call when a date is selected 6739 @param settings object - update the dialog date picker instance's settings (anonymous object) 6740 @param pos int[2] - coordinates for the dialog's position within the screen or 6741 event - with x/y coordinates or 6742 leave empty for default (screen centre) 6743 @return the manager object */ 6744 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 6745 var inst = this._dialogInst; // internal instance 6746 if (!inst) { 6747 this.uuid += 1; 6748 var id = 'dp' + this.uuid; 6749 this._dialogInput = $('<input type="text" id="' + id + 6750 '" style="position: absolute; top: -100px; width: 0px;"/>'); 6751 this._dialogInput.keydown(this._doKeyDown); 6752 $('body').append(this._dialogInput); 6753 inst = this._dialogInst = this._newInst(this._dialogInput, false); 6754 inst.settings = {}; 6755 $.data(this._dialogInput[0], PROP_NAME, inst); 6756 } 6757 extendRemove(inst.settings, settings || {}); 6758 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); 6759 this._dialogInput.val(date); 6760 6761 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 6762 if (!this._pos) { 6763 var browserWidth = document.documentElement.clientWidth; 6764 var browserHeight = document.documentElement.clientHeight; 6765 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 6766 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 6767 this._pos = // should use actual width/height below 6768 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 6769 } 6770 6771 // move input on screen for focus, but hidden behind dialog 6772 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); 6773 inst.settings.onSelect = onSelect; 6774 this._inDialog = true; 6775 this.dpDiv.addClass(this._dialogClass); 6776 this._showDatepicker(this._dialogInput[0]); 6777 if ($.blockUI) 6778 $.blockUI(this.dpDiv); 6779 $.data(this._dialogInput[0], PROP_NAME, inst); 6780 return this; 6781 }, 6782 6783 /* Detach a datepicker from its control. 6784 @param target element - the target input field or division or span */ 6785 _destroyDatepicker: function(target) { 6786 var $target = $(target); 6787 var inst = $.data(target, PROP_NAME); 6788 if (!$target.hasClass(this.markerClassName)) { 6789 return; 6790 } 6791 var nodeName = target.nodeName.toLowerCase(); 6792 $.removeData(target, PROP_NAME); 6793 if (nodeName == 'input') {
6794 inst.append.remove(); 6795 inst.trigger.remove(); 6796 $target.removeClass(this.markerClassName). 6797 unbind('focus', this._showDatepicker). 6798 unbind('keydown', this._doKeyDown). 6799 unbind('keypress', this._doKeyPress). 6800 unbind('keyup', this._doKeyUp); 6801 } else if (nodeName == 'div' || nodeName == 'span') 6802 $target.removeClass(this.markerClassName).empty(); 6803 }, 6804 6805 /* Enable the date picker to a jQuery selection. 6806 @param target element - the target input field or division or span */ 6807 _enableDatepicker: function(target) { 6808 var $target = $(target); 6809 var inst = $.data(target, PROP_NAME); 6810 if (!$target.hasClass(this.markerClassName)) { 6811 return; 6812 } 6813 var nodeName = target.nodeName.toLowerCase(); 6814 if (nodeName == 'input') { 6815 target.disabled = false; 6816 inst.trigger.filter('button'). 6817 each(function() { this.disabled = false; }).end(). 6818 filter('img').css({opacity: '1.0', cursor: ''}); 6819 } 6820 else if (nodeName == 'div' || nodeName == 'span') { 6821 var inline = $target.children('.' + this._inlineClass); 6822 inline.children().removeClass('ui-state-disabled'); 6823 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 6824 prop("disabled", false); 6825 } 6826 this._disabledInputs = $.map(this._disabledInputs, 6827 function(value) { return (value == target ? null : value); }); // delete entry 6828 }, 6829 6830 /* Disable the date picker to a jQuery selection. 6831 @param target element - the target input field or division or span */ 6832 _disableDatepicker: function(target) { 6833 var $target = $(target); 6834 var inst = $.data(target, PROP_NAME); 6835 if (!$target.hasClass(this.markerClassName)) { 6836 return; 6837 } 6838 var nodeName = target.nodeName.toLowerCase(); 6839 if (nodeName == 'input') { 6840 target.disabled = true; 6841 inst.trigger.filter('button'). 6842 each(function() { this.disabled = true; }).end(). 6843 filter('img').css({opacity: '0.5', cursor: 'default'}); 6844 } 6845 else if (nodeName == 'div' || nodeName == 'span') { 6846 var inline = $target.children('.' + this._inlineClass); 6847 inline.children().addClass('ui-state-disabled'); 6848 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 6849 prop("disabled", true); 6850 } 6851 this._disabledInputs = $.map(this._disabledInputs, 6852 function(value) { return (value == target ? null : value); }); // delete entry 6853 this._disabledInputs[this._disabledInputs.length] = target; 6854 }, 6855 6856 /* Is the first field in a jQuery collection disabled as a datepicker? 6857 @param target element - the target input field or division or span 6858 @return boolean - true if disabled, false if enabled */ 6859 _isDisabledDatepicker: function(target) { 6860 if (!target) { 6861 return false; 6862 } 6863 for (var i = 0; i < this._disabledInputs.length; i++) { 6864 if (this._disabledInputs[i] == target) 6865 return true; 6866 } 6867 return false; 6868 }, 6869 6870 /* Retrieve the instance data for the target control. 6871 @param target element - the target input field or division or span 6872 @return object - the associated instance data 6873 @throws error if a jQuery problem getting data */ 6874 _getInst: function(target) { 6875 try { 6876 return $.data(target, PROP_NAME); 6877 } 6878 catch (err) { 6879 throw 'Missing instance data for this datepicker'; 6880 } 6881 }, 6882 6883 /* Update or retrieve the settings for a date picker attached to an input field or division. 6884 @param target element - the target input field or division or span 6885 @param name object - the new settings to update or 6886 string - the name of the setting to change or retrieve, 6887 when retrieving also 'all' for all instance settings or 6888 'defaults' for all global defaults 6889 @param value any - the new value for the setting 6890 (omit if above is an object or to retrieve a value) */ 6891 _optionDatepicker: function(target, name, value) { 6892 var inst = this._getInst(target); 6893 if (arguments.length == 2 && typeof name == 'string') { 6894 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : 6895 (inst ? (name == 'all' ? $.extend({}, inst.settings) : 6896 this._get(inst, name)) : null)); 6897 } 6898 var settings = name || {}; 6899 if (typeof name == 'string') { 6900 settings = {}; 6901 settings[name] = value; 6902 } 6903 if (inst) { 6904 if (this._curInst == inst) { 6905 this._hideDatepicker(); 6906 } 6907 var date = this._getDateDatepicker(target, true); 6908 var minDate = this._getMinMaxDate(inst, 'min'); 6909 var maxDate = this._getMinMaxDate(inst, 'max'); 6910 extendRemove(inst.settings, settings); 6911 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 6912 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 6913 inst.settings.minDate = this._formatDate(inst, minDate); 6914 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 6915 inst.settings.maxDate = this._formatDate(inst, maxDate); 6916 this._attachments($(target), inst); 6917 this._autoSize(inst); 6918 this._setDate(inst, date); 6919 this._updateAlternate(inst); 6920 this._updateDatepicker(inst); 6921 } 6922 }, 6923 6924 // change method deprecated 6925 _changeDatepicker: function(target, name, value) { 6926 this._optionDatepicker(target, name, value); 6927 }, 6928 6929 /* Redraw the date picker attached to an input field or division. 6930 @param target element - the target input field or division or span */ 6931 _refreshDatepicker: function(target) { 6932 var inst = this._getInst(target); 6933 if (inst) { 6934 this._updateDatepicker(inst); 6935 } 6936 }, 6937 6938 /* Set the dates for a jQuery selection. 6939 @param target element - the target input field or division or span 6940 @param date Date - the new date */ 6941 _setDateDatepicker: function(target, date) { 6942 var inst = this._getInst(target); 6943 if (inst) { 6944 this._setDate(inst, date); 6945 this._updateDatepicker(inst); 6946 this._updateAlternate(inst); 6947 } 6948 }, 6949 6950 /* Get the date(s) for the first entry in a jQuery selection. 6951 @param target element - the target input field or division or span 6952 @param noDefault boolean - true if no default date is to be used 6953 @return Date - the current date */ 6954 _getDateDatepicker: function(target, noDefault) { 6955 var inst = this._getInst(target); 6956 if (inst && !inst.inline) 6957 this._setDateFromField(inst, noDefault); 6958 return (inst ? this._getDate(inst) : null); 6959 }, 6960 6961 /* Handle keystrokes. */ 6962 _doKeyDown: function(event) { 6963 var inst = $.datepicker._getInst(event.target); 6964 var handled = true; 6965 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); 6966 inst._keyEvent = true; 6967 if ($.datepicker._datepickerShowing) 6968 switch (event.keyCode) { 6969 case 9: $.datepicker._hideDatepicker(); 6970 handled = false; 6971 break; // hide on tab out 6972 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 6973 $.datepicker._currentClass + ')', inst.dpDiv); 6974 if (sel[0]) 6975 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 6976 var onSelect = $.datepicker._get(inst, 'onSelect'); 6977 if (onSelect) { 6978 var dateStr = $.datepicker._formatDate(inst); 6979 6980 // trigger custom callback 6981 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 6982 } 6983 else 6984 $.datepicker._hideDatepicker(); 6985 return false; // don't submit the form 6986 break; // select the value on enter 6987 case 27: $.datepicker._hideDatepicker(); 6988 break; // hide on escape 6989 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 6990 -$.datepicker._get(inst, 'stepBigMonths') : 6991 -$.datepicker._get(inst, 'stepMonths')), 'M'); 6992 break; // previous month/year on page up/+ ctrl 6993 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 6994 +$.datepicker._get(inst, 'stepBigMonths') : 6995 +$.datepicker._get(inst, 'stepMonths')), 'M'); 6996 break; // next month/year on page down/+ ctrl 6997 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 6998 handled = event.ctrlKey || event.metaKey; 6999 break; // clear on ctrl or command +end 7000 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 7001 handled = event.ctrlKey || event.metaKey; 7002 break; // current on ctrl or command +home 7003 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); 7004 handled = event.ctrlKey || event.metaKey; 7005 // -1 day on ctrl or command +left 7006 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7007 -$.datepicker._get(inst, 'stepBigMonths') : 7008 -$.datepicker._get(inst, 'stepMonths')), 'M'); 7009 // next month/year on alt +left on Mac 7010 break; 7011 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 7012 handled = event.ctrlKey || event.metaKey; 7013 break; // -1 week on ctrl or command +up 7014 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); 7015 handled = event.ctrlKey || event.metaKey; 7016 // +1 day on ctrl or command +right 7017 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7018 +$.datepicker._get(inst, 'stepBigMonths') : 7019 +$.datepicker._get(inst, 'stepMonths')), 'M'); 7020 // next month/year on alt +right 7021 break; 7022 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 7023 handled = event.ctrlKey || event.metaKey; 7024 break; // +1 week on ctrl or command +down 7025 default: handled = false; 7026 } 7027 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 7028 $.datepicker._showDatepicker(this); 7029 else { 7030 handled = false; 7031 } 7032 if (handled) { 7033 event.preventDefault(); 7034 event.stopPropagation(); 7035 } 7036 }, 7037 7038 /* Filter entered characters - based on date format. */ 7039 _doKeyPress: function(event) { 7040 var inst = $.datepicker._getInst(event.target); 7041 if ($.datepicker._get(inst, 'constrainInput')) { 7042 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
vendor: 27,447 bytes, lines 7043-7774
7043 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 7044 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 7045 } 7046 }, 7047 7048 /* Synchronise manual entry and field/alternate field. */ 7049 _doKeyUp: function(event) { 7050 var inst = $.datepicker._getInst(event.target); 7051 if (inst.input.val() != inst.lastVal) { 7052 try { 7053 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 7054 (inst.input ? inst.input.val() : null), 7055 $.datepicker._getFormatConfig(inst)); 7056 if (date) { // only if valid 7057 $.datepicker._setDateFromField(inst); 7058 $.datepicker._updateAlternate(inst); 7059 $.datepicker._updateDatepicker(inst); 7060 } 7061 } 7062 catch (err) { 7063 $.datepicker.log(err); 7064 } 7065 } 7066 return true; 7067 }, 7068 7069 /* Pop-up the date picker for a given input field. 7070 If false returned from beforeShow event handler do not show. 7071 @param input element - the input field attached to the date picker or 7072 event - if triggered by focus */ 7073 _showDatepicker: function(input) { 7074 input = input.target || input; 7075 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 7076 input = $('input', input.parentNode)[0]; 7077 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 7078 return; 7079 var inst = $.datepicker._getInst(input); 7080 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 7081 $.datepicker._curInst.dpDiv.stop(true, true); 7082 if ( inst && $.datepicker._datepickerShowing ) { 7083 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 7084 } 7085 } 7086 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 7087 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7088 if(beforeShowSettings === false){ 7089 //false 7090 return; 7091 } 7092 extendRemove(inst.settings, beforeShowSettings); 7093 inst.lastVal = null; 7094 $.datepicker._lastInput = input; 7095 $.datepicker._setDateFromField(inst); 7096 if ($.datepicker._inDialog) // hide cursor 7097 input.value = ''; 7098 if (!$.datepicker._pos) { // position below input 7099 $.datepicker._pos = $.datepicker._findPos(input); 7100 $.datepicker._pos[1] += input.offsetHeight; // add the height 7101 } 7102 var isFixed = false; 7103 $(input).parents().each(function() { 7104 isFixed |= $(this).css('position') == 'fixed'; 7105 return !isFixed; 7106 }); 7107 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 7108 $.datepicker._pos = null; 7109 //to avoid flashes on Firefox 7110 inst.dpDiv.empty(); 7111 // determine sizing offscreen 7112 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); 7113 $.datepicker._updateDatepicker(inst); 7114 // fix width for dynamic number of date pickers 7115 // and adjust position before showing 7116 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7117 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 7118 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 7119 left: offset.left + 'px', top: offset.top + 'px'}); 7120 if (!inst.inline) { 7121 var showAnim = $.datepicker._get(inst, 'showAnim'); 7122 var duration = $.datepicker._get(inst, 'duration'); 7123 var postProcess = function() { 7124 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7125 if( !! cover.length ){ 7126 var borders = $.datepicker._getBorders(inst.dpDiv); 7127 cover.css({left: -borders[0], top: -borders[1], 7128 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); 7129 } 7130 }; 7131 inst.dpDiv.zIndex($(input).zIndex()+1); 7132 $.datepicker._datepickerShowing = true; 7133 7134 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7135 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 7136 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 7137 else 7138 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); 7139 if (!showAnim || !duration) 7140 postProcess(); 7141 if (inst.input.is(':visible') && !inst.input.is(':disabled')) 7142 inst.input.focus(); 7143 $.datepicker._curInst = inst; 7144 } 7145 }, 7146 7147 /* Generate the date picker content. */ 7148 _updateDatepicker: function(inst) { 7149 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 7150 var borders = $.datepicker._getBorders(inst.dpDiv); 7151 instActive = inst; // for delegate hover events 7152 inst.dpDiv.empty().append(this._generateHTML(inst)); 7153 this._attachHandlers(inst); 7154 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 7155 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 7156 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) 7157 } 7158 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 7159 var numMonths = this._getNumberOfMonths(inst); 7160 var cols = numMonths[1]; 7161 var width = 17; 7162 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 7163 if (cols > 1) 7164 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 7165 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 7166 'Class']('ui-datepicker-multi'); 7167 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 7168 'Class']('ui-datepicker-rtl'); 7169 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 7170 // #6694 - don't focus the input if it's already focused 7171 // this breaks the change event in IE 7172 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) 7173 inst.input.focus(); 7174 // deffered render of the years select (to avoid flashes on Firefox) 7175 if( inst.yearshtml ){ 7176 var origyearshtml = inst.yearshtml; 7177 setTimeout(function(){ 7178 //assure that inst.yearshtml didn't change. 7179 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 7180 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 7181 } 7182 origyearshtml = inst.yearshtml = null; 7183 }, 0); 7184 } 7185 }, 7186 7187 /* Retrieve the size of left and top borders for an element. 7188 @param elem (jQuery object) the element of interest 7189 @return (number[2]) the left and top borders */ 7190 _getBorders: function(elem) { 7191 var convert = function(value) { 7192 return {thin: 1, medium: 2, thick: 3}[value] || value; 7193 }; 7194 return [parseFloat(convert(elem.css('border-left-width'))), 7195 parseFloat(convert(elem.css('border-top-width')))]; 7196 }, 7197 7198 /* Check positioning to remain on screen. */ 7199 _checkOffset: function(inst, offset, isFixed) { 7200 var dpWidth = inst.dpDiv.outerWidth(); 7201 var dpHeight = inst.dpDiv.outerHeight(); 7202 var inputWidth = inst.input ? inst.input.outerWidth() : 0; 7203 var inputHeight = inst.input ? inst.input.outerHeight() : 0; 7204 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); 7205 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 7206 7207 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); 7208 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; 7209 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 7210 7211 // now check if datepicker is showing outside window viewport - move to a better place if so. 7212 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 7213 Math.abs(offset.left + dpWidth - viewWidth) : 0); 7214 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 7215 Math.abs(dpHeight + inputHeight) : 0); 7216 7217 return offset; 7218 }, 7219 7220 /* Find an object's position on the screen. */ 7221 _findPos: function(obj) { 7222 var inst = this._getInst(obj); 7223 var isRTL = this._get(inst, 'isRTL'); 7224 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { 7225 obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; 7226 } 7227 var position = $(obj).offset(); 7228 return [position.left, position.top]; 7229 }, 7230 7231 /* Hide the date picker from view. 7232 @param input element - the input field attached to the date picker */ 7233 _hideDatepicker: function(input) { 7234 var inst = this._curInst; 7235 if (!inst || (input && inst != $.data(input, PROP_NAME))) 7236 return; 7237 if (this._datepickerShowing) { 7238 var showAnim = this._get(inst, 'showAnim'); 7239 var duration = this._get(inst, 'duration'); 7240 var postProcess = function() { 7241 $.datepicker._tidyDialog(inst); 7242 }; 7243 7244 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7245 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 7246 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 7247 else 7248 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : 7249 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); 7250 if (!showAnim) 7251 postProcess(); 7252 this._datepickerShowing = false; 7253 var onClose = this._get(inst, 'onClose'); 7254 if (onClose) 7255 onClose.apply((inst.input ? inst.input[0] : null), 7256 [(inst.input ? inst.input.val() : ''), inst]); 7257 this._lastInput = null; 7258 if (this._inDialog) { 7259 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 7260 if ($.blockUI) { 7261 $.unblockUI(); 7262 $('body').append(this.dpDiv); 7263 } 7264 } 7265 this._inDialog = false; 7266 } 7267 }, 7268 7269 /* Tidy up after a dialog display. */ 7270 _tidyDialog: function(inst) { 7271 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); 7272 }, 7273 7274 /* Close date picker if clicked elsewhere. */ 7275 _checkExternalClick: function(event) { 7276 if (!$.datepicker._curInst) 7277 return; 7278 7279 var $target = $(event.target), 7280 inst = $.datepicker._getInst($target[0]); 7281 7282 if ( ( ( $target[0].id != $.datepicker._mainDivId && 7283 $target.parents('#' + $.datepicker._mainDivId).length == 0 && 7284 !$target.hasClass($.datepicker.markerClassName) && 7285 !$target.closest("." + $.datepicker._triggerClass).length && 7286 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 7287 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) 7288 $.datepicker._hideDatepicker(); 7289 }, 7290 7291 /* Adjust one of the date sub-fields. */ 7292 _adjustDate: function(id, offset, period) { 7293 var target = $(id); 7294 var inst = this._getInst(target[0]); 7295 if (this._isDisabledDatepicker(target[0])) { 7296 return; 7297 } 7298 this._adjustInstDate(inst, offset + 7299 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning 7300 period); 7301 this._updateDatepicker(inst); 7302 }, 7303 7304 /* Action for current link. */ 7305 _gotoToday: function(id) { 7306 var target = $(id); 7307 var inst = this._getInst(target[0]); 7308 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 7309 inst.selectedDay = inst.currentDay; 7310 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 7311 inst.drawYear = inst.selectedYear = inst.currentYear; 7312 } 7313 else { 7314 var date = new Date(); 7315 inst.selectedDay = date.getDate(); 7316 inst.drawMonth = inst.selectedMonth = date.getMonth(); 7317 inst.drawYear = inst.selectedYear = date.getFullYear(); 7318 } 7319 this._notifyChange(inst); 7320 this._adjustDate(target); 7321 }, 7322 7323 /* Action for selecting a new month/year. */ 7324 _selectMonthYear: function(id, select, period) { 7325 var target = $(id); 7326 var inst = this._getInst(target[0]); 7327 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 7328 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 7329 parseInt(select.options[select.selectedIndex].value,10); 7330 this._notifyChange(inst); 7331 this._adjustDate(target); 7332 }, 7333 7334 /* Action for selecting a day. */ 7335 _selectDay: function(id, month, year, td) { 7336 var target = $(id); 7337 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 7338 return; 7339 } 7340 var inst = this._getInst(target[0]); 7341 inst.selectedDay = inst.currentDay = $('a', td).html(); 7342 inst.selectedMonth = inst.currentMonth = month; 7343 inst.selectedYear = inst.currentYear = year; 7344 this._selectDate(id, this._formatDate(inst, 7345 inst.currentDay, inst.currentMonth, inst.currentYear)); 7346 }, 7347 7348 /* Erase the input field and hide the date picker. */ 7349 _clearDate: function(id) { 7350 var target = $(id); 7351 var inst = this._getInst(target[0]); 7352 this._selectDate(target, ''); 7353 }, 7354 7355 /* Update the input field with the selected date. */ 7356 _selectDate: function(id, dateStr) { 7357 var target = $(id); 7358 var inst = this._getInst(target[0]); 7359 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 7360 if (inst.input) 7361 inst.input.val(dateStr); 7362 this._updateAlternate(inst); 7363 var onSelect = this._get(inst, 'onSelect'); 7364 if (onSelect) 7365 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 7366 else if (inst.input) 7367 inst.input.trigger('change'); // fire the change event 7368 if (inst.inline) 7369 this._updateDatepicker(inst); 7370 else { 7371 this._hideDatepicker(); 7372 this._lastInput = inst.input[0]; 7373 if (typeof(inst.input[0]) != 'object') 7374 inst.input.focus(); // restore focus 7375 this._lastInput = null; 7376 } 7377 }, 7378 7379 /* Update any alternate field to synchronise with the main field. */ 7380 _updateAlternate: function(inst) { 7381 var altField = this._get(inst, 'altField'); 7382 if (altField) { // update alternate field too 7383 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 7384 var date = this._getDate(inst); 7385 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 7386 $(altField).each(function() { $(this).val(dateStr); }); 7387 } 7388 }, 7389 7390 /* Set as beforeShowDay function to prevent selection of weekends. 7391 @param date Date - the date to customise 7392 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 7393 noWeekends: function(date) { 7394 var day = date.getDay(); 7395 return [(day > 0 && day < 6), '']; 7396 }, 7397 7398 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 7399 @param date Date - the date to get the week for 7400 @return number - the number of the week within the year that contains this date */ 7401 iso8601Week: function(date) { 7402 var checkDate = new Date(date.getTime()); 7403 // Find Thursday of this week starting on Monday 7404 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 7405 var time = checkDate.getTime(); 7406 checkDate.setMonth(0); // Compare with Jan 1 7407 checkDate.setDate(1); 7408 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 7409 }, 7410 7411 /* Parse a string value into a date object. 7412 See formatDate below for the possible formats. 7413 7414 @param format string - the expected format of the date 7415 @param value string - the date in the above format 7416 @param settings Object - attributes include: 7417 shortYearCutoff number - the cutoff year for determining the century (optional) 7418 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 7419 dayNames string[7] - names of the days from Sunday (optional) 7420 monthNamesShort string[12] - abbreviated names of the months (optional) 7421 monthNames string[12] - names of the months (optional) 7422 @return Date - the extracted date value or null if value is blank */ 7423 parseDate: function (format, value, settings) { 7424 if (format == null || value == null) 7425 throw 'Invalid arguments'; 7426 value = (typeof value == 'object' ? value.toString() : value + ''); 7427 if (value == '') 7428 return null; 7429 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 7430 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 7431 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 7432 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 7433 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 7434 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 7435 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 7436 var year = -1; 7437 var month = -1; 7438 var day = -1; 7439 var doy = -1; 7440 var literal = false; 7441 // Check whether a format character is doubled 7442 var lookAhead = function(match) { 7443 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 7444 if (matches) 7445 iFormat++; 7446 return matches; 7447 }; 7448 // Extract a number from the string value 7449 var getNumber = function(match) { 7450 var isDoubled = lookAhead(match); 7451 var size = (match == '@' ? 14 : (match == '!' ? 20 : 7452 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); 7453 var digits = new RegExp('^\\d{1,' + size + '}'); 7454 var num = value.substring(iValue).match(digits); 7455 if (!num) 7456 throw 'Missing number at position ' + iValue; 7457 iValue += num[0].length; 7458 return parseInt(num[0], 10); 7459 }; 7460 // Extract a name from the string value and convert to an index 7461 var getName = function(match, shortNames, longNames) { 7462 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 7463 return [ [k, v] ]; 7464 }).sort(function (a, b) { 7465 return -(a[1].length - b[1].length); 7466 }); 7467 var index = -1; 7468 $.each(names, function (i, pair) { 7469 var name = pair[1]; 7470 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 7471 index = pair[0]; 7472 iValue += name.length; 7473 return false; 7474 } 7475 }); 7476 if (index != -1) 7477 return index + 1; 7478 else 7479 throw 'Unknown name at position ' + iValue; 7480 }; 7481 // Confirm that a literal character matches the string value 7482 var checkLiteral = function() { 7483 if (value.charAt(iValue) != format.charAt(iFormat)) 7484 throw 'Unexpected literal at position ' + iValue; 7485 iValue++; 7486 }; 7487 var iValue = 0; 7488 for (var iFormat = 0; iFormat < format.length; iFormat++) { 7489 if (literal) 7490 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 7491 literal = false; 7492 else 7493 checkLiteral(); 7494 else 7495 switch (format.charAt(iFormat)) { 7496 case 'd': 7497 day = getNumber('d'); 7498 break; 7499 case 'D': 7500 getName('D', dayNamesShort, dayNames); 7501 break; 7502 case 'o': 7503 doy = getNumber('o'); 7504 break; 7505 case 'm': 7506 month = getNumber('m'); 7507 break; 7508 case 'M': 7509 month = getName('M', monthNamesShort, monthNames); 7510 break; 7511 case 'y': 7512 year = getNumber('y'); 7513 break; 7514 case '@': 7515 var date = new Date(getNumber('@')); 7516 year = date.getFullYear(); 7517 month = date.getMonth() + 1; 7518 day = date.getDate(); 7519 break; 7520 case '!': 7521 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); 7522 year = date.getFullYear(); 7523 month = date.getMonth() + 1; 7524 day = date.getDate(); 7525 break; 7526 case "'": 7527 if (lookAhead("'")) 7528 checkLiteral(); 7529 else 7530 literal = true; 7531 break; 7532 default: 7533 checkLiteral(); 7534 } 7535 } 7536 if (iValue < value.length){ 7537 var extra = value.substr(iValue); 7538 if (!/^\s+/.test(extra)) { 7539 throw "Extra/unparsed characters found in date: " + extra; 7540 } 7541 } 7542 if (year == -1) 7543 year = new Date().getFullYear(); 7544 else if (year < 100) 7545 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 7546 (year <= shortYearCutoff ? 0 : -100); 7547 if (doy > -1) { 7548 month = 1; 7549 day = doy; 7550 do { 7551 var dim = this._getDaysInMonth(year, month - 1); 7552 if (day <= dim) 7553 break; 7554 month++; 7555 day -= dim; 7556 } while (true); 7557 } 7558 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 7559 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 7560 throw 'Invalid date'; // E.g. 31/02/00 7561 return date; 7562 }, 7563 7564 /* Standard date formats. */ 7565 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 7566 COOKIE: 'D, dd M yy', 7567 ISO_8601: 'yy-mm-dd', 7568 RFC_822: 'D, d M y', 7569 RFC_850: 'DD, dd-M-y', 7570 RFC_1036: 'D, d M y', 7571 RFC_1123: 'D, d M yy', 7572 RFC_2822: 'D, d M yy', 7573 RSS: 'D, d M y', // RFC 822 7574 TICKS: '!', 7575 TIMESTAMP: '@', 7576 W3C: 'yy-mm-dd', // ISO 8601 7577 7578 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 7579 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 7580 7581 /* Format a date object into a string value. 7582 The format can be combinations of the following: 7583 d - day of month (no leading zero) 7584 dd - day of month (two digit) 7585 o - day of year (no leading zeros) 7586 oo - day of year (three digit) 7587 D - day name short 7588 DD - day name long 7589 m - month of year (no leading zero) 7590 mm - month of year (two digit) 7591 M - month name short 7592 MM - month name long 7593 y - year (two digit) 7594 yy - year (four digit) 7595 @ - Unix timestamp (ms since 01/01/1970) 7596 ! - Windows ticks (100ns since 01/01/0001) 7597 '...' - literal text 7598 '' - single quote 7599 7600 @param format string - the desired format of the date 7601 @param date Date - the date value to format 7602 @param settings Object - attributes include: 7603 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 7604 dayNames string[7] - names of the days from Sunday (optional) 7605 monthNamesShort string[12] - abbreviated names of the months (optional) 7606 monthNames string[12] - names of the months (optional) 7607 @return string - the date in the above format */ 7608 formatDate: function (format, date, settings) { 7609 if (!date) 7610 return ''; 7611 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 7612 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 7613 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 7614 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 7615 // Check whether a format character is doubled 7616 var lookAhead = function(match) { 7617 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 7618 if (matches) 7619 iFormat++; 7620 return matches; 7621 }; 7622 // Format a number, with leading zero if necessary 7623 var formatNumber = function(match, value, len) { 7624 var num = '' + value; 7625 if (lookAhead(match)) 7626 while (num.length < len) 7627 num = '0' + num; 7628 return num; 7629 }; 7630 // Format a name, short or long as requested 7631 var formatName = function(match, value, shortNames, longNames) { 7632 return (lookAhead(match) ? longNames[value] : shortNames[value]); 7633 }; 7634 var output = ''; 7635 var literal = false; 7636 if (date) 7637 for (var iFormat = 0; iFormat < format.length; iFormat++) { 7638 if (literal) 7639 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 7640 literal = false; 7641 else 7642 output += format.charAt(iFormat); 7643 else 7644 switch (format.charAt(iFormat)) { 7645 case 'd': 7646 output += formatNumber('d', date.getDate(), 2); 7647 break; 7648 case 'D': 7649 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 7650 break; 7651 case 'o': 7652 output += formatNumber('o', 7653 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 7654 break; 7655 case 'm': 7656 output += formatNumber('m', date.getMonth() + 1, 2); 7657 break; 7658 case 'M': 7659 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 7660 break; 7661 case 'y': 7662 output += (lookAhead('y') ? date.getFullYear() : 7663 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 7664 break; 7665 case '@': 7666 output += date.getTime(); 7667 break; 7668 case '!': 7669 output += date.getTime() * 10000 + this._ticksTo1970; 7670 break; 7671 case "'": 7672 if (lookAhead("'")) 7673 output += "'"; 7674 else 7675 literal = true; 7676 break; 7677 default: 7678 output += format.charAt(iFormat); 7679 } 7680 } 7681 return output; 7682 }, 7683 7684 /* Extract all possible characters from the date format. */ 7685 _possibleChars: function (format) { 7686 var chars = ''; 7687 var literal = false; 7688 // Check whether a format character is doubled 7689 var lookAhead = function(match) { 7690 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 7691 if (matches) 7692 iFormat++; 7693 return matches; 7694 }; 7695 for (var iFormat = 0; iFormat < format.length; iFormat++) 7696 if (literal) 7697 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 7698 literal = false; 7699 else 7700 chars += format.charAt(iFormat); 7701 else 7702 switch (format.charAt(iFormat)) { 7703 case 'd': case 'm': case 'y': case '@': 7704 chars += '0123456789'; 7705 break; 7706 case 'D': case 'M': 7707 return null; // Accept anything 7708 case "'": 7709 if (lookAhead("'")) 7710 chars += "'"; 7711 else 7712 literal = true; 7713 break; 7714 default: 7715 chars += format.charAt(iFormat); 7716 } 7717 return chars; 7718 }, 7719 7720 /* Get a setting value, defaulting if necessary. */ 7721 _get: function(inst, name) { 7722 return inst.settings[name] !== undefined ? 7723 inst.settings[name] : this._defaults[name]; 7724 }, 7725 7726 /* Parse existing date and initialise date picker. */ 7727 _setDateFromField: function(inst, noDefault) { 7728 if (inst.input.val() == inst.lastVal) { 7729 return; 7730 } 7731 var dateFormat = this._get(inst, 'dateFormat'); 7732 var dates = inst.lastVal = inst.input ? inst.input.val() : null; 7733 var date, defaultDate; 7734 date = defaultDate = this._getDefaultDate(inst); 7735 var settings = this._getFormatConfig(inst); 7736 try { 7737 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 7738 } catch (event) { 7739 this.log(event); 7740 dates = (noDefault ? '' : dates); 7741 } 7742 inst.selectedDay = date.getDate(); 7743 inst.drawMonth = inst.selectedMonth = date.getMonth(); 7744 inst.drawYear = inst.selectedYear = date.getFullYear(); 7745 inst.currentDay = (dates ? date.getDate() : 0); 7746 inst.currentMonth = (dates ? date.getMonth() : 0); 7747 inst.currentYear = (dates ? date.getFullYear() : 0); 7748 this._adjustInstDate(inst); 7749 }, 7750 7751 /* Retrieve the default date shown on opening. */ 7752 _getDefaultDate: function(inst) { 7753 return this._restrictMinMax(inst, 7754 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); 7755 }, 7756 7757 /* A date may be specified as an exact value or a relative one. */ 7758 _determineDate: function(inst, date, defaultDate) { 7759 var offsetNumeric = function(offset) { 7760 var date = new Date(); 7761 date.setDate(date.getDate() + offset); 7762 return date; 7763 }; 7764 var offsetString = function(offset) { 7765 try { 7766 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 7767 offset, $.datepicker._getFormatConfig(inst)); 7768 } 7769 catch (e) { 7770 // Ignore 7771 } 7772 var date = (offset.toLowerCase().match(/^c/) ? 7773 $.datepicker._getDate(inst) : null) || new Date(); 7774 var year = date.getFullYear();
7775 var month = date.getMonth(); 7776 var day = date.getDate(); 7777 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 7778 var matches = pattern.exec(offset); 7779 while (matches) { 7780 switch (matches[2] || 'd') { 7781 case 'd' : case 'D' : 7782 day += parseInt(matches[1],10); break; 7783 case 'w' : case 'W' : 7784 day += parseInt(matches[1],10) * 7; break; 7785 case 'm' : case 'M' : 7786 month += parseInt(matches[1],10); 7787 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 7788 break; 7789 case 'y': case 'Y' : 7790 year += parseInt(matches[1],10); 7791 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 7792 break; 7793 } 7794 matches = pattern.exec(offset); 7795 } 7796 return new Date(year, month, day); 7797 }; 7798 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : 7799 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 7800 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); 7801 if (newDate) { 7802 newDate.setHours(0); 7803 newDate.setMinutes(0); 7804 newDate.setSeconds(0); 7805 newDate.setMilliseconds(0); 7806 } 7807 return this._daylightSavingAdjust(newDate); 7808 }, 7809 7810 /* Handle switch to/from daylight saving. 7811 Hours may be non-zero on daylight saving cut-over: 7812 > 12 when midnight changeover, but then cannot generate 7813 midnight datetime, so jump to 1AM, otherwise reset. 7814 @param date (Date) the date to check 7815 @return (Date) the corrected date */ 7816 _daylightSavingAdjust: function(date) { 7817 if (!date) return null; 7818 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 7819 return date; 7820 }, 7821 7822 /* Set the date(s) directly. */ 7823 _setDate: function(inst, date, noChange) { 7824 var clear = !date; 7825 var origMonth = inst.selectedMonth; 7826 var origYear = inst.selectedYear; 7827 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 7828 inst.selectedDay = inst.currentDay = newDate.getDate(); 7829 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 7830 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 7831 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) 7832 this._notifyChange(inst); 7833 this._adjustInstDate(inst); 7834 if (inst.input) { 7835 inst.input.val(clear ? '' : this._formatDate(inst)); 7836 } 7837 }, 7838 7839 /* Retrieve the date(s) directly. */ 7840 _getDate: function(inst) { 7841 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 7842 this._daylightSavingAdjust(new Date( 7843 inst.currentYear, inst.currentMonth, inst.currentDay))); 7844 return startDate; 7845 }, 7846 7847 /* Attach the onxxx handlers. These are declared statically so 7848 * they work with static code transformers like Caja. 7849 */ 7850 _attachHandlers: function(inst) { 7851 var stepMonths = this._get(inst, 'stepMonths'); 7852 var id = '#' + inst.id.replace( /\\\\/g, "\\" ); 7853 inst.dpDiv.find('[data-handler]').map(function () { 7854 var handler = { 7855 prev: function () { 7856 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); 7857 }, 7858 next: function () { 7859 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); 7860 }, 7861 hide: function () { 7862 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); 7863 }, 7864 today: function () { 7865 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); 7866 }, 7867 selectDay: function () { 7868 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); 7869 return false; 7870 }, 7871 selectMonth: function () { 7872 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); 7873 return false; 7874 }, 7875 selectYear: function () { 7876 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); 7877 return false; 7878 } 7879 }; 7880 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); 7881 }); 7882 }, 7883 7884 /* Generate the HTML for the current state of the date picker. */ 7885 _generateHTML: function(inst) { 7886 var today = new Date(); 7887 today = this._daylightSavingAdjust( 7888 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 7889 var isRTL = this._get(inst, 'isRTL'); 7890 var showButtonPanel = this._get(inst, 'showButtonPanel'); 7891 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 7892 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 7893 var numMonths = this._getNumberOfMonths(inst); 7894 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 7895 var stepMonths = this._get(inst, 'stepMonths'); 7896 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 7897 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 7898 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 7899 var minDate = this._getMinMaxDate(inst, 'min'); 7900 var maxDate = this._getMinMaxDate(inst, 'max'); 7901 var drawMonth = inst.drawMonth - showCurrentAtPos; 7902 var drawYear = inst.drawYear; 7903 if (drawMonth < 0) { 7904 drawMonth += 12; 7905 drawYear--; 7906 } 7907 if (maxDate) { 7908 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 7909 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 7910 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 7911 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 7912 drawMonth--; 7913 if (drawMonth < 0) { 7914 drawMonth = 11; 7915 drawYear--; 7916 } 7917 } 7918 } 7919 inst.drawMonth = drawMonth; 7920 inst.drawYear = drawYear; 7921 var prevText = this._get(inst, 'prevText'); 7922 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 7923 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 7924 this._getFormatConfig(inst))); 7925 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 7926 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + 7927 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : 7928 (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>')); 7929 var nextText = this._get(inst, 'nextText'); 7930 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 7931 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 7932 this._getFormatConfig(inst))); 7933 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 7934 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + 7935 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : 7936 (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>')); 7937 var currentText = this._get(inst, 'currentText'); 7938 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 7939 currentText = (!navigationAsDateFormat ? currentText : 7940 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 7941 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">' + 7942 this._get(inst, 'closeText') + '</button>' : ''); 7943 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + 7944 (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"' + 7945 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; 7946 var firstDay = parseInt(this._get(inst, 'firstDay'),10); 7947 firstDay = (isNaN(firstDay) ? 0 : firstDay); 7948 var showWeek = this._get(inst, 'showWeek'); 7949 var dayNames = this._get(inst, 'dayNames'); 7950 var dayNamesShort = this._get(inst, 'dayNamesShort'); 7951 var dayNamesMin = this._get(inst, 'dayNamesMin'); 7952 var monthNames = this._get(inst, 'monthNames'); 7953 var monthNamesShort = this._get(inst, 'monthNamesShort'); 7954 var beforeShowDay = this._get(inst, 'beforeShowDay'); 7955 var showOtherMonths = this._get(inst, 'showOtherMonths'); 7956 var selectOtherMonths = this._get(inst, 'selectOtherMonths'); 7957 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 7958 var defaultDate = this._getDefaultDate(inst); 7959 var html = ''; 7960 for (var row = 0; row < numMonths[0]; row++) { 7961 var group = ''; 7962 this.maxRows = 4; 7963 for (var col = 0; col < numMonths[1]; col++) { 7964 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 7965 var cornerClass = ' ui-corner-all'; 7966 var calender = ''; 7967 if (isMultiMonth) { 7968 calender += '<div class="ui-datepicker-group'; 7969 if (numMonths[1] > 1) 7970 switch (col) { 7971 case 0: calender += ' ui-datepicker-group-first'; 7972 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; 7973 case numMonths[1]-1: calender += ' ui-datepicker-group-last'; 7974 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; 7975 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; 7976 } 7977 calender += '">'; 7978 } 7979 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + 7980 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + 7981 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + 7982 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 7983 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 7984 '</div><table class="ui-datepicker-calendar"><thead>' + 7985 '<tr>'; 7986 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); 7987 for (var dow = 0; dow < 7; dow++) { // days of the week 7988 var day = (dow + firstDay) % 7; 7989 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
7989' + 7990 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; 7991 } 7992 calender += thead + '</tr></thead><tbody>'; 7993 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 7994 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 7995 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 7996 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 7997 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 7998 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 7999 this.maxRows = numRows; 8000 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8001 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 8002 calender += '<tr>'; 8003 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + 8004 this._get(inst, 'calculateWeek')(printDate) + '</td>'); 8005 for (var dow = 0; dow < 7; dow++) { // create date picker days 8006 var daySettings = (beforeShowDay ? 8007 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 8008 var otherMonth = (printDate.getMonth() != drawMonth); 8009 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 8010 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 8011 tbody += '<td class="' + 8012 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends 8013 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 8014 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 8015 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 8016 // or defaultDate is current printedDate and defaultDate is selectedDate 8017 ' ' + this._dayOverClass : '') + // highlight selected day 8018 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days 8019 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 8020 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day 8021 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 8022 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 8023 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions 8024 (otherMonth && !showOtherMonths ? ' ' : // display for other months 8025 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + 8026 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + 8027 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day 8028 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months 8029 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date 8030 printDate.setDate(printDate.getDate() + 1); 8031 printDate = this._daylightSavingAdjust(printDate); 8032 } 8033 calender += tbody + '</tr>'; 8034 } 8035 drawMonth++; 8036 if (drawMonth > 11) { 8037 drawMonth = 0; 8038 drawYear++; 8039 } 8040 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 8041 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); 8042 group += calender; 8043 } 8044 html += group; 8045 } 8046 html += buttonPanel + ($.ui.ie6 && !inst.inline ? 8047 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); 8048 inst._keyEvent = false; 8049 return html; 8050 }, 8051 8052 /* Generate the month and year header. */ 8053 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 8054 secondary, monthNames, monthNamesShort) { 8055 var changeMonth = this._get(inst, 'changeMonth'); 8056 var changeYear = this._get(inst, 'changeYear'); 8057 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 8058 var html = '<div class="ui-datepicker-title">'; 8059 var monthHtml = ''; 8060 // month selection 8061 if (secondary || !changeMonth) 8062 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 8063 else { 8064 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 8065 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 8066 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8067 for (var month = 0; month < 12; month++) { 8068 if ((!inMinYear || month >= minDate.getMonth()) && 8069 (!inMaxYear || month <= maxDate.getMonth())) 8070 monthHtml += '<option value="' + month + '"' + 8071 (month == drawMonth ? ' selected="selected"' : '') + 8072 '>' + monthNamesShort[month] + '</option>'; 8073 } 8074 monthHtml += '</select>'; 8075 } 8076 if (!showMonthAfterYear) 8077 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 8078 // year selection 8079 if ( !inst.yearshtml ) { 8080 inst.yearshtml = ''; 8081 if (secondary || !changeYear) 8082 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 8083 else { 8084 // determine range of years to display 8085 var years = this._get(inst, 'yearRange').split(':'); 8086 var thisYear = new Date().getFullYear(); 8087 var determineYear = function(value) { 8088 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8089 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 8090 parseInt(value, 10))); 8091 return (isNaN(year) ? thisYear : year); 8092 }; 8093 var year = determineYear(years[0]); 8094 var endYear = Math.max(year, determineYear(years[1] || '')); 8095 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8096 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8097 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 8098 for (; year <= endYear; year++) { 8099 inst.yearshtml += '<option value="' + year + '"' + 8100 (year == drawYear ? ' selected="selected"' : '') + 8101 '>' + year + '</option>'; 8102 } 8103 inst.yearshtml += '</select>'; 8104 8105 html += inst.yearshtml; 8106 inst.yearshtml = null; 8107 } 8108 } 8109 html += this._get(inst, 'yearSuffix'); 8110 if (showMonthAfterYear) 8111 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 8112 html += '</div>'; // Close datepicker_header 8113 return html; 8114 }, 8115 8116 /* Adjust one of the date sub-fields. */ 8117 _adjustInstDate: function(inst, offset, period) { 8118 var year = inst.drawYear + (period == 'Y' ? offset : 0); 8119 var month = inst.drawMonth + (period == 'M' ? offset : 0); 8120 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 8121 (period == 'D' ? offset : 0); 8122 var date = this._restrictMinMax(inst, 8123 this._daylightSavingAdjust(new Date(year, month, day))); 8124 inst.selectedDay = date.getDate(); 8125 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8126 inst.drawYear = inst.selectedYear = date.getFullYear(); 8127 if (period == 'M' || period == 'Y') 8128 this._notifyChange(inst); 8129 }, 8130 8131 /* Ensure a date is within any min/max bounds. */ 8132 _restrictMinMax: function(inst, date) { 8133 var minDate = this._getMinMaxDate(inst, 'min'); 8134 var maxDate = this._getMinMaxDate(inst, 'max'); 8135 var newDate = (minDate && date < minDate ? minDate : date); 8136 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 8137 return newDate; 8138 }, 8139 8140 /* Notify change of month/year. */ 8141 _notifyChange: function(inst) { 8142 var onChange = this._get(inst, 'onChangeMonthYear'); 8143 if (onChange) 8144 onChange.apply((inst.input ? inst.input[0] : null), 8145 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8146 }, 8147 8148 /* Determine the number of months to show. */ 8149 _getNumberOfMonths: function(inst) { 8150 var numMonths = this._get(inst, 'numberOfMonths'); 8151 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 8152 }, 8153 8154 /* Determine the current maximum date - ensure no time components are set. */ 8155 _getMinMaxDate: function(inst, minMax) { 8156 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 8157 }, 8158 8159 /* Find the number of days in a given month. */ 8160 _getDaysInMonth: function(year, month) { 8161 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8162 }, 8163 8164 /* Find the day of the week of the first of a month. */ 8165 _getFirstDayOfMonth: function(year, month) { 8166 return new Date(year, month, 1).getDay(); 8167 }, 8168 8169 /* Determines if we should allow a "next/prev" month display change. */ 8170 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 8171 var numMonths = this._getNumberOfMonths(inst); 8172 var date = this._daylightSavingAdjust(new Date(curYear, 8173 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8174 if (offset < 0) 8175 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8176 return this._isInRange(inst, date); 8177 }, 8178 8179 /* Is the given date in the accepted range? */ 8180 _isInRange: function(inst, date) { 8181 var minDate = this._getMinMaxDate(inst, 'min'); 8182 var maxDate = this._getMinMaxDate(inst, 'max'); 8183 return ((!minDate || date.getTime() >= minDate.getTime()) && 8184 (!maxDate || date.getTime() <= maxDate.getTime())); 8185 }, 8186 8187 /* Provide the configuration settings for formatting/parsing. */ 8188 _getFormatConfig: function(inst) { 8189 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 8190 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8191 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8192 return {shortYearCutoff: shortYearCutoff, 8193 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 8194 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 8195 }, 8196 8197 /* Format the given date for display. */ 8198 _formatDate: function(inst, day, month, year) { 8199 if (!day) { 8200 inst.currentDay = inst.selectedDay; 8201 inst.currentMonth = inst.selectedMonth; 8202 inst.currentYear = inst.selectedYear; 8203 } 8204 var date = (day ? (typeof day == 'object' ? day : 8205 this._daylightSavingAdjust(new Date(year, month, day))) : 8206 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8207 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 8208 } 8209}); 8210 8211/* 8212 * Bind hover events for datepicker elements. 8213 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8214 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8215 */ 8216function bindHover(dpDiv) { 8217 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 8218 return dpDiv.delegate(selector, 'mouseout', function() { 8219 $(this).removeClass('ui-state-hover'); 8220 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 8221 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 8222 }) 8223 .delegate(selector, 'mouseover', function(){ 8224 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 8225 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 8226 $(this).addClass('ui-state-hover'); 8227 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 8228 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 8229 } 8230 }); 8231} 8232 8233/* jQuery extend now ignores nulls! */ 8234function extendRemove(target, props) { 8235 $.extend(target, props); 8236 for (var name in props) 8237 if (props[name] == null || props[name] == undefined) 8238 target[name] = props[name]; 8239 return target; 8240}; 8241 8242/* Invoke the datepicker functionality. 8243 @param options string - a command, optionally followed by additional parameters or 8244 Object - settings for attaching new datepicker functionality 8245 @return jQuery object */ 8246$.fn.datepicker = function(options){ 8247 8248 /* Verify an empty collection wasn't passed - Fixes #6976 */ 8249 if ( !this.length ) { 8250 return this; 8251 } 8252 8253 /* Initialise the date picker. */ 8254 if (!$.datepicker.initialized) { 8255 $(document).mousedown($.datepicker._checkExternalClick). 8256 find(document.body).append($.datepicker.dpDiv); 8257 $.datepicker.initialized = true; 8258 } 8259 8260 var otherArgs = Array.prototype.slice.call(arguments, 1); 8261 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 8262 return $.datepicker['_' + options + 'Datepicker']. 8263 apply($.datepicker, [this[0]].concat(otherArgs)); 8264 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 8265 return $.datepicker['_' + options + 'Datepicker']. 8266 apply($.datepicker, [this[0]].concat(otherArgs)); 8267 return this.each(function() { 8268 typeof options == 'string' ? 8269 $.datepicker['_' + options + 'Datepicker']. 8270 apply($.datepicker, [this].concat(otherArgs)) : 8271 $.datepicker._attachDatepicker(this, options); 8272 }); 8273}; 8274 8275$.datepicker = new Datepicker(); // singleton instance 8276$.datepicker.initialized = false; 8277$.datepicker.uuid = new Date().getTime(); 8278$.datepicker.version = "1.9.2"; 8279 8280// Workaround for #4055 8281// Add another global to avoid noConflict issues with inline event handlers 8282window['DP_jQuery_' + dpuuid] = $; 8283 8284})(jQuery); 8285(function( $, undefined ) { 8286 8287var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", 8288 sizeRelatedOptions = { 8289 buttons: true, 8290 height: true, 8291 maxHeight: true, 8292 maxWidth: true, 8293 minHeight: true, 8294 minWidth: true, 8295 width: true 8296 }, 8297 resizableRelatedOptions = { 8298 maxHeight: true, 8299 maxWidth: true, 8300 minHeight: true, 8301 minWidth: true 8302 }; 8303 8304$.widget("ui.dialog", { 8305 version: "1.9.2", 8306 options: { 8307 autoOpen: true, 8308 buttons: {}, 8309 closeOnEscape: true, 8310 closeText: "close", 8311 dialogClass: "", 8312 draggable: true, 8313 hide: null, 8314 height: "auto", 8315 maxHeight: false, 8316 maxWidth: false, 8317 minHeight: 150, 8318 minWidth: 150, 8319 modal: false, 8320 position: { 8321 my: "center", 8322 at: "center", 8323 of: window, 8324 collision: "fit", 8325 // ensure that the titlebar is never outside the document 8326 using: function( pos ) { 8327 var topOffset = $( this ).css( pos ).offset().top; 8328 if ( topOffset < 0 ) { 8329 $( this ).css( "top", pos.top - topOffset ); 8330 } 8331 } 8332 }, 8333 resizable: true, 8334 show: null, 8335 stack: true, 8336 title: "", 8337 width: 300, 8338 zIndex: 1000 8339 }, 8340 8341 _create: function() { 8342 this.originalTitle = this.element.attr( "title" ); 8343 // #5742 - .attr() might return a DOMElement 8344 if ( typeof this.originalTitle !== "string" ) { 8345 this.originalTitle = ""; 8346 } 8347 this.oldPosition = { 8348 parent: this.element.parent(), 8349 index: this.element.parent().children().index( this.element ) 8350 }; 8351 this.options.title = this.options.title || this.originalTitle; 8352 var that = this, 8353 options = this.options, 8354 8355 title = options.title || " ", 8356 uiDialog, 8357 uiDialogTitlebar, 8358 uiDialogTitlebarClose, 8359 uiDialogTitle, 8360 uiDialogButtonPane; 8361 8362 uiDialog = ( this.uiDialog = $( "<div>" ) ) 8363 .addClass( uiDialogClasses + options.dialogClass ) 8364 .css({ 8365 display: "none", 8366 outline: 0, // TODO: move to stylesheet 8367 zIndex: options.zIndex 8368 }) 8369 // setting tabIndex makes the div focusable 8370 .attr( "tabIndex", -1) 8371 .keydown(function( event ) { 8372 if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 8373 event.keyCode === $.ui.keyCode.ESCAPE ) { 8374 that.close( event ); 8375 event.preventDefault(); 8376 } 8377 }) 8378 .mousedown(function( event ) {
8379 that.moveToTop( false, event ); 8380 }) 8381 .appendTo( "body" ); 8382 8383 this.element 8384 .show() 8385 .removeAttr( "title" ) 8386 .addClass( "ui-dialog-content ui-widget-content" ) 8387 .appendTo( uiDialog ); 8388 8389 uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) ) 8390 .addClass( "ui-dialog-titlebar ui-widget-header " + 8391 "ui-corner-all ui-helper-clearfix" ) 8392 .bind( "mousedown", function() { 8393 // Dialog isn't getting focus when dragging (#8063) 8394 uiDialog.focus(); 8395 }) 8396 .prependTo( uiDialog ); 8397 8398 uiDialogTitlebarClose = $( "<a href='#'></a>" ) 8399 .addClass( "ui-dialog-titlebar-close ui-corner-all" ) 8400 .attr( "role", "button" ) 8401 .click(function( event ) { 8402 event.preventDefault(); 8403 that.close( event ); 8404 }) 8405 .appendTo( uiDialogTitlebar ); 8406 8407 ( this.uiDialogTitlebarCloseText = $( "<span>" ) ) 8408 .addClass( "ui-icon ui-icon-closethick" ) 8409 .text( options.closeText ) 8410 .appendTo( uiDialogTitlebarClose ); 8411 8412 uiDialogTitle = $( "<span>" ) 8413 .uniqueId() 8414 .addClass( "ui-dialog-title" ) 8415 .html( title ) 8416 .prependTo( uiDialogTitlebar ); 8417 8418 uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) 8419 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 8420 8421 ( this.uiButtonSet = $( "<div>" ) ) 8422 .addClass( "ui-dialog-buttonset" ) 8423 .appendTo( uiDialogButtonPane ); 8424 8425 uiDialog.attr({ 8426 role: "dialog", 8427 "aria-labelledby": uiDialogTitle.attr( "id" ) 8428 }); 8429 8430 uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); 8431 this._hoverable( uiDialogTitlebarClose ); 8432 this._focusable( uiDialogTitlebarClose ); 8433 8434 if ( options.draggable && $.fn.draggable ) { 8435 this._makeDraggable(); 8436 } 8437 if ( options.resizable && $.fn.resizable ) { 8438 this._makeResizable(); 8439 } 8440 8441 this._createButtons( options.buttons ); 8442 this._isOpen = false; 8443 8444 if ( $.fn.bgiframe ) { 8445 uiDialog.bgiframe(); 8446 } 8447 8448 // prevent tabbing out of modal dialogs 8449 this._on( uiDialog, { keydown: function( event ) { 8450 if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { 8451 return; 8452 } 8453 8454 var tabbables = $( ":tabbable", uiDialog ), 8455 first = tabbables.filter( ":first" ), 8456 last = tabbables.filter( ":last" ); 8457 8458 if ( event.target === last[0] && !event.shiftKey ) { 8459 first.focus( 1 ); 8460 return false; 8461 } else if ( event.target === first[0] && event.shiftKey ) { 8462 last.focus( 1 ); 8463 return false; 8464 } 8465 }}); 8466 }, 8467 8468 _init: function() { 8469 if ( this.options.autoOpen ) { 8470 this.open(); 8471 } 8472 }, 8473 8474 _destroy: function() { 8475 var next, 8476 oldPosition = this.oldPosition; 8477 8478 if ( this.overlay ) { 8479 this.overlay.destroy(); 8480 } 8481 this.uiDialog.hide(); 8482 this.element 8483 .removeClass( "ui-dialog-content ui-widget-content" ) 8484 .hide() 8485 .appendTo( "body" ); 8486 this.uiDialog.remove(); 8487 8488 if ( this.originalTitle ) { 8489 this.element.attr( "title", this.originalTitle ); 8490 } 8491 8492 next = oldPosition.parent.children().eq( oldPosition.index ); 8493 // Don't try to place the dialog next to itself (#8613) 8494 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 8495 next.before( this.element ); 8496 } else { 8497 oldPosition.parent.append( this.element ); 8498 } 8499 }, 8500 8501 widget: function() { 8502 return this.uiDialog; 8503 }, 8504 8505 close: function( event ) { 8506 var that = this, 8507 maxZ, thisZ; 8508 8509 if ( !this._isOpen ) { 8510 return; 8511 } 8512 8513 if ( false === this._trigger( "beforeClose", event ) ) { 8514 return; 8515 } 8516 8517 this._isOpen = false; 8518 8519 if ( this.overlay ) { 8520 this.overlay.destroy(); 8521 } 8522 8523 if ( this.options.hide ) { 8524 this._hide( this.uiDialog, this.options.hide, function() { 8525 that._trigger( "close", event ); 8526 }); 8527 } else { 8528 this.uiDialog.hide(); 8529 this._trigger( "close", event ); 8530 } 8531 8532 $.ui.dialog.overlay.resize(); 8533 8534 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 8535 if ( this.options.modal ) { 8536 maxZ = 0; 8537 $( ".ui-dialog" ).each(function() { 8538 if ( this !== that.uiDialog[0] ) { 8539 thisZ = $( this ).css( "z-index" ); 8540 if ( !isNaN( thisZ ) ) { 8541 maxZ = Math.max( maxZ, thisZ ); 8542 } 8543 } 8544 }); 8545 $.ui.dialog.maxZ = maxZ; 8546 } 8547 8548 return this; 8549 }, 8550 8551 isOpen: function() { 8552 return this._isOpen; 8553 }, 8554 8555 // the force parameter allows us to move modal dialogs to their correct 8556 // position on open 8557 moveToTop: function( force, event ) { 8558 var options = this.options, 8559 saveScroll; 8560 8561 if ( ( options.modal && !force ) || 8562 ( !options.stack && !options.modal ) ) { 8563 return this._trigger( "focus", event ); 8564 } 8565 8566 if ( options.zIndex > $.ui.dialog.maxZ ) { 8567 $.ui.dialog.maxZ = options.zIndex; 8568 } 8569 if ( this.overlay ) { 8570 $.ui.dialog.maxZ += 1; 8571 $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
8572 this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); 8573 } 8574 8575 // Save and then restore scroll 8576 // Opera 9.5+ resets when parent z-index is changed. 8577 // http://bugs.jqueryui.com/ticket/3193 8578 saveScroll = { 8579 scrollTop: this.element.scrollTop(), 8580 scrollLeft: this.element.scrollLeft() 8581 }; 8582 $.ui.dialog.maxZ += 1; 8583 this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); 8584 this.element.attr( saveScroll ); 8585 this._trigger( "focus", event ); 8586 8587 return this; 8588 }, 8589 8590 open: function() { 8591 if ( this._isOpen ) { 8592 return; 8593 } 8594 8595 var hasFocus, 8596 options = this.options, 8597 uiDialog = this.uiDialog; 8598 8599 this._size(); 8600 this._position( options.position ); 8601 uiDialog.show( options.show ); 8602 this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; 8603 this.moveToTop( true ); 8604 8605 // set focus to the first tabbable element in the content area or the first button 8606 // if there are no tabbable elements, set focus on the dialog itself 8607 hasFocus = this.element.find( ":tabbable" ); 8608 if ( !hasFocus.length ) { 8609 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 8610 if ( !hasFocus.length ) { 8611 hasFocus = uiDialog; 8612 } 8613 } 8614 hasFocus.eq( 0 ).focus(); 8615 8616 this._isOpen = true; 8617 this._trigger( "open" ); 8618 8619 return this; 8620 }, 8621 8622 _createButtons: function( buttons ) { 8623 var that = this, 8624 hasButtons = false; 8625 8626 // if we already have a button pane, remove it 8627 this.uiDialogButtonPane.remove(); 8628 this.uiButtonSet.empty(); 8629 8630 if ( typeof buttons === "object" && buttons !== null ) { 8631 $.each( buttons, function() { 8632 return !(hasButtons = true); 8633 }); 8634 } 8635 if ( hasButtons ) { 8636 $.each( buttons, function( name, props ) { 8637 var button, click; 8638 props = $.isFunction( props ) ? 8639 { click: props, text: name } : 8640 props; 8641 // Default to a non-submitting button 8642 props = $.extend( { type: "button" }, props ); 8643 // Change the context for the click callback to be the main element 8644 click = props.click; 8645 props.click = function() { 8646 click.apply( that.element[0], arguments ); 8647 }; 8648 button = $( "<button></button>", props ) 8649 .appendTo( that.uiButtonSet ); 8650 if ( $.fn.button ) { 8651 button.button(); 8652 } 8653 }); 8654 this.uiDialog.addClass( "ui-dialog-buttons" ); 8655 this.uiDialogButtonPane.appendTo( this.uiDialog ); 8656 } else { 8657 this.uiDialog.removeClass( "ui-dialog-buttons" ); 8658 } 8659 }, 8660 8661 _makeDraggable: function() { 8662 var that = this, 8663 options = this.options; 8664 8665 function filteredUi( ui ) { 8666 return { 8667 position: ui.position, 8668 offset: ui.offset 8669 }; 8670 } 8671 8672 this.uiDialog.draggable({ 8673 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 8674 handle: ".ui-dialog-titlebar", 8675 containment: "document", 8676 start: function( event, ui ) { 8677 $( this ) 8678 .addClass( "ui-dialog-dragging" ); 8679 that._trigger( "dragStart", event, filteredUi( ui ) ); 8680 }, 8681 drag: function( event, ui ) { 8682 that._trigger( "drag", event, filteredUi( ui ) ); 8683 }, 8684 stop: function( event, ui ) { 8685 options.position = [ 8686 ui.position.left - that.document.scrollLeft(), 8687 ui.position.top - that.document.scrollTop() 8688 ]; 8689 $( this ) 8690 .removeClass( "ui-dialog-dragging" ); 8691 that._trigger( "dragStop", event, filteredUi( ui ) ); 8692 $.ui.dialog.overlay.resize(); 8693 } 8694 }); 8695 }, 8696 8697 _makeResizable: function( handles ) { 8698 handles = (handles === undefined ? this.options.resizable : handles); 8699 var that = this, 8700 options = this.options, 8701 // .ui-resizable has position: relative defined in the stylesheet 8702 // but dialogs have to use absolute or fixed positioning 8703 position = this.uiDialog.css( "position" ), 8704 resizeHandles = typeof handles === 'string' ? 8705 handles : 8706 "n,e,s,w,se,sw,ne,nw"; 8707 8708 function filteredUi( ui ) { 8709 return { 8710 originalPosition: ui.originalPosition, 8711 originalSize: ui.originalSize, 8712 position: ui.position, 8713 size: ui.size 8714 }; 8715 } 8716 8717 this.uiDialog.resizable({ 8718 cancel: ".ui-dialog-content", 8719 containment: "document", 8720 alsoResize: this.element, 8721 maxWidth: options.maxWidth, 8722 maxHeight: options.maxHeight, 8723 minWidth: options.minWidth, 8724 minHeight: this._minHeight(), 8725 handles: resizeHandles, 8726 start: function( event, ui ) { 8727 $( this ).addClass( "ui-dialog-resizing" ); 8728 that._trigger( "resizeStart", event, filteredUi( ui ) ); 8729 }, 8730 resize: function( event, ui ) { 8731 that._trigger( "resize", event, filteredUi( ui ) ); 8732 }, 8733 stop: function( event, ui ) { 8734 $( this ).removeClass( "ui-dialog-resizing" ); 8735 options.height = $( this ).height(); 8736 options.width = $( this ).width(); 8737 that._trigger( "resizeStop", event, filteredUi( ui ) ); 8738 $.ui.dialog.overlay.resize(); 8739 } 8740 }) 8741 .css( "position", position ) 8742 .find( ".ui-resizable-se" ) 8743 .addClass( "ui-icon ui-icon-grip-diagonal-se" ); 8744 }, 8745 8746 _minHeight: function() { 8747 var options = this.options; 8748 8749 if ( options.height === "auto" ) { 8750 return options.minHeight; 8751 } else { 8752 return Math.min( options.minHeight, options.height ); 8753 } 8754 }, 8755 8756 _position: function( position ) { 8757 var myAt = [], 8758 offset = [ 0, 0 ], 8759 isVisible; 8760 8761 if ( position ) { 8762 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( 8763 // if (typeof position == 'string' || $.isArray(position)) { 8764 // myAt = $.isArray(position) ? position : position.split(' '); 8765 8766 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 8767 myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; 8768 if ( myAt.length === 1 ) { 8769 myAt[ 1 ] = myAt[ 0 ]; 8770 } 8771 8772 $.each( [ "left", "top" ], function( i, offsetPosition ) { 8773 if ( +myAt[ i ] === myAt[ i ] ) { 8774 offset[ i ] = myAt[ i ]; 8775 myAt[ i ] = offsetPosition; 8776 } 8777 }); 8778 8779 position = { 8780 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 8781 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 8782 at: myAt.join( " " ) 8783 }; 8784 } 8785 8786 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 8787 } else { 8788 position = $.ui.dialog.prototype.options.position; 8789 } 8790 8791 // need to show the dialog to get the actual offset in the position plugin 8792 isVisible = this.uiDialog.is( ":visible" ); 8793 if ( !isVisible ) { 8794 this.uiDialog.show(); 8795 } 8796 this.uiDialog.position( position ); 8797 if ( !isVisible ) { 8798 this.uiDialog.hide(); 8799 } 8800 }, 8801 8802 _setOptions: function( options ) { 8803 var that = this, 8804 resizableOptions = {}, 8805 resize = false; 8806 8807 $.each( options, function( key, value ) { 8808 that._setOption( key, value ); 8809 8810 if ( key in sizeRelatedOptions ) { 8811 resize = true; 8812 } 8813 if ( key in resizableRelatedOptions ) { 8814 resizableOptions[ key ] = value; 8815 } 8816 }); 8817 8818 if ( resize ) { 8819 this._size(); 8820 } 8821 if ( this.uiDialog.is( ":data(resizable)" ) ) { 8822 this.uiDialog.resizable( "option", resizableOptions ); 8823 } 8824 }, 8825 8826 _setOption: function( key, value ) { 8827 var isDraggable, isResizable, 8828 uiDialog = this.uiDialog; 8829 8830 switch ( key ) { 8831 case "buttons": 8832 this._createButtons( value ); 8833 break; 8834 case "closeText": 8835 // ensure that we always pass a string 8836 this.uiDialogTitlebarCloseText.text( "" + value ); 8837 break; 8838 case "dialogClass": 8839 uiDialog 8840 .removeClass( this.options.dialogClass ) 8841 .addClass( uiDialogClasses + value ); 8842 break; 8843 case "disabled": 8844 if ( value ) { 8845 uiDialog.addClass( "ui-dialog-disabled" ); 8846 } else { 8847 uiDialog.removeClass( "ui-dialog-disabled" ); 8848 } 8849 break; 8850 case "draggable": 8851 isDraggable = uiDialog.is( ":data(draggable)" ); 8852 if ( isDraggable && !value ) { 8853 uiDialog.draggable( "destroy" ); 8854 } 8855 8856 if ( !isDraggable && value ) { 8857 this._makeDraggable(); 8858 } 8859 break; 8860 case "position": 8861 this._position( value ); 8862 break; 8863 case "resizable": 8864 // currently resizable, becoming non-resizable 8865 isResizable = uiDialog.is( ":data(resizable)" ); 8866 if ( isResizable && !value ) { 8867 uiDialog.resizable( "destroy" ); 8868 } 8869 8870 // currently resizable, changing handles 8871 if ( isResizable && typeof value === "string" ) { 8872 uiDialog.resizable( "option", "handles", value ); 8873 } 8874 8875 // currently non-resizable, becoming resizable 8876 if ( !isResizable && value !== false ) { 8877 this._makeResizable( value ); 8878 } 8879 break; 8880 case "title": 8881 // convert whatever was passed in o a string, for html() to not throw up 8882 $( ".ui-dialog-title", this.uiDialogTitlebar ) 8883 .html( "" + ( value || " " ) ); 8884 break; 8885 } 8886 8887 this._super( key, value ); 8888 }, 8889 8890 _size: function() { 8891 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 8892 * divs will both have width and height set, so we need to reset them 8893 */ 8894 var nonContentHeight, minContentHeight, autoHeight, 8895 options = this.options, 8896 isVisible = this.uiDialog.is( ":visible" ); 8897 8898 // reset content sizing 8899 this.element.show().css({ 8900 width: "auto", 8901 minHeight: 0, 8902 height: 0 8903 }); 8904 8905 if ( options.minWidth > options.width ) { 8906 options.width = options.minWidth; 8907 } 8908 8909 // reset wrapper sizing 8910 // determine the height of all the non-content elements 8911 nonContentHeight = this.uiDialog.css({ 8912 height: "auto", 8913 width: options.width 8914 }) 8915 .outerHeight(); 8916 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 8917 8918 if ( options.height === "auto" ) { 8919 // only needed for IE6 support 8920 if ( $.support.minHeight ) { 8921 this.element.css({ 8922 minHeight: minContentHeight, 8923 height: "auto" 8924 }); 8925 } else { 8926 this.uiDialog.show(); 8927 autoHeight = this.element.css( "height", "auto" ).height(); 8928 if ( !isVisible ) { 8929 this.uiDialog.hide(); 8930 } 8931 this.element.height( Math.max( autoHeight, minContentHeight ) ); 8932 } 8933 } else { 8934 this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); 8935 } 8936 8937 if (this.uiDialog.is( ":data(resizable)" ) ) { 8938 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 8939 } 8940 } 8941}); 8942 8943$.extend($.ui.dialog, { 8944 uuid: 0, 8945 maxZ: 0, 8946 8947 getTitleId: function($el) { 8948 var id = $el.attr( "id" ); 8949 if ( !id ) { 8950 this.uuid += 1; 8951 id = this.uuid; 8952 } 8953 return "ui-dialog-title-" + id; 8954 }, 8955 8956 overlay: function( dialog ) { 8957 this.$el = $.ui.dialog.overlay.create( dialog ); 8958 } 8959}); 8960 8961$.extend( $.ui.dialog.overlay, { 8962 instances: [], 8963 // reuse old instances due to IE memory leak with alpha transparency (see #5185) 8964 oldInstances: [], 8965 maxZ: 0, 8966 events: $.map(
8967 "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), 8968 function( event ) { 8969 return event + ".dialog-overlay"; 8970 } 8971 ).join( " " ), 8972 create: function( dialog ) { 8973 if ( this.instances.length === 0 ) { 8974 // prevent use of anchors and inputs 8975 // we use a setTimeout in case the overlay is created from an 8976 // event that we're going to be cancelling (see #2804) 8977 setTimeout(function() { 8978 // handle $(el).dialog().dialog('close') (see #4065) 8979 if ( $.ui.dialog.overlay.instances.length ) { 8980 $( document ).bind( $.ui.dialog.overlay.events, function( event ) { 8981 // stop events if the z-index of the target is < the z-index of the overlay 8982 // we cannot return true when we don't want to cancel the event (#3523) 8983 if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { 8984 return false; 8985 } 8986 }); 8987 } 8988 }, 1 ); 8989 8990 // handle window resize 8991 $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); 8992 } 8993 8994 var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); 8995 8996 // allow closing by pressing the escape key 8997 $( document ).bind( "keydown.dialog-overlay", function( event ) { 8998 var instances = $.ui.dialog.overlay.instances; 8999 // only react to the event if we're the top overlay 9000 if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && 9001 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9002 event.keyCode === $.ui.keyCode.ESCAPE ) { 9003 9004 dialog.close( event ); 9005 event.preventDefault(); 9006 } 9007 }); 9008 9009 $el.appendTo( document.body ).css({ 9010 width: this.width(), 9011 height: this.height() 9012 }); 9013 9014 if ( $.fn.bgiframe ) { 9015 $el.bgiframe(); 9016 } 9017 9018 this.instances.push( $el ); 9019 return $el; 9020 }, 9021 9022 destroy: function( $el ) { 9023 var indexOf = $.inArray( $el, this.instances ), 9024 maxZ = 0; 9025 9026 if ( indexOf !== -1 ) { 9027 this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); 9028 } 9029 9030 if ( this.instances.length === 0 ) { 9031 $( [ document, window ] ).unbind( ".dialog-overlay" ); 9032 } 9033 9034 $el.height( 0 ).width( 0 ).remove(); 9035 9036 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9037 $.each( this.instances, function() { 9038 maxZ = Math.max( maxZ, this.css( "z-index" ) ); 9039 }); 9040 this.maxZ = maxZ; 9041 }, 9042 9043 height: function() { 9044 var scrollHeight, 9045 offsetHeight; 9046 // handle IE 9047 if ( $.ui.ie ) { 9048 scrollHeight = Math.max( 9049 document.documentElement.scrollHeight, 9050 document.body.scrollHeight 9051 ); 9052 offsetHeight = Math.max( 9053 document.documentElement.offsetHeight, 9054 document.body.offsetHeight 9055 ); 9056 9057 if ( scrollHeight < offsetHeight ) { 9058 return $( window ).height() + "px"; 9059 } else { 9060 return scrollHeight + "px"; 9061 } 9062 // handle "good" browsers 9063 } else { 9064 return $( document ).height() + "px"; 9065 } 9066 }, 9067 9068 width: function() { 9069 var scrollWidth, 9070 offsetWidth; 9071 // handle IE 9072 if ( $.ui.ie ) { 9073 scrollWidth = Math.max( 9074 document.documentElement.scrollWidth, 9075 document.body.scrollWidth 9076 ); 9077 offsetWidth = Math.max( 9078 document.documentElement.offsetWidth, 9079 document.body.offsetWidth 9080 ); 9081 9082 if ( scrollWidth < offsetWidth ) { 9083 return $( window ).width() + "px"; 9084 } else { 9085 return scrollWidth + "px"; 9086 } 9087 // handle "good" browsers 9088 } else { 9089 return $( document ).width() + "px"; 9090 } 9091 }, 9092 9093 resize: function() { 9094 /* If the dialog is draggable and the user drags it past the 9095 * right edge of the window, the document becomes wider so we 9096 * need to stretch the overlay. If the user then drags the 9097 * dialog back to the left, the document will become narrower, 9098 * so we need to shrink the overlay to the appropriate size. 9099 * This is handled by shrinking the overlay before setting it 9100 * to the full document size. 9101 */ 9102 var $overlays = $( [] ); 9103 $.each( $.ui.dialog.overlay.instances, function() { 9104 $overlays = $overlays.add( this ); 9105 }); 9106 9107 $overlays.css({ 9108 width: 0, 9109 height: 0 9110 }).css({ 9111 width: $.ui.dialog.overlay.width(), 9112 height: $.ui.dialog.overlay.height() 9113 }); 9114 } 9115}); 9116 9117$.extend( $.ui.dialog.overlay.prototype, { 9118 destroy: function() { 9119 $.ui.dialog.overlay.destroy( this.$el ); 9120 } 9121}); 9122 9123}( jQuery ) ); 9124(function( $, undefined ) { 9125 9126var mouseHandled = false; 9127 9128$.widget( "ui.menu", { 9129 version: "1.9.2", 9130 defaultElement: "<ul>", 9131 delay: 300, 9132 options: { 9133 icons: { 9134 submenu: "ui-icon-carat-1-e" 9135 }, 9136 menus: "ul", 9137 position: { 9138 my: "left top", 9139 at: "right top" 9140 }, 9141 role: "menu", 9142 9143 // callbacks 9144 blur: null, 9145 focus: null, 9146 select: null 9147 }, 9148 9149 _create: function() { 9150 this.activeMenu = this.element; 9151 this.element 9152 .uniqueId() 9153 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9154 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 9155 .attr({ 9156 role: this.options.role, 9157 tabIndex: 0 9158 }) 9159 // need to catch all clicks on disabled menu 9160 // not possible through _on 9161 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 9162 if ( this.options.disabled ) { 9163 event.preventDefault(); 9164 } 9165 }, this )); 9166 9167 if ( this.options.disabled ) { 9168 this.element 9169 .addClass( "ui-state-disabled" ) 9170 .attr( "aria-disabled", "true" ); 9171 } 9172 9173 this._on({ 9174 // Prevent focus from sticking to links inside menu after clicking 9175 // them (focus should always stay on UL during navigation). 9176 "mousedown .ui-menu-item > a": function( event ) { 9177 event.preventDefault(); 9178 }, 9179 "click .ui-state-disabled > a": function( event ) { 9180 event.preventDefault(); 9181 }, 9182 "click .ui-menu-item:has(a)": function( event ) { 9183 var target = $( event.target ).closest( ".ui-menu-item" ); 9184 if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { 9185 mouseHandled = true; 9186 9187 this.select( event ); 9188 // Open submenu on click 9189 if ( target.has( ".ui-menu" ).length ) { 9190 this.expand( event ); 9191 } else if ( !this.element.is( ":focus" ) ) { 9192 // Redirect focus to the menu 9193 this.element.trigger( "focus", [ true ] ); 9194 9195 // If the active item is on the top level, let it stay active. 9196 // Otherwise, blur the active item since it is no longer visible. 9197 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 9198 clearTimeout( this.timer ); 9199 } 9200 } 9201 } 9202 }, 9203 "mouseenter .ui-menu-item": function( event ) { 9204 var target = $( event.currentTarget ); 9205 // Remove ui-state-active class from siblings of the newly focused menu item 9206 // to avoid a jump caused by adjacent elements both having a class with a border 9207 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 9208 this.focus( event, target ); 9209 }, 9210 mouseleave: "collapseAll", 9211 "mouseleave .ui-menu": "collapseAll", 9212 focus: function( event, keepActiveItem ) { 9213 // If there's already an active item, keep it active 9214 // If not, activate the first item 9215 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 9216 9217 if ( !keepActiveItem ) { 9218 this.focus( event, item ); 9219 } 9220 }, 9221 blur: function( event ) { 9222 this._delay(function() { 9223 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 9224 this.collapseAll( event ); 9225 } 9226 }); 9227 }, 9228 keydown: "_keydown" 9229 }); 9230 9231 this.refresh();
vendor: 69,658 bytes, lines 9232-11793
9232 9233 // Clicks outside of a menu collapse any open menus 9234 this._on( this.document, { 9235 click: function( event ) { 9236 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 9237 this.collapseAll( event ); 9238 } 9239 9240 // Reset the mouseHandled flag 9241 mouseHandled = false; 9242 } 9243 }); 9244 }, 9245 9246 _destroy: function() { 9247 // Destroy (sub)menus 9248 this.element 9249 .removeAttr( "aria-activedescendant" ) 9250 .find( ".ui-menu" ).andSelf() 9251 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 9252 .removeAttr( "role" ) 9253 .removeAttr( "tabIndex" ) 9254 .removeAttr( "aria-labelledby" ) 9255 .removeAttr( "aria-expanded" ) 9256 .removeAttr( "aria-hidden" ) 9257 .removeAttr( "aria-disabled" ) 9258 .removeUniqueId() 9259 .show(); 9260 9261 // Destroy menu items 9262 this.element.find( ".ui-menu-item" ) 9263 .removeClass( "ui-menu-item" ) 9264 .removeAttr( "role" ) 9265 .removeAttr( "aria-disabled" ) 9266 .children( "a" ) 9267 .removeUniqueId() 9268 .removeClass( "ui-corner-all ui-state-hover" ) 9269 .removeAttr( "tabIndex" ) 9270 .removeAttr( "role" ) 9271 .removeAttr( "aria-haspopup" ) 9272 .children().each( function() { 9273 var elem = $( this ); 9274 if ( elem.data( "ui-menu-submenu-carat" ) ) { 9275 elem.remove(); 9276 } 9277 }); 9278 9279 // Destroy menu dividers 9280 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 9281 }, 9282 9283 _keydown: function( event ) { 9284 var match, prev, character, skip, regex, 9285 preventDefault = true; 9286 9287 function escape( value ) { 9288 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 9289 } 9290 9291 switch ( event.keyCode ) { 9292 case $.ui.keyCode.PAGE_UP: 9293 this.previousPage( event ); 9294 break; 9295 case $.ui.keyCode.PAGE_DOWN: 9296 this.nextPage( event ); 9297 break; 9298 case $.ui.keyCode.HOME: 9299 this._move( "first", "first", event ); 9300 break; 9301 case $.ui.keyCode.END: 9302 this._move( "last", "last", event ); 9303 break; 9304 case $.ui.keyCode.UP: 9305 this.previous( event ); 9306 break; 9307 case $.ui.keyCode.DOWN: 9308 this.next( event ); 9309 break; 9310 case $.ui.keyCode.LEFT: 9311 this.collapse( event ); 9312 break; 9313 case $.ui.keyCode.RIGHT: 9314 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 9315 this.expand( event ); 9316 } 9317 break; 9318 case $.ui.keyCode.ENTER: 9319 case $.ui.keyCode.SPACE: 9320 this._activate( event ); 9321 break; 9322 case $.ui.keyCode.ESCAPE: 9323 this.collapse( event ); 9324 break; 9325 default: 9326 preventDefault = false; 9327 prev = this.previousFilter || ""; 9328 character = String.fromCharCode( event.keyCode ); 9329 skip = false; 9330 9331 clearTimeout( this.filterTimer ); 9332 9333 if ( character === prev ) { 9334 skip = true; 9335 } else { 9336 character = prev + character; 9337 } 9338 9339 regex = new RegExp( "^" + escape( character ), "i" ); 9340 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9341 return regex.test( $( this ).children( "a" ).text() ); 9342 }); 9343 match = skip && match.index( this.active.next() ) !== -1 ? 9344 this.active.nextAll( ".ui-menu-item" ) : 9345 match; 9346 9347 // If no matches on the current filter, reset to the last character pressed 9348 // to move down the menu to the first item that starts with that character 9349 if ( !match.length ) { 9350 character = String.fromCharCode( event.keyCode ); 9351 regex = new RegExp( "^" + escape( character ), "i" ); 9352 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9353 return regex.test( $( this ).children( "a" ).text() ); 9354 }); 9355 } 9356 9357 if ( match.length ) { 9358 this.focus( event, match ); 9359 if ( match.length > 1 ) { 9360 this.previousFilter = character; 9361 this.filterTimer = this._delay(function() { 9362 delete this.previousFilter; 9363 }, 1000 ); 9364 } else { 9365 delete this.previousFilter; 9366 } 9367 } else { 9368 delete this.previousFilter; 9369 } 9370 } 9371 9372 if ( preventDefault ) { 9373 event.preventDefault(); 9374 } 9375 }, 9376 9377 _activate: function( event ) { 9378 if ( !this.active.is( ".ui-state-disabled" ) ) { 9379 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 9380 this.expand( event ); 9381 } else { 9382 this.select( event ); 9383 } 9384 } 9385 }, 9386 9387 refresh: function() { 9388 var menus, 9389 icon = this.options.icons.submenu, 9390 submenus = this.element.find( this.options.menus ); 9391 9392 // Initialize nested menus 9393 submenus.filter( ":not(.ui-menu)" ) 9394 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9395 .hide() 9396 .attr({ 9397 role: this.options.role, 9398 "aria-hidden": "true", 9399 "aria-expanded": "false" 9400 }) 9401 .each(function() { 9402 var menu = $( this ), 9403 item = menu.prev( "a" ), 9404 submenuCarat = $( "<span>" ) 9405 .addClass( "ui-menu-icon ui-icon " + icon ) 9406 .data( "ui-menu-submenu-carat", true ); 9407 9408 item 9409 .attr( "aria-haspopup", "true" ) 9410 .prepend( submenuCarat ); 9411 menu.attr( "aria-labelledby", item.attr( "id" ) ); 9412 }); 9413 9414 menus = submenus.add( this.element ); 9415 9416 // Don't refresh list items that are already adapted 9417 menus.children( ":not(.ui-menu-item):has(a)" ) 9418 .addClass( "ui-menu-item" ) 9419 .attr( "role", "presentation" ) 9420 .children( "a" ) 9421 .uniqueId() 9422 .addClass( "ui-corner-all" ) 9423 .attr({ 9424 tabIndex: -1, 9425 role: this._itemRole() 9426 }); 9427 9428 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 9429 menus.children( ":not(.ui-menu-item)" ).each(function() { 9430 var item = $( this ); 9431 // hyphen, em dash, en dash 9432 if ( !/[^\-—–\s]/.test( item.text() ) ) { 9433 item.addClass( "ui-widget-content ui-menu-divider" ); 9434 } 9435 }); 9436 9437 // Add aria-disabled attribute to any disabled menu item 9438 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 9439 9440 // If the active item has been removed, blur the menu 9441 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 9442 this.blur(); 9443 } 9444 }, 9445 9446 _itemRole: function() { 9447 return { 9448 menu: "menuitem", 9449 listbox: "option" 9450 }[ this.options.role ]; 9451 }, 9452 9453 focus: function( event, item ) { 9454 var nested, focused; 9455 this.blur( event, event && event.type === "focus" ); 9456 9457 this._scrollIntoView( item ); 9458 9459 this.active = item.first(); 9460 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 9461 // Only update aria-activedescendant if there's a role 9462 // otherwise we assume focus is managed elsewhere 9463 if ( this.options.role ) { 9464 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 9465 } 9466 9467 // Highlight active parent menu item, if any 9468 this.active 9469 .parent() 9470 .closest( ".ui-menu-item" ) 9471 .children( "a:first" ) 9472 .addClass( "ui-state-active" ); 9473 9474 if ( event && event.type === "keydown" ) { 9475 this._close(); 9476 } else { 9477 this.timer = this._delay(function() { 9478 this._close(); 9479 }, this.delay ); 9480 } 9481 9482 nested = item.children( ".ui-menu" ); 9483 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 9484 this._startOpening(nested); 9485 } 9486 this.activeMenu = item.parent(); 9487 9488 this._trigger( "focus", event, { item: item } ); 9489 }, 9490 9491 _scrollIntoView: function( item ) { 9492 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 9493 if ( this._hasScroll() ) { 9494 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 9495 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 9496 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 9497 scroll = this.activeMenu.scrollTop(); 9498 elementHeight = this.activeMenu.height(); 9499 itemHeight = item.height(); 9500 9501 if ( offset < 0 ) { 9502 this.activeMenu.scrollTop( scroll + offset ); 9503 } else if ( offset + itemHeight > elementHeight ) { 9504 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 9505 } 9506 } 9507 }, 9508 9509 blur: function( event, fromFocus ) { 9510 if ( !fromFocus ) { 9511 clearTimeout( this.timer ); 9512 } 9513 9514 if ( !this.active ) { 9515 return; 9516 } 9517 9518 this.active.children( "a" ).removeClass( "ui-state-focus" ); 9519 this.active = null; 9520 9521 this._trigger( "blur", event, { item: this.active } ); 9522 }, 9523 9524 _startOpening: function( submenu ) { 9525 clearTimeout( this.timer ); 9526 9527 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 9528 // shift in the submenu position when mousing over the carat icon 9529 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 9530 return; 9531 } 9532 9533 this.timer = this._delay(function() { 9534 this._close(); 9535 this._open( submenu ); 9536 }, this.delay ); 9537 }, 9538 9539 _open: function( submenu ) { 9540 var position = $.extend({ 9541 of: this.active 9542 }, this.options.position ); 9543 9544 clearTimeout( this.timer ); 9545 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 9546 .hide() 9547 .attr( "aria-hidden", "true" ); 9548 9549 submenu 9550 .show() 9551 .removeAttr( "aria-hidden" ) 9552 .attr( "aria-expanded", "true" ) 9553 .position( position ); 9554 }, 9555 9556 collapseAll: function( event, all ) { 9557 clearTimeout( this.timer ); 9558 this.timer = this._delay(function() { 9559 // If we were passed an event, look for the submenu that contains the event 9560 var currentMenu = all ? this.element : 9561 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 9562 9563 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 9564 if ( !currentMenu.length ) { 9565 currentMenu = this.element; 9566 } 9567 9568 this._close( currentMenu ); 9569 9570 this.blur( event ); 9571 this.activeMenu = currentMenu; 9572 }, this.delay ); 9573 }, 9574 9575 // With no arguments, closes the currently active menu - if nothing is active 9576 // it closes all menus. If passed an argument, it will search for menus BELOW 9577 _close: function( startMenu ) { 9578 if ( !startMenu ) { 9579 startMenu = this.active ? this.active.parent() : this.element; 9580 } 9581 9582 startMenu 9583 .find( ".ui-menu" ) 9584 .hide() 9585 .attr( "aria-hidden", "true" ) 9586 .attr( "aria-expanded", "false" ) 9587 .end() 9588 .find( "a.ui-state-active" ) 9589 .removeClass( "ui-state-active" ); 9590 }, 9591 9592 collapse: function( event ) { 9593 var newItem = this.active && 9594 this.active.parent().closest( ".ui-menu-item", this.element ); 9595 if ( newItem && newItem.length ) { 9596 this._close(); 9597 this.focus( event, newItem ); 9598 } 9599 }, 9600 9601 expand: function( event ) { 9602 var newItem = this.active && 9603 this.active 9604 .children( ".ui-menu " ) 9605 .children( ".ui-menu-item" ) 9606 .first(); 9607 9608 if ( newItem && newItem.length ) { 9609 this._open( newItem.parent() ); 9610 9611 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 9612 this._delay(function() { 9613 this.focus( event, newItem ); 9614 }); 9615 } 9616 }, 9617 9618 next: function( event ) { 9619 this._move( "next", "first", event ); 9620 }, 9621 9622 previous: function( event ) { 9623 this._move( "prev", "last", event ); 9624 }, 9625 9626 isFirstItem: function() { 9627 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 9628 }, 9629 9630 isLastItem: function() { 9631 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 9632 }, 9633 9634 _move: function( direction, filter, event ) { 9635 var next; 9636 if ( this.active ) { 9637 if ( direction === "first" || direction === "last" ) { 9638 next = this.active 9639 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 9640 .eq( -1 ); 9641 } else { 9642 next = this.active 9643 [ direction + "All" ]( ".ui-menu-item" ) 9644 .eq( 0 ); 9645 } 9646 } 9647 if ( !next || !next.length || !this.active ) { 9648 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 9649 } 9650 9651 this.focus( event, next ); 9652 }, 9653 9654 nextPage: function( event ) { 9655 var item, base, height; 9656 9657 if ( !this.active ) { 9658 this.next( event ); 9659 return; 9660 } 9661 if ( this.isLastItem() ) { 9662 return; 9663 } 9664 if ( this._hasScroll() ) { 9665 base = this.active.offset().top; 9666 height = this.element.height(); 9667 this.active.nextAll( ".ui-menu-item" ).each(function() { 9668 item = $( this ); 9669 return item.offset().top - base - height < 0; 9670 }); 9671 9672 this.focus( event, item ); 9673 } else { 9674 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 9675 [ !this.active ? "first" : "last" ]() ); 9676 } 9677 }, 9678 9679 previousPage: function( event ) { 9680 var item, base, height; 9681 if ( !this.active ) { 9682 this.next( event ); 9683 return; 9684 } 9685 if ( this.isFirstItem() ) { 9686 return; 9687 } 9688 if ( this._hasScroll() ) { 9689 base = this.active.offset().top; 9690 height = this.element.height(); 9691 this.active.prevAll( ".ui-menu-item" ).each(function() { 9692 item = $( this ); 9693 return item.offset().top - base + height > 0; 9694 }); 9695 9696 this.focus( event, item ); 9697 } else { 9698 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 9699 } 9700 }, 9701 9702 _hasScroll: function() { 9703 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 9704 }, 9705 9706 select: function( event ) { 9707 // TODO: It should never be possible to not have an active item at this 9708 // point, but the tests don't trigger mouseenter before click. 9709 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 9710 var ui = { item: this.active }; 9711 if ( !this.active.has( ".ui-menu" ).length ) { 9712 this.collapseAll( event, true ); 9713 } 9714 this._trigger( "select", event, ui ); 9715 } 9716}); 9717 9718}( jQuery )); 9719(function( $, undefined ) { 9720 9721$.widget( "ui.progressbar", { 9722 version: "1.9.2", 9723 options: { 9724 value: 0, 9725 max: 100 9726 }, 9727 9728 min: 0, 9729 9730 _create: function() { 9731 this.element 9732 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 9733 .attr({ 9734 role: "progressbar", 9735 "aria-valuemin": this.min, 9736 "aria-valuemax": this.options.max, 9737 "aria-valuenow": this._value() 9738 }); 9739 9740 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 9741 .appendTo( this.element ); 9742 9743 this.oldValue = this._value(); 9744 this._refreshValue(); 9745 }, 9746 9747 _destroy: function() { 9748 this.element 9749 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 9750 .removeAttr( "role" ) 9751 .removeAttr( "aria-valuemin" ) 9752 .removeAttr( "aria-valuemax" ) 9753 .removeAttr( "aria-valuenow" ); 9754 9755 this.valueDiv.remove(); 9756 }, 9757 9758 value: function( newValue ) { 9759 if ( newValue === undefined ) { 9760 return this._value(); 9761 } 9762 9763 this._setOption( "value", newValue ); 9764 return this; 9765 }, 9766 9767 _setOption: function( key, value ) { 9768 if ( key === "value" ) { 9769 this.options.value = value; 9770 this._refreshValue(); 9771 if ( this._value() === this.options.max ) { 9772 this._trigger( "complete" ); 9773 } 9774 } 9775 9776 this._super( key, value ); 9777 }, 9778 9779 _value: function() { 9780 var val = this.options.value; 9781 // normalize invalid value 9782 if ( typeof val !== "number" ) { 9783 val = 0; 9784 } 9785 return Math.min( this.options.max, Math.max( this.min, val ) ); 9786 }, 9787 9788 _percentage: function() { 9789 return 100 * this._value() / this.options.max; 9790 }, 9791 9792 _refreshValue: function() { 9793 var value = this.value(), 9794 percentage = this._percentage(); 9795 9796 if ( this.oldValue !== value ) { 9797 this.oldValue = value; 9798 this._trigger( "change" ); 9799 } 9800 9801 this.valueDiv 9802 .toggle( value > this.min ) 9803 .toggleClass( "ui-corner-right", value === this.options.max ) 9804 .width( percentage.toFixed(0) + "%" ); 9805 this.element.attr( "aria-valuenow", value ); 9806 } 9807}); 9808 9809})( jQuery ); 9810(function( $, undefined ) { 9811 9812// number of pages in a slider 9813// (how many times can you page up/down to go through the whole range) 9814var numPages = 5; 9815 9816$.widget( "ui.slider", $.ui.mouse, { 9817 version: "1.9.2", 9818 widgetEventPrefix: "slide", 9819 9820 options: { 9821 animate: false, 9822 distance: 0, 9823 max: 100, 9824 min: 0, 9825 orientation: "horizontal", 9826 range: false, 9827 step: 1, 9828 value: 0, 9829 values: null 9830 }, 9831 9832 _create: function() { 9833 var i, handleCount, 9834 o = this.options, 9835 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 9836 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 9837 handles = []; 9838 9839 this._keySliding = false; 9840 this._mouseSliding = false; 9841 this._animateOff = true; 9842 this._handleIndex = null; 9843 this._detectOrientation(); 9844 this._mouseInit(); 9845 9846 this.element 9847 .addClass( "ui-slider" + 9848 " ui-slider-" + this.orientation + 9849 " ui-widget" + 9850 " ui-widget-content" + 9851 " ui-corner-all" + 9852 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); 9853 9854 this.range = $([]); 9855 9856 if ( o.range ) { 9857 if ( o.range === true ) { 9858 if ( !o.values ) { 9859 o.values = [ this._valueMin(), this._valueMin() ]; 9860 } 9861 if ( o.values.length && o.values.length !== 2 ) { 9862 o.values = [ o.values[0], o.values[0] ]; 9863 } 9864 } 9865 9866 this.range = $( "<div></div>" ) 9867 .appendTo( this.element ) 9868 .addClass( "ui-slider-range" + 9869 // note: this isn't the most fittingly semantic framework class for this element, 9870 // but worked best visually with a variety of themes 9871 " ui-widget-header" + 9872 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); 9873 } 9874 9875 handleCount = ( o.values && o.values.length ) || 1; 9876 9877 for ( i = existingHandles.length; i < handleCount; i++ ) { 9878 handles.push( handle ); 9879 } 9880 9881 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 9882 9883 this.handle = this.handles.eq( 0 ); 9884 9885 this.handles.add( this.range ).filter( "a" ) 9886 .click(function( event ) { 9887 event.preventDefault(); 9888 }) 9889 .mouseenter(function() { 9890 if ( !o.disabled ) { 9891 $( this ).addClass( "ui-state-hover" ); 9892 } 9893 }) 9894 .mouseleave(function() { 9895 $( this ).removeClass( "ui-state-hover" ); 9896 }) 9897 .focus(function() { 9898 if ( !o.disabled ) { 9899 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); 9900 $( this ).addClass( "ui-state-focus" ); 9901 } else { 9902 $( this ).blur(); 9903 } 9904 }) 9905 .blur(function() { 9906 $( this ).removeClass( "ui-state-focus" ); 9907 }); 9908 9909 this.handles.each(function( i ) { 9910 $( this ).data( "ui-slider-handle-index", i ); 9911 }); 9912 9913 this._on( this.handles, { 9914 keydown: function( event ) { 9915 var allowed, curVal, newVal, step, 9916 index = $( event.target ).data( "ui-slider-handle-index" ); 9917 9918 switch ( event.keyCode ) { 9919 case $.ui.keyCode.HOME: 9920 case $.ui.keyCode.END: 9921 case $.ui.keyCode.PAGE_UP: 9922 case $.ui.keyCode.PAGE_DOWN: 9923 case $.ui.keyCode.UP: 9924 case $.ui.keyCode.RIGHT: 9925 case $.ui.keyCode.DOWN: 9926 case $.ui.keyCode.LEFT: 9927 event.preventDefault(); 9928 if ( !this._keySliding ) { 9929 this._keySliding = true; 9930 $( event.target ).addClass( "ui-state-active" ); 9931 allowed = this._start( event, index ); 9932 if ( allowed === false ) { 9933 return; 9934 } 9935 } 9936 break; 9937 } 9938 9939 step = this.options.step; 9940 if ( this.options.values && this.options.values.length ) { 9941 curVal = newVal = this.values( index ); 9942 } else { 9943 curVal = newVal = this.value(); 9944 } 9945 9946 switch ( event.keyCode ) { 9947 case $.ui.keyCode.HOME: 9948 newVal = this._valueMin(); 9949 break; 9950 case $.ui.keyCode.END: 9951 newVal = this._valueMax(); 9952 break; 9953 case $.ui.keyCode.PAGE_UP: 9954 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 9955 break; 9956 case $.ui.keyCode.PAGE_DOWN: 9957 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 9958 break; 9959 case $.ui.keyCode.UP: 9960 case $.ui.keyCode.RIGHT: 9961 if ( curVal === this._valueMax() ) { 9962 return; 9963 } 9964 newVal = this._trimAlignValue( curVal + step ); 9965 break; 9966 case $.ui.keyCode.DOWN: 9967 case $.ui.keyCode.LEFT: 9968 if ( curVal === this._valueMin() ) { 9969 return; 9970 } 9971 newVal = this._trimAlignValue( curVal - step ); 9972 break; 9973 } 9974 9975 this._slide( event, index, newVal ); 9976 }, 9977 keyup: function( event ) { 9978 var index = $( event.target ).data( "ui-slider-handle-index" ); 9979 9980 if ( this._keySliding ) { 9981 this._keySliding = false; 9982 this._stop( event, index ); 9983 this._change( event, index ); 9984 $( event.target ).removeClass( "ui-state-active" ); 9985 } 9986 } 9987 }); 9988 9989 this._refreshValue(); 9990 9991 this._animateOff = false; 9992 }, 9993 9994 _destroy: function() { 9995 this.handles.remove(); 9996 this.range.remove(); 9997 9998 this.element 9999 .removeClass( "ui-slider" + 10000 " ui-slider-horizontal" + 10001 " ui-slider-vertical" + 10002 " ui-slider-disabled" + 10003 " ui-widget" + 10004 " ui-widget-content" + 10005 " ui-corner-all" ); 10006 10007 this._mouseDestroy(); 10008 }, 10009 10010 _mouseCapture: function( event ) { 10011 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 10012 that = this, 10013 o = this.options; 10014 10015 if ( o.disabled ) { 10016 return false; 10017 } 10018 10019 this.elementSize = { 10020 width: this.element.outerWidth(), 10021 height: this.element.outerHeight() 10022 }; 10023 this.elementOffset = this.element.offset(); 10024 10025 position = { x: event.pageX, y: event.pageY }; 10026 normValue = this._normValueFromMouse( position ); 10027 distance = this._valueMax() - this._valueMin() + 1; 10028 this.handles.each(function( i ) { 10029 var thisDistance = Math.abs( normValue - that.values(i) ); 10030 if ( distance > thisDistance ) { 10031 distance = thisDistance; 10032 closestHandle = $( this ); 10033 index = i; 10034 } 10035 }); 10036 10037 // workaround for bug #3736 (if both handles of a range are at 0, 10038 // the first is always used as the one with least distance, 10039 // and moving it is obviously prevented by preventing negative ranges) 10040 if( o.range === true && this.values(1) === o.min ) { 10041 index += 1; 10042 closestHandle = $( this.handles[index] ); 10043 } 10044 10045 allowed = this._start( event, index ); 10046 if ( allowed === false ) { 10047 return false; 10048 } 10049 this._mouseSliding = true; 10050 10051 this._handleIndex = index; 10052 10053 closestHandle 10054 .addClass( "ui-state-active" ) 10055 .focus(); 10056 10057 offset = closestHandle.offset(); 10058 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); 10059 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 10060 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 10061 top: event.pageY - offset.top - 10062 ( closestHandle.height() / 2 ) - 10063 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 10064 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 10065 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 10066 }; 10067 10068 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 10069 this._slide( event, index, normValue ); 10070 } 10071 this._animateOff = true; 10072 return true; 10073 }, 10074 10075 _mouseStart: function() { 10076 return true; 10077 }, 10078 10079 _mouseDrag: function( event ) { 10080 var position = { x: event.pageX, y: event.pageY }, 10081 normValue = this._normValueFromMouse( position ); 10082 10083 this._slide( event, this._handleIndex, normValue ); 10084 10085 return false; 10086 }, 10087 10088 _mouseStop: function( event ) { 10089 this.handles.removeClass( "ui-state-active" ); 10090 this._mouseSliding = false; 10091 10092 this._stop( event, this._handleIndex ); 10093 this._change( event, this._handleIndex ); 10094 10095 this._handleIndex = null; 10096 this._clickOffset = null; 10097 this._animateOff = false; 10098 10099 return false; 10100 }, 10101 10102 _detectOrientation: function() { 10103 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 10104 }, 10105 10106 _normValueFromMouse: function( position ) { 10107 var pixelTotal, 10108 pixelMouse, 10109 percentMouse, 10110 valueTotal, 10111 valueMouse; 10112 10113 if ( this.orientation === "horizontal" ) { 10114 pixelTotal = this.elementSize.width; 10115 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 10116 } else { 10117 pixelTotal = this.elementSize.height; 10118 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 10119 } 10120 10121 percentMouse = ( pixelMouse / pixelTotal ); 10122 if ( percentMouse > 1 ) { 10123 percentMouse = 1; 10124 } 10125 if ( percentMouse < 0 ) { 10126 percentMouse = 0; 10127 } 10128 if ( this.orientation === "vertical" ) { 10129 percentMouse = 1 - percentMouse; 10130 } 10131 10132 valueTotal = this._valueMax() - this._valueMin(); 10133 valueMouse = this._valueMin() + percentMouse * valueTotal; 10134 10135 return this._trimAlignValue( valueMouse ); 10136 }, 10137 10138 _start: function( event, index ) { 10139 var uiHash = { 10140 handle: this.handles[ index ], 10141 value: this.value() 10142 }; 10143 if ( this.options.values && this.options.values.length ) { 10144 uiHash.value = this.values( index ); 10145 uiHash.values = this.values(); 10146 } 10147 return this._trigger( "start", event, uiHash ); 10148 }, 10149 10150 _slide: function( event, index, newVal ) { 10151 var otherVal, 10152 newValues, 10153 allowed; 10154 10155 if ( this.options.values && this.options.values.length ) { 10156 otherVal = this.values( index ? 0 : 1 ); 10157 10158 if ( ( this.options.values.length === 2 && this.options.range === true ) && 10159 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 10160 ) { 10161 newVal = otherVal; 10162 } 10163 10164 if ( newVal !== this.values( index ) ) { 10165 newValues = this.values(); 10166 newValues[ index ] = newVal; 10167 // A slide can be canceled by returning false from the slide callback 10168 allowed = this._trigger( "slide", event, { 10169 handle: this.handles[ index ], 10170 value: newVal, 10171 values: newValues 10172 } ); 10173 otherVal = this.values( index ? 0 : 1 ); 10174 if ( allowed !== false ) { 10175 this.values( index, newVal, true ); 10176 } 10177 } 10178 } else { 10179 if ( newVal !== this.value() ) { 10180 // A slide can be canceled by returning false from the slide callback 10181 allowed = this._trigger( "slide", event, { 10182 handle: this.handles[ index ], 10183 value: newVal 10184 } ); 10185 if ( allowed !== false ) { 10186 this.value( newVal ); 10187 } 10188 } 10189 } 10190 }, 10191 10192 _stop: function( event, index ) { 10193 var uiHash = { 10194 handle: this.handles[ index ], 10195 value: this.value() 10196 }; 10197 if ( this.options.values && this.options.values.length ) { 10198 uiHash.value = this.values( index ); 10199 uiHash.values = this.values(); 10200 } 10201 10202 this._trigger( "stop", event, uiHash ); 10203 }, 10204 10205 _change: function( event, index ) { 10206 if ( !this._keySliding && !this._mouseSliding ) { 10207 var uiHash = { 10208 handle: this.handles[ index ], 10209 value: this.value() 10210 }; 10211 if ( this.options.values && this.options.values.length ) { 10212 uiHash.value = this.values( index ); 10213 uiHash.values = this.values(); 10214 } 10215 10216 this._trigger( "change", event, uiHash ); 10217 } 10218 }, 10219 10220 value: function( newValue ) { 10221 if ( arguments.length ) { 10222 this.options.value = this._trimAlignValue( newValue ); 10223 this._refreshValue(); 10224 this._change( null, 0 ); 10225 return; 10226 } 10227 10228 return this._value(); 10229 }, 10230 10231 values: function( index, newValue ) { 10232 var vals, 10233 newValues, 10234 i; 10235 10236 if ( arguments.length > 1 ) { 10237 this.options.values[ index ] = this._trimAlignValue( newValue ); 10238 this._refreshValue(); 10239 this._change( null, index ); 10240 return; 10241 } 10242 10243 if ( arguments.length ) { 10244 if ( $.isArray( arguments[ 0 ] ) ) { 10245 vals = this.options.values; 10246 newValues = arguments[ 0 ]; 10247 for ( i = 0; i < vals.length; i += 1 ) { 10248 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 10249 this._change( null, i ); 10250 } 10251 this._refreshValue(); 10252 } else { 10253 if ( this.options.values && this.options.values.length ) { 10254 return this._values( index ); 10255 } else { 10256 return this.value(); 10257 } 10258 } 10259 } else { 10260 return this._values(); 10261 } 10262 }, 10263 10264 _setOption: function( key, value ) { 10265 var i, 10266 valsLength = 0; 10267 10268 if ( $.isArray( this.options.values ) ) { 10269 valsLength = this.options.values.length; 10270 } 10271 10272 $.Widget.prototype._setOption.apply( this, arguments ); 10273 10274 switch ( key ) { 10275 case "disabled": 10276 if ( value ) { 10277 this.handles.filter( ".ui-state-focus" ).blur(); 10278 this.handles.removeClass( "ui-state-hover" ); 10279 this.handles.prop( "disabled", true ); 10280 this.element.addClass( "ui-disabled" ); 10281 } else { 10282 this.handles.prop( "disabled", false ); 10283 this.element.removeClass( "ui-disabled" ); 10284 } 10285 break; 10286 case "orientation": 10287 this._detectOrientation(); 10288 this.element 10289 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 10290 .addClass( "ui-slider-" + this.orientation ); 10291 this._refreshValue(); 10292 break; 10293 case "value": 10294 this._animateOff = true; 10295 this._refreshValue(); 10296 this._change( null, 0 ); 10297 this._animateOff = false; 10298 break; 10299 case "values": 10300 this._animateOff = true; 10301 this._refreshValue(); 10302 for ( i = 0; i < valsLength; i += 1 ) { 10303 this._change( null, i ); 10304 } 10305 this._animateOff = false; 10306 break; 10307 case "min": 10308 case "max": 10309 this._animateOff = true; 10310 this._refreshValue(); 10311 this._animateOff = false; 10312 break; 10313 } 10314 }, 10315 10316 //internal value getter 10317 // _value() returns value trimmed by min and max, aligned by step 10318 _value: function() { 10319 var val = this.options.value; 10320 val = this._trimAlignValue( val ); 10321 10322 return val; 10323 }, 10324 10325 //internal values getter 10326 // _values() returns array of values trimmed by min and max, aligned by step 10327 // _values( index ) returns single value trimmed by min and max, aligned by step 10328 _values: function( index ) { 10329 var val, 10330 vals, 10331 i; 10332 10333 if ( arguments.length ) { 10334 val = this.options.values[ index ]; 10335 val = this._trimAlignValue( val ); 10336 10337 return val; 10338 } else { 10339 // .slice() creates a copy of the array 10340 // this copy gets trimmed by min and max and then returned 10341 vals = this.options.values.slice(); 10342 for ( i = 0; i < vals.length; i+= 1) { 10343 vals[ i ] = this._trimAlignValue( vals[ i ] ); 10344 } 10345 10346 return vals; 10347 } 10348 }, 10349 10350 // returns the step-aligned value that val is closest to, between (inclusive) min and max 10351 _trimAlignValue: function( val ) { 10352 if ( val <= this._valueMin() ) { 10353 return this._valueMin(); 10354 } 10355 if ( val >= this._valueMax() ) { 10356 return this._valueMax(); 10357 } 10358 var step = ( this.options.step > 0 ) ? this.options.step : 1, 10359 valModStep = (val - this._valueMin()) % step, 10360 alignValue = val - valModStep; 10361 10362 if ( Math.abs(valModStep) * 2 >= step ) { 10363 alignValue += ( valModStep > 0 ) ? step : ( -step ); 10364 } 10365 10366 // Since JavaScript has problems with large floats, round 10367 // the final value to 5 digits after the decimal point (see #4124) 10368 return parseFloat( alignValue.toFixed(5) ); 10369 }, 10370 10371 _valueMin: function() { 10372 return this.options.min; 10373 }, 10374 10375 _valueMax: function() { 10376 return this.options.max; 10377 }, 10378 10379 _refreshValue: function() { 10380 var lastValPercent, valPercent, value, valueMin, valueMax, 10381 oRange = this.options.range, 10382 o = this.options, 10383 that = this, 10384 animate = ( !this._animateOff ) ? o.animate : false, 10385 _set = {}; 10386 10387 if ( this.options.values && this.options.values.length ) { 10388 this.handles.each(function( i ) { 10389 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 10390 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10391 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10392 if ( that.options.range === true ) { 10393 if ( that.orientation === "horizontal" ) { 10394 if ( i === 0 ) { 10395 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 10396 } 10397 if ( i === 1 ) { 10398 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10399 } 10400 } else { 10401 if ( i === 0 ) { 10402 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 10403 } 10404 if ( i === 1 ) { 10405 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10406 } 10407 } 10408 } 10409 lastValPercent = valPercent; 10410 }); 10411 } else { 10412 value = this.value(); 10413 valueMin = this._valueMin(); 10414 valueMax = this._valueMax(); 10415 valPercent = ( valueMax !== valueMin ) ? 10416 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 10417 0; 10418 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10419 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10420 10421 if ( oRange === "min" && this.orientation === "horizontal" ) { 10422 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 10423 } 10424 if ( oRange === "max" && this.orientation === "horizontal" ) { 10425 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10426 } 10427 if ( oRange === "min" && this.orientation === "vertical" ) { 10428 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 10429 } 10430 if ( oRange === "max" && this.orientation === "vertical" ) { 10431 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10432 } 10433 } 10434 } 10435 10436}); 10437 10438}(jQuery)); 10439(function( $ ) { 10440 10441function modifier( fn ) { 10442 return function() { 10443 var previous = this.element.val(); 10444 fn.apply( this, arguments ); 10445 this._refresh(); 10446 if ( previous !== this.element.val() ) { 10447 this._trigger( "change" ); 10448 } 10449 }; 10450} 10451 10452$.widget( "ui.spinner", { 10453 version: "1.9.2", 10454 defaultElement: "<input>", 10455 widgetEventPrefix: "spin", 10456 options: { 10457 culture: null, 10458 icons: { 10459 down: "ui-icon-triangle-1-s", 10460 up: "ui-icon-triangle-1-n" 10461 }, 10462 incremental: true, 10463 max: null, 10464 min: null, 10465 numberFormat: null, 10466 page: 10, 10467 step: 1, 10468 10469 change: null, 10470 spin: null, 10471 start: null, 10472 stop: null 10473 }, 10474 10475 _create: function() { 10476 // handle string values that need to be parsed 10477 this._setOption( "max", this.options.max ); 10478 this._setOption( "min", this.options.min ); 10479 this._setOption( "step", this.options.step ); 10480 10481 // format the value, but don't constrain 10482 this._value( this.element.val(), true ); 10483 10484 this._draw(); 10485 this._on( this._events ); 10486 this._refresh(); 10487 10488 // turning off autocomplete prevents the browser from remembering the 10489 // value when navigating through history, so we re-enable autocomplete 10490 // if the page is unloaded before the widget is destroyed. #7790 10491 this._on( this.window, { 10492 beforeunload: function() { 10493 this.element.removeAttr( "autocomplete" ); 10494 } 10495 }); 10496 }, 10497 10498 _getCreateOptions: function() { 10499 var options = {}, 10500 element = this.element; 10501 10502 $.each( [ "min", "max", "step" ], function( i, option ) { 10503 var value = element.attr( option ); 10504 if ( value !== undefined && value.length ) { 10505 options[ option ] = value; 10506 } 10507 }); 10508 10509 return options; 10510 }, 10511 10512 _events: { 10513 keydown: function( event ) { 10514 if ( this._start( event ) && this._keydown( event ) ) { 10515 event.preventDefault(); 10516 } 10517 }, 10518 keyup: "_stop", 10519 focus: function() { 10520 this.previous = this.element.val(); 10521 }, 10522 blur: function( event ) { 10523 if ( this.cancelBlur ) { 10524 delete this.cancelBlur; 10525 return; 10526 } 10527 10528 this._refresh(); 10529 if ( this.previous !== this.element.val() ) { 10530 this._trigger( "change", event ); 10531 } 10532 }, 10533 mousewheel: function( event, delta ) { 10534 if ( !delta ) { 10535 return; 10536 } 10537 if ( !this.spinning && !this._start( event ) ) { 10538 return false; 10539 } 10540 10541 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 10542 clearTimeout( this.mousewheelTimer ); 10543 this.mousewheelTimer = this._delay(function() { 10544 if ( this.spinning ) { 10545 this._stop( event ); 10546 } 10547 }, 100 ); 10548 event.preventDefault(); 10549 }, 10550 "mousedown .ui-spinner-button": function( event ) { 10551 var previous; 10552 10553 // We never want the buttons to have focus; whenever the user is 10554 // interacting with the spinner, the focus should be on the input. 10555 // If the input is focused then this.previous is properly set from 10556 // when the input first received focus. If the input is not focused 10557 // then we need to set this.previous based on the value before spinning. 10558 previous = this.element[0] === this.document[0].activeElement ? 10559 this.previous : this.element.val(); 10560 function checkFocus() { 10561 var isActive = this.element[0] === this.document[0].activeElement; 10562 if ( !isActive ) { 10563 this.element.focus(); 10564 this.previous = previous; 10565 // support: IE 10566 // IE sets focus asynchronously, so we need to check if focus 10567 // moved off of the input because the user clicked on the button. 10568 this._delay(function() { 10569 this.previous = previous; 10570 }); 10571 } 10572 } 10573 10574 // ensure focus is on (or stays on) the text field 10575 event.preventDefault(); 10576 checkFocus.call( this ); 10577 10578 // support: IE 10579 // IE doesn't prevent moving focus even with event.preventDefault() 10580 // so we set a flag to know when we should ignore the blur event 10581 // and check (again) if focus moved off of the input. 10582 this.cancelBlur = true; 10583 this._delay(function() { 10584 delete this.cancelBlur; 10585 checkFocus.call( this ); 10586 }); 10587 10588 if ( this._start( event ) === false ) { 10589 return; 10590 } 10591 10592 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 10593 }, 10594 "mouseup .ui-spinner-button": "_stop", 10595 "mouseenter .ui-spinner-button": function( event ) { 10596 // button will add ui-state-active if mouse was down while mouseleave and kept down 10597 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 10598 return; 10599 } 10600 10601 if ( this._start( event ) === false ) { 10602 return false; 10603 } 10604 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 10605 }, 10606 // TODO: do we really want to consider this a stop? 10607 // shouldn't we just stop the repeater and wait until mouseup before 10608 // we trigger the stop event? 10609 "mouseleave .ui-spinner-button": "_stop" 10610 }, 10611 10612 _draw: function() { 10613 var uiSpinner = this.uiSpinner = this.element 10614 .addClass( "ui-spinner-input" ) 10615 .attr( "autocomplete", "off" ) 10616 .wrap( this._uiSpinnerHtml() ) 10617 .parent() 10618 // add buttons 10619 .append( this._buttonHtml() ); 10620 10621 this.element.attr( "role", "spinbutton" ); 10622 10623 // button bindings 10624 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 10625 .attr( "tabIndex", -1 ) 10626 .button() 10627 .removeClass( "ui-corner-all" ); 10628 10629 // IE 6 doesn't understand height: 50% for the buttons 10630 // unless the wrapper has an explicit height 10631 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 10632 uiSpinner.height() > 0 ) { 10633 uiSpinner.height( uiSpinner.height() ); 10634 } 10635 10636 // disable spinner if element was already disabled 10637 if ( this.options.disabled ) { 10638 this.disable(); 10639 } 10640 }, 10641 10642 _keydown: function( event ) { 10643 var options = this.options, 10644 keyCode = $.ui.keyCode; 10645 10646 switch ( event.keyCode ) { 10647 case keyCode.UP: 10648 this._repeat( null, 1, event ); 10649 return true; 10650 case keyCode.DOWN: 10651 this._repeat( null, -1, event ); 10652 return true; 10653 case keyCode.PAGE_UP: 10654 this._repeat( null, options.page, event ); 10655 return true; 10656 case keyCode.PAGE_DOWN: 10657 this._repeat( null, -options.page, event ); 10658 return true; 10659 } 10660 10661 return false; 10662 }, 10663 10664 _uiSpinnerHtml: function() { 10665 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 10666 }, 10667 10668 _buttonHtml: function() { 10669 return "" + 10670 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 10671 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 10672 "</a>" + 10673 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 10674 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 10675 "</a>"; 10676 }, 10677 10678 _start: function( event ) { 10679 if ( !this.spinning && this._trigger( "start", event ) === false ) { 10680 return false; 10681 } 10682 10683 if ( !this.counter ) { 10684 this.counter = 1; 10685 } 10686 this.spinning = true; 10687 return true; 10688 }, 10689 10690 _repeat: function( i, steps, event ) { 10691 i = i || 500; 10692 10693 clearTimeout( this.timer ); 10694 this.timer = this._delay(function() { 10695 this._repeat( 40, steps, event ); 10696 }, i ); 10697 10698 this._spin( steps * this.options.step, event ); 10699 }, 10700 10701 _spin: function( step, event ) { 10702 var value = this.value() || 0; 10703 10704 if ( !this.counter ) { 10705 this.counter = 1; 10706 } 10707 10708 value = this._adjustValue( value + step * this._increment( this.counter ) ); 10709 10710 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 10711 this._value( value ); 10712 this.counter++; 10713 } 10714 }, 10715 10716 _increment: function( i ) { 10717 var incremental = this.options.incremental; 10718 10719 if ( incremental ) { 10720 return $.isFunction( incremental ) ? 10721 incremental( i ) : 10722 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 10723 } 10724 10725 return 1; 10726 }, 10727 10728 _precision: function() { 10729 var precision = this._precisionOf( this.options.step ); 10730 if ( this.options.min !== null ) { 10731 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 10732 } 10733 return precision; 10734 }, 10735 10736 _precisionOf: function( num ) { 10737 var str = num.toString(), 10738 decimal = str.indexOf( "." ); 10739 return decimal === -1 ? 0 : str.length - decimal - 1; 10740 }, 10741 10742 _adjustValue: function( value ) { 10743 var base, aboveMin, 10744 options = this.options; 10745 10746 // make sure we're at a valid step 10747 // - find out where we are relative to the base (min or 0) 10748 base = options.min !== null ? options.min : 0; 10749 aboveMin = value - base; 10750 // - round to the nearest step 10751 aboveMin = Math.round(aboveMin / options.step) * options.step; 10752 // - rounding is based on 0, so adjust back to our base 10753 value = base + aboveMin; 10754 10755 // fix precision from bad JS floating point math 10756 value = parseFloat( value.toFixed( this._precision() ) ); 10757 10758 // clamp the value 10759 if ( options.max !== null && value > options.max) { 10760 return options.max; 10761 } 10762 if ( options.min !== null && value < options.min ) { 10763 return options.min; 10764 } 10765 10766 return value; 10767 }, 10768 10769 _stop: function( event ) { 10770 if ( !this.spinning ) { 10771 return; 10772 } 10773 10774 clearTimeout( this.timer ); 10775 clearTimeout( this.mousewheelTimer ); 10776 this.counter = 0; 10777 this.spinning = false; 10778 this._trigger( "stop", event ); 10779 }, 10780 10781 _setOption: function( key, value ) { 10782 if ( key === "culture" || key === "numberFormat" ) { 10783 var prevValue = this._parse( this.element.val() ); 10784 this.options[ key ] = value; 10785 this.element.val( this._format( prevValue ) ); 10786 return; 10787 } 10788 10789 if ( key === "max" || key === "min" || key === "step" ) { 10790 if ( typeof value === "string" ) { 10791 value = this._parse( value ); 10792 } 10793 } 10794 10795 this._super( key, value ); 10796 10797 if ( key === "disabled" ) { 10798 if ( value ) { 10799 this.element.prop( "disabled", true ); 10800 this.buttons.button( "disable" ); 10801 } else { 10802 this.element.prop( "disabled", false ); 10803 this.buttons.button( "enable" ); 10804 } 10805 } 10806 }, 10807 10808 _setOptions: modifier(function( options ) { 10809 this._super( options ); 10810 this._value( this.element.val() ); 10811 }), 10812 10813 _parse: function( val ) { 10814 if ( typeof val === "string" && val !== "" ) { 10815 val = window.Globalize && this.options.numberFormat ? 10816 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 10817 } 10818 return val === "" || isNaN( val ) ? null : val; 10819 }, 10820 10821 _format: function( value ) { 10822 if ( value === "" ) { 10823 return ""; 10824 } 10825 return window.Globalize && this.options.numberFormat ? 10826 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 10827 value; 10828 }, 10829 10830 _refresh: function() { 10831 this.element.attr({ 10832 "aria-valuemin": this.options.min, 10833 "aria-valuemax": this.options.max, 10834 // TODO: what should we do with values that can't be parsed? 10835 "aria-valuenow": this._parse( this.element.val() ) 10836 }); 10837 }, 10838 10839 // update the value without triggering change 10840 _value: function( value, allowAny ) { 10841 var parsed; 10842 if ( value !== "" ) { 10843 parsed = this._parse( value ); 10844 if ( parsed !== null ) { 10845 if ( !allowAny ) { 10846 parsed = this._adjustValue( parsed ); 10847 } 10848 value = this._format( parsed ); 10849 } 10850 } 10851 this.element.val( value ); 10852 this._refresh(); 10853 }, 10854 10855 _destroy: function() { 10856 this.element 10857 .removeClass( "ui-spinner-input" ) 10858 .prop( "disabled", false ) 10859 .removeAttr( "autocomplete" ) 10860 .removeAttr( "role" ) 10861 .removeAttr( "aria-valuemin" ) 10862 .removeAttr( "aria-valuemax" ) 10863 .removeAttr( "aria-valuenow" ); 10864 this.uiSpinner.replaceWith( this.element ); 10865 }, 10866 10867 stepUp: modifier(function( steps ) { 10868 this._stepUp( steps ); 10869 }), 10870 _stepUp: function( steps ) { 10871 this._spin( (steps || 1) * this.options.step ); 10872 }, 10873 10874 stepDown: modifier(function( steps ) { 10875 this._stepDown( steps ); 10876 }), 10877 _stepDown: function( steps ) { 10878 this._spin( (steps || 1) * -this.options.step ); 10879 }, 10880 10881 pageUp: modifier(function( pages ) { 10882 this._stepUp( (pages || 1) * this.options.page ); 10883 }), 10884 10885 pageDown: modifier(function( pages ) { 10886 this._stepDown( (pages || 1) * this.options.page ); 10887 }), 10888 10889 value: function( newVal ) { 10890 if ( !arguments.length ) { 10891 return this._parse( this.element.val() ); 10892 } 10893 modifier( this._value ).call( this, newVal ); 10894 }, 10895 10896 widget: function() { 10897 return this.uiSpinner; 10898 } 10899}); 10900 10901}( jQuery ) ); 10902(function( $, undefined ) { 10903 10904var tabId = 0, 10905 rhash = /#.*$/; 10906 10907function getNextTabId() { 10908 return ++tabId; 10909} 10910 10911function isLocal( anchor ) { 10912 return anchor.hash.length > 1 && 10913 anchor.href.replace( rhash, "" ) === 10914 location.href.replace( rhash, "" ) 10915 // support: Safari 5.1 10916 // Safari 5.1 doesn't encode spaces in window.location 10917 // but it does encode spaces from anchors (#8777) 10918 .replace( /\s/g, "%20" ); 10919} 10920 10921$.widget( "ui.tabs", { 10922 version: "1.9.2", 10923 delay: 300, 10924 options: { 10925 active: null, 10926 collapsible: false, 10927 event: "click", 10928 heightStyle: "content", 10929 hide: null, 10930 show: null, 10931 10932 // callbacks 10933 activate: null, 10934 beforeActivate: null, 10935 beforeLoad: null, 10936 load: null 10937 }, 10938 10939 _create: function() { 10940 var that = this, 10941 options = this.options, 10942 active = options.active, 10943 locationHash = location.hash.substring( 1 ); 10944 10945 this.running = false; 10946 10947 this.element 10948 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 10949 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 10950 // Prevent users from focusing disabled tabs via click 10951 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 10952 if ( $( this ).is( ".ui-state-disabled" ) ) { 10953 event.preventDefault(); 10954 } 10955 }) 10956 // support: IE <9 10957 // Preventing the default action in mousedown doesn't prevent IE 10958 // from focusing the element, so if the anchor gets focused, blur. 10959 // We don't have to worry about focusing the previously focused 10960 // element since clicking on a non-focusable element should focus 10961 // the body anyway. 10962 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 10963 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 10964 this.blur(); 10965 } 10966 }); 10967 10968 this._processTabs(); 10969 10970 if ( active === null ) { 10971 // check the fragment identifier in the URL 10972 if ( locationHash ) { 10973 this.tabs.each(function( i, tab ) { 10974 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 10975 active = i; 10976 return false; 10977 } 10978 }); 10979 } 10980 10981 // check for a tab marked active via a class 10982 if ( active === null ) { 10983 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 10984 } 10985 10986 // no active tab, set to false 10987 if ( active === null || active === -1 ) { 10988 active = this.tabs.length ? 0 : false; 10989 } 10990 } 10991 10992 // handle numbers: negative, out of range 10993 if ( active !== false ) { 10994 active = this.tabs.index( this.tabs.eq( active ) ); 10995 if ( active === -1 ) { 10996 active = options.collapsible ? false : 0; 10997 } 10998 } 10999 options.active = active; 11000 11001 // don't allow collapsible: false and active: false 11002 if ( !options.collapsible && options.active === false && this.anchors.length ) { 11003 options.active = 0; 11004 } 11005 11006 // Take disabling tabs via class attribute from HTML 11007 // into account and update option properly. 11008 if ( $.isArray( options.disabled ) ) { 11009 options.disabled = $.unique( options.disabled.concat( 11010 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 11011 return that.tabs.index( li ); 11012 }) 11013 ) ).sort(); 11014 } 11015 11016 // check for length avoids error when initializing empty list 11017 if ( this.options.active !== false && this.anchors.length ) { 11018 this.active = this._findActive( this.options.active ); 11019 } else { 11020 this.active = $(); 11021 } 11022 11023 this._refresh(); 11024 11025 if ( this.active.length ) { 11026 this.load( options.active ); 11027 } 11028 }, 11029 11030 _getCreateEventData: function() { 11031 return { 11032 tab: this.active, 11033 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 11034 }; 11035 }, 11036 11037 _tabKeydown: function( event ) { 11038 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 11039 selectedIndex = this.tabs.index( focusedTab ), 11040 goingForward = true; 11041 11042 if ( this._handlePageNav( event ) ) { 11043 return; 11044 } 11045 11046 switch ( event.keyCode ) { 11047 case $.ui.keyCode.RIGHT: 11048 case $.ui.keyCode.DOWN: 11049 selectedIndex++; 11050 break; 11051 case $.ui.keyCode.UP: 11052 case $.ui.keyCode.LEFT: 11053 goingForward = false; 11054 selectedIndex--; 11055 break; 11056 case $.ui.keyCode.END: 11057 selectedIndex = this.anchors.length - 1; 11058 break; 11059 case $.ui.keyCode.HOME: 11060 selectedIndex = 0; 11061 break; 11062 case $.ui.keyCode.SPACE: 11063 // Activate only, no collapsing 11064 event.preventDefault(); 11065 clearTimeout( this.activating ); 11066 this._activate( selectedIndex ); 11067 return; 11068 case $.ui.keyCode.ENTER: 11069 // Toggle (cancel delayed activation, allow collapsing) 11070 event.preventDefault(); 11071 clearTimeout( this.activating ); 11072 // Determine if we should collapse or activate 11073 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 11074 return; 11075 default: 11076 return; 11077 } 11078 11079 // Focus the appropriate tab, based on which key was pressed 11080 event.preventDefault(); 11081 clearTimeout( this.activating ); 11082 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 11083 11084 // Navigating with control key will prevent automatic activation 11085 if ( !event.ctrlKey ) { 11086 // Update aria-selected immediately so that AT think the tab is already selected. 11087 // Otherwise AT may confuse the user by stating that they need to activate the tab, 11088 // but the tab will already be activated by the time the announcement finishes. 11089 focusedTab.attr( "aria-selected", "false" ); 11090 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 11091 11092 this.activating = this._delay(function() { 11093 this.option( "active", selectedIndex ); 11094 }, this.delay ); 11095 } 11096 }, 11097 11098 _panelKeydown: function( event ) { 11099 if ( this._handlePageNav( event ) ) { 11100 return; 11101 } 11102 11103 // Ctrl+up moves focus to the current tab 11104 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 11105 event.preventDefault(); 11106 this.active.focus(); 11107 } 11108 }, 11109 11110 // Alt+page up/down moves focus to the previous/next tab (and activates) 11111 _handlePageNav: function( event ) { 11112 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 11113 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 11114 return true; 11115 } 11116 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 11117 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 11118 return true; 11119 } 11120 }, 11121 11122 _findNextTab: function( index, goingForward ) { 11123 var lastTabIndex = this.tabs.length - 1; 11124 11125 function constrain() { 11126 if ( index > lastTabIndex ) { 11127 index = 0; 11128 } 11129 if ( index < 0 ) { 11130 index = lastTabIndex; 11131 } 11132 return index; 11133 } 11134 11135 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 11136 index = goingForward ? index + 1 : index - 1; 11137 } 11138 11139 return index; 11140 }, 11141 11142 _focusNextTab: function( index, goingForward ) { 11143 index = this._findNextTab( index, goingForward ); 11144 this.tabs.eq( index ).focus(); 11145 return index; 11146 }, 11147 11148 _setOption: function( key, value ) { 11149 if ( key === "active" ) { 11150 // _activate() will handle invalid values and update this.options 11151 this._activate( value ); 11152 return; 11153 } 11154 11155 if ( key === "disabled" ) { 11156 // don't use the widget factory's disabled handling 11157 this._setupDisabled( value ); 11158 return; 11159 } 11160 11161 this._super( key, value); 11162 11163 if ( key === "collapsible" ) { 11164 this.element.toggleClass( "ui-tabs-collapsible", value ); 11165 // Setting collapsible: false while collapsed; open first panel 11166 if ( !value && this.options.active === false ) { 11167 this._activate( 0 ); 11168 } 11169 } 11170 11171 if ( key === "event" ) { 11172 this._setupEvents( value ); 11173 } 11174 11175 if ( key === "heightStyle" ) { 11176 this._setupHeightStyle( value ); 11177 } 11178 }, 11179 11180 _tabId: function( tab ) { 11181 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 11182 }, 11183 11184 _sanitizeSelector: function( hash ) { 11185 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 11186 }, 11187 11188 refresh: function() { 11189 var options = this.options, 11190 lis = this.tablist.children( ":has(a[href])" ); 11191 11192 // get disabled tabs from class attribute from HTML 11193 // this will get converted to a boolean if needed in _refresh() 11194 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 11195 return lis.index( tab ); 11196 }); 11197 11198 this._processTabs(); 11199 11200 // was collapsed or no tabs 11201 if ( options.active === false || !this.anchors.length ) { 11202 options.active = false; 11203 this.active = $(); 11204 // was active, but active tab is gone 11205 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 11206 // all remaining tabs are disabled 11207 if ( this.tabs.length === options.disabled.length ) { 11208 options.active = false; 11209 this.active = $(); 11210 // activate previous tab 11211 } else { 11212 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 11213 } 11214 // was active, active tab still exists 11215 } else { 11216 // make sure active index is correct 11217 options.active = this.tabs.index( this.active ); 11218 } 11219 11220 this._refresh(); 11221 }, 11222 11223 _refresh: function() { 11224 this._setupDisabled( this.options.disabled ); 11225 this._setupEvents( this.options.event ); 11226 this._setupHeightStyle( this.options.heightStyle ); 11227 11228 this.tabs.not( this.active ).attr({ 11229 "aria-selected": "false", 11230 tabIndex: -1 11231 }); 11232 this.panels.not( this._getPanelForTab( this.active ) ) 11233 .hide() 11234 .attr({ 11235 "aria-expanded": "false", 11236 "aria-hidden": "true" 11237 }); 11238 11239 // Make sure one tab is in the tab order 11240 if ( !this.active.length ) { 11241 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 11242 } else { 11243 this.active 11244 .addClass( "ui-tabs-active ui-state-active" ) 11245 .attr({ 11246 "aria-selected": "true", 11247 tabIndex: 0 11248 }); 11249 this._getPanelForTab( this.active ) 11250 .show() 11251 .attr({ 11252 "aria-expanded": "true", 11253 "aria-hidden": "false" 11254 }); 11255 } 11256 }, 11257 11258 _processTabs: function() { 11259 var that = this; 11260 11261 this.tablist = this._getList() 11262 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11263 .attr( "role", "tablist" ); 11264 11265 this.tabs = this.tablist.find( "> li:has(a[href])" ) 11266 .addClass( "ui-state-default ui-corner-top" ) 11267 .attr({ 11268 role: "tab", 11269 tabIndex: -1 11270 }); 11271 11272 this.anchors = this.tabs.map(function() { 11273 return $( "a", this )[ 0 ]; 11274 }) 11275 .addClass( "ui-tabs-anchor" ) 11276 .attr({ 11277 role: "presentation", 11278 tabIndex: -1 11279 }); 11280 11281 this.panels = $(); 11282 11283 this.anchors.each(function( i, anchor ) { 11284 var selector, panel, panelId, 11285 anchorId = $( anchor ).uniqueId().attr( "id" ), 11286 tab = $( anchor ).closest( "li" ), 11287 originalAriaControls = tab.attr( "aria-controls" ); 11288 11289 // inline tab 11290 if ( isLocal( anchor ) ) { 11291 selector = anchor.hash; 11292 panel = that.element.find( that._sanitizeSelector( selector ) ); 11293 // remote tab 11294 } else { 11295 panelId = that._tabId( tab ); 11296 selector = "#" + panelId; 11297 panel = that.element.find( selector ); 11298 if ( !panel.length ) { 11299 panel = that._createPanel( panelId ); 11300 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 11301 } 11302 panel.attr( "aria-live", "polite" ); 11303 } 11304 11305 if ( panel.length) { 11306 that.panels = that.panels.add( panel ); 11307 } 11308 if ( originalAriaControls ) { 11309 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 11310 } 11311 tab.attr({ 11312 "aria-controls": selector.substring( 1 ), 11313 "aria-labelledby": anchorId 11314 }); 11315 panel.attr( "aria-labelledby", anchorId ); 11316 }); 11317 11318 this.panels 11319 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11320 .attr( "role", "tabpanel" ); 11321 }, 11322 11323 // allow overriding how to find the list for rare usage scenarios (#7715) 11324 _getList: function() { 11325 return this.element.find( "ol,ul" ).eq( 0 ); 11326 }, 11327 11328 _createPanel: function( id ) { 11329 return $( "<div>" ) 11330 .attr( "id", id ) 11331 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11332 .data( "ui-tabs-destroy", true ); 11333 }, 11334 11335 _setupDisabled: function( disabled ) { 11336 if ( $.isArray( disabled ) ) { 11337 if ( !disabled.length ) { 11338 disabled = false; 11339 } else if ( disabled.length === this.anchors.length ) { 11340 disabled = true; 11341 } 11342 } 11343 11344 // disable tabs 11345 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 11346 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 11347 $( li ) 11348 .addClass( "ui-state-disabled" ) 11349 .attr( "aria-disabled", "true" ); 11350 } else { 11351 $( li ) 11352 .removeClass( "ui-state-disabled" ) 11353 .removeAttr( "aria-disabled" ); 11354 } 11355 } 11356 11357 this.options.disabled = disabled; 11358 }, 11359 11360 _setupEvents: function( event ) { 11361 var events = { 11362 click: function( event ) { 11363 event.preventDefault(); 11364 } 11365 }; 11366 if ( event ) { 11367 $.each( event.split(" "), function( index, eventName ) { 11368 events[ eventName ] = "_eventHandler"; 11369 }); 11370 } 11371 11372 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 11373 this._on( this.anchors, events ); 11374 this._on( this.tabs, { keydown: "_tabKeydown" } ); 11375 this._on( this.panels, { keydown: "_panelKeydown" } ); 11376 11377 this._focusable( this.tabs ); 11378 this._hoverable( this.tabs ); 11379 }, 11380 11381 _setupHeightStyle: function( heightStyle ) { 11382 var maxHeight, overflow, 11383 parent = this.element.parent(); 11384 11385 if ( heightStyle === "fill" ) { 11386 // IE 6 treats height like minHeight, so we need to turn off overflow 11387 // in order to get a reliable height 11388 // we use the minHeight support test because we assume that only 11389 // browsers that don't support minHeight will treat height as minHeight 11390 if ( !$.support.minHeight ) { 11391 overflow = parent.css( "overflow" ); 11392 parent.css( "overflow", "hidden"); 11393 } 11394 maxHeight = parent.height(); 11395 this.element.siblings( ":visible" ).each(function() { 11396 var elem = $( this ), 11397 position = elem.css( "position" ); 11398 11399 if ( position === "absolute" || position === "fixed" ) { 11400 return; 11401 } 11402 maxHeight -= elem.outerHeight( true ); 11403 }); 11404 if ( overflow ) { 11405 parent.css( "overflow", overflow ); 11406 } 11407 11408 this.element.children().not( this.panels ).each(function() { 11409 maxHeight -= $( this ).outerHeight( true ); 11410 }); 11411 11412 this.panels.each(function() { 11413 $( this ).height( Math.max( 0, maxHeight - 11414 $( this ).innerHeight() + $( this ).height() ) ); 11415 }) 11416 .css( "overflow", "auto" ); 11417 } else if ( heightStyle === "auto" ) { 11418 maxHeight = 0; 11419 this.panels.each(function() { 11420 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 11421 }).height( maxHeight ); 11422 } 11423 }, 11424 11425 _eventHandler: function( event ) { 11426 var options = this.options, 11427 active = this.active, 11428 anchor = $( event.currentTarget ), 11429 tab = anchor.closest( "li" ), 11430 clickedIsActive = tab[ 0 ] === active[ 0 ], 11431 collapsing = clickedIsActive && options.collapsible, 11432 toShow = collapsing ? $() : this._getPanelForTab( tab ), 11433 toHide = !active.length ? $() : this._getPanelForTab( active ), 11434 eventData = { 11435 oldTab: active, 11436 oldPanel: toHide, 11437 newTab: collapsing ? $() : tab, 11438 newPanel: toShow 11439 }; 11440 11441 event.preventDefault(); 11442 11443 if ( tab.hasClass( "ui-state-disabled" ) || 11444 // tab is already loading 11445 tab.hasClass( "ui-tabs-loading" ) || 11446 // can't switch durning an animation 11447 this.running || 11448 // click on active header, but not collapsible 11449 ( clickedIsActive && !options.collapsible ) || 11450 // allow canceling activation 11451 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 11452 return; 11453 } 11454 11455 options.active = collapsing ? false : this.tabs.index( tab ); 11456 11457 this.active = clickedIsActive ? $() : tab; 11458 if ( this.xhr ) { 11459 this.xhr.abort(); 11460 } 11461 11462 if ( !toHide.length && !toShow.length ) { 11463 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 11464 } 11465 11466 if ( toShow.length ) { 11467 this.load( this.tabs.index( tab ), event ); 11468 } 11469 this._toggle( event, eventData ); 11470 }, 11471 11472 // handles show/hide for selecting tabs 11473 _toggle: function( event, eventData ) { 11474 var that = this, 11475 toShow = eventData.newPanel, 11476 toHide = eventData.oldPanel; 11477 11478 this.running = true; 11479 11480 function complete() { 11481 that.running = false; 11482 that._trigger( "activate", event, eventData ); 11483 } 11484 11485 function show() { 11486 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 11487 11488 if ( toShow.length && that.options.show ) { 11489 that._show( toShow, that.options.show, complete ); 11490 } else { 11491 toShow.show(); 11492 complete(); 11493 } 11494 } 11495 11496 // start out by hiding, then showing, then completing 11497 if ( toHide.length && this.options.hide ) { 11498 this._hide( toHide, this.options.hide, function() { 11499 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 11500 show(); 11501 }); 11502 } else { 11503 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 11504 toHide.hide(); 11505 show(); 11506 } 11507 11508 toHide.attr({ 11509 "aria-expanded": "false", 11510 "aria-hidden": "true" 11511 }); 11512 eventData.oldTab.attr( "aria-selected", "false" ); 11513 // If we're switching tabs, remove the old tab from the tab order. 11514 // If we're opening from collapsed state, remove the previous tab from the tab order. 11515 // If we're collapsing, then keep the collapsing tab in the tab order. 11516 if ( toShow.length && toHide.length ) { 11517 eventData.oldTab.attr( "tabIndex", -1 ); 11518 } else if ( toShow.length ) { 11519 this.tabs.filter(function() { 11520 return $( this ).attr( "tabIndex" ) === 0; 11521 }) 11522 .attr( "tabIndex", -1 ); 11523 } 11524 11525 toShow.attr({ 11526 "aria-expanded": "true", 11527 "aria-hidden": "false" 11528 }); 11529 eventData.newTab.attr({ 11530 "aria-selected": "true", 11531 tabIndex: 0 11532 }); 11533 }, 11534 11535 _activate: function( index ) { 11536 var anchor, 11537 active = this._findActive( index ); 11538 11539 // trying to activate the already active panel 11540 if ( active[ 0 ] === this.active[ 0 ] ) { 11541 return; 11542 } 11543 11544 // trying to collapse, simulate a click on the current active header 11545 if ( !active.length ) { 11546 active = this.active; 11547 } 11548 11549 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 11550 this._eventHandler({ 11551 target: anchor, 11552 currentTarget: anchor, 11553 preventDefault: $.noop 11554 }); 11555 }, 11556 11557 _findActive: function( index ) { 11558 return index === false ? $() : this.tabs.eq( index ); 11559 }, 11560 11561 _getIndex: function( index ) { 11562 // meta-function to give users option to provide a href string instead of a numerical index. 11563 if ( typeof index === "string" ) { 11564 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 11565 } 11566 11567 return index; 11568 }, 11569 11570 _destroy: function() { 11571 if ( this.xhr ) { 11572 this.xhr.abort(); 11573 } 11574 11575 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 11576 11577 this.tablist 11578 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11579 .removeAttr( "role" ); 11580 11581 this.anchors 11582 .removeClass( "ui-tabs-anchor" ) 11583 .removeAttr( "role" ) 11584 .removeAttr( "tabIndex" ) 11585 .removeData( "href.tabs" ) 11586 .removeData( "load.tabs" ) 11587 .removeUniqueId(); 11588 11589 this.tabs.add( this.panels ).each(function() { 11590 if ( $.data( this, "ui-tabs-destroy" ) ) { 11591 $( this ).remove(); 11592 } else { 11593 $( this ) 11594 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 11595 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 11596 .removeAttr( "tabIndex" ) 11597 .removeAttr( "aria-live" ) 11598 .removeAttr( "aria-busy" ) 11599 .removeAttr( "aria-selected" ) 11600 .removeAttr( "aria-labelledby" ) 11601 .removeAttr( "aria-hidden" ) 11602 .removeAttr( "aria-expanded" ) 11603 .removeAttr( "role" ); 11604 } 11605 }); 11606 11607 this.tabs.each(function() { 11608 var li = $( this ), 11609 prev = li.data( "ui-tabs-aria-controls" ); 11610 if ( prev ) { 11611 li.attr( "aria-controls", prev ); 11612 } else { 11613 li.removeAttr( "aria-controls" ); 11614 } 11615 }); 11616 11617 this.panels.show(); 11618 11619 if ( this.options.heightStyle !== "content" ) { 11620 this.panels.css( "height", "" ); 11621 } 11622 }, 11623 11624 enable: function( index ) { 11625 var disabled = this.options.disabled; 11626 if ( disabled === false ) { 11627 return; 11628 } 11629 11630 if ( index === undefined ) { 11631 disabled = false; 11632 } else { 11633 index = this._getIndex( index ); 11634 if ( $.isArray( disabled ) ) { 11635 disabled = $.map( disabled, function( num ) { 11636 return num !== index ? num : null; 11637 }); 11638 } else { 11639 disabled = $.map( this.tabs, function( li, num ) { 11640 return num !== index ? num : null; 11641 }); 11642 } 11643 } 11644 this._setupDisabled( disabled ); 11645 }, 11646 11647 disable: function( index ) { 11648 var disabled = this.options.disabled; 11649 if ( disabled === true ) { 11650 return; 11651 } 11652 11653 if ( index === undefined ) { 11654 disabled = true; 11655 } else { 11656 index = this._getIndex( index ); 11657 if ( $.inArray( index, disabled ) !== -1 ) { 11658 return; 11659 } 11660 if ( $.isArray( disabled ) ) { 11661 disabled = $.merge( [ index ], disabled ).sort(); 11662 } else { 11663 disabled = [ index ]; 11664 } 11665 } 11666 this._setupDisabled( disabled ); 11667 }, 11668 11669 load: function( index, event ) { 11670 index = this._getIndex( index ); 11671 var that = this, 11672 tab = this.tabs.eq( index ), 11673 anchor = tab.find( ".ui-tabs-anchor" ), 11674 panel = this._getPanelForTab( tab ), 11675 eventData = { 11676 tab: tab, 11677 panel: panel 11678 }; 11679 11680 // not remote 11681 if ( isLocal( anchor[ 0 ] ) ) { 11682 return; 11683 } 11684 11685 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 11686 11687 // support: jQuery <1.8 11688 // jQuery <1.8 returns false if the request is canceled in beforeSend, 11689 // but as of 1.8, $.ajax() always returns a jqXHR object. 11690 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 11691 tab.addClass( "ui-tabs-loading" ); 11692 panel.attr( "aria-busy", "true" ); 11693 11694 this.xhr 11695 .success(function( response ) { 11696 // support: jQuery <1.8 11697 // http://bugs.jquery.com/ticket/11778 11698 setTimeout(function() { 11699 panel.html( response ); 11700 that._trigger( "load", event, eventData ); 11701 }, 1 ); 11702 }) 11703 .complete(function( jqXHR, status ) { 11704 // support: jQuery <1.8 11705 // http://bugs.jquery.com/ticket/11778 11706 setTimeout(function() { 11707 if ( status === "abort" ) { 11708 that.panels.stop( false, true ); 11709 } 11710 11711 tab.removeClass( "ui-tabs-loading" ); 11712 panel.removeAttr( "aria-busy" ); 11713 11714 if ( jqXHR === that.xhr ) { 11715 delete that.xhr; 11716 } 11717 }, 1 ); 11718 }); 11719 } 11720 }, 11721 11722 // TODO: Remove this function in 1.10 when ajaxOptions is removed 11723 _ajaxSettings: function( anchor, event, eventData ) { 11724 var that = this; 11725 return { 11726 url: anchor.attr( "href" ), 11727 beforeSend: function( jqXHR, settings ) { 11728 return that._trigger( "beforeLoad", event, 11729 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 11730 } 11731 }; 11732 }, 11733 11734 _getPanelForTab: function( tab ) { 11735 var id = $( tab ).attr( "aria-controls" ); 11736 return this.element.find( this._sanitizeSelector( "#" + id ) ); 11737 } 11738}); 11739 11740// DEPRECATED 11741if ( $.uiBackCompat !== false ) { 11742 11743 // helper method for a lot of the back compat extensions 11744 $.ui.tabs.prototype._ui = function( tab, panel ) { 11745 return { 11746 tab: tab, 11747 panel: panel, 11748 index: this.anchors.index( tab ) 11749 }; 11750 }; 11751 11752 // url method 11753 $.widget( "ui.tabs", $.ui.tabs, { 11754 url: function( index, url ) { 11755 this.anchors.eq( index ).attr( "href", url ); 11756 } 11757 }); 11758 11759 // TODO: Remove _ajaxSettings() method when removing this extension 11760 // ajaxOptions and cache options 11761 $.widget( "ui.tabs", $.ui.tabs, { 11762 options: { 11763 ajaxOptions: null, 11764 cache: false 11765 }, 11766 11767 _create: function() { 11768 this._super(); 11769 11770 var that = this; 11771 11772 this._on({ tabsbeforeload: function( event, ui ) { 11773 // tab is already cached 11774 if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { 11775 event.preventDefault(); 11776 return; 11777 } 11778 11779 ui.jqXHR.success(function() { 11780 if ( that.options.cache ) { 11781 $.data( ui.tab[ 0 ], "cache.tabs", true ); 11782 } 11783 }); 11784 }}); 11785 }, 11786 11787 _ajaxSettings: function( anchor, event, ui ) { 11788 var ajaxOptions = this.options.ajaxOptions; 11789 return $.extend( {}, ajaxOptions, { 11790 error: function( xhr, status ) { 11791 try { 11792 // Passing index avoid a race condition when this method is 11793 // called after the user has selected another tab.
11794 // Pass the anchor that initiated this request allows 11795 // loadError to manipulate the tab content panel via $(a.hash) 11796 ajaxOptions.error( 11797 xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); 11798 } 11799 catch ( error ) {} 11800 } 11801 }, this._superApply( arguments ) ); 11802 }, 11803 11804 _setOption: function( key, value ) { 11805 // reset cache if switching from cached to not cached 11806 if ( key === "cache" && value === false ) { 11807 this.anchors.removeData( "cache.tabs" ); 11808 } 11809 this._super( key, value ); 11810 }, 11811 11812 _destroy: function() { 11813 this.anchors.removeData( "cache.tabs" ); 11814 this._super(); 11815 }, 11816 11817 url: function( index ){ 11818 this.anchors.eq( index ).removeData( "cache.tabs" ); 11819 this._superApply( arguments ); 11820 } 11821 }); 11822 11823 // abort method 11824 $.widget( "ui.tabs", $.ui.tabs, { 11825 abort: function() { 11826 if ( this.xhr ) { 11827 this.xhr.abort(); 11828 } 11829 } 11830 }); 11831 11832 // spinner 11833 $.widget( "ui.tabs", $.ui.tabs, { 11834 options: { 11835 spinner: "<em>Loading…</em>" 11836 }, 11837 _create: function() { 11838 this._super(); 11839 this._on({ 11840 tabsbeforeload: function( event, ui ) { 11841 // Don't react to nested tabs or tabs that don't use a spinner 11842 if ( event.target !== this.element[ 0 ] || 11843 !this.options.spinner ) { 11844 return; 11845 } 11846 11847 var span = ui.tab.find( "span" ), 11848 html = span.html(); 11849 span.html( this.options.spinner ); 11850 ui.jqXHR.complete(function() { 11851 span.html( html ); 11852 }); 11853 } 11854 }); 11855 } 11856 }); 11857 11858 // enable/disable events 11859 $.widget( "ui.tabs", $.ui.tabs, { 11860 options: { 11861 enable: null, 11862 disable: null 11863 }, 11864 11865 enable: function( index ) { 11866 var options = this.options, 11867 trigger; 11868 11869 if ( index && options.disabled === true || 11870 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { 11871 trigger = true; 11872 } 11873 11874 this._superApply( arguments ); 11875 11876 if ( trigger ) { 11877 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11878 } 11879 }, 11880 11881 disable: function( index ) { 11882 var options = this.options, 11883 trigger; 11884 11885 if ( index && options.disabled === false || 11886 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { 11887 trigger = true; 11888 } 11889 11890 this._superApply( arguments ); 11891 11892 if ( trigger ) { 11893 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11894 } 11895 } 11896 }); 11897 11898 // add/remove methods and events 11899 $.widget( "ui.tabs", $.ui.tabs, { 11900 options: { 11901 add: null, 11902 remove: null, 11903 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" 11904 }, 11905 11906 add: function( url, label, index ) { 11907 if ( index === undefined ) { 11908 index = this.anchors.length; 11909 } 11910 11911 var doInsertAfter, panel, 11912 options = this.options, 11913 li = $( options.tabTemplate 11914 .replace( /#\{href\}/g, url ) 11915 .replace( /#\{label\}/g, label ) ), 11916 id = !url.indexOf( "#" ) ? 11917 url.replace( "#", "" ) : 11918 this._tabId( li ); 11919 11920 li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); 11921 li.attr( "aria-controls", id ); 11922 11923 doInsertAfter = index >= this.tabs.length; 11924 11925 // try to find an existing element before creating a new one 11926 panel = this.element.find( "#" + id ); 11927 if ( !panel.length ) { 11928 panel = this._createPanel( id ); 11929 if ( doInsertAfter ) { 11930 if ( index > 0 ) { 11931 panel.insertAfter( this.panels.eq( -1 ) ); 11932 } else { 11933 panel.appendTo( this.element ); 11934 } 11935 } else { 11936 panel.insertBefore( this.panels[ index ] ); 11937 } 11938 } 11939 panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); 11940 11941 if ( doInsertAfter ) { 11942 li.appendTo( this.tablist ); 11943 } else { 11944 li.insertBefore( this.tabs[ index ] ); 11945 } 11946 11947 options.disabled = $.map( options.disabled, function( n ) { 11948 return n >= index ? ++n : n; 11949 }); 11950 11951 this.refresh(); 11952 if ( this.tabs.length === 1 && options.active === false ) { 11953 this.option( "active", 0 ); 11954 } 11955 11956 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11957 return this; 11958 }, 11959 11960 remove: function( index ) { 11961 index = this._getIndex( index ); 11962 var options = this.options, 11963 tab = this.tabs.eq( index ).remove(), 11964 panel = this._getPanelForTab( tab ).remove(); 11965 11966 // If selected tab was removed focus tab to the right or 11967 // in case the last tab was removed the tab to the left. 11968 // We check for more than 2 tabs, because if there are only 2, 11969 // then when we remove this tab, there will only be one tab left 11970 // so we don't need to detect which tab to activate. 11971 if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { 11972 this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); 11973 } 11974 11975 options.disabled = $.map( 11976 $.grep( options.disabled, function( n ) { 11977 return n !== index; 11978 }), 11979 function( n ) { 11980 return n >= index ? --n : n; 11981 }); 11982 11983 this.refresh();
11984 11985 this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); 11986 return this; 11987 } 11988 }); 11989 11990 // length method 11991 $.widget( "ui.tabs", $.ui.tabs, { 11992 length: function() { 11993 return this.anchors.length; 11994 } 11995 }); 11996 11997 // panel ids (idPrefix option + title attribute) 11998 $.widget( "ui.tabs", $.ui.tabs, { 11999 options: { 12000 idPrefix: "ui-tabs-" 12001 }, 12002 12003 _tabId: function( tab ) { 12004 var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; 12005 a = a[0]; 12006 return $( a ).closest( "li" ).attr( "aria-controls" ) || 12007 a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || 12008 this.options.idPrefix + getNextTabId(); 12009 } 12010 }); 12011 12012 // _createPanel method 12013 $.widget( "ui.tabs", $.ui.tabs, { 12014 options: { 12015 panelTemplate: "<div></div>" 12016 }, 12017 12018 _createPanel: function( id ) { 12019 return $( this.options.panelTemplate ) 12020 .attr( "id", id ) 12021 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 12022 .data( "ui-tabs-destroy", true ); 12023 } 12024 }); 12025 12026 // selected option 12027 $.widget( "ui.tabs", $.ui.tabs, { 12028 _create: function() { 12029 var options = this.options; 12030 if ( options.active === null && options.selected !== undefined ) { 12031 options.active = options.selected === -1 ? false : options.selected; 12032 } 12033 this._super(); 12034 options.selected = options.active; 12035 if ( options.selected === false ) { 12036 options.selected = -1; 12037 } 12038 }, 12039 12040 _setOption: function( key, value ) { 12041 if ( key !== "selected" ) { 12042 return this._super( key, value ); 12043 } 12044 12045 var options = this.options; 12046 this._super( "active", value === -1 ? false : value ); 12047 options.selected = options.active; 12048 if ( options.selected === false ) { 12049 options.selected = -1; 12050 } 12051 }, 12052 12053 _eventHandler: function() { 12054 this._superApply( arguments ); 12055 this.options.selected = this.options.active; 12056 if ( this.options.selected === false ) { 12057 this.options.selected = -1; 12058 } 12059 } 12060 }); 12061 12062 // show and select event 12063 $.widget( "ui.tabs", $.ui.tabs, { 12064 options: { 12065 show: null, 12066 select: null 12067 }, 12068 _create: function() { 12069 this._super(); 12070 if ( this.options.active !== false ) { 12071 this._trigger( "show", null, this._ui( 12072 this.active.find( ".ui-tabs-anchor" )[ 0 ], 12073 this._getPanelForTab( this.active )[ 0 ] ) ); 12074 } 12075 }, 12076 _trigger: function( type, event, data ) { 12077 var tab, panel, 12078 ret = this._superApply( arguments ); 12079 12080 if ( !ret ) { 12081 return false; 12082 } 12083 12084 if ( type === "beforeActivate" ) { 12085 tab = data.newTab.length ? data.newTab : data.oldTab; 12086 panel = data.newPanel.length ? data.newPanel : data.oldPanel; 12087 ret = this._super( "select", event, { 12088 tab: tab.find( ".ui-tabs-anchor" )[ 0], 12089 panel: panel[ 0 ], 12090 index: tab.closest( "li" ).index() 12091 }); 12092 } else if ( type === "activate" && data.newTab.length ) { 12093 ret = this._super( "show", event, { 12094 tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], 12095 panel: data.newPanel[ 0 ], 12096 index: data.newTab.closest( "li" ).index() 12097 }); 12098 } 12099 return ret; 12100 } 12101 }); 12102 12103 // select method 12104 $.widget( "ui.tabs", $.ui.tabs, { 12105 select: function( index ) { 12106 index = this._getIndex( index ); 12107 if ( index === -1 ) { 12108 if ( this.options.collapsible && this.options.selected !== -1 ) { 12109 index = this.options.selected; 12110 } else { 12111 return; 12112 } 12113 } 12114 this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); 12115 } 12116 }); 12117 12118 // cookie option 12119 (function() { 12120 12121 var listId = 0; 12122 12123 $.widget( "ui.tabs", $.ui.tabs, { 12124 options: { 12125 cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 12126 }, 12127 _create: function() { 12128 var options = this.options, 12129 active; 12130 if ( options.active == null && options.cookie ) { 12131 active = parseInt( this._cookie(), 10 ); 12132 if ( active === -1 ) { 12133 active = false; 12134 } 12135 options.active = active; 12136 } 12137 this._super(); 12138 }, 12139 _cookie: function( active ) { 12140 var cookie = [ this.cookie || 12141 ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; 12142 if ( arguments.length ) { 12143 cookie.push( active === false ? -1 : active ); 12144 cookie.push( this.options.cookie ); 12145 } 12146 return $.cookie.apply( null, cookie ); 12147 }, 12148 _refresh: function() { 12149 this._super(); 12150 if ( this.options.cookie ) { 12151 this._cookie( this.options.active, this.options.cookie ); 12152 } 12153 }, 12154 _eventHandler: function() { 12155 this._superApply( arguments ); 12156 if ( this.options.cookie ) { 12157 this._cookie( this.options.active, this.options.cookie ); 12158 } 12159 }, 12160 _destroy: function() { 12161 this._super(); 12162 if ( this.options.cookie ) { 12163 this._cookie( null, this.options.cookie ); 12164 } 12165 } 12166 }); 12167 12168 })(); 12169 12170 // load event 12171 $.widget( "ui.tabs", $.ui.tabs, { 12172 _trigger: function( type, event, data ) { 12173 var _data = $.extend( {}, data ); 12174 if ( type === "load" ) { 12175 _data.panel = _data.panel[ 0 ]; 12176 _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; 12177 } 12178 return this._super( type, event, _data ); 12179 } 12180 }); 12181 12182 // fx option 12183 // The new animation options (show, hide) conflict with the old show callback. 12184 // The old fx option wins over show/hide anyway (always favor back-compat). 12185 // If a user wants to use the new animation API, they must give up the old API. 12186 $.widget( "ui.tabs", $.ui.tabs, { 12187 options: { 12188 fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } 12189 }, 12190 12191 _getFx: function() { 12192 var hide, show, 12193 fx = this.options.fx; 12194 12195 if ( fx ) { 12196 if ( $.isArray( fx ) ) { 12197 hide = fx[ 0 ]; 12198 show = fx[ 1 ]; 12199 } else { 12200 hide = show = fx; 12201 } 12202 } 12203 12204 return fx ? { show: show, hide: hide } : null; 12205 }, 12206 12207 _toggle: function( event, eventData ) { 12208 var that = this, 12209 toShow = eventData.newPanel, 12210 toHide = eventData.oldPanel, 12211 fx = this._getFx();
vendor: 68,909 bytes, lines 12212-14868
12212 12213 if ( !fx ) { 12214 return this._super( event, eventData ); 12215 } 12216 12217 that.running = true; 12218 12219 function complete() { 12220 that.running = false; 12221 that._trigger( "activate", event, eventData ); 12222 } 12223 12224 function show() { 12225 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 12226 12227 if ( toShow.length && fx.show ) { 12228 toShow 12229 .animate( fx.show, fx.show.duration, function() { 12230 complete(); 12231 }); 12232 } else { 12233 toShow.show(); 12234 complete(); 12235 } 12236 } 12237 12238 // start out by hiding, then showing, then completing 12239 if ( toHide.length && fx.hide ) { 12240 toHide.animate( fx.hide, fx.hide.duration, function() { 12241 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12242 show(); 12243 }); 12244 } else { 12245 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12246 toHide.hide(); 12247 show(); 12248 } 12249 } 12250 }); 12251} 12252 12253})( jQuery ); 12254(function( $ ) { 12255 12256var increments = 0; 12257 12258function addDescribedBy( elem, id ) { 12259 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 12260 describedby.push( id ); 12261 elem 12262 .data( "ui-tooltip-id", id ) 12263 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 12264} 12265 12266function removeDescribedBy( elem ) { 12267 var id = elem.data( "ui-tooltip-id" ), 12268 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 12269 index = $.inArray( id, describedby ); 12270 if ( index !== -1 ) { 12271 describedby.splice( index, 1 ); 12272 } 12273 12274 elem.removeData( "ui-tooltip-id" ); 12275 describedby = $.trim( describedby.join( " " ) ); 12276 if ( describedby ) { 12277 elem.attr( "aria-describedby", describedby ); 12278 } else { 12279 elem.removeAttr( "aria-describedby" ); 12280 } 12281} 12282 12283$.widget( "ui.tooltip", { 12284 version: "1.9.2", 12285 options: { 12286 content: function() { 12287 return $( this ).attr( "title" ); 12288 }, 12289 hide: true, 12290 // Disabled elements have inconsistent behavior across browsers (#8661) 12291 items: "[title]:not([disabled])", 12292 position: { 12293 my: "left top+15", 12294 at: "left bottom", 12295 collision: "flipfit flip" 12296 }, 12297 show: true, 12298 tooltipClass: null, 12299 track: false, 12300 12301 // callbacks 12302 close: null, 12303 open: null 12304 }, 12305 12306 _create: function() { 12307 this._on({ 12308 mouseover: "open", 12309 focusin: "open" 12310 }); 12311 12312 // IDs of generated tooltips, needed for destroy 12313 this.tooltips = {}; 12314 // IDs of parent tooltips where we removed the title attribute 12315 this.parents = {}; 12316 12317 if ( this.options.disabled ) { 12318 this._disable(); 12319 } 12320 }, 12321 12322 _setOption: function( key, value ) { 12323 var that = this; 12324 12325 if ( key === "disabled" ) { 12326 this[ value ? "_disable" : "_enable" ](); 12327 this.options[ key ] = value; 12328 // disable element style changes 12329 return; 12330 } 12331 12332 this._super( key, value ); 12333 12334 if ( key === "content" ) { 12335 $.each( this.tooltips, function( id, element ) { 12336 that._updateContent( element ); 12337 }); 12338 } 12339 }, 12340 12341 _disable: function() { 12342 var that = this; 12343 12344 // close open tooltips 12345 $.each( this.tooltips, function( id, element ) { 12346 var event = $.Event( "blur" ); 12347 event.target = event.currentTarget = element[0]; 12348 that.close( event, true ); 12349 }); 12350 12351 // remove title attributes to prevent native tooltips 12352 this.element.find( this.options.items ).andSelf().each(function() { 12353 var element = $( this ); 12354 if ( element.is( "[title]" ) ) { 12355 element 12356 .data( "ui-tooltip-title", element.attr( "title" ) ) 12357 .attr( "title", "" ); 12358 } 12359 }); 12360 }, 12361 12362 _enable: function() { 12363 // restore title attributes 12364 this.element.find( this.options.items ).andSelf().each(function() { 12365 var element = $( this ); 12366 if ( element.data( "ui-tooltip-title" ) ) { 12367 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12368 } 12369 }); 12370 }, 12371 12372 open: function( event ) { 12373 var that = this, 12374 target = $( event ? event.target : this.element ) 12375 // we need closest here due to mouseover bubbling, 12376 // but always pointing at the same event target 12377 .closest( this.options.items ); 12378 12379 // No element to show a tooltip for or the tooltip is already open 12380 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 12381 return; 12382 } 12383 12384 if ( target.attr( "title" ) ) { 12385 target.data( "ui-tooltip-title", target.attr( "title" ) ); 12386 } 12387 12388 target.data( "ui-tooltip-open", true ); 12389 12390 // kill parent tooltips, custom or native, for hover 12391 if ( event && event.type === "mouseover" ) { 12392 target.parents().each(function() { 12393 var parent = $( this ), 12394 blurEvent; 12395 if ( parent.data( "ui-tooltip-open" ) ) { 12396 blurEvent = $.Event( "blur" ); 12397 blurEvent.target = blurEvent.currentTarget = this; 12398 that.close( blurEvent, true ); 12399 } 12400 if ( parent.attr( "title" ) ) { 12401 parent.uniqueId(); 12402 that.parents[ this.id ] = { 12403 element: this, 12404 title: parent.attr( "title" ) 12405 }; 12406 parent.attr( "title", "" ); 12407 } 12408 }); 12409 } 12410 12411 this._updateContent( target, event ); 12412 }, 12413 12414 _updateContent: function( target, event ) { 12415 var content, 12416 contentOption = this.options.content, 12417 that = this, 12418 eventType = event ? event.type : null; 12419 12420 if ( typeof contentOption === "string" ) { 12421 return this._open( event, target, contentOption ); 12422 } 12423 12424 content = contentOption.call( target[0], function( response ) { 12425 // ignore async response if tooltip was closed already 12426 if ( !target.data( "ui-tooltip-open" ) ) { 12427 return; 12428 } 12429 // IE may instantly serve a cached response for ajax requests 12430 // delay this call to _open so the other call to _open runs first 12431 that._delay(function() { 12432 // jQuery creates a special event for focusin when it doesn't 12433 // exist natively. To improve performance, the native event 12434 // object is reused and the type is changed. Therefore, we can't 12435 // rely on the type being correct after the event finished 12436 // bubbling, so we set it back to the previous value. (#8740) 12437 if ( event ) { 12438 event.type = eventType; 12439 } 12440 this._open( event, target, response ); 12441 }); 12442 }); 12443 if ( content ) { 12444 this._open( event, target, content ); 12445 } 12446 }, 12447 12448 _open: function( event, target, content ) { 12449 var tooltip, events, delayedShow, 12450 positionOption = $.extend( {}, this.options.position ); 12451 12452 if ( !content ) { 12453 return; 12454 } 12455 12456 // Content can be updated multiple times. If the tooltip already 12457 // exists, then just update the content and bail. 12458 tooltip = this._find( target ); 12459 if ( tooltip.length ) { 12460 tooltip.find( ".ui-tooltip-content" ).html( content ); 12461 return; 12462 } 12463 12464 // if we have a title, clear it to prevent the native tooltip 12465 // we have to check first to avoid defining a title if none exists 12466 // (we don't want to cause an element to start matching [title]) 12467 // 12468 // We use removeAttr only for key events, to allow IE to export the correct 12469 // accessible attributes. For mouse events, set to empty string to avoid 12470 // native tooltip showing up (happens only when removing inside mouseover). 12471 if ( target.is( "[title]" ) ) { 12472 if ( event && event.type === "mouseover" ) { 12473 target.attr( "title", "" ); 12474 } else { 12475 target.removeAttr( "title" ); 12476 } 12477 } 12478 12479 tooltip = this._tooltip( target ); 12480 addDescribedBy( target, tooltip.attr( "id" ) ); 12481 tooltip.find( ".ui-tooltip-content" ).html( content ); 12482 12483 function position( event ) { 12484 positionOption.of = event; 12485 if ( tooltip.is( ":hidden" ) ) { 12486 return; 12487 } 12488 tooltip.position( positionOption ); 12489 } 12490 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 12491 this._on( this.document, { 12492 mousemove: position 12493 }); 12494 // trigger once to override element-relative positioning 12495 position( event ); 12496 } else { 12497 tooltip.position( $.extend({ 12498 of: target 12499 }, this.options.position ) ); 12500 } 12501 12502 tooltip.hide(); 12503 12504 this._show( tooltip, this.options.show ); 12505 // Handle tracking tooltips that are shown with a delay (#8644). As soon 12506 // as the tooltip is visible, position the tooltip using the most recent 12507 // event. 12508 if ( this.options.show && this.options.show.delay ) { 12509 delayedShow = setInterval(function() { 12510 if ( tooltip.is( ":visible" ) ) { 12511 position( positionOption.of ); 12512 clearInterval( delayedShow ); 12513 } 12514 }, $.fx.interval ); 12515 } 12516 12517 this._trigger( "open", event, { tooltip: tooltip } ); 12518 12519 events = { 12520 keyup: function( event ) { 12521 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 12522 var fakeEvent = $.Event(event); 12523 fakeEvent.currentTarget = target[0]; 12524 this.close( fakeEvent, true ); 12525 } 12526 }, 12527 remove: function() { 12528 this._removeTooltip( tooltip ); 12529 } 12530 }; 12531 if ( !event || event.type === "mouseover" ) { 12532 events.mouseleave = "close"; 12533 } 12534 if ( !event || event.type === "focusin" ) { 12535 events.focusout = "close"; 12536 } 12537 this._on( true, target, events ); 12538 }, 12539 12540 close: function( event ) { 12541 var that = this, 12542 target = $( event ? event.currentTarget : this.element ), 12543 tooltip = this._find( target ); 12544 12545 // disabling closes the tooltip, so we need to track when we're closing 12546 // to avoid an infinite loop in case the tooltip becomes disabled on close 12547 if ( this.closing ) { 12548 return; 12549 } 12550 12551 // only set title if we had one before (see comment in _open()) 12552 if ( target.data( "ui-tooltip-title" ) ) { 12553 target.attr( "title", target.data( "ui-tooltip-title" ) ); 12554 } 12555 12556 removeDescribedBy( target ); 12557 12558 tooltip.stop( true ); 12559 this._hide( tooltip, this.options.hide, function() { 12560 that._removeTooltip( $( this ) ); 12561 }); 12562 12563 target.removeData( "ui-tooltip-open" ); 12564 this._off( target, "mouseleave focusout keyup" ); 12565 // Remove 'remove' binding only on delegated targets 12566 if ( target[0] !== this.element[0] ) { 12567 this._off( target, "remove" ); 12568 } 12569 this._off( this.document, "mousemove" ); 12570 12571 if ( event && event.type === "mouseleave" ) { 12572 $.each( this.parents, function( id, parent ) { 12573 $( parent.element ).attr( "title", parent.title ); 12574 delete that.parents[ id ]; 12575 }); 12576 } 12577 12578 this.closing = true; 12579 this._trigger( "close", event, { tooltip: tooltip } ); 12580 this.closing = false; 12581 }, 12582 12583 _tooltip: function( element ) { 12584 var id = "ui-tooltip-" + increments++, 12585 tooltip = $( "<div>" ) 12586 .attr({ 12587 id: id, 12588 role: "tooltip" 12589 }) 12590 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 12591 ( this.options.tooltipClass || "" ) ); 12592 $( "<div>" ) 12593 .addClass( "ui-tooltip-content" ) 12594 .appendTo( tooltip ); 12595 tooltip.appendTo( this.document[0].body ); 12596 if ( $.fn.bgiframe ) { 12597 tooltip.bgiframe(); 12598 } 12599 this.tooltips[ id ] = element; 12600 return tooltip; 12601 }, 12602 12603 _find: function( target ) { 12604 var id = target.data( "ui-tooltip-id" ); 12605 return id ? $( "#" + id ) : $(); 12606 }, 12607 12608 _removeTooltip: function( tooltip ) { 12609 tooltip.remove(); 12610 delete this.tooltips[ tooltip.attr( "id" ) ]; 12611 }, 12612 12613 _destroy: function() { 12614 var that = this; 12615 12616 // close open tooltips 12617 $.each( this.tooltips, function( id, element ) { 12618 // Delegate to close method to handle common cleanup 12619 var event = $.Event( "blur" ); 12620 event.target = event.currentTarget = element[0]; 12621 that.close( event, true ); 12622 12623 // Remove immediately; destroying an open tooltip doesn't use the 12624 // hide animation 12625 $( "#" + id ).remove(); 12626 12627 // Restore the title 12628 if ( element.data( "ui-tooltip-title" ) ) { 12629 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12630 element.removeData( "ui-tooltip-title" ); 12631 } 12632 }); 12633 } 12634}); 12635 12636}( jQuery ) ); 12637;(jQuery.effects || (function($, undefined) { 12638 12639var backCompat = $.uiBackCompat !== false, 12640 // prefix used for storing data on .data() 12641 dataSpace = "ui-effects-"; 12642 12643$.effects = { 12644 effect: {} 12645}; 12646 12647/*! 12648 * jQuery Color Animations v2.0.0 12649 * http://jquery.com/ 12650 * 12651 * Copyright 2012 jQuery Foundation and other contributors 12652 * Released under the MIT license. 12653 * http://jquery.org/license 12654 * 12655 * Date: Mon Aug 13 13:41:02 2012 -0500 12656 */ 12657(function( jQuery, undefined ) { 12658 12659 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), 12660 12661 // plusequals test for += 100 -= 100 12662 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 12663 // a set of RE's that can match strings and generate color tuples. 12664 stringParsers = [{ 12665 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12666 parse: function( execResult ) { 12667 return [ 12668 execResult[ 1 ], 12669 execResult[ 2 ], 12670 execResult[ 3 ], 12671 execResult[ 4 ] 12672 ]; 12673 } 12674 }, { 12675 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12676 parse: function( execResult ) { 12677 return [ 12678 execResult[ 1 ] * 2.55, 12679 execResult[ 2 ] * 2.55, 12680 execResult[ 3 ] * 2.55, 12681 execResult[ 4 ] 12682 ]; 12683 } 12684 }, { 12685 // this regex ignores A-F because it's compared against an already lowercased string 12686 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 12687 parse: function( execResult ) { 12688 return [ 12689 parseInt( execResult[ 1 ], 16 ), 12690 parseInt( execResult[ 2 ], 16 ), 12691 parseInt( execResult[ 3 ], 16 ) 12692 ]; 12693 } 12694 }, { 12695 // this regex ignores A-F because it's compared against an already lowercased string 12696 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 12697 parse: function( execResult ) { 12698 return [ 12699 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 12700 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 12701 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 12702 ]; 12703 } 12704 }, { 12705 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12706 space: "hsla", 12707 parse: function( execResult ) { 12708 return [ 12709 execResult[ 1 ], 12710 execResult[ 2 ] / 100, 12711 execResult[ 3 ] / 100, 12712 execResult[ 4 ] 12713 ]; 12714 } 12715 }], 12716 12717 // jQuery.Color( ) 12718 color = jQuery.Color = function( color, green, blue, alpha ) { 12719 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 12720 }, 12721 spaces = { 12722 rgba: { 12723 props: { 12724 red: { 12725 idx: 0, 12726 type: "byte" 12727 }, 12728 green: { 12729 idx: 1, 12730 type: "byte" 12731 }, 12732 blue: { 12733 idx: 2, 12734 type: "byte" 12735 } 12736 } 12737 }, 12738 12739 hsla: { 12740 props: { 12741 hue: { 12742 idx: 0, 12743 type: "degrees" 12744 }, 12745 saturation: { 12746 idx: 1, 12747 type: "percent" 12748 }, 12749 lightness: { 12750 idx: 2, 12751 type: "percent" 12752 } 12753 } 12754 } 12755 }, 12756 propTypes = { 12757 "byte": { 12758 floor: true, 12759 max: 255 12760 }, 12761 "percent": { 12762 max: 1 12763 }, 12764 "degrees": { 12765 mod: 360, 12766 floor: true 12767 } 12768 }, 12769 support = color.support = {}, 12770 12771 // element for support tests 12772 supportElem = jQuery( "<p>" )[ 0 ], 12773 12774 // colors = jQuery.Color.names 12775 colors, 12776 12777 // local aliases of functions called often 12778 each = jQuery.each; 12779 12780// determine rgba support immediately 12781supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 12782support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 12783 12784// define cache name and alpha properties 12785// for rgba and hsla spaces 12786each( spaces, function( spaceName, space ) { 12787 space.cache = "_" + spaceName; 12788 space.props.alpha = { 12789 idx: 3, 12790 type: "percent", 12791 def: 1 12792 }; 12793}); 12794 12795function clamp( value, prop, allowEmpty ) { 12796 var type = propTypes[ prop.type ] || {}; 12797 12798 if ( value == null ) { 12799 return (allowEmpty || !prop.def) ? null : prop.def; 12800 } 12801 12802 // ~~ is an short way of doing floor for positive numbers 12803 value = type.floor ? ~~value : parseFloat( value ); 12804 12805 // IE will pass in empty strings as value for alpha, 12806 // which will hit this case 12807 if ( isNaN( value ) ) { 12808 return prop.def; 12809 } 12810 12811 if ( type.mod ) { 12812 // we add mod before modding to make sure that negatives values 12813 // get converted properly: -10 -> 350 12814 return (value + type.mod) % type.mod; 12815 } 12816 12817 // for now all property types without mod have min and max 12818 return 0 > value ? 0 : type.max < value ? type.max : value; 12819} 12820 12821function stringParse( string ) { 12822 var inst = color(), 12823 rgba = inst._rgba = []; 12824 12825 string = string.toLowerCase(); 12826 12827 each( stringParsers, function( i, parser ) { 12828 var parsed, 12829 match = parser.re.exec( string ), 12830 values = match && parser.parse( match ), 12831 spaceName = parser.space || "rgba"; 12832 12833 if ( values ) { 12834 parsed = inst[ spaceName ]( values ); 12835 12836 // if this was an rgba parse the assignment might happen twice 12837 // oh well.... 12838 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12839 rgba = inst._rgba = parsed._rgba; 12840 12841 // exit each( stringParsers ) here because we matched 12842 return false; 12843 } 12844 }); 12845 12846 // Found a stringParser that handled it 12847 if ( rgba.length ) { 12848 12849 // if this came from a parsed string, force "transparent" when alpha is 0 12850 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12851 if ( rgba.join() === "0,0,0,0" ) { 12852 jQuery.extend( rgba, colors.transparent ); 12853 } 12854 return inst; 12855 } 12856 12857 // named colors 12858 return colors[ string ]; 12859} 12860 12861color.fn = jQuery.extend( color.prototype, { 12862 parse: function( red, green, blue, alpha ) { 12863 if ( red === undefined ) { 12864 this._rgba = [ null, null, null, null ]; 12865 return this; 12866 } 12867 if ( red.jquery || red.nodeType ) { 12868 red = jQuery( red ).css( green ); 12869 green = undefined; 12870 } 12871 12872 var inst = this, 12873 type = jQuery.type( red ), 12874 rgba = this._rgba = []; 12875 12876 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12877 if ( green !== undefined ) { 12878 red = [ red, green, blue, alpha ]; 12879 type = "array"; 12880 } 12881 12882 if ( type === "string" ) { 12883 return this.parse( stringParse( red ) || colors._default ); 12884 } 12885 12886 if ( type === "array" ) { 12887 each( spaces.rgba.props, function( key, prop ) { 12888 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 12889 }); 12890 return this; 12891 } 12892 12893 if ( type === "object" ) { 12894 if ( red instanceof color ) { 12895 each( spaces, function( spaceName, space ) { 12896 if ( red[ space.cache ] ) { 12897 inst[ space.cache ] = red[ space.cache ].slice(); 12898 } 12899 }); 12900 } else { 12901 each( spaces, function( spaceName, space ) { 12902 var cache = space.cache; 12903 each( space.props, function( key, prop ) { 12904 12905 // if the cache doesn't exist, and we know how to convert 12906 if ( !inst[ cache ] && space.to ) { 12907 12908 // if the value was null, we don't need to copy it 12909 // if the key was alpha, we don't need to copy it either 12910 if ( key === "alpha" || red[ key ] == null ) { 12911 return; 12912 } 12913 inst[ cache ] = space.to( inst._rgba ); 12914 } 12915 12916 // this is the only case where we allow nulls for ALL properties. 12917 // call clamp with alwaysAllowEmpty 12918 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 12919 }); 12920 12921 // everything defined but alpha? 12922 if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 12923 // use the default of 1 12924 inst[ cache ][ 3 ] = 1; 12925 if ( space.from ) { 12926 inst._rgba = space.from( inst[ cache ] ); 12927 } 12928 } 12929 }); 12930 } 12931 return this; 12932 } 12933 }, 12934 is: function( compare ) { 12935 var is = color( compare ), 12936 same = true, 12937 inst = this; 12938 12939 each( spaces, function( _, space ) { 12940 var localCache, 12941 isCache = is[ space.cache ]; 12942 if (isCache) { 12943 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 12944 each( space.props, function( _, prop ) { 12945 if ( isCache[ prop.idx ] != null ) { 12946 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 12947 return same; 12948 } 12949 }); 12950 } 12951 return same; 12952 }); 12953 return same; 12954 }, 12955 _space: function() { 12956 var used = [], 12957 inst = this; 12958 each( spaces, function( spaceName, space ) { 12959 if ( inst[ space.cache ] ) { 12960 used.push( spaceName ); 12961 } 12962 }); 12963 return used.pop(); 12964 }, 12965 transition: function( other, distance ) { 12966 var end = color( other ), 12967 spaceName = end._space(), 12968 space = spaces[ spaceName ], 12969 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 12970 start = startColor[ space.cache ] || space.to( startColor._rgba ), 12971 result = start.slice(); 12972 12973 end = end[ space.cache ]; 12974 each( space.props, function( key, prop ) { 12975 var index = prop.idx, 12976 startValue = start[ index ], 12977 endValue = end[ index ], 12978 type = propTypes[ prop.type ] || {}; 12979 12980 // if null, don't override start value 12981 if ( endValue === null ) { 12982 return; 12983 } 12984 // if null - use end 12985 if ( startValue === null ) { 12986 result[ index ] = endValue; 12987 } else { 12988 if ( type.mod ) { 12989 if ( endValue - startValue > type.mod / 2 ) { 12990 startValue += type.mod; 12991 } else if ( startValue - endValue > type.mod / 2 ) { 12992 startValue -= type.mod; 12993 } 12994 } 12995 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 12996 } 12997 }); 12998 return this[ spaceName ]( result ); 12999 }, 13000 blend: function( opaque ) { 13001 // if we are already opaque - return ourself 13002 if ( this._rgba[ 3 ] === 1 ) { 13003 return this; 13004 } 13005 13006 var rgb = this._rgba.slice(), 13007 a = rgb.pop(), 13008 blend = color( opaque )._rgba; 13009 13010 return color( jQuery.map( rgb, function( v, i ) { 13011 return ( 1 - a ) * blend[ i ] + a * v; 13012 })); 13013 }, 13014 toRgbaString: function() { 13015 var prefix = "rgba(", 13016 rgba = jQuery.map( this._rgba, function( v, i ) { 13017 return v == null ? ( i > 2 ? 1 : 0 ) : v; 13018 }); 13019 13020 if ( rgba[ 3 ] === 1 ) { 13021 rgba.pop(); 13022 prefix = "rgb("; 13023 } 13024 13025 return prefix + rgba.join() + ")"; 13026 }, 13027 toHslaString: function() { 13028 var prefix = "hsla(", 13029 hsla = jQuery.map( this.hsla(), function( v, i ) { 13030 if ( v == null ) { 13031 v = i > 2 ? 1 : 0; 13032 } 13033 13034 // catch 1 and 2 13035 if ( i && i < 3 ) { 13036 v = Math.round( v * 100 ) + "%"; 13037 } 13038 return v; 13039 }); 13040 13041 if ( hsla[ 3 ] === 1 ) { 13042 hsla.pop(); 13043 prefix = "hsl("; 13044 } 13045 return prefix + hsla.join() + ")"; 13046 }, 13047 toHexString: function( includeAlpha ) { 13048 var rgba = this._rgba.slice(), 13049 alpha = rgba.pop(); 13050 13051 if ( includeAlpha ) { 13052 rgba.push( ~~( alpha * 255 ) ); 13053 } 13054 13055 return "#" + jQuery.map( rgba, function( v ) { 13056 13057 // default to 0 when nulls exist 13058 v = ( v || 0 ).toString( 16 ); 13059 return v.length === 1 ? "0" + v : v; 13060 }).join(""); 13061 }, 13062 toString: function() { 13063 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 13064 } 13065}); 13066color.fn.parse.prototype = color.fn; 13067 13068// hsla conversions adapted from: 13069// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 13070 13071function hue2rgb( p, q, h ) { 13072 h = ( h + 1 ) % 1; 13073 if ( h * 6 < 1 ) { 13074 return p + (q - p) * h * 6; 13075 } 13076 if ( h * 2 < 1) { 13077 return q; 13078 } 13079 if ( h * 3 < 2 ) { 13080 return p + (q - p) * ((2/3) - h) * 6; 13081 } 13082 return p; 13083} 13084 13085spaces.hsla.to = function ( rgba ) { 13086 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 13087 return [ null, null, null, rgba[ 3 ] ]; 13088 } 13089 var r = rgba[ 0 ] / 255, 13090 g = rgba[ 1 ] / 255, 13091 b = rgba[ 2 ] / 255, 13092 a = rgba[ 3 ], 13093 max = Math.max( r, g, b ), 13094 min = Math.min( r, g, b ), 13095 diff = max - min, 13096 add = max + min, 13097 l = add * 0.5, 13098 h, s; 13099 13100 if ( min === max ) { 13101 h = 0; 13102 } else if ( r === max ) { 13103 h = ( 60 * ( g - b ) / diff ) + 360; 13104 } else if ( g === max ) { 13105 h = ( 60 * ( b - r ) / diff ) + 120; 13106 } else { 13107 h = ( 60 * ( r - g ) / diff ) + 240; 13108 } 13109 13110 if ( l === 0 || l === 1 ) { 13111 s = l; 13112 } else if ( l <= 0.5 ) { 13113 s = diff / add; 13114 } else { 13115 s = diff / ( 2 - add ); 13116 } 13117 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 13118}; 13119 13120spaces.hsla.from = function ( hsla ) { 13121 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 13122 return [ null, null, null, hsla[ 3 ] ]; 13123 } 13124 var h = hsla[ 0 ] / 360, 13125 s = hsla[ 1 ], 13126 l = hsla[ 2 ], 13127 a = hsla[ 3 ], 13128 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 13129 p = 2 * l - q; 13130 13131 return [ 13132 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 13133 Math.round( hue2rgb( p, q, h ) * 255 ), 13134 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 13135 a 13136 ]; 13137}; 13138 13139 13140each( spaces, function( spaceName, space ) { 13141 var props = space.props, 13142 cache = space.cache, 13143 to = space.to, 13144 from = space.from; 13145 13146 // makes rgba() and hsla() 13147 color.fn[ spaceName ] = function( value ) { 13148 13149 // generate a cache for this space if it doesn't exist 13150 if ( to && !this[ cache ] ) { 13151 this[ cache ] = to( this._rgba ); 13152 } 13153 if ( value === undefined ) { 13154 return this[ cache ].slice(); 13155 } 13156 13157 var ret, 13158 type = jQuery.type( value ), 13159 arr = ( type === "array" || type === "object" ) ? value : arguments, 13160 local = this[ cache ].slice(); 13161 13162 each( props, function( key, prop ) { 13163 var val = arr[ type === "object" ? key : prop.idx ]; 13164 if ( val == null ) { 13165 val = local[ prop.idx ]; 13166 } 13167 local[ prop.idx ] = clamp( val, prop ); 13168 }); 13169 13170 if ( from ) { 13171 ret = color( from( local ) ); 13172 ret[ cache ] = local; 13173 return ret; 13174 } else { 13175 return color( local ); 13176 } 13177 }; 13178 13179 // makes red() green() blue() alpha() hue() saturation() lightness() 13180 each( props, function( key, prop ) { 13181 // alpha is included in more than one space 13182 if ( color.fn[ key ] ) { 13183 return; 13184 } 13185 color.fn[ key ] = function( value ) { 13186 var vtype = jQuery.type( value ), 13187 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 13188 local = this[ fn ](), 13189 cur = local[ prop.idx ], 13190 match; 13191 13192 if ( vtype === "undefined" ) { 13193 return cur; 13194 } 13195 13196 if ( vtype === "function" ) { 13197 value = value.call( this, cur ); 13198 vtype = jQuery.type( value ); 13199 } 13200 if ( value == null && prop.empty ) { 13201 return this; 13202 } 13203 if ( vtype === "string" ) { 13204 match = rplusequals.exec( value ); 13205 if ( match ) { 13206 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 13207 } 13208 } 13209 local[ prop.idx ] = value; 13210 return this[ fn ]( local ); 13211 }; 13212 }); 13213}); 13214 13215// add .fx.step functions 13216each( stepHooks, function( i, hook ) { 13217 jQuery.cssHooks[ hook ] = { 13218 set: function( elem, value ) { 13219 var parsed, curElem, 13220 backgroundColor = ""; 13221 13222 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 13223 value = color( parsed || value ); 13224 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 13225 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 13226 while ( 13227 (backgroundColor === "" || backgroundColor === "transparent") && 13228 curElem && curElem.style 13229 ) { 13230 try { 13231 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 13232 curElem = curElem.parentNode; 13233 } catch ( e ) { 13234 } 13235 } 13236 13237 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 13238 backgroundColor : 13239 "_default" ); 13240 } 13241 13242 value = value.toRgbaString(); 13243 } 13244 try { 13245 elem.style[ hook ] = value; 13246 } catch( error ) { 13247 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 13248 } 13249 } 13250 }; 13251 jQuery.fx.step[ hook ] = function( fx ) { 13252 if ( !fx.colorInit ) { 13253 fx.start = color( fx.elem, hook ); 13254 fx.end = color( fx.end ); 13255 fx.colorInit = true; 13256 } 13257 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 13258 }; 13259}); 13260 13261jQuery.cssHooks.borderColor = { 13262 expand: function( value ) { 13263 var expanded = {}; 13264 13265 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 13266 expanded[ "border" + part + "Color" ] = value; 13267 }); 13268 return expanded; 13269 } 13270}; 13271 13272// Basic color names only. 13273// Usage of any of the other color names requires adding yourself or including 13274// jquery.color.svg-names.js. 13275colors = jQuery.Color.names = { 13276 // 4.1. Basic color keywords 13277 aqua: "#00ffff", 13278 black: "#000000", 13279 blue: "#0000ff", 13280 fuchsia: "#ff00ff", 13281 gray: "#808080", 13282 green: "#008000", 13283 lime: "#00ff00", 13284 maroon: "#800000", 13285 navy: "#000080", 13286 olive: "#808000", 13287 purple: "#800080", 13288 red: "#ff0000", 13289 silver: "#c0c0c0", 13290 teal: "#008080", 13291 white: "#ffffff", 13292 yellow: "#ffff00", 13293 13294 // 4.2.3. "transparent" color keyword 13295 transparent: [ null, null, null, 0 ], 13296 13297 _default: "#ffffff" 13298}; 13299 13300})( jQuery ); 13301 13302 13303 13304/******************************************************************************/ 13305/****************************** CLASS ANIMATIONS ******************************/ 13306/******************************************************************************/ 13307(function() { 13308 13309var classAnimationActions = [ "add", "remove", "toggle" ], 13310 shorthandStyles = { 13311 border: 1, 13312 borderBottom: 1, 13313 borderColor: 1, 13314 borderLeft: 1, 13315 borderRight: 1, 13316 borderTop: 1, 13317 borderWidth: 1, 13318 margin: 1, 13319 padding: 1 13320 }; 13321 13322$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 13323 $.fx.step[ prop ] = function( fx ) { 13324 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 13325 jQuery.style( fx.elem, prop, fx.end ); 13326 fx.setAttr = true; 13327 } 13328 }; 13329}); 13330 13331function getElementStyles() { 13332 var style = this.ownerDocument.defaultView ? 13333 this.ownerDocument.defaultView.getComputedStyle( this, null ) : 13334 this.currentStyle, 13335 newStyle = {}, 13336 key, 13337 len; 13338 13339 // webkit enumerates style porperties 13340 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 13341 len = style.length; 13342 while ( len-- ) { 13343 key = style[ len ]; 13344 if ( typeof style[ key ] === "string" ) { 13345 newStyle[ $.camelCase( key ) ] = style[ key ]; 13346 } 13347 } 13348 } else { 13349 for ( key in style ) { 13350 if ( typeof style[ key ] === "string" ) { 13351 newStyle[ key ] = style[ key ]; 13352 } 13353 } 13354 } 13355 13356 return newStyle; 13357} 13358 13359 13360function styleDifference( oldStyle, newStyle ) { 13361 var diff = {}, 13362 name, value; 13363 13364 for ( name in newStyle ) { 13365 value = newStyle[ name ]; 13366 if ( oldStyle[ name ] !== value ) { 13367 if ( !shorthandStyles[ name ] ) { 13368 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 13369 diff[ name ] = value; 13370 } 13371 } 13372 } 13373 } 13374 13375 return diff; 13376} 13377 13378$.effects.animateClass = function( value, duration, easing, callback ) { 13379 var o = $.speed( duration, easing, callback ); 13380 13381 return this.queue( function() { 13382 var animated = $( this ), 13383 baseClass = animated.attr( "class" ) || "", 13384 applyClassChange, 13385 allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; 13386 13387 // map the animated objects to store the original styles. 13388 allAnimations = allAnimations.map(function() { 13389 var el = $( this ); 13390 return { 13391 el: el, 13392 start: getElementStyles.call( this ) 13393 }; 13394 }); 13395 13396 // apply class change 13397 applyClassChange = function() { 13398 $.each( classAnimationActions, function(i, action) { 13399 if ( value[ action ] ) { 13400 animated[ action + "Class" ]( value[ action ] ); 13401 } 13402 }); 13403 }; 13404 applyClassChange(); 13405 13406 // map all animated objects again - calculate new styles and diff 13407 allAnimations = allAnimations.map(function() { 13408 this.end = getElementStyles.call( this.el[ 0 ] ); 13409 this.diff = styleDifference( this.start, this.end ); 13410 return this; 13411 }); 13412 13413 // apply original class 13414 animated.attr( "class", baseClass ); 13415 13416 // map all animated objects again - this time collecting a promise 13417 allAnimations = allAnimations.map(function() { 13418 var styleInfo = this, 13419 dfd = $.Deferred(), 13420 opts = jQuery.extend({}, o, { 13421 queue: false, 13422 complete: function() { 13423 dfd.resolve( styleInfo ); 13424 } 13425 }); 13426 13427 this.el.animate( this.diff, opts ); 13428 return dfd.promise(); 13429 }); 13430 13431 // once all animations have completed: 13432 $.when.apply( $, allAnimations.get() ).done(function() { 13433 13434 // set the final class 13435 applyClassChange(); 13436 13437 // for each animated element, 13438 // clear all css properties that were animated 13439 $.each( arguments, function() { 13440 var el = this.el; 13441 $.each( this.diff, function(key) { 13442 el.css( key, '' ); 13443 }); 13444 }); 13445 13446 // this is guarnteed to be there if you use jQuery.speed() 13447 // it also handles dequeuing the next anim... 13448 o.complete.call( animated[ 0 ] ); 13449 }); 13450 }); 13451}; 13452 13453$.fn.extend({ 13454 _addClass: $.fn.addClass, 13455 addClass: function( classNames, speed, easing, callback ) { 13456 return speed ? 13457 $.effects.animateClass.call( this, 13458 { add: classNames }, speed, easing, callback ) : 13459 this._addClass( classNames ); 13460 }, 13461 13462 _removeClass: $.fn.removeClass, 13463 removeClass: function( classNames, speed, easing, callback ) { 13464 return speed ? 13465 $.effects.animateClass.call( this, 13466 { remove: classNames }, speed, easing, callback ) : 13467 this._removeClass( classNames ); 13468 }, 13469 13470 _toggleClass: $.fn.toggleClass, 13471 toggleClass: function( classNames, force, speed, easing, callback ) { 13472 if ( typeof force === "boolean" || force === undefined ) { 13473 if ( !speed ) { 13474 // without speed parameter 13475 return this._toggleClass( classNames, force ); 13476 } else { 13477 return $.effects.animateClass.call( this, 13478 (force ? { add: classNames } : { remove: classNames }), 13479 speed, easing, callback ); 13480 } 13481 } else { 13482 // without force parameter 13483 return $.effects.animateClass.call( this, 13484 { toggle: classNames }, force, speed, easing ); 13485 } 13486 }, 13487 13488 switchClass: function( remove, add, speed, easing, callback) { 13489 return $.effects.animateClass.call( this, { 13490 add: add, 13491 remove: remove 13492 }, speed, easing, callback ); 13493 } 13494}); 13495 13496})(); 13497 13498/******************************************************************************/ 13499/*********************************** EFFECTS **********************************/ 13500/******************************************************************************/ 13501 13502(function() { 13503 13504$.extend( $.effects, { 13505 version: "1.9.2", 13506 13507 // Saves a set of properties in a data storage 13508 save: function( element, set ) { 13509 for( var i=0; i < set.length; i++ ) { 13510 if ( set[ i ] !== null ) { 13511 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 13512 } 13513 } 13514 }, 13515 13516 // Restores a set of previously saved properties from a data storage 13517 restore: function( element, set ) { 13518 var val, i; 13519 for( i=0; i < set.length; i++ ) { 13520 if ( set[ i ] !== null ) { 13521 val = element.data( dataSpace + set[ i ] ); 13522 // support: jQuery 1.6.2 13523 // http://bugs.jquery.com/ticket/9917 13524 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 13525 // We can't differentiate between "" and 0 here, so we just assume 13526 // empty string since it's likely to be a more common value... 13527 if ( val === undefined ) { 13528 val = ""; 13529 } 13530 element.css( set[ i ], val ); 13531 } 13532 } 13533 }, 13534 13535 setMode: function( el, mode ) { 13536 if (mode === "toggle") { 13537 mode = el.is( ":hidden" ) ? "show" : "hide"; 13538 } 13539 return mode; 13540 }, 13541 13542 // Translates a [top,left] array into a baseline value 13543 // this should be a little more flexible in the future to handle a string & hash 13544 getBaseline: function( origin, original ) { 13545 var y, x; 13546 switch ( origin[ 0 ] ) { 13547 case "top": y = 0; break; 13548 case "middle": y = 0.5; break; 13549 case "bottom": y = 1; break; 13550 default: y = origin[ 0 ] / original.height; 13551 } 13552 switch ( origin[ 1 ] ) { 13553 case "left": x = 0; break; 13554 case "center": x = 0.5; break; 13555 case "right": x = 1; break; 13556 default: x = origin[ 1 ] / original.width; 13557 } 13558 return { 13559 x: x, 13560 y: y 13561 }; 13562 }, 13563 13564 // Wraps the element around a wrapper that copies position properties 13565 createWrapper: function( element ) { 13566 13567 // if the element is already wrapped, return it 13568 if ( element.parent().is( ".ui-effects-wrapper" )) { 13569 return element.parent(); 13570 } 13571 13572 // wrap the element 13573 var props = { 13574 width: element.outerWidth(true), 13575 height: element.outerHeight(true), 13576 "float": element.css( "float" ) 13577 }, 13578 wrapper = $( "<div></div>" ) 13579 .addClass( "ui-effects-wrapper" ) 13580 .css({ 13581 fontSize: "100%", 13582 background: "transparent", 13583 border: "none", 13584 margin: 0, 13585 padding: 0 13586 }), 13587 // Store the size in case width/height are defined in % - Fixes #5245 13588 size = { 13589 width: element.width(), 13590 height: element.height() 13591 }, 13592 active = document.activeElement; 13593 13594 // support: Firefox 13595 // Firefox incorrectly exposes anonymous content 13596 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 13597 try { 13598 active.id; 13599 } catch( e ) { 13600 active = document.body; 13601 } 13602 13603 element.wrap( wrapper ); 13604 13605 // Fixes #7595 - Elements lose focus when wrapped. 13606 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13607 $( active ).focus(); 13608 } 13609 13610 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 13611 13612 // transfer positioning properties to the wrapper 13613 if ( element.css( "position" ) === "static" ) { 13614 wrapper.css({ position: "relative" }); 13615 element.css({ position: "relative" }); 13616 } else { 13617 $.extend( props, { 13618 position: element.css( "position" ), 13619 zIndex: element.css( "z-index" ) 13620 }); 13621 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 13622 props[ pos ] = element.css( pos ); 13623 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 13624 props[ pos ] = "auto"; 13625 } 13626 }); 13627 element.css({ 13628 position: "relative", 13629 top: 0, 13630 left: 0, 13631 right: "auto", 13632 bottom: "auto" 13633 }); 13634 } 13635 element.css(size); 13636 13637 return wrapper.css( props ).show(); 13638 }, 13639 13640 removeWrapper: function( element ) { 13641 var active = document.activeElement; 13642 13643 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13644 element.parent().replaceWith( element ); 13645 13646 // Fixes #7595 - Elements lose focus when wrapped. 13647 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13648 $( active ).focus(); 13649 } 13650 } 13651 13652 13653 return element; 13654 }, 13655 13656 setTransition: function( element, list, factor, value ) { 13657 value = value || {}; 13658 $.each( list, function( i, x ) { 13659 var unit = element.cssUnit( x ); 13660 if ( unit[ 0 ] > 0 ) { 13661 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13662 } 13663 }); 13664 return value; 13665 } 13666}); 13667 13668// return an effect options object for the given parameters: 13669function _normalizeArguments( effect, options, speed, callback ) { 13670 13671 // allow passing all options as the first parameter 13672 if ( $.isPlainObject( effect ) ) { 13673 options = effect; 13674 effect = effect.effect; 13675 } 13676 13677 // convert to an object 13678 effect = { effect: effect }; 13679 13680 // catch (effect, null, ...) 13681 if ( options == null ) { 13682 options = {}; 13683 } 13684 13685 // catch (effect, callback) 13686 if ( $.isFunction( options ) ) { 13687 callback = options; 13688 speed = null; 13689 options = {}; 13690 } 13691 13692 // catch (effect, speed, ?) 13693 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13694 callback = speed; 13695 speed = options; 13696 options = {}; 13697 } 13698 13699 // catch (effect, options, callback) 13700 if ( $.isFunction( speed ) ) { 13701 callback = speed; 13702 speed = null; 13703 } 13704 13705 // add options to effect 13706 if ( options ) { 13707 $.extend( effect, options ); 13708 } 13709 13710 speed = speed || options.duration; 13711 effect.duration = $.fx.off ? 0 : 13712 typeof speed === "number" ? speed : 13713 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13714 $.fx.speeds._default; 13715 13716 effect.complete = callback || options.complete; 13717 13718 return effect; 13719} 13720 13721function standardSpeed( speed ) { 13722 // valid standard speeds 13723 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 13724 return true; 13725 } 13726 13727 // invalid strings - treat as "normal" speed 13728 if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { 13729 // TODO: remove in 2.0 (#7115) 13730 if ( backCompat && $.effects[ speed ] ) { 13731 return false; 13732 } 13733 return true; 13734 } 13735 13736 return false; 13737} 13738 13739$.fn.extend({ 13740 effect: function( /* effect, options, speed, callback */ ) { 13741 var args = _normalizeArguments.apply( this, arguments ), 13742 mode = args.mode, 13743 queue = args.queue, 13744 effectMethod = $.effects.effect[ args.effect ], 13745 13746 // DEPRECATED: remove in 2.0 (#7115) 13747 oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; 13748 13749 if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { 13750 // delegate to the original method (e.g., .show()) if possible 13751 if ( mode ) { 13752 return this[ mode ]( args.duration, args.complete ); 13753 } else { 13754 return this.each( function() { 13755 if ( args.complete ) { 13756 args.complete.call( this ); 13757 } 13758 }); 13759 } 13760 } 13761 13762 function run( next ) { 13763 var elem = $( this ), 13764 complete = args.complete, 13765 mode = args.mode; 13766 13767 function done() { 13768 if ( $.isFunction( complete ) ) { 13769 complete.call( elem[0] ); 13770 } 13771 if ( $.isFunction( next ) ) { 13772 next(); 13773 } 13774 } 13775 13776 // if the element is hiddden and mode is hide, 13777 // or element is visible and mode is show 13778 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13779 done(); 13780 } else { 13781 effectMethod.call( elem[0], args, done ); 13782 } 13783 } 13784 13785 // TODO: remove this check in 2.0, effectMethod will always be true 13786 if ( effectMethod ) { 13787 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 13788 } else { 13789 // DEPRECATED: remove in 2.0 (#7115) 13790 return oldEffectMethod.call(this, { 13791 options: args, 13792 duration: args.duration, 13793 callback: args.complete, 13794 mode: args.mode 13795 }); 13796 } 13797 }, 13798 13799 _show: $.fn.show, 13800 show: function( speed ) { 13801 if ( standardSpeed( speed ) ) { 13802 return this._show.apply( this, arguments ); 13803 } else { 13804 var args = _normalizeArguments.apply( this, arguments ); 13805 args.mode = "show"; 13806 return this.effect.call( this, args ); 13807 } 13808 }, 13809 13810 _hide: $.fn.hide, 13811 hide: function( speed ) { 13812 if ( standardSpeed( speed ) ) { 13813 return this._hide.apply( this, arguments ); 13814 } else { 13815 var args = _normalizeArguments.apply( this, arguments ); 13816 args.mode = "hide"; 13817 return this.effect.call( this, args ); 13818 } 13819 }, 13820 13821 // jQuery core overloads toggle and creates _toggle 13822 __toggle: $.fn.toggle, 13823 toggle: function( speed ) { 13824 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 13825 return this.__toggle.apply( this, arguments ); 13826 } else { 13827 var args = _normalizeArguments.apply( this, arguments ); 13828 args.mode = "toggle"; 13829 return this.effect.call( this, args ); 13830 } 13831 }, 13832 13833 // helper functions 13834 cssUnit: function(key) { 13835 var style = this.css( key ), 13836 val = []; 13837 13838 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13839 if ( style.indexOf( unit ) > 0 ) { 13840 val = [ parseFloat( style ), unit ]; 13841 } 13842 }); 13843 return val; 13844 } 13845}); 13846 13847})(); 13848 13849/******************************************************************************/ 13850/*********************************** EASING ***********************************/ 13851/******************************************************************************/ 13852 13853(function() { 13854 13855// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 13856 13857var baseEasings = {}; 13858 13859$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13860 baseEasings[ name ] = function( p ) { 13861 return Math.pow( p, i + 2 ); 13862 }; 13863}); 13864 13865$.extend( baseEasings, { 13866 Sine: function ( p ) { 13867 return 1 - Math.cos( p * Math.PI / 2 ); 13868 }, 13869 Circ: function ( p ) { 13870 return 1 - Math.sqrt( 1 - p * p ); 13871 }, 13872 Elastic: function( p ) { 13873 return p === 0 || p === 1 ? p : 13874 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 13875 }, 13876 Back: function( p ) { 13877 return p * p * ( 3 * p - 2 ); 13878 }, 13879 Bounce: function ( p ) { 13880 var pow2, 13881 bounce = 4; 13882 13883 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 13884 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 13885 } 13886}); 13887 13888$.each( baseEasings, function( name, easeIn ) { 13889 $.easing[ "easeIn" + name ] = easeIn; 13890 $.easing[ "easeOut" + name ] = function( p ) { 13891 return 1 - easeIn( 1 - p ); 13892 }; 13893 $.easing[ "easeInOut" + name ] = function( p ) { 13894 return p < 0.5 ? 13895 easeIn( p * 2 ) / 2 : 13896 1 - easeIn( p * -2 + 2 ) / 2; 13897 }; 13898}); 13899 13900})(); 13901 13902})(jQuery)); 13903(function( $, undefined ) { 13904 13905var rvertical = /up|down|vertical/, 13906 rpositivemotion = /up|left|vertical|horizontal/; 13907 13908$.effects.effect.blind = function( o, done ) { 13909 // Create element 13910 var el = $( this ), 13911 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13912 mode = $.effects.setMode( el, o.mode || "hide" ), 13913 direction = o.direction || "up", 13914 vertical = rvertical.test( direction ), 13915 ref = vertical ? "height" : "width", 13916 ref2 = vertical ? "top" : "left", 13917 motion = rpositivemotion.test( direction ), 13918 animation = {}, 13919 show = mode === "show", 13920 wrapper, distance, margin; 13921 13922 // if already wrapped, the wrapper's properties are my property. #6245 13923 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 13924 $.effects.save( el.parent(), props ); 13925 } else { 13926 $.effects.save( el, props ); 13927 } 13928 el.show(); 13929 wrapper = $.effects.createWrapper( el ).css({ 13930 overflow: "hidden" 13931 }); 13932 13933 distance = wrapper[ ref ](); 13934 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 13935 13936 animation[ ref ] = show ? distance : 0; 13937 if ( !motion ) { 13938 el 13939 .css( vertical ? "bottom" : "right", 0 ) 13940 .css( vertical ? "top" : "left", "auto" ) 13941 .css({ position: "absolute" }); 13942 13943 animation[ ref2 ] = show ? margin : distance + margin; 13944 } 13945 13946 // start at 0 if we are showing 13947 if ( show ) { 13948 wrapper.css( ref, 0 ); 13949 if ( ! motion ) { 13950 wrapper.css( ref2, margin + distance ); 13951 } 13952 } 13953 13954 // Animate 13955 wrapper.animate( animation, { 13956 duration: o.duration, 13957 easing: o.easing, 13958 queue: false, 13959 complete: function() { 13960 if ( mode === "hide" ) { 13961 el.hide(); 13962 } 13963 $.effects.restore( el, props ); 13964 $.effects.removeWrapper( el ); 13965 done(); 13966 } 13967 }); 13968 13969}; 13970 13971})(jQuery); 13972(function( $, undefined ) { 13973 13974$.effects.effect.bounce = function( o, done ) { 13975 var el = $( this ), 13976 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13977 13978 // defaults: 13979 mode = $.effects.setMode( el, o.mode || "effect" ), 13980 hide = mode === "hide", 13981 show = mode === "show", 13982 direction = o.direction || "up", 13983 distance = o.distance, 13984 times = o.times || 5, 13985 13986 // number of internal animations 13987 anims = times * 2 + ( show || hide ? 1 : 0 ), 13988 speed = o.duration / anims, 13989 easing = o.easing, 13990 13991 // utility: 13992 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 13993 motion = ( direction === "up" || direction === "left" ), 13994 i, 13995 upAnim, 13996 downAnim, 13997 13998 // we will need to re-assemble the queue to stack our animations in place 13999 queue = el.queue(), 14000 queuelen = queue.length; 14001 14002 // Avoid touching opacity to prevent clearType and PNG issues in IE 14003 if ( show || hide ) { 14004 props.push( "opacity" ); 14005 } 14006 14007 $.effects.save( el, props ); 14008 el.show(); 14009 $.effects.createWrapper( el ); // Create Wrapper 14010 14011 // default distance for the BIGGEST bounce is the outer Distance / 3 14012 if ( !distance ) { 14013 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 14014 } 14015 14016 if ( show ) { 14017 downAnim = { opacity: 1 }; 14018 downAnim[ ref ] = 0; 14019 14020 // if we are showing, force opacity 0 and set the initial position 14021 // then do the "first" animation 14022 el.css( "opacity", 0 ) 14023 .css( ref, motion ? -distance * 2 : distance * 2 ) 14024 .animate( downAnim, speed, easing ); 14025 } 14026 14027 // start at the smallest distance if we are hiding 14028 if ( hide ) { 14029 distance = distance / Math.pow( 2, times - 1 ); 14030 } 14031 14032 downAnim = {}; 14033 downAnim[ ref ] = 0; 14034 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 14035 for ( i = 0; i < times; i++ ) { 14036 upAnim = {}; 14037 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14038 14039 el.animate( upAnim, speed, easing ) 14040 .animate( downAnim, speed, easing ); 14041 14042 distance = hide ? distance * 2 : distance / 2; 14043 } 14044 14045 // Last Bounce when Hiding 14046 if ( hide ) { 14047 upAnim = { opacity: 0 }; 14048 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14049 14050 el.animate( upAnim, speed, easing ); 14051 } 14052 14053 el.queue(function() { 14054 if ( hide ) { 14055 el.hide(); 14056 } 14057 $.effects.restore( el, props ); 14058 $.effects.removeWrapper( el ); 14059 done(); 14060 }); 14061 14062 // inject all the animations we just queued to be first in line (after "inprogress") 14063 if ( queuelen > 1) { 14064 queue.splice.apply( queue, 14065 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14066 } 14067 el.dequeue(); 14068 14069}; 14070 14071})(jQuery); 14072(function( $, undefined ) { 14073 14074$.effects.effect.clip = function( o, done ) { 14075 // Create element 14076 var el = $( this ), 14077 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14078 mode = $.effects.setMode( el, o.mode || "hide" ), 14079 show = mode === "show", 14080 direction = o.direction || "vertical", 14081 vert = direction === "vertical", 14082 size = vert ? "height" : "width", 14083 position = vert ? "top" : "left", 14084 animation = {}, 14085 wrapper, animate, distance; 14086 14087 // Save & Show 14088 $.effects.save( el, props ); 14089 el.show(); 14090 14091 // Create Wrapper 14092 wrapper = $.effects.createWrapper( el ).css({ 14093 overflow: "hidden" 14094 }); 14095 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 14096 distance = animate[ size ](); 14097 14098 // Shift 14099 if ( show ) { 14100 animate.css( size, 0 ); 14101 animate.css( position, distance / 2 ); 14102 } 14103 14104 // Create Animation Object: 14105 animation[ size ] = show ? distance : 0; 14106 animation[ position ] = show ? 0 : distance / 2; 14107 14108 // Animate 14109 animate.animate( animation, { 14110 queue: false, 14111 duration: o.duration, 14112 easing: o.easing, 14113 complete: function() { 14114 if ( !show ) { 14115 el.hide(); 14116 } 14117 $.effects.restore( el, props ); 14118 $.effects.removeWrapper( el ); 14119 done(); 14120 } 14121 }); 14122 14123}; 14124 14125})(jQuery); 14126(function( $, undefined ) { 14127 14128$.effects.effect.drop = function( o, done ) { 14129 14130 var el = $( this ), 14131 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 14132 mode = $.effects.setMode( el, o.mode || "hide" ), 14133 show = mode === "show", 14134 direction = o.direction || "left", 14135 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14136 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 14137 animation = { 14138 opacity: show ? 1 : 0 14139 }, 14140 distance; 14141 14142 // Adjust 14143 $.effects.save( el, props ); 14144 el.show(); 14145 $.effects.createWrapper( el ); 14146 14147 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 14148 14149 if ( show ) { 14150 el 14151 .css( "opacity", 0 ) 14152 .css( ref, motion === "pos" ? -distance : distance ); 14153 } 14154 14155 // Animation 14156 animation[ ref ] = ( show ? 14157 ( motion === "pos" ? "+=" : "-=" ) : 14158 ( motion === "pos" ? "-=" : "+=" ) ) + 14159 distance; 14160 14161 // Animate 14162 el.animate( animation, { 14163 queue: false, 14164 duration: o.duration, 14165 easing: o.easing, 14166 complete: function() { 14167 if ( mode === "hide" ) { 14168 el.hide(); 14169 } 14170 $.effects.restore( el, props ); 14171 $.effects.removeWrapper( el ); 14172 done(); 14173 } 14174 }); 14175}; 14176 14177})(jQuery); 14178(function( $, undefined ) { 14179 14180$.effects.effect.explode = function( o, done ) { 14181 14182 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 14183 cells = rows, 14184 el = $( this ), 14185 mode = $.effects.setMode( el, o.mode || "hide" ), 14186 show = mode === "show", 14187 14188 // show and then visibility:hidden the element before calculating offset 14189 offset = el.show().css( "visibility", "hidden" ).offset(), 14190 14191 // width and height of a piece 14192 width = Math.ceil( el.outerWidth() / cells ), 14193 height = Math.ceil( el.outerHeight() / rows ), 14194 pieces = [], 14195 14196 // loop 14197 i, j, left, top, mx, my; 14198 14199 // children animate complete: 14200 function childComplete() { 14201 pieces.push( this ); 14202 if ( pieces.length === rows * cells ) { 14203 animComplete(); 14204 } 14205 } 14206 14207 // clone the element for each row and cell. 14208 for( i = 0; i < rows ; i++ ) { // ===> 14209 top = offset.top + i * height; 14210 my = i - ( rows - 1 ) / 2 ; 14211 14212 for( j = 0; j < cells ; j++ ) { // ||| 14213 left = offset.left + j * width; 14214 mx = j - ( cells - 1 ) / 2 ; 14215 14216 // Create a clone of the now hidden main element that will be absolute positioned 14217 // within a wrapper div off the -left and -top equal to size of our pieces 14218 el 14219 .clone() 14220 .appendTo( "body" ) 14221 .wrap( "<div></div>" ) 14222 .css({ 14223 position: "absolute", 14224 visibility: "visible", 14225 left: -j * width, 14226 top: -i * height 14227 }) 14228 14229 // select the wrapper - make it overflow: hidden and absolute positioned based on 14230 // where the original was located +left and +top equal to the size of pieces 14231 .parent() 14232 .addClass( "ui-effects-explode" ) 14233 .css({ 14234 position: "absolute", 14235 overflow: "hidden", 14236 width: width, 14237 height: height, 14238 left: left + ( show ? mx * width : 0 ), 14239 top: top + ( show ? my * height : 0 ), 14240 opacity: show ? 0 : 1 14241 }).animate({ 14242 left: left + ( show ? 0 : mx * width ), 14243 top: top + ( show ? 0 : my * height ), 14244 opacity: show ? 1 : 0 14245 }, o.duration || 500, o.easing, childComplete ); 14246 } 14247 } 14248 14249 function animComplete() { 14250 el.css({ 14251 visibility: "visible" 14252 }); 14253 $( pieces ).remove(); 14254 if ( !show ) { 14255 el.hide(); 14256 } 14257 done(); 14258 } 14259}; 14260 14261})(jQuery); 14262(function( $, undefined ) { 14263 14264$.effects.effect.fade = function( o, done ) { 14265 var el = $( this ), 14266 mode = $.effects.setMode( el, o.mode || "toggle" ); 14267 14268 el.animate({ 14269 opacity: mode 14270 }, { 14271 queue: false, 14272 duration: o.duration, 14273 easing: o.easing, 14274 complete: done 14275 }); 14276}; 14277 14278})( jQuery ); 14279(function( $, undefined ) { 14280 14281$.effects.effect.fold = function( o, done ) { 14282 14283 // Create element 14284 var el = $( this ), 14285 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14286 mode = $.effects.setMode( el, o.mode || "hide" ), 14287 show = mode === "show", 14288 hide = mode === "hide", 14289 size = o.size || 15, 14290 percent = /([0-9]+)%/.exec( size ), 14291 horizFirst = !!o.horizFirst, 14292 widthFirst = show !== horizFirst, 14293 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 14294 duration = o.duration / 2, 14295 wrapper, distance, 14296 animation1 = {}, 14297 animation2 = {}; 14298 14299 $.effects.save( el, props ); 14300 el.show(); 14301 14302 // Create Wrapper 14303 wrapper = $.effects.createWrapper( el ).css({ 14304 overflow: "hidden" 14305 }); 14306 distance = widthFirst ? 14307 [ wrapper.width(), wrapper.height() ] : 14308 [ wrapper.height(), wrapper.width() ]; 14309 14310 if ( percent ) { 14311 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 14312 } 14313 if ( show ) { 14314 wrapper.css( horizFirst ? { 14315 height: 0, 14316 width: size 14317 } : { 14318 height: size, 14319 width: 0 14320 }); 14321 } 14322 14323 // Animation 14324 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 14325 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 14326 14327 // Animate 14328 wrapper 14329 .animate( animation1, duration, o.easing ) 14330 .animate( animation2, duration, o.easing, function() { 14331 if ( hide ) { 14332 el.hide(); 14333 } 14334 $.effects.restore( el, props ); 14335 $.effects.removeWrapper( el ); 14336 done(); 14337 }); 14338 14339}; 14340 14341})(jQuery); 14342(function( $, undefined ) { 14343 14344$.effects.effect.highlight = function( o, done ) { 14345 var elem = $( this ), 14346 props = [ "backgroundImage", "backgroundColor", "opacity" ], 14347 mode = $.effects.setMode( elem, o.mode || "show" ), 14348 animation = { 14349 backgroundColor: elem.css( "backgroundColor" ) 14350 }; 14351 14352 if (mode === "hide") { 14353 animation.opacity = 0; 14354 } 14355 14356 $.effects.save( elem, props ); 14357 14358 elem 14359 .show() 14360 .css({ 14361 backgroundImage: "none", 14362 backgroundColor: o.color || "#ffff99" 14363 }) 14364 .animate( animation, { 14365 queue: false, 14366 duration: o.duration, 14367 easing: o.easing, 14368 complete: function() { 14369 if ( mode === "hide" ) { 14370 elem.hide(); 14371 } 14372 $.effects.restore( elem, props ); 14373 done(); 14374 } 14375 }); 14376}; 14377 14378})(jQuery); 14379(function( $, undefined ) { 14380 14381$.effects.effect.pulsate = function( o, done ) { 14382 var elem = $( this ), 14383 mode = $.effects.setMode( elem, o.mode || "show" ), 14384 show = mode === "show", 14385 hide = mode === "hide", 14386 showhide = ( show || mode === "hide" ), 14387 14388 // showing or hiding leaves of the "last" animation 14389 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 14390 duration = o.duration / anims, 14391 animateTo = 0, 14392 queue = elem.queue(), 14393 queuelen = queue.length, 14394 i; 14395 14396 if ( show || !elem.is(":visible")) { 14397 elem.css( "opacity", 0 ).show(); 14398 animateTo = 1; 14399 } 14400 14401 // anims - 1 opacity "toggles" 14402 for ( i = 1; i < anims; i++ ) { 14403 elem.animate({ 14404 opacity: animateTo 14405 }, duration, o.easing ); 14406 animateTo = 1 - animateTo; 14407 } 14408 14409 elem.animate({ 14410 opacity: animateTo 14411 }, duration, o.easing); 14412 14413 elem.queue(function() { 14414 if ( hide ) { 14415 elem.hide(); 14416 } 14417 done(); 14418 }); 14419 14420 // We just queued up "anims" animations, we need to put them next in the queue 14421 if ( queuelen > 1 ) { 14422 queue.splice.apply( queue, 14423 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14424 } 14425 elem.dequeue(); 14426}; 14427 14428})(jQuery); 14429(function( $, undefined ) { 14430 14431$.effects.effect.puff = function( o, done ) { 14432 var elem = $( this ), 14433 mode = $.effects.setMode( elem, o.mode || "hide" ), 14434 hide = mode === "hide", 14435 percent = parseInt( o.percent, 10 ) || 150, 14436 factor = percent / 100, 14437 original = { 14438 height: elem.height(), 14439 width: elem.width(), 14440 outerHeight: elem.outerHeight(), 14441 outerWidth: elem.outerWidth() 14442 }; 14443 14444 $.extend( o, { 14445 effect: "scale", 14446 queue: false, 14447 fade: true, 14448 mode: mode, 14449 complete: done, 14450 percent: hide ? percent : 100, 14451 from: hide ? 14452 original : 14453 { 14454 height: original.height * factor, 14455 width: original.width * factor, 14456 outerHeight: original.outerHeight * factor, 14457 outerWidth: original.outerWidth * factor 14458 } 14459 }); 14460 14461 elem.effect( o ); 14462}; 14463 14464$.effects.effect.scale = function( o, done ) { 14465 14466 // Create element 14467 var el = $( this ), 14468 options = $.extend( true, {}, o ), 14469 mode = $.effects.setMode( el, o.mode || "effect" ), 14470 percent = parseInt( o.percent, 10 ) || 14471 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 14472 direction = o.direction || "both", 14473 origin = o.origin, 14474 original = { 14475 height: el.height(), 14476 width: el.width(), 14477 outerHeight: el.outerHeight(), 14478 outerWidth: el.outerWidth() 14479 }, 14480 factor = { 14481 y: direction !== "horizontal" ? (percent / 100) : 1, 14482 x: direction !== "vertical" ? (percent / 100) : 1 14483 }; 14484 14485 // We are going to pass this effect to the size effect: 14486 options.effect = "size"; 14487 options.queue = false; 14488 options.complete = done; 14489 14490 // Set default origin and restore for show/hide 14491 if ( mode !== "effect" ) { 14492 options.origin = origin || ["middle","center"]; 14493 options.restore = true; 14494 } 14495 14496 options.from = o.from || ( mode === "show" ? { 14497 height: 0, 14498 width: 0, 14499 outerHeight: 0, 14500 outerWidth: 0 14501 } : original ); 14502 options.to = { 14503 height: original.height * factor.y, 14504 width: original.width * factor.x, 14505 outerHeight: original.outerHeight * factor.y, 14506 outerWidth: original.outerWidth * factor.x 14507 }; 14508 14509 // Fade option to support puff 14510 if ( options.fade ) { 14511 if ( mode === "show" ) { 14512 options.from.opacity = 0; 14513 options.to.opacity = 1; 14514 } 14515 if ( mode === "hide" ) { 14516 options.from.opacity = 1; 14517 options.to.opacity = 0; 14518 } 14519 } 14520 14521 // Animate 14522 el.effect( options ); 14523 14524}; 14525 14526$.effects.effect.size = function( o, done ) { 14527 14528 // Create element 14529 var original, baseline, factor, 14530 el = $( this ), 14531 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 14532 14533 // Always restore 14534 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 14535 14536 // Copy for children 14537 props2 = [ "width", "height", "overflow" ], 14538 cProps = [ "fontSize" ], 14539 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 14540 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 14541 14542 // Set options 14543 mode = $.effects.setMode( el, o.mode || "effect" ), 14544 restore = o.restore || mode !== "effect", 14545 scale = o.scale || "both", 14546 origin = o.origin || [ "middle", "center" ], 14547 position = el.css( "position" ), 14548 props = restore ? props0 : props1, 14549 zero = { 14550 height: 0, 14551 width: 0, 14552 outerHeight: 0, 14553 outerWidth: 0 14554 }; 14555 14556 if ( mode === "show" ) { 14557 el.show(); 14558 } 14559 original = { 14560 height: el.height(), 14561 width: el.width(), 14562 outerHeight: el.outerHeight(), 14563 outerWidth: el.outerWidth() 14564 }; 14565 14566 if ( o.mode === "toggle" && mode === "show" ) { 14567 el.from = o.to || zero; 14568 el.to = o.from || original; 14569 } else { 14570 el.from = o.from || ( mode === "show" ? zero : original ); 14571 el.to = o.to || ( mode === "hide" ? zero : original ); 14572 } 14573 14574 // Set scaling factor 14575 factor = { 14576 from: { 14577 y: el.from.height / original.height, 14578 x: el.from.width / original.width 14579 }, 14580 to: { 14581 y: el.to.height / original.height, 14582 x: el.to.width / original.width 14583 } 14584 }; 14585 14586 // Scale the css box 14587 if ( scale === "box" || scale === "both" ) { 14588 14589 // Vertical props scaling 14590 if ( factor.from.y !== factor.to.y ) { 14591 props = props.concat( vProps ); 14592 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 14593 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 14594 } 14595 14596 // Horizontal props scaling 14597 if ( factor.from.x !== factor.to.x ) { 14598 props = props.concat( hProps ); 14599 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 14600 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 14601 } 14602 } 14603 14604 // Scale the content 14605 if ( scale === "content" || scale === "both" ) { 14606 14607 // Vertical props scaling 14608 if ( factor.from.y !== factor.to.y ) { 14609 props = props.concat( cProps ).concat( props2 ); 14610 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 14611 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 14612 } 14613 } 14614 14615 $.effects.save( el, props ); 14616 el.show(); 14617 $.effects.createWrapper( el ); 14618 el.css( "overflow", "hidden" ).css( el.from ); 14619 14620 // Adjust 14621 if (origin) { // Calculate baseline shifts 14622 baseline = $.effects.getBaseline( origin, original ); 14623 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 14624 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 14625 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 14626 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 14627 } 14628 el.css( el.from ); // set top & left 14629 14630 // Animate 14631 if ( scale === "content" || scale === "both" ) { // Scale the children 14632 14633 // Add margins/font-size 14634 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 14635 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 14636 props2 = props0.concat(vProps).concat(hProps); 14637 14638 el.find( "*[width]" ).each( function(){ 14639 var child = $( this ), 14640 c_original = { 14641 height: child.height(), 14642 width: child.width(), 14643 outerHeight: child.outerHeight(), 14644 outerWidth: child.outerWidth() 14645 }; 14646 if (restore) { 14647 $.effects.save(child, props2); 14648 } 14649 14650 child.from = { 14651 height: c_original.height * factor.from.y, 14652 width: c_original.width * factor.from.x, 14653 outerHeight: c_original.outerHeight * factor.from.y, 14654 outerWidth: c_original.outerWidth * factor.from.x 14655 }; 14656 child.to = { 14657 height: c_original.height * factor.to.y, 14658 width: c_original.width * factor.to.x, 14659 outerHeight: c_original.height * factor.to.y, 14660 outerWidth: c_original.width * factor.to.x 14661 }; 14662 14663 // Vertical props scaling 14664 if ( factor.from.y !== factor.to.y ) { 14665 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 14666 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 14667 } 14668 14669 // Horizontal props scaling 14670 if ( factor.from.x !== factor.to.x ) { 14671 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 14672 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 14673 } 14674 14675 // Animate children 14676 child.css( child.from ); 14677 child.animate( child.to, o.duration, o.easing, function() { 14678 14679 // Restore children 14680 if ( restore ) { 14681 $.effects.restore( child, props2 ); 14682 } 14683 }); 14684 }); 14685 } 14686 14687 // Animate 14688 el.animate( el.to, { 14689 queue: false, 14690 duration: o.duration, 14691 easing: o.easing, 14692 complete: function() { 14693 if ( el.to.opacity === 0 ) { 14694 el.css( "opacity", el.from.opacity ); 14695 } 14696 if( mode === "hide" ) { 14697 el.hide(); 14698 } 14699 $.effects.restore( el, props ); 14700 if ( !restore ) { 14701 14702 // we need to calculate our new positioning based on the scaling 14703 if ( position === "static" ) { 14704 el.css({ 14705 position: "relative", 14706 top: el.to.top, 14707 left: el.to.left 14708 }); 14709 } else { 14710 $.each([ "top", "left" ], function( idx, pos ) { 14711 el.css( pos, function( _, str ) { 14712 var val = parseInt( str, 10 ), 14713 toRef = idx ? el.to.left : el.to.top; 14714 14715 // if original was "auto", recalculate the new value from wrapper 14716 if ( str === "auto" ) { 14717 return toRef + "px"; 14718 } 14719 14720 return val + toRef + "px"; 14721 }); 14722 }); 14723 } 14724 } 14725 14726 $.effects.removeWrapper( el ); 14727 done(); 14728 } 14729 }); 14730 14731}; 14732 14733})(jQuery); 14734(function( $, undefined ) { 14735 14736$.effects.effect.shake = function( o, done ) { 14737 14738 var el = $( this ), 14739 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14740 mode = $.effects.setMode( el, o.mode || "effect" ), 14741 direction = o.direction || "left", 14742 distance = o.distance || 20, 14743 times = o.times || 3, 14744 anims = times * 2 + 1, 14745 speed = Math.round(o.duration/anims), 14746 ref = (direction === "up" || direction === "down") ? "top" : "left", 14747 positiveMotion = (direction === "up" || direction === "left"), 14748 animation = {}, 14749 animation1 = {}, 14750 animation2 = {}, 14751 i, 14752 14753 // we will need to re-assemble the queue to stack our animations in place 14754 queue = el.queue(), 14755 queuelen = queue.length; 14756 14757 $.effects.save( el, props ); 14758 el.show(); 14759 $.effects.createWrapper( el ); 14760 14761 // Animation 14762 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 14763 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 14764 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 14765 14766 // Animate 14767 el.animate( animation, speed, o.easing ); 14768 14769 // Shakes 14770 for ( i = 1; i < times; i++ ) { 14771 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 14772 } 14773 el 14774 .animate( animation1, speed, o.easing ) 14775 .animate( animation, speed / 2, o.easing ) 14776 .queue(function() { 14777 if ( mode === "hide" ) { 14778 el.hide(); 14779 } 14780 $.effects.restore( el, props ); 14781 $.effects.removeWrapper( el ); 14782 done(); 14783 }); 14784 14785 // inject all the animations we just queued to be first in line (after "inprogress") 14786 if ( queuelen > 1) { 14787 queue.splice.apply( queue, 14788 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14789 } 14790 el.dequeue(); 14791 14792}; 14793 14794})(jQuery); 14795(function( $, undefined ) { 14796 14797$.effects.effect.slide = function( o, done ) { 14798 14799 // Create element 14800 var el = $( this ), 14801 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 14802 mode = $.effects.setMode( el, o.mode || "show" ), 14803 show = mode === "show", 14804 direction = o.direction || "left", 14805 ref = (direction === "up" || direction === "down") ? "top" : "left", 14806 positiveMotion = (direction === "up" || direction === "left"), 14807 distance, 14808 animation = {}; 14809 14810 // Adjust 14811 $.effects.save( el, props ); 14812 el.show(); 14813 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 14814 14815 $.effects.createWrapper( el ).css({ 14816 overflow: "hidden" 14817 }); 14818 14819 if ( show ) { 14820 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 14821 } 14822 14823 // Animation 14824 animation[ ref ] = ( show ? 14825 ( positiveMotion ? "+=" : "-=") : 14826 ( positiveMotion ? "-=" : "+=")) + 14827 distance; 14828 14829 // Animate 14830 el.animate( animation, { 14831 queue: false, 14832 duration: o.duration, 14833 easing: o.easing, 14834 complete: function() { 14835 if ( mode === "hide" ) { 14836 el.hide(); 14837 } 14838 $.effects.restore( el, props ); 14839 $.effects.removeWrapper( el ); 14840 done(); 14841 } 14842 }); 14843}; 14844 14845})(jQuery); 14846(function( $, undefined ) { 14847 14848$.effects.effect.transfer = function( o, done ) { 14849 var elem = $( this ), 14850 target = $( o.to ), 14851 targetFixed = target.css( "position" ) === "fixed", 14852 body = $("body"), 14853 fixTop = targetFixed ? body.scrollTop() : 0, 14854 fixLeft = targetFixed ? body.scrollLeft() : 0, 14855 endPosition = target.offset(), 14856 animation = { 14857 top: endPosition.top - fixTop , 14858 left: endPosition.left - fixLeft , 14859 height: target.innerHeight(), 14860 width: target.innerWidth() 14861 }, 14862 startPosition = elem.offset(), 14863 transfer = $( '<div class="ui-effects-transfer"></div>' ) 14864 .appendTo( document.body ) 14865 .addClass( o.className ) 14866 .css({ 14867 top: startPosition.top - fixTop , 14868 left: startPosition.left - fixLeft ,
14869 height: elem.innerHeight(), 14870 width: elem.innerWidth(), 14871 position: targetFixed ? "fixed" : "absolute" 14872 }) 14873 .animate( animation, o.duration, o.easing, function() { 14874 transfer.remove(); 14875 done(); 14876 }); 14877}; 14878 14879})(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.