vendor: 9,149 bytes, lines 1-321
1/*! jQuery UI - v1.9.2 - 2014-02-09 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 2014 jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// prevent duplicate loading 12// this is only a problem because we proxy existing functions 13// and we don't want to double proxy them 14$.ui = $.ui || {}; 15if ( $.ui.version ) { 16 return; 17} 18 19$.extend( $.ui, { 20 version: "1.9.2", 21 22 keyCode: { 23 BACKSPACE: 8, 24 COMMA: 188, 25 DELETE: 46, 26 DOWN: 40, 27 END: 35, 28 ENTER: 13, 29 ESCAPE: 27, 30 HOME: 36, 31 LEFT: 37, 32 NUMPAD_ADD: 107, 33 NUMPAD_DECIMAL: 110, 34 NUMPAD_DIVIDE: 111, 35 NUMPAD_ENTER: 108, 36 NUMPAD_MULTIPLY: 106, 37 NUMPAD_SUBTRACT: 109, 38 PAGE_DOWN: 34, 39 PAGE_UP: 33, 40 PERIOD: 190, 41 RIGHT: 39, 42 SPACE: 32, 43 TAB: 9, 44 UP: 38 45 } 46}); 47 48// plugins 49$.fn.extend({ 50 _focus: $.fn.focus, 51 focus: function( delay, fn ) { 52 return typeof delay === "number" ? 53 this.each(function() { 54 var elem = this; 55 setTimeout(function() { 56 $( elem ).focus(); 57 if ( fn ) { 58 fn.call( elem ); 59 } 60 }, delay ); 61 }) : 62 this._focus.apply( this, arguments ); 63 }, 64 65 scrollParent: function() { 66 var scrollParent; 67 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { 68 scrollParent = this.parents().filter(function() { 69 return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 70 }).eq(0); 71 } else { 72 scrollParent = this.parents().filter(function() { 73 return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 74 }).eq(0); 75 } 76 77 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; 78 }, 79 80 zIndex: function( zIndex ) { 81 if ( zIndex !== undefined ) { 82 return this.css( "zIndex", zIndex ); 83 } 84 85 if ( this.length ) { 86 var elem = $( this[ 0 ] ), position, value; 87 while ( elem.length && elem[ 0 ] !== document ) { 88 // Ignore z-index if position is set to a value where z-index is ignored by the browser 89 // This makes behavior of this function consistent across browsers 90 // WebKit always returns auto if the element is positioned 91 position = elem.css( "position" ); 92 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 93 // IE returns 0 when zIndex is not specified 94 // other browsers return a string 95 // we ignore the case of nested elements with an explicit value of 0 96 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 97 value = parseInt( elem.css( "zIndex" ), 10 ); 98 if ( !isNaN( value ) && value !== 0 ) { 99 return value; 100 } 101 } 102 elem = elem.parent(); 103 } 104 } 105 106 return 0; 107 }, 108 109 uniqueId: function() { 110 return this.each(function() { 111 if ( !this.id ) { 112 this.id = "ui-id-" + (++uuid); 113 } 114 }); 115 }, 116 117 removeUniqueId: function() { 118 return this.each(function() { 119 if ( runiqueId.test( this.id ) ) { 120 $( this ).removeAttr( "id" ); 121 } 122 }); 123 } 124}); 125 126// selectors 127function focusable( element, isTabIndexNotNaN ) { 128 var map, mapName, img, 129 nodeName = element.nodeName.toLowerCase(); 130 if ( "area" === nodeName ) { 131 map = element.parentNode; 132 mapName = map.name; 133 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 134 return false; 135 } 136 img = $( "img[usemap=#" + mapName + "]" )[0]; 137 return !!img && visible( img ); 138 } 139 return ( /input|select|textarea|button|object/.test( nodeName ) ? 140 !element.disabled : 141 "a" === nodeName ? 142 element.href || isTabIndexNotNaN : 143 isTabIndexNotNaN) && 144 // the element and all of its ancestors must be visible 145 visible( element ); 146} 147 148function visible( element ) { 149 return $.expr.filters.visible( element ) && 150 !$( element ).parents().andSelf().filter(function() { 151 return $.css( this, "visibility" ) === "hidden"; 152 }).length; 153} 154 155$.extend( $.expr[ ":" ], { 156 data: $.expr.createPseudo ? 157 $.expr.createPseudo(function( dataName ) { 158 return function( elem ) { 159 return !!$.data( elem, dataName ); 160 }; 161 }) : 162 // support: jQuery <1.8 163 function( elem, i, match ) { 164 return !!$.data( elem, match[ 3 ] ); 165 }, 166 167 focusable: function( element ) { 168 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 169 }, 170 171 tabbable: function( element ) { 172 var tabIndex = $.attr( element, "tabindex" ), 173 isTabIndexNaN = isNaN( tabIndex ); 174 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 175 } 176}); 177 178// support 179$(function() { 180 var body = document.body, 181 div = body.appendChild( div = document.createElement( "div" ) ); 182 183 // access offsetHeight before setting the style to prevent a layout bug 184 // in IE 9 which causes the element to continue to take up space even 185 // after it is removed from the DOM (#8026) 186 div.offsetHeight; 187 188 $.extend( div.style, { 189 minHeight: "100px", 190 height: "auto", 191 padding: 0, 192 borderWidth: 0 193 }); 194 195 $.support.minHeight = div.offsetHeight === 100; 196 $.support.selectstart = "onselectstart" in div; 197 198 // set display to none to avoid a layout bug in IE 199 // http://dev.jquery.com/ticket/4014 200 body.removeChild( div ).style.display = "none"; 201}); 202 203// support: jQuery <1.8 204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 205 $.each( [ "Width", "Height" ], function( i, name ) { 206 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 207 type = name.toLowerCase(), 208 orig = { 209 innerWidth: $.fn.innerWidth, 210 innerHeight: $.fn.innerHeight, 211 outerWidth: $.fn.outerWidth, 212 outerHeight: $.fn.outerHeight 213 }; 214 215 function reduce( elem, size, border, margin ) { 216 $.each( side, function() { 217 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 218 if ( border ) { 219 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 220 } 221 if ( margin ) { 222 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 223 } 224 }); 225 return size; 226 } 227 228 $.fn[ "inner" + name ] = function( size ) { 229 if ( size === undefined ) { 230 return orig[ "inner" + name ].call( this ); 231 } 232 233 return this.each(function() { 234 $( this ).css( type, reduce( this, size ) + "px" ); 235 }); 236 }; 237 238 $.fn[ "outer" + name] = function( size, margin ) { 239 if ( typeof size !== "number" ) { 240 return orig[ "outer" + name ].call( this, size ); 241 } 242 243 return this.each(function() { 244 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 245 }); 246 }; 247 }); 248} 249 250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 252 $.fn.removeData = (function( removeData ) { 253 return function( key ) { 254 if ( arguments.length ) { 255 return removeData.call( this, $.camelCase( key ) ); 256 } else { 257 return removeData.call( this ); 258 } 259 }; 260 })( $.fn.removeData ); 261} 262 263 264 265 266 267// deprecated 268 269(function() { 270 var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || []; 271 $.ui.ie = uaMatch.length ? true : false; 272 $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6; 273})(); 274 275$.fn.extend({ 276 disableSelection: function() { 277 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 278 ".ui-disableSelection", function( event ) { 279 event.preventDefault(); 280 }); 281 }, 282 283 enableSelection: function() { 284 return this.unbind( ".ui-disableSelection" ); 285 } 286}); 287 288$.extend( $.ui, { 289 // $.ui.plugin is deprecated. Use the proxy pattern instead. 290 plugin: { 291 add: function( module, option, set ) { 292 var i, 293 proto = $.ui[ module ].prototype; 294 for ( i in set ) { 295 proto.plugins[ i ] = proto.plugins[ i ] || []; 296 proto.plugins[ i ].push( [ option, set[ i ] ] ); 297 } 298 }, 299 call: function( instance, name, args ) { 300 var i, 301 set = instance.plugins[ name ]; 302 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 303 return; 304 } 305 306 for ( i = 0; i < set.length; i++ ) { 307 if ( instance.options[ set[ i ][ 0 ] ] ) { 308 set[ i ][ 1 ].apply( instance.element, args ); 309 } 310 } 311 } 312 }, 313 314 contains: $.contains, 315 316 // only used by resizable 317 hasScroll: function( el, a ) { 318 319 //If overflow is hidden, the element might have extra content, but the user wants to hide it 320 if ( $( el ).css( "overflow" ) === "hidden") { 321 return false;
vendor: 4,237 bytes, lines 322-458
322 } 323 324 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 325 has = false; 326 327 if ( el[ scroll ] > 0 ) { 328 return true; 329 } 330 331 // TODO: determine which cases actually cause this to happen 332 // if the element doesn't have the scroll set, see if it's possible to 333 // set the scroll 334 el[ scroll ] = 1; 335 has = ( el[ scroll ] > 0 ); 336 el[ scroll ] = 0; 337 return has; 338 }, 339 340 // these are odd functions, fix the API or move into individual plugins 341 isOverAxis: function( x, reference, size ) { 342 //Determines when x coordinate is over "b" element axis 343 return ( x > reference ) && ( x < ( reference + size ) ); 344 }, 345 isOver: function( y, x, top, left, height, width ) { 346 //Determines when x, y coordinates is over "b" element 347 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); 348 } 349}); 350 351})( jQuery ); 352(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.
vendor: 11,206 bytes, lines 459-848
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,170 bytes, lines 849-1003
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: 12,659 bytes, lines 1147-1544
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 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.size.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;
vendor: 4,195 bytes, lines 3509-3647
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 }); 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;
vendor: 11,425 bytes, lines 4703-5134
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() { 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, 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;
vendor: 21,656 bytes, lines 5522-6300
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 }, 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 ) {
vendor: 7,201 bytes, lines 6301-6502
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(); 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: ['1ì','2ì','3ì','4ì','5ì','6ì', 6488 '7ì','8ì','9ì','10ì','11ì','12ì'], // 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: ['ì¼','ì','í','ì','목','ê¸','í '], // Column headings for days starting at Sunday 6493 weekHeader: 'Wk', // Column header for week of the year 6494 dateFormat: 'yy-mm-dd', // 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: 4,836 bytes, lines 6503-6589
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 }
vendor: 4,711 bytes, lines 6700-6815
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')); 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);
vendor: 8,608 bytes, lines 7051-7252
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
vendor: 4,158 bytes, lines 7414-7522
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;
vendor: 5,981 bytes, lines 7671-7852
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 8061 // year selection 8062 if ( !inst.yearshtml ) { 8063 inst.yearshtml = ''; 8064 if (secondary || !changeYear) 8065 html += '<span class="ui-datepicker-year">' + drawYear + 'ë </span>'; 8066 else { 8067 // determine range of years to display 8068 var years = this._get(inst, 'yearRange').split(':'); 8069 var thisYear = new Date().getFullYear(); 8070 var determineYear = function(value) { 8071 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8072 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 8073 parseInt(value, 10))); 8074 return (isNaN(year) ? thisYear : year); 8075 }; 8076 var year = determineYear(years[0]); 8077 var endYear = Math.max(year, determineYear(years[1] || '')); 8078 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8079 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8080 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 8081 for (; year <= endYear; year++) { 8082 inst.yearshtml += '<option value="' + year + '"' + 8083 (year == drawYear ? ' selected="selected"' : '') + 8084 '>' + year + '</option>'; 8085 } 8086 inst.yearshtml += '</select>'; 8087 8088 html += inst.yearshtml; 8089 inst.yearshtml = null; 8090 } 8091 } 8092 html += this._get(inst, 'yearSuffix'); 8093 if (showMonthAfterYear) 8094 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 8095 // month selection 8096 if (secondary || !changeMonth) 8097 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 8098 else { 8099 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 8100 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 8101 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8102 for (var month = 0; month < 12; month++) { 8103 if ((!inMinYear || month >= minDate.getMonth()) && 8104 (!inMaxYear || month <= maxDate.getMonth())) 8105 monthHtml += '<option value="' + month + '"' + 8106 (month == drawMonth ? ' selected="selected"' : '') + 8107 '>' + monthNamesShort[month] + '</option>'; 8108 } 8109 monthHtml += '</select>'; 8110 } 8111 if (!showMonthAfterYear) 8112 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 8113 html += '</div>'; // Close datepicker_header 8114 return html; 8115 }, 8116 8117 /* Adjust one of the date sub-fields. */ 8118 _adjustInstDate: function(inst, offset, period) { 8119 var year = inst.drawYear + (period == 'Y' ? offset : 0); 8120 var month = inst.drawMonth + (period == 'M' ? offset : 0); 8121 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 8122 (period == 'D' ? offset : 0); 8123 var date = this._restrictMinMax(inst, 8124 this._daylightSavingAdjust(new Date(year, month, day))); 8125 inst.selectedDay = date.getDate(); 8126 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8127 inst.drawYear = inst.selectedYear = date.getFullYear(); 8128 if (period == 'M' || period == 'Y') 8129 this._notifyChange(inst); 8130 }, 8131 8132 /* Ensure a date is within any min/max bounds. */ 8133 _restrictMinMax: function(inst, date) { 8134 var minDate = this._getMinMaxDate(inst, 'min'); 8135 var maxDate = this._getMinMaxDate(inst, 'max'); 8136 var newDate = (minDate && date < minDate ? minDate : date); 8137 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 8138 return newDate; 8139 }, 8140 8141 /* Notify change of month/year. */ 8142 _notifyChange: function(inst) { 8143 var onChange = this._get(inst, 'onChangeMonthYear'); 8144 if (onChange) 8145 onChange.apply((inst.input ? inst.input[0] : null), 8146 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8147 }, 8148 8149 /* Determine the number of months to show. */ 8150 _getNumberOfMonths: function(inst) { 8151 var numMonths = this._get(inst, 'numberOfMonths'); 8152 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 8153 }, 8154 8155 /* Determine the current maximum date - ensure no time components are set. */ 8156 _getMinMaxDate: function(inst, minMax) { 8157 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 8158 }, 8159 8160 /* Find the number of days in a given month. */ 8161 _getDaysInMonth: function(year, month) { 8162 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8163 }, 8164 8165 /* Find the day of the week of the first of a month. */ 8166 _getFirstDayOfMonth: function(year, month) { 8167 return new Date(year, month, 1).getDay(); 8168 }, 8169 8170 /* Determines if we should allow a "next/prev" month display change. */ 8171 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 8172 var numMonths = this._getNumberOfMonths(inst); 8173 var date = this._daylightSavingAdjust(new Date(curYear, 8174 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8175 if (offset < 0) 8176 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8177 return this._isInRange(inst, date); 8178 }, 8179 8180 /* Is the given date in the accepted range? */ 8181 _isInRange: function(inst, date) { 8182 var minDate = this._getMinMaxDate(inst, 'min'); 8183 var maxDate = this._getMinMaxDate(inst, 'max'); 8184 return ((!minDate || date.getTime() >= minDate.getTime()) && 8185 (!maxDate || date.getTime() <= maxDate.getTime())); 8186 }, 8187 8188 /* Provide the configuration settings for formatting/parsing. */ 8189 _getFormatConfig: function(inst) { 8190 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 8191 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 8192 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8193 return {shortYearCutoff: shortYearCutoff, 8194 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 8195 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 8196 }, 8197 8198 /* Format the given date for display. */ 8199 _formatDate: function(inst, day, month, year) { 8200 if (!day) { 8201 inst.currentDay = inst.selectedDay; 8202 inst.currentMonth = inst.selectedMonth; 8203 inst.currentYear = inst.selectedYear; 8204 } 8205 var date = (day ? (typeof day == 'object' ? day : 8206 this._daylightSavingAdjust(new Date(year, month, day))) : 8207 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8208 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 8209 } 8210}); 8211 8212/* 8213 * Bind hover events for datepicker elements. 8214 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8215 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8216 */ 8217function bindHover(dpDiv) { 8218 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 8219 return dpDiv.delegate(selector, 'mouseout', function() { 8220 $(this).removeClass('ui-state-hover'); 8221 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 8222 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 8223 }) 8224 .delegate(selector, 'mouseover', function(){ 8225 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 8226 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 8227 $(this).addClass('ui-state-hover'); 8228 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 8229 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 8230 } 8231 }); 8232} 8233 8234/* jQuery extend now ignores nulls! */ 8235function extendRemove(target, props) { 8236 $.extend(target, props); 8237 for (var name in props) 8238 if (props[name] == null || props[name] == undefined) 8239 target[name] = props[name]; 8240 return target; 8241}; 8242 8243/* Invoke the datepicker functionality. 8244 @param options string - a command, optionally followed by additional parameters or 8245 Object - settings for attaching new datepicker functionality 8246 @return jQuery object */ 8247$.fn.datepicker = function(options){ 8248 8249 /* Verify an empty collection wasn't passed - Fixes #6976 */ 8250 if ( !this.length ) { 8251 return this; 8252 } 8253 8254 /* Initialise the date picker. */ 8255 if (!$.datepicker.initialized) { 8256 $(document).mousedown($.datepicker._checkExternalClick). 8257 find(document.body).append($.datepicker.dpDiv); 8258 $.datepicker.initialized = true; 8259 } 8260 8261 var otherArgs = Array.prototype.slice.call(arguments, 1); 8262 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 8263 return $.datepicker['_' + options + 'Datepicker']. 8264 apply($.datepicker, [this[0]].concat(otherArgs)); 8265 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 8266 return $.datepicker['_' + options + 'Datepicker']. 8267 apply($.datepicker, [this[0]].concat(otherArgs)); 8268 return this.each(function() { 8269 typeof options == 'string' ? 8270 $.datepicker['_' + options + 'Datepicker']. 8271 apply($.datepicker, [this].concat(otherArgs)) : 8272 $.datepicker._attachDatepicker(this, options); 8273 }); 8274}; 8275 8276$.datepicker = new Datepicker(); // singleton instance 8277$.datepicker.initialized = false;
8278$.datepicker.uuid = new Date().getTime(); 8279$.datepicker.version = "1.9.2"; 8280 8281// Workaround for #4055 8282// Add another global to avoid noConflict issues with inline event handlers 8283window['DP_jQuery_' + dpuuid] = $; 8284 8285})(jQuery); 8286(function( $, undefined ) { 8287 8288var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", 8289 sizeRelatedOptions = { 8290 buttons: true, 8291 height: true, 8292 maxHeight: true, 8293 maxWidth: true, 8294 minHeight: true, 8295 minWidth: true, 8296 width: true 8297 }, 8298 resizableRelatedOptions = { 8299 maxHeight: true, 8300 maxWidth: true, 8301 minHeight: true, 8302 minWidth: true 8303 }; 8304 8305$.widget("ui.dialog", { 8306 version: "1.9.2", 8307 options: { 8308 autoOpen: true, 8309 buttons: {}, 8310 closeOnEscape: true, 8311 closeText: "close", 8312 dialogClass: "", 8313 draggable: true, 8314 hide: null, 8315 height: "auto", 8316 maxHeight: false, 8317 maxWidth: false, 8318 minHeight: 150, 8319 minWidth: 150, 8320 modal: false, 8321 position: { 8322 my: "center", 8323 at: "center", 8324 of: window, 8325 collision: "fit", 8326 // ensure that the titlebar is never outside the document 8327 using: function( pos ) { 8328 var topOffset = $( this ).css( pos ).offset().top; 8329 if ( topOffset < 0 ) { 8330 $( this ).css( "top", pos.top - topOffset ); 8331 } 8332 } 8333 }, 8334 resizable: true, 8335 show: null, 8336 stack: true, 8337 title: "", 8338 width: 300, 8339 zIndex: 1000 8340 }, 8341 8342 _create: function() { 8343 this.originalTitle = this.element.attr( "title" ); 8344 // #5742 - .attr() might return a DOMElement 8345 if ( typeof this.originalTitle !== "string" ) { 8346 this.originalTitle = ""; 8347 } 8348 this.oldPosition = { 8349 parent: this.element.parent(), 8350 index: this.element.parent().children().index( this.element ) 8351 }; 8352 this.options.title = this.options.title || this.originalTitle; 8353 var that = this, 8354 options = this.options, 8355 8356 title = options.title || " ", 8357 uiDialog, 8358 uiDialogTitlebar, 8359 uiDialogTitlebarClose, 8360 uiDialogTitle, 8361 uiDialogButtonPane; 8362 8363 uiDialog = ( this.uiDialog = $( "<div>" ) ) 8364 .addClass( uiDialogClasses + options.dialogClass ) 8365 .css({ 8366 display: "none", 8367 outline: 0, // TODO: move to stylesheet 8368 zIndex: options.zIndex 8369 }) 8370 // setting tabIndex makes the div focusable 8371 .attr( "tabIndex", -1) 8372 .keydown(function( event ) { 8373 if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 8374 event.keyCode === $.ui.keyCode.ESCAPE ) { 8375 that.close( event ); 8376 event.preventDefault(); 8377 } 8378 }) 8379 .mousedown(function( event ) { 8380 that.moveToTop( false, event ); 8381 }) 8382 .appendTo( "body" ); 8383 8384 this.element 8385 .show() 8386 .removeAttr( "title" ) 8387 .addClass( "ui-dialog-content ui-widget-content" ) 8388 .appendTo( uiDialog ); 8389 8390 uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) ) 8391 .addClass( "ui-dialog-titlebar ui-widget-header " + 8392 "ui-corner-all ui-helper-clearfix" ) 8393 .bind( "mousedown", function() { 8394 // Dialog isn't getting focus when dragging (#8063) 8395 uiDialog.focus(); 8396 }) 8397 .prependTo( uiDialog ); 8398 8399 uiDialogTitlebarClose = $( "<a href='#'></a>" ) 8400 .addClass( "ui-dialog-titlebar-close ui-corner-all" ) 8401 .attr( "role", "button" ) 8402 .click(function( event ) { 8403 event.preventDefault(); 8404 that.close( event ); 8405 }) 8406 .appendTo( uiDialogTitlebar ); 8407 8408 ( this.uiDialogTitlebarCloseText = $( "<span>" ) ) 8409 .addClass( "ui-icon ui-icon-closethick" ) 8410 .text( options.closeText ) 8411 .appendTo( uiDialogTitlebarClose ); 8412 8413 uiDialogTitle = $( "<span>" ) 8414 .uniqueId() 8415 .addClass( "ui-dialog-title" ) 8416 .html( title ) 8417 .prependTo( uiDialogTitlebar ); 8418 8419 uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) 8420 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 8421 8422 ( this.uiButtonSet = $( "<div>" ) ) 8423 .addClass( "ui-dialog-buttonset" ) 8424 .appendTo( uiDialogButtonPane ); 8425 8426 uiDialog.attr({ 8427 role: "dialog", 8428 "aria-labelledby": uiDialogTitle.attr( "id" ) 8429 }); 8430 8431 uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); 8432 this._hoverable( uiDialogTitlebarClose ); 8433 this._focusable( uiDialogTitlebarClose ); 8434 8435 if ( options.draggable && $.fn.draggable ) { 8436 this._makeDraggable(); 8437 } 8438 if ( options.resizable && $.fn.resizable ) { 8439 this._makeResizable(); 8440 } 8441
8442 this._createButtons( options.buttons ); 8443 this._isOpen = false; 8444 8445 if ( $.fn.bgiframe ) { 8446 uiDialog.bgiframe(); 8447 } 8448 8449 // prevent tabbing out of modal dialogs 8450 this._on( uiDialog, { keydown: function( event ) { 8451 if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { 8452 return; 8453 } 8454 8455 var tabbables = $( ":tabbable", uiDialog ), 8456 first = tabbables.filter( ":first" ), 8457 last = tabbables.filter( ":last" ); 8458 8459 if ( event.target === last[0] && !event.shiftKey ) { 8460 first.focus( 1 ); 8461 return false; 8462 } else if ( event.target === first[0] && event.shiftKey ) { 8463 last.focus( 1 ); 8464 return false; 8465 } 8466 }}); 8467 }, 8468 8469 _init: function() { 8470 if ( this.options.autoOpen ) { 8471 this.open(); 8472 } 8473 }, 8474 8475 _destroy: function() { 8476 var next, 8477 oldPosition = this.oldPosition; 8478 8479 if ( this.overlay ) { 8480 this.overlay.destroy(); 8481 } 8482 this.uiDialog.hide(); 8483 this.element 8484 .removeClass( "ui-dialog-content ui-widget-content" ) 8485 .hide() 8486 .appendTo( "body" ); 8487 this.uiDialog.remove(); 8488 8489 if ( this.originalTitle ) { 8490 this.element.attr( "title", this.originalTitle ); 8491 } 8492 8493 next = oldPosition.parent.children().eq( oldPosition.index ); 8494 // Don't try to place the dialog next to itself (#8613) 8495 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 8496 next.before( this.element ); 8497 } else { 8498 oldPosition.parent.append( this.element ); 8499 } 8500 }, 8501 8502 widget: function() { 8503 return this.uiDialog; 8504 }, 8505 8506 close: function( event ) { 8507 var that = this, 8508 maxZ, thisZ; 8509 8510 if ( !this._isOpen ) { 8511 return; 8512 } 8513 8514 if ( false === this._trigger( "beforeClose", event ) ) { 8515 return; 8516 } 8517 8518 this._isOpen = false; 8519 8520 if ( this.overlay ) { 8521 this.overlay.destroy(); 8522 } 8523 8524 if ( this.options.hide ) { 8525 this._hide( this.uiDialog, this.options.hide, function() { 8526 that._trigger( "close", event ); 8527 }); 8528 } else { 8529 this.uiDialog.hide(); 8530 this._trigger( "close", event ); 8531 } 8532 8533 $.ui.dialog.overlay.resize(); 8534 8535 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 8536 if ( this.options.modal ) { 8537 maxZ = 0; 8538 $( ".ui-dialog" ).each(function() { 8539 if ( this !== that.uiDialog[0] ) { 8540 thisZ = $( this ).css( "z-index" ); 8541 if ( !isNaN( thisZ ) ) { 8542 maxZ = Math.max( maxZ, thisZ ); 8543 } 8544 } 8545 }); 8546 $.ui.dialog.maxZ = maxZ; 8547 } 8548 8549 return this; 8550 }, 8551 8552 isOpen: function() { 8553 return this._isOpen; 8554 }, 8555 8556 // the force parameter allows us to move modal dialogs to their correct 8557 // position on open 8558 moveToTop: function( force, event ) { 8559 var options = this.options, 8560 saveScroll; 8561 8562 if ( ( options.modal && !force ) || 8563 ( !options.stack && !options.modal ) ) { 8564 return this._trigger( "focus", event ); 8565 } 8566 8567 if ( options.zIndex > $.ui.dialog.maxZ ) { 8568 $.ui.dialog.maxZ = options.zIndex; 8569 } 8570 if ( this.overlay ) { 8571 $.ui.dialog.maxZ += 1; 8572 $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; 8573 this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); 8574 } 8575 8576 // Save and then restore scroll 8577 // Opera 9.5+ resets when parent z-index is changed. 8578 // http://bugs.jqueryui.com/ticket/3193 8579 saveScroll = { 8580 scrollTop: this.element.scrollTop(), 8581 scrollLeft: this.element.scrollLeft() 8582 }; 8583 $.ui.dialog.maxZ += 1; 8584 this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); 8585 this.element.attr( saveScroll ); 8586 this._trigger( "focus", event ); 8587 8588 return this; 8589 }, 8590 8591 open: function() { 8592 if ( this._isOpen ) { 8593 return; 8594 } 8595 8596 var hasFocus, 8597 options = this.options, 8598 uiDialog = this.uiDialog; 8599 8600 this._size(); 8601 this._position( options.position ); 8602 uiDialog.show( options.show ); 8603 this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; 8604 this.moveToTop( true ); 8605 8606 // set focus to the first tabbable element in the content area or the first button 8607 // if there are no tabbable elements, set focus on the dialog itself 8608 hasFocus = this.element.find( ":tabbable" ); 8609 if ( !hasFocus.length ) { 8610 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 8611 if ( !hasFocus.length ) { 8612 hasFocus = uiDialog; 8613 } 8614 } 8615 hasFocus.eq( 0 ).focus(); 8616 8617 this._isOpen = true; 8618 this._trigger( "open" ); 8619 8620 return this; 8621 }, 8622 8623 _createButtons: function( buttons ) { 8624 var that = this, 8625 hasButtons = false;
8626 8627 // if we already have a button pane, remove it 8628 this.uiDialogButtonPane.remove(); 8629 this.uiButtonSet.empty(); 8630 8631 if ( typeof buttons === "object" && buttons !== null ) { 8632 $.each( buttons, function() { 8633 return !(hasButtons = true); 8634 }); 8635 } 8636 if ( hasButtons ) { 8637 $.each( buttons, function( name, props ) { 8638 var button, click; 8639 props = $.isFunction( props ) ? 8640 { click: props, text: name } : 8641 props; 8642 // Default to a non-submitting button 8643 props = $.extend( { type: "button" }, props ); 8644 // Change the context for the click callback to be the main element 8645 click = props.click; 8646 props.click = function() { 8647 click.apply( that.element[0], arguments ); 8648 }; 8649 button = $( "<button></button>", props ) 8650 .appendTo( that.uiButtonSet ); 8651 if ( $.fn.button ) { 8652 button.button(); 8653 } 8654 }); 8655 this.uiDialog.addClass( "ui-dialog-buttons" ); 8656 this.uiDialogButtonPane.appendTo( this.uiDialog ); 8657 } else { 8658 this.uiDialog.removeClass( "ui-dialog-buttons" ); 8659 } 8660 }, 8661 8662 _makeDraggable: function() { 8663 var that = this, 8664 options = this.options; 8665 8666 function filteredUi( ui ) { 8667 return { 8668 position: ui.position, 8669 offset: ui.offset 8670 }; 8671 } 8672 8673 this.uiDialog.draggable({ 8674 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 8675 handle: ".ui-dialog-titlebar", 8676 containment: "document", 8677 start: function( event, ui ) { 8678 $( this ) 8679 .addClass( "ui-dialog-dragging" ); 8680 that._trigger( "dragStart", event, filteredUi( ui ) ); 8681 }, 8682 drag: function( event, ui ) { 8683 that._trigger( "drag", event, filteredUi( ui ) ); 8684 }, 8685 stop: function( event, ui ) { 8686 options.position = [ 8687 ui.position.left - that.document.scrollLeft(), 8688 ui.position.top - that.document.scrollTop() 8689 ]; 8690 $( this ) 8691 .removeClass( "ui-dialog-dragging" ); 8692 that._trigger( "dragStop", event, filteredUi( ui ) ); 8693 $.ui.dialog.overlay.resize(); 8694 } 8695 }); 8696 }, 8697 8698 _makeResizable: function( handles ) { 8699 handles = (handles === undefined ? this.options.resizable : handles); 8700 var that = this, 8701 options = this.options, 8702 // .ui-resizable has position: relative defined in the stylesheet 8703 // but dialogs have to use absolute or fixed positioning 8704 position = this.uiDialog.css( "position" ), 8705 resizeHandles = typeof handles === 'string' ? 8706 handles : 8707 "n,e,s,w,se,sw,ne,nw"; 8708 8709 function filteredUi( ui ) { 8710 return { 8711 originalPosition: ui.originalPosition, 8712 originalSize: ui.originalSize, 8713 position: ui.position, 8714 size: ui.size 8715 }; 8716 } 8717 8718 this.uiDialog.resizable({ 8719 cancel: ".ui-dialog-content", 8720 containment: "document", 8721 alsoResize: this.element, 8722 maxWidth: options.maxWidth, 8723 maxHeight: options.maxHeight, 8724 minWidth: options.minWidth, 8725 minHeight: this._minHeight(), 8726 handles: resizeHandles, 8727 start: function( event, ui ) { 8728 $( this ).addClass( "ui-dialog-resizing" ); 8729 that._trigger( "resizeStart", event, filteredUi( ui ) ); 8730 }, 8731 resize: function( event, ui ) { 8732 that._trigger( "resize", event, filteredUi( ui ) ); 8733 }, 8734 stop: function( event, ui ) { 8735 $( this ).removeClass( "ui-dialog-resizing" ); 8736 options.height = $( this ).height(); 8737 options.width = $( this ).width(); 8738 that._trigger( "resizeStop", event, filteredUi( ui ) ); 8739 $.ui.dialog.overlay.resize(); 8740 } 8741 }) 8742 .css( "position", position ) 8743 .find( ".ui-resizable-se" ) 8744 .addClass( "ui-icon ui-icon-grip-diagonal-se" ); 8745 }, 8746 8747 _minHeight: function() { 8748 var options = this.options; 8749 8750 if ( options.height === "auto" ) { 8751 return options.minHeight; 8752 } else { 8753 return Math.min( options.minHeight, options.height ); 8754 } 8755 }, 8756 8757 _position: function( position ) { 8758 var myAt = [], 8759 offset = [ 0, 0 ], 8760 isVisible; 8761 8762 if ( position ) { 8763 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( 8764 // if (typeof position == 'string' || $.isArray(position)) { 8765 // myAt = $.isArray(position) ? position : position.split(' '); 8766 8767 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 8768 myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; 8769 if ( myAt.length === 1 ) { 8770 myAt[ 1 ] = myAt[ 0 ]; 8771 } 8772 8773 $.each( [ "left", "top" ], function( i, offsetPosition ) { 8774 if ( +myAt[ i ] === myAt[ i ] ) { 8775 offset[ i ] = myAt[ i ]; 8776 myAt[ i ] = offsetPosition; 8777 } 8778 }); 8779 8780 position = { 8781 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 8782 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 8783 at: myAt.join( " " ) 8784 }; 8785 } 8786 8787 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 8788 } else { 8789 position = $.ui.dialog.prototype.options.position; 8790 } 8791 8792 // need to show the dialog to get the actual offset in the position plugin 8793 isVisible = this.uiDialog.is( ":visible" ); 8794 if ( !isVisible ) { 8795 this.uiDialog.show(); 8796 } 8797 this.uiDialog.position( position ); 8798 if ( !isVisible ) { 8799 this.uiDialog.hide(); 8800 } 8801 }, 8802 8803 _setOptions: function( options ) { 8804 var that = this, 8805 resizableOptions = {}, 8806 resize = false;
8807 8808 $.each( options, function( key, value ) { 8809 that._setOption( key, value ); 8810 8811 if ( key in sizeRelatedOptions ) { 8812 resize = true; 8813 } 8814 if ( key in resizableRelatedOptions ) { 8815 resizableOptions[ key ] = value; 8816 } 8817 }); 8818 8819 if ( resize ) { 8820 this._size(); 8821 } 8822 if ( this.uiDialog.is( ":data(resizable)" ) ) { 8823 this.uiDialog.resizable( "option", resizableOptions ); 8824 } 8825 }, 8826 8827 _setOption: function( key, value ) { 8828 var isDraggable, isResizable, 8829 uiDialog = this.uiDialog; 8830 8831 switch ( key ) { 8832 case "buttons": 8833 this._createButtons( value ); 8834 break; 8835 case "closeText": 8836 // ensure that we always pass a string 8837 this.uiDialogTitlebarCloseText.text( "" + value ); 8838 break; 8839 case "dialogClass": 8840 uiDialog 8841 .removeClass( this.options.dialogClass ) 8842 .addClass( uiDialogClasses + value ); 8843 break; 8844 case "disabled": 8845 if ( value ) { 8846 uiDialog.addClass( "ui-dialog-disabled" ); 8847 } else { 8848 uiDialog.removeClass( "ui-dialog-disabled" ); 8849 } 8850 break; 8851 case "draggable": 8852 isDraggable = uiDialog.is( ":data(draggable)" ); 8853 if ( isDraggable && !value ) { 8854 uiDialog.draggable( "destroy" ); 8855 } 8856 8857 if ( !isDraggable && value ) { 8858 this._makeDraggable(); 8859 } 8860 break; 8861 case "position": 8862 this._position( value ); 8863 break; 8864 case "resizable": 8865 // currently resizable, becoming non-resizable 8866 isResizable = uiDialog.is( ":data(resizable)" ); 8867 if ( isResizable && !value ) { 8868 uiDialog.resizable( "destroy" ); 8869 } 8870 8871 // currently resizable, changing handles 8872 if ( isResizable && typeof value === "string" ) { 8873 uiDialog.resizable( "option", "handles", value ); 8874 } 8875 8876 // currently non-resizable, becoming resizable 8877 if ( !isResizable && value !== false ) { 8878 this._makeResizable( value ); 8879 } 8880 break; 8881 case "title": 8882 // convert whatever was passed in o a string, for html() to not throw up 8883 $( ".ui-dialog-title", this.uiDialogTitlebar ) 8884 .html( "" + ( value || " " ) ); 8885 break; 8886 } 8887 8888 this._super( key, value ); 8889 }, 8890 8891 _size: function() { 8892 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 8893 * divs will both have width and height set, so we need to reset them 8894 */ 8895 var nonContentHeight, minContentHeight, autoHeight, 8896 options = this.options, 8897 isVisible = this.uiDialog.is( ":visible" ); 8898 8899 // reset content sizing 8900 this.element.show().css({ 8901 width: "auto", 8902 minHeight: 0, 8903 height: 0 8904 }); 8905 8906 if ( options.minWidth > options.width ) { 8907 options.width = options.minWidth; 8908 } 8909 8910 // reset wrapper sizing 8911 // determine the height of all the non-content elements 8912 nonContentHeight = this.uiDialog.css({ 8913 height: "auto", 8914 width: options.width 8915 }) 8916 .outerHeight(); 8917 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 8918 8919 if ( options.height === "auto" ) { 8920 // only needed for IE6 support 8921 if ( $.support.minHeight ) { 8922 this.element.css({ 8923 minHeight: minContentHeight, 8924 height: "auto" 8925 }); 8926 } else { 8927 this.uiDialog.show(); 8928 autoHeight = this.element.css( "height", "auto" ).height(); 8929 if ( !isVisible ) { 8930 this.uiDialog.hide(); 8931 } 8932 this.element.height( Math.max( autoHeight, minContentHeight ) ); 8933 } 8934 } else { 8935 this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); 8936 } 8937 8938 if (this.uiDialog.is( ":data(resizable)" ) ) { 8939 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 8940 } 8941 } 8942}); 8943 8944$.extend($.ui.dialog, { 8945 uuid: 0, 8946 maxZ: 0, 8947 8948 getTitleId: function($el) { 8949 var id = $el.attr( "id" ); 8950 if ( !id ) { 8951 this.uuid += 1; 8952 id = this.uuid; 8953 } 8954 return "ui-dialog-title-" + id; 8955 }, 8956 8957 overlay: function( dialog ) { 8958 this.$el = $.ui.dialog.overlay.create( dialog ); 8959 } 8960}); 8961 8962$.extend( $.ui.dialog.overlay, { 8963 instances: [], 8964 // reuse old instances due to IE memory leak with alpha transparency (see #5185) 8965 oldInstances: [], 8966 maxZ: 0, 8967 events: $.map( 8968 "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), 8969 function( event ) { 8970 return event + ".dialog-overlay"; 8971 } 8972 ).join( " " ), 8973 create: function( dialog ) { 8974 if ( this.instances.length === 0 ) { 8975 // prevent use of anchors and inputs 8976 // we use a setTimeout in case the overlay is created from an 8977 // event that we're going to be cancelling (see #2804) 8978 setTimeout(function() { 8979 // handle $(el).dialog().dialog('close') (see #4065) 8980 if ( $.ui.dialog.overlay.instances.length ) { 8981 $( document ).bind( $.ui.dialog.overlay.events, function( event ) { 8982 // stop events if the z-index of the target is < the z-index of the overlay 8983 // we cannot return true when we don't want to cancel the event (#3523) 8984 if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { 8985 return false;
8986 } 8987 }); 8988 } 8989 }, 1 ); 8990 8991 // handle window resize 8992 $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); 8993 } 8994 8995 var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); 8996 8997 // allow closing by pressing the escape key 8998 $( document ).bind( "keydown.dialog-overlay", function( event ) { 8999 var instances = $.ui.dialog.overlay.instances; 9000 // only react to the event if we're the top overlay 9001 if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && 9002 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9003 event.keyCode === $.ui.keyCode.ESCAPE ) { 9004 9005 dialog.close( event ); 9006 event.preventDefault(); 9007 } 9008 }); 9009 9010 $el.appendTo( document.body ).css({ 9011 width: this.width(), 9012 height: this.height() 9013 }); 9014 9015 if ( $.fn.bgiframe ) { 9016 $el.bgiframe(); 9017 } 9018 9019 this.instances.push( $el ); 9020 return $el; 9021 }, 9022 9023 destroy: function( $el ) { 9024 var indexOf = $.inArray( $el, this.instances ), 9025 maxZ = 0; 9026 9027 if ( indexOf !== -1 ) { 9028 this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); 9029 } 9030 9031 if ( this.instances.length === 0 ) { 9032 $( [ document, window ] ).unbind( ".dialog-overlay" ); 9033 } 9034 9035 $el.height( 0 ).width( 0 ).remove(); 9036 9037 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 9038 $.each( this.instances, function() { 9039 maxZ = Math.max( maxZ, this.css( "z-index" ) ); 9040 }); 9041 this.maxZ = maxZ; 9042 }, 9043 9044 height: function() { 9045 var scrollHeight, 9046 offsetHeight; 9047 // handle IE 9048 if ( $.ui.ie ) { 9049 scrollHeight = Math.max( 9050 document.documentElement.scrollHeight, 9051 document.body.scrollHeight 9052 ); 9053 offsetHeight = Math.max( 9054 document.documentElement.offsetHeight, 9055 document.body.offsetHeight 9056 ); 9057 9058 if ( scrollHeight < offsetHeight ) { 9059 return $( window ).height() + "px"; 9060 } else { 9061 return scrollHeight + "px"; 9062 } 9063 // handle "good" browsers 9064 } else { 9065 return $( document ).height() + "px"; 9066 } 9067 }, 9068 9069 width: function() { 9070 var scrollWidth, 9071 offsetWidth; 9072 // handle IE 9073 if ( $.ui.ie ) { 9074 scrollWidth = Math.max( 9075 document.documentElement.scrollWidth, 9076 document.body.scrollWidth 9077 ); 9078 offsetWidth = Math.max( 9079 document.documentElement.offsetWidth, 9080 document.body.offsetWidth 9081 ); 9082 9083 if ( scrollWidth < offsetWidth ) { 9084 return $( window ).width() + "px"; 9085 } else { 9086 return scrollWidth + "px"; 9087 } 9088 // handle "good" browsers 9089 } else { 9090 return $( document ).width() + "px"; 9091 } 9092 }, 9093 9094 resize: function() { 9095 /* If the dialog is draggable and the user drags it past the 9096 * right edge of the window, the document becomes wider so we 9097 * need to stretch the overlay. If the user then drags the 9098 * dialog back to the left, the document will become narrower, 9099 * so we need to shrink the overlay to the appropriate size. 9100 * This is handled by shrinking the overlay before setting it 9101 * to the full document size. 9102 */ 9103 var $overlays = $( [] ); 9104 $.each( $.ui.dialog.overlay.instances, function() { 9105 $overlays = $overlays.add( this ); 9106 }); 9107 9108 $overlays.css({ 9109 width: 0, 9110 height: 0 9111 }).css({ 9112 width: $.ui.dialog.overlay.width(), 9113 height: $.ui.dialog.overlay.height() 9114 }); 9115 } 9116}); 9117 9118$.extend( $.ui.dialog.overlay.prototype, { 9119 destroy: function() { 9120 $.ui.dialog.overlay.destroy( this.$el ); 9121 } 9122}); 9123 9124}( jQuery ) ); 9125(function( $, undefined ) { 9126 9127var mouseHandled = false; 9128 9129$.widget( "ui.menu", { 9130 version: "1.9.2", 9131 defaultElement: "<ul>", 9132 delay: 300, 9133 options: { 9134 icons: { 9135 submenu: "ui-icon-carat-1-e" 9136 }, 9137 menus: "ul", 9138 position: { 9139 my: "left top", 9140 at: "right top" 9141 }, 9142 role: "menu", 9143 9144 // callbacks 9145 blur: null, 9146 focus: null, 9147 select: null 9148 }, 9149 9150 _create: function() { 9151 this.activeMenu = this.element; 9152 this.element 9153 .uniqueId() 9154 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9155 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 9156 .attr({ 9157 role: this.options.role, 9158 tabIndex: 0 9159 }) 9160 // need to catch all clicks on disabled menu 9161 // not possible through _on 9162 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 9163 if ( this.options.disabled ) { 9164 event.preventDefault(); 9165 } 9166 }, this )); 9167 9168 if ( this.options.disabled ) { 9169 this.element 9170 .addClass( "ui-state-disabled" ) 9171 .attr( "aria-disabled", "true" ); 9172 } 9173 9174 this._on({ 9175 // Prevent focus from sticking to links inside menu after clicking 9176 // them (focus should always stay on UL during navigation). 9177 "mousedown .ui-menu-item > a": function( event ) { 9178 event.preventDefault(); 9179 }, 9180 "click .ui-state-disabled > a": function( event ) { 9181 event.preventDefault(); 9182 }, 9183 "click .ui-menu-item:has(a)": function( event ) { 9184 var target = $( event.target ).closest( ".ui-menu-item" ); 9185 if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { 9186 mouseHandled = true; 9187 9188 this.select( event ); 9189 // Open submenu on click 9190 if ( target.has( ".ui-menu" ).length ) { 9191 this.expand( event ); 9192 } else if ( !this.element.is( ":focus" ) ) { 9193 // Redirect focus to the menu 9194 this.element.trigger( "focus", [ true ] ); 9195 9196 // If the active item is on the top level, let it stay active. 9197 // Otherwise, blur the active item since it is no longer visible. 9198 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 9199 clearTimeout( this.timer ); 9200 } 9201 } 9202 } 9203 }, 9204 "mouseenter .ui-menu-item": function( event ) { 9205 var target = $( event.currentTarget ); 9206 // Remove ui-state-active class from siblings of the newly focused menu item 9207 // to avoid a jump caused by adjacent elements both having a class with a border 9208 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 9209 this.focus( event, target ); 9210 }, 9211 mouseleave: "collapseAll", 9212 "mouseleave .ui-menu": "collapseAll", 9213 focus: function( event, keepActiveItem ) { 9214 // If there's already an active item, keep it active 9215 // If not, activate the first item 9216 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 9217 9218 if ( !keepActiveItem ) { 9219 this.focus( event, item ); 9220 } 9221 }, 9222 blur: function( event ) { 9223 this._delay(function() { 9224 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 9225 this.collapseAll( event ); 9226 } 9227 }); 9228 }, 9229 keydown: "_keydown" 9230 }); 9231 9232 this.refresh(); 9233
vendor: 40,717 bytes, lines 9234-10778
9234 // Clicks outside of a menu collapse any open menus 9235 this._on( this.document, { 9236 click: function( event ) { 9237 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 9238 this.collapseAll( event ); 9239 } 9240 9241 // Reset the mouseHandled flag 9242 mouseHandled = false; 9243 } 9244 }); 9245 }, 9246 9247 _destroy: function() { 9248 // Destroy (sub)menus 9249 this.element 9250 .removeAttr( "aria-activedescendant" ) 9251 .find( ".ui-menu" ).andSelf() 9252 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 9253 .removeAttr( "role" ) 9254 .removeAttr( "tabIndex" ) 9255 .removeAttr( "aria-labelledby" ) 9256 .removeAttr( "aria-expanded" ) 9257 .removeAttr( "aria-hidden" ) 9258 .removeAttr( "aria-disabled" ) 9259 .removeUniqueId() 9260 .show(); 9261 9262 // Destroy menu items 9263 this.element.find( ".ui-menu-item" ) 9264 .removeClass( "ui-menu-item" ) 9265 .removeAttr( "role" ) 9266 .removeAttr( "aria-disabled" ) 9267 .children( "a" ) 9268 .removeUniqueId() 9269 .removeClass( "ui-corner-all ui-state-hover" ) 9270 .removeAttr( "tabIndex" ) 9271 .removeAttr( "role" ) 9272 .removeAttr( "aria-haspopup" ) 9273 .children().each( function() { 9274 var elem = $( this ); 9275 if ( elem.data( "ui-menu-submenu-carat" ) ) { 9276 elem.remove(); 9277 } 9278 }); 9279 9280 // Destroy menu dividers 9281 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 9282 }, 9283 9284 _keydown: function( event ) { 9285 var match, prev, character, skip, regex, 9286 preventDefault = true; 9287 9288 function escape( value ) { 9289 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 9290 } 9291 9292 switch ( event.keyCode ) { 9293 case $.ui.keyCode.PAGE_UP: 9294 this.previousPage( event ); 9295 break; 9296 case $.ui.keyCode.PAGE_DOWN: 9297 this.nextPage( event ); 9298 break; 9299 case $.ui.keyCode.HOME: 9300 this._move( "first", "first", event ); 9301 break; 9302 case $.ui.keyCode.END: 9303 this._move( "last", "last", event ); 9304 break; 9305 case $.ui.keyCode.UP: 9306 this.previous( event ); 9307 break; 9308 case $.ui.keyCode.DOWN: 9309 this.next( event ); 9310 break; 9311 case $.ui.keyCode.LEFT: 9312 this.collapse( event ); 9313 break; 9314 case $.ui.keyCode.RIGHT: 9315 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 9316 this.expand( event ); 9317 } 9318 break; 9319 case $.ui.keyCode.ENTER: 9320 case $.ui.keyCode.SPACE: 9321 this._activate( event ); 9322 break; 9323 case $.ui.keyCode.ESCAPE: 9324 this.collapse( event ); 9325 break; 9326 default: 9327 preventDefault = false; 9328 prev = this.previousFilter || ""; 9329 character = String.fromCharCode( event.keyCode ); 9330 skip = false; 9331 9332 clearTimeout( this.filterTimer ); 9333 9334 if ( character === prev ) { 9335 skip = true; 9336 } else { 9337 character = prev + character; 9338 } 9339 9340 regex = new RegExp( "^" + escape( character ), "i" ); 9341 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9342 return regex.test( $( this ).children( "a" ).text() ); 9343 }); 9344 match = skip && match.index( this.active.next() ) !== -1 ? 9345 this.active.nextAll( ".ui-menu-item" ) : 9346 match; 9347 9348 // If no matches on the current filter, reset to the last character pressed 9349 // to move down the menu to the first item that starts with that character 9350 if ( !match.length ) { 9351 character = String.fromCharCode( event.keyCode ); 9352 regex = new RegExp( "^" + escape( character ), "i" ); 9353 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9354 return regex.test( $( this ).children( "a" ).text() ); 9355 }); 9356 } 9357 9358 if ( match.length ) { 9359 this.focus( event, match ); 9360 if ( match.length > 1 ) { 9361 this.previousFilter = character; 9362 this.filterTimer = this._delay(function() { 9363 delete this.previousFilter; 9364 }, 1000 ); 9365 } else { 9366 delete this.previousFilter; 9367 } 9368 } else { 9369 delete this.previousFilter; 9370 } 9371 } 9372 9373 if ( preventDefault ) { 9374 event.preventDefault(); 9375 } 9376 }, 9377 9378 _activate: function( event ) { 9379 if ( !this.active.is( ".ui-state-disabled" ) ) { 9380 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 9381 this.expand( event ); 9382 } else { 9383 this.select( event ); 9384 } 9385 } 9386 }, 9387 9388 refresh: function() { 9389 var menus, 9390 icon = this.options.icons.submenu, 9391 submenus = this.element.find( this.options.menus ); 9392 9393 // Initialize nested menus 9394 submenus.filter( ":not(.ui-menu)" ) 9395 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9396 .hide() 9397 .attr({ 9398 role: this.options.role, 9399 "aria-hidden": "true", 9400 "aria-expanded": "false" 9401 }) 9402 .each(function() { 9403 var menu = $( this ), 9404 item = menu.prev( "a" ), 9405 submenuCarat = $( "<span>" ) 9406 .addClass( "ui-menu-icon ui-icon " + icon ) 9407 .data( "ui-menu-submenu-carat", true ); 9408 9409 item 9410 .attr( "aria-haspopup", "true" ) 9411 .prepend( submenuCarat ); 9412 menu.attr( "aria-labelledby", item.attr( "id" ) ); 9413 }); 9414 9415 menus = submenus.add( this.element ); 9416 9417 // Don't refresh list items that are already adapted 9418 menus.children( ":not(.ui-menu-item):has(a)" ) 9419 .addClass( "ui-menu-item" ) 9420 .attr( "role", "presentation" ) 9421 .children( "a" ) 9422 .uniqueId() 9423 .addClass( "ui-corner-all" ) 9424 .attr({ 9425 tabIndex: -1, 9426 role: this._itemRole() 9427 }); 9428 9429 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 9430 menus.children( ":not(.ui-menu-item)" ).each(function() { 9431 var item = $( this ); 9432 // hyphen, em dash, en dash 9433 if ( !/[^\-ââ\s]/.test( item.text() ) ) { 9434 item.addClass( "ui-widget-content ui-menu-divider" ); 9435 } 9436 }); 9437 9438 // Add aria-disabled attribute to any disabled menu item 9439 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 9440 9441 // If the active item has been removed, blur the menu 9442 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 9443 this.blur(); 9444 } 9445 }, 9446 9447 _itemRole: function() { 9448 return { 9449 menu: "menuitem", 9450 listbox: "option" 9451 }[ this.options.role ]; 9452 }, 9453 9454 focus: function( event, item ) { 9455 var nested, focused; 9456 this.blur( event, event && event.type === "focus" ); 9457 9458 this._scrollIntoView( item ); 9459 9460 this.active = item.first(); 9461 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 9462 // Only update aria-activedescendant if there's a role 9463 // otherwise we assume focus is managed elsewhere 9464 if ( this.options.role ) { 9465 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 9466 } 9467 9468 // Highlight active parent menu item, if any 9469 this.active 9470 .parent() 9471 .closest( ".ui-menu-item" ) 9472 .children( "a:first" ) 9473 .addClass( "ui-state-active" ); 9474 9475 if ( event && event.type === "keydown" ) { 9476 this._close(); 9477 } else { 9478 this.timer = this._delay(function() { 9479 this._close(); 9480 }, this.delay ); 9481 } 9482 9483 nested = item.children( ".ui-menu" ); 9484 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 9485 this._startOpening(nested); 9486 } 9487 this.activeMenu = item.parent(); 9488 9489 this._trigger( "focus", event, { item: item } ); 9490 }, 9491 9492 _scrollIntoView: function( item ) { 9493 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 9494 if ( this._hasScroll() ) { 9495 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 9496 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 9497 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 9498 scroll = this.activeMenu.scrollTop(); 9499 elementHeight = this.activeMenu.height(); 9500 itemHeight = item.height(); 9501 9502 if ( offset < 0 ) { 9503 this.activeMenu.scrollTop( scroll + offset ); 9504 } else if ( offset + itemHeight > elementHeight ) { 9505 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 9506 } 9507 } 9508 }, 9509 9510 blur: function( event, fromFocus ) { 9511 if ( !fromFocus ) { 9512 clearTimeout( this.timer ); 9513 } 9514 9515 if ( !this.active ) { 9516 return; 9517 } 9518 9519 this.active.children( "a" ).removeClass( "ui-state-focus" ); 9520 this.active = null; 9521 9522 this._trigger( "blur", event, { item: this.active } ); 9523 }, 9524 9525 _startOpening: function( submenu ) { 9526 clearTimeout( this.timer ); 9527 9528 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 9529 // shift in the submenu position when mousing over the carat icon 9530 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 9531 return; 9532 } 9533 9534 this.timer = this._delay(function() { 9535 this._close(); 9536 this._open( submenu ); 9537 }, this.delay ); 9538 }, 9539 9540 _open: function( submenu ) { 9541 var position = $.extend({ 9542 of: this.active 9543 }, this.options.position ); 9544 9545 clearTimeout( this.timer ); 9546 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 9547 .hide() 9548 .attr( "aria-hidden", "true" ); 9549 9550 submenu 9551 .show() 9552 .removeAttr( "aria-hidden" ) 9553 .attr( "aria-expanded", "true" ) 9554 .position( position ); 9555 }, 9556 9557 collapseAll: function( event, all ) { 9558 clearTimeout( this.timer ); 9559 this.timer = this._delay(function() { 9560 // If we were passed an event, look for the submenu that contains the event 9561 var currentMenu = all ? this.element : 9562 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 9563 9564 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 9565 if ( !currentMenu.length ) { 9566 currentMenu = this.element; 9567 } 9568 9569 this._close( currentMenu ); 9570 9571 this.blur( event ); 9572 this.activeMenu = currentMenu; 9573 }, this.delay ); 9574 }, 9575 9576 // With no arguments, closes the currently active menu - if nothing is active 9577 // it closes all menus. If passed an argument, it will search for menus BELOW 9578 _close: function( startMenu ) { 9579 if ( !startMenu ) { 9580 startMenu = this.active ? this.active.parent() : this.element; 9581 } 9582 9583 startMenu 9584 .find( ".ui-menu" ) 9585 .hide() 9586 .attr( "aria-hidden", "true" ) 9587 .attr( "aria-expanded", "false" ) 9588 .end() 9589 .find( "a.ui-state-active" ) 9590 .removeClass( "ui-state-active" ); 9591 }, 9592 9593 collapse: function( event ) { 9594 var newItem = this.active && 9595 this.active.parent().closest( ".ui-menu-item", this.element ); 9596 if ( newItem && newItem.length ) { 9597 this._close(); 9598 this.focus( event, newItem ); 9599 } 9600 }, 9601 9602 expand: function( event ) { 9603 var newItem = this.active && 9604 this.active 9605 .children( ".ui-menu " ) 9606 .children( ".ui-menu-item" ) 9607 .first(); 9608 9609 if ( newItem && newItem.length ) { 9610 this._open( newItem.parent() ); 9611 9612 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 9613 this._delay(function() { 9614 this.focus( event, newItem ); 9615 }); 9616 } 9617 }, 9618 9619 next: function( event ) { 9620 this._move( "next", "first", event ); 9621 }, 9622 9623 previous: function( event ) { 9624 this._move( "prev", "last", event ); 9625 }, 9626 9627 isFirstItem: function() { 9628 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 9629 }, 9630 9631 isLastItem: function() { 9632 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 9633 }, 9634 9635 _move: function( direction, filter, event ) { 9636 var next; 9637 if ( this.active ) { 9638 if ( direction === "first" || direction === "last" ) { 9639 next = this.active 9640 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 9641 .eq( -1 ); 9642 } else { 9643 next = this.active 9644 [ direction + "All" ]( ".ui-menu-item" ) 9645 .eq( 0 ); 9646 } 9647 } 9648 if ( !next || !next.length || !this.active ) { 9649 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 9650 } 9651 9652 this.focus( event, next ); 9653 }, 9654 9655 nextPage: function( event ) { 9656 var item, base, height; 9657 9658 if ( !this.active ) { 9659 this.next( event ); 9660 return; 9661 } 9662 if ( this.isLastItem() ) { 9663 return; 9664 } 9665 if ( this._hasScroll() ) { 9666 base = this.active.offset().top; 9667 height = this.element.height(); 9668 this.active.nextAll( ".ui-menu-item" ).each(function() { 9669 item = $( this ); 9670 return item.offset().top - base - height < 0; 9671 }); 9672 9673 this.focus( event, item ); 9674 } else { 9675 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 9676 [ !this.active ? "first" : "last" ]() ); 9677 } 9678 }, 9679 9680 previousPage: function( event ) { 9681 var item, base, height; 9682 if ( !this.active ) { 9683 this.next( event ); 9684 return; 9685 } 9686 if ( this.isFirstItem() ) { 9687 return; 9688 } 9689 if ( this._hasScroll() ) { 9690 base = this.active.offset().top; 9691 height = this.element.height(); 9692 this.active.prevAll( ".ui-menu-item" ).each(function() { 9693 item = $( this ); 9694 return item.offset().top - base + height > 0; 9695 }); 9696 9697 this.focus( event, item ); 9698 } else { 9699 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 9700 } 9701 }, 9702 9703 _hasScroll: function() { 9704 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 9705 }, 9706 9707 select: function( event ) { 9708 // TODO: It should never be possible to not have an active item at this 9709 // point, but the tests don't trigger mouseenter before click. 9710 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 9711 var ui = { item: this.active }; 9712 if ( !this.active.has( ".ui-menu" ).length ) { 9713 this.collapseAll( event, true ); 9714 } 9715 this._trigger( "select", event, ui ); 9716 } 9717}); 9718 9719}( jQuery )); 9720(function( $, undefined ) { 9721 9722$.widget( "ui.progressbar", { 9723 version: "1.9.2", 9724 options: { 9725 value: 0, 9726 max: 100 9727 }, 9728 9729 min: 0, 9730 9731 _create: function() { 9732 this.element 9733 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 9734 .attr({ 9735 role: "progressbar", 9736 "aria-valuemin": this.min, 9737 "aria-valuemax": this.options.max, 9738 "aria-valuenow": this._value() 9739 }); 9740 9741 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 9742 .appendTo( this.element ); 9743 9744 this.oldValue = this._value(); 9745 this._refreshValue(); 9746 }, 9747 9748 _destroy: function() { 9749 this.element 9750 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 9751 .removeAttr( "role" ) 9752 .removeAttr( "aria-valuemin" ) 9753 .removeAttr( "aria-valuemax" ) 9754 .removeAttr( "aria-valuenow" ); 9755 9756 this.valueDiv.remove(); 9757 }, 9758 9759 value: function( newValue ) { 9760 if ( newValue === undefined ) { 9761 return this._value(); 9762 } 9763 9764 this._setOption( "value", newValue ); 9765 return this; 9766 }, 9767 9768 _setOption: function( key, value ) { 9769 if ( key === "value" ) { 9770 this.options.value = value; 9771 this._refreshValue(); 9772 if ( this._value() === this.options.max ) { 9773 this._trigger( "complete" ); 9774 } 9775 } 9776 9777 this._super( key, value ); 9778 }, 9779 9780 _value: function() { 9781 var val = this.options.value; 9782 // normalize invalid value 9783 if ( typeof val !== "number" ) { 9784 val = 0; 9785 } 9786 return Math.min( this.options.max, Math.max( this.min, val ) ); 9787 }, 9788 9789 _percentage: function() { 9790 return 100 * this._value() / this.options.max; 9791 }, 9792 9793 _refreshValue: function() { 9794 var value = this.value(), 9795 percentage = this._percentage(); 9796 9797 if ( this.oldValue !== value ) { 9798 this.oldValue = value; 9799 this._trigger( "change" ); 9800 } 9801 9802 this.valueDiv 9803 .toggle( value > this.min ) 9804 .toggleClass( "ui-corner-right", value === this.options.max ) 9805 .width( percentage.toFixed(0) + "%" ); 9806 this.element.attr( "aria-valuenow", value ); 9807 } 9808}); 9809 9810})( jQuery ); 9811(function( $, undefined ) { 9812 9813// number of pages in a slider 9814// (how many times can you page up/down to go through the whole range) 9815var numPages = 5; 9816 9817$.widget( "ui.slider", $.ui.mouse, { 9818 version: "1.9.2", 9819 widgetEventPrefix: "slide", 9820 9821 options: { 9822 animate: false, 9823 distance: 0, 9824 max: 100, 9825 min: 0, 9826 orientation: "horizontal", 9827 range: false, 9828 step: 1, 9829 value: 0, 9830 values: null 9831 }, 9832 9833 _create: function() { 9834 var i, handleCount, 9835 o = this.options, 9836 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 9837 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 9838 handles = []; 9839 9840 this._keySliding = false; 9841 this._mouseSliding = false; 9842 this._animateOff = true; 9843 this._handleIndex = null; 9844 this._detectOrientation(); 9845 this._mouseInit(); 9846 9847 this.element 9848 .addClass( "ui-slider" + 9849 " ui-slider-" + this.orientation + 9850 " ui-widget" + 9851 " ui-widget-content" + 9852 " ui-corner-all" + 9853 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); 9854 9855 this.range = $([]); 9856 9857 if ( o.range ) { 9858 if ( o.range === true ) { 9859 if ( !o.values ) { 9860 o.values = [ this._valueMin(), this._valueMin() ]; 9861 } 9862 if ( o.values.length && o.values.length !== 2 ) { 9863 o.values = [ o.values[0], o.values[0] ]; 9864 } 9865 } 9866 9867 this.range = $( "<div></div>" ) 9868 .appendTo( this.element ) 9869 .addClass( "ui-slider-range" + 9870 // note: this isn't the most fittingly semantic framework class for this element, 9871 // but worked best visually with a variety of themes 9872 " ui-widget-header" + 9873 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); 9874 } 9875 9876 handleCount = ( o.values && o.values.length ) || 1; 9877 9878 for ( i = existingHandles.length; i < handleCount; i++ ) { 9879 handles.push( handle ); 9880 } 9881 9882 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 9883 9884 this.handle = this.handles.eq( 0 ); 9885 9886 this.handles.add( this.range ).filter( "a" ) 9887 .click(function( event ) { 9888 event.preventDefault(); 9889 }) 9890 .mouseenter(function() { 9891 if ( !o.disabled ) { 9892 $( this ).addClass( "ui-state-hover" ); 9893 } 9894 }) 9895 .mouseleave(function() { 9896 $( this ).removeClass( "ui-state-hover" ); 9897 }) 9898 .focus(function() { 9899 if ( !o.disabled ) { 9900 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); 9901 $( this ).addClass( "ui-state-focus" ); 9902 } else { 9903 $( this ).blur(); 9904 } 9905 }) 9906 .blur(function() { 9907 $( this ).removeClass( "ui-state-focus" ); 9908 }); 9909 9910 this.handles.each(function( i ) { 9911 $( this ).data( "ui-slider-handle-index", i ); 9912 }); 9913 9914 this._on( this.handles, { 9915 keydown: function( event ) { 9916 var allowed, curVal, newVal, step, 9917 index = $( event.target ).data( "ui-slider-handle-index" ); 9918 9919 switch ( event.keyCode ) { 9920 case $.ui.keyCode.HOME: 9921 case $.ui.keyCode.END: 9922 case $.ui.keyCode.PAGE_UP: 9923 case $.ui.keyCode.PAGE_DOWN: 9924 case $.ui.keyCode.UP: 9925 case $.ui.keyCode.RIGHT: 9926 case $.ui.keyCode.DOWN: 9927 case $.ui.keyCode.LEFT: 9928 event.preventDefault(); 9929 if ( !this._keySliding ) { 9930 this._keySliding = true; 9931 $( event.target ).addClass( "ui-state-active" ); 9932 allowed = this._start( event, index ); 9933 if ( allowed === false ) { 9934 return; 9935 } 9936 } 9937 break; 9938 } 9939 9940 step = this.options.step; 9941 if ( this.options.values && this.options.values.length ) { 9942 curVal = newVal = this.values( index ); 9943 } else { 9944 curVal = newVal = this.value(); 9945 } 9946 9947 switch ( event.keyCode ) { 9948 case $.ui.keyCode.HOME: 9949 newVal = this._valueMin(); 9950 break; 9951 case $.ui.keyCode.END: 9952 newVal = this._valueMax(); 9953 break; 9954 case $.ui.keyCode.PAGE_UP: 9955 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 9956 break; 9957 case $.ui.keyCode.PAGE_DOWN: 9958 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 9959 break; 9960 case $.ui.keyCode.UP: 9961 case $.ui.keyCode.RIGHT: 9962 if ( curVal === this._valueMax() ) { 9963 return; 9964 } 9965 newVal = this._trimAlignValue( curVal + step ); 9966 break; 9967 case $.ui.keyCode.DOWN: 9968 case $.ui.keyCode.LEFT: 9969 if ( curVal === this._valueMin() ) { 9970 return; 9971 } 9972 newVal = this._trimAlignValue( curVal - step ); 9973 break; 9974 } 9975 9976 this._slide( event, index, newVal ); 9977 }, 9978 keyup: function( event ) { 9979 var index = $( event.target ).data( "ui-slider-handle-index" ); 9980 9981 if ( this._keySliding ) { 9982 this._keySliding = false; 9983 this._stop( event, index ); 9984 this._change( event, index ); 9985 $( event.target ).removeClass( "ui-state-active" ); 9986 } 9987 } 9988 }); 9989 9990 this._refreshValue(); 9991 9992 this._animateOff = false; 9993 }, 9994 9995 _destroy: function() { 9996 this.handles.remove(); 9997 this.range.remove(); 9998 9999 this.element 10000 .removeClass( "ui-slider" + 10001 " ui-slider-horizontal" + 10002 " ui-slider-vertical" + 10003 " ui-slider-disabled" + 10004 " ui-widget" + 10005 " ui-widget-content" + 10006 " ui-corner-all" ); 10007 10008 this._mouseDestroy(); 10009 }, 10010 10011 _mouseCapture: function( event ) { 10012 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 10013 that = this, 10014 o = this.options; 10015 10016 if ( o.disabled ) { 10017 return false; 10018 } 10019 10020 this.elementSize = { 10021 width: this.element.outerWidth(), 10022 height: this.element.outerHeight() 10023 }; 10024 this.elementOffset = this.element.offset(); 10025 10026 position = { x: event.pageX, y: event.pageY }; 10027 normValue = this._normValueFromMouse( position ); 10028 distance = this._valueMax() - this._valueMin() + 1; 10029 this.handles.each(function( i ) { 10030 var thisDistance = Math.abs( normValue - that.values(i) ); 10031 if ( distance > thisDistance ) { 10032 distance = thisDistance; 10033 closestHandle = $( this ); 10034 index = i; 10035 } 10036 }); 10037 10038 // workaround for bug #3736 (if both handles of a range are at 0, 10039 // the first is always used as the one with least distance, 10040 // and moving it is obviously prevented by preventing negative ranges) 10041 if( o.range === true && this.values(1) === o.min ) { 10042 index += 1; 10043 closestHandle = $( this.handles[index] ); 10044 } 10045 10046 allowed = this._start( event, index ); 10047 if ( allowed === false ) { 10048 return false; 10049 } 10050 this._mouseSliding = true; 10051 10052 this._handleIndex = index; 10053 10054 closestHandle 10055 .addClass( "ui-state-active" ) 10056 .focus(); 10057 10058 offset = closestHandle.offset(); 10059 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); 10060 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 10061 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 10062 top: event.pageY - offset.top - 10063 ( closestHandle.height() / 2 ) - 10064 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 10065 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 10066 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 10067 }; 10068 10069 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 10070 this._slide( event, index, normValue ); 10071 } 10072 this._animateOff = true; 10073 return true; 10074 }, 10075 10076 _mouseStart: function() { 10077 return true; 10078 }, 10079 10080 _mouseDrag: function( event ) { 10081 var position = { x: event.pageX, y: event.pageY }, 10082 normValue = this._normValueFromMouse( position ); 10083 10084 this._slide( event, this._handleIndex, normValue ); 10085 10086 return false; 10087 }, 10088 10089 _mouseStop: function( event ) { 10090 this.handles.removeClass( "ui-state-active" ); 10091 this._mouseSliding = false; 10092 10093 this._stop( event, this._handleIndex ); 10094 this._change( event, this._handleIndex ); 10095 10096 this._handleIndex = null; 10097 this._clickOffset = null; 10098 this._animateOff = false; 10099 10100 return false; 10101 }, 10102 10103 _detectOrientation: function() { 10104 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 10105 }, 10106 10107 _normValueFromMouse: function( position ) { 10108 var pixelTotal, 10109 pixelMouse, 10110 percentMouse, 10111 valueTotal, 10112 valueMouse; 10113 10114 if ( this.orientation === "horizontal" ) { 10115 pixelTotal = this.elementSize.width; 10116 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 10117 } else { 10118 pixelTotal = this.elementSize.height; 10119 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 10120 } 10121 10122 percentMouse = ( pixelMouse / pixelTotal ); 10123 if ( percentMouse > 1 ) { 10124 percentMouse = 1; 10125 } 10126 if ( percentMouse < 0 ) { 10127 percentMouse = 0; 10128 } 10129 if ( this.orientation === "vertical" ) { 10130 percentMouse = 1 - percentMouse; 10131 } 10132 10133 valueTotal = this._valueMax() - this._valueMin(); 10134 valueMouse = this._valueMin() + percentMouse * valueTotal; 10135 10136 return this._trimAlignValue( valueMouse ); 10137 }, 10138 10139 _start: function( event, index ) { 10140 var uiHash = { 10141 handle: this.handles[ index ], 10142 value: this.value() 10143 }; 10144 if ( this.options.values && this.options.values.length ) { 10145 uiHash.value = this.values( index ); 10146 uiHash.values = this.values(); 10147 } 10148 return this._trigger( "start", event, uiHash ); 10149 }, 10150 10151 _slide: function( event, index, newVal ) { 10152 var otherVal, 10153 newValues, 10154 allowed; 10155 10156 if ( this.options.values && this.options.values.length ) { 10157 otherVal = this.values( index ? 0 : 1 ); 10158 10159 if ( ( this.options.values.length === 2 && this.options.range === true ) && 10160 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 10161 ) { 10162 newVal = otherVal; 10163 } 10164 10165 if ( newVal !== this.values( index ) ) { 10166 newValues = this.values(); 10167 newValues[ index ] = newVal; 10168 // A slide can be canceled by returning false from the slide callback 10169 allowed = this._trigger( "slide", event, { 10170 handle: this.handles[ index ], 10171 value: newVal, 10172 values: newValues 10173 } ); 10174 otherVal = this.values( index ? 0 : 1 ); 10175 if ( allowed !== false ) { 10176 this.values( index, newVal, true ); 10177 } 10178 } 10179 } else { 10180 if ( newVal !== this.value() ) { 10181 // A slide can be canceled by returning false from the slide callback 10182 allowed = this._trigger( "slide", event, { 10183 handle: this.handles[ index ], 10184 value: newVal 10185 } ); 10186 if ( allowed !== false ) { 10187 this.value( newVal ); 10188 } 10189 } 10190 } 10191 }, 10192 10193 _stop: function( event, index ) { 10194 var uiHash = { 10195 handle: this.handles[ index ], 10196 value: this.value() 10197 }; 10198 if ( this.options.values && this.options.values.length ) { 10199 uiHash.value = this.values( index ); 10200 uiHash.values = this.values(); 10201 } 10202 10203 this._trigger( "stop", event, uiHash ); 10204 }, 10205 10206 _change: function( event, index ) { 10207 if ( !this._keySliding && !this._mouseSliding ) { 10208 var uiHash = { 10209 handle: this.handles[ index ], 10210 value: this.value() 10211 }; 10212 if ( this.options.values && this.options.values.length ) { 10213 uiHash.value = this.values( index ); 10214 uiHash.values = this.values(); 10215 } 10216 10217 this._trigger( "change", event, uiHash ); 10218 } 10219 }, 10220 10221 value: function( newValue ) { 10222 if ( arguments.length ) { 10223 this.options.value = this._trimAlignValue( newValue ); 10224 this._refreshValue(); 10225 this._change( null, 0 ); 10226 return; 10227 } 10228 10229 return this._value(); 10230 }, 10231 10232 values: function( index, newValue ) { 10233 var vals, 10234 newValues, 10235 i; 10236 10237 if ( arguments.length > 1 ) { 10238 this.options.values[ index ] = this._trimAlignValue( newValue ); 10239 this._refreshValue(); 10240 this._change( null, index ); 10241 return; 10242 } 10243 10244 if ( arguments.length ) { 10245 if ( $.isArray( arguments[ 0 ] ) ) { 10246 vals = this.options.values; 10247 newValues = arguments[ 0 ]; 10248 for ( i = 0; i < vals.length; i += 1 ) { 10249 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 10250 this._change( null, i ); 10251 } 10252 this._refreshValue(); 10253 } else { 10254 if ( this.options.values && this.options.values.length ) { 10255 return this._values( index ); 10256 } else { 10257 return this.value(); 10258 } 10259 } 10260 } else { 10261 return this._values(); 10262 } 10263 }, 10264 10265 _setOption: function( key, value ) { 10266 var i, 10267 valsLength = 0; 10268 10269 if ( $.isArray( this.options.values ) ) { 10270 valsLength = this.options.values.length; 10271 } 10272 10273 $.Widget.prototype._setOption.apply( this, arguments ); 10274 10275 switch ( key ) { 10276 case "disabled": 10277 if ( value ) { 10278 this.handles.filter( ".ui-state-focus" ).blur(); 10279 this.handles.removeClass( "ui-state-hover" ); 10280 this.handles.prop( "disabled", true ); 10281 this.element.addClass( "ui-disabled" ); 10282 } else { 10283 this.handles.prop( "disabled", false ); 10284 this.element.removeClass( "ui-disabled" ); 10285 } 10286 break; 10287 case "orientation": 10288 this._detectOrientation(); 10289 this.element 10290 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 10291 .addClass( "ui-slider-" + this.orientation ); 10292 this._refreshValue(); 10293 break; 10294 case "value": 10295 this._animateOff = true; 10296 this._refreshValue(); 10297 this._change( null, 0 ); 10298 this._animateOff = false; 10299 break; 10300 case "values": 10301 this._animateOff = true; 10302 this._refreshValue(); 10303 for ( i = 0; i < valsLength; i += 1 ) { 10304 this._change( null, i ); 10305 } 10306 this._animateOff = false; 10307 break; 10308 case "min": 10309 case "max": 10310 this._animateOff = true; 10311 this._refreshValue(); 10312 this._animateOff = false; 10313 break; 10314 } 10315 }, 10316 10317 //internal value getter 10318 // _value() returns value trimmed by min and max, aligned by step 10319 _value: function() { 10320 var val = this.options.value; 10321 val = this._trimAlignValue( val ); 10322 10323 return val; 10324 }, 10325 10326 //internal values getter 10327 // _values() returns array of values trimmed by min and max, aligned by step 10328 // _values( index ) returns single value trimmed by min and max, aligned by step 10329 _values: function( index ) { 10330 var val, 10331 vals, 10332 i; 10333 10334 if ( arguments.length ) { 10335 val = this.options.values[ index ]; 10336 val = this._trimAlignValue( val ); 10337 10338 return val; 10339 } else { 10340 // .slice() creates a copy of the array 10341 // this copy gets trimmed by min and max and then returned 10342 vals = this.options.values.slice(); 10343 for ( i = 0; i < vals.length; i+= 1) { 10344 vals[ i ] = this._trimAlignValue( vals[ i ] ); 10345 } 10346 10347 return vals; 10348 } 10349 }, 10350 10351 // returns the step-aligned value that val is closest to, between (inclusive) min and max 10352 _trimAlignValue: function( val ) { 10353 if ( val <= this._valueMin() ) { 10354 return this._valueMin(); 10355 } 10356 if ( val >= this._valueMax() ) { 10357 return this._valueMax(); 10358 } 10359 var step = ( this.options.step > 0 ) ? this.options.step : 1, 10360 valModStep = (val - this._valueMin()) % step, 10361 alignValue = val - valModStep; 10362 10363 if ( Math.abs(valModStep) * 2 >= step ) { 10364 alignValue += ( valModStep > 0 ) ? step : ( -step ); 10365 } 10366 10367 // Since JavaScript has problems with large floats, round 10368 // the final value to 5 digits after the decimal point (see #4124) 10369 return parseFloat( alignValue.toFixed(5) ); 10370 }, 10371 10372 _valueMin: function() { 10373 return this.options.min; 10374 }, 10375 10376 _valueMax: function() { 10377 return this.options.max; 10378 }, 10379 10380 _refreshValue: function() { 10381 var lastValPercent, valPercent, value, valueMin, valueMax, 10382 oRange = this.options.range, 10383 o = this.options, 10384 that = this, 10385 animate = ( !this._animateOff ) ? o.animate : false, 10386 _set = {}; 10387 10388 if ( this.options.values && this.options.values.length ) { 10389 this.handles.each(function( i ) { 10390 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 10391 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10392 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10393 if ( that.options.range === true ) { 10394 if ( that.orientation === "horizontal" ) { 10395 if ( i === 0 ) { 10396 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 10397 } 10398 if ( i === 1 ) { 10399 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10400 } 10401 } else { 10402 if ( i === 0 ) { 10403 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 10404 } 10405 if ( i === 1 ) { 10406 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10407 } 10408 } 10409 } 10410 lastValPercent = valPercent; 10411 }); 10412 } else { 10413 value = this.value(); 10414 valueMin = this._valueMin(); 10415 valueMax = this._valueMax(); 10416 valPercent = ( valueMax !== valueMin ) ? 10417 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 10418 0; 10419 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10420 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10421 10422 if ( oRange === "min" && this.orientation === "horizontal" ) { 10423 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 10424 } 10425 if ( oRange === "max" && this.orientation === "horizontal" ) { 10426 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10427 } 10428 if ( oRange === "min" && this.orientation === "vertical" ) { 10429 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 10430 } 10431 if ( oRange === "max" && this.orientation === "vertical" ) { 10432 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10433 } 10434 } 10435 } 10436 10437}); 10438 10439}(jQuery)); 10440(function( $ ) { 10441 10442function modifier( fn ) { 10443 return function() { 10444 var previous = this.element.val(); 10445 fn.apply( this, arguments ); 10446 this._refresh(); 10447 if ( previous !== this.element.val() ) { 10448 this._trigger( "change" ); 10449 } 10450 }; 10451} 10452 10453$.widget( "ui.spinner", { 10454 version: "1.9.2", 10455 defaultElement: "<input>", 10456 widgetEventPrefix: "spin", 10457 options: { 10458 culture: null, 10459 icons: { 10460 down: "ui-icon-triangle-1-s", 10461 up: "ui-icon-triangle-1-n" 10462 }, 10463 incremental: true, 10464 max: null, 10465 min: null, 10466 numberFormat: null, 10467 page: 10, 10468 step: 1, 10469 10470 change: null, 10471 spin: null, 10472 start: null, 10473 stop: null 10474 }, 10475 10476 _create: function() { 10477 // handle string values that need to be parsed 10478 this._setOption( "max", this.options.max ); 10479 this._setOption( "min", this.options.min ); 10480 this._setOption( "step", this.options.step ); 10481 10482 // format the value, but don't constrain 10483 this._value( this.element.val(), true ); 10484 10485 this._draw(); 10486 this._on( this._events ); 10487 this._refresh(); 10488 10489 // turning off autocomplete prevents the browser from remembering the 10490 // value when navigating through history, so we re-enable autocomplete 10491 // if the page is unloaded before the widget is destroyed. #7790 10492 this._on( this.window, { 10493 beforeunload: function() { 10494 this.element.removeAttr( "autocomplete" ); 10495 } 10496 }); 10497 }, 10498 10499 _getCreateOptions: function() { 10500 var options = {}, 10501 element = this.element; 10502 10503 $.each( [ "min", "max", "step" ], function( i, option ) { 10504 var value = element.attr( option ); 10505 if ( value !== undefined && value.length ) { 10506 options[ option ] = value; 10507 } 10508 }); 10509 10510 return options; 10511 }, 10512 10513 _events: { 10514 keydown: function( event ) { 10515 if ( this._start( event ) && this._keydown( event ) ) { 10516 event.preventDefault(); 10517 } 10518 }, 10519 keyup: "_stop", 10520 focus: function() { 10521 this.previous = this.element.val(); 10522 }, 10523 blur: function( event ) { 10524 if ( this.cancelBlur ) { 10525 delete this.cancelBlur; 10526 return; 10527 } 10528 10529 this._refresh(); 10530 if ( this.previous !== this.element.val() ) { 10531 this._trigger( "change", event ); 10532 } 10533 }, 10534 mousewheel: function( event, delta ) { 10535 if ( !delta ) { 10536 return; 10537 } 10538 if ( !this.spinning && !this._start( event ) ) { 10539 return false; 10540 } 10541 10542 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 10543 clearTimeout( this.mousewheelTimer ); 10544 this.mousewheelTimer = this._delay(function() { 10545 if ( this.spinning ) { 10546 this._stop( event ); 10547 } 10548 }, 100 ); 10549 event.preventDefault(); 10550 }, 10551 "mousedown .ui-spinner-button": function( event ) { 10552 var previous; 10553 10554 // We never want the buttons to have focus; whenever the user is 10555 // interacting with the spinner, the focus should be on the input. 10556 // If the input is focused then this.previous is properly set from 10557 // when the input first received focus. If the input is not focused 10558 // then we need to set this.previous based on the value before spinning. 10559 previous = this.element[0] === this.document[0].activeElement ? 10560 this.previous : this.element.val(); 10561 function checkFocus() { 10562 var isActive = this.element[0] === this.document[0].activeElement; 10563 if ( !isActive ) { 10564 this.element.focus(); 10565 this.previous = previous; 10566 // support: IE 10567 // IE sets focus asynchronously, so we need to check if focus 10568 // moved off of the input because the user clicked on the button. 10569 this._delay(function() { 10570 this.previous = previous; 10571 }); 10572 } 10573 } 10574 10575 // ensure focus is on (or stays on) the text field 10576 event.preventDefault(); 10577 checkFocus.call( this ); 10578 10579 // support: IE 10580 // IE doesn't prevent moving focus even with event.preventDefault() 10581 // so we set a flag to know when we should ignore the blur event 10582 // and check (again) if focus moved off of the input. 10583 this.cancelBlur = true; 10584 this._delay(function() { 10585 delete this.cancelBlur; 10586 checkFocus.call( this ); 10587 }); 10588 10589 if ( this._start( event ) === false ) { 10590 return; 10591 } 10592 10593 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 10594 }, 10595 "mouseup .ui-spinner-button": "_stop", 10596 "mouseenter .ui-spinner-button": function( event ) { 10597 // button will add ui-state-active if mouse was down while mouseleave and kept down 10598 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 10599 return; 10600 } 10601 10602 if ( this._start( event ) === false ) { 10603 return false; 10604 } 10605 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 10606 }, 10607 // TODO: do we really want to consider this a stop? 10608 // shouldn't we just stop the repeater and wait until mouseup before 10609 // we trigger the stop event? 10610 "mouseleave .ui-spinner-button": "_stop" 10611 }, 10612 10613 _draw: function() { 10614 var uiSpinner = this.uiSpinner = this.element 10615 .addClass( "ui-spinner-input" ) 10616 .attr( "autocomplete", "off" ) 10617 .wrap( this._uiSpinnerHtml() ) 10618 .parent() 10619 // add buttons 10620 .append( this._buttonHtml() ); 10621 10622 this.element.attr( "role", "spinbutton" ); 10623 10624 // button bindings 10625 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 10626 .attr( "tabIndex", -1 ) 10627 .button() 10628 .removeClass( "ui-corner-all" ); 10629 10630 // IE 6 doesn't understand height: 50% for the buttons 10631 // unless the wrapper has an explicit height 10632 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 10633 uiSpinner.height() > 0 ) { 10634 uiSpinner.height( uiSpinner.height() ); 10635 } 10636 10637 // disable spinner if element was already disabled 10638 if ( this.options.disabled ) { 10639 this.disable(); 10640 } 10641 }, 10642 10643 _keydown: function( event ) { 10644 var options = this.options, 10645 keyCode = $.ui.keyCode; 10646 10647 switch ( event.keyCode ) { 10648 case keyCode.UP: 10649 this._repeat( null, 1, event ); 10650 return true; 10651 case keyCode.DOWN: 10652 this._repeat( null, -1, event ); 10653 return true; 10654 case keyCode.PAGE_UP: 10655 this._repeat( null, options.page, event ); 10656 return true; 10657 case keyCode.PAGE_DOWN: 10658 this._repeat( null, -options.page, event ); 10659 return true; 10660 } 10661 10662 return false; 10663 }, 10664 10665 _uiSpinnerHtml: function() { 10666 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 10667 }, 10668 10669 _buttonHtml: function() { 10670 return "" + 10671 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 10672 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 10673 "</a>" + 10674 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 10675 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 10676 "</a>"; 10677 }, 10678 10679 _start: function( event ) { 10680 if ( !this.spinning && this._trigger( "start", event ) === false ) { 10681 return false; 10682 } 10683 10684 if ( !this.counter ) { 10685 this.counter = 1; 10686 } 10687 this.spinning = true; 10688 return true; 10689 }, 10690 10691 _repeat: function( i, steps, event ) { 10692 i = i || 500; 10693 10694 clearTimeout( this.timer ); 10695 this.timer = this._delay(function() { 10696 this._repeat( 40, steps, event ); 10697 }, i ); 10698 10699 this._spin( steps * this.options.step, event ); 10700 }, 10701 10702 _spin: function( step, event ) { 10703 var value = this.value() || 0; 10704 10705 if ( !this.counter ) { 10706 this.counter = 1; 10707 } 10708 10709 value = this._adjustValue( value + step * this._increment( this.counter ) ); 10710 10711 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 10712 this._value( value ); 10713 this.counter++; 10714 } 10715 }, 10716 10717 _increment: function( i ) { 10718 var incremental = this.options.incremental; 10719 10720 if ( incremental ) { 10721 return $.isFunction( incremental ) ? 10722 incremental( i ) : 10723 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 10724 } 10725 10726 return 1; 10727 }, 10728 10729 _precision: function() { 10730 var precision = this._precisionOf( this.options.step ); 10731 if ( this.options.min !== null ) { 10732 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 10733 } 10734 return precision; 10735 }, 10736 10737 _precisionOf: function( num ) { 10738 var str = num.toString(), 10739 decimal = str.indexOf( "." ); 10740 return decimal === -1 ? 0 : str.length - decimal - 1; 10741 }, 10742 10743 _adjustValue: function( value ) { 10744 var base, aboveMin, 10745 options = this.options; 10746 10747 // make sure we're at a valid step 10748 // - find out where we are relative to the base (min or 0) 10749 base = options.min !== null ? options.min : 0; 10750 aboveMin = value - base; 10751 // - round to the nearest step 10752 aboveMin = Math.round(aboveMin / options.step) * options.step; 10753 // - rounding is based on 0, so adjust back to our base 10754 value = base + aboveMin; 10755 10756 // fix precision from bad JS floating point math 10757 value = parseFloat( value.toFixed( this._precision() ) ); 10758 10759 // clamp the value 10760 if ( options.max !== null && value > options.max) { 10761 return options.max; 10762 } 10763 if ( options.min !== null && value < options.min ) { 10764 return options.min; 10765 } 10766 10767 return value; 10768 }, 10769 10770 _stop: function( event ) { 10771 if ( !this.spinning ) { 10772 return; 10773 } 10774 10775 clearTimeout( this.timer ); 10776 clearTimeout( this.mousewheelTimer ); 10777 this.counter = 0; 10778 this.spinning = false;
10779 this._trigger( "stop", event ); 10780 }, 10781 10782 _setOption: function( key, value ) { 10783 if ( key === "culture" || key === "numberFormat" ) { 10784 var prevValue = this._parse( this.element.val() ); 10785 this.options[ key ] = value; 10786 this.element.val( this._format( prevValue ) ); 10787 return; 10788 } 10789 10790 if ( key === "max" || key === "min" || key === "step" ) { 10791 if ( typeof value === "string" ) { 10792 value = this._parse( value ); 10793 } 10794 } 10795 10796 this._super( key, value ); 10797 10798 if ( key === "disabled" ) { 10799 if ( value ) { 10800 this.element.prop( "disabled", true ); 10801 this.buttons.button( "disable" ); 10802 } else { 10803 this.element.prop( "disabled", false ); 10804 this.buttons.button( "enable" ); 10805 } 10806 } 10807 }, 10808 10809 _setOptions: modifier(function( options ) { 10810 this._super( options ); 10811 this._value( this.element.val() ); 10812 }), 10813 10814 _parse: function( val ) { 10815 if ( typeof val === "string" && val !== "" ) { 10816 val = window.Globalize && this.options.numberFormat ? 10817 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 10818 } 10819 return val === "" || isNaN( val ) ? null : val; 10820 }, 10821 10822 _format: function( value ) { 10823 if ( value === "" ) { 10824 return ""; 10825 } 10826 return window.Globalize && this.options.numberFormat ? 10827 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 10828 value; 10829 }, 10830 10831 _refresh: function() { 10832 this.element.attr({ 10833 "aria-valuemin": this.options.min, 10834 "aria-valuemax": this.options.max, 10835 // TODO: what should we do with values that can't be parsed? 10836 "aria-valuenow": this._parse( this.element.val() ) 10837 }); 10838 }, 10839 10840 // update the value without triggering change 10841 _value: function( value, allowAny ) { 10842 var parsed; 10843 if ( value !== "" ) { 10844 parsed = this._parse( value ); 10845 if ( parsed !== null ) { 10846 if ( !allowAny ) { 10847 parsed = this._adjustValue( parsed ); 10848 } 10849 value = this._format( parsed ); 10850 } 10851 } 10852 this.element.val( value ); 10853 this._refresh(); 10854 }, 10855 10856 _destroy: function() { 10857 this.element 10858 .removeClass( "ui-spinner-input" ) 10859 .prop( "disabled", false ) 10860 .removeAttr( "autocomplete" ) 10861 .removeAttr( "role" ) 10862 .removeAttr( "aria-valuemin" ) 10863 .removeAttr( "aria-valuemax" ) 10864 .removeAttr( "aria-valuenow" ); 10865 this.uiSpinner.replaceWith( this.element ); 10866 }, 10867 10868 stepUp: modifier(function( steps ) { 10869 this._stepUp( steps ); 10870 }), 10871 _stepUp: function( steps ) { 10872 this._spin( (steps || 1) * this.options.step ); 10873 }, 10874 10875 stepDown: modifier(function( steps ) { 10876 this._stepDown( steps ); 10877 }), 10878 _stepDown: function( steps ) { 10879 this._spin( (steps || 1) * -this.options.step ); 10880 }, 10881 10882 pageUp: modifier(function( pages ) { 10883 this._stepUp( (pages || 1) * this.options.page ); 10884 }), 10885 10886 pageDown: modifier(function( pages ) { 10887 this._stepDown( (pages || 1) * this.options.page ); 10888 }), 10889 10890 value: function( newVal ) { 10891 if ( !arguments.length ) { 10892 return this._parse( this.element.val() ); 10893 } 10894 modifier( this._value ).call( this, newVal ); 10895 }, 10896 10897 widget: function() { 10898 return this.uiSpinner; 10899 } 10900}); 10901 10902}( jQuery ) ); 10903(function( $, undefined ) { 10904 10905var tabId = 0, 10906 rhash = /#.*$/; 10907 10908function getNextTabId() { 10909 return ++tabId; 10910} 10911 10912function isLocal( anchor ) { 10913 return anchor.hash.length > 1 && 10914 anchor.href.replace( rhash, "" ) === 10915 location.href.replace( rhash, "" ) 10916 // support: Safari 5.1 10917 // Safari 5.1 doesn't encode spaces in window.location 10918 // but it does encode spaces from anchors (#8777) 10919 .replace( /\s/g, "%20" ); 10920} 10921 10922$.widget( "ui.tabs", { 10923 version: "1.9.2", 10924 delay: 300, 10925 options: { 10926 active: null, 10927 collapsible: false, 10928 event: "click", 10929 heightStyle: "content", 10930 hide: null, 10931 show: null, 10932 10933 // callbacks 10934 activate: null, 10935 beforeActivate: null, 10936 beforeLoad: null, 10937 load: null 10938 }, 10939 10940 _create: function() { 10941 var that = this, 10942 options = this.options, 10943 active = options.active, 10944 locationHash = location.hash.substring( 1 ); 10945 10946 this.running = false; 10947 10948 this.element 10949 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 10950 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 10951 // Prevent users from focusing disabled tabs via click 10952 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 10953 if ( $( this ).is( ".ui-state-disabled" ) ) { 10954 event.preventDefault(); 10955 } 10956 }) 10957 // support: IE <9 10958 // Preventing the default action in mousedown doesn't prevent IE
vendor: 18,149 bytes, lines 10959-11632
10959 // from focusing the element, so if the anchor gets focused, blur. 10960 // We don't have to worry about focusing the previously focused 10961 // element since clicking on a non-focusable element should focus 10962 // the body anyway. 10963 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 10964 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 10965 this.blur(); 10966 } 10967 }); 10968 10969 this._processTabs(); 10970 10971 if ( active === null ) { 10972 // check the fragment identifier in the URL 10973 if ( locationHash ) { 10974 this.tabs.each(function( i, tab ) { 10975 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 10976 active = i; 10977 return false; 10978 } 10979 }); 10980 } 10981 10982 // check for a tab marked active via a class 10983 if ( active === null ) { 10984 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 10985 } 10986 10987 // no active tab, set to false 10988 if ( active === null || active === -1 ) { 10989 active = this.tabs.length ? 0 : false; 10990 } 10991 } 10992 10993 // handle numbers: negative, out of range 10994 if ( active !== false ) { 10995 active = this.tabs.index( this.tabs.eq( active ) ); 10996 if ( active === -1 ) { 10997 active = options.collapsible ? false : 0; 10998 } 10999 } 11000 options.active = active; 11001 11002 // don't allow collapsible: false and active: false 11003 if ( !options.collapsible && options.active === false && this.anchors.length ) { 11004 options.active = 0; 11005 } 11006 11007 // Take disabling tabs via class attribute from HTML 11008 // into account and update option properly. 11009 if ( $.isArray( options.disabled ) ) { 11010 options.disabled = $.unique( options.disabled.concat( 11011 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 11012 return that.tabs.index( li ); 11013 }) 11014 ) ).sort(); 11015 } 11016 11017 // check for length avoids error when initializing empty list 11018 if ( this.options.active !== false && this.anchors.length ) { 11019 this.active = this._findActive( this.options.active ); 11020 } else { 11021 this.active = $(); 11022 } 11023 11024 this._refresh(); 11025 11026 if ( this.active.length ) { 11027 this.load( options.active ); 11028 } 11029 }, 11030 11031 _getCreateEventData: function() { 11032 return { 11033 tab: this.active, 11034 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 11035 }; 11036 }, 11037 11038 _tabKeydown: function( event ) { 11039 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 11040 selectedIndex = this.tabs.index( focusedTab ), 11041 goingForward = true; 11042 11043 if ( this._handlePageNav( event ) ) { 11044 return; 11045 } 11046 11047 switch ( event.keyCode ) { 11048 case $.ui.keyCode.RIGHT: 11049 case $.ui.keyCode.DOWN: 11050 selectedIndex++; 11051 break; 11052 case $.ui.keyCode.UP: 11053 case $.ui.keyCode.LEFT: 11054 goingForward = false; 11055 selectedIndex--; 11056 break; 11057 case $.ui.keyCode.END: 11058 selectedIndex = this.anchors.length - 1; 11059 break; 11060 case $.ui.keyCode.HOME: 11061 selectedIndex = 0; 11062 break; 11063 case $.ui.keyCode.SPACE: 11064 // Activate only, no collapsing 11065 event.preventDefault(); 11066 clearTimeout( this.activating ); 11067 this._activate( selectedIndex ); 11068 return; 11069 case $.ui.keyCode.ENTER: 11070 // Toggle (cancel delayed activation, allow collapsing) 11071 event.preventDefault(); 11072 clearTimeout( this.activating ); 11073 // Determine if we should collapse or activate 11074 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 11075 return; 11076 default: 11077 return; 11078 } 11079 11080 // Focus the appropriate tab, based on which key was pressed 11081 event.preventDefault(); 11082 clearTimeout( this.activating ); 11083 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 11084 11085 // Navigating with control key will prevent automatic activation 11086 if ( !event.ctrlKey ) { 11087 // Update aria-selected immediately so that AT think the tab is already selected. 11088 // Otherwise AT may confuse the user by stating that they need to activate the tab, 11089 // but the tab will already be activated by the time the announcement finishes. 11090 focusedTab.attr( "aria-selected", "false" ); 11091 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 11092 11093 this.activating = this._delay(function() { 11094 this.option( "active", selectedIndex ); 11095 }, this.delay ); 11096 } 11097 }, 11098 11099 _panelKeydown: function( event ) { 11100 if ( this._handlePageNav( event ) ) { 11101 return; 11102 } 11103 11104 // Ctrl+up moves focus to the current tab 11105 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 11106 event.preventDefault(); 11107 this.active.focus(); 11108 } 11109 }, 11110 11111 // Alt+page up/down moves focus to the previous/next tab (and activates) 11112 _handlePageNav: function( event ) { 11113 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 11114 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 11115 return true; 11116 } 11117 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 11118 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 11119 return true; 11120 } 11121 }, 11122 11123 _findNextTab: function( index, goingForward ) { 11124 var lastTabIndex = this.tabs.length - 1; 11125 11126 function constrain() { 11127 if ( index > lastTabIndex ) { 11128 index = 0; 11129 } 11130 if ( index < 0 ) { 11131 index = lastTabIndex; 11132 } 11133 return index; 11134 } 11135 11136 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 11137 index = goingForward ? index + 1 : index - 1; 11138 } 11139 11140 return index; 11141 }, 11142 11143 _focusNextTab: function( index, goingForward ) { 11144 index = this._findNextTab( index, goingForward ); 11145 this.tabs.eq( index ).focus(); 11146 return index; 11147 }, 11148 11149 _setOption: function( key, value ) { 11150 if ( key === "active" ) { 11151 // _activate() will handle invalid values and update this.options 11152 this._activate( value ); 11153 return; 11154 } 11155 11156 if ( key === "disabled" ) { 11157 // don't use the widget factory's disabled handling 11158 this._setupDisabled( value ); 11159 return; 11160 } 11161 11162 this._super( key, value); 11163 11164 if ( key === "collapsible" ) { 11165 this.element.toggleClass( "ui-tabs-collapsible", value ); 11166 // Setting collapsible: false while collapsed; open first panel 11167 if ( !value && this.options.active === false ) { 11168 this._activate( 0 ); 11169 } 11170 } 11171 11172 if ( key === "event" ) { 11173 this._setupEvents( value ); 11174 } 11175 11176 if ( key === "heightStyle" ) { 11177 this._setupHeightStyle( value ); 11178 } 11179 }, 11180 11181 _tabId: function( tab ) { 11182 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 11183 }, 11184 11185 _sanitizeSelector: function( hash ) { 11186 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 11187 }, 11188 11189 refresh: function() { 11190 var options = this.options, 11191 lis = this.tablist.children( ":has(a[href])" ); 11192 11193 // get disabled tabs from class attribute from HTML 11194 // this will get converted to a boolean if needed in _refresh() 11195 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 11196 return lis.index( tab ); 11197 }); 11198 11199 this._processTabs(); 11200 11201 // was collapsed or no tabs 11202 if ( options.active === false || !this.anchors.length ) { 11203 options.active = false; 11204 this.active = $(); 11205 // was active, but active tab is gone 11206 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 11207 // all remaining tabs are disabled 11208 if ( this.tabs.length === options.disabled.length ) { 11209 options.active = false; 11210 this.active = $(); 11211 // activate previous tab 11212 } else { 11213 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 11214 } 11215 // was active, active tab still exists 11216 } else { 11217 // make sure active index is correct 11218 options.active = this.tabs.index( this.active ); 11219 } 11220 11221 this._refresh(); 11222 }, 11223 11224 _refresh: function() { 11225 this._setupDisabled( this.options.disabled ); 11226 this._setupEvents( this.options.event ); 11227 this._setupHeightStyle( this.options.heightStyle ); 11228 11229 this.tabs.not( this.active ).attr({ 11230 "aria-selected": "false", 11231 tabIndex: -1 11232 }); 11233 this.panels.not( this._getPanelForTab( this.active ) ) 11234 .hide() 11235 .attr({ 11236 "aria-expanded": "false", 11237 "aria-hidden": "true" 11238 }); 11239 11240 // Make sure one tab is in the tab order 11241 if ( !this.active.length ) { 11242 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 11243 } else { 11244 this.active 11245 .addClass( "ui-tabs-active ui-state-active" ) 11246 .attr({ 11247 "aria-selected": "true", 11248 tabIndex: 0 11249 }); 11250 this._getPanelForTab( this.active ) 11251 .show() 11252 .attr({ 11253 "aria-expanded": "true", 11254 "aria-hidden": "false" 11255 }); 11256 } 11257 }, 11258 11259 _processTabs: function() { 11260 var that = this; 11261 11262 this.tablist = this._getList() 11263 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11264 .attr( "role", "tablist" ); 11265 11266 this.tabs = this.tablist.find( "> li:has(a[href])" ) 11267 .addClass( "ui-state-default ui-corner-top" ) 11268 .attr({ 11269 role: "tab", 11270 tabIndex: -1 11271 }); 11272 11273 this.anchors = this.tabs.map(function() { 11274 return $( "a", this )[ 0 ]; 11275 }) 11276 .addClass( "ui-tabs-anchor" ) 11277 .attr({ 11278 role: "presentation", 11279 tabIndex: -1 11280 }); 11281 11282 this.panels = $(); 11283 11284 this.anchors.each(function( i, anchor ) { 11285 var selector, panel, panelId, 11286 anchorId = $( anchor ).uniqueId().attr( "id" ), 11287 tab = $( anchor ).closest( "li" ), 11288 originalAriaControls = tab.attr( "aria-controls" ); 11289 11290 // inline tab 11291 if ( isLocal( anchor ) ) { 11292 selector = anchor.hash; 11293 panel = that.element.find( that._sanitizeSelector( selector ) ); 11294 // remote tab 11295 } else { 11296 panelId = that._tabId( tab ); 11297 selector = "#" + panelId; 11298 panel = that.element.find( selector ); 11299 if ( !panel.length ) { 11300 panel = that._createPanel( panelId ); 11301 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 11302 } 11303 panel.attr( "aria-live", "polite" ); 11304 } 11305 11306 if ( panel.length) { 11307 that.panels = that.panels.add( panel ); 11308 } 11309 if ( originalAriaControls ) { 11310 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 11311 } 11312 tab.attr({ 11313 "aria-controls": selector.substring( 1 ), 11314 "aria-labelledby": anchorId 11315 }); 11316 panel.attr( "aria-labelledby", anchorId ); 11317 }); 11318 11319 this.panels 11320 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11321 .attr( "role", "tabpanel" ); 11322 }, 11323 11324 // allow overriding how to find the list for rare usage scenarios (#7715) 11325 _getList: function() { 11326 return this.element.find( "ol,ul" ).eq( 0 ); 11327 }, 11328 11329 _createPanel: function( id ) { 11330 return $( "<div>" ) 11331 .attr( "id", id ) 11332 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11333 .data( "ui-tabs-destroy", true ); 11334 }, 11335 11336 _setupDisabled: function( disabled ) { 11337 if ( $.isArray( disabled ) ) { 11338 if ( !disabled.length ) { 11339 disabled = false; 11340 } else if ( disabled.length === this.anchors.length ) { 11341 disabled = true; 11342 } 11343 } 11344 11345 // disable tabs 11346 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 11347 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 11348 $( li ) 11349 .addClass( "ui-state-disabled" ) 11350 .attr( "aria-disabled", "true" ); 11351 } else { 11352 $( li ) 11353 .removeClass( "ui-state-disabled" ) 11354 .removeAttr( "aria-disabled" ); 11355 } 11356 } 11357 11358 this.options.disabled = disabled; 11359 }, 11360 11361 _setupEvents: function( event ) { 11362 var events = { 11363 click: function( event ) { 11364 event.preventDefault(); 11365 } 11366 }; 11367 if ( event ) { 11368 $.each( event.split(" "), function( index, eventName ) { 11369 events[ eventName ] = "_eventHandler"; 11370 }); 11371 } 11372 11373 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 11374 this._on( this.anchors, events ); 11375 this._on( this.tabs, { keydown: "_tabKeydown" } ); 11376 this._on( this.panels, { keydown: "_panelKeydown" } ); 11377 11378 this._focusable( this.tabs ); 11379 this._hoverable( this.tabs ); 11380 }, 11381 11382 _setupHeightStyle: function( heightStyle ) { 11383 var maxHeight, overflow, 11384 parent = this.element.parent(); 11385 11386 if ( heightStyle === "fill" ) { 11387 // IE 6 treats height like minHeight, so we need to turn off overflow 11388 // in order to get a reliable height 11389 // we use the minHeight support test because we assume that only 11390 // browsers that don't support minHeight will treat height as minHeight 11391 if ( !$.support.minHeight ) { 11392 overflow = parent.css( "overflow" ); 11393 parent.css( "overflow", "hidden"); 11394 } 11395 maxHeight = parent.height(); 11396 this.element.siblings( ":visible" ).each(function() { 11397 var elem = $( this ), 11398 position = elem.css( "position" ); 11399 11400 if ( position === "absolute" || position === "fixed" ) { 11401 return; 11402 } 11403 maxHeight -= elem.outerHeight( true ); 11404 }); 11405 if ( overflow ) { 11406 parent.css( "overflow", overflow ); 11407 } 11408 11409 this.element.children().not( this.panels ).each(function() { 11410 maxHeight -= $( this ).outerHeight( true ); 11411 }); 11412 11413 this.panels.each(function() { 11414 $( this ).height( Math.max( 0, maxHeight - 11415 $( this ).innerHeight() + $( this ).height() ) ); 11416 }) 11417 .css( "overflow", "auto" ); 11418 } else if ( heightStyle === "auto" ) { 11419 maxHeight = 0; 11420 this.panels.each(function() { 11421 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 11422 }).height( maxHeight ); 11423 } 11424 }, 11425 11426 _eventHandler: function( event ) { 11427 var options = this.options, 11428 active = this.active, 11429 anchor = $( event.currentTarget ), 11430 tab = anchor.closest( "li" ), 11431 clickedIsActive = tab[ 0 ] === active[ 0 ], 11432 collapsing = clickedIsActive && options.collapsible, 11433 toShow = collapsing ? $() : this._getPanelForTab( tab ), 11434 toHide = !active.length ? $() : this._getPanelForTab( active ), 11435 eventData = { 11436 oldTab: active, 11437 oldPanel: toHide, 11438 newTab: collapsing ? $() : tab, 11439 newPanel: toShow 11440 }; 11441 11442 event.preventDefault(); 11443 11444 if ( tab.hasClass( "ui-state-disabled" ) || 11445 // tab is already loading 11446 tab.hasClass( "ui-tabs-loading" ) || 11447 // can't switch durning an animation 11448 this.running || 11449 // click on active header, but not collapsible 11450 ( clickedIsActive && !options.collapsible ) || 11451 // allow canceling activation 11452 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 11453 return; 11454 } 11455 11456 options.active = collapsing ? false : this.tabs.index( tab ); 11457 11458 this.active = clickedIsActive ? $() : tab; 11459 if ( this.xhr ) { 11460 this.xhr.abort(); 11461 } 11462 11463 if ( !toHide.length && !toShow.length ) { 11464 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 11465 } 11466 11467 if ( toShow.length ) { 11468 this.load( this.tabs.index( tab ), event ); 11469 } 11470 this._toggle( event, eventData ); 11471 }, 11472 11473 // handles show/hide for selecting tabs 11474 _toggle: function( event, eventData ) { 11475 var that = this, 11476 toShow = eventData.newPanel, 11477 toHide = eventData.oldPanel; 11478 11479 this.running = true; 11480 11481 function complete() { 11482 that.running = false; 11483 that._trigger( "activate", event, eventData ); 11484 } 11485 11486 function show() { 11487 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 11488 11489 if ( toShow.length && that.options.show ) { 11490 that._show( toShow, that.options.show, complete ); 11491 } else { 11492 toShow.show(); 11493 complete(); 11494 } 11495 } 11496 11497 // start out by hiding, then showing, then completing 11498 if ( toHide.length && this.options.hide ) { 11499 this._hide( toHide, this.options.hide, function() { 11500 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 11501 show(); 11502 }); 11503 } else { 11504 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 11505 toHide.hide(); 11506 show(); 11507 } 11508 11509 toHide.attr({ 11510 "aria-expanded": "false", 11511 "aria-hidden": "true" 11512 }); 11513 eventData.oldTab.attr( "aria-selected", "false" ); 11514 // If we're switching tabs, remove the old tab from the tab order. 11515 // If we're opening from collapsed state, remove the previous tab from the tab order. 11516 // If we're collapsing, then keep the collapsing tab in the tab order. 11517 if ( toShow.length && toHide.length ) { 11518 eventData.oldTab.attr( "tabIndex", -1 ); 11519 } else if ( toShow.length ) { 11520 this.tabs.filter(function() { 11521 return $( this ).attr( "tabIndex" ) === 0; 11522 }) 11523 .attr( "tabIndex", -1 ); 11524 } 11525 11526 toShow.attr({ 11527 "aria-expanded": "true", 11528 "aria-hidden": "false" 11529 }); 11530 eventData.newTab.attr({ 11531 "aria-selected": "true", 11532 tabIndex: 0 11533 }); 11534 }, 11535 11536 _activate: function( index ) { 11537 var anchor, 11538 active = this._findActive( index ); 11539 11540 // trying to activate the already active panel 11541 if ( active[ 0 ] === this.active[ 0 ] ) { 11542 return; 11543 } 11544 11545 // trying to collapse, simulate a click on the current active header 11546 if ( !active.length ) { 11547 active = this.active; 11548 } 11549 11550 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 11551 this._eventHandler({ 11552 target: anchor, 11553 currentTarget: anchor, 11554 preventDefault: $.noop 11555 }); 11556 }, 11557 11558 _findActive: function( index ) { 11559 return index === false ? $() : this.tabs.eq( index ); 11560 }, 11561 11562 _getIndex: function( index ) { 11563 // meta-function to give users option to provide a href string instead of a numerical index. 11564 if ( typeof index === "string" ) { 11565 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 11566 } 11567 11568 return index; 11569 }, 11570 11571 _destroy: function() { 11572 if ( this.xhr ) { 11573 this.xhr.abort(); 11574 } 11575 11576 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 11577 11578 this.tablist 11579 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11580 .removeAttr( "role" ); 11581 11582 this.anchors 11583 .removeClass( "ui-tabs-anchor" ) 11584 .removeAttr( "role" ) 11585 .removeAttr( "tabIndex" ) 11586 .removeData( "href.tabs" ) 11587 .removeData( "load.tabs" ) 11588 .removeUniqueId(); 11589 11590 this.tabs.add( this.panels ).each(function() { 11591 if ( $.data( this, "ui-tabs-destroy" ) ) { 11592 $( this ).remove(); 11593 } else { 11594 $( this ) 11595 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 11596 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 11597 .removeAttr( "tabIndex" ) 11598 .removeAttr( "aria-live" ) 11599 .removeAttr( "aria-busy" ) 11600 .removeAttr( "aria-selected" ) 11601 .removeAttr( "aria-labelledby" ) 11602 .removeAttr( "aria-hidden" ) 11603 .removeAttr( "aria-expanded" ) 11604 .removeAttr( "role" ); 11605 } 11606 }); 11607 11608 this.tabs.each(function() { 11609 var li = $( this ), 11610 prev = li.data( "ui-tabs-aria-controls" ); 11611 if ( prev ) { 11612 li.attr( "aria-controls", prev ); 11613 } else { 11614 li.removeAttr( "aria-controls" ); 11615 } 11616 }); 11617 11618 this.panels.show(); 11619 11620 if ( this.options.heightStyle !== "content" ) { 11621 this.panels.css( "height", "" ); 11622 } 11623 }, 11624 11625 enable: function( index ) { 11626 var disabled = this.options.disabled; 11627 if ( disabled === false ) { 11628 return; 11629 } 11630 11631 if ( index === undefined ) { 11632 disabled = false;
11633 } else { 11634 index = this._getIndex( index ); 11635 if ( $.isArray( disabled ) ) { 11636 disabled = $.map( disabled, function( num ) { 11637 return num !== index ? num : null; 11638 }); 11639 } else { 11640 disabled = $.map( this.tabs, function( li, num ) { 11641 return num !== index ? num : null; 11642 }); 11643 } 11644 } 11645 this._setupDisabled( disabled ); 11646 }, 11647 11648 disable: function( index ) { 11649 var disabled = this.options.disabled; 11650 if ( disabled === true ) { 11651 return; 11652 } 11653 11654 if ( index === undefined ) { 11655 disabled = true; 11656 } else { 11657 index = this._getIndex( index ); 11658 if ( $.inArray( index, disabled ) !== -1 ) { 11659 return; 11660 } 11661 if ( $.isArray( disabled ) ) { 11662 disabled = $.merge( [ index ], disabled ).sort(); 11663 } else { 11664 disabled = [ index ]; 11665 } 11666 } 11667 this._setupDisabled( disabled ); 11668 }, 11669 11670 load: function( index, event ) { 11671 index = this._getIndex( index ); 11672 var that = this, 11673 tab = this.tabs.eq( index ), 11674 anchor = tab.find( ".ui-tabs-anchor" ), 11675 panel = this._getPanelForTab( tab ), 11676 eventData = { 11677 tab: tab, 11678 panel: panel 11679 }; 11680 11681 // not remote 11682 if ( isLocal( anchor[ 0 ] ) ) { 11683 return; 11684 } 11685 11686 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 11687 11688 // support: jQuery <1.8 11689 // jQuery <1.8 returns false if the request is canceled in beforeSend, 11690 // but as of 1.8, $.ajax() always returns a jqXHR object. 11691 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 11692 tab.addClass( "ui-tabs-loading" ); 11693 panel.attr( "aria-busy", "true" ); 11694 11695 this.xhr 11696 .success(function( response ) { 11697 // support: jQuery <1.8 11698 // http://bugs.jquery.com/ticket/11778 11699 setTimeout(function() { 11700 panel.html( response ); 11701 that._trigger( "load", event, eventData ); 11702 }, 1 ); 11703 }) 11704 .complete(function( jqXHR, status ) { 11705 // support: jQuery <1.8 11706 // http://bugs.jquery.com/ticket/11778 11707 setTimeout(function() { 11708 if ( status === "abort" ) { 11709 that.panels.stop( false, true ); 11710 } 11711 11712 tab.removeClass( "ui-tabs-loading" ); 11713 panel.removeAttr( "aria-busy" ); 11714 11715 if ( jqXHR === that.xhr ) { 11716 delete that.xhr; 11717 } 11718 }, 1 ); 11719 }); 11720 } 11721 }, 11722 11723 // TODO: Remove this function in 1.10 when ajaxOptions is removed 11724 _ajaxSettings: function( anchor, event, eventData ) { 11725 var that = this; 11726 return { 11727 url: anchor.attr( "href" ), 11728 beforeSend: function( jqXHR, settings ) { 11729 return that._trigger( "beforeLoad", event, 11730 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 11731 } 11732 }; 11733 }, 11734 11735 _getPanelForTab: function( tab ) { 11736 var id = $( tab ).attr( "aria-controls" ); 11737 return this.element.find( this._sanitizeSelector( "#" + id ) ); 11738 } 11739}); 11740 11741// DEPRECATED 11742if ( $.uiBackCompat !== false ) { 11743 11744 // helper method for a lot of the back compat extensions 11745 $.ui.tabs.prototype._ui = function( tab, panel ) { 11746 return { 11747 tab: tab, 11748 panel: panel, 11749 index: this.anchors.index( tab ) 11750 }; 11751 }; 11752 11753 // url method 11754 $.widget( "ui.tabs", $.ui.tabs, { 11755 url: function( index, url ) { 11756 this.anchors.eq( index ).attr( "href", url ); 11757 } 11758 }); 11759 11760 // TODO: Remove _ajaxSettings() method when removing this extension 11761 // ajaxOptions and cache options 11762 $.widget( "ui.tabs", $.ui.tabs, { 11763 options: { 11764 ajaxOptions: null, 11765 cache: false 11766 }, 11767 11768 _create: function() { 11769 this._super(); 11770 11771 var that = this; 11772 11773 this._on({ tabsbeforeload: function( event, ui ) { 11774 // tab is already cached 11775 if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { 11776 event.preventDefault(); 11777 return; 11778 } 11779 11780 ui.jqXHR.success(function() { 11781 if ( that.options.cache ) { 11782 $.data( ui.tab[ 0 ], "cache.tabs", true ); 11783 } 11784 }); 11785 }}); 11786 }, 11787 11788 _ajaxSettings: function( anchor, event, ui ) { 11789 var ajaxOptions = this.options.ajaxOptions; 11790 return $.extend( {}, ajaxOptions, { 11791 error: function( xhr, status ) { 11792 try { 11793 // Passing index avoid a race condition when this method is 11794 // called after the user has selected another tab. 11795 // Pass the anchor that initiated this request allows 11796 // loadError to manipulate the tab content panel via $(a.hash) 11797 ajaxOptions.error( 11798 xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); 11799 } 11800 catch ( error ) {} 11801 } 11802 }, this._superApply( arguments ) ); 11803 }, 11804 11805 _setOption: function( key, value ) { 11806 // reset cache if switching from cached to not cached 11807 if ( key === "cache" && value === false ) { 11808 this.anchors.removeData( "cache.tabs" ); 11809 } 11810 this._super( key, value ); 11811 }, 11812 11813 _destroy: function() { 11814 this.anchors.removeData( "cache.tabs" ); 11815 this._super(); 11816 }, 11817 11818 url: function( index ){ 11819 this.anchors.eq( index ).removeData( "cache.tabs" ); 11820 this._superApply( arguments ); 11821 } 11822 }); 11823 11824 // abort method 11825 $.widget( "ui.tabs", $.ui.tabs, { 11826 abort: function() { 11827 if ( this.xhr ) { 11828 this.xhr.abort(); 11829 } 11830 } 11831 }); 11832 11833 // spinner 11834 $.widget( "ui.tabs", $.ui.tabs, { 11835 options: { 11836 spinner: "<em>Loading…</em>" 11837 }, 11838 _create: function() { 11839 this._super(); 11840 this._on({ 11841 tabsbeforeload: function( event, ui ) { 11842 // Don't react to nested tabs or tabs that don't use a spinner 11843 if ( event.target !== this.element[ 0 ] || 11844 !this.options.spinner ) { 11845 return; 11846 } 11847 11848 var span = ui.tab.find( "span" ), 11849 html = span.html(); 11850 span.html( this.options.spinner ); 11851 ui.jqXHR.complete(function() { 11852 span.html( html ); 11853 }); 11854 } 11855 }); 11856 } 11857 }); 11858 11859 // enable/disable events 11860 $.widget( "ui.tabs", $.ui.tabs, { 11861 options: { 11862 enable: null, 11863 disable: null 11864 }, 11865 11866 enable: function( index ) { 11867 var options = this.options, 11868 trigger; 11869 11870 if ( index && options.disabled === true || 11871 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { 11872 trigger = true; 11873 } 11874 11875 this._superApply( arguments ); 11876 11877 if ( trigger ) { 11878 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11879 } 11880 }, 11881 11882 disable: function( index ) { 11883 var options = this.options, 11884 trigger; 11885 11886 if ( index && options.disabled === false || 11887 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { 11888 trigger = true; 11889 } 11890 11891 this._superApply( arguments ); 11892 11893 if ( trigger ) { 11894 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11895 } 11896 } 11897 }); 11898 11899 // add/remove methods and events 11900 $.widget( "ui.tabs", $.ui.tabs, { 11901 options: { 11902 add: null, 11903 remove: null, 11904 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" 11905 }, 11906 11907 add: function( url, label, index ) { 11908 if ( index === undefined ) { 11909 index = this.anchors.length; 11910 } 11911 11912 var doInsertAfter, panel, 11913 options = this.options, 11914 li = $( options.tabTemplate 11915 .replace( /#\{href\}/g, url ) 11916 .replace( /#\{label\}/g, label ) ), 11917 id = !url.indexOf( "#" ) ? 11918 url.replace( "#", "" ) : 11919 this._tabId( li ); 11920 11921 li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); 11922 li.attr( "aria-controls", id ); 11923 11924 doInsertAfter = index >= this.tabs.length; 11925 11926 // try to find an existing element before creating a new one 11927 panel = this.element.find( "#" + id ); 11928 if ( !panel.length ) { 11929 panel = this._createPanel( id ); 11930 if ( doInsertAfter ) { 11931 if ( index > 0 ) { 11932 panel.insertAfter( this.panels.eq( -1 ) ); 11933 } else { 11934 panel.appendTo( this.element ); 11935 } 11936 } else { 11937 panel.insertBefore( this.panels[ index ] ); 11938 } 11939 } 11940 panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); 11941 11942 if ( doInsertAfter ) { 11943 li.appendTo( this.tablist ); 11944 } else { 11945 li.insertBefore( this.tabs[ index ] ); 11946 } 11947 11948 options.disabled = $.map( options.disabled, function( n ) { 11949 return n >= index ? ++n : n; 11950 }); 11951 11952 this.refresh(); 11953 if ( this.tabs.length === 1 && options.active === false ) { 11954 this.option( "active", 0 ); 11955 } 11956 11957 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 11958 return this; 11959 }, 11960 11961 remove: function( index ) { 11962 index = this._getIndex( index ); 11963 var options = this.options, 11964 tab = this.tabs.eq( index ).remove(), 11965 panel = this._getPanelForTab( tab ).remove(); 11966 11967 // If selected tab was removed focus tab to the right or 11968 // in case the last tab was removed the tab to the left. 11969 // We check for more than 2 tabs, because if there are only 2, 11970 // then when we remove this tab, there will only be one tab left 11971 // so we don't need to detect which tab to activate. 11972 if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { 11973 this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); 11974 } 11975 11976 options.disabled = $.map( 11977 $.grep( options.disabled, function( n ) { 11978 return n !== index; 11979 }), 11980 function( n ) { 11981 return n >= index ? --n : n; 11982 }); 11983 11984 this.refresh(); 11985 11986 this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); 11987 return this; 11988 } 11989 }); 11990 11991 // length method 11992 $.widget( "ui.tabs", $.ui.tabs, { 11993 length: function() { 11994 return this.anchors.length; 11995 } 11996 }); 11997 11998 // panel ids (idPrefix option + title attribute) 11999 $.widget( "ui.tabs", $.ui.tabs, { 12000 options: { 12001 idPrefix: "ui-tabs-" 12002 }, 12003 12004 _tabId: function( tab ) { 12005 var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; 12006 a = a[0]; 12007 return $( a ).closest( "li" ).attr( "aria-controls" ) || 12008 a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || 12009 this.options.idPrefix + getNextTabId(); 12010 } 12011 }); 12012 12013 // _createPanel method 12014 $.widget( "ui.tabs", $.ui.tabs, { 12015 options: { 12016 panelTemplate: "<div></div>" 12017 }, 12018 12019 _createPanel: function( id ) { 12020 return $( this.options.panelTemplate ) 12021 .attr( "id", id ) 12022 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 12023 .data( "ui-tabs-destroy", true ); 12024 } 12025 }); 12026 12027 // selected option 12028 $.widget( "ui.tabs", $.ui.tabs, { 12029 _create: function() { 12030 var options = this.options; 12031 if ( options.active === null && options.selected !== undefined ) { 12032 options.active = options.selected === -1 ? false : options.selected; 12033 } 12034 this._super(); 12035 options.selected = options.active; 12036 if ( options.selected === false ) { 12037 options.selected = -1; 12038 } 12039 }, 12040 12041 _setOption: function( key, value ) { 12042 if ( key !== "selected" ) { 12043 return this._super( key, value ); 12044 } 12045 12046 var options = this.options; 12047 this._super( "active", value === -1 ? false : value ); 12048 options.selected = options.active; 12049 if ( options.selected === false ) { 12050 options.selected = -1; 12051 } 12052 }, 12053 12054 _eventHandler: function() { 12055 this._superApply( arguments ); 12056 this.options.selected = this.options.active; 12057 if ( this.options.selected === false ) { 12058 this.options.selected = -1; 12059 } 12060 } 12061 }); 12062 12063 // show and select event 12064 $.widget( "ui.tabs", $.ui.tabs, { 12065 options: { 12066 show: null, 12067 select: null 12068 }, 12069 _create: function() { 12070 this._super(); 12071 if ( this.options.active !== false ) { 12072 this._trigger( "show", null, this._ui( 12073 this.active.find( ".ui-tabs-anchor" )[ 0 ], 12074 this._getPanelForTab( this.active )[ 0 ] ) ); 12075 } 12076 }, 12077 _trigger: function( type, event, data ) { 12078 var tab, panel, 12079 ret = this._superApply( arguments ); 12080 12081 if ( !ret ) { 12082 return false;
12083 } 12084 12085 if ( type === "beforeActivate" ) { 12086 tab = data.newTab.length ? data.newTab : data.oldTab; 12087 panel = data.newPanel.length ? data.newPanel : data.oldPanel; 12088 ret = this._super( "select", event, { 12089 tab: tab.find( ".ui-tabs-anchor" )[ 0], 12090 panel: panel[ 0 ], 12091 index: tab.closest( "li" ).index() 12092 }); 12093 } else if ( type === "activate" && data.newTab.length ) { 12094 ret = this._super( "show", event, { 12095 tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], 12096 panel: data.newPanel[ 0 ], 12097 index: data.newTab.closest( "li" ).index() 12098 }); 12099 } 12100 return ret; 12101 } 12102 }); 12103 12104 // select method 12105 $.widget( "ui.tabs", $.ui.tabs, { 12106 select: function( index ) { 12107 index = this._getIndex( index ); 12108 if ( index === -1 ) { 12109 if ( this.options.collapsible && this.options.selected !== -1 ) { 12110 index = this.options.selected; 12111 } else { 12112 return; 12113 } 12114 } 12115 this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); 12116 } 12117 }); 12118 12119 // cookie option 12120 (function() { 12121 12122 var listId = 0; 12123 12124 $.widget( "ui.tabs", $.ui.tabs, { 12125 options: { 12126 cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 12127 }, 12128 _create: function() { 12129 var options = this.options, 12130 active; 12131 if ( options.active == null && options.cookie ) { 12132 active = parseInt( this._cookie(), 10 ); 12133 if ( active === -1 ) { 12134 active = false; 12135 } 12136 options.active = active; 12137 } 12138 this._super(); 12139 }, 12140 _cookie: function( active ) { 12141 var cookie = [ this.cookie || 12142 ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; 12143 if ( arguments.length ) { 12144 cookie.push( active === false ? -1 : active ); 12145 cookie.push( this.options.cookie ); 12146 } 12147 return $.cookie.apply( null, cookie ); 12148 }, 12149 _refresh: function() { 12150 this._super(); 12151 if ( this.options.cookie ) { 12152 this._cookie( this.options.active, this.options.cookie ); 12153 } 12154 }, 12155 _eventHandler: function() { 12156 this._superApply( arguments ); 12157 if ( this.options.cookie ) { 12158 this._cookie( this.options.active, this.options.cookie ); 12159 } 12160 }, 12161 _destroy: function() { 12162 this._super(); 12163 if ( this.options.cookie ) { 12164 this._cookie( null, this.options.cookie ); 12165 } 12166 } 12167 }); 12168 12169 })(); 12170 12171 // load event 12172 $.widget( "ui.tabs", $.ui.tabs, { 12173 _trigger: function( type, event, data ) { 12174 var _data = $.extend( {}, data ); 12175 if ( type === "load" ) { 12176 _data.panel = _data.panel[ 0 ]; 12177 _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; 12178 } 12179 return this._super( type, event, _data ); 12180 } 12181 }); 12182 12183 // fx option 12184 // The new animation options (show, hide) conflict with the old show callback. 12185 // The old fx option wins over show/hide anyway (always favor back-compat). 12186 // If a user wants to use the new animation API, they must give up the old API. 12187 $.widget( "ui.tabs", $.ui.tabs, { 12188 options: { 12189 fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } 12190 }, 12191 12192 _getFx: function() { 12193 var hide, show, 12194 fx = this.options.fx; 12195 12196 if ( fx ) { 12197 if ( $.isArray( fx ) ) { 12198 hide = fx[ 0 ]; 12199 show = fx[ 1 ]; 12200 } else { 12201 hide = show = fx; 12202 } 12203 } 12204 12205 return fx ? { show: show, hide: hide } : null; 12206 }, 12207 12208 _toggle: function( event, eventData ) { 12209 var that = this, 12210 toShow = eventData.newPanel, 12211 toHide = eventData.oldPanel, 12212 fx = this._getFx(); 12213 12214 if ( !fx ) { 12215 return this._super( event, eventData ); 12216 } 12217 12218 that.running = true; 12219 12220 function complete() { 12221 that.running = false; 12222 that._trigger( "activate", event, eventData ); 12223 } 12224 12225 function show() { 12226 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 12227 12228 if ( toShow.length && fx.show ) { 12229 toShow 12230 .animate( fx.show, fx.show.duration, function() { 12231 complete(); 12232 }); 12233 } else { 12234 toShow.show(); 12235 complete(); 12236 } 12237 } 12238 12239 // start out by hiding, then showing, then completing 12240 if ( toHide.length && fx.hide ) { 12241 toHide.animate( fx.hide, fx.hide.duration, function() { 12242 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12243 show(); 12244 }); 12245 } else { 12246 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12247 toHide.hide(); 12248 show(); 12249 } 12250 } 12251 }); 12252} 12253 12254})( jQuery ); 12255(function( $ ) { 12256 12257var increments = 0; 12258 12259function addDescribedBy( elem, id ) { 12260 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 12261 describedby.push( id ); 12262 elem 12263 .data( "ui-tooltip-id", id ) 12264 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 12265} 12266 12267function removeDescribedBy( elem ) { 12268 var id = elem.data( "ui-tooltip-id" ),
vendor: 65,202 bytes, lines 12269-14880
12269 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 12270 index = $.inArray( id, describedby ); 12271 if ( index !== -1 ) { 12272 describedby.splice( index, 1 ); 12273 } 12274 12275 elem.removeData( "ui-tooltip-id" ); 12276 describedby = $.trim( describedby.join( " " ) ); 12277 if ( describedby ) { 12278 elem.attr( "aria-describedby", describedby ); 12279 } else { 12280 elem.removeAttr( "aria-describedby" ); 12281 } 12282} 12283 12284$.widget( "ui.tooltip", { 12285 version: "1.9.2", 12286 options: { 12287 content: function() { 12288 return $( this ).attr( "title" ); 12289 }, 12290 hide: true, 12291 // Disabled elements have inconsistent behavior across browsers (#8661) 12292 items: "[title]:not([disabled])", 12293 position: { 12294 my: "left top+15", 12295 at: "left bottom", 12296 collision: "flipfit flip" 12297 }, 12298 show: true, 12299 tooltipClass: null, 12300 track: false, 12301 12302 // callbacks 12303 close: null, 12304 open: null 12305 }, 12306 12307 _create: function() { 12308 this._on({ 12309 mouseover: "open", 12310 focusin: "open" 12311 }); 12312 12313 // IDs of generated tooltips, needed for destroy 12314 this.tooltips = {}; 12315 // IDs of parent tooltips where we removed the title attribute 12316 this.parents = {}; 12317 12318 if ( this.options.disabled ) { 12319 this._disable(); 12320 } 12321 }, 12322 12323 _setOption: function( key, value ) { 12324 var that = this; 12325 12326 if ( key === "disabled" ) { 12327 this[ value ? "_disable" : "_enable" ](); 12328 this.options[ key ] = value; 12329 // disable element style changes 12330 return; 12331 } 12332 12333 this._super( key, value ); 12334 12335 if ( key === "content" ) { 12336 $.each( this.tooltips, function( id, element ) { 12337 that._updateContent( element ); 12338 }); 12339 } 12340 }, 12341 12342 _disable: function() { 12343 var that = this; 12344 12345 // close open tooltips 12346 $.each( this.tooltips, function( id, element ) { 12347 var event = $.Event( "blur" ); 12348 event.target = event.currentTarget = element[0]; 12349 that.close( event, true ); 12350 }); 12351 12352 // remove title attributes to prevent native tooltips 12353 this.element.find( this.options.items ).andSelf().each(function() { 12354 var element = $( this ); 12355 if ( element.is( "[title]" ) ) { 12356 element 12357 .data( "ui-tooltip-title", element.attr( "title" ) ) 12358 .attr( "title", "" ); 12359 } 12360 }); 12361 }, 12362 12363 _enable: function() { 12364 // restore title attributes 12365 this.element.find( this.options.items ).andSelf().each(function() { 12366 var element = $( this ); 12367 if ( element.data( "ui-tooltip-title" ) ) { 12368 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12369 } 12370 }); 12371 }, 12372 12373 open: function( event ) { 12374 var that = this, 12375 target = $( event ? event.target : this.element ) 12376 // we need closest here due to mouseover bubbling, 12377 // but always pointing at the same event target 12378 .closest( this.options.items ); 12379 12380 // No element to show a tooltip for or the tooltip is already open 12381 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 12382 return; 12383 } 12384 12385 if ( target.attr( "title" ) ) { 12386 target.data( "ui-tooltip-title", target.attr( "title" ) ); 12387 } 12388 12389 target.data( "ui-tooltip-open", true ); 12390 12391 // kill parent tooltips, custom or native, for hover 12392 if ( event && event.type === "mouseover" ) { 12393 target.parents().each(function() { 12394 var parent = $( this ), 12395 blurEvent; 12396 if ( parent.data( "ui-tooltip-open" ) ) { 12397 blurEvent = $.Event( "blur" ); 12398 blurEvent.target = blurEvent.currentTarget = this; 12399 that.close( blurEvent, true ); 12400 } 12401 if ( parent.attr( "title" ) ) { 12402 parent.uniqueId(); 12403 that.parents[ this.id ] = { 12404 element: this, 12405 title: parent.attr( "title" ) 12406 }; 12407 parent.attr( "title", "" ); 12408 } 12409 }); 12410 } 12411 12412 this._updateContent( target, event ); 12413 }, 12414 12415 _updateContent: function( target, event ) { 12416 var content, 12417 contentOption = this.options.content, 12418 that = this, 12419 eventType = event ? event.type : null; 12420 12421 if ( typeof contentOption === "string" ) { 12422 return this._open( event, target, contentOption ); 12423 } 12424 12425 content = contentOption.call( target[0], function( response ) { 12426 // ignore async response if tooltip was closed already 12427 if ( !target.data( "ui-tooltip-open" ) ) { 12428 return; 12429 } 12430 // IE may instantly serve a cached response for ajax requests 12431 // delay this call to _open so the other call to _open runs first 12432 that._delay(function() { 12433 // jQuery creates a special event for focusin when it doesn't 12434 // exist natively. To improve performance, the native event 12435 // object is reused and the type is changed. Therefore, we can't 12436 // rely on the type being correct after the event finished 12437 // bubbling, so we set it back to the previous value. (#8740) 12438 if ( event ) { 12439 event.type = eventType; 12440 } 12441 this._open( event, target, response ); 12442 }); 12443 }); 12444 if ( content ) { 12445 this._open( event, target, content ); 12446 } 12447 }, 12448 12449 _open: function( event, target, content ) { 12450 var tooltip, events, delayedShow, 12451 positionOption = $.extend( {}, this.options.position ); 12452 12453 if ( !content ) { 12454 return; 12455 } 12456 12457 // Content can be updated multiple times. If the tooltip already 12458 // exists, then just update the content and bail. 12459 tooltip = this._find( target ); 12460 if ( tooltip.length ) { 12461 tooltip.find( ".ui-tooltip-content" ).html( content ); 12462 return; 12463 } 12464 12465 // if we have a title, clear it to prevent the native tooltip 12466 // we have to check first to avoid defining a title if none exists 12467 // (we don't want to cause an element to start matching [title]) 12468 // 12469 // We use removeAttr only for key events, to allow IE to export the correct 12470 // accessible attributes. For mouse events, set to empty string to avoid 12471 // native tooltip showing up (happens only when removing inside mouseover). 12472 if ( target.is( "[title]" ) ) { 12473 if ( event && event.type === "mouseover" ) { 12474 target.attr( "title", "" ); 12475 } else { 12476 target.removeAttr( "title" ); 12477 } 12478 } 12479 12480 tooltip = this._tooltip( target ); 12481 addDescribedBy( target, tooltip.attr( "id" ) ); 12482 tooltip.find( ".ui-tooltip-content" ).html( content ); 12483 12484 function position( event ) { 12485 positionOption.of = event; 12486 if ( tooltip.is( ":hidden" ) ) { 12487 return; 12488 } 12489 tooltip.position( positionOption ); 12490 } 12491 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 12492 this._on( this.document, { 12493 mousemove: position 12494 }); 12495 // trigger once to override element-relative positioning 12496 position( event ); 12497 } else { 12498 tooltip.position( $.extend({ 12499 of: target 12500 }, this.options.position ) ); 12501 } 12502 12503 tooltip.hide(); 12504 12505 this._show( tooltip, this.options.show ); 12506 // Handle tracking tooltips that are shown with a delay (#8644). As soon 12507 // as the tooltip is visible, position the tooltip using the most recent 12508 // event. 12509 if ( this.options.show && this.options.show.delay ) { 12510 delayedShow = setInterval(function() { 12511 if ( tooltip.is( ":visible" ) ) { 12512 position( positionOption.of ); 12513 clearInterval( delayedShow ); 12514 } 12515 }, $.fx.interval ); 12516 } 12517 12518 this._trigger( "open", event, { tooltip: tooltip } ); 12519 12520 events = { 12521 keyup: function( event ) { 12522 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 12523 var fakeEvent = $.Event(event); 12524 fakeEvent.currentTarget = target[0]; 12525 this.close( fakeEvent, true ); 12526 } 12527 }, 12528 remove: function() { 12529 this._removeTooltip( tooltip ); 12530 } 12531 }; 12532 if ( !event || event.type === "mouseover" ) { 12533 events.mouseleave = "close"; 12534 } 12535 if ( !event || event.type === "focusin" ) { 12536 events.focusout = "close"; 12537 } 12538 this._on( true, target, events ); 12539 }, 12540 12541 close: function( event ) { 12542 var that = this, 12543 target = $( event ? event.currentTarget : this.element ), 12544 tooltip = this._find( target ); 12545 12546 // disabling closes the tooltip, so we need to track when we're closing 12547 // to avoid an infinite loop in case the tooltip becomes disabled on close 12548 if ( this.closing ) { 12549 return; 12550 } 12551 12552 // only set title if we had one before (see comment in _open()) 12553 if ( target.data( "ui-tooltip-title" ) ) { 12554 target.attr( "title", target.data( "ui-tooltip-title" ) ); 12555 } 12556 12557 removeDescribedBy( target ); 12558 12559 tooltip.stop( true ); 12560 this._hide( tooltip, this.options.hide, function() { 12561 that._removeTooltip( $( this ) ); 12562 }); 12563 12564 target.removeData( "ui-tooltip-open" ); 12565 this._off( target, "mouseleave focusout keyup" ); 12566 // Remove 'remove' binding only on delegated targets 12567 if ( target[0] !== this.element[0] ) { 12568 this._off( target, "remove" ); 12569 } 12570 this._off( this.document, "mousemove" ); 12571 12572 if ( event && event.type === "mouseleave" ) { 12573 $.each( this.parents, function( id, parent ) { 12574 $( parent.element ).attr( "title", parent.title ); 12575 delete that.parents[ id ]; 12576 }); 12577 } 12578 12579 this.closing = true; 12580 this._trigger( "close", event, { tooltip: tooltip } ); 12581 this.closing = false; 12582 }, 12583 12584 _tooltip: function( element ) { 12585 var id = "ui-tooltip-" + increments++, 12586 tooltip = $( "<div>" ) 12587 .attr({ 12588 id: id, 12589 role: "tooltip" 12590 }) 12591 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 12592 ( this.options.tooltipClass || "" ) ); 12593 $( "<div>" ) 12594 .addClass( "ui-tooltip-content" ) 12595 .appendTo( tooltip ); 12596 tooltip.appendTo( this.document[0].body ); 12597 if ( $.fn.bgiframe ) { 12598 tooltip.bgiframe(); 12599 } 12600 this.tooltips[ id ] = element; 12601 return tooltip; 12602 }, 12603 12604 _find: function( target ) { 12605 var id = target.data( "ui-tooltip-id" ); 12606 return id ? $( "#" + id ) : $(); 12607 }, 12608 12609 _removeTooltip: function( tooltip ) { 12610 tooltip.remove(); 12611 delete this.tooltips[ tooltip.attr( "id" ) ]; 12612 }, 12613 12614 _destroy: function() { 12615 var that = this; 12616 12617 // close open tooltips 12618 $.each( this.tooltips, function( id, element ) { 12619 // Delegate to close method to handle common cleanup 12620 var event = $.Event( "blur" ); 12621 event.target = event.currentTarget = element[0]; 12622 that.close( event, true ); 12623 12624 // Remove immediately; destroying an open tooltip doesn't use the 12625 // hide animation 12626 $( "#" + id ).remove(); 12627 12628 // Restore the title 12629 if ( element.data( "ui-tooltip-title" ) ) { 12630 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12631 element.removeData( "ui-tooltip-title" ); 12632 } 12633 }); 12634 } 12635}); 12636 12637}( jQuery ) ); 12638;(jQuery.effects || (function($, undefined) { 12639 12640var backCompat = $.uiBackCompat !== false, 12641 // prefix used for storing data on .data() 12642 dataSpace = "ui-effects-"; 12643 12644$.effects = { 12645 effect: {} 12646}; 12647 12648/*! 12649 * jQuery Color Animations v2.0.0 12650 * http://jquery.com/ 12651 * 12652 * Copyright 2012 jQuery Foundation and other contributors 12653 * Released under the MIT license. 12654 * http://jquery.org/license 12655 * 12656 * Date: Mon Aug 13 13:41:02 2012 -0500 12657 */ 12658(function( jQuery, undefined ) { 12659 12660 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), 12661 12662 // plusequals test for += 100 -= 100 12663 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 12664 // a set of RE's that can match strings and generate color tuples. 12665 stringParsers = [{ 12666 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12667 parse: function( execResult ) { 12668 return [ 12669 execResult[ 1 ], 12670 execResult[ 2 ], 12671 execResult[ 3 ], 12672 execResult[ 4 ] 12673 ]; 12674 } 12675 }, { 12676 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12677 parse: function( execResult ) { 12678 return [ 12679 execResult[ 1 ] * 2.55, 12680 execResult[ 2 ] * 2.55, 12681 execResult[ 3 ] * 2.55, 12682 execResult[ 4 ] 12683 ]; 12684 } 12685 }, { 12686 // this regex ignores A-F because it's compared against an already lowercased string 12687 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 12688 parse: function( execResult ) { 12689 return [ 12690 parseInt( execResult[ 1 ], 16 ), 12691 parseInt( execResult[ 2 ], 16 ), 12692 parseInt( execResult[ 3 ], 16 ) 12693 ]; 12694 } 12695 }, { 12696 // this regex ignores A-F because it's compared against an already lowercased string 12697 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 12698 parse: function( execResult ) { 12699 return [ 12700 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 12701 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 12702 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 12703 ]; 12704 } 12705 }, { 12706 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 12707 space: "hsla", 12708 parse: function( execResult ) { 12709 return [ 12710 execResult[ 1 ], 12711 execResult[ 2 ] / 100, 12712 execResult[ 3 ] / 100, 12713 execResult[ 4 ] 12714 ]; 12715 } 12716 }], 12717 12718 // jQuery.Color( ) 12719 color = jQuery.Color = function( color, green, blue, alpha ) { 12720 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 12721 }, 12722 spaces = { 12723 rgba: { 12724 props: { 12725 red: { 12726 idx: 0, 12727 type: "byte" 12728 }, 12729 green: { 12730 idx: 1, 12731 type: "byte" 12732 }, 12733 blue: { 12734 idx: 2, 12735 type: "byte" 12736 } 12737 } 12738 }, 12739 12740 hsla: { 12741 props: { 12742 hue: { 12743 idx: 0, 12744 type: "degrees" 12745 }, 12746 saturation: { 12747 idx: 1, 12748 type: "percent" 12749 }, 12750 lightness: { 12751 idx: 2, 12752 type: "percent" 12753 } 12754 } 12755 } 12756 }, 12757 propTypes = { 12758 "byte": { 12759 floor: true, 12760 max: 255 12761 }, 12762 "percent": { 12763 max: 1 12764 }, 12765 "degrees": { 12766 mod: 360, 12767 floor: true 12768 } 12769 }, 12770 support = color.support = {}, 12771 12772 // element for support tests 12773 supportElem = jQuery( "<p>" )[ 0 ], 12774 12775 // colors = jQuery.Color.names 12776 colors, 12777 12778 // local aliases of functions called often 12779 each = jQuery.each; 12780 12781// determine rgba support immediately 12782supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 12783support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 12784 12785// define cache name and alpha properties 12786// for rgba and hsla spaces 12787each( spaces, function( spaceName, space ) { 12788 space.cache = "_" + spaceName; 12789 space.props.alpha = { 12790 idx: 3, 12791 type: "percent", 12792 def: 1 12793 }; 12794}); 12795 12796function clamp( value, prop, allowEmpty ) { 12797 var type = propTypes[ prop.type ] || {}; 12798 12799 if ( value == null ) { 12800 return (allowEmpty || !prop.def) ? null : prop.def; 12801 } 12802 12803 // ~~ is an short way of doing floor for positive numbers 12804 value = type.floor ? ~~value : parseFloat( value ); 12805 12806 // IE will pass in empty strings as value for alpha, 12807 // which will hit this case 12808 if ( isNaN( value ) ) { 12809 return prop.def; 12810 } 12811 12812 if ( type.mod ) { 12813 // we add mod before modding to make sure that negatives values 12814 // get converted properly: -10 -> 350 12815 return (value + type.mod) % type.mod; 12816 } 12817 12818 // for now all property types without mod have min and max 12819 return 0 > value ? 0 : type.max < value ? type.max : value; 12820} 12821 12822function stringParse( string ) { 12823 var inst = color(), 12824 rgba = inst._rgba = []; 12825 12826 string = string.toLowerCase(); 12827 12828 each( stringParsers, function( i, parser ) { 12829 var parsed, 12830 match = parser.re.exec( string ), 12831 values = match && parser.parse( match ), 12832 spaceName = parser.space || "rgba"; 12833 12834 if ( values ) { 12835 parsed = inst[ spaceName ]( values ); 12836 12837 // if this was an rgba parse the assignment might happen twice 12838 // oh well.... 12839 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12840 rgba = inst._rgba = parsed._rgba; 12841 12842 // exit each( stringParsers ) here because we matched 12843 return false; 12844 } 12845 }); 12846 12847 // Found a stringParser that handled it 12848 if ( rgba.length ) { 12849 12850 // if this came from a parsed string, force "transparent" when alpha is 0 12851 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12852 if ( rgba.join() === "0,0,0,0" ) { 12853 jQuery.extend( rgba, colors.transparent ); 12854 } 12855 return inst; 12856 } 12857 12858 // named colors 12859 return colors[ string ]; 12860} 12861 12862color.fn = jQuery.extend( color.prototype, { 12863 parse: function( red, green, blue, alpha ) { 12864 if ( red === undefined ) { 12865 this._rgba = [ null, null, null, null ]; 12866 return this; 12867 } 12868 if ( red.jquery || red.nodeType ) { 12869 red = jQuery( red ).css( green ); 12870 green = undefined; 12871 } 12872 12873 var inst = this, 12874 type = jQuery.type( red ), 12875 rgba = this._rgba = []; 12876 12877 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12878 if ( green !== undefined ) { 12879 red = [ red, green, blue, alpha ]; 12880 type = "array"; 12881 } 12882 12883 if ( type === "string" ) { 12884 return this.parse( stringParse( red ) || colors._default ); 12885 } 12886 12887 if ( type === "array" ) { 12888 each( spaces.rgba.props, function( key, prop ) { 12889 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 12890 }); 12891 return this; 12892 } 12893 12894 if ( type === "object" ) { 12895 if ( red instanceof color ) { 12896 each( spaces, function( spaceName, space ) { 12897 if ( red[ space.cache ] ) { 12898 inst[ space.cache ] = red[ space.cache ].slice(); 12899 } 12900 }); 12901 } else { 12902 each( spaces, function( spaceName, space ) { 12903 var cache = space.cache; 12904 each( space.props, function( key, prop ) { 12905 12906 // if the cache doesn't exist, and we know how to convert 12907 if ( !inst[ cache ] && space.to ) { 12908 12909 // if the value was null, we don't need to copy it 12910 // if the key was alpha, we don't need to copy it either 12911 if ( key === "alpha" || red[ key ] == null ) { 12912 return; 12913 } 12914 inst[ cache ] = space.to( inst._rgba ); 12915 } 12916 12917 // this is the only case where we allow nulls for ALL properties. 12918 // call clamp with alwaysAllowEmpty 12919 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 12920 }); 12921 12922 // everything defined but alpha? 12923 if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 12924 // use the default of 1 12925 inst[ cache ][ 3 ] = 1; 12926 if ( space.from ) { 12927 inst._rgba = space.from( inst[ cache ] ); 12928 } 12929 } 12930 }); 12931 } 12932 return this; 12933 } 12934 }, 12935 is: function( compare ) { 12936 var is = color( compare ), 12937 same = true, 12938 inst = this; 12939 12940 each( spaces, function( _, space ) { 12941 var localCache, 12942 isCache = is[ space.cache ]; 12943 if (isCache) { 12944 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 12945 each( space.props, function( _, prop ) { 12946 if ( isCache[ prop.idx ] != null ) { 12947 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 12948 return same; 12949 } 12950 }); 12951 } 12952 return same; 12953 }); 12954 return same; 12955 }, 12956 _space: function() { 12957 var used = [], 12958 inst = this; 12959 each( spaces, function( spaceName, space ) { 12960 if ( inst[ space.cache ] ) { 12961 used.push( spaceName ); 12962 } 12963 }); 12964 return used.pop(); 12965 }, 12966 transition: function( other, distance ) { 12967 var end = color( other ), 12968 spaceName = end._space(), 12969 space = spaces[ spaceName ], 12970 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 12971 start = startColor[ space.cache ] || space.to( startColor._rgba ), 12972 result = start.slice(); 12973 12974 end = end[ space.cache ]; 12975 each( space.props, function( key, prop ) { 12976 var index = prop.idx, 12977 startValue = start[ index ], 12978 endValue = end[ index ], 12979 type = propTypes[ prop.type ] || {}; 12980 12981 // if null, don't override start value 12982 if ( endValue === null ) { 12983 return; 12984 } 12985 // if null - use end 12986 if ( startValue === null ) { 12987 result[ index ] = endValue; 12988 } else { 12989 if ( type.mod ) { 12990 if ( endValue - startValue > type.mod / 2 ) { 12991 startValue += type.mod; 12992 } else if ( startValue - endValue > type.mod / 2 ) { 12993 startValue -= type.mod; 12994 } 12995 } 12996 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 12997 } 12998 }); 12999 return this[ spaceName ]( result ); 13000 }, 13001 blend: function( opaque ) { 13002 // if we are already opaque - return ourself 13003 if ( this._rgba[ 3 ] === 1 ) { 13004 return this; 13005 } 13006 13007 var rgb = this._rgba.slice(), 13008 a = rgb.pop(), 13009 blend = color( opaque )._rgba; 13010 13011 return color( jQuery.map( rgb, function( v, i ) { 13012 return ( 1 - a ) * blend[ i ] + a * v; 13013 })); 13014 }, 13015 toRgbaString: function() { 13016 var prefix = "rgba(", 13017 rgba = jQuery.map( this._rgba, function( v, i ) { 13018 return v == null ? ( i > 2 ? 1 : 0 ) : v; 13019 }); 13020 13021 if ( rgba[ 3 ] === 1 ) { 13022 rgba.pop(); 13023 prefix = "rgb("; 13024 } 13025 13026 return prefix + rgba.join() + ")"; 13027 }, 13028 toHslaString: function() { 13029 var prefix = "hsla(", 13030 hsla = jQuery.map( this.hsla(), function( v, i ) { 13031 if ( v == null ) { 13032 v = i > 2 ? 1 : 0; 13033 } 13034 13035 // catch 1 and 2 13036 if ( i && i < 3 ) { 13037 v = Math.round( v * 100 ) + "%"; 13038 } 13039 return v; 13040 }); 13041 13042 if ( hsla[ 3 ] === 1 ) { 13043 hsla.pop(); 13044 prefix = "hsl("; 13045 } 13046 return prefix + hsla.join() + ")"; 13047 }, 13048 toHexString: function( includeAlpha ) { 13049 var rgba = this._rgba.slice(), 13050 alpha = rgba.pop(); 13051 13052 if ( includeAlpha ) { 13053 rgba.push( ~~( alpha * 255 ) ); 13054 } 13055 13056 return "#" + jQuery.map( rgba, function( v ) { 13057 13058 // default to 0 when nulls exist 13059 v = ( v || 0 ).toString( 16 ); 13060 return v.length === 1 ? "0" + v : v; 13061 }).join(""); 13062 }, 13063 toString: function() { 13064 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 13065 } 13066}); 13067color.fn.parse.prototype = color.fn; 13068 13069// hsla conversions adapted from: 13070// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 13071 13072function hue2rgb( p, q, h ) { 13073 h = ( h + 1 ) % 1; 13074 if ( h * 6 < 1 ) { 13075 return p + (q - p) * h * 6; 13076 } 13077 if ( h * 2 < 1) { 13078 return q; 13079 } 13080 if ( h * 3 < 2 ) { 13081 return p + (q - p) * ((2/3) - h) * 6; 13082 } 13083 return p; 13084} 13085 13086spaces.hsla.to = function ( rgba ) { 13087 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 13088 return [ null, null, null, rgba[ 3 ] ]; 13089 } 13090 var r = rgba[ 0 ] / 255, 13091 g = rgba[ 1 ] / 255, 13092 b = rgba[ 2 ] / 255, 13093 a = rgba[ 3 ], 13094 max = Math.max( r, g, b ), 13095 min = Math.min( r, g, b ), 13096 diff = max - min, 13097 add = max + min, 13098 l = add * 0.5, 13099 h, s; 13100 13101 if ( min === max ) { 13102 h = 0; 13103 } else if ( r === max ) { 13104 h = ( 60 * ( g - b ) / diff ) + 360; 13105 } else if ( g === max ) { 13106 h = ( 60 * ( b - r ) / diff ) + 120; 13107 } else { 13108 h = ( 60 * ( r - g ) / diff ) + 240; 13109 } 13110 13111 if ( l === 0 || l === 1 ) { 13112 s = l; 13113 } else if ( l <= 0.5 ) { 13114 s = diff / add; 13115 } else { 13116 s = diff / ( 2 - add ); 13117 } 13118 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 13119}; 13120 13121spaces.hsla.from = function ( hsla ) { 13122 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 13123 return [ null, null, null, hsla[ 3 ] ]; 13124 } 13125 var h = hsla[ 0 ] / 360, 13126 s = hsla[ 1 ], 13127 l = hsla[ 2 ], 13128 a = hsla[ 3 ], 13129 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 13130 p = 2 * l - q; 13131 13132 return [ 13133 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 13134 Math.round( hue2rgb( p, q, h ) * 255 ), 13135 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 13136 a 13137 ]; 13138}; 13139 13140 13141each( spaces, function( spaceName, space ) { 13142 var props = space.props, 13143 cache = space.cache, 13144 to = space.to, 13145 from = space.from; 13146 13147 // makes rgba() and hsla() 13148 color.fn[ spaceName ] = function( value ) { 13149 13150 // generate a cache for this space if it doesn't exist 13151 if ( to && !this[ cache ] ) { 13152 this[ cache ] = to( this._rgba ); 13153 } 13154 if ( value === undefined ) { 13155 return this[ cache ].slice(); 13156 } 13157 13158 var ret, 13159 type = jQuery.type( value ), 13160 arr = ( type === "array" || type === "object" ) ? value : arguments, 13161 local = this[ cache ].slice(); 13162 13163 each( props, function( key, prop ) { 13164 var val = arr[ type === "object" ? key : prop.idx ]; 13165 if ( val == null ) { 13166 val = local[ prop.idx ]; 13167 } 13168 local[ prop.idx ] = clamp( val, prop ); 13169 }); 13170 13171 if ( from ) { 13172 ret = color( from( local ) ); 13173 ret[ cache ] = local; 13174 return ret; 13175 } else { 13176 return color( local ); 13177 } 13178 }; 13179 13180 // makes red() green() blue() alpha() hue() saturation() lightness() 13181 each( props, function( key, prop ) { 13182 // alpha is included in more than one space 13183 if ( color.fn[ key ] ) { 13184 return; 13185 } 13186 color.fn[ key ] = function( value ) { 13187 var vtype = jQuery.type( value ), 13188 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 13189 local = this[ fn ](), 13190 cur = local[ prop.idx ], 13191 match; 13192 13193 if ( vtype === "undefined" ) { 13194 return cur; 13195 } 13196 13197 if ( vtype === "function" ) { 13198 value = value.call( this, cur ); 13199 vtype = jQuery.type( value ); 13200 } 13201 if ( value == null && prop.empty ) { 13202 return this; 13203 } 13204 if ( vtype === "string" ) { 13205 match = rplusequals.exec( value ); 13206 if ( match ) { 13207 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 13208 } 13209 } 13210 local[ prop.idx ] = value; 13211 return this[ fn ]( local ); 13212 }; 13213 }); 13214}); 13215 13216// add .fx.step functions 13217each( stepHooks, function( i, hook ) { 13218 jQuery.cssHooks[ hook ] = { 13219 set: function( elem, value ) { 13220 var parsed, curElem, 13221 backgroundColor = ""; 13222 13223 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 13224 value = color( parsed || value ); 13225 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 13226 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 13227 while ( 13228 (backgroundColor === "" || backgroundColor === "transparent") && 13229 curElem && curElem.style 13230 ) { 13231 try { 13232 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 13233 curElem = curElem.parentNode; 13234 } catch ( e ) { 13235 } 13236 } 13237 13238 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 13239 backgroundColor : 13240 "_default" ); 13241 } 13242 13243 value = value.toRgbaString(); 13244 } 13245 try { 13246 elem.style[ hook ] = value; 13247 } catch( error ) { 13248 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 13249 } 13250 } 13251 }; 13252 jQuery.fx.step[ hook ] = function( fx ) { 13253 if ( !fx.colorInit ) { 13254 fx.start = color( fx.elem, hook ); 13255 fx.end = color( fx.end ); 13256 fx.colorInit = true; 13257 } 13258 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 13259 }; 13260}); 13261 13262jQuery.cssHooks.borderColor = { 13263 expand: function( value ) { 13264 var expanded = {}; 13265 13266 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 13267 expanded[ "border" + part + "Color" ] = value; 13268 }); 13269 return expanded; 13270 } 13271}; 13272 13273// Basic color names only. 13274// Usage of any of the other color names requires adding yourself or including 13275// jquery.color.svg-names.js. 13276colors = jQuery.Color.names = { 13277 // 4.1. Basic color keywords 13278 aqua: "#00ffff", 13279 black: "#000000", 13280 blue: "#0000ff", 13281 fuchsia: "#ff00ff", 13282 gray: "#808080", 13283 green: "#008000", 13284 lime: "#00ff00", 13285 maroon: "#800000", 13286 navy: "#000080", 13287 olive: "#808000", 13288 purple: "#800080", 13289 red: "#ff0000", 13290 silver: "#c0c0c0", 13291 teal: "#008080", 13292 white: "#ffffff", 13293 yellow: "#ffff00", 13294 13295 // 4.2.3. "transparent" color keyword 13296 transparent: [ null, null, null, 0 ], 13297 13298 _default: "#ffffff" 13299}; 13300 13301})( jQuery ); 13302 13303 13304 13305/******************************************************************************/ 13306/****************************** CLASS ANIMATIONS ******************************/ 13307/******************************************************************************/ 13308(function() { 13309 13310var classAnimationActions = [ "add", "remove", "toggle" ], 13311 shorthandStyles = { 13312 border: 1, 13313 borderBottom: 1, 13314 borderColor: 1, 13315 borderLeft: 1, 13316 borderRight: 1, 13317 borderTop: 1, 13318 borderWidth: 1, 13319 margin: 1, 13320 padding: 1 13321 }; 13322 13323$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 13324 $.fx.step[ prop ] = function( fx ) { 13325 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 13326 jQuery.style( fx.elem, prop, fx.end ); 13327 fx.setAttr = true; 13328 } 13329 }; 13330}); 13331 13332function getElementStyles() { 13333 var style = this.ownerDocument.defaultView ? 13334 this.ownerDocument.defaultView.getComputedStyle( this, null ) : 13335 this.currentStyle, 13336 newStyle = {}, 13337 key, 13338 len; 13339 13340 // webkit enumerates style porperties 13341 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 13342 len = style.length; 13343 while ( len-- ) { 13344 key = style[ len ]; 13345 if ( typeof style[ key ] === "string" ) { 13346 newStyle[ $.camelCase( key ) ] = style[ key ]; 13347 } 13348 } 13349 } else { 13350 for ( key in style ) { 13351 if ( typeof style[ key ] === "string" ) { 13352 newStyle[ key ] = style[ key ]; 13353 } 13354 } 13355 } 13356 13357 return newStyle; 13358} 13359 13360 13361function styleDifference( oldStyle, newStyle ) { 13362 var diff = {}, 13363 name, value; 13364 13365 for ( name in newStyle ) { 13366 value = newStyle[ name ]; 13367 if ( oldStyle[ name ] !== value ) { 13368 if ( !shorthandStyles[ name ] ) { 13369 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 13370 diff[ name ] = value; 13371 } 13372 } 13373 } 13374 } 13375 13376 return diff; 13377} 13378 13379$.effects.animateClass = function( value, duration, easing, callback ) { 13380 var o = $.speed( duration, easing, callback ); 13381 13382 return this.queue( function() { 13383 var animated = $( this ), 13384 baseClass = animated.attr( "class" ) || "", 13385 applyClassChange, 13386 allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; 13387 13388 // map the animated objects to store the original styles. 13389 allAnimations = allAnimations.map(function() { 13390 var el = $( this ); 13391 return { 13392 el: el, 13393 start: getElementStyles.call( this ) 13394 }; 13395 }); 13396 13397 // apply class change 13398 applyClassChange = function() { 13399 $.each( classAnimationActions, function(i, action) { 13400 if ( value[ action ] ) { 13401 animated[ action + "Class" ]( value[ action ] ); 13402 } 13403 }); 13404 }; 13405 applyClassChange(); 13406 13407 // map all animated objects again - calculate new styles and diff 13408 allAnimations = allAnimations.map(function() { 13409 this.end = getElementStyles.call( this.el[ 0 ] ); 13410 this.diff = styleDifference( this.start, this.end ); 13411 return this; 13412 }); 13413 13414 // apply original class 13415 animated.attr( "class", baseClass ); 13416 13417 // map all animated objects again - this time collecting a promise 13418 allAnimations = allAnimations.map(function() { 13419 var styleInfo = this, 13420 dfd = $.Deferred(), 13421 opts = jQuery.extend({}, o, { 13422 queue: false, 13423 complete: function() { 13424 dfd.resolve( styleInfo ); 13425 } 13426 }); 13427 13428 this.el.animate( this.diff, opts ); 13429 return dfd.promise(); 13430 }); 13431 13432 // once all animations have completed: 13433 $.when.apply( $, allAnimations.get() ).done(function() { 13434 13435 // set the final class 13436 applyClassChange(); 13437 13438 // for each animated element, 13439 // clear all css properties that were animated 13440 $.each( arguments, function() { 13441 var el = this.el; 13442 $.each( this.diff, function(key) { 13443 el.css( key, '' ); 13444 }); 13445 }); 13446 13447 // this is guarnteed to be there if you use jQuery.speed() 13448 // it also handles dequeuing the next anim... 13449 o.complete.call( animated[ 0 ] ); 13450 }); 13451 }); 13452}; 13453 13454$.fn.extend({ 13455 _addClass: $.fn.addClass, 13456 addClass: function( classNames, speed, easing, callback ) { 13457 return speed ? 13458 $.effects.animateClass.call( this, 13459 { add: classNames }, speed, easing, callback ) : 13460 this._addClass( classNames ); 13461 }, 13462 13463 _removeClass: $.fn.removeClass, 13464 removeClass: function( classNames, speed, easing, callback ) { 13465 return speed ? 13466 $.effects.animateClass.call( this, 13467 { remove: classNames }, speed, easing, callback ) : 13468 this._removeClass( classNames ); 13469 }, 13470 13471 _toggleClass: $.fn.toggleClass, 13472 toggleClass: function( classNames, force, speed, easing, callback ) { 13473 if ( typeof force === "boolean" || force === undefined ) { 13474 if ( !speed ) { 13475 // without speed parameter 13476 return this._toggleClass( classNames, force ); 13477 } else { 13478 return $.effects.animateClass.call( this, 13479 (force ? { add: classNames } : { remove: classNames }), 13480 speed, easing, callback ); 13481 } 13482 } else { 13483 // without force parameter 13484 return $.effects.animateClass.call( this, 13485 { toggle: classNames }, force, speed, easing ); 13486 } 13487 }, 13488 13489 switchClass: function( remove, add, speed, easing, callback) { 13490 return $.effects.animateClass.call( this, { 13491 add: add, 13492 remove: remove 13493 }, speed, easing, callback ); 13494 } 13495}); 13496 13497})(); 13498 13499/******************************************************************************/ 13500/*********************************** EFFECTS **********************************/ 13501/******************************************************************************/ 13502 13503(function() { 13504 13505$.extend( $.effects, { 13506 version: "1.9.2", 13507 13508 // Saves a set of properties in a data storage 13509 save: function( element, set ) { 13510 for( var i=0; i < set.length; i++ ) { 13511 if ( set[ i ] !== null ) { 13512 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 13513 } 13514 } 13515 }, 13516 13517 // Restores a set of previously saved properties from a data storage 13518 restore: function( element, set ) { 13519 var val, i; 13520 for( i=0; i < set.length; i++ ) { 13521 if ( set[ i ] !== null ) { 13522 val = element.data( dataSpace + set[ i ] ); 13523 // support: jQuery 1.6.2 13524 // http://bugs.jquery.com/ticket/9917 13525 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 13526 // We can't differentiate between "" and 0 here, so we just assume 13527 // empty string since it's likely to be a more common value... 13528 if ( val === undefined ) { 13529 val = ""; 13530 } 13531 element.css( set[ i ], val ); 13532 } 13533 } 13534 }, 13535 13536 setMode: function( el, mode ) { 13537 if (mode === "toggle") { 13538 mode = el.is( ":hidden" ) ? "show" : "hide"; 13539 } 13540 return mode; 13541 }, 13542 13543 // Translates a [top,left] array into a baseline value 13544 // this should be a little more flexible in the future to handle a string & hash 13545 getBaseline: function( origin, original ) { 13546 var y, x; 13547 switch ( origin[ 0 ] ) { 13548 case "top": y = 0; break; 13549 case "middle": y = 0.5; break; 13550 case "bottom": y = 1; break; 13551 default: y = origin[ 0 ] / original.height; 13552 } 13553 switch ( origin[ 1 ] ) { 13554 case "left": x = 0; break; 13555 case "center": x = 0.5; break; 13556 case "right": x = 1; break; 13557 default: x = origin[ 1 ] / original.width; 13558 } 13559 return { 13560 x: x, 13561 y: y 13562 }; 13563 }, 13564 13565 // Wraps the element around a wrapper that copies position properties 13566 createWrapper: function( element ) { 13567 13568 // if the element is already wrapped, return it 13569 if ( element.parent().is( ".ui-effects-wrapper" )) { 13570 return element.parent(); 13571 } 13572 13573 // wrap the element 13574 var props = { 13575 width: element.outerWidth(true), 13576 height: element.outerHeight(true), 13577 "float": element.css( "float" ) 13578 }, 13579 wrapper = $( "<div></div>" ) 13580 .addClass( "ui-effects-wrapper" ) 13581 .css({ 13582 fontSize: "100%", 13583 background: "transparent", 13584 border: "none", 13585 margin: 0, 13586 padding: 0 13587 }), 13588 // Store the size in case width/height are defined in % - Fixes #5245 13589 size = { 13590 width: element.width(), 13591 height: element.height() 13592 }, 13593 active = document.activeElement; 13594 13595 // support: Firefox 13596 // Firefox incorrectly exposes anonymous content 13597 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 13598 try { 13599 active.id; 13600 } catch( e ) { 13601 active = document.body; 13602 } 13603 13604 element.wrap( wrapper ); 13605 13606 // Fixes #7595 - Elements lose focus when wrapped. 13607 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13608 $( active ).focus(); 13609 } 13610 13611 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 13612 13613 // transfer positioning properties to the wrapper 13614 if ( element.css( "position" ) === "static" ) { 13615 wrapper.css({ position: "relative" }); 13616 element.css({ position: "relative" }); 13617 } else { 13618 $.extend( props, { 13619 position: element.css( "position" ), 13620 zIndex: element.css( "z-index" ) 13621 }); 13622 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 13623 props[ pos ] = element.css( pos ); 13624 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 13625 props[ pos ] = "auto"; 13626 } 13627 }); 13628 element.css({ 13629 position: "relative", 13630 top: 0, 13631 left: 0, 13632 right: "auto", 13633 bottom: "auto" 13634 }); 13635 } 13636 element.css(size); 13637 13638 return wrapper.css( props ).show(); 13639 }, 13640 13641 removeWrapper: function( element ) { 13642 var active = document.activeElement; 13643 13644 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13645 element.parent().replaceWith( element ); 13646 13647 // Fixes #7595 - Elements lose focus when wrapped. 13648 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13649 $( active ).focus(); 13650 } 13651 } 13652 13653 13654 return element; 13655 }, 13656 13657 setTransition: function( element, list, factor, value ) { 13658 value = value || {}; 13659 $.each( list, function( i, x ) { 13660 var unit = element.cssUnit( x ); 13661 if ( unit[ 0 ] > 0 ) { 13662 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13663 } 13664 }); 13665 return value; 13666 } 13667}); 13668 13669// return an effect options object for the given parameters: 13670function _normalizeArguments( effect, options, speed, callback ) { 13671 13672 // allow passing all options as the first parameter 13673 if ( $.isPlainObject( effect ) ) { 13674 options = effect; 13675 effect = effect.effect; 13676 } 13677 13678 // convert to an object 13679 effect = { effect: effect }; 13680 13681 // catch (effect, null, ...) 13682 if ( options == null ) { 13683 options = {}; 13684 } 13685 13686 // catch (effect, callback) 13687 if ( $.isFunction( options ) ) { 13688 callback = options; 13689 speed = null; 13690 options = {}; 13691 } 13692 13693 // catch (effect, speed, ?) 13694 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13695 callback = speed; 13696 speed = options; 13697 options = {}; 13698 } 13699 13700 // catch (effect, options, callback) 13701 if ( $.isFunction( speed ) ) { 13702 callback = speed; 13703 speed = null; 13704 } 13705 13706 // add options to effect 13707 if ( options ) { 13708 $.extend( effect, options ); 13709 } 13710 13711 speed = speed || options.duration; 13712 effect.duration = $.fx.off ? 0 : 13713 typeof speed === "number" ? speed : 13714 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13715 $.fx.speeds._default; 13716 13717 effect.complete = callback || options.complete; 13718 13719 return effect; 13720} 13721 13722function standardSpeed( speed ) { 13723 // valid standard speeds 13724 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 13725 return true; 13726 } 13727 13728 // invalid strings - treat as "normal" speed 13729 if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { 13730 // TODO: remove in 2.0 (#7115) 13731 if ( backCompat && $.effects[ speed ] ) { 13732 return false; 13733 } 13734 return true; 13735 } 13736 13737 return false; 13738} 13739 13740$.fn.extend({ 13741 effect: function( /* effect, options, speed, callback */ ) { 13742 var args = _normalizeArguments.apply( this, arguments ), 13743 mode = args.mode, 13744 queue = args.queue, 13745 effectMethod = $.effects.effect[ args.effect ], 13746 13747 // DEPRECATED: remove in 2.0 (#7115) 13748 oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; 13749 13750 if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { 13751 // delegate to the original method (e.g., .show()) if possible 13752 if ( mode ) { 13753 return this[ mode ]( args.duration, args.complete ); 13754 } else { 13755 return this.each( function() { 13756 if ( args.complete ) { 13757 args.complete.call( this ); 13758 } 13759 }); 13760 } 13761 } 13762 13763 function run( next ) { 13764 var elem = $( this ), 13765 complete = args.complete, 13766 mode = args.mode; 13767 13768 function done() { 13769 if ( $.isFunction( complete ) ) { 13770 complete.call( elem[0] ); 13771 } 13772 if ( $.isFunction( next ) ) { 13773 next(); 13774 } 13775 } 13776 13777 // if the element is hiddden and mode is hide, 13778 // or element is visible and mode is show 13779 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13780 done(); 13781 } else { 13782 effectMethod.call( elem[0], args, done ); 13783 } 13784 } 13785 13786 // TODO: remove this check in 2.0, effectMethod will always be true 13787 if ( effectMethod ) { 13788 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 13789 } else { 13790 // DEPRECATED: remove in 2.0 (#7115) 13791 return oldEffectMethod.call(this, { 13792 options: args, 13793 duration: args.duration, 13794 callback: args.complete, 13795 mode: args.mode 13796 }); 13797 } 13798 }, 13799 13800 _show: $.fn.show, 13801 show: function( speed ) { 13802 if ( standardSpeed( speed ) ) { 13803 return this._show.apply( this, arguments ); 13804 } else { 13805 var args = _normalizeArguments.apply( this, arguments ); 13806 args.mode = "show"; 13807 return this.effect.call( this, args ); 13808 } 13809 }, 13810 13811 _hide: $.fn.hide, 13812 hide: function( speed ) { 13813 if ( standardSpeed( speed ) ) { 13814 return this._hide.apply( this, arguments ); 13815 } else { 13816 var args = _normalizeArguments.apply( this, arguments ); 13817 args.mode = "hide"; 13818 return this.effect.call( this, args ); 13819 } 13820 }, 13821 13822 // jQuery core overloads toggle and creates _toggle 13823 __toggle: $.fn.toggle, 13824 toggle: function( speed ) { 13825 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 13826 return this.__toggle.apply( this, arguments ); 13827 } else { 13828 var args = _normalizeArguments.apply( this, arguments ); 13829 args.mode = "toggle"; 13830 return this.effect.call( this, args ); 13831 } 13832 }, 13833 13834 // helper functions 13835 cssUnit: function(key) { 13836 var style = this.css( key ), 13837 val = []; 13838 13839 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13840 if ( style.indexOf( unit ) > 0 ) { 13841 val = [ parseFloat( style ), unit ]; 13842 } 13843 }); 13844 return val; 13845 } 13846}); 13847 13848})(); 13849 13850/******************************************************************************/ 13851/*********************************** EASING ***********************************/ 13852/******************************************************************************/ 13853 13854(function() { 13855 13856// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 13857 13858var baseEasings = {}; 13859 13860$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13861 baseEasings[ name ] = function( p ) { 13862 return Math.pow( p, i + 2 ); 13863 }; 13864}); 13865 13866$.extend( baseEasings, { 13867 Sine: function ( p ) { 13868 return 1 - Math.cos( p * Math.PI / 2 ); 13869 }, 13870 Circ: function ( p ) { 13871 return 1 - Math.sqrt( 1 - p * p ); 13872 }, 13873 Elastic: function( p ) { 13874 return p === 0 || p === 1 ? p : 13875 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 13876 }, 13877 Back: function( p ) { 13878 return p * p * ( 3 * p - 2 ); 13879 }, 13880 Bounce: function ( p ) { 13881 var pow2, 13882 bounce = 4; 13883 13884 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 13885 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 13886 } 13887}); 13888 13889$.each( baseEasings, function( name, easeIn ) { 13890 $.easing[ "easeIn" + name ] = easeIn; 13891 $.easing[ "easeOut" + name ] = function( p ) { 13892 return 1 - easeIn( 1 - p ); 13893 }; 13894 $.easing[ "easeInOut" + name ] = function( p ) { 13895 return p < 0.5 ? 13896 easeIn( p * 2 ) / 2 : 13897 1 - easeIn( p * -2 + 2 ) / 2; 13898 }; 13899}); 13900 13901})(); 13902 13903})(jQuery)); 13904(function( $, undefined ) { 13905 13906var rvertical = /up|down|vertical/, 13907 rpositivemotion = /up|left|vertical|horizontal/; 13908 13909$.effects.effect.blind = function( o, done ) { 13910 // Create element 13911 var el = $( this ), 13912 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13913 mode = $.effects.setMode( el, o.mode || "hide" ), 13914 direction = o.direction || "up", 13915 vertical = rvertical.test( direction ), 13916 ref = vertical ? "height" : "width", 13917 ref2 = vertical ? "top" : "left", 13918 motion = rpositivemotion.test( direction ), 13919 animation = {}, 13920 show = mode === "show", 13921 wrapper, distance, margin; 13922 13923 // if already wrapped, the wrapper's properties are my property. #6245 13924 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 13925 $.effects.save( el.parent(), props ); 13926 } else { 13927 $.effects.save( el, props ); 13928 } 13929 el.show(); 13930 wrapper = $.effects.createWrapper( el ).css({ 13931 overflow: "hidden" 13932 }); 13933 13934 distance = wrapper[ ref ](); 13935 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 13936 13937 animation[ ref ] = show ? distance : 0; 13938 if ( !motion ) { 13939 el 13940 .css( vertical ? "bottom" : "right", 0 ) 13941 .css( vertical ? "top" : "left", "auto" ) 13942 .css({ position: "absolute" }); 13943 13944 animation[ ref2 ] = show ? margin : distance + margin; 13945 } 13946 13947 // start at 0 if we are showing 13948 if ( show ) { 13949 wrapper.css( ref, 0 ); 13950 if ( ! motion ) { 13951 wrapper.css( ref2, margin + distance ); 13952 } 13953 } 13954 13955 // Animate 13956 wrapper.animate( animation, { 13957 duration: o.duration, 13958 easing: o.easing, 13959 queue: false, 13960 complete: function() { 13961 if ( mode === "hide" ) { 13962 el.hide(); 13963 } 13964 $.effects.restore( el, props ); 13965 $.effects.removeWrapper( el ); 13966 done(); 13967 } 13968 }); 13969 13970}; 13971 13972})(jQuery); 13973(function( $, undefined ) { 13974 13975$.effects.effect.bounce = function( o, done ) { 13976 var el = $( this ), 13977 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13978 13979 // defaults: 13980 mode = $.effects.setMode( el, o.mode || "effect" ), 13981 hide = mode === "hide", 13982 show = mode === "show", 13983 direction = o.direction || "up", 13984 distance = o.distance, 13985 times = o.times || 5, 13986 13987 // number of internal animations 13988 anims = times * 2 + ( show || hide ? 1 : 0 ), 13989 speed = o.duration / anims, 13990 easing = o.easing, 13991 13992 // utility: 13993 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 13994 motion = ( direction === "up" || direction === "left" ), 13995 i, 13996 upAnim, 13997 downAnim, 13998 13999 // we will need to re-assemble the queue to stack our animations in place 14000 queue = el.queue(), 14001 queuelen = queue.length; 14002 14003 // Avoid touching opacity to prevent clearType and PNG issues in IE 14004 if ( show || hide ) { 14005 props.push( "opacity" ); 14006 } 14007 14008 $.effects.save( el, props ); 14009 el.show(); 14010 $.effects.createWrapper( el ); // Create Wrapper 14011 14012 // default distance for the BIGGEST bounce is the outer Distance / 3 14013 if ( !distance ) { 14014 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 14015 } 14016 14017 if ( show ) { 14018 downAnim = { opacity: 1 }; 14019 downAnim[ ref ] = 0; 14020 14021 // if we are showing, force opacity 0 and set the initial position 14022 // then do the "first" animation 14023 el.css( "opacity", 0 ) 14024 .css( ref, motion ? -distance * 2 : distance * 2 ) 14025 .animate( downAnim, speed, easing ); 14026 } 14027 14028 // start at the smallest distance if we are hiding 14029 if ( hide ) { 14030 distance = distance / Math.pow( 2, times - 1 ); 14031 } 14032 14033 downAnim = {}; 14034 downAnim[ ref ] = 0; 14035 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 14036 for ( i = 0; i < times; i++ ) { 14037 upAnim = {}; 14038 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14039 14040 el.animate( upAnim, speed, easing ) 14041 .animate( downAnim, speed, easing ); 14042 14043 distance = hide ? distance * 2 : distance / 2; 14044 } 14045 14046 // Last Bounce when Hiding 14047 if ( hide ) { 14048 upAnim = { opacity: 0 }; 14049 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14050 14051 el.animate( upAnim, speed, easing ); 14052 } 14053 14054 el.queue(function() { 14055 if ( hide ) { 14056 el.hide(); 14057 } 14058 $.effects.restore( el, props ); 14059 $.effects.removeWrapper( el ); 14060 done(); 14061 }); 14062 14063 // inject all the animations we just queued to be first in line (after "inprogress") 14064 if ( queuelen > 1) { 14065 queue.splice.apply( queue, 14066 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14067 } 14068 el.dequeue(); 14069 14070}; 14071 14072})(jQuery); 14073(function( $, undefined ) { 14074 14075$.effects.effect.clip = function( o, done ) { 14076 // Create element 14077 var el = $( this ), 14078 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14079 mode = $.effects.setMode( el, o.mode || "hide" ), 14080 show = mode === "show", 14081 direction = o.direction || "vertical", 14082 vert = direction === "vertical", 14083 size = vert ? "height" : "width", 14084 position = vert ? "top" : "left", 14085 animation = {}, 14086 wrapper, animate, distance; 14087 14088 // Save & Show 14089 $.effects.save( el, props ); 14090 el.show(); 14091 14092 // Create Wrapper 14093 wrapper = $.effects.createWrapper( el ).css({ 14094 overflow: "hidden" 14095 }); 14096 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 14097 distance = animate[ size ](); 14098 14099 // Shift 14100 if ( show ) { 14101 animate.css( size, 0 ); 14102 animate.css( position, distance / 2 ); 14103 } 14104 14105 // Create Animation Object: 14106 animation[ size ] = show ? distance : 0; 14107 animation[ position ] = show ? 0 : distance / 2; 14108 14109 // Animate 14110 animate.animate( animation, { 14111 queue: false, 14112 duration: o.duration, 14113 easing: o.easing, 14114 complete: function() { 14115 if ( !show ) { 14116 el.hide(); 14117 } 14118 $.effects.restore( el, props ); 14119 $.effects.removeWrapper( el ); 14120 done(); 14121 } 14122 }); 14123 14124}; 14125 14126})(jQuery); 14127(function( $, undefined ) { 14128 14129$.effects.effect.drop = function( o, done ) { 14130 14131 var el = $( this ), 14132 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 14133 mode = $.effects.setMode( el, o.mode || "hide" ), 14134 show = mode === "show", 14135 direction = o.direction || "left", 14136 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14137 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 14138 animation = { 14139 opacity: show ? 1 : 0 14140 }, 14141 distance; 14142 14143 // Adjust 14144 $.effects.save( el, props ); 14145 el.show(); 14146 $.effects.createWrapper( el ); 14147 14148 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 14149 14150 if ( show ) { 14151 el 14152 .css( "opacity", 0 ) 14153 .css( ref, motion === "pos" ? -distance : distance ); 14154 } 14155 14156 // Animation 14157 animation[ ref ] = ( show ? 14158 ( motion === "pos" ? "+=" : "-=" ) : 14159 ( motion === "pos" ? "-=" : "+=" ) ) + 14160 distance; 14161 14162 // Animate 14163 el.animate( animation, { 14164 queue: false, 14165 duration: o.duration, 14166 easing: o.easing, 14167 complete: function() { 14168 if ( mode === "hide" ) { 14169 el.hide(); 14170 } 14171 $.effects.restore( el, props ); 14172 $.effects.removeWrapper( el ); 14173 done(); 14174 } 14175 }); 14176}; 14177 14178})(jQuery); 14179(function( $, undefined ) { 14180 14181$.effects.effect.explode = function( o, done ) { 14182 14183 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 14184 cells = rows, 14185 el = $( this ), 14186 mode = $.effects.setMode( el, o.mode || "hide" ), 14187 show = mode === "show", 14188 14189 // show and then visibility:hidden the element before calculating offset 14190 offset = el.show().css( "visibility", "hidden" ).offset(), 14191 14192 // width and height of a piece 14193 width = Math.ceil( el.outerWidth() / cells ), 14194 height = Math.ceil( el.outerHeight() / rows ), 14195 pieces = [], 14196 14197 // loop 14198 i, j, left, top, mx, my; 14199 14200 // children animate complete: 14201 function childComplete() { 14202 pieces.push( this ); 14203 if ( pieces.length === rows * cells ) { 14204 animComplete(); 14205 } 14206 } 14207 14208 // clone the element for each row and cell. 14209 for( i = 0; i < rows ; i++ ) { // ===> 14210 top = offset.top + i * height; 14211 my = i - ( rows - 1 ) / 2 ; 14212 14213 for( j = 0; j < cells ; j++ ) { // ||| 14214 left = offset.left + j * width; 14215 mx = j - ( cells - 1 ) / 2 ; 14216 14217 // Create a clone of the now hidden main element that will be absolute positioned 14218 // within a wrapper div off the -left and -top equal to size of our pieces 14219 el 14220 .clone() 14221 .appendTo( "body" ) 14222 .wrap( "<div></div>" ) 14223 .css({ 14224 position: "absolute", 14225 visibility: "visible", 14226 left: -j * width, 14227 top: -i * height 14228 }) 14229 14230 // select the wrapper - make it overflow: hidden and absolute positioned based on 14231 // where the original was located +left and +top equal to the size of pieces 14232 .parent() 14233 .addClass( "ui-effects-explode" ) 14234 .css({ 14235 position: "absolute", 14236 overflow: "hidden", 14237 width: width, 14238 height: height, 14239 left: left + ( show ? mx * width : 0 ), 14240 top: top + ( show ? my * height : 0 ), 14241 opacity: show ? 0 : 1 14242 }).animate({ 14243 left: left + ( show ? 0 : mx * width ), 14244 top: top + ( show ? 0 : my * height ), 14245 opacity: show ? 1 : 0 14246 }, o.duration || 500, o.easing, childComplete ); 14247 } 14248 } 14249 14250 function animComplete() { 14251 el.css({ 14252 visibility: "visible" 14253 }); 14254 $( pieces ).remove(); 14255 if ( !show ) { 14256 el.hide(); 14257 } 14258 done(); 14259 } 14260}; 14261 14262})(jQuery); 14263(function( $, undefined ) { 14264 14265$.effects.effect.fade = function( o, done ) { 14266 var el = $( this ), 14267 mode = $.effects.setMode( el, o.mode || "toggle" ); 14268 14269 el.animate({ 14270 opacity: mode 14271 }, { 14272 queue: false, 14273 duration: o.duration, 14274 easing: o.easing, 14275 complete: done 14276 }); 14277}; 14278 14279})( jQuery ); 14280(function( $, undefined ) { 14281 14282$.effects.effect.fold = function( o, done ) { 14283 14284 // Create element 14285 var el = $( this ), 14286 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14287 mode = $.effects.setMode( el, o.mode || "hide" ), 14288 show = mode === "show", 14289 hide = mode === "hide", 14290 size = o.size || 15, 14291 percent = /([0-9]+)%/.exec( size ), 14292 horizFirst = !!o.horizFirst, 14293 widthFirst = show !== horizFirst, 14294 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 14295 duration = o.duration / 2, 14296 wrapper, distance, 14297 animation1 = {}, 14298 animation2 = {}; 14299 14300 $.effects.save( el, props ); 14301 el.show(); 14302 14303 // Create Wrapper 14304 wrapper = $.effects.createWrapper( el ).css({ 14305 overflow: "hidden" 14306 }); 14307 distance = widthFirst ? 14308 [ wrapper.width(), wrapper.height() ] : 14309 [ wrapper.height(), wrapper.width() ]; 14310 14311 if ( percent ) { 14312 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 14313 } 14314 if ( show ) { 14315 wrapper.css( horizFirst ? { 14316 height: 0, 14317 width: size 14318 } : { 14319 height: size, 14320 width: 0 14321 }); 14322 } 14323 14324 // Animation 14325 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 14326 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 14327 14328 // Animate 14329 wrapper 14330 .animate( animation1, duration, o.easing ) 14331 .animate( animation2, duration, o.easing, function() { 14332 if ( hide ) { 14333 el.hide(); 14334 } 14335 $.effects.restore( el, props ); 14336 $.effects.removeWrapper( el ); 14337 done(); 14338 }); 14339 14340}; 14341 14342})(jQuery); 14343(function( $, undefined ) { 14344 14345$.effects.effect.highlight = function( o, done ) { 14346 var elem = $( this ), 14347 props = [ "backgroundImage", "backgroundColor", "opacity" ], 14348 mode = $.effects.setMode( elem, o.mode || "show" ), 14349 animation = { 14350 backgroundColor: elem.css( "backgroundColor" ) 14351 }; 14352 14353 if (mode === "hide") { 14354 animation.opacity = 0; 14355 } 14356 14357 $.effects.save( elem, props ); 14358 14359 elem 14360 .show() 14361 .css({ 14362 backgroundImage: "none", 14363 backgroundColor: o.color || "#ffff99" 14364 }) 14365 .animate( animation, { 14366 queue: false, 14367 duration: o.duration, 14368 easing: o.easing, 14369 complete: function() { 14370 if ( mode === "hide" ) { 14371 elem.hide(); 14372 } 14373 $.effects.restore( elem, props ); 14374 done(); 14375 } 14376 }); 14377}; 14378 14379})(jQuery); 14380(function( $, undefined ) { 14381 14382$.effects.effect.pulsate = function( o, done ) { 14383 var elem = $( this ), 14384 mode = $.effects.setMode( elem, o.mode || "show" ), 14385 show = mode === "show", 14386 hide = mode === "hide", 14387 showhide = ( show || mode === "hide" ), 14388 14389 // showing or hiding leaves of the "last" animation 14390 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 14391 duration = o.duration / anims, 14392 animateTo = 0, 14393 queue = elem.queue(), 14394 queuelen = queue.length, 14395 i; 14396 14397 if ( show || !elem.is(":visible")) { 14398 elem.css( "opacity", 0 ).show(); 14399 animateTo = 1; 14400 } 14401 14402 // anims - 1 opacity "toggles" 14403 for ( i = 1; i < anims; i++ ) { 14404 elem.animate({ 14405 opacity: animateTo 14406 }, duration, o.easing ); 14407 animateTo = 1 - animateTo; 14408 } 14409 14410 elem.animate({ 14411 opacity: animateTo 14412 }, duration, o.easing); 14413 14414 elem.queue(function() { 14415 if ( hide ) { 14416 elem.hide(); 14417 } 14418 done(); 14419 }); 14420 14421 // We just queued up "anims" animations, we need to put them next in the queue 14422 if ( queuelen > 1 ) { 14423 queue.splice.apply( queue, 14424 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14425 } 14426 elem.dequeue(); 14427}; 14428 14429})(jQuery); 14430(function( $, undefined ) { 14431 14432$.effects.effect.puff = function( o, done ) { 14433 var elem = $( this ), 14434 mode = $.effects.setMode( elem, o.mode || "hide" ), 14435 hide = mode === "hide", 14436 percent = parseInt( o.percent, 10 ) || 150, 14437 factor = percent / 100, 14438 original = { 14439 height: elem.height(), 14440 width: elem.width(), 14441 outerHeight: elem.outerHeight(), 14442 outerWidth: elem.outerWidth() 14443 }; 14444 14445 $.extend( o, { 14446 effect: "scale", 14447 queue: false, 14448 fade: true, 14449 mode: mode, 14450 complete: done, 14451 percent: hide ? percent : 100, 14452 from: hide ? 14453 original : 14454 { 14455 height: original.height * factor, 14456 width: original.width * factor, 14457 outerHeight: original.outerHeight * factor, 14458 outerWidth: original.outerWidth * factor 14459 } 14460 }); 14461 14462 elem.effect( o ); 14463}; 14464 14465$.effects.effect.scale = function( o, done ) { 14466 14467 // Create element 14468 var el = $( this ), 14469 options = $.extend( true, {}, o ), 14470 mode = $.effects.setMode( el, o.mode || "effect" ), 14471 percent = parseInt( o.percent, 10 ) || 14472 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 14473 direction = o.direction || "both", 14474 origin = o.origin, 14475 original = { 14476 height: el.height(), 14477 width: el.width(), 14478 outerHeight: el.outerHeight(), 14479 outerWidth: el.outerWidth() 14480 }, 14481 factor = { 14482 y: direction !== "horizontal" ? (percent / 100) : 1, 14483 x: direction !== "vertical" ? (percent / 100) : 1 14484 }; 14485 14486 // We are going to pass this effect to the size effect: 14487 options.effect = "size"; 14488 options.queue = false; 14489 options.complete = done; 14490 14491 // Set default origin and restore for show/hide 14492 if ( mode !== "effect" ) { 14493 options.origin = origin || ["middle","center"]; 14494 options.restore = true; 14495 } 14496 14497 options.from = o.from || ( mode === "show" ? { 14498 height: 0, 14499 width: 0, 14500 outerHeight: 0, 14501 outerWidth: 0 14502 } : original ); 14503 options.to = { 14504 height: original.height * factor.y, 14505 width: original.width * factor.x, 14506 outerHeight: original.outerHeight * factor.y, 14507 outerWidth: original.outerWidth * factor.x 14508 }; 14509 14510 // Fade option to support puff 14511 if ( options.fade ) { 14512 if ( mode === "show" ) { 14513 options.from.opacity = 0; 14514 options.to.opacity = 1; 14515 } 14516 if ( mode === "hide" ) { 14517 options.from.opacity = 1; 14518 options.to.opacity = 0; 14519 } 14520 } 14521 14522 // Animate 14523 el.effect( options ); 14524 14525}; 14526 14527$.effects.effect.size = function( o, done ) { 14528 14529 // Create element 14530 var original, baseline, factor, 14531 el = $( this ), 14532 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 14533 14534 // Always restore 14535 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 14536 14537 // Copy for children 14538 props2 = [ "width", "height", "overflow" ], 14539 cProps = [ "fontSize" ], 14540 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 14541 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 14542 14543 // Set options 14544 mode = $.effects.setMode( el, o.mode || "effect" ), 14545 restore = o.restore || mode !== "effect", 14546 scale = o.scale || "both", 14547 origin = o.origin || [ "middle", "center" ], 14548 position = el.css( "position" ), 14549 props = restore ? props0 : props1, 14550 zero = { 14551 height: 0, 14552 width: 0, 14553 outerHeight: 0, 14554 outerWidth: 0 14555 }; 14556 14557 if ( mode === "show" ) { 14558 el.show(); 14559 } 14560 original = { 14561 height: el.height(), 14562 width: el.width(), 14563 outerHeight: el.outerHeight(), 14564 outerWidth: el.outerWidth() 14565 }; 14566 14567 if ( o.mode === "toggle" && mode === "show" ) { 14568 el.from = o.to || zero; 14569 el.to = o.from || original; 14570 } else { 14571 el.from = o.from || ( mode === "show" ? zero : original ); 14572 el.to = o.to || ( mode === "hide" ? zero : original ); 14573 } 14574 14575 // Set scaling factor 14576 factor = { 14577 from: { 14578 y: el.from.height / original.height, 14579 x: el.from.width / original.width 14580 }, 14581 to: { 14582 y: el.to.height / original.height, 14583 x: el.to.width / original.width 14584 } 14585 }; 14586 14587 // Scale the css box 14588 if ( scale === "box" || scale === "both" ) { 14589 14590 // Vertical props scaling 14591 if ( factor.from.y !== factor.to.y ) { 14592 props = props.concat( vProps ); 14593 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 14594 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 14595 } 14596 14597 // Horizontal props scaling 14598 if ( factor.from.x !== factor.to.x ) { 14599 props = props.concat( hProps ); 14600 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 14601 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 14602 } 14603 } 14604 14605 // Scale the content 14606 if ( scale === "content" || scale === "both" ) { 14607 14608 // Vertical props scaling 14609 if ( factor.from.y !== factor.to.y ) { 14610 props = props.concat( cProps ).concat( props2 ); 14611 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 14612 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 14613 } 14614 } 14615 14616 $.effects.save( el, props ); 14617 el.show(); 14618 $.effects.createWrapper( el ); 14619 el.css( "overflow", "hidden" ).css( el.from ); 14620 14621 // Adjust 14622 if (origin) { // Calculate baseline shifts 14623 baseline = $.effects.getBaseline( origin, original ); 14624 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 14625 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 14626 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 14627 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 14628 } 14629 el.css( el.from ); // set top & left 14630 14631 // Animate 14632 if ( scale === "content" || scale === "both" ) { // Scale the children 14633 14634 // Add margins/font-size 14635 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 14636 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 14637 props2 = props0.concat(vProps).concat(hProps); 14638 14639 el.find( "*[width]" ).each( function(){ 14640 var child = $( this ), 14641 c_original = { 14642 height: child.height(), 14643 width: child.width(), 14644 outerHeight: child.outerHeight(), 14645 outerWidth: child.outerWidth() 14646 }; 14647 if (restore) { 14648 $.effects.save(child, props2); 14649 } 14650 14651 child.from = { 14652 height: c_original.height * factor.from.y, 14653 width: c_original.width * factor.from.x, 14654 outerHeight: c_original.outerHeight * factor.from.y, 14655 outerWidth: c_original.outerWidth * factor.from.x 14656 }; 14657 child.to = { 14658 height: c_original.height * factor.to.y, 14659 width: c_original.width * factor.to.x, 14660 outerHeight: c_original.height * factor.to.y, 14661 outerWidth: c_original.width * factor.to.x 14662 }; 14663 14664 // Vertical props scaling 14665 if ( factor.from.y !== factor.to.y ) { 14666 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 14667 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 14668 } 14669 14670 // Horizontal props scaling 14671 if ( factor.from.x !== factor.to.x ) { 14672 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 14673 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 14674 } 14675 14676 // Animate children 14677 child.css( child.from ); 14678 child.animate( child.to, o.duration, o.easing, function() { 14679 14680 // Restore children 14681 if ( restore ) { 14682 $.effects.restore( child, props2 ); 14683 } 14684 }); 14685 }); 14686 } 14687 14688 // Animate 14689 el.animate( el.to, { 14690 queue: false, 14691 duration: o.duration, 14692 easing: o.easing, 14693 complete: function() { 14694 if ( el.to.opacity === 0 ) { 14695 el.css( "opacity", el.from.opacity ); 14696 } 14697 if( mode === "hide" ) { 14698 el.hide(); 14699 } 14700 $.effects.restore( el, props ); 14701 if ( !restore ) { 14702 14703 // we need to calculate our new positioning based on the scaling 14704 if ( position === "static" ) { 14705 el.css({ 14706 position: "relative", 14707 top: el.to.top, 14708 left: el.to.left 14709 }); 14710 } else { 14711 $.each([ "top", "left" ], function( idx, pos ) { 14712 el.css( pos, function( _, str ) { 14713 var val = parseInt( str, 10 ), 14714 toRef = idx ? el.to.left : el.to.top; 14715 14716 // if original was "auto", recalculate the new value from wrapper 14717 if ( str === "auto" ) { 14718 return toRef + "px"; 14719 } 14720 14721 return val + toRef + "px"; 14722 }); 14723 }); 14724 } 14725 } 14726 14727 $.effects.removeWrapper( el ); 14728 done(); 14729 } 14730 }); 14731 14732}; 14733 14734})(jQuery); 14735(function( $, undefined ) { 14736 14737$.effects.effect.shake = function( o, done ) { 14738 14739 var el = $( this ), 14740 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14741 mode = $.effects.setMode( el, o.mode || "effect" ), 14742 direction = o.direction || "left", 14743 distance = o.distance || 20, 14744 times = o.times || 3, 14745 anims = times * 2 + 1, 14746 speed = Math.round(o.duration/anims), 14747 ref = (direction === "up" || direction === "down") ? "top" : "left", 14748 positiveMotion = (direction === "up" || direction === "left"), 14749 animation = {}, 14750 animation1 = {}, 14751 animation2 = {}, 14752 i, 14753 14754 // we will need to re-assemble the queue to stack our animations in place 14755 queue = el.queue(), 14756 queuelen = queue.length; 14757 14758 $.effects.save( el, props ); 14759 el.show(); 14760 $.effects.createWrapper( el ); 14761 14762 // Animation 14763 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 14764 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 14765 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 14766 14767 // Animate 14768 el.animate( animation, speed, o.easing ); 14769 14770 // Shakes 14771 for ( i = 1; i < times; i++ ) { 14772 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 14773 } 14774 el 14775 .animate( animation1, speed, o.easing ) 14776 .animate( animation, speed / 2, o.easing ) 14777 .queue(function() { 14778 if ( mode === "hide" ) { 14779 el.hide(); 14780 } 14781 $.effects.restore( el, props ); 14782 $.effects.removeWrapper( el ); 14783 done(); 14784 }); 14785 14786 // inject all the animations we just queued to be first in line (after "inprogress") 14787 if ( queuelen > 1) { 14788 queue.splice.apply( queue, 14789 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14790 } 14791 el.dequeue(); 14792 14793}; 14794 14795})(jQuery); 14796(function( $, undefined ) { 14797 14798$.effects.effect.slide = function( o, done ) { 14799 14800 // Create element 14801 var el = $( this ), 14802 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 14803 mode = $.effects.setMode( el, o.mode || "show" ), 14804 show = mode === "show", 14805 direction = o.direction || "left", 14806 ref = (direction === "up" || direction === "down") ? "top" : "left", 14807 positiveMotion = (direction === "up" || direction === "left"), 14808 distance, 14809 animation = {}; 14810 14811 // Adjust 14812 $.effects.save( el, props ); 14813 el.show(); 14814 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 14815 14816 $.effects.createWrapper( el ).css({ 14817 overflow: "hidden" 14818 }); 14819 14820 if ( show ) { 14821 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 14822 } 14823 14824 // Animation 14825 animation[ ref ] = ( show ? 14826 ( positiveMotion ? "+=" : "-=") : 14827 ( positiveMotion ? "-=" : "+=")) + 14828 distance; 14829 14830 // Animate 14831 el.animate( animation, { 14832 queue: false, 14833 duration: o.duration, 14834 easing: o.easing, 14835 complete: function() { 14836 if ( mode === "hide" ) { 14837 el.hide(); 14838 } 14839 $.effects.restore( el, props ); 14840 $.effects.removeWrapper( el ); 14841 done(); 14842 } 14843 }); 14844}; 14845 14846})(jQuery); 14847(function( $, undefined ) { 14848 14849$.effects.effect.transfer = function( o, done ) { 14850 var elem = $( this ), 14851 target = $( o.to ), 14852 targetFixed = target.css( "position" ) === "fixed", 14853 body = $("body"), 14854 fixTop = targetFixed ? body.scrollTop() : 0, 14855 fixLeft = targetFixed ? body.scrollLeft() : 0, 14856 endPosition = target.offset(), 14857 animation = { 14858 top: endPosition.top - fixTop , 14859 left: endPosition.left - fixLeft , 14860 height: target.innerHeight(), 14861 width: target.innerWidth() 14862 }, 14863 startPosition = elem.offset(), 14864 transfer = $( '<div class="ui-effects-transfer"></div>' ) 14865 .appendTo( document.body ) 14866 .addClass( o.className ) 14867 .css({ 14868 top: startPosition.top - fixTop , 14869 left: startPosition.left - fixLeft , 14870 height: elem.innerHeight(), 14871 width: elem.innerWidth(), 14872 position: targetFixed ? "fixed" : "absolute" 14873 }) 14874 .animate( animation, o.duration, o.easing, function() { 14875 transfer.remove(); 14876 done(); 14877 }); 14878}; 14879 14880})(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.