vendor: 8,600 bytes, lines 1-299
1/*! jQuery UI - v1.10.1 - 2013-02-21 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 (c) 2013 jQuery Foundation and other contributors Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// prevent duplicate loading 12// this is only a problem because we proxy existing functions 13// and we don't want to double proxy them 14$.ui = $.ui || {}; 15if ( $.ui.version ) { 16 return; 17} 18 19$.extend( $.ui, { 20 version: "1.10.1", 21 22 keyCode: { 23 BACKSPACE: 8, 24 COMMA: 188, 25 DELETE: 46, 26 DOWN: 40, 27 END: 35, 28 ENTER: 13, 29 ESCAPE: 27, 30 HOME: 36, 31 LEFT: 37, 32 NUMPAD_ADD: 107, 33 NUMPAD_DECIMAL: 110, 34 NUMPAD_DIVIDE: 111, 35 NUMPAD_ENTER: 108, 36 NUMPAD_MULTIPLY: 106, 37 NUMPAD_SUBTRACT: 109, 38 PAGE_DOWN: 34, 39 PAGE_UP: 33, 40 PERIOD: 190, 41 RIGHT: 39, 42 SPACE: 32, 43 TAB: 9, 44 UP: 38 45 } 46}); 47 48// plugins 49$.fn.extend({ 50 _focus: $.fn.focus, 51 focus: function( delay, fn ) { 52 return typeof delay === "number" ? 53 this.each(function() { 54 var elem = this; 55 setTimeout(function() { 56 $( elem ).focus(); 57 if ( fn ) { 58 fn.call( elem ); 59 } 60 }, delay ); 61 }) : 62 this._focus.apply( this, arguments ); 63 }, 64 65 scrollParent: function() { 66 var scrollParent; 67 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 68 scrollParent = this.parents().filter(function() { 69 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } else { 72 scrollParent = this.parents().filter(function() { 73 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 74 }).eq(0); 75 } 76 77 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 78 }, 79 80 zIndex: function( zIndex ) { 81 if ( zIndex !== undefined ) { 82 return this.css( "zIndex", zIndex ); 83 } 84 85 if ( this.length ) { 86 var elem = $( this[ 0 ] ), position, value; 87 while ( elem.length && elem[ 0 ] !== document ) { 88 // Ignore z-index if position is set to a value where z-index is ignored by the browser 89 // This makes behavior of this function consistent across browsers 90 // WebKit always returns auto if the element is positioned 91 position = elem.css( "position" ); 92 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 93 // IE returns 0 when zIndex is not specified 94 // other browsers return a string 95 // we ignore the case of nested elements with an explicit value of 0 96 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 97 value = parseInt( elem.css( "zIndex" ), 10 ); 98 if ( !isNaN( value ) && value !== 0 ) { 99 return value; 100 } 101 } 102 elem = elem.parent(); 103 } 104 } 105 106 return 0; 107 }, 108 109 uniqueId: function() { 110 return this.each(function() { 111 if ( !this.id ) { 112 this.id = "ui-id-" + (++uuid); 113 } 114 }); 115 }, 116 117 removeUniqueId: function() { 118 return this.each(function() { 119 if ( runiqueId.test( this.id ) ) { 120 $( this ).removeAttr( "id" ); 121 } 122 }); 123 } 124}); 125 126// selectors 127function focusable( element, isTabIndexNotNaN ) { 128 var map, mapName, img, 129 nodeName = element.nodeName.toLowerCase(); 130 if ( "area" === nodeName ) { 131 map = element.parentNode; 132 mapName = map.name; 133 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 134 return false; 135 } 136 img = $( "img[usemap=#" + mapName + "]" )[0]; 137 return !!img && visible( img ); 138 } 139 return ( /input|select|textarea|button|object/.test( nodeName ) ? 140 !element.disabled : 141 "a" === nodeName ? 142 element.href || isTabIndexNotNaN : 143 isTabIndexNotNaN) && 144 // the element and all of its ancestors must be visible 145 visible( element ); 146} 147 148function visible( element ) { 149 return $.expr.filters.visible( element ) && 150 !$( element ).parents().addBack().filter(function() { 151 return $.css( this, "visibility" ) === "hidden"; 152 }).length; 153} 154 155$.extend( $.expr[ ":" ], { 156 data: $.expr.createPseudo ? 157 $.expr.createPseudo(function( dataName ) { 158 return function( elem ) { 159 return !!$.data( elem, dataName ); 160 }; 161 }) : 162 // support: jQuery <1.8 163 function( elem, i, match ) { 164 return !!$.data( elem, match[ 3 ] ); 165 }, 166 167 focusable: function( element ) { 168 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 169 }, 170 171 tabbable: function( element ) { 172 var tabIndex = $.attr( element, "tabindex" ), 173 isTabIndexNaN = isNaN( tabIndex ); 174 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 175 } 176}); 177 178// support: jQuery <1.8 179if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 180 $.each( [ "Width", "Height" ], function( i, name ) { 181 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 182 type = name.toLowerCase(), 183 orig = { 184 innerWidth: $.fn.innerWidth, 185 innerHeight: $.fn.innerHeight, 186 outerWidth: $.fn.outerWidth, 187 outerHeight: $.fn.outerHeight 188 }; 189 190 function reduce( elem, size, border, margin ) { 191 $.each( side, function() { 192 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 193 if ( border ) { 194 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 195 } 196 if ( margin ) { 197 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 198 } 199 }); 200 return size; 201 } 202 203 $.fn[ "inner" + name ] = function( size ) { 204 if ( size === undefined ) { 205 return orig[ "inner" + name ].call( this ); 206 } 207 208 return this.each(function() { 209 $( this ).css( type, reduce( this, size ) + "px" ); 210 }); 211 }; 212 213 $.fn[ "outer" + name] = function( size, margin ) { 214 if ( typeof size !== "number" ) { 215 return orig[ "outer" + name ].call( this, size ); 216 } 217 218 return this.each(function() { 219 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 220 }); 221 }; 222 }); 223} 224 225// support: jQuery <1.8 226if ( !$.fn.addBack ) { 227 $.fn.addBack = function( selector ) { 228 return this.add( selector == null ? 229 this.prevObject : this.prevObject.filter( selector ) 230 ); 231 }; 232} 233 234// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 235if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 236 $.fn.removeData = (function( removeData ) { 237 return function( key ) { 238 if ( arguments.length ) { 239 return removeData.call( this, $.camelCase( key ) ); 240 } else { 241 return removeData.call( this ); 242 } 243 }; 244 })( $.fn.removeData ); 245} 246 247 248 249 250 251// deprecated 252$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 253 254$.support.selectstart = "onselectstart" in document.createElement( "div" ); 255$.fn.extend({ 256 disableSelection: function() { 257 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 258 ".ui-disableSelection", function( event ) { 259 event.preventDefault(); 260 }); 261 }, 262 263 enableSelection: function() { 264 return this.unbind( ".ui-disableSelection" ); 265 } 266}); 267 268$.extend( $.ui, { 269 // $.ui.plugin is deprecated. Use the proxy pattern instead. 270 plugin: { 271 add: function( module, option, set ) { 272 var i, 273 proto = $.ui[ module ].prototype; 274 for ( i in set ) { 275 proto.plugins[ i ] = proto.plugins[ i ] || []; 276 proto.plugins[ i ].push( [ option, set[ i ] ] ); 277 } 278 }, 279 call: function( instance, name, args ) { 280 var i, 281 set = instance.plugins[ name ]; 282 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 283 return; 284 } 285 286 for ( i = 0; i < set.length; i++ ) { 287 if ( instance.options[ set[ i ][ 0 ] ] ) { 288 set[ i ][ 1 ].apply( instance.element, args ); 289 } 290 } 291 } 292 }, 293 294 // only used by resizable 295 hasScroll: function( el, a ) { 296 297 //If overflow is hidden, the element might have extra content, but the user wants to hide it 298 if ( $( el ).css( "overflow" ) === "hidden") { 299 return false;
300 } 301 302 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 303 has = false; 304 305 if ( el[ scroll ] > 0 ) { 306 return true; 307 } 308 309 // TODO: determine which cases actually cause this to happen 310 // if the element doesn't have the scroll set, see if it's possible to 311 // set the scroll 312 el[ scroll ] = 1; 313 has = ( el[ scroll ] > 0 ); 314 el[ scroll ] = 0; 315 return has; 316 } 317}); 318 319})( jQuery );
vendor: 14,841 bytes, lines 319-830
319 320(function( $, undefined ) { 321 322var uuid = 0, 323 slice = Array.prototype.slice, 324 _cleanData = $.cleanData; 325$.cleanData = function( elems ) { 326 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 327 try { 328 $( elem ).triggerHandler( "remove" ); 329 // http://bugs.jquery.com/ticket/8235 330 } catch( e ) {} 331 } 332 _cleanData( elems ); 333}; 334 335$.widget = function( name, base, prototype ) { 336 var fullName, existingConstructor, constructor, basePrototype, 337 // proxiedPrototype allows the provided prototype to remain unmodified 338 // so that it can be used as a mixin for multiple widgets (#8876) 339 proxiedPrototype = {}, 340 namespace = name.split( "." )[ 0 ]; 341 342 name = name.split( "." )[ 1 ]; 343 fullName = namespace + "-" + name; 344 345 if ( !prototype ) { 346 prototype = base; 347 base = $.Widget; 348 } 349 350 // create selector for plugin 351 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 352 return !!$.data( elem, fullName ); 353 }; 354 355 $[ namespace ] = $[ namespace ] || {}; 356 existingConstructor = $[ namespace ][ name ]; 357 constructor = $[ namespace ][ name ] = function( options, element ) { 358 // allow instantiation without "new" keyword 359 if ( !this._createWidget ) { 360 return new constructor( options, element ); 361 } 362 363 // allow instantiation without initializing for simple inheritance 364 // must use "new" keyword (the code above always passes args) 365 if ( arguments.length ) { 366 this._createWidget( options, element ); 367 } 368 }; 369 // extend with the existing constructor to carry over any static properties 370 $.extend( constructor, existingConstructor, { 371 version: prototype.version, 372 // copy the object used to create the prototype in case we need to 373 // redefine the widget later 374 _proto: $.extend( {}, prototype ), 375 // track widgets that inherit from this widget in case this widget is 376 // redefined after a widget inherits from it 377 _childConstructors: [] 378 }); 379 380 basePrototype = new base(); 381 // we need to make the options hash a property directly on the new instance 382 // otherwise we'll modify the options hash on the prototype that we're 383 // inheriting from 384 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 385 $.each( prototype, function( prop, value ) { 386 if ( !$.isFunction( value ) ) { 387 proxiedPrototype[ prop ] = value; 388 return; 389 } 390 proxiedPrototype[ prop ] = (function() { 391 var _super = function() { 392 return base.prototype[ prop ].apply( this, arguments ); 393 }, 394 _superApply = function( args ) { 395 return base.prototype[ prop ].apply( this, args ); 396 }; 397 return function() { 398 var __super = this._super, 399 __superApply = this._superApply, 400 returnValue; 401 402 this._super = _super; 403 this._superApply = _superApply; 404 405 returnValue = value.apply( this, arguments ); 406 407 this._super = __super; 408 this._superApply = __superApply; 409 410 return returnValue; 411 }; 412 })(); 413 }); 414 constructor.prototype = $.widget.extend( basePrototype, { 415 // TODO: remove support for widgetEventPrefix 416 // always use the name + a colon as the prefix, e.g., draggable:start 417 // don't prefix for widgets that aren't DOM-based 418 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 419 }, proxiedPrototype, { 420 constructor: constructor, 421 namespace: namespace, 422 widgetName: name, 423 widgetFullName: fullName 424 }); 425 426 // If this widget is being redefined then we need to find all widgets that 427 // are inheriting from it and redefine all of them so that they inherit from 428 // the new version of this widget. We're essentially trying to replace one 429 // level in the prototype chain. 430 if ( existingConstructor ) { 431 $.each( existingConstructor._childConstructors, function( i, child ) { 432 var childPrototype = child.prototype; 433 434 // redefine the child widget using the same prototype that was 435 // originally used, but inherit from the new version of the base 436 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 437 }); 438 // remove the list of existing child constructors from the old constructor 439 // so the old child constructors can be garbage collected 440 delete existingConstructor._childConstructors; 441 } else { 442 base._childConstructors.push( constructor ); 443 } 444 445 $.widget.bridge( name, constructor ); 446}; 447 448$.widget.extend = function( target ) { 449 var input = slice.call( arguments, 1 ), 450 inputIndex = 0, 451 inputLength = input.length, 452 key, 453 value; 454 for ( ; inputIndex < inputLength; inputIndex++ ) { 455 for ( key in input[ inputIndex ] ) { 456 value = input[ inputIndex ][ key ]; 457 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 458 // Clone objects 459 if ( $.isPlainObject( value ) ) { 460 target[ key ] = $.isPlainObject( target[ key ] ) ? 461 $.widget.extend( {}, target[ key ], value ) : 462 // Don't extend strings, arrays, etc. with objects 463 $.widget.extend( {}, value ); 464 // Copy everything else by reference 465 } else { 466 target[ key ] = value; 467 } 468 } 469 } 470 } 471 return target; 472}; 473 474$.widget.bridge = function( name, object ) { 475 var fullName = object.prototype.widgetFullName || name; 476 $.fn[ name ] = function( options ) { 477 var isMethodCall = typeof options === "string", 478 args = slice.call( arguments, 1 ), 479 returnValue = this; 480 481 // allow multiple hashes to be passed on init 482 options = !isMethodCall && args.length ? 483 $.widget.extend.apply( null, [ options ].concat(args) ) : 484 options; 485 486 if ( isMethodCall ) { 487 this.each(function() { 488 var methodValue, 489 instance = $.data( this, fullName ); 490 if ( !instance ) { 491 return $.error( "cannot call methods on " + name + " prior to initialization; " + 492 "attempted to call method '" + options + "'" ); 493 } 494 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 495 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 496 } 497 methodValue = instance[ options ].apply( instance, args ); 498 if ( methodValue !== instance && methodValue !== undefined ) { 499 returnValue = methodValue && methodValue.jquery ? 500 returnValue.pushStack( methodValue.get() ) : 501 methodValue; 502 return false; 503 } 504 }); 505 } else { 506 this.each(function() { 507 var instance = $.data( this, fullName ); 508 if ( instance ) { 509 instance.option( options || {} )._init(); 510 } else { 511 $.data( this, fullName, new object( options, this ) ); 512 } 513 }); 514 } 515 516 return returnValue; 517 }; 518}; 519 520$.Widget = function( /* options, element */ ) {}; 521$.Widget._childConstructors = []; 522 523$.Widget.prototype = { 524 widgetName: "widget", 525 widgetEventPrefix: "", 526 defaultElement: "<div>", 527 options: { 528 disabled: false, 529 530 // callbacks 531 create: null 532 }, 533 _createWidget: function( options, element ) { 534 element = $( element || this.defaultElement || this )[ 0 ]; 535 this.element = $( element ); 536 this.uuid = uuid++; 537 this.eventNamespace = "." + this.widgetName + this.uuid; 538 this.options = $.widget.extend( {}, 539 this.options, 540 this._getCreateOptions(), 541 options ); 542 543 this.bindings = $(); 544 this.hoverable = $(); 545 this.focusable = $(); 546 547 if ( element !== this ) { 548 $.data( element, this.widgetFullName, this ); 549 this._on( true, this.element, { 550 remove: function( event ) { 551 if ( event.target === element ) { 552 this.destroy(); 553 } 554 } 555 }); 556 this.document = $( element.style ? 557 // element within the document 558 element.ownerDocument : 559 // element is window or document 560 element.document || element ); 561 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 562 } 563 564 this._create(); 565 this._trigger( "create", null, this._getCreateEventData() ); 566 this._init(); 567 }, 568 _getCreateOptions: $.noop, 569 _getCreateEventData: $.noop, 570 _create: $.noop, 571 _init: $.noop, 572 573 destroy: function() { 574 this._destroy(); 575 // we can probably remove the unbind calls in 2.0 576 // all event bindings should go through this._on() 577 this.element 578 .unbind( this.eventNamespace ) 579 // 1.9 BC for #7810 580 // TODO remove dual storage 581 .removeData( this.widgetName ) 582 .removeData( this.widgetFullName ) 583 // support: jquery <1.6.3 584 // http://bugs.jquery.com/ticket/9413 585 .removeData( $.camelCase( this.widgetFullName ) ); 586 this.widget() 587 .unbind( this.eventNamespace ) 588 .removeAttr( "aria-disabled" ) 589 .removeClass( 590 this.widgetFullName + "-disabled " + 591 "ui-state-disabled" ); 592 593 // clean up events and states 594 this.bindings.unbind( this.eventNamespace ); 595 this.hoverable.removeClass( "ui-state-hover" ); 596 this.focusable.removeClass( "ui-state-focus" ); 597 }, 598 _destroy: $.noop, 599 600 widget: function() { 601 return this.element; 602 }, 603 604 option: function( key, value ) { 605 var options = key, 606 parts, 607 curOption, 608 i; 609 610 if ( arguments.length === 0 ) { 611 // don't return a reference to the internal hash 612 return $.widget.extend( {}, this.options ); 613 } 614 615 if ( typeof key === "string" ) { 616 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 617 options = {}; 618 parts = key.split( "." ); 619 key = parts.shift(); 620 if ( parts.length ) { 621 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 622 for ( i = 0; i < parts.length - 1; i++ ) { 623 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 624 curOption = curOption[ parts[ i ] ]; 625 } 626 key = parts.pop(); 627 if ( value === undefined ) { 628 return curOption[ key ] === undefined ? null : curOption[ key ]; 629 } 630 curOption[ key ] = value; 631 } else { 632 if ( value === undefined ) { 633 return this.options[ key ] === undefined ? null : this.options[ key ]; 634 } 635 options[ key ] = value; 636 } 637 } 638 639 this._setOptions( options ); 640 641 return this; 642 }, 643 _setOptions: function( options ) { 644 var key; 645 646 for ( key in options ) { 647 this._setOption( key, options[ key ] ); 648 } 649 650 return this; 651 }, 652 _setOption: function( key, value ) { 653 this.options[ key ] = value; 654 655 if ( key === "disabled" ) { 656 this.widget() 657 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 658 .attr( "aria-disabled", value ); 659 this.hoverable.removeClass( "ui-state-hover" ); 660 this.focusable.removeClass( "ui-state-focus" ); 661 } 662 663 return this; 664 }, 665 666 enable: function() { 667 return this._setOption( "disabled", false ); 668 }, 669 disable: function() { 670 return this._setOption( "disabled", true ); 671 }, 672 673 _on: function( suppressDisabledCheck, element, handlers ) { 674 var delegateElement, 675 instance = this; 676 677 // no suppressDisabledCheck flag, shuffle arguments 678 if ( typeof suppressDisabledCheck !== "boolean" ) { 679 handlers = element; 680 element = suppressDisabledCheck; 681 suppressDisabledCheck = false; 682 } 683 684 // no element argument, shuffle and use this.element 685 if ( !handlers ) { 686 handlers = element; 687 element = this.element; 688 delegateElement = this.widget(); 689 } else { 690 // accept selectors, DOM elements 691 element = delegateElement = $( element ); 692 this.bindings = this.bindings.add( element ); 693 } 694 695 $.each( handlers, function( event, handler ) { 696 function handlerProxy() { 697 // allow widgets to customize the disabled handling 698 // - disabled as an array instead of boolean 699 // - disabled class as method for disabling individual parts 700 if ( !suppressDisabledCheck && 701 ( instance.options.disabled === true || 702 $( this ).hasClass( "ui-state-disabled" ) ) ) { 703 return; 704 } 705 return ( typeof handler === "string" ? instance[ handler ] : handler ) 706 .apply( instance, arguments ); 707 } 708 709 // copy the guid so direct unbinding works 710 if ( typeof handler !== "string" ) { 711 handlerProxy.guid = handler.guid = 712 handler.guid || handlerProxy.guid || $.guid++; 713 } 714 715 var match = event.match( /^(\w+)\s*(.*)$/ ), 716 eventName = match[1] + instance.eventNamespace, 717 selector = match[2]; 718 if ( selector ) { 719 delegateElement.delegate( selector, eventName, handlerProxy ); 720 } else { 721 element.bind( eventName, handlerProxy ); 722 } 723 }); 724 }, 725 726 _off: function( element, eventName ) { 727 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 728 element.unbind( eventName ).undelegate( eventName ); 729 }, 730 731 _delay: function( handler, delay ) { 732 function handlerProxy() { 733 return ( typeof handler === "string" ? instance[ handler ] : handler ) 734 .apply( instance, arguments ); 735 } 736 var instance = this; 737 return setTimeout( handlerProxy, delay || 0 ); 738 }, 739 740 _hoverable: function( element ) { 741 this.hoverable = this.hoverable.add( element ); 742 this._on( element, { 743 mouseenter: function( event ) { 744 $( event.currentTarget ).addClass( "ui-state-hover" ); 745 }, 746 mouseleave: function( event ) { 747 $( event.currentTarget ).removeClass( "ui-state-hover" ); 748 } 749 }); 750 }, 751 752 _focusable: function( element ) { 753 this.focusable = this.focusable.add( element ); 754 this._on( element, { 755 focusin: function( event ) { 756 $( event.currentTarget ).addClass( "ui-state-focus" ); 757 }, 758 focusout: function( event ) { 759 $( event.currentTarget ).removeClass( "ui-state-focus" ); 760 } 761 }); 762 }, 763 764 _trigger: function( type, event, data ) { 765 var prop, orig, 766 callback = this.options[ type ]; 767 768 data = data || {}; 769 event = $.Event( event ); 770 event.type = ( type === this.widgetEventPrefix ? 771 type : 772 this.widgetEventPrefix + type ).toLowerCase(); 773 // the original event may come from any element 774 // so we need to reset the target on the new event 775 event.target = this.element[ 0 ]; 776 777 // copy original event properties over to the new event 778 orig = event.originalEvent; 779 if ( orig ) { 780 for ( prop in orig ) { 781 if ( !( prop in event ) ) { 782 event[ prop ] = orig[ prop ]; 783 } 784 } 785 } 786 787 this.element.trigger( event, data ); 788 return !( $.isFunction( callback ) && 789 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 790 event.isDefaultPrevented() ); 791 } 792}; 793 794$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 795 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 796 if ( typeof options === "string" ) { 797 options = { effect: options }; 798 } 799 var hasOptions, 800 effectName = !options ? 801 method : 802 options === true || typeof options === "number" ? 803 defaultEffect : 804 options.effect || defaultEffect; 805 options = options || {}; 806 if ( typeof options === "number" ) { 807 options = { duration: options }; 808 } 809 hasOptions = !$.isEmptyObject( options ); 810 options.complete = callback; 811 if ( options.delay ) { 812 element.delay( options.delay ); 813 } 814 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 815 element[ method ]( options ); 816 } else if ( effectName !== method && element[ effectName ] ) { 817 element[ effectName ]( options.duration, options.easing, callback ); 818 } else { 819 element.queue(function( next ) { 820 $( this )[ method ](); 821 if ( callback ) { 822 callback.call( element[ 0 ] ); 823 } 824 next(); 825 }); 826 } 827 }; 828}); 829 830})( jQuery );
831(function( $, undefined ) { 832 833var mouseHandled = false;
vendor: 29,209 bytes, lines 834-1818
834$( document ).mouseup( function() { 835 mouseHandled = false; 836}); 837 838$.widget("ui.mouse", { 839 version: "1.10.1", 840 options: { 841 cancel: "input,textarea,button,select,option", 842 distance: 1, 843 delay: 0 844 }, 845 _mouseInit: function() { 846 var that = this; 847 848 this.element 849 .bind("mousedown."+this.widgetName, function(event) { 850 return that._mouseDown(event); 851 }) 852 .bind("click."+this.widgetName, function(event) { 853 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 854 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 855 event.stopImmediatePropagation(); 856 return false; 857 } 858 }); 859 860 this.started = false; 861 }, 862 863 // TODO: make sure destroying one instance of mouse doesn't mess with 864 // other instances of mouse 865 _mouseDestroy: function() { 866 this.element.unbind("."+this.widgetName); 867 if ( this._mouseMoveDelegate ) { 868 $(document) 869 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 870 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 871 } 872 }, 873 874 _mouseDown: function(event) { 875 // don't let more than one widget handle mouseStart 876 if( mouseHandled ) { return; } 877 878 // we may have missed mouseup (out of window) 879 (this._mouseStarted && this._mouseUp(event)); 880 881 this._mouseDownEvent = event; 882 883 var that = this, 884 btnIsLeft = (event.which === 1), 885 // event.target.nodeName works around a bug in IE 8 with 886 // disabled inputs (#7620) 887 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 888 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 889 return true; 890 } 891 892 this.mouseDelayMet = !this.options.delay; 893 if (!this.mouseDelayMet) { 894 this._mouseDelayTimer = setTimeout(function() { 895 that.mouseDelayMet = true; 896 }, this.options.delay); 897 } 898 899 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 900 this._mouseStarted = (this._mouseStart(event) !== false); 901 if (!this._mouseStarted) { 902 event.preventDefault(); 903 return true; 904 } 905 } 906 907 // Click event may never have fired (Gecko & Opera) 908 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 909 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 910 } 911 912 // these delegates are required to keep context 913 this._mouseMoveDelegate = function(event) { 914 return that._mouseMove(event); 915 }; 916 this._mouseUpDelegate = function(event) { 917 return that._mouseUp(event); 918 }; 919 $(document) 920 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 921 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 922 923 event.preventDefault(); 924 925 mouseHandled = true; 926 return true; 927 }, 928 929 _mouseMove: function(event) { 930 // IE mouseup check - mouseup happened when mouse was out of window 931 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 932 return this._mouseUp(event); 933 } 934 935 if (this._mouseStarted) { 936 this._mouseDrag(event); 937 return event.preventDefault(); 938 } 939 940 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 941 this._mouseStarted = 942 (this._mouseStart(this._mouseDownEvent, event) !== false); 943 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 944 } 945 946 return !this._mouseStarted; 947 }, 948 949 _mouseUp: function(event) { 950 $(document) 951 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 952 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 953 954 if (this._mouseStarted) { 955 this._mouseStarted = false; 956 957 if (event.target === this._mouseDownEvent.target) { 958 $.data(event.target, this.widgetName + ".preventClickEvent", true); 959 } 960 961 this._mouseStop(event); 962 } 963 964 return false; 965 }, 966 967 _mouseDistanceMet: function(event) { 968 return (Math.max( 969 Math.abs(this._mouseDownEvent.pageX - event.pageX), 970 Math.abs(this._mouseDownEvent.pageY - event.pageY) 971 ) >= this.options.distance 972 ); 973 }, 974 975 _mouseDelayMet: function(/* event */) { 976 return this.mouseDelayMet; 977 }, 978 979 // These are placeholder methods, to be overriden by extending plugin 980 _mouseStart: function(/* event */) {}, 981 _mouseDrag: function(/* event */) {}, 982 _mouseStop: function(/* event */) {}, 983 _mouseCapture: function(/* event */) { return true; } 984}); 985 986})(jQuery); 987(function( $, undefined ) { 988 989$.ui = $.ui || {}; 990 991var cachedScrollbarWidth, 992 max = Math.max, 993 abs = Math.abs, 994 round = Math.round, 995 rhorizontal = /left|center|right/, 996 rvertical = /top|center|bottom/, 997 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 998 rposition = /^\w+/, 999 rpercent = /%$/, 1000 _position = $.fn.position; 1001 1002function getOffsets( offsets, width, height ) { 1003 return [ 1004 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1005 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1006 ]; 1007} 1008 1009function parseCss( element, property ) { 1010 return parseInt( $.css( element, property ), 10 ) || 0; 1011} 1012 1013function getDimensions( elem ) { 1014 var raw = elem[0]; 1015 if ( raw.nodeType === 9 ) { 1016 return { 1017 width: elem.width(), 1018 height: elem.height(), 1019 offset: { top: 0, left: 0 } 1020 }; 1021 } 1022 if ( $.isWindow( raw ) ) { 1023 return { 1024 width: elem.width(), 1025 height: elem.height(), 1026 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1027 }; 1028 } 1029 if ( raw.preventDefault ) { 1030 return { 1031 width: 0, 1032 height: 0, 1033 offset: { top: raw.pageY, left: raw.pageX } 1034 }; 1035 } 1036 return { 1037 width: elem.outerWidth(), 1038 height: elem.outerHeight(), 1039 offset: elem.offset() 1040 }; 1041} 1042 1043$.position = { 1044 scrollbarWidth: function() { 1045 if ( cachedScrollbarWidth !== undefined ) { 1046 return cachedScrollbarWidth; 1047 } 1048 var w1, w2, 1049 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1050 innerDiv = div.children()[0]; 1051 1052 $( "body" ).append( div ); 1053 w1 = innerDiv.offsetWidth; 1054 div.css( "overflow", "scroll" ); 1055 1056 w2 = innerDiv.offsetWidth; 1057 1058 if ( w1 === w2 ) { 1059 w2 = div[0].clientWidth; 1060 } 1061 1062 div.remove(); 1063 1064 return (cachedScrollbarWidth = w1 - w2); 1065 }, 1066 getScrollInfo: function( within ) { 1067 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 1068 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 1069 hasOverflowX = overflowX === "scroll" || 1070 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1071 hasOverflowY = overflowY === "scroll" || 1072 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1073 return { 1074 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 1075 height: hasOverflowY ? $.position.scrollbarWidth() : 0 1076 }; 1077 }, 1078 getWithinInfo: function( element ) { 1079 var withinElement = $( element || window ), 1080 isWindow = $.isWindow( withinElement[0] ); 1081 return { 1082 element: withinElement, 1083 isWindow: isWindow, 1084 offset: withinElement.offset() || { left: 0, top: 0 }, 1085 scrollLeft: withinElement.scrollLeft(), 1086 scrollTop: withinElement.scrollTop(), 1087 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1088 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1089 }; 1090 } 1091}; 1092 1093$.fn.position = function( options ) { 1094 if ( !options || !options.of ) { 1095 return _position.apply( this, arguments ); 1096 } 1097 1098 // make a copy, we don't want to modify arguments 1099 options = $.extend( {}, options ); 1100 1101 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1102 target = $( options.of ), 1103 within = $.position.getWithinInfo( options.within ), 1104 scrollInfo = $.position.getScrollInfo( within ), 1105 collision = ( options.collision || "flip" ).split( " " ), 1106 offsets = {}; 1107 1108 dimensions = getDimensions( target ); 1109 if ( target[0].preventDefault ) { 1110 // force left top to allow flipping 1111 options.at = "left top"; 1112 } 1113 targetWidth = dimensions.width; 1114 targetHeight = dimensions.height; 1115 targetOffset = dimensions.offset; 1116 // clone to reuse original targetOffset later 1117 basePosition = $.extend( {}, targetOffset ); 1118 1119 // force my and at to have valid horizontal and vertical positions 1120 // if a value is missing or invalid, it will be converted to center 1121 $.each( [ "my", "at" ], function() { 1122 var pos = ( options[ this ] || "" ).split( " " ), 1123 horizontalOffset, 1124 verticalOffset; 1125 1126 if ( pos.length === 1) { 1127 pos = rhorizontal.test( pos[ 0 ] ) ? 1128 pos.concat( [ "center" ] ) : 1129 rvertical.test( pos[ 0 ] ) ? 1130 [ "center" ].concat( pos ) : 1131 [ "center", "center" ]; 1132 } 1133 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1134 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1135 1136 // calculate offsets 1137 horizontalOffset = roffset.exec( pos[ 0 ] ); 1138 verticalOffset = roffset.exec( pos[ 1 ] ); 1139 offsets[ this ] = [ 1140 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1141 verticalOffset ? verticalOffset[ 0 ] : 0 1142 ]; 1143 1144 // reduce to just the positions without the offsets 1145 options[ this ] = [ 1146 rposition.exec( pos[ 0 ] )[ 0 ], 1147 rposition.exec( pos[ 1 ] )[ 0 ] 1148 ]; 1149 }); 1150 1151 // normalize collision option 1152 if ( collision.length === 1 ) { 1153 collision[ 1 ] = collision[ 0 ]; 1154 } 1155 1156 if ( options.at[ 0 ] === "right" ) { 1157 basePosition.left += targetWidth; 1158 } else if ( options.at[ 0 ] === "center" ) { 1159 basePosition.left += targetWidth / 2; 1160 } 1161 1162 if ( options.at[ 1 ] === "bottom" ) { 1163 basePosition.top += targetHeight; 1164 } else if ( options.at[ 1 ] === "center" ) { 1165 basePosition.top += targetHeight / 2; 1166 } 1167 1168 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1169 basePosition.left += atOffset[ 0 ]; 1170 basePosition.top += atOffset[ 1 ]; 1171 1172 return this.each(function() { 1173 var collisionPosition, using, 1174 elem = $( this ), 1175 elemWidth = elem.outerWidth(), 1176 elemHeight = elem.outerHeight(), 1177 marginLeft = parseCss( this, "marginLeft" ), 1178 marginTop = parseCss( this, "marginTop" ), 1179 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1180 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1181 position = $.extend( {}, basePosition ), 1182 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1183 1184 if ( options.my[ 0 ] === "right" ) { 1185 position.left -= elemWidth; 1186 } else if ( options.my[ 0 ] === "center" ) { 1187 position.left -= elemWidth / 2; 1188 } 1189 1190 if ( options.my[ 1 ] === "bottom" ) { 1191 position.top -= elemHeight; 1192 } else if ( options.my[ 1 ] === "center" ) { 1193 position.top -= elemHeight / 2; 1194 } 1195 1196 position.left += myOffset[ 0 ]; 1197 position.top += myOffset[ 1 ]; 1198 1199 // if the browser doesn't support fractions, then round for consistent results 1200 if ( !$.support.offsetFractions ) { 1201 position.left = round( position.left ); 1202 position.top = round( position.top ); 1203 } 1204 1205 collisionPosition = { 1206 marginLeft: marginLeft, 1207 marginTop: marginTop 1208 }; 1209 1210 $.each( [ "left", "top" ], function( i, dir ) { 1211 if ( $.ui.position[ collision[ i ] ] ) { 1212 $.ui.position[ collision[ i ] ][ dir ]( position, { 1213 targetWidth: targetWidth, 1214 targetHeight: targetHeight, 1215 elemWidth: elemWidth, 1216 elemHeight: elemHeight, 1217 collisionPosition: collisionPosition, 1218 collisionWidth: collisionWidth, 1219 collisionHeight: collisionHeight, 1220 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1221 my: options.my, 1222 at: options.at, 1223 within: within, 1224 elem : elem 1225 }); 1226 } 1227 }); 1228 1229 if ( options.using ) { 1230 // adds feedback as second argument to using callback, if present 1231 using = function( props ) { 1232 var left = targetOffset.left - position.left, 1233 right = left + targetWidth - elemWidth, 1234 top = targetOffset.top - position.top, 1235 bottom = top + targetHeight - elemHeight, 1236 feedback = { 1237 target: { 1238 element: target, 1239 left: targetOffset.left, 1240 top: targetOffset.top, 1241 width: targetWidth, 1242 height: targetHeight 1243 }, 1244 element: { 1245 element: elem, 1246 left: position.left, 1247 top: position.top, 1248 width: elemWidth, 1249 height: elemHeight 1250 }, 1251 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1252 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1253 }; 1254 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1255 feedback.horizontal = "center"; 1256 } 1257 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1258 feedback.vertical = "middle"; 1259 } 1260 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1261 feedback.important = "horizontal"; 1262 } else { 1263 feedback.important = "vertical"; 1264 } 1265 options.using.call( this, props, feedback ); 1266 }; 1267 } 1268 1269 elem.offset( $.extend( position, { using: using } ) ); 1270 }); 1271}; 1272 1273$.ui.position = { 1274 fit: { 1275 left: function( position, data ) { 1276 var within = data.within, 1277 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1278 outerWidth = within.width, 1279 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1280 overLeft = withinOffset - collisionPosLeft, 1281 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1282 newOverRight; 1283 1284 // element is wider than within 1285 if ( data.collisionWidth > outerWidth ) { 1286 // element is initially over the left side of within 1287 if ( overLeft > 0 && overRight <= 0 ) { 1288 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1289 position.left += overLeft - newOverRight; 1290 // element is initially over right side of within 1291 } else if ( overRight > 0 && overLeft <= 0 ) { 1292 position.left = withinOffset; 1293 // element is initially over both left and right sides of within 1294 } else { 1295 if ( overLeft > overRight ) { 1296 position.left = withinOffset + outerWidth - data.collisionWidth; 1297 } else { 1298 position.left = withinOffset; 1299 } 1300 } 1301 // too far left -> align with left edge 1302 } else if ( overLeft > 0 ) { 1303 position.left += overLeft; 1304 // too far right -> align with right edge 1305 } else if ( overRight > 0 ) { 1306 position.left -= overRight; 1307 // adjust based on position and margin 1308 } else { 1309 position.left = max( position.left - collisionPosLeft, position.left ); 1310 } 1311 }, 1312 top: function( position, data ) { 1313 var within = data.within, 1314 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1315 outerHeight = data.within.height, 1316 collisionPosTop = position.top - data.collisionPosition.marginTop, 1317 overTop = withinOffset - collisionPosTop, 1318 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1319 newOverBottom; 1320 1321 // element is taller than within 1322 if ( data.collisionHeight > outerHeight ) { 1323 // element is initially over the top of within 1324 if ( overTop > 0 && overBottom <= 0 ) { 1325 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1326 position.top += overTop - newOverBottom; 1327 // element is initially over bottom of within 1328 } else if ( overBottom > 0 && overTop <= 0 ) { 1329 position.top = withinOffset; 1330 // element is initially over both top and bottom of within 1331 } else { 1332 if ( overTop > overBottom ) { 1333 position.top = withinOffset + outerHeight - data.collisionHeight; 1334 } else { 1335 position.top = withinOffset; 1336 } 1337 } 1338 // too far up -> align with top 1339 } else if ( overTop > 0 ) { 1340 position.top += overTop; 1341 // too far down -> align with bottom edge 1342 } else if ( overBottom > 0 ) { 1343 position.top -= overBottom; 1344 // adjust based on position and margin 1345 } else { 1346 position.top = max( position.top - collisionPosTop, position.top ); 1347 } 1348 } 1349 }, 1350 flip: { 1351 left: function( position, data ) { 1352 var within = data.within, 1353 withinOffset = within.offset.left + within.scrollLeft, 1354 outerWidth = within.width, 1355 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1356 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1357 overLeft = collisionPosLeft - offsetLeft, 1358 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1359 myOffset = data.my[ 0 ] === "left" ? 1360 -data.elemWidth : 1361 data.my[ 0 ] === "right" ? 1362 data.elemWidth : 1363 0, 1364 atOffset = data.at[ 0 ] === "left" ? 1365 data.targetWidth : 1366 data.at[ 0 ] === "right" ? 1367 -data.targetWidth : 1368 0, 1369 offset = -2 * data.offset[ 0 ], 1370 newOverRight, 1371 newOverLeft; 1372 1373 if ( overLeft < 0 ) { 1374 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1375 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1376 position.left += myOffset + atOffset + offset; 1377 } 1378 } 1379 else if ( overRight > 0 ) { 1380 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1381 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1382 position.left += myOffset + atOffset + offset; 1383 } 1384 } 1385 }, 1386 top: function( position, data ) { 1387 var within = data.within, 1388 withinOffset = within.offset.top + within.scrollTop, 1389 outerHeight = within.height, 1390 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1391 collisionPosTop = position.top - data.collisionPosition.marginTop, 1392 overTop = collisionPosTop - offsetTop, 1393 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1394 top = data.my[ 1 ] === "top", 1395 myOffset = top ? 1396 -data.elemHeight : 1397 data.my[ 1 ] === "bottom" ? 1398 data.elemHeight : 1399 0, 1400 atOffset = data.at[ 1 ] === "top" ? 1401 data.targetHeight : 1402 data.at[ 1 ] === "bottom" ? 1403 -data.targetHeight : 1404 0, 1405 offset = -2 * data.offset[ 1 ], 1406 newOverTop, 1407 newOverBottom; 1408 if ( overTop < 0 ) { 1409 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1410 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1411 position.top += myOffset + atOffset + offset; 1412 } 1413 } 1414 else if ( overBottom > 0 ) { 1415 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1416 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1417 position.top += myOffset + atOffset + offset; 1418 } 1419 } 1420 } 1421 }, 1422 flipfit: { 1423 left: function() { 1424 $.ui.position.flip.left.apply( this, arguments ); 1425 $.ui.position.fit.left.apply( this, arguments ); 1426 }, 1427 top: function() { 1428 $.ui.position.flip.top.apply( this, arguments ); 1429 $.ui.position.fit.top.apply( this, arguments ); 1430 } 1431 } 1432}; 1433 1434// fraction support test 1435(function () { 1436 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1437 body = document.getElementsByTagName( "body" )[ 0 ], 1438 div = document.createElement( "div" ); 1439 1440 //Create a "fake body" for testing based on method used in jQuery.support 1441 testElement = document.createElement( body ? "div" : "body" ); 1442 testElementStyle = { 1443 visibility: "hidden", 1444 width: 0, 1445 height: 0, 1446 border: 0, 1447 margin: 0, 1448 background: "none" 1449 }; 1450 if ( body ) { 1451 $.extend( testElementStyle, { 1452 position: "absolute", 1453 left: "-1000px", 1454 top: "-1000px" 1455 }); 1456 } 1457 for ( i in testElementStyle ) { 1458 testElement.style[ i ] = testElementStyle[ i ]; 1459 } 1460 testElement.appendChild( div ); 1461 testElementParent = body || document.documentElement; 1462 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1463 1464 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1465 1466 offsetLeft = $( div ).offset().left; 1467 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1468 1469 testElement.innerHTML = ""; 1470 testElementParent.removeChild( testElement ); 1471})(); 1472 1473}( jQuery ) ); 1474(function( $, undefined ) { 1475 1476$.widget("ui.draggable", $.ui.mouse, { 1477 version: "1.10.1", 1478 widgetEventPrefix: "drag", 1479 options: { 1480 addClasses: true, 1481 appendTo: "parent", 1482 axis: false, 1483 connectToSortable: false, 1484 containment: false, 1485 cursor: "auto", 1486 cursorAt: false, 1487 grid: false, 1488 handle: false, 1489 helper: "original", 1490 iframeFix: false, 1491 opacity: false, 1492 refreshPositions: false, 1493 revert: false, 1494 revertDuration: 500, 1495 scope: "default", 1496 scroll: true, 1497 scrollSensitivity: 20, 1498 scrollSpeed: 20, 1499 snap: false, 1500 snapMode: "both", 1501 snapTolerance: 20, 1502 stack: false, 1503 zIndex: false, 1504 1505 // callbacks 1506 drag: null, 1507 start: null, 1508 stop: null 1509 }, 1510 _create: function() { 1511 1512 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1513 this.element[0].style.position = "relative"; 1514 } 1515 if (this.options.addClasses){ 1516 this.element.addClass("ui-draggable"); 1517 } 1518 if (this.options.disabled){ 1519 this.element.addClass("ui-draggable-disabled"); 1520 } 1521 1522 this._mouseInit(); 1523 1524 }, 1525 1526 _destroy: function() { 1527 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1528 this._mouseDestroy(); 1529 }, 1530 1531 _mouseCapture: function(event) { 1532 1533 var o = this.options; 1534 1535 // among others, prevent a drag on a resizable-handle 1536 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1537 return false; 1538 } 1539 1540 //Quit if we're not on a valid handle 1541 this.handle = this._getHandle(event); 1542 if (!this.handle) { 1543 return false; 1544 } 1545 1546 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1547 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1548 .css({ 1549 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1550 position: "absolute", opacity: "0.001", zIndex: 1000 1551 }) 1552 .css($(this).offset()) 1553 .appendTo("body"); 1554 }); 1555 1556 return true; 1557 1558 }, 1559 1560 _mouseStart: function(event) { 1561 1562 var o = this.options; 1563 1564 //Create and append the visible helper 1565 this.helper = this._createHelper(event); 1566 1567 this.helper.addClass("ui-draggable-dragging"); 1568 1569 //Cache the helper size 1570 this._cacheHelperProportions(); 1571 1572 //If ddmanager is used for droppables, set the global draggable 1573 if($.ui.ddmanager) { 1574 $.ui.ddmanager.current = this; 1575 } 1576 1577 /* 1578 * - Position generation - 1579 * This block generates everything position related - it's the core of draggables. 1580 */ 1581 1582 //Cache the margins of the original element 1583 this._cacheMargins(); 1584 1585 //Store the helper's css position 1586 this.cssPosition = this.helper.css("position"); 1587 this.scrollParent = this.helper.scrollParent(); 1588 1589 //The element's absolute position on the page minus margins 1590 this.offset = this.positionAbs = this.element.offset(); 1591 this.offset = { 1592 top: this.offset.top - this.margins.top, 1593 left: this.offset.left - this.margins.left 1594 }; 1595 1596 $.extend(this.offset, { 1597 click: { //Where the click happened, relative to the element 1598 left: event.pageX - this.offset.left, 1599 top: event.pageY - this.offset.top 1600 }, 1601 parent: this._getParentOffset(), 1602 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1603 }); 1604 1605 //Generate the original position 1606 this.originalPosition = this.position = this._generatePosition(event); 1607 this.originalPageX = event.pageX; 1608 this.originalPageY = event.pageY; 1609 1610 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1611 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1612 1613 //Set a containment if given in the options 1614 if(o.containment) { 1615 this._setContainment(); 1616 } 1617 1618 //Trigger event + callbacks 1619 if(this._trigger("start", event) === false) { 1620 this._clear(); 1621 return false; 1622 } 1623 1624 //Recache the helper size 1625 this._cacheHelperProportions(); 1626 1627 //Prepare the droppable offsets 1628 if ($.ui.ddmanager && !o.dropBehaviour) { 1629 $.ui.ddmanager.prepareOffsets(this, event); 1630 } 1631 1632 1633 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1634 1635 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1636 if ( $.ui.ddmanager ) { 1637 $.ui.ddmanager.dragStart(this, event); 1638 } 1639 1640 return true; 1641 }, 1642 1643 _mouseDrag: function(event, noPropagation) { 1644 1645 //Compute the helpers position 1646 this.position = this._generatePosition(event); 1647 this.positionAbs = this._convertPositionTo("absolute"); 1648 1649 //Call plugins and callbacks and use the resulting position if something is returned 1650 if (!noPropagation) { 1651 var ui = this._uiHash(); 1652 if(this._trigger("drag", event, ui) === false) { 1653 this._mouseUp({}); 1654 return false; 1655 } 1656 this.position = ui.position; 1657 } 1658 1659 if(!this.options.axis || this.options.axis !== "y") { 1660 this.helper[0].style.left = this.position.left+"px"; 1661 } 1662 if(!this.options.axis || this.options.axis !== "x") { 1663 this.helper[0].style.top = this.position.top+"px"; 1664 } 1665 if($.ui.ddmanager) { 1666 $.ui.ddmanager.drag(this, event); 1667 } 1668 1669 return false; 1670 }, 1671 1672 _mouseStop: function(event) { 1673 1674 //If we are using droppables, inform the manager about the drop 1675 var element, 1676 that = this, 1677 elementInDom = false, 1678 dropped = false; 1679 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1680 dropped = $.ui.ddmanager.drop(this, event); 1681 } 1682 1683 //if a drop comes from outside (a sortable) 1684 if(this.dropped) { 1685 dropped = this.dropped; 1686 this.dropped = false; 1687 } 1688 1689 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1690 element = this.element[0]; 1691 while ( element && (element = element.parentNode) ) { 1692 if (element === document ) { 1693 elementInDom = true; 1694 } 1695 } 1696 if ( !elementInDom && this.options.helper === "original" ) { 1697 return false; 1698 } 1699 1700 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))) { 1701 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1702 if(that._trigger("stop", event) !== false) { 1703 that._clear(); 1704 } 1705 }); 1706 } else { 1707 if(this._trigger("stop", event) !== false) { 1708 this._clear(); 1709 } 1710 } 1711 1712 return false; 1713 }, 1714 1715 _mouseUp: function(event) { 1716 //Remove frame helpers 1717 $("div.ui-draggable-iframeFix").each(function() { 1718 this.parentNode.removeChild(this); 1719 }); 1720 1721 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1722 if( $.ui.ddmanager ) { 1723 $.ui.ddmanager.dragStop(this, event); 1724 } 1725 1726 return $.ui.mouse.prototype._mouseUp.call(this, event); 1727 }, 1728 1729 cancel: function() { 1730 1731 if(this.helper.is(".ui-draggable-dragging")) { 1732 this._mouseUp({}); 1733 } else { 1734 this._clear(); 1735 } 1736 1737 return this; 1738 1739 }, 1740 1741 _getHandle: function(event) { 1742 1743 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 1744 $(this.options.handle, this.element) 1745 .find("*") 1746 .addBack() 1747 .each(function() { 1748 if(this === event.target) { 1749 handle = true; 1750 } 1751 }); 1752 1753 return handle; 1754 1755 }, 1756 1757 _createHelper: function(event) { 1758 1759 var o = this.options, 1760 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1761 1762 if(!helper.parents("body").length) { 1763 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1764 } 1765 1766 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1767 helper.css("position", "absolute"); 1768 } 1769 1770 return helper; 1771 1772 }, 1773 1774 _adjustOffsetFromHelper: function(obj) { 1775 if (typeof obj === "string") { 1776 obj = obj.split(" "); 1777 } 1778 if ($.isArray(obj)) { 1779 obj = {left: +obj[0], top: +obj[1] || 0}; 1780 } 1781 if ("left" in obj) { 1782 this.offset.click.left = obj.left + this.margins.left; 1783 } 1784 if ("right" in obj) { 1785 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1786 } 1787 if ("top" in obj) { 1788 this.offset.click.top = obj.top + this.margins.top; 1789 } 1790 if ("bottom" in obj) { 1791 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1792 } 1793 }, 1794 1795 _getParentOffset: function() { 1796 1797 //Get the offsetParent and cache its position 1798 this.offsetParent = this.helper.offsetParent(); 1799 var po = this.offsetParent.offset(); 1800 1801 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1802 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1803 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1804 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1805 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1806 po.left += this.scrollParent.scrollLeft(); 1807 po.top += this.scrollParent.scrollTop(); 1808 } 1809 1810 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1811 //Ugly IE fix 1812 if((this.offsetParent[0] === document.body) || 1813 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1814 po = { top: 0, left: 0 }; 1815 } 1816 1817 return { 1818 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
vendor: 1,408 bytes, lines 1818-1865
181810) || 0), 1819 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1820 }; 1821 1822 }, 1823 1824 _getRelativeOffset: function() { 1825 1826 if(this.cssPosition === "relative") { 1827 var p = this.element.position(); 1828 return { 1829 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1830 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1831 }; 1832 } else { 1833 return { top: 0, left: 0 }; 1834 } 1835 1836 }, 1837 1838 _cacheMargins: function() { 1839 this.margins = { 1840 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1841 top: (parseInt(this.element.css("marginTop"),10) || 0), 1842 right: (parseInt(this.element.css("marginRight"),10) || 0), 1843 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1844 }; 1845 }, 1846 1847 _cacheHelperProportions: function() { 1848 this.helperProportions = { 1849 width: this.helper.outerWidth(), 1850 height: this.helper.outerHeight() 1851 }; 1852 }, 1853 1854 _setContainment: function() { 1855 1856 var over, c, ce, 1857 o = this.options; 1858 1859 if(o.containment === "parent") { 1860 o.containment = this.helper[0].parentNode; 1861 } 1862 if(o.containment === "document" || o.containment === "window") { 1863 this.containment = [ 1864 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1865 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
vendor: 86,373 bytes, lines 1866-4726
1866 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 1867 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1868 ]; 1869 } 1870 1871 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { 1872 c = $(o.containment); 1873 ce = c[0]; 1874 1875 if(!ce) { 1876 return; 1877 } 1878 1879 over = ($(ce).css("overflow") !== "hidden"); 1880 1881 this.containment = [ 1882 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1883 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1884 (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, 1885 (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 1886 ]; 1887 this.relative_container = c; 1888 1889 } else if(o.containment.constructor === Array) { 1890 this.containment = o.containment; 1891 } 1892 1893 }, 1894 1895 _convertPositionTo: function(d, pos) { 1896 1897 if(!pos) { 1898 pos = this.position; 1899 } 1900 1901 var mod = d === "absolute" ? 1 : -1, 1902 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); 1903 1904 return { 1905 top: ( 1906 pos.top + // The absolute mouse position 1907 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1908 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1909 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1910 ), 1911 left: ( 1912 pos.left + // The absolute mouse position 1913 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1914 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1915 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1916 ) 1917 }; 1918 1919 }, 1920 1921 _generatePosition: function(event) { 1922 1923 var containment, co, top, left, 1924 o = this.options, 1925 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 1926 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), 1927 pageX = event.pageX, 1928 pageY = event.pageY; 1929 1930 /* 1931 * - Position constraining - 1932 * Constrain the position to a mix of grid, containment. 1933 */ 1934 1935 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1936 if(this.containment) { 1937 if (this.relative_container){ 1938 co = this.relative_container.offset(); 1939 containment = [ this.containment[0] + co.left, 1940 this.containment[1] + co.top, 1941 this.containment[2] + co.left, 1942 this.containment[3] + co.top ]; 1943 } 1944 else { 1945 containment = this.containment; 1946 } 1947 1948 if(event.pageX - this.offset.click.left < containment[0]) { 1949 pageX = containment[0] + this.offset.click.left; 1950 } 1951 if(event.pageY - this.offset.click.top < containment[1]) { 1952 pageY = containment[1] + this.offset.click.top; 1953 } 1954 if(event.pageX - this.offset.click.left > containment[2]) { 1955 pageX = containment[2] + this.offset.click.left; 1956 } 1957 if(event.pageY - this.offset.click.top > containment[3]) { 1958 pageY = containment[3] + this.offset.click.top; 1959 } 1960 } 1961 1962 if(o.grid) { 1963 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1964 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1965 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; 1966 1967 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1968 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; 1969 } 1970 1971 } 1972 1973 return { 1974 top: ( 1975 pageY - // The absolute mouse position 1976 this.offset.click.top - // Click offset (relative to the element) 1977 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1978 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1979 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1980 ), 1981 left: ( 1982 pageX - // The absolute mouse position 1983 this.offset.click.left - // Click offset (relative to the element) 1984 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1985 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1986 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1987 ) 1988 }; 1989 1990 }, 1991 1992 _clear: function() { 1993 this.helper.removeClass("ui-draggable-dragging"); 1994 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1995 this.helper.remove(); 1996 } 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 //The absolute position has to be recalculated after plugins 2007 if(type === "drag") { 2008 this.positionAbs = this._convertPositionTo("absolute"); 2009 } 2010 return $.Widget.prototype._trigger.call(this, type, event, ui); 2011 }, 2012 2013 plugins: {}, 2014 2015 _uiHash: function() { 2016 return { 2017 helper: this.helper, 2018 position: this.position, 2019 originalPosition: this.originalPosition, 2020 offset: this.positionAbs 2021 }; 2022 } 2023 2024}); 2025 2026$.ui.plugin.add("draggable", "connectToSortable", { 2027 start: function(event, ui) { 2028 2029 var inst = $(this).data("ui-draggable"), o = inst.options, 2030 uiSortable = $.extend({}, ui, { item: inst.element }); 2031 inst.sortables = []; 2032 $(o.connectToSortable).each(function() { 2033 var sortable = $.data(this, "ui-sortable"); 2034 if (sortable && !sortable.options.disabled) { 2035 inst.sortables.push({ 2036 instance: sortable, 2037 shouldRevert: sortable.options.revert 2038 }); 2039 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). 2040 sortable._trigger("activate", event, uiSortable); 2041 } 2042 }); 2043 2044 }, 2045 stop: function(event, ui) { 2046 2047 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2048 var inst = $(this).data("ui-draggable"), 2049 uiSortable = $.extend({}, ui, { item: inst.element }); 2050 2051 $.each(inst.sortables, function() { 2052 if(this.instance.isOver) { 2053 2054 this.instance.isOver = 0; 2055 2056 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2057 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2058 2059 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 2060 if(this.shouldRevert) { 2061 this.instance.options.revert = true; 2062 } 2063 2064 //Trigger the stop of the sortable 2065 this.instance._mouseStop(event); 2066 2067 this.instance.options.helper = this.instance.options._helper; 2068 2069 //If the helper has been the original item, restore properties in the sortable 2070 if(inst.options.helper === "original") { 2071 this.instance.currentItem.css({ top: "auto", left: "auto" }); 2072 } 2073 2074 } else { 2075 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2076 this.instance._trigger("deactivate", event, uiSortable); 2077 } 2078 2079 }); 2080 2081 }, 2082 drag: function(event, ui) { 2083 2084 var inst = $(this).data("ui-draggable"), that = this; 2085 2086 $.each(inst.sortables, function() { 2087 2088 var innermostIntersecting = false, 2089 thisSortable = this; 2090 2091 //Copy over some variables to allow calling the sortable's native _intersectsWith 2092 this.instance.positionAbs = inst.positionAbs; 2093 this.instance.helperProportions = inst.helperProportions; 2094 this.instance.offset.click = inst.offset.click; 2095 2096 if(this.instance._intersectsWith(this.instance.containerCache)) { 2097 innermostIntersecting = true; 2098 $.each(inst.sortables, function () { 2099 this.instance.positionAbs = inst.positionAbs; 2100 this.instance.helperProportions = inst.helperProportions; 2101 this.instance.offset.click = inst.offset.click; 2102 if (this !== thisSortable && 2103 this.instance._intersectsWith(this.instance.containerCache) && 2104 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 2105 ) { 2106 innermostIntersecting = false; 2107 } 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("ui-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) { 2145 this.instance._mouseDrag(event); 2146 } 2147 2148 } else { 2149 2150 //If it doesn't intersect with the sortable, and it intersected before, 2151 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2152 if(this.instance.isOver) { 2153 2154 this.instance.isOver = 0; 2155 this.instance.cancelHelperRemoval = true; 2156 2157 //Prevent reverting on this forced stop 2158 this.instance.options.revert = false; 2159 2160 // The out event needs to be triggered independently 2161 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 2162 2163 this.instance._mouseStop(event, true); 2164 this.instance.options.helper = this.instance.options._helper; 2165 2166 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2167 this.instance.currentItem.remove(); 2168 if(this.instance.placeholder) { 2169 this.instance.placeholder.remove(); 2170 } 2171 2172 inst._trigger("fromSortable", event); 2173 inst.dropped = false; //draggable revert needs that 2174 } 2175 2176 } 2177 2178 }); 2179 2180 } 2181}); 2182 2183$.ui.plugin.add("draggable", "cursor", { 2184 start: function() { 2185 var t = $("body"), o = $(this).data("ui-draggable").options; 2186 if (t.css("cursor")) { 2187 o._cursor = t.css("cursor"); 2188 } 2189 t.css("cursor", o.cursor); 2190 }, 2191 stop: function() { 2192 var o = $(this).data("ui-draggable").options; 2193 if (o._cursor) { 2194 $("body").css("cursor", o._cursor); 2195 } 2196 } 2197}); 2198 2199$.ui.plugin.add("draggable", "opacity", { 2200 start: function(event, ui) { 2201 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2202 if(t.css("opacity")) { 2203 o._opacity = t.css("opacity"); 2204 } 2205 t.css("opacity", o.opacity); 2206 }, 2207 stop: function(event, ui) { 2208 var o = $(this).data("ui-draggable").options; 2209 if(o._opacity) { 2210 $(ui.helper).css("opacity", o._opacity); 2211 } 2212 } 2213}); 2214 2215$.ui.plugin.add("draggable", "scroll", { 2216 start: function() { 2217 var i = $(this).data("ui-draggable"); 2218 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2219 i.overflowOffset = i.scrollParent.offset(); 2220 } 2221 }, 2222 drag: function( event ) { 2223 2224 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 2225 2226 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2227 2228 if(!o.axis || o.axis !== "x") { 2229 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 2230 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 2231 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 2232 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 2233 } 2234 } 2235 2236 if(!o.axis || o.axis !== "y") { 2237 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 2238 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 2239 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 2240 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 2241 } 2242 } 2243 2244 } else { 2245 2246 if(!o.axis || o.axis !== "x") { 2247 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 2248 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2249 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 2250 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2251 } 2252 } 2253 2254 if(!o.axis || o.axis !== "y") { 2255 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 2256 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2257 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 2258 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2259 } 2260 } 2261 2262 } 2263 2264 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 2265 $.ui.ddmanager.prepareOffsets(i, event); 2266 } 2267 2268 } 2269}); 2270 2271$.ui.plugin.add("draggable", "snap", { 2272 start: function() { 2273 2274 var i = $(this).data("ui-draggable"), 2275 o = i.options; 2276 2277 i.snapElements = []; 2278 2279 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 2280 var $t = $(this), 2281 $o = $t.offset(); 2282 if(this !== i.element[0]) { 2283 i.snapElements.push({ 2284 item: this, 2285 width: $t.outerWidth(), height: $t.outerHeight(), 2286 top: $o.top, left: $o.left 2287 }); 2288 } 2289 }); 2290 2291 }, 2292 drag: function(event, ui) { 2293 2294 var ts, bs, ls, rs, l, r, t, b, i, first, 2295 inst = $(this).data("ui-draggable"), 2296 o = inst.options, 2297 d = o.snapTolerance, 2298 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2299 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2300 2301 for (i = inst.snapElements.length - 1; i >= 0; i--){ 2302 2303 l = inst.snapElements[i].left; 2304 r = l + inst.snapElements[i].width; 2305 t = inst.snapElements[i].top; 2306 b = t + inst.snapElements[i].height; 2307 2308 //Yes, I know, this is insane ;) 2309 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))) { 2310 if(inst.snapElements[i].snapping) { 2311 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2312 } 2313 inst.snapElements[i].snapping = false; 2314 continue; 2315 } 2316 2317 if(o.snapMode !== "inner") { 2318 ts = Math.abs(t - y2) <= d; 2319 bs = Math.abs(b - y1) <= d; 2320 ls = Math.abs(l - x2) <= d; 2321 rs = Math.abs(r - x1) <= d; 2322 if(ts) { 2323 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2324 } 2325 if(bs) { 2326 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2327 } 2328 if(ls) { 2329 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2330 } 2331 if(rs) { 2332 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2333 } 2334 } 2335 2336 first = (ts || bs || ls || rs); 2337 2338 if(o.snapMode !== "outer") { 2339 ts = Math.abs(t - y1) <= d; 2340 bs = Math.abs(b - y2) <= d; 2341 ls = Math.abs(l - x1) <= d; 2342 rs = Math.abs(r - x2) <= d; 2343 if(ts) { 2344 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2345 } 2346 if(bs) { 2347 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2348 } 2349 if(ls) { 2350 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2351 } 2352 if(rs) { 2353 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2354 } 2355 } 2356 2357 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 2358 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2359 } 2360 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2361 2362 } 2363 2364 } 2365}); 2366 2367$.ui.plugin.add("draggable", "stack", { 2368 start: function() { 2369 var min, 2370 o = this.data("ui-draggable").options, 2371 group = $.makeArray($(o.stack)).sort(function(a,b) { 2372 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 2373 }); 2374 2375 if (!group.length) { return; } 2376 2377 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 2378 $(group).each(function(i) { 2379 $(this).css("zIndex", min + i); 2380 }); 2381 this.css("zIndex", (min + group.length)); 2382 } 2383}); 2384 2385$.ui.plugin.add("draggable", "zIndex", { 2386 start: function(event, ui) { 2387 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2388 if(t.css("zIndex")) { 2389 o._zIndex = t.css("zIndex"); 2390 } 2391 t.css("zIndex", o.zIndex); 2392 }, 2393 stop: function(event, ui) { 2394 var o = $(this).data("ui-draggable").options; 2395 if(o._zIndex) { 2396 $(ui.helper).css("zIndex", o._zIndex); 2397 } 2398 } 2399}); 2400 2401})(jQuery); 2402(function( $, undefined ) { 2403 2404function isOverAxis( x, reference, size ) { 2405 return ( x > reference ) && ( x < ( reference + size ) ); 2406} 2407 2408$.widget("ui.droppable", { 2409 version: "1.10.1", 2410 widgetEventPrefix: "drop", 2411 options: { 2412 accept: "*", 2413 activeClass: false, 2414 addClasses: true, 2415 greedy: false, 2416 hoverClass: false, 2417 scope: "default", 2418 tolerance: "intersect", 2419 2420 // callbacks 2421 activate: null, 2422 deactivate: null, 2423 drop: null, 2424 out: null, 2425 over: null 2426 }, 2427 _create: function() { 2428 2429 var o = this.options, 2430 accept = o.accept; 2431 2432 this.isover = false; 2433 this.isout = true; 2434 2435 this.accept = $.isFunction(accept) ? accept : function(d) { 2436 return d.is(accept); 2437 }; 2438 2439 //Store the droppable's proportions 2440 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 2441 2442 // Add the reference and positions to the manager 2443 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 2444 $.ui.ddmanager.droppables[o.scope].push(this); 2445 2446 (o.addClasses && this.element.addClass("ui-droppable")); 2447 2448 }, 2449 2450 _destroy: function() { 2451 var i = 0, 2452 drop = $.ui.ddmanager.droppables[this.options.scope]; 2453 2454 for ( ; i < drop.length; i++ ) { 2455 if ( drop[i] === this ) { 2456 drop.splice(i, 1); 2457 } 2458 } 2459 2460 this.element.removeClass("ui-droppable ui-droppable-disabled"); 2461 }, 2462 2463 _setOption: function(key, value) { 2464 2465 if(key === "accept") { 2466 this.accept = $.isFunction(value) ? value : function(d) { 2467 return d.is(value); 2468 }; 2469 } 2470 $.Widget.prototype._setOption.apply(this, arguments); 2471 }, 2472 2473 _activate: function(event) { 2474 var draggable = $.ui.ddmanager.current; 2475 if(this.options.activeClass) { 2476 this.element.addClass(this.options.activeClass); 2477 } 2478 if(draggable){ 2479 this._trigger("activate", event, this.ui(draggable)); 2480 } 2481 }, 2482 2483 _deactivate: function(event) { 2484 var draggable = $.ui.ddmanager.current; 2485 if(this.options.activeClass) { 2486 this.element.removeClass(this.options.activeClass); 2487 } 2488 if(draggable){ 2489 this._trigger("deactivate", event, this.ui(draggable)); 2490 } 2491 }, 2492 2493 _over: function(event) { 2494 2495 var draggable = $.ui.ddmanager.current; 2496 2497 // Bail if draggable and droppable are same element 2498 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2499 return; 2500 } 2501 2502 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2503 if(this.options.hoverClass) { 2504 this.element.addClass(this.options.hoverClass); 2505 } 2506 this._trigger("over", event, this.ui(draggable)); 2507 } 2508 2509 }, 2510 2511 _out: function(event) { 2512 2513 var draggable = $.ui.ddmanager.current; 2514 2515 // Bail if draggable and droppable are same element 2516 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2517 return; 2518 } 2519 2520 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2521 if(this.options.hoverClass) { 2522 this.element.removeClass(this.options.hoverClass); 2523 } 2524 this._trigger("out", event, this.ui(draggable)); 2525 } 2526 2527 }, 2528 2529 _drop: function(event,custom) { 2530 2531 var draggable = custom || $.ui.ddmanager.current, 2532 childrenIntersection = false; 2533 2534 // Bail if draggable and droppable are same element 2535 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2536 return false; 2537 } 2538 2539 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2540 var inst = $.data(this, "ui-droppable"); 2541 if( 2542 inst.options.greedy && 2543 !inst.options.disabled && 2544 inst.options.scope === draggable.options.scope && 2545 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2546 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2547 ) { childrenIntersection = true; return false; } 2548 }); 2549 if(childrenIntersection) { 2550 return false; 2551 } 2552 2553 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2554 if(this.options.activeClass) { 2555 this.element.removeClass(this.options.activeClass); 2556 } 2557 if(this.options.hoverClass) { 2558 this.element.removeClass(this.options.hoverClass); 2559 } 2560 this._trigger("drop", event, this.ui(draggable)); 2561 return this.element; 2562 } 2563 2564 return false; 2565 2566 }, 2567 2568 ui: function(c) { 2569 return { 2570 draggable: (c.currentItem || c.element), 2571 helper: c.helper, 2572 position: c.position, 2573 offset: c.positionAbs 2574 }; 2575 } 2576 2577}); 2578 2579$.ui.intersect = function(draggable, droppable, toleranceMode) { 2580 2581 if (!droppable.offset) { 2582 return false; 2583 } 2584 2585 var draggableLeft, draggableTop, 2586 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2587 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2588 l = droppable.offset.left, r = l + droppable.proportions.width, 2589 t = droppable.offset.top, b = t + droppable.proportions.height; 2590 2591 switch (toleranceMode) { 2592 case "fit": 2593 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2594 case "intersect": 2595 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2596 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2597 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2598 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2599 case "pointer": 2600 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2601 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2602 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2603 case "touch": 2604 return ( 2605 (y1 >= t && y1 <= b) || // Top edge touching 2606 (y2 >= t && y2 <= b) || // Bottom edge touching 2607 (y1 < t && y2 > b) // Surrounded vertically 2608 ) && ( 2609 (x1 >= l && x1 <= r) || // Left edge touching 2610 (x2 >= l && x2 <= r) || // Right edge touching 2611 (x1 < l && x2 > r) // Surrounded horizontally 2612 ); 2613 default: 2614 return false; 2615 } 2616 2617}; 2618 2619/* 2620 This manager tracks offsets of draggables and droppables 2621*/ 2622$.ui.ddmanager = { 2623 current: null, 2624 droppables: { "default": [] }, 2625 prepareOffsets: function(t, event) { 2626 2627 var i, j, 2628 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2629 type = event ? event.type : null, // workaround for #2317 2630 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2631 2632 droppablesLoop: for (i = 0; i < m.length; i++) { 2633 2634 //No disabled and non-accepted 2635 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2636 continue; 2637 } 2638 2639 // Filter out elements in the current dragged item 2640 for (j=0; j < list.length; j++) { 2641 if(list[j] === m[i].element[0]) { 2642 m[i].proportions.height = 0; 2643 continue droppablesLoop; 2644 } 2645 } 2646 2647 m[i].visible = m[i].element.css("display") !== "none"; 2648 if(!m[i].visible) { 2649 continue; 2650 } 2651 2652 //Activate the droppable if used directly from draggables 2653 if(type === "mousedown") { 2654 m[i]._activate.call(m[i], event); 2655 } 2656 2657 m[i].offset = m[i].element.offset(); 2658 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2659 2660 } 2661 2662 }, 2663 drop: function(draggable, event) { 2664 2665 var dropped = false; 2666 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2667 2668 if(!this.options) { 2669 return; 2670 } 2671 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2672 dropped = this._drop.call(this, event) || dropped; 2673 } 2674 2675 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2676 this.isout = true; 2677 this.isover = false; 2678 this._deactivate.call(this, event); 2679 } 2680 2681 }); 2682 return dropped; 2683 2684 }, 2685 dragStart: function( draggable, event ) { 2686 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2687 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2688 if( !draggable.options.refreshPositions ) { 2689 $.ui.ddmanager.prepareOffsets( draggable, event ); 2690 } 2691 }); 2692 }, 2693 drag: function(draggable, event) { 2694 2695 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2696 if(draggable.options.refreshPositions) { 2697 $.ui.ddmanager.prepareOffsets(draggable, event); 2698 } 2699 2700 //Run through all droppables and check their positions based on specific tolerance options 2701 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2702 2703 if(this.options.disabled || this.greedyChild || !this.visible) { 2704 return; 2705 } 2706 2707 var parentInstance, scope, parent, 2708 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2709 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2710 if(!c) { 2711 return; 2712 } 2713 2714 if (this.options.greedy) { 2715 // find droppable parents with same scope 2716 scope = this.options.scope; 2717 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2718 return $.data(this, "ui-droppable").options.scope === scope; 2719 }); 2720 2721 if (parent.length) { 2722 parentInstance = $.data(parent[0], "ui-droppable"); 2723 parentInstance.greedyChild = (c === "isover"); 2724 } 2725 } 2726 2727 // we just moved into a greedy child 2728 if (parentInstance && c === "isover") { 2729 parentInstance.isover = false; 2730 parentInstance.isout = true; 2731 parentInstance._out.call(parentInstance, event); 2732 } 2733 2734 this[c] = true; 2735 this[c === "isout" ? "isover" : "isout"] = false; 2736 this[c === "isover" ? "_over" : "_out"].call(this, event); 2737 2738 // we just moved out of a greedy child 2739 if (parentInstance && c === "isout") { 2740 parentInstance.isout = false; 2741 parentInstance.isover = true; 2742 parentInstance._over.call(parentInstance, event); 2743 } 2744 }); 2745 2746 }, 2747 dragStop: function( draggable, event ) { 2748 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2749 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2750 if( !draggable.options.refreshPositions ) { 2751 $.ui.ddmanager.prepareOffsets( draggable, event ); 2752 } 2753 } 2754}; 2755 2756})(jQuery); 2757(function( $, undefined ) { 2758 2759function num(v) { 2760 return parseInt(v, 10) || 0; 2761} 2762 2763function isNumber(value) { 2764 return !isNaN(parseInt(value, 10)); 2765} 2766 2767$.widget("ui.resizable", $.ui.mouse, { 2768 version: "1.10.1", 2769 widgetEventPrefix: "resize", 2770 options: { 2771 alsoResize: false, 2772 animate: false, 2773 animateDuration: "slow", 2774 animateEasing: "swing", 2775 aspectRatio: false, 2776 autoHide: false, 2777 containment: false, 2778 ghost: false, 2779 grid: false, 2780 handles: "e,s,se", 2781 helper: false, 2782 maxHeight: null, 2783 maxWidth: null, 2784 minHeight: 10, 2785 minWidth: 10, 2786 // See #7960 2787 zIndex: 90, 2788 2789 // callbacks 2790 resize: null, 2791 start: null, 2792 stop: null 2793 }, 2794 _create: function() { 2795 2796 var n, i, handle, axis, hname, 2797 that = this, 2798 o = this.options; 2799 this.element.addClass("ui-resizable"); 2800 2801 $.extend(this, { 2802 _aspectRatio: !!(o.aspectRatio), 2803 aspectRatio: o.aspectRatio, 2804 originalElement: this.element, 2805 _proportionallyResizeElements: [], 2806 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2807 }); 2808 2809 //Wrap the element if it cannot hold child nodes 2810 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2811 2812 //Create a wrapper element and set the wrapper to the new current internal element 2813 this.element.wrap( 2814 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2815 position: this.element.css("position"), 2816 width: this.element.outerWidth(), 2817 height: this.element.outerHeight(), 2818 top: this.element.css("top"), 2819 left: this.element.css("left") 2820 }) 2821 ); 2822 2823 //Overwrite the original this.element 2824 this.element = this.element.parent().data( 2825 "ui-resizable", this.element.data("ui-resizable") 2826 ); 2827 2828 this.elementIsWrapper = true; 2829 2830 //Move margins to the wrapper 2831 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2832 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2833 2834 //Prevent Safari textarea resize 2835 this.originalResizeStyle = this.originalElement.css("resize"); 2836 this.originalElement.css("resize", "none"); 2837 2838 //Push the actual element to our proportionallyResize internal array 2839 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2840 2841 // avoid IE jump (hard set the margin) 2842 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2843 2844 // fix handlers offset 2845 this._proportionallyResize(); 2846 2847 } 2848 2849 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" }); 2850 if(this.handles.constructor === String) { 2851 2852 if ( this.handles === "all") { 2853 this.handles = "n,e,s,w,se,sw,ne,nw"; 2854 } 2855 2856 n = this.handles.split(","); 2857 this.handles = {}; 2858 2859 for(i = 0; i < n.length; i++) { 2860 2861 handle = $.trim(n[i]); 2862 hname = "ui-resizable-"+handle; 2863 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2864 2865 // Apply zIndex to all handles - see #7960 2866 axis.css({ zIndex: o.zIndex }); 2867 2868 //TODO : What's going on here? 2869 if ("se" === handle) { 2870 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2871 } 2872 2873 //Insert into internal handles object and append to element 2874 this.handles[handle] = ".ui-resizable-"+handle; 2875 this.element.append(axis); 2876 } 2877 2878 } 2879 2880 this._renderAxis = function(target) { 2881 2882 var i, axis, padPos, padWrapper; 2883 2884 target = target || this.element; 2885 2886 for(i in this.handles) { 2887 2888 if(this.handles[i].constructor === String) { 2889 this.handles[i] = $(this.handles[i], this.element).show(); 2890 } 2891 2892 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2893 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2894 2895 axis = $(this.handles[i], this.element); 2896 2897 //Checking the correct pad and border 2898 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2899 2900 //The padding type i have to apply... 2901 padPos = [ "padding", 2902 /ne|nw|n/.test(i) ? "Top" : 2903 /se|sw|s/.test(i) ? "Bottom" : 2904 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2905 2906 target.css(padPos, padWrapper); 2907 2908 this._proportionallyResize(); 2909 2910 } 2911 2912 //TODO: What's that good for? There's not anything to be executed left 2913 if(!$(this.handles[i]).length) { 2914 continue; 2915 } 2916 } 2917 }; 2918 2919 //TODO: make renderAxis a prototype function 2920 this._renderAxis(this.element); 2921 2922 this._handles = $(".ui-resizable-handle", this.element) 2923 .disableSelection(); 2924 2925 //Matching axis name 2926 this._handles.mouseover(function() { 2927 if (!that.resizing) { 2928 if (this.className) { 2929 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2930 } 2931 //Axis, default = se 2932 that.axis = axis && axis[1] ? axis[1] : "se"; 2933 } 2934 }); 2935 2936 //If we want to auto hide the elements 2937 if (o.autoHide) { 2938 this._handles.hide(); 2939 $(this.element) 2940 .addClass("ui-resizable-autohide") 2941 .mouseenter(function() { 2942 if (o.disabled) { 2943 return; 2944 } 2945 $(this).removeClass("ui-resizable-autohide"); 2946 that._handles.show(); 2947 }) 2948 .mouseleave(function(){ 2949 if (o.disabled) { 2950 return; 2951 } 2952 if (!that.resizing) { 2953 $(this).addClass("ui-resizable-autohide"); 2954 that._handles.hide(); 2955 } 2956 }); 2957 } 2958 2959 //Initialize the mouse interaction 2960 this._mouseInit(); 2961 2962 }, 2963 2964 _destroy: function() { 2965 2966 this._mouseDestroy(); 2967 2968 var wrapper, 2969 _destroy = function(exp) { 2970 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2971 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2972 }; 2973 2974 //TODO: Unwrap at same DOM position 2975 if (this.elementIsWrapper) { 2976 _destroy(this.element); 2977 wrapper = this.element; 2978 this.originalElement.css({ 2979 position: wrapper.css("position"), 2980 width: wrapper.outerWidth(), 2981 height: wrapper.outerHeight(), 2982 top: wrapper.css("top"), 2983 left: wrapper.css("left") 2984 }).insertAfter( wrapper ); 2985 wrapper.remove(); 2986 } 2987 2988 this.originalElement.css("resize", this.originalResizeStyle); 2989 _destroy(this.originalElement); 2990 2991 return this; 2992 }, 2993 2994 _mouseCapture: function(event) { 2995 var i, handle, 2996 capture = false; 2997 2998 for (i in this.handles) { 2999 handle = $(this.handles[i])[0]; 3000 if (handle === event.target || $.contains(handle, event.target)) { 3001 capture = true; 3002 } 3003 } 3004 3005 return !this.options.disabled && capture; 3006 }, 3007 3008 _mouseStart: function(event) { 3009 3010 var curleft, curtop, cursor, 3011 o = this.options, 3012 iniPos = this.element.position(), 3013 el = this.element; 3014 3015 this.resizing = true; 3016 3017 // bugfix for http://dev.jquery.com/ticket/1749 3018 if ( (/absolute/).test( el.css("position") ) ) { 3019 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 3020 } else if (el.is(".ui-draggable")) { 3021 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 3022 } 3023 3024 this._renderProxy(); 3025 3026 curleft = num(this.helper.css("left")); 3027 curtop = num(this.helper.css("top")); 3028 3029 if (o.containment) { 3030 curleft += $(o.containment).scrollLeft() || 0; 3031 curtop += $(o.containment).scrollTop() || 0; 3032 } 3033 3034 //Store needed variables 3035 this.offset = this.helper.offset(); 3036 this.position = { left: curleft, top: curtop }; 3037 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 3038 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 3039 this.originalPosition = { left: curleft, top: curtop }; 3040 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 3041 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 3042 3043 //Aspect Ratio 3044 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 3045 3046 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 3047 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 3048 3049 el.addClass("ui-resizable-resizing"); 3050 this._propagate("start", event); 3051 return true; 3052 }, 3053 3054 _mouseDrag: function(event) { 3055 3056 //Increase performance, avoid regex 3057 var data, 3058 el = this.helper, props = {}, 3059 smp = this.originalMousePosition, 3060 a = this.axis, 3061 prevTop = this.position.top, 3062 prevLeft = this.position.left, 3063 prevWidth = this.size.width, 3064 prevHeight = this.size.height, 3065 dx = (event.pageX-smp.left)||0, 3066 dy = (event.pageY-smp.top)||0, 3067 trigger = this._change[a]; 3068 3069 if (!trigger) { 3070 return false; 3071 } 3072 3073 // Calculate the attrs that will be change 3074 data = trigger.apply(this, [event, dx, dy]); 3075 3076 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 3077 this._updateVirtualBoundaries(event.shiftKey); 3078 if (this._aspectRatio || event.shiftKey) { 3079 data = this._updateRatio(data, event); 3080 } 3081 3082 data = this._respectSize(data, event); 3083 3084 this._updateCache(data); 3085 3086 // plugins callbacks need to be called first 3087 this._propagate("resize", event); 3088 3089 if (this.position.top !== prevTop) { 3090 props.top = this.position.top + "px"; 3091 } 3092 if (this.position.left !== prevLeft) { 3093 props.left = this.position.left + "px"; 3094 } 3095 if (this.size.width !== prevWidth) { 3096 props.width = this.size.width + "px"; 3097 } 3098 if (this.size.height !== prevHeight) { 3099 props.height = this.size.height + "px"; 3100 } 3101 el.css(props); 3102 3103 if (!this._helper && this._proportionallyResizeElements.length) { 3104 this._proportionallyResize(); 3105 } 3106 3107 // Call the user callback if the element was resized 3108 if ( ! $.isEmptyObject(props) ) { 3109 this._trigger("resize", event, this.ui()); 3110 } 3111 3112 return false; 3113 }, 3114 3115 _mouseStop: function(event) { 3116 3117 this.resizing = false; 3118 var pr, ista, soffseth, soffsetw, s, left, top, 3119 o = this.options, that = this; 3120 3121 if(this._helper) { 3122 3123 pr = this._proportionallyResizeElements; 3124 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 3125 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 3126 soffsetw = ista ? 0 : that.sizeDiff.width; 3127 3128 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 3129 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 3130 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3131 3132 if (!o.animate) { 3133 this.element.css($.extend(s, { top: top, left: left })); 3134 } 3135 3136 that.helper.height(that.size.height); 3137 that.helper.width(that.size.width); 3138 3139 if (this._helper && !o.animate) { 3140 this._proportionallyResize(); 3141 } 3142 } 3143 3144 $("body").css("cursor", "auto"); 3145 3146 this.element.removeClass("ui-resizable-resizing"); 3147 3148 this._propagate("stop", event); 3149 3150 if (this._helper) { 3151 this.helper.remove(); 3152 } 3153 3154 return false; 3155 3156 }, 3157 3158 _updateVirtualBoundaries: function(forceAspectRatio) { 3159 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 3160 o = this.options; 3161 3162 b = { 3163 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 3164 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 3165 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 3166 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 3167 }; 3168 3169 if(this._aspectRatio || forceAspectRatio) { 3170 // We want to create an enclosing box whose aspect ration is the requested one 3171 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 3172 pMinWidth = b.minHeight * this.aspectRatio; 3173 pMinHeight = b.minWidth / this.aspectRatio; 3174 pMaxWidth = b.maxHeight * this.aspectRatio; 3175 pMaxHeight = b.maxWidth / this.aspectRatio; 3176 3177 if(pMinWidth > b.minWidth) { 3178 b.minWidth = pMinWidth; 3179 } 3180 if(pMinHeight > b.minHeight) { 3181 b.minHeight = pMinHeight; 3182 } 3183 if(pMaxWidth < b.maxWidth) { 3184 b.maxWidth = pMaxWidth; 3185 } 3186 if(pMaxHeight < b.maxHeight) { 3187 b.maxHeight = pMaxHeight; 3188 } 3189 } 3190 this._vBoundaries = b; 3191 }, 3192 3193 _updateCache: function(data) { 3194 this.offset = this.helper.offset(); 3195 if (isNumber(data.left)) { 3196 this.position.left = data.left; 3197 } 3198 if (isNumber(data.top)) { 3199 this.position.top = data.top; 3200 } 3201 if (isNumber(data.height)) { 3202 this.size.height = data.height; 3203 } 3204 if (isNumber(data.width)) { 3205 this.size.width = data.width; 3206 } 3207 }, 3208 3209 _updateRatio: function( data ) { 3210 3211 var cpos = this.position, 3212 csize = this.size, 3213 a = this.axis; 3214 3215 if (isNumber(data.height)) { 3216 data.width = (data.height * this.aspectRatio); 3217 } else if (isNumber(data.width)) { 3218 data.height = (data.width / this.aspectRatio); 3219 } 3220 3221 if (a === "sw") { 3222 data.left = cpos.left + (csize.width - data.width); 3223 data.top = null; 3224 } 3225 if (a === "nw") { 3226 data.top = cpos.top + (csize.height - data.height); 3227 data.left = cpos.left + (csize.width - data.width); 3228 } 3229 3230 return data; 3231 }, 3232 3233 _respectSize: function( data ) { 3234 3235 var o = this._vBoundaries, 3236 a = this.axis, 3237 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3238 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 3239 dw = this.originalPosition.left + this.originalSize.width, 3240 dh = this.position.top + this.size.height, 3241 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3242 if (isminw) { 3243 data.width = o.minWidth; 3244 } 3245 if (isminh) { 3246 data.height = o.minHeight; 3247 } 3248 if (ismaxw) { 3249 data.width = o.maxWidth; 3250 } 3251 if (ismaxh) { 3252 data.height = o.maxHeight; 3253 } 3254 3255 if (isminw && cw) { 3256 data.left = dw - o.minWidth; 3257 } 3258 if (ismaxw && cw) { 3259 data.left = dw - o.maxWidth; 3260 } 3261 if (isminh && ch) { 3262 data.top = dh - o.minHeight; 3263 } 3264 if (ismaxh && ch) { 3265 data.top = dh - o.maxHeight; 3266 } 3267 3268 // fixing jump error on top/left - bug #2330 3269 if (!data.width && !data.height && !data.left && data.top) { 3270 data.top = null; 3271 } else if (!data.width && !data.height && !data.top && data.left) { 3272 data.left = null; 3273 } 3274 3275 return data; 3276 }, 3277 3278 _proportionallyResize: function() { 3279 3280 if (!this._proportionallyResizeElements.length) { 3281 return; 3282 } 3283 3284 var i, j, borders, paddings, prel, 3285 element = this.helper || this.element; 3286 3287 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 3288 3289 prel = this._proportionallyResizeElements[i]; 3290 3291 if (!this.borderDif) { 3292 this.borderDif = []; 3293 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 3294 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 3295 3296 for ( j = 0; j < borders.length; j++ ) { 3297 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 3298 } 3299 } 3300 3301 prel.css({ 3302 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 3303 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 3304 }); 3305 3306 } 3307 3308 }, 3309 3310 _renderProxy: function() { 3311 3312 var el = this.element, o = this.options; 3313 this.elementOffset = el.offset(); 3314 3315 if(this._helper) { 3316 3317 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 3318 3319 this.helper.addClass(this._helper).css({ 3320 width: this.element.outerWidth() - 1, 3321 height: this.element.outerHeight() - 1, 3322 position: "absolute", 3323 left: this.elementOffset.left +"px", 3324 top: this.elementOffset.top +"px", 3325 zIndex: ++o.zIndex //TODO: Don't modify option 3326 }); 3327 3328 this.helper 3329 .appendTo("body") 3330 .disableSelection(); 3331 3332 } else { 3333 this.helper = this.element; 3334 } 3335 3336 }, 3337 3338 _change: { 3339 e: function(event, dx) { 3340 return { width: this.originalSize.width + dx }; 3341 }, 3342 w: function(event, dx) { 3343 var cs = this.originalSize, sp = this.originalPosition; 3344 return { left: sp.left + dx, width: cs.width - dx }; 3345 }, 3346 n: function(event, dx, dy) { 3347 var cs = this.originalSize, sp = this.originalPosition; 3348 return { top: sp.top + dy, height: cs.height - dy }; 3349 }, 3350 s: function(event, dx, dy) { 3351 return { height: this.originalSize.height + dy }; 3352 }, 3353 se: function(event, dx, dy) { 3354 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3355 }, 3356 sw: function(event, dx, dy) { 3357 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3358 }, 3359 ne: function(event, dx, dy) { 3360 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3361 }, 3362 nw: function(event, dx, dy) { 3363 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3364 } 3365 }, 3366 3367 _propagate: function(n, event) { 3368 $.ui.plugin.call(this, n, [event, this.ui()]); 3369 (n !== "resize" && this._trigger(n, event, this.ui())); 3370 }, 3371 3372 plugins: {}, 3373 3374 ui: function() { 3375 return { 3376 originalElement: this.originalElement, 3377 element: this.element, 3378 helper: this.helper, 3379 position: this.position, 3380 size: this.size, 3381 originalSize: this.originalSize, 3382 originalPosition: this.originalPosition 3383 }; 3384 } 3385 3386}); 3387 3388/* 3389 * Resizable Extensions 3390 */ 3391 3392$.ui.plugin.add("resizable", "animate", { 3393 3394 stop: function( event ) { 3395 var that = $(this).data("ui-resizable"), 3396 o = that.options, 3397 pr = that._proportionallyResizeElements, 3398 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3399 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 3400 soffsetw = ista ? 0 : that.sizeDiff.width, 3401 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3402 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 3403 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3404 3405 that.element.animate( 3406 $.extend(style, top && left ? { top: top, left: left } : {}), { 3407 duration: o.animateDuration, 3408 easing: o.animateEasing, 3409 step: function() { 3410 3411 var data = { 3412 width: parseInt(that.element.css("width"), 10), 3413 height: parseInt(that.element.css("height"), 10), 3414 top: parseInt(that.element.css("top"), 10), 3415 left: parseInt(that.element.css("left"), 10) 3416 }; 3417 3418 if (pr && pr.length) { 3419 $(pr[0]).css({ width: data.width, height: data.height }); 3420 } 3421 3422 // propagating resize, and updating values for each animation step 3423 that._updateCache(data); 3424 that._propagate("resize", event); 3425 3426 } 3427 } 3428 ); 3429 } 3430 3431}); 3432 3433$.ui.plugin.add("resizable", "containment", { 3434 3435 start: function() { 3436 var element, p, co, ch, cw, width, height, 3437 that = $(this).data("ui-resizable"), 3438 o = that.options, 3439 el = that.element, 3440 oc = o.containment, 3441 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 3442 3443 if (!ce) { 3444 return; 3445 } 3446 3447 that.containerElement = $(ce); 3448 3449 if (/document/.test(oc) || oc === document) { 3450 that.containerOffset = { left: 0, top: 0 }; 3451 that.containerPosition = { left: 0, top: 0 }; 3452 3453 that.parentData = { 3454 element: $(document), left: 0, top: 0, 3455 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 3456 }; 3457 } 3458 3459 // i'm a node, so compute top, left, right, bottom 3460 else { 3461 element = $(ce); 3462 p = []; 3463 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 3464 3465 that.containerOffset = element.offset(); 3466 that.containerPosition = element.position(); 3467 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 3468 3469 co = that.containerOffset; 3470 ch = that.containerSize.height; 3471 cw = that.containerSize.width; 3472 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 3473 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3474 3475 that.parentData = { 3476 element: ce, left: co.left, top: co.top, width: width, height: height 3477 }; 3478 } 3479 }, 3480 3481 resize: function( event ) { 3482 var woset, hoset, isParent, isOffsetRelative, 3483 that = $(this).data("ui-resizable"), 3484 o = that.options, 3485 co = that.containerOffset, cp = that.position, 3486 pRatio = that._aspectRatio || event.shiftKey, 3487 cop = { top:0, left:0 }, ce = that.containerElement; 3488 3489 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3490 cop = co; 3491 } 3492 3493 if (cp.left < (that._helper ? co.left : 0)) { 3494 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3495 if (pRatio) { 3496 that.size.height = that.size.width / that.aspectRatio; 3497 } 3498 that.position.left = o.helper ? co.left : 0; 3499 } 3500 3501 if (cp.top < (that._helper ? co.top : 0)) { 3502 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3503 if (pRatio) { 3504 that.size.width = that.size.height * that.aspectRatio; 3505 } 3506 that.position.top = that._helper ? co.top : 0; 3507 } 3508 3509 that.offset.left = that.parentData.left+that.position.left; 3510 that.offset.top = that.parentData.top+that.position.top; 3511 3512 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3513 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3514 3515 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3516 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3517 3518 if(isParent && isOffsetRelative) { 3519 woset -= that.parentData.left; 3520 } 3521 3522 if (woset + that.size.width >= that.parentData.width) { 3523 that.size.width = that.parentData.width - woset; 3524 if (pRatio) { 3525 that.size.height = that.size.width / that.aspectRatio; 3526 } 3527 } 3528 3529 if (hoset + that.size.height >= that.parentData.height) { 3530 that.size.height = that.parentData.height - hoset; 3531 if (pRatio) { 3532 that.size.width = that.size.height * that.aspectRatio; 3533 } 3534 } 3535 }, 3536 3537 stop: function(){ 3538 var that = $(this).data("ui-resizable"), 3539 o = that.options, 3540 co = that.containerOffset, 3541 cop = that.containerPosition, 3542 ce = that.containerElement, 3543 helper = $(that.helper), 3544 ho = helper.offset(), 3545 w = helper.outerWidth() - that.sizeDiff.width, 3546 h = helper.outerHeight() - that.sizeDiff.height; 3547 3548 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3549 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3550 } 3551 3552 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3553 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3554 } 3555 3556 } 3557}); 3558 3559$.ui.plugin.add("resizable", "alsoResize", { 3560 3561 start: function () { 3562 var that = $(this).data("ui-resizable"), 3563 o = that.options, 3564 _store = function (exp) { 3565 $(exp).each(function() { 3566 var el = $(this); 3567 el.data("ui-resizable-alsoresize", { 3568 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3569 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3570 }); 3571 }); 3572 }; 3573 3574 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3575 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3576 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3577 }else{ 3578 _store(o.alsoResize); 3579 } 3580 }, 3581 3582 resize: function (event, ui) { 3583 var that = $(this).data("ui-resizable"), 3584 o = that.options, 3585 os = that.originalSize, 3586 op = that.originalPosition, 3587 delta = { 3588 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3589 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3590 }, 3591 3592 _alsoResize = function (exp, c) { 3593 $(exp).each(function() { 3594 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3595 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3596 3597 $.each(css, function (i, prop) { 3598 var sum = (start[prop]||0) + (delta[prop]||0); 3599 if (sum && sum >= 0) { 3600 style[prop] = sum || null; 3601 } 3602 }); 3603 3604 el.css(style); 3605 }); 3606 }; 3607 3608 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3609 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3610 }else{ 3611 _alsoResize(o.alsoResize); 3612 } 3613 }, 3614 3615 stop: function () { 3616 $(this).removeData("resizable-alsoresize"); 3617 } 3618}); 3619 3620$.ui.plugin.add("resizable", "ghost", { 3621 3622 start: function() { 3623 3624 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3625 3626 that.ghost = that.originalElement.clone(); 3627 that.ghost 3628 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3629 .addClass("ui-resizable-ghost") 3630 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3631 3632 that.ghost.appendTo(that.helper); 3633 3634 }, 3635 3636 resize: function(){ 3637 var that = $(this).data("ui-resizable"); 3638 if (that.ghost) { 3639 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3640 } 3641 }, 3642 3643 stop: function() { 3644 var that = $(this).data("ui-resizable"); 3645 if (that.ghost && that.helper) { 3646 that.helper.get(0).removeChild(that.ghost.get(0)); 3647 } 3648 } 3649 3650}); 3651 3652$.ui.plugin.add("resizable", "grid", { 3653 3654 resize: function() { 3655 var that = $(this).data("ui-resizable"), 3656 o = that.options, 3657 cs = that.size, 3658 os = that.originalSize, 3659 op = that.originalPosition, 3660 a = that.axis, 3661 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3662 gridX = (grid[0]||1), 3663 gridY = (grid[1]||1), 3664 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3665 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3666 newWidth = os.width + ox, 3667 newHeight = os.height + oy, 3668 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3669 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3670 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3671 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3672 3673 o.grid = grid; 3674 3675 if (isMinWidth) { 3676 newWidth = newWidth + gridX; 3677 } 3678 if (isMinHeight) { 3679 newHeight = newHeight + gridY; 3680 } 3681 if (isMaxWidth) { 3682 newWidth = newWidth - gridX; 3683 } 3684 if (isMaxHeight) { 3685 newHeight = newHeight - gridY; 3686 } 3687 3688 if (/^(se|s|e)$/.test(a)) { 3689 that.size.width = newWidth; 3690 that.size.height = newHeight; 3691 } else if (/^(ne)$/.test(a)) { 3692 that.size.width = newWidth; 3693 that.size.height = newHeight; 3694 that.position.top = op.top - oy; 3695 } else if (/^(sw)$/.test(a)) { 3696 that.size.width = newWidth; 3697 that.size.height = newHeight; 3698 that.position.left = op.left - ox; 3699 } else { 3700 that.size.width = newWidth; 3701 that.size.height = newHeight; 3702 that.position.top = op.top - oy; 3703 that.position.left = op.left - ox; 3704 } 3705 } 3706 3707}); 3708 3709})(jQuery); 3710(function( $, undefined ) { 3711 3712$.widget("ui.selectable", $.ui.mouse, { 3713 version: "1.10.1", 3714 options: { 3715 appendTo: "body", 3716 autoRefresh: true, 3717 distance: 0, 3718 filter: "*", 3719 tolerance: "touch", 3720 3721 // callbacks 3722 selected: null, 3723 selecting: null, 3724 start: null, 3725 stop: null, 3726 unselected: null, 3727 unselecting: null 3728 }, 3729 _create: function() { 3730 var selectees, 3731 that = this; 3732 3733 this.element.addClass("ui-selectable"); 3734 3735 this.dragged = false; 3736 3737 // cache selectee children based on filter 3738 this.refresh = function() { 3739 selectees = $(that.options.filter, that.element[0]); 3740 selectees.addClass("ui-selectee"); 3741 selectees.each(function() { 3742 var $this = $(this), 3743 pos = $this.offset(); 3744 $.data(this, "selectable-item", { 3745 element: this, 3746 $element: $this, 3747 left: pos.left, 3748 top: pos.top, 3749 right: pos.left + $this.outerWidth(), 3750 bottom: pos.top + $this.outerHeight(), 3751 startselected: false, 3752 selected: $this.hasClass("ui-selected"), 3753 selecting: $this.hasClass("ui-selecting"), 3754 unselecting: $this.hasClass("ui-unselecting") 3755 }); 3756 }); 3757 }; 3758 this.refresh(); 3759 3760 this.selectees = selectees.addClass("ui-selectee"); 3761 3762 this._mouseInit(); 3763 3764 this.helper = $("<div class='ui-selectable-helper'></div>"); 3765 }, 3766 3767 _destroy: function() { 3768 this.selectees 3769 .removeClass("ui-selectee") 3770 .removeData("selectable-item"); 3771 this.element 3772 .removeClass("ui-selectable ui-selectable-disabled"); 3773 this._mouseDestroy(); 3774 }, 3775 3776 _mouseStart: function(event) { 3777 var that = this, 3778 options = this.options; 3779 3780 this.opos = [event.pageX, event.pageY]; 3781 3782 if (this.options.disabled) { 3783 return; 3784 } 3785 3786 this.selectees = $(options.filter, this.element[0]); 3787 3788 this._trigger("start", event); 3789 3790 $(options.appendTo).append(this.helper); 3791 // position helper (lasso) 3792 this.helper.css({ 3793 "left": event.pageX, 3794 "top": event.pageY, 3795 "width": 0, 3796 "height": 0 3797 }); 3798 3799 if (options.autoRefresh) { 3800 this.refresh(); 3801 } 3802 3803 this.selectees.filter(".ui-selected").each(function() { 3804 var selectee = $.data(this, "selectable-item"); 3805 selectee.startselected = true; 3806 if (!event.metaKey && !event.ctrlKey) { 3807 selectee.$element.removeClass("ui-selected"); 3808 selectee.selected = false; 3809 selectee.$element.addClass("ui-unselecting"); 3810 selectee.unselecting = true; 3811 // selectable UNSELECTING callback 3812 that._trigger("unselecting", event, { 3813 unselecting: selectee.element 3814 }); 3815 } 3816 }); 3817 3818 $(event.target).parents().addBack().each(function() { 3819 var doSelect, 3820 selectee = $.data(this, "selectable-item"); 3821 if (selectee) { 3822 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3823 selectee.$element 3824 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3825 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3826 selectee.unselecting = !doSelect; 3827 selectee.selecting = doSelect; 3828 selectee.selected = doSelect; 3829 // selectable (UN)SELECTING callback 3830 if (doSelect) { 3831 that._trigger("selecting", event, { 3832 selecting: selectee.element 3833 }); 3834 } else { 3835 that._trigger("unselecting", event, { 3836 unselecting: selectee.element 3837 }); 3838 } 3839 return false; 3840 } 3841 }); 3842 3843 }, 3844 3845 _mouseDrag: function(event) { 3846 3847 this.dragged = true; 3848 3849 if (this.options.disabled) { 3850 return; 3851 } 3852 3853 var tmp, 3854 that = this, 3855 options = this.options, 3856 x1 = this.opos[0], 3857 y1 = this.opos[1], 3858 x2 = event.pageX, 3859 y2 = event.pageY; 3860 3861 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3862 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3863 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3864 3865 this.selectees.each(function() { 3866 var selectee = $.data(this, "selectable-item"), 3867 hit = false; 3868 3869 //prevent helper from being selected if appendTo: selectable 3870 if (!selectee || selectee.element === that.element[0]) { 3871 return; 3872 } 3873 3874 if (options.tolerance === "touch") { 3875 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3876 } else if (options.tolerance === "fit") { 3877 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3878 } 3879 3880 if (hit) { 3881 // SELECT 3882 if (selectee.selected) { 3883 selectee.$element.removeClass("ui-selected"); 3884 selectee.selected = false; 3885 } 3886 if (selectee.unselecting) { 3887 selectee.$element.removeClass("ui-unselecting"); 3888 selectee.unselecting = false; 3889 } 3890 if (!selectee.selecting) { 3891 selectee.$element.addClass("ui-selecting"); 3892 selectee.selecting = true; 3893 // selectable SELECTING callback 3894 that._trigger("selecting", event, { 3895 selecting: selectee.element 3896 }); 3897 } 3898 } else { 3899 // UNSELECT 3900 if (selectee.selecting) { 3901 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3902 selectee.$element.removeClass("ui-selecting"); 3903 selectee.selecting = false; 3904 selectee.$element.addClass("ui-selected"); 3905 selectee.selected = true; 3906 } else { 3907 selectee.$element.removeClass("ui-selecting"); 3908 selectee.selecting = false; 3909 if (selectee.startselected) { 3910 selectee.$element.addClass("ui-unselecting"); 3911 selectee.unselecting = true; 3912 } 3913 // selectable UNSELECTING callback 3914 that._trigger("unselecting", event, { 3915 unselecting: selectee.element 3916 }); 3917 } 3918 } 3919 if (selectee.selected) { 3920 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3921 selectee.$element.removeClass("ui-selected"); 3922 selectee.selected = false; 3923 3924 selectee.$element.addClass("ui-unselecting"); 3925 selectee.unselecting = true; 3926 // selectable UNSELECTING callback 3927 that._trigger("unselecting", event, { 3928 unselecting: selectee.element 3929 }); 3930 } 3931 } 3932 } 3933 }); 3934 3935 return false; 3936 }, 3937 3938 _mouseStop: function(event) { 3939 var that = this; 3940 3941 this.dragged = false; 3942 3943 $(".ui-unselecting", this.element[0]).each(function() { 3944 var selectee = $.data(this, "selectable-item"); 3945 selectee.$element.removeClass("ui-unselecting"); 3946 selectee.unselecting = false; 3947 selectee.startselected = false; 3948 that._trigger("unselected", event, { 3949 unselected: selectee.element 3950 }); 3951 }); 3952 $(".ui-selecting", this.element[0]).each(function() { 3953 var selectee = $.data(this, "selectable-item"); 3954 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3955 selectee.selecting = false; 3956 selectee.selected = true; 3957 selectee.startselected = true; 3958 that._trigger("selected", event, { 3959 selected: selectee.element 3960 }); 3961 }); 3962 this._trigger("stop", event); 3963 3964 this.helper.remove(); 3965 3966 return false; 3967 } 3968 3969}); 3970 3971})(jQuery); 3972(function( $, undefined ) { 3973 3974/*jshint loopfunc: true */ 3975 3976function isOverAxis( x, reference, size ) { 3977 return ( x > reference ) && ( x < ( reference + size ) ); 3978} 3979 3980$.widget("ui.sortable", $.ui.mouse, { 3981 version: "1.10.1", 3982 widgetEventPrefix: "sort", 3983 ready: false, 3984 options: { 3985 appendTo: "parent", 3986 axis: false, 3987 connectWith: false, 3988 containment: false, 3989 cursor: "auto", 3990 cursorAt: false, 3991 dropOnEmpty: true, 3992 forcePlaceholderSize: false, 3993 forceHelperSize: false, 3994 grid: false, 3995 handle: false, 3996 helper: "original", 3997 items: "> *", 3998 opacity: false, 3999 placeholder: false, 4000 revert: false, 4001 scroll: true, 4002 scrollSensitivity: 20, 4003 scrollSpeed: 20, 4004 scope: "default", 4005 tolerance: "intersect", 4006 zIndex: 1000, 4007 4008 // callbacks 4009 activate: null, 4010 beforeStop: null, 4011 change: null, 4012 deactivate: null, 4013 out: null, 4014 over: null, 4015 receive: null, 4016 remove: null, 4017 sort: null, 4018 start: null, 4019 stop: null, 4020 update: null 4021 }, 4022 _create: function() { 4023 4024 var o = this.options; 4025 this.containerCache = {}; 4026 this.element.addClass("ui-sortable"); 4027 4028 //Get the items 4029 this.refresh(); 4030 4031 //Let's determine if the items are being displayed horizontally 4032 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; 4033 4034 //Let's determine the parent's offset 4035 this.offset = this.element.offset(); 4036 4037 //Initialize mouse events for interaction 4038 this._mouseInit(); 4039 4040 //We're ready to go 4041 this.ready = true; 4042 4043 }, 4044 4045 _destroy: function() { 4046 this.element 4047 .removeClass("ui-sortable ui-sortable-disabled"); 4048 this._mouseDestroy(); 4049 4050 for ( var i = this.items.length - 1; i >= 0; i-- ) { 4051 this.items[i].item.removeData(this.widgetName + "-item"); 4052 } 4053 4054 return this; 4055 }, 4056 4057 _setOption: function(key, value){ 4058 if ( key === "disabled" ) { 4059 this.options[ key ] = value; 4060 4061 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 4062 } else { 4063 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 4064 $.Widget.prototype._setOption.apply(this, arguments); 4065 } 4066 }, 4067 4068 _mouseCapture: function(event, overrideHandle) { 4069 var currentItem = null, 4070 validHandle = false, 4071 that = this; 4072 4073 if (this.reverting) { 4074 return false; 4075 } 4076 4077 if(this.options.disabled || this.options.type === "static") { 4078 return false; 4079 } 4080 4081 //We have to refresh the items data once first 4082 this._refreshItems(event); 4083 4084 //Find out if the clicked node (or one of its parents) is a actual item in this.items 4085 $(event.target).parents().each(function() { 4086 if($.data(this, that.widgetName + "-item") === that) { 4087 currentItem = $(this); 4088 return false; 4089 } 4090 }); 4091 if($.data(event.target, that.widgetName + "-item") === that) { 4092 currentItem = $(event.target); 4093 } 4094 4095 if(!currentItem) { 4096 return false; 4097 } 4098 if(this.options.handle && !overrideHandle) { 4099 $(this.options.handle, currentItem).find("*").addBack().each(function() { 4100 if(this === event.target) { 4101 validHandle = true; 4102 } 4103 }); 4104 if(!validHandle) { 4105 return false; 4106 } 4107 } 4108 4109 this.currentItem = currentItem; 4110 this._removeCurrentsFromItems(); 4111 return true; 4112 4113 }, 4114 4115 _mouseStart: function(event, overrideHandle, noActivation) { 4116 4117 var i, 4118 o = this.options; 4119 4120 this.currentContainer = this; 4121 4122 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 4123 this.refreshPositions(); 4124 4125 //Create and append the visible helper 4126 this.helper = this._createHelper(event); 4127 4128 //Cache the helper size 4129 this._cacheHelperProportions(); 4130 4131 /* 4132 * - Position generation - 4133 * This block generates everything position related - it's the core of draggables. 4134 */ 4135 4136 //Cache the margins of the original element 4137 this._cacheMargins(); 4138 4139 //Get the next scrolling parent 4140 this.scrollParent = this.helper.scrollParent(); 4141 4142 //The element's absolute position on the page minus margins 4143 this.offset = this.currentItem.offset(); 4144 this.offset = { 4145 top: this.offset.top - this.margins.top, 4146 left: this.offset.left - this.margins.left 4147 }; 4148 4149 $.extend(this.offset, { 4150 click: { //Where the click happened, relative to the element 4151 left: event.pageX - this.offset.left, 4152 top: event.pageY - this.offset.top 4153 }, 4154 parent: this._getParentOffset(), 4155 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 4156 }); 4157 4158 // Only after we got the offset, we can change the helper's position to absolute 4159 // TODO: Still need to figure out a way to make relative sorting possible 4160 this.helper.css("position", "absolute"); 4161 this.cssPosition = this.helper.css("position"); 4162 4163 //Generate the original position 4164 this.originalPosition = this._generatePosition(event); 4165 this.originalPageX = event.pageX; 4166 this.originalPageY = event.pageY; 4167 4168 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 4169 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 4170 4171 //Cache the former DOM position 4172 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 4173 4174 //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 4175 if(this.helper[0] !== this.currentItem[0]) { 4176 this.currentItem.hide(); 4177 } 4178 4179 //Create the placeholder 4180 this._createPlaceholder(); 4181 4182 //Set a containment if given in the options 4183 if(o.containment) { 4184 this._setContainment(); 4185 } 4186 4187 if(o.cursor) { // cursor option 4188 if ($("body").css("cursor")) { 4189 this._storedCursor = $("body").css("cursor"); 4190 } 4191 $("body").css("cursor", o.cursor); 4192 } 4193 4194 if(o.opacity) { // opacity option 4195 if (this.helper.css("opacity")) { 4196 this._storedOpacity = this.helper.css("opacity"); 4197 } 4198 this.helper.css("opacity", o.opacity); 4199 } 4200 4201 if(o.zIndex) { // zIndex option 4202 if (this.helper.css("zIndex")) { 4203 this._storedZIndex = this.helper.css("zIndex"); 4204 } 4205 this.helper.css("zIndex", o.zIndex); 4206 } 4207 4208 //Prepare scrolling 4209 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4210 this.overflowOffset = this.scrollParent.offset(); 4211 } 4212 4213 //Call callbacks 4214 this._trigger("start", event, this._uiHash()); 4215 4216 //Recache the helper size 4217 if(!this._preserveHelperProportions) { 4218 this._cacheHelperProportions(); 4219 } 4220 4221 4222 //Post "activate" events to possible containers 4223 if( !noActivation ) { 4224 for ( i = this.containers.length - 1; i >= 0; i-- ) { 4225 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 4226 } 4227 } 4228 4229 //Prepare possible droppables 4230 if($.ui.ddmanager) { 4231 $.ui.ddmanager.current = this; 4232 } 4233 4234 if ($.ui.ddmanager && !o.dropBehaviour) { 4235 $.ui.ddmanager.prepareOffsets(this, event); 4236 } 4237 4238 this.dragging = true; 4239 4240 this.helper.addClass("ui-sortable-helper"); 4241 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 4242 return true; 4243 4244 }, 4245 4246 _mouseDrag: function(event) { 4247 var i, item, itemElement, intersection, 4248 o = this.options, 4249 scrolled = false; 4250 4251 //Compute the helpers position 4252 this.position = this._generatePosition(event); 4253 this.positionAbs = this._convertPositionTo("absolute"); 4254 4255 if (!this.lastPositionAbs) { 4256 this.lastPositionAbs = this.positionAbs; 4257 } 4258 4259 //Do scrolling 4260 if(this.options.scroll) { 4261 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4262 4263 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 4264 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 4265 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 4266 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 4267 } 4268 4269 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 4270 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 4271 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 4272 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 4273 } 4274 4275 } else { 4276 4277 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 4278 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4279 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 4280 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4281 } 4282 4283 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 4284 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4285 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 4286 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4287 } 4288 4289 } 4290 4291 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 4292 $.ui.ddmanager.prepareOffsets(this, event); 4293 } 4294 } 4295 4296 //Regenerate the absolute position used for position checks 4297 this.positionAbs = this._convertPositionTo("absolute"); 4298 4299 //Set the helper position 4300 if(!this.options.axis || this.options.axis !== "y") { 4301 this.helper[0].style.left = this.position.left+"px"; 4302 } 4303 if(!this.options.axis || this.options.axis !== "x") { 4304 this.helper[0].style.top = this.position.top+"px"; 4305 } 4306 4307 //Rearrange 4308 for (i = this.items.length - 1; i >= 0; i--) { 4309 4310 //Cache variables and intersection, continue if no intersection 4311 item = this.items[i]; 4312 itemElement = item.item[0]; 4313 intersection = this._intersectsWithPointer(item); 4314 if (!intersection) { 4315 continue; 4316 } 4317 4318 // Only put the placeholder inside the current Container, skip all 4319 // items form other containers. This works because when moving 4320 // an item from one container to another the 4321 // currentContainer is switched before the placeholder is moved. 4322 // 4323 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 4324 // beetween the outer and inner container. 4325 if (item.instance !== this.currentContainer) { 4326 continue; 4327 } 4328 4329 // cannot intersect with itself 4330 // no useless actions that have been done before 4331 // no action if the item moved is the parent of the item checked 4332 if (itemElement !== this.currentItem[0] && 4333 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 4334 !$.contains(this.placeholder[0], itemElement) && 4335 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 4336 ) { 4337 4338 this.direction = intersection === 1 ? "down" : "up"; 4339 4340 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 4341 this._rearrange(event, item); 4342 } else { 4343 break; 4344 } 4345 4346 this._trigger("change", event, this._uiHash()); 4347 break; 4348 } 4349 } 4350 4351 //Post events to containers 4352 this._contactContainers(event); 4353 4354 //Interconnect with droppables 4355 if($.ui.ddmanager) { 4356 $.ui.ddmanager.drag(this, event); 4357 } 4358 4359 //Call callbacks 4360 this._trigger("sort", event, this._uiHash()); 4361 4362 this.lastPositionAbs = this.positionAbs; 4363 return false; 4364 4365 }, 4366 4367 _mouseStop: function(event, noPropagation) { 4368 4369 if(!event) { 4370 return; 4371 } 4372 4373 //If we are using droppables, inform the manager about the drop 4374 if ($.ui.ddmanager && !this.options.dropBehaviour) { 4375 $.ui.ddmanager.drop(this, event); 4376 } 4377 4378 if(this.options.revert) { 4379 var that = this, 4380 cur = this.placeholder.offset(); 4381 4382 this.reverting = true; 4383 4384 $(this.helper).animate({ 4385 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft), 4386 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop) 4387 }, parseInt(this.options.revert, 10) || 500, function() { 4388 that._clear(event); 4389 }); 4390 } else { 4391 this._clear(event, noPropagation); 4392 } 4393 4394 return false; 4395 4396 }, 4397 4398 cancel: function() { 4399 4400 if(this.dragging) { 4401 4402 this._mouseUp({ target: null }); 4403 4404 if(this.options.helper === "original") { 4405 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4406 } else { 4407 this.currentItem.show(); 4408 } 4409 4410 //Post deactivating events to containers 4411 for (var i = this.containers.length - 1; i >= 0; i--){ 4412 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4413 if(this.containers[i].containerCache.over) { 4414 this.containers[i]._trigger("out", null, this._uiHash(this)); 4415 this.containers[i].containerCache.over = 0; 4416 } 4417 } 4418 4419 } 4420 4421 if (this.placeholder) { 4422 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4423 if(this.placeholder[0].parentNode) { 4424 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4425 } 4426 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 4427 this.helper.remove(); 4428 } 4429 4430 $.extend(this, { 4431 helper: null, 4432 dragging: false, 4433 reverting: false, 4434 _noFinalSort: null 4435 }); 4436 4437 if(this.domPosition.prev) { 4438 $(this.domPosition.prev).after(this.currentItem); 4439 } else { 4440 $(this.domPosition.parent).prepend(this.currentItem); 4441 } 4442 } 4443 4444 return this; 4445 4446 }, 4447 4448 serialize: function(o) { 4449 4450 var items = this._getItemsAsjQuery(o && o.connected), 4451 str = []; 4452 o = o || {}; 4453 4454 $(items).each(function() { 4455 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 4456 if (res) { 4457 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4458 } 4459 }); 4460 4461 if(!str.length && o.key) { 4462 str.push(o.key + "="); 4463 } 4464 4465 return str.join("&"); 4466 4467 }, 4468 4469 toArray: function(o) { 4470 4471 var items = this._getItemsAsjQuery(o && o.connected), 4472 ret = []; 4473 4474 o = o || {}; 4475 4476 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4477 return ret; 4478 4479 }, 4480 4481 /* Be careful with the following core functions */ 4482 _intersectsWith: function(item) { 4483 4484 var x1 = this.positionAbs.left, 4485 x2 = x1 + this.helperProportions.width, 4486 y1 = this.positionAbs.top, 4487 y2 = y1 + this.helperProportions.height, 4488 l = item.left, 4489 r = l + item.width, 4490 t = item.top, 4491 b = t + item.height, 4492 dyClick = this.offset.click.top, 4493 dxClick = this.offset.click.left, 4494 isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4495 4496 if ( this.options.tolerance === "pointer" || 4497 this.options.forcePointerForContainers || 4498 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4499 ) { 4500 return isOverElement; 4501 } else { 4502 4503 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4504 x2 - (this.helperProportions.width / 2) < r && // Left Half 4505 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4506 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4507 4508 } 4509 }, 4510 4511 _intersectsWithPointer: function(item) { 4512 4513 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4514 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4515 isOverElement = isOverElementHeight && isOverElementWidth, 4516 verticalDirection = this._getDragVerticalDirection(), 4517 horizontalDirection = this._getDragHorizontalDirection(); 4518 4519 if (!isOverElement) { 4520 return false; 4521 } 4522 4523 return this.floating ? 4524 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4525 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4526 4527 }, 4528 4529 _intersectsWithSides: function(item) { 4530 4531 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4532 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4533 verticalDirection = this._getDragVerticalDirection(), 4534 horizontalDirection = this._getDragHorizontalDirection(); 4535 4536 if (this.floating && horizontalDirection) { 4537 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4538 } else { 4539 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4540 } 4541 4542 }, 4543 4544 _getDragVerticalDirection: function() { 4545 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4546 return delta !== 0 && (delta > 0 ? "down" : "up"); 4547 }, 4548 4549 _getDragHorizontalDirection: function() { 4550 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4551 return delta !== 0 && (delta > 0 ? "right" : "left"); 4552 }, 4553 4554 refresh: function(event) { 4555 this._refreshItems(event); 4556 this.refreshPositions(); 4557 return this; 4558 }, 4559 4560 _connectWith: function() { 4561 var options = this.options; 4562 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4563 }, 4564 4565 _getItemsAsjQuery: function(connected) { 4566 4567 var i, j, cur, inst, 4568 items = [], 4569 queries = [], 4570 connectWith = this._connectWith(); 4571 4572 if(connectWith && connected) { 4573 for (i = connectWith.length - 1; i >= 0; i--){ 4574 cur = $(connectWith[i]); 4575 for ( j = cur.length - 1; j >= 0; j--){ 4576 inst = $.data(cur[j], this.widgetFullName); 4577 if(inst && inst !== this && !inst.options.disabled) { 4578 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]); 4579 } 4580 } 4581 } 4582 } 4583 4584 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]); 4585 4586 for (i = queries.length - 1; i >= 0; i--){ 4587 queries[i][0].each(function() { 4588 items.push(this); 4589 }); 4590 } 4591 4592 return $(items); 4593 4594 }, 4595 4596 _removeCurrentsFromItems: function() { 4597 4598 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4599 4600 this.items = $.grep(this.items, function (item) { 4601 for (var j=0; j < list.length; j++) { 4602 if(list[j] === item.item[0]) { 4603 return false; 4604 } 4605 } 4606 return true; 4607 }); 4608 4609 }, 4610 4611 _refreshItems: function(event) { 4612 4613 this.items = []; 4614 this.containers = [this]; 4615 4616 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4617 items = this.items, 4618 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4619 connectWith = this._connectWith(); 4620 4621 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4622 for (i = connectWith.length - 1; i >= 0; i--){ 4623 cur = $(connectWith[i]); 4624 for (j = cur.length - 1; j >= 0; j--){ 4625 inst = $.data(cur[j], this.widgetFullName); 4626 if(inst && inst !== this && !inst.options.disabled) { 4627 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4628 this.containers.push(inst); 4629 } 4630 } 4631 } 4632 } 4633 4634 for (i = queries.length - 1; i >= 0; i--) { 4635 targetData = queries[i][1]; 4636 _queries = queries[i][0]; 4637 4638 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4639 item = $(_queries[j]); 4640 4641 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4642 4643 items.push({ 4644 item: item, 4645 instance: targetData, 4646 width: 0, height: 0, 4647 left: 0, top: 0 4648 }); 4649 } 4650 } 4651 4652 }, 4653 4654 refreshPositions: function(fast) { 4655 4656 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4657 if(this.offsetParent && this.helper) { 4658 this.offset.parent = this._getParentOffset(); 4659 } 4660 4661 var i, item, t, p; 4662 4663 for (i = this.items.length - 1; i >= 0; i--){ 4664 item = this.items[i]; 4665 4666 //We ignore calculating positions of all connected containers when we're not over them 4667 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4668 continue; 4669 } 4670 4671 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4672 4673 if (!fast) { 4674 item.width = t.outerWidth(); 4675 item.height = t.outerHeight(); 4676 } 4677 4678 p = t.offset(); 4679 item.left = p.left; 4680 item.top = p.top; 4681 } 4682 4683 if(this.options.custom && this.options.custom.refreshContainers) { 4684 this.options.custom.refreshContainers.call(this); 4685 } else { 4686 for (i = this.containers.length - 1; i >= 0; i--){ 4687 p = this.containers[i].element.offset(); 4688 this.containers[i].containerCache.left = p.left; 4689 this.containers[i].containerCache.top = p.top; 4690 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4691 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4692 } 4693 } 4694 4695 return this; 4696 }, 4697 4698 _createPlaceholder: function(that) { 4699 that = that || this; 4700 var className, 4701 o = that.options; 4702 4703 if(!o.placeholder || o.placeholder.constructor === String) { 4704 className = o.placeholder; 4705 o.placeholder = { 4706 element: function() { 4707 4708 var el = $(document.createElement(that.currentItem[0].nodeName)) 4709 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4710 .removeClass("ui-sortable-helper")[0]; 4711 4712 if(!className) { 4713 el.style.visibility = "hidden"; 4714 } 4715 4716 return el; 4717 }, 4718 update: function(container, p) { 4719 4720 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4721 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4722 if(className && !o.forcePlaceholderSize) { 4723 return; 4724 } 4725 4726 //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
vendor: 3,629 bytes, lines 4727-4822
4727 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4728 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4729 } 4730 }; 4731 } 4732 4733 //Create the placeholder 4734 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4735 4736 //Append it after the actual current item 4737 that.currentItem.after(that.placeholder); 4738 4739 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4740 o.placeholder.update(that, that.placeholder); 4741 4742 }, 4743 4744 _contactContainers: function(event) { 4745 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, 4746 innermostContainer = null, 4747 innermostIndex = null; 4748 4749 // get innermost container that intersects with item 4750 for (i = this.containers.length - 1; i >= 0; i--) { 4751 4752 // never consider a container that's located within the item itself 4753 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4754 continue; 4755 } 4756 4757 if(this._intersectsWith(this.containers[i].containerCache)) { 4758 4759 // if we've already found a container and it's more "inner" than this, then continue 4760 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4761 continue; 4762 } 4763 4764 innermostContainer = this.containers[i]; 4765 innermostIndex = i; 4766 4767 } else { 4768 // container doesn't intersect. trigger "out" event if necessary 4769 if(this.containers[i].containerCache.over) { 4770 this.containers[i]._trigger("out", event, this._uiHash(this)); 4771 this.containers[i].containerCache.over = 0; 4772 } 4773 } 4774 4775 } 4776 4777 // if no intersecting containers found, return 4778 if(!innermostContainer) { 4779 return; 4780 } 4781 4782 // move the item into the container if it's not there already 4783 if(this.containers.length === 1) { 4784 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4785 this.containers[innermostIndex].containerCache.over = 1; 4786 } else { 4787 4788 //When entering a new container, we will find the item with the least distance and append our item near it 4789 dist = 10000; 4790 itemWithLeastDistance = null; 4791 posProperty = this.containers[innermostIndex].floating ? "left" : "top"; 4792 sizeProperty = this.containers[innermostIndex].floating ? "width" : "height"; 4793 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4794 for (j = this.items.length - 1; j >= 0; j--) { 4795 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4796 continue; 4797 } 4798 if(this.items[j].item[0] === this.currentItem[0]) { 4799 continue; 4800 } 4801 cur = this.items[j].item.offset()[posProperty]; 4802 nearBottom = false; 4803 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4804 nearBottom = true; 4805 cur += this.items[j][sizeProperty]; 4806 } 4807 4808 if(Math.abs(cur - base) < dist) { 4809 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 4810 this.direction = nearBottom ? "up": "down"; 4811 } 4812 } 4813 4814 //Check if dropOnEmpty is enabled 4815 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4816 return; 4817 } 4818 4819 this.currentContainer = this.containers[innermostIndex]; 4820 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4821 this._trigger("change", event, this._uiHash()); 4822 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this))
vendor: 12,924 bytes, lines 4822-5126
4822; 4823 4824 //Update the placeholder 4825 this.options.placeholder.update(this.currentContainer, this.placeholder); 4826 4827 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4828 this.containers[innermostIndex].containerCache.over = 1; 4829 } 4830 4831 4832 }, 4833 4834 _createHelper: function(event) { 4835 4836 var o = this.options, 4837 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4838 4839 //Add the helper to the DOM if that didn't happen already 4840 if(!helper.parents("body").length) { 4841 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4842 } 4843 4844 if(helper[0] === this.currentItem[0]) { 4845 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: this.currentItem.css("left") }; 4846 } 4847 4848 if(!helper[0].style.width || o.forceHelperSize) { 4849 helper.width(this.currentItem.width()); 4850 } 4851 if(!helper[0].style.height || o.forceHelperSize) { 4852 helper.height(this.currentItem.height()); 4853 } 4854 4855 return helper; 4856 4857 }, 4858 4859 _adjustOffsetFromHelper: function(obj) { 4860 if (typeof obj === "string") { 4861 obj = obj.split(" "); 4862 } 4863 if ($.isArray(obj)) { 4864 obj = {left: +obj[0], top: +obj[1] || 0}; 4865 } 4866 if ("left" in obj) { 4867 this.offset.click.left = obj.left + this.margins.left; 4868 } 4869 if ("right" in obj) { 4870 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4871 } 4872 if ("top" in obj) { 4873 this.offset.click.top = obj.top + this.margins.top; 4874 } 4875 if ("bottom" in obj) { 4876 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4877 } 4878 }, 4879 4880 _getParentOffset: function() { 4881 4882 4883 //Get the offsetParent and cache its position 4884 this.offsetParent = this.helper.offsetParent(); 4885 var po = this.offsetParent.offset(); 4886 4887 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4888 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4889 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4890 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4891 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4892 po.left += this.scrollParent.scrollLeft(); 4893 po.top += this.scrollParent.scrollTop(); 4894 } 4895 4896 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4897 // with an ugly IE fix 4898 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4899 po = { top: 0, left: 0 }; 4900 } 4901 4902 return { 4903 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4904 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4905 }; 4906 4907 }, 4908 4909 _getRelativeOffset: function() { 4910 4911 if(this.cssPosition === "relative") { 4912 var p = this.currentItem.position(); 4913 return { 4914 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4915 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4916 }; 4917 } else { 4918 return { top: 0, left: 0 }; 4919 } 4920 4921 }, 4922 4923 _cacheMargins: function() { 4924 this.margins = { 4925 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4926 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4927 }; 4928 }, 4929 4930 _cacheHelperProportions: function() { 4931 this.helperProportions = { 4932 width: this.helper.outerWidth(), 4933 height: this.helper.outerHeight() 4934 }; 4935 }, 4936 4937 _setContainment: function() { 4938 4939 var ce, co, over, 4940 o = this.options; 4941 if(o.containment === "parent") { 4942 o.containment = this.helper[0].parentNode; 4943 } 4944 if(o.containment === "document" || o.containment === "window") { 4945 this.containment = [ 4946 0 - this.offset.relative.left - this.offset.parent.left, 4947 0 - this.offset.relative.top - this.offset.parent.top, 4948 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4949 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4950 ]; 4951 } 4952 4953 if(!(/^(document|window|parent)$/).test(o.containment)) { 4954 ce = $(o.containment)[0]; 4955 co = $(o.containment).offset(); 4956 over = ($(ce).css("overflow") !== "hidden"); 4957 4958 this.containment = [ 4959 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4960 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4961 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, 4962 co.top+(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 4963 ]; 4964 } 4965 4966 }, 4967 4968 _convertPositionTo: function(d, pos) { 4969 4970 if(!pos) { 4971 pos = this.position; 4972 } 4973 var mod = d === "absolute" ? 1 : -1, 4974 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4975 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4976 4977 return { 4978 top: ( 4979 pos.top + // The absolute mouse position 4980 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4981 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4982 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4983 ), 4984 left: ( 4985 pos.left + // The absolute mouse position 4986 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4987 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4988 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4989 ) 4990 }; 4991 4992 }, 4993 4994 _generatePosition: function(event) { 4995 4996 var top, left, 4997 o = this.options, 4998 pageX = event.pageX, 4999 pageY = event.pageY, 5000 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); 5001 5002 // This is another very weird special case that only happens for relative elements: 5003 // 1. If the css position is relative 5004 // 2. and the scroll parent is the document or similar to the offset parent 5005 // we have to refresh the relative offset during the scroll so there are no jumps 5006 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 5007 this.offset.relative = this._getRelativeOffset(); 5008 } 5009 5010 /* 5011 * - Position constraining - 5012 * Constrain the position to a mix of grid, containment. 5013 */ 5014 5015 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 5016 5017 if(this.containment) { 5018 if(event.pageX - this.offset.click.left < this.containment[0]) { 5019 pageX = this.containment[0] + this.offset.click.left; 5020 } 5021 if(event.pageY - this.offset.click.top < this.containment[1]) { 5022 pageY = this.containment[1] + this.offset.click.top; 5023 } 5024 if(event.pageX - this.offset.click.left > this.containment[2]) { 5025 pageX = this.containment[2] + this.offset.click.left; 5026 } 5027 if(event.pageY - this.offset.click.top > this.containment[3]) { 5028 pageY = this.containment[3] + this.offset.click.top; 5029 } 5030 } 5031 5032 if(o.grid) { 5033 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 5034 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; 5035 5036 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 5037 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; 5038 } 5039 5040 } 5041 5042 return { 5043 top: ( 5044 pageY - // The absolute mouse position 5045 this.offset.click.top - // Click offset (relative to the element) 5046 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 5047 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 5048 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 5049 ), 5050 left: ( 5051 pageX - // The absolute mouse position 5052 this.offset.click.left - // Click offset (relative to the element) 5053 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 5054 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 5055 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 5056 ) 5057 }; 5058 5059 }, 5060 5061 _rearrange: function(event, i, a, hardRefresh) { 5062 5063 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)); 5064 5065 //Various things done here to improve the performance: 5066 // 1. we create a setTimeout, that calls refreshPositions 5067 // 2. on the instance, we have a counter variable, that get's higher after every append 5068 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 5069 // 4. this lets only the last addition to the timeout stack through 5070 this.counter = this.counter ? ++this.counter : 1; 5071 var counter = this.counter; 5072 5073 this._delay(function() { 5074 if(counter === this.counter) { 5075 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 5076 } 5077 }); 5078 5079 }, 5080 5081 _clear: function(event, noPropagation) { 5082 5083 this.reverting = false; 5084 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 5085 // everything else normalized again 5086 var i, 5087 delayedTriggers = []; 5088 5089 // We first have to update the dom position of the actual currentItem 5090 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 5091 if(!this._noFinalSort && this.currentItem.parent().length) { 5092 this.placeholder.before(this.currentItem); 5093 } 5094 this._noFinalSort = null; 5095 5096 if(this.helper[0] === this.currentItem[0]) { 5097 for(i in this._storedCSS) { 5098 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 5099 this._storedCSS[i] = ""; 5100 } 5101 } 5102 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 5103 } else { 5104 this.currentItem.show(); 5105 } 5106 5107 if(this.fromOutside && !noPropagation) { 5108 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 5109 } 5110 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 5111 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 5112 } 5113 5114 // Check if the items Container has Changed and trigger appropriate 5115 // events. 5116 if (this !== this.currentContainer) { 5117 if(!noPropagation) { 5118 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 5119 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5120 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5121 } 5122 } 5123 5124 5125 //Post events to containers 5126 f
vendor: 40,091 bytes, lines 5126-6610
5126or (i = this.containers.length - 1; i >= 0; i--){ 5127 if(!noPropagation) { 5128 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 5129 } 5130 if(this.containers[i].containerCache.over) { 5131 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 5132 this.containers[i].containerCache.over = 0; 5133 } 5134 } 5135 5136 //Do what was originally in plugins 5137 if(this._storedCursor) { 5138 $("body").css("cursor", this._storedCursor); 5139 } 5140 if(this._storedOpacity) { 5141 this.helper.css("opacity", this._storedOpacity); 5142 } 5143 if(this._storedZIndex) { 5144 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 5145 } 5146 5147 this.dragging = false; 5148 if(this.cancelHelperRemoval) { 5149 if(!noPropagation) { 5150 this._trigger("beforeStop", event, this._uiHash()); 5151 for (i=0; i < delayedTriggers.length; i++) { 5152 delayedTriggers[i].call(this, event); 5153 } //Trigger all delayed events 5154 this._trigger("stop", event, this._uiHash()); 5155 } 5156 5157 this.fromOutside = false; 5158 return false; 5159 } 5160 5161 if(!noPropagation) { 5162 this._trigger("beforeStop", event, this._uiHash()); 5163 } 5164 5165 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 5166 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 5167 5168 if(this.helper[0] !== this.currentItem[0]) { 5169 this.helper.remove(); 5170 } 5171 this.helper = null; 5172 5173 if(!noPropagation) { 5174 for (i=0; i < delayedTriggers.length; i++) { 5175 delayedTriggers[i].call(this, event); 5176 } //Trigger all delayed events 5177 this._trigger("stop", event, this._uiHash()); 5178 } 5179 5180 this.fromOutside = false; 5181 return true; 5182 5183 }, 5184 5185 _trigger: function() { 5186 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 5187 this.cancel(); 5188 } 5189 }, 5190 5191 _uiHash: function(_inst) { 5192 var inst = _inst || this; 5193 return { 5194 helper: inst.helper, 5195 placeholder: inst.placeholder || $([]), 5196 position: inst.position, 5197 originalPosition: inst.originalPosition, 5198 offset: inst.positionAbs, 5199 item: inst.currentItem, 5200 sender: _inst ? _inst.element : null 5201 }; 5202 } 5203 5204}); 5205 5206})(jQuery); 5207(function( $, undefined ) { 5208 5209var uid = 0, 5210 hideProps = {}, 5211 showProps = {}; 5212 5213hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5214 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5215showProps.height = showProps.paddingTop = showProps.paddingBottom = 5216 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5217 5218$.widget( "ui.accordion", { 5219 version: "1.10.1", 5220 options: { 5221 active: 0, 5222 animate: {}, 5223 collapsible: false, 5224 event: "click", 5225 header: "> li > :first-child,> :not(li):even", 5226 heightStyle: "auto", 5227 icons: { 5228 activeHeader: "ui-icon-triangle-1-s", 5229 header: "ui-icon-triangle-1-e" 5230 }, 5231 5232 // callbacks 5233 activate: null, 5234 beforeActivate: null 5235 }, 5236 5237 _create: function() { 5238 var options = this.options; 5239 this.prevShow = this.prevHide = $(); 5240 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 5241 // ARIA 5242 .attr( "role", "tablist" ); 5243 5244 // don't allow collapsible: false and active: false / null 5245 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5246 options.active = 0; 5247 } 5248 5249 this._processPanels(); 5250 // handle negative values 5251 if ( options.active < 0 ) { 5252 options.active += this.headers.length; 5253 } 5254 this._refresh(); 5255 }, 5256 5257 _getCreateEventData: function() { 5258 return { 5259 header: this.active, 5260 panel: !this.active.length ? $() : this.active.next(), 5261 content: !this.active.length ? $() : this.active.next() 5262 }; 5263 }, 5264 5265 _createIcons: function() { 5266 var icons = this.options.icons; 5267 if ( icons ) { 5268 $( "<span>" ) 5269 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5270 .prependTo( this.headers ); 5271 this.active.children( ".ui-accordion-header-icon" ) 5272 .removeClass( icons.header ) 5273 .addClass( icons.activeHeader ); 5274 this.headers.addClass( "ui-accordion-icons" ); 5275 } 5276 }, 5277 5278 _destroyIcons: function() { 5279 this.headers 5280 .removeClass( "ui-accordion-icons" ) 5281 .children( ".ui-accordion-header-icon" ) 5282 .remove(); 5283 }, 5284 5285 _destroy: function() { 5286 var contents; 5287 5288 // clean up main element 5289 this.element 5290 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5291 .removeAttr( "role" ); 5292 5293 // clean up headers 5294 this.headers 5295 .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" ) 5296 .removeAttr( "role" ) 5297 .removeAttr( "aria-selected" ) 5298 .removeAttr( "aria-controls" ) 5299 .removeAttr( "tabIndex" ) 5300 .each(function() { 5301 if ( /^ui-accordion/.test( this.id ) ) { 5302 this.removeAttribute( "id" ); 5303 } 5304 }); 5305 this._destroyIcons(); 5306 5307 // clean up content panels 5308 contents = this.headers.next() 5309 .css( "display", "" ) 5310 .removeAttr( "role" ) 5311 .removeAttr( "aria-expanded" ) 5312 .removeAttr( "aria-hidden" ) 5313 .removeAttr( "aria-labelledby" ) 5314 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5315 .each(function() { 5316 if ( /^ui-accordion/.test( this.id ) ) { 5317 this.removeAttribute( "id" ); 5318 } 5319 }); 5320 if ( this.options.heightStyle !== "content" ) { 5321 contents.css( "height", "" ); 5322 } 5323 }, 5324 5325 _setOption: function( key, value ) { 5326 if ( key === "active" ) { 5327 // _activate() will handle invalid values and update this.options 5328 this._activate( value ); 5329 return; 5330 } 5331 5332 if ( key === "event" ) { 5333 if ( this.options.event ) { 5334 this._off( this.headers, this.options.event ); 5335 } 5336 this._setupEvents( value ); 5337 } 5338 5339 this._super( key, value ); 5340 5341 // setting collapsible: false while collapsed; open first panel 5342 if ( key === "collapsible" && !value && this.options.active === false ) { 5343 this._activate( 0 ); 5344 } 5345 5346 if ( key === "icons" ) { 5347 this._destroyIcons(); 5348 if ( value ) { 5349 this._createIcons(); 5350 } 5351 } 5352 5353 // #5332 - opacity doesn't cascade to positioned elements in IE 5354 // so we need to add the disabled class to the headers and panels 5355 if ( key === "disabled" ) { 5356 this.headers.add( this.headers.next() ) 5357 .toggleClass( "ui-state-disabled", !!value ); 5358 } 5359 }, 5360 5361 _keydown: function( event ) { 5362 /*jshint maxcomplexity:15*/ 5363 if ( event.altKey || event.ctrlKey ) { 5364 return; 5365 } 5366 5367 var keyCode = $.ui.keyCode, 5368 length = this.headers.length, 5369 currentIndex = this.headers.index( event.target ), 5370 toFocus = false; 5371 5372 switch ( event.keyCode ) { 5373 case keyCode.RIGHT: 5374 case keyCode.DOWN: 5375 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5376 break; 5377 case keyCode.LEFT: 5378 case keyCode.UP: 5379 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5380 break; 5381 case keyCode.SPACE: 5382 case keyCode.ENTER: 5383 this._eventHandler( event ); 5384 break; 5385 case keyCode.HOME: 5386 toFocus = this.headers[ 0 ]; 5387 break; 5388 case keyCode.END: 5389 toFocus = this.headers[ length - 1 ]; 5390 break; 5391 } 5392 5393 if ( toFocus ) { 5394 $( event.target ).attr( "tabIndex", -1 ); 5395 $( toFocus ).attr( "tabIndex", 0 ); 5396 toFocus.focus(); 5397 event.preventDefault(); 5398 } 5399 }, 5400 5401 _panelKeyDown : function( event ) { 5402 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5403 $( event.currentTarget ).prev().focus(); 5404 } 5405 }, 5406 5407 refresh: function() { 5408 var options = this.options; 5409 this._processPanels(); 5410 5411 // was collapsed or no panel 5412 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 5413 options.active = false; 5414 this.active = $(); 5415 // active false only when collapsible is true 5416 } if ( options.active === false ) { 5417 this._activate( 0 ); 5418 // was active, but active panel is gone 5419 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5420 // all remaining panel are disabled 5421 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 5422 options.active = false; 5423 this.active = $(); 5424 // activate previous panel 5425 } else { 5426 this._activate( Math.max( 0, options.active - 1 ) ); 5427 } 5428 // was active, active panel still exists 5429 } else { 5430 // make sure active index is correct 5431 options.active = this.headers.index( this.active ); 5432 } 5433 5434 this._destroyIcons(); 5435 5436 this._refresh(); 5437 }, 5438 5439 _processPanels: function() { 5440 this.headers = this.element.find( this.options.header ) 5441 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 5442 5443 this.headers.next() 5444 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 5445 .filter(":not(.ui-accordion-content-active)") 5446 .hide(); 5447 }, 5448 5449 _refresh: function() { 5450 var maxHeight, 5451 options = this.options, 5452 heightStyle = options.heightStyle, 5453 parent = this.element.parent(), 5454 accordionId = this.accordionId = "ui-accordion-" + 5455 (this.element.attr( "id" ) || ++uid); 5456 5457 this.active = this._findActive( options.active ) 5458 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 5459 .removeClass( "ui-corner-all" ); 5460 this.active.next() 5461 .addClass( "ui-accordion-content-active" ) 5462 .show(); 5463 5464 this.headers 5465 .attr( "role", "tab" ) 5466 .each(function( i ) { 5467 var header = $( this ), 5468 headerId = header.attr( "id" ), 5469 panel = header.next(), 5470 panelId = panel.attr( "id" ); 5471 if ( !headerId ) { 5472 headerId = accordionId + "-header-" + i; 5473 header.attr( "id", headerId ); 5474 } 5475 if ( !panelId ) { 5476 panelId = accordionId + "-panel-" + i; 5477 panel.attr( "id", panelId ); 5478 } 5479 header.attr( "aria-controls", panelId ); 5480 panel.attr( "aria-labelledby", headerId ); 5481 }) 5482 .next() 5483 .attr( "role", "tabpanel" ); 5484 5485 this.headers 5486 .not( this.active ) 5487 .attr({ 5488 "aria-selected": "false", 5489 tabIndex: -1 5490 }) 5491 .next() 5492 .attr({ 5493 "aria-expanded": "false", 5494 "aria-hidden": "true" 5495 }) 5496 .hide(); 5497 5498 // make sure at least one header is in the tab order 5499 if ( !this.active.length ) { 5500 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5501 } else { 5502 this.active.attr({ 5503 "aria-selected": "true", 5504 tabIndex: 0 5505 }) 5506 .next() 5507 .attr({ 5508 "aria-expanded": "true", 5509 "aria-hidden": "false" 5510 }); 5511 } 5512 5513 this._createIcons(); 5514 5515 this._setupEvents( options.event ); 5516 5517 if ( heightStyle === "fill" ) { 5518 maxHeight = parent.height(); 5519 this.element.siblings( ":visible" ).each(function() { 5520 var elem = $( this ), 5521 position = elem.css( "position" ); 5522 5523 if ( position === "absolute" || position === "fixed" ) { 5524 return; 5525 } 5526 maxHeight -= elem.outerHeight( true ); 5527 }); 5528 5529 this.headers.each(function() { 5530 maxHeight -= $( this ).outerHeight( true ); 5531 }); 5532 5533 this.headers.next() 5534 .each(function() { 5535 $( this ).height( Math.max( 0, maxHeight - 5536 $( this ).innerHeight() + $( this ).height() ) ); 5537 }) 5538 .css( "overflow", "auto" ); 5539 } else if ( heightStyle === "auto" ) { 5540 maxHeight = 0; 5541 this.headers.next() 5542 .each(function() { 5543 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5544 }) 5545 .height( maxHeight ); 5546 } 5547 }, 5548 5549 _activate: function( index ) { 5550 var active = this._findActive( index )[ 0 ]; 5551 5552 // trying to activate the already active panel 5553 if ( active === this.active[ 0 ] ) { 5554 return; 5555 } 5556 5557 // trying to collapse, simulate a click on the currently active header 5558 active = active || this.active[ 0 ]; 5559 5560 this._eventHandler({ 5561 target: active, 5562 currentTarget: active, 5563 preventDefault: $.noop 5564 }); 5565 }, 5566 5567 _findActive: function( selector ) { 5568 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5569 }, 5570 5571 _setupEvents: function( event ) { 5572 var events = { 5573 keydown: "_keydown" 5574 }; 5575 if ( event ) { 5576 $.each( event.split(" "), function( index, eventName ) { 5577 events[ eventName ] = "_eventHandler"; 5578 }); 5579 } 5580 5581 this._off( this.headers.add( this.headers.next() ) ); 5582 this._on( this.headers, events ); 5583 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 5584 this._hoverable( this.headers ); 5585 this._focusable( this.headers ); 5586 }, 5587 5588 _eventHandler: function( event ) { 5589 var options = this.options, 5590 active = this.active, 5591 clicked = $( event.currentTarget ), 5592 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5593 collapsing = clickedIsActive && options.collapsible, 5594 toShow = collapsing ? $() : clicked.next(), 5595 toHide = active.next(), 5596 eventData = { 5597 oldHeader: active, 5598 oldPanel: toHide, 5599 newHeader: collapsing ? $() : clicked, 5600 newPanel: toShow 5601 }; 5602 5603 event.preventDefault(); 5604 5605 if ( 5606 // click on active header, but not collapsible 5607 ( clickedIsActive && !options.collapsible ) || 5608 // allow canceling activation 5609 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5610 return; 5611 } 5612 5613 options.active = collapsing ? false : this.headers.index( clicked ); 5614 5615 // when the call to ._toggle() comes after the class changes 5616 // it causes a very odd bug in IE 8 (see #6720) 5617 this.active = clickedIsActive ? $() : clicked; 5618 this._toggle( eventData ); 5619 5620 // switch classes 5621 // corner classes on the previously active header stay after the animation 5622 active.removeClass( "ui-accordion-header-active ui-state-active" ); 5623 if ( options.icons ) { 5624 active.children( ".ui-accordion-header-icon" ) 5625 .removeClass( options.icons.activeHeader ) 5626 .addClass( options.icons.header ); 5627 } 5628 5629 if ( !clickedIsActive ) { 5630 clicked 5631 .removeClass( "ui-corner-all" ) 5632 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 5633 if ( options.icons ) { 5634 clicked.children( ".ui-accordion-header-icon" ) 5635 .removeClass( options.icons.header ) 5636 .addClass( options.icons.activeHeader ); 5637 } 5638 5639 clicked 5640 .next() 5641 .addClass( "ui-accordion-content-active" ); 5642 } 5643 }, 5644 5645 _toggle: function( data ) { 5646 var toShow = data.newPanel, 5647 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5648 5649 // handle activating a panel during the animation for another activation 5650 this.prevShow.add( this.prevHide ).stop( true, true ); 5651 this.prevShow = toShow; 5652 this.prevHide = toHide; 5653 5654 if ( this.options.animate ) { 5655 this._animate( toShow, toHide, data ); 5656 } else { 5657 toHide.hide(); 5658 toShow.show(); 5659 this._toggleComplete( data ); 5660 } 5661 5662 toHide.attr({ 5663 "aria-expanded": "false", 5664 "aria-hidden": "true" 5665 }); 5666 toHide.prev().attr( "aria-selected", "false" ); 5667 // if we're switching panels, remove the old header from the tab order 5668 // if we're opening from collapsed state, remove the previous header from the tab order 5669 // if we're collapsing, then keep the collapsing header in the tab order 5670 if ( toShow.length && toHide.length ) { 5671 toHide.prev().attr( "tabIndex", -1 ); 5672 } else if ( toShow.length ) { 5673 this.headers.filter(function() { 5674 return $( this ).attr( "tabIndex" ) === 0; 5675 }) 5676 .attr( "tabIndex", -1 ); 5677 } 5678 5679 toShow 5680 .attr({ 5681 "aria-expanded": "true", 5682 "aria-hidden": "false" 5683 }) 5684 .prev() 5685 .attr({ 5686 "aria-selected": "true", 5687 tabIndex: 0 5688 }); 5689 }, 5690 5691 _animate: function( toShow, toHide, data ) { 5692 var total, easing, duration, 5693 that = this, 5694 adjust = 0, 5695 down = toShow.length && 5696 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5697 animate = this.options.animate || {}, 5698 options = down && animate.down || animate, 5699 complete = function() { 5700 that._toggleComplete( data ); 5701 }; 5702 5703 if ( typeof options === "number" ) { 5704 duration = options; 5705 } 5706 if ( typeof options === "string" ) { 5707 easing = options; 5708 } 5709 // fall back from options to animation in case of partial down settings 5710 easing = easing || options.easing || animate.easing; 5711 duration = duration || options.duration || animate.duration; 5712 5713 if ( !toHide.length ) { 5714 return toShow.animate( showProps, duration, easing, complete ); 5715 } 5716 if ( !toShow.length ) { 5717 return toHide.animate( hideProps, duration, easing, complete ); 5718 } 5719 5720 total = toShow.show().outerHeight(); 5721 toHide.animate( hideProps, { 5722 duration: duration, 5723 easing: easing, 5724 step: function( now, fx ) { 5725 fx.now = Math.round( now ); 5726 } 5727 }); 5728 toShow 5729 .hide() 5730 .animate( showProps, { 5731 duration: duration, 5732 easing: easing, 5733 complete: complete, 5734 step: function( now, fx ) { 5735 fx.now = Math.round( now ); 5736 if ( fx.prop !== "height" ) { 5737 adjust += fx.now; 5738 } else if ( that.options.heightStyle !== "content" ) { 5739 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 5740 adjust = 0; 5741 } 5742 } 5743 }); 5744 }, 5745 5746 _toggleComplete: function( data ) { 5747 var toHide = data.oldPanel; 5748 5749 toHide 5750 .removeClass( "ui-accordion-content-active" ) 5751 .prev() 5752 .removeClass( "ui-corner-top" ) 5753 .addClass( "ui-corner-all" ); 5754 5755 // Work around for rendering bug in IE (#5421) 5756 if ( toHide.length ) { 5757 toHide.parent()[0].className = toHide.parent()[0].className; 5758 } 5759 5760 this._trigger( "activate", null, data ); 5761 } 5762}); 5763 5764})( jQuery ); 5765(function( $, undefined ) { 5766 5767// used to prevent race conditions with remote data sources 5768var requestIndex = 0; 5769 5770$.widget( "ui.autocomplete", { 5771 version: "1.10.1", 5772 defaultElement: "<input>", 5773 options: { 5774 appendTo: null, 5775 autoFocus: false, 5776 delay: 300, 5777 minLength: 1, 5778 position: { 5779 my: "left top", 5780 at: "left bottom", 5781 collision: "none" 5782 }, 5783 source: null, 5784 5785 // callbacks 5786 change: null, 5787 close: null, 5788 focus: null, 5789 open: null, 5790 response: null, 5791 search: null, 5792 select: null 5793 }, 5794 5795 pending: 0, 5796 5797 _create: function() { 5798 // Some browsers only repeat keydown events, not keypress events, 5799 // so we use the suppressKeyPress flag to determine if we've already 5800 // handled the keydown event. #7269 5801 // Unfortunately the code for & in keypress is the same as the up arrow, 5802 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 5803 // events when we know the keydown event was used to modify the 5804 // search term. #7799 5805 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 5806 nodeName = this.element[0].nodeName.toLowerCase(), 5807 isTextarea = nodeName === "textarea", 5808 isInput = nodeName === "input"; 5809 5810 this.isMultiLine = 5811 // Textareas are always multi-line 5812 isTextarea ? true : 5813 // Inputs are always single-line, even if inside a contentEditable element 5814 // IE also treats inputs as contentEditable 5815 isInput ? false : 5816 // All other element types are determined by whether or not they're contentEditable 5817 this.element.prop( "isContentEditable" ); 5818 5819 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 5820 this.isNewMenu = true; 5821 5822 this.element 5823 .addClass( "ui-autocomplete-input" ) 5824 .attr( "autocomplete", "off" ); 5825 5826 this._on( this.element, { 5827 keydown: function( event ) { 5828 /*jshint maxcomplexity:15*/ 5829 if ( this.element.prop( "readOnly" ) ) { 5830 suppressKeyPress = true; 5831 suppressInput = true; 5832 suppressKeyPressRepeat = true; 5833 return; 5834 } 5835 5836 suppressKeyPress = false; 5837 suppressInput = false; 5838 suppressKeyPressRepeat = false; 5839 var keyCode = $.ui.keyCode; 5840 switch( event.keyCode ) { 5841 case keyCode.PAGE_UP: 5842 suppressKeyPress = true; 5843 this._move( "previousPage", event ); 5844 break; 5845 case keyCode.PAGE_DOWN: 5846 suppressKeyPress = true; 5847 this._move( "nextPage", event ); 5848 break; 5849 case keyCode.UP: 5850 suppressKeyPress = true; 5851 this._keyEvent( "previous", event ); 5852 break; 5853 case keyCode.DOWN: 5854 suppressKeyPress = true; 5855 this._keyEvent( "next", event ); 5856 break; 5857 case keyCode.ENTER: 5858 case keyCode.NUMPAD_ENTER: 5859 // when menu is open and has focus 5860 if ( this.menu.active ) { 5861 // #6055 - Opera still allows the keypress to occur 5862 // which causes forms to submit 5863 suppressKeyPress = true; 5864 event.preventDefault(); 5865 this.menu.select( event ); 5866 } 5867 break; 5868 case keyCode.TAB: 5869 if ( this.menu.active ) { 5870 this.menu.select( event ); 5871 } 5872 break; 5873 case keyCode.ESCAPE: 5874 if ( this.menu.element.is( ":visible" ) ) { 5875 this._value( this.term ); 5876 this.close( event ); 5877 // Different browsers have different default behavior for escape 5878 // Single press can mean undo or clear 5879 // Double press in IE means clear the whole form 5880 event.preventDefault(); 5881 } 5882 break; 5883 default: 5884 suppressKeyPressRepeat = true; 5885 // search timeout should be triggered before the input value is changed 5886 this._searchTimeout( event ); 5887 break; 5888 } 5889 }, 5890 keypress: function( event ) { 5891 if ( suppressKeyPress ) { 5892 suppressKeyPress = false; 5893 event.preventDefault(); 5894 return; 5895 } 5896 if ( suppressKeyPressRepeat ) { 5897 return; 5898 } 5899 5900 // replicate some key handlers to allow them to repeat in Firefox and Opera 5901 var keyCode = $.ui.keyCode; 5902 switch( event.keyCode ) { 5903 case keyCode.PAGE_UP: 5904 this._move( "previousPage", event ); 5905 break; 5906 case keyCode.PAGE_DOWN: 5907 this._move( "nextPage", event ); 5908 break; 5909 case keyCode.UP: 5910 this._keyEvent( "previous", event ); 5911 break; 5912 case keyCode.DOWN: 5913 this._keyEvent( "next", event ); 5914 break; 5915 } 5916 }, 5917 input: function( event ) { 5918 if ( suppressInput ) { 5919 suppressInput = false; 5920 event.preventDefault(); 5921 return; 5922 } 5923 this._searchTimeout( event ); 5924 }, 5925 focus: function() { 5926 this.selectedItem = null; 5927 this.previous = this._value(); 5928 }, 5929 blur: function( event ) { 5930 if ( this.cancelBlur ) { 5931 delete this.cancelBlur; 5932 return; 5933 } 5934 5935 clearTimeout( this.searching ); 5936 this.close( event ); 5937 this._change( event ); 5938 } 5939 }); 5940 5941 this._initSource(); 5942 this.menu = $( "<ul>" ) 5943 .addClass( "ui-autocomplete ui-front" ) 5944 .appendTo( this._appendTo() ) 5945 .menu({ 5946 // custom key handling for now 5947 input: $(), 5948 // disable ARIA support, the live region takes care of that 5949 role: null 5950 }) 5951 .hide() 5952 .data( "ui-menu" ); 5953 5954 this._on( this.menu.element, { 5955 mousedown: function( event ) { 5956 // prevent moving focus out of the text field 5957 event.preventDefault(); 5958 5959 // IE doesn't prevent moving focus even with event.preventDefault() 5960 // so we set a flag to know when we should ignore the blur event 5961 this.cancelBlur = true; 5962 this._delay(function() { 5963 delete this.cancelBlur; 5964 }); 5965 5966 // clicking on the scrollbar causes focus to shift to the body 5967 // but we can't detect a mouseup or a click immediately afterward 5968 // so we have to track the next mousedown and close the menu if 5969 // the user clicks somewhere outside of the autocomplete 5970 var menuElement = this.menu.element[ 0 ]; 5971 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 5972 this._delay(function() { 5973 var that = this; 5974 this.document.one( "mousedown", function( event ) { 5975 if ( event.target !== that.element[ 0 ] && 5976 event.target !== menuElement && 5977 !$.contains( menuElement, event.target ) ) { 5978 that.close(); 5979 } 5980 }); 5981 }); 5982 } 5983 }, 5984 menufocus: function( event, ui ) { 5985 // #7024 - Prevent accidental activation of menu items in Firefox 5986 if ( this.isNewMenu ) { 5987 this.isNewMenu = false; 5988 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 5989 this.menu.blur(); 5990 5991 this.document.one( "mousemove", function() { 5992 $( event.target ).trigger( event.originalEvent ); 5993 }); 5994 5995 return; 5996 } 5997 } 5998 5999 var item = ui.item.data( "ui-autocomplete-item" ); 6000 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6001 // use value to match what will end up in the input, if it was a key event 6002 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6003 this._value( item.value ); 6004 } 6005 } else { 6006 // Normally the input is populated with the item's value as the 6007 // menu is navigated, causing screen readers to notice a change and 6008 // announce the item. Since the focus event was canceled, this doesn't 6009 // happen, so we update the live region so that screen readers can 6010 // still notice the change and announce it. 6011 this.liveRegion.text( item.value ); 6012 } 6013 }, 6014 menuselect: function( event, ui ) { 6015 var item = ui.item.data( "ui-autocomplete-item" ), 6016 previous = this.previous; 6017 6018 // only trigger when focus was lost (click on menu) 6019 if ( this.element[0] !== this.document[0].activeElement ) { 6020 this.element.focus(); 6021 this.previous = previous; 6022 // #6109 - IE triggers two focus events and the second 6023 // is asynchronous, so we need to reset the previous 6024 // term synchronously and asynchronously :-( 6025 this._delay(function() { 6026 this.previous = previous; 6027 this.selectedItem = item; 6028 }); 6029 } 6030 6031 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6032 this._value( item.value ); 6033 } 6034 // reset the term after the select event 6035 // this allows custom select handling to work properly 6036 this.term = this._value(); 6037 6038 this.close( event ); 6039 this.selectedItem = item; 6040 } 6041 }); 6042 6043 this.liveRegion = $( "<span>", { 6044 role: "status", 6045 "aria-live": "polite" 6046 }) 6047 .addClass( "ui-helper-hidden-accessible" ) 6048 .insertAfter( this.element ); 6049 6050 // turning off autocomplete prevents the browser from remembering the 6051 // value when navigating through history, so we re-enable autocomplete 6052 // if the page is unloaded before the widget is destroyed. #7790 6053 this._on( this.window, { 6054 beforeunload: function() { 6055 this.element.removeAttr( "autocomplete" ); 6056 } 6057 }); 6058 }, 6059 6060 _destroy: function() { 6061 clearTimeout( this.searching ); 6062 this.element 6063 .removeClass( "ui-autocomplete-input" ) 6064 .removeAttr( "autocomplete" ); 6065 this.menu.element.remove(); 6066 this.liveRegion.remove(); 6067 }, 6068 6069 _setOption: function( key, value ) { 6070 this._super( key, value ); 6071 if ( key === "source" ) { 6072 this._initSource(); 6073 } 6074 if ( key === "appendTo" ) { 6075 this.menu.element.appendTo( this._appendTo() ); 6076 } 6077 if ( key === "disabled" && value && this.xhr ) { 6078 this.xhr.abort(); 6079 } 6080 }, 6081 6082 _appendTo: function() { 6083 var element = this.options.appendTo; 6084 6085 if ( element ) { 6086 element = element.jquery || element.nodeType ? 6087 $( element ) : 6088 this.document.find( element ).eq( 0 ); 6089 } 6090 6091 if ( !element ) { 6092 element = this.element.closest( ".ui-front" ); 6093 } 6094 6095 if ( !element.length ) { 6096 element = this.document[0].body; 6097 } 6098 6099 return element; 6100 }, 6101 6102 _initSource: function() { 6103 var array, url, 6104 that = this; 6105 if ( $.isArray(this.options.source) ) { 6106 array = this.options.source; 6107 this.source = function( request, response ) { 6108 response( $.ui.autocomplete.filter( array, request.term ) ); 6109 }; 6110 } else if ( typeof this.options.source === "string" ) { 6111 url = this.options.source; 6112 this.source = function( request, response ) { 6113 if ( that.xhr ) { 6114 that.xhr.abort(); 6115 } 6116 that.xhr = $.ajax({ 6117 url: url, 6118 data: request, 6119 dataType: "json", 6120 success: function( data ) { 6121 response( data ); 6122 }, 6123 error: function() { 6124 response( [] ); 6125 } 6126 }); 6127 }; 6128 } else { 6129 this.source = this.options.source; 6130 } 6131 }, 6132 6133 _searchTimeout: function( event ) { 6134 clearTimeout( this.searching ); 6135 this.searching = this._delay(function() { 6136 // only search if the value has changed 6137 if ( this.term !== this._value() ) { 6138 this.selectedItem = null; 6139 this.search( null, event ); 6140 } 6141 }, this.options.delay ); 6142 }, 6143 6144 search: function( value, event ) { 6145 value = value != null ? value : this._value(); 6146 6147 // always save the actual value, not the one passed as an argument 6148 this.term = this._value(); 6149 6150 if ( value.length < this.options.minLength ) { 6151 return this.close( event ); 6152 } 6153 6154 if ( this._trigger( "search", event ) === false ) { 6155 return; 6156 } 6157 6158 return this._search( value ); 6159 }, 6160 6161 _search: function( value ) { 6162 this.pending++; 6163 this.element.addClass( "ui-autocomplete-loading" ); 6164 this.cancelSearch = false; 6165 6166 this.source( { term: value }, this._response() ); 6167 }, 6168 6169 _response: function() { 6170 var that = this, 6171 index = ++requestIndex; 6172 6173 return function( content ) { 6174 if ( index === requestIndex ) { 6175 that.__response( content ); 6176 } 6177 6178 that.pending--; 6179 if ( !that.pending ) { 6180 that.element.removeClass( "ui-autocomplete-loading" ); 6181 } 6182 }; 6183 }, 6184 6185 __response: function( content ) { 6186 if ( content ) { 6187 content = this._normalize( content ); 6188 } 6189 this._trigger( "response", null, { content: content } ); 6190 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6191 this._suggest( content ); 6192 this._trigger( "open" ); 6193 } else { 6194 // use ._close() instead of .close() so we don't cancel future searches 6195 this._close(); 6196 } 6197 }, 6198 6199 close: function( event ) { 6200 this.cancelSearch = true; 6201 this._close( event ); 6202 }, 6203 6204 _close: function( event ) { 6205 if ( this.menu.element.is( ":visible" ) ) { 6206 this.menu.element.hide(); 6207 this.menu.blur(); 6208 this.isNewMenu = true; 6209 this._trigger( "close", event ); 6210 } 6211 }, 6212 6213 _change: function( event ) { 6214 if ( this.previous !== this._value() ) { 6215 this._trigger( "change", event, { item: this.selectedItem } ); 6216 } 6217 }, 6218 6219 _normalize: function( items ) { 6220 // assume all items have the right format when the first item is complete 6221 if ( items.length && items[0].label && items[0].value ) { 6222 return items; 6223 } 6224 return $.map( items, function( item ) { 6225 if ( typeof item === "string" ) { 6226 return { 6227 label: item, 6228 value: item 6229 }; 6230 } 6231 return $.extend({ 6232 label: item.label || item.value, 6233 value: item.value || item.label 6234 }, item ); 6235 }); 6236 }, 6237 6238 _suggest: function( items ) { 6239 var ul = this.menu.element.empty(); 6240 this._renderMenu( ul, items ); 6241 this.menu.refresh(); 6242 6243 // size and position menu 6244 ul.show(); 6245 this._resizeMenu(); 6246 ul.position( $.extend({ 6247 of: this.element 6248 }, this.options.position )); 6249 6250 if ( this.options.autoFocus ) { 6251 this.menu.next(); 6252 } 6253 }, 6254 6255 _resizeMenu: function() { 6256 var ul = this.menu.element; 6257 ul.outerWidth( Math.max( 6258 // Firefox wraps long text (possibly a rounding bug) 6259 // so we add 1px to avoid the wrapping (#7513) 6260 ul.width( "" ).outerWidth() + 1, 6261 this.element.outerWidth() 6262 ) ); 6263 }, 6264 6265 _renderMenu: function( ul, items ) { 6266 var that = this; 6267 $.each( items, function( index, item ) { 6268 that._renderItemData( ul, item ); 6269 }); 6270 }, 6271 6272 _renderItemData: function( ul, item ) { 6273 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6274 }, 6275 6276 _renderItem: function( ul, item ) { 6277 return $( "<li>" ) 6278 .append( $( "<a>" ).text( item.label ) ) 6279 .appendTo( ul ); 6280 }, 6281 6282 _move: function( direction, event ) { 6283 if ( !this.menu.element.is( ":visible" ) ) { 6284 this.search( null, event ); 6285 return; 6286 } 6287 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6288 this.menu.isLastItem() && /^next/.test( direction ) ) { 6289 this._value( this.term ); 6290 this.menu.blur(); 6291 return; 6292 } 6293 this.menu[ direction ]( event ); 6294 }, 6295 6296 widget: function() { 6297 return this.menu.element; 6298 }, 6299 6300 _value: function() { 6301 return this.valueMethod.apply( this.element, arguments ); 6302 }, 6303 6304 _keyEvent: function( keyEvent, event ) { 6305 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6306 this._move( keyEvent, event ); 6307 6308 // prevents moving cursor to beginning/end of the text field in some browsers 6309 event.preventDefault(); 6310 } 6311 } 6312}); 6313 6314$.extend( $.ui.autocomplete, { 6315 escapeRegex: function( value ) { 6316 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6317 }, 6318 filter: function(array, term) { 6319 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 6320 return $.grep( array, function(value) { 6321 return matcher.test( value.label || value.value || value ); 6322 }); 6323 } 6324}); 6325 6326 6327// live region extension, adding a `messages` option 6328// NOTE: This is an experimental API. We are still investigating 6329// a full solution for string manipulation and internationalization. 6330$.widget( "ui.autocomplete", $.ui.autocomplete, { 6331 options: { 6332 messages: { 6333 noResults: "No search results.", 6334 results: function( amount ) { 6335 return amount + ( amount > 1 ? " results are" : " result is" ) + 6336 " available, use up and down arrow keys to navigate."; 6337 } 6338 } 6339 }, 6340 6341 __response: function( content ) { 6342 var message; 6343 this._superApply( arguments ); 6344 if ( this.options.disabled || this.cancelSearch ) { 6345 return; 6346 } 6347 if ( content && content.length ) { 6348 message = this.options.messages.results( content.length ); 6349 } else { 6350 message = this.options.messages.noResults; 6351 } 6352 this.liveRegion.text( message ); 6353 } 6354}); 6355 6356}( jQuery )); 6357(function( $, undefined ) { 6358 6359var lastActive, startXPos, startYPos, clickDragged, 6360 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6361 stateClasses = "ui-state-hover ui-state-active ", 6362 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", 6363 formResetHandler = function() { 6364 var buttons = $( this ).find( ":ui-button" ); 6365 setTimeout(function() { 6366 buttons.button( "refresh" ); 6367 }, 1 ); 6368 }, 6369 radioGroup = function( radio ) { 6370 var name = radio.name, 6371 form = radio.form, 6372 radios = $( [] ); 6373 if ( name ) { 6374 name = name.replace( /'/g, "\\'" ); 6375 if ( form ) { 6376 radios = $( form ).find( "[name='" + name + "']" ); 6377 } else { 6378 radios = $( "[name='" + name + "']", radio.ownerDocument ) 6379 .filter(function() { 6380 return !this.form; 6381 }); 6382 } 6383 } 6384 return radios; 6385 }; 6386 6387$.widget( "ui.button", { 6388 version: "1.10.1", 6389 defaultElement: "<button>", 6390 options: { 6391 disabled: null, 6392 text: true, 6393 label: null, 6394 icons: { 6395 primary: null, 6396 secondary: null 6397 } 6398 }, 6399 _create: function() { 6400 this.element.closest( "form" ) 6401 .unbind( "reset" + this.eventNamespace ) 6402 .bind( "reset" + this.eventNamespace, formResetHandler ); 6403 6404 if ( typeof this.options.disabled !== "boolean" ) { 6405 this.options.disabled = !!this.element.prop( "disabled" ); 6406 } else { 6407 this.element.prop( "disabled", this.options.disabled ); 6408 } 6409 6410 this._determineButtonType(); 6411 this.hasTitle = !!this.buttonElement.attr( "title" ); 6412 6413 var that = this, 6414 options = this.options, 6415 toggleButton = this.type === "checkbox" || this.type === "radio", 6416 activeClass = !toggleButton ? "ui-state-active" : "", 6417 focusClass = "ui-state-focus"; 6418 6419 if ( options.label === null ) { 6420 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6421 } 6422 6423 this._hoverable( this.buttonElement ); 6424 6425 this.buttonElement 6426 .addClass( baseClasses ) 6427 .attr( "role", "button" ) 6428 .bind( "mouseenter" + this.eventNamespace, function() { 6429 if ( options.disabled ) { 6430 return; 6431 } 6432 if ( this === lastActive ) { 6433 $( this ).addClass( "ui-state-active" ); 6434 } 6435 }) 6436 .bind( "mouseleave" + this.eventNamespace, function() { 6437 if ( options.disabled ) { 6438 return; 6439 } 6440 $( this ).removeClass( activeClass ); 6441 }) 6442 .bind( "click" + this.eventNamespace, function( event ) { 6443 if ( options.disabled ) { 6444 event.preventDefault(); 6445 event.stopImmediatePropagation(); 6446 } 6447 }); 6448 6449 this.element 6450 .bind( "focus" + this.eventNamespace, function() { 6451 // no need to check disabled, focus won't be triggered anyway 6452 that.buttonElement.addClass( focusClass ); 6453 }) 6454 .bind( "blur" + this.eventNamespace, function() { 6455 that.buttonElement.removeClass( focusClass ); 6456 }); 6457 6458 if ( toggleButton ) { 6459 this.element.bind( "change" + this.eventNamespace, function() { 6460 if ( clickDragged ) { 6461 return; 6462 } 6463 that.refresh(); 6464 }); 6465 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 6466 // prevents issue where button state changes but checkbox/radio checked state 6467 // does not in Firefox (see ticket #6970) 6468 this.buttonElement 6469 .bind( "mousedown" + this.eventNamespace, function( event ) { 6470 if ( options.disabled ) { 6471 return; 6472 } 6473 clickDragged = false; 6474 startXPos = event.pageX; 6475 startYPos = event.pageY; 6476 }) 6477 .bind( "mouseup" + this.eventNamespace, function( event ) { 6478 if ( options.disabled ) { 6479 return; 6480 } 6481 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 6482 clickDragged = true; 6483 } 6484 }); 6485 } 6486 6487 if ( this.type === "checkbox" ) { 6488 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6489 if ( options.disabled || clickDragged ) { 6490 return false; 6491 } 6492 }); 6493 } else if ( this.type === "radio" ) { 6494 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6495 if ( options.disabled || clickDragged ) { 6496 return false; 6497 } 6498 $( this ).addClass( "ui-state-active" ); 6499 that.buttonElement.attr( "aria-pressed", "true" ); 6500 6501 var radio = that.element[ 0 ]; 6502 radioGroup( radio ) 6503 .not( radio ) 6504 .map(function() { 6505 return $( this ).button( "widget" )[ 0 ]; 6506 }) 6507 .removeClass( "ui-state-active" ) 6508 .attr( "aria-pressed", "false" ); 6509 }); 6510 } else { 6511 this.buttonElement 6512 .bind( "mousedown" + this.eventNamespace, function() { 6513 if ( options.disabled ) { 6514 return false; 6515 } 6516 $( this ).addClass( "ui-state-active" ); 6517 lastActive = this; 6518 that.document.one( "mouseup", function() { 6519 lastActive = null; 6520 }); 6521 }) 6522 .bind( "mouseup" + this.eventNamespace, function() { 6523 if ( options.disabled ) { 6524 return false; 6525 } 6526 $( this ).removeClass( "ui-state-active" ); 6527 }) 6528 .bind( "keydown" + this.eventNamespace, function(event) { 6529 if ( options.disabled ) { 6530 return false; 6531 } 6532 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 6533 $( this ).addClass( "ui-state-active" ); 6534 } 6535 }) 6536 // see #8559, we bind to blur here in case the button element loses 6537 // focus between keydown and keyup, it would be left in an "active" state 6538 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 6539 $( this ).removeClass( "ui-state-active" ); 6540 }); 6541 6542 if ( this.buttonElement.is("a") ) { 6543 this.buttonElement.keyup(function(event) { 6544 if ( event.keyCode === $.ui.keyCode.SPACE ) { 6545 // TODO pass through original event correctly (just as 2nd argument doesn't work) 6546 $( this ).click(); 6547 } 6548 }); 6549 } 6550 } 6551 6552 // TODO: pull out $.Widget's handling for the disabled option into 6553 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 6554 // be overridden by individual plugins 6555 this._setOption( "disabled", options.disabled ); 6556 this._resetButton(); 6557 }, 6558 6559 _determineButtonType: function() { 6560 var ancestor, labelSelector, checked; 6561 6562 if ( this.element.is("[type=checkbox]") ) { 6563 this.type = "checkbox"; 6564 } else if ( this.element.is("[type=radio]") ) { 6565 this.type = "radio"; 6566 } else if ( this.element.is("input") ) { 6567 this.type = "input"; 6568 } else { 6569 this.type = "button"; 6570 } 6571 6572 if ( this.type === "checkbox" || this.type === "radio" ) { 6573 // we don't search against the document in case the element 6574 // is disconnected from the DOM 6575 ancestor = this.element.parents().last(); 6576 labelSelector = "label[for='" + this.element.attr("id") + "']"; 6577 this.buttonElement = ancestor.find( labelSelector ); 6578 if ( !this.buttonElement.length ) { 6579 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 6580 this.buttonElement = ancestor.filter( labelSelector ); 6581 if ( !this.buttonElement.length ) { 6582 this.buttonElement = ancestor.find( labelSelector ); 6583 } 6584 } 6585 this.element.addClass( "ui-helper-hidden-accessible" ); 6586 6587 checked = this.element.is( ":checked" ); 6588 if ( checked ) { 6589 this.buttonElement.addClass( "ui-state-active" ); 6590 } 6591 this.buttonElement.prop( "aria-pressed", checked ); 6592 } else { 6593 this.buttonElement = this.element; 6594 } 6595 }, 6596 6597 widget: function() { 6598 return this.buttonElement; 6599 }, 6600 6601 _destroy: function() { 6602 this.element 6603 .removeClass( "ui-helper-hidden-accessible" ); 6604 this.buttonElement 6605 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 6606 .removeAttr( "role" ) 6607 .removeAttr( "aria-pressed" ) 6608 .html( this.buttonElement.find(".ui-button-text").html() ); 6609 6610 if ( !this.hasTitle ) {
vendor: 6,788 bytes, lines 6611-6806
6611 this.buttonElement.removeAttr( "title" ); 6612 } 6613 }, 6614 6615 _setOption: function( key, value ) { 6616 this._super( key, value ); 6617 if ( key === "disabled" ) { 6618 if ( value ) { 6619 this.element.prop( "disabled", true ); 6620 } else { 6621 this.element.prop( "disabled", false ); 6622 } 6623 return; 6624 } 6625 this._resetButton(); 6626 }, 6627 6628 refresh: function() { 6629 //See #8237 & #8828 6630 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 6631 6632 if ( isDisabled !== this.options.disabled ) { 6633 this._setOption( "disabled", isDisabled ); 6634 } 6635 if ( this.type === "radio" ) { 6636 radioGroup( this.element[0] ).each(function() { 6637 if ( $( this ).is( ":checked" ) ) { 6638 $( this ).button( "widget" ) 6639 .addClass( "ui-state-active" ) 6640 .attr( "aria-pressed", "true" ); 6641 } else { 6642 $( this ).button( "widget" ) 6643 .removeClass( "ui-state-active" ) 6644 .attr( "aria-pressed", "false" ); 6645 } 6646 }); 6647 } else if ( this.type === "checkbox" ) { 6648 if ( this.element.is( ":checked" ) ) { 6649 this.buttonElement 6650 .addClass( "ui-state-active" ) 6651 .attr( "aria-pressed", "true" ); 6652 } else { 6653 this.buttonElement 6654 .removeClass( "ui-state-active" ) 6655 .attr( "aria-pressed", "false" ); 6656 } 6657 } 6658 }, 6659 6660 _resetButton: function() { 6661 if ( this.type === "input" ) { 6662 if ( this.options.label ) { 6663 this.element.val( this.options.label ); 6664 } 6665 return; 6666 } 6667 var buttonElement = this.buttonElement.removeClass( typeClasses ), 6668 buttonText = $( "<span></span>", this.document[0] ) 6669 .addClass( "ui-button-text" ) 6670 .html( this.options.label ) 6671 .appendTo( buttonElement.empty() ) 6672 .text(), 6673 icons = this.options.icons, 6674 multipleIcons = icons.primary && icons.secondary, 6675 buttonClasses = []; 6676 6677 if ( icons.primary || icons.secondary ) { 6678 if ( this.options.text ) { 6679 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 6680 } 6681 6682 if ( icons.primary ) { 6683 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 6684 } 6685 6686 if ( icons.secondary ) { 6687 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 6688 } 6689 6690 if ( !this.options.text ) { 6691 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 6692 6693 if ( !this.hasTitle ) { 6694 buttonElement.attr( "title", $.trim( buttonText ) ); 6695 } 6696 } 6697 } else { 6698 buttonClasses.push( "ui-button-text-only" ); 6699 } 6700 buttonElement.addClass( buttonClasses.join( " " ) ); 6701 } 6702}); 6703 6704$.widget( "ui.buttonset", { 6705 version: "1.10.1", 6706 options: { 6707 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 6708 }, 6709 6710 _create: function() { 6711 this.element.addClass( "ui-buttonset" ); 6712 }, 6713 6714 _init: function() { 6715 this.refresh(); 6716 }, 6717 6718 _setOption: function( key, value ) { 6719 if ( key === "disabled" ) { 6720 this.buttons.button( "option", key, value ); 6721 } 6722 6723 this._super( key, value ); 6724 }, 6725 6726 refresh: function() { 6727 var rtl = this.element.css( "direction" ) === "rtl"; 6728 6729 this.buttons = this.element.find( this.options.items ) 6730 .filter( ":ui-button" ) 6731 .button( "refresh" ) 6732 .end() 6733 .not( ":ui-button" ) 6734 .button() 6735 .end() 6736 .map(function() { 6737 return $( this ).button( "widget" )[ 0 ]; 6738 }) 6739 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 6740 .filter( ":first" ) 6741 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 6742 .end() 6743 .filter( ":last" ) 6744 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 6745 .end() 6746 .end(); 6747 }, 6748 6749 _destroy: function() { 6750 this.element.removeClass( "ui-buttonset" ); 6751 this.buttons 6752 .map(function() { 6753 return $( this ).button( "widget" )[ 0 ]; 6754 }) 6755 .removeClass( "ui-corner-left ui-corner-right" ) 6756 .end() 6757 .button( "destroy" ); 6758 } 6759}); 6760 6761}( jQuery ) ); 6762(function( $, undefined ) { 6763 6764$.extend($.ui, { datepicker: { version: "1.10.1" } }); 6765 6766var PROP_NAME = "datepicker", 6767 dpuuid = new Date().getTime(), 6768 instActive; 6769 6770/* Date picker manager. 6771 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 6772 Settings for (groups of) date pickers are maintained in an instance object, 6773 allowing multiple different settings on the same page. */ 6774 6775function Datepicker() { 6776 this._curInst = null; // The current instance in use 6777 this._keyEvent = false; // If the last event was a key event 6778 this._disabledInputs = []; // List of date picker inputs that have been disabled 6779 this._datepickerShowing = false; // True if the popup picker is showing , false if not 6780 this._inDialog = false; // True if showing within a "dialog", false if not 6781 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 6782 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 6783 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 6784 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 6785 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 6786 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 6787 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 6788 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 6789 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 6790 this.regional = []; // Available regional settings, indexed by language code 6791 this.regional[""] = { // Default regional settings 6792 closeText: "Done", // Display text for close link 6793 prevText: "Prev", // Display text for previous month link 6794 nextText: "Next", // Display text for next month link 6795 currentText: "Today", // Display text for current month link 6796 monthNames: ["1æ","2æ","3æ","4æ","5æ","6æ", 6797 "7æ","8æ","9æ","10æ","11æ","12æ"], // Names of months for drop-down and formatting 6798 monthNamesShort: ["1æ", "2æ", "3æ", "4æ", "5æ", "6æ", "7æ", "8æ", "9æ", "10æ", "11æ", "12æ"], // For formatting 6799 dayNames: ["æ¥", "æ", "ç«", "æ°´", "æ¨", "é", "å"], // For formatting 6800 dayNamesShort: ["æ¥", "æ", "ç«", "æ°´", "æ¨", "é", "å"], // For formatting 6801 dayNamesMin: ["æ¥","æ","ç«","æ°´","æ¨","é","å"], // Column headings for days starting at Sunday 6802 weekHeader: "Wk", // Column header for week of the year 6803 dateFormat: "mm/dd/yy", // See format options on parseDate 6804 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 6805 isRTL: false, // True if right-to-left language, false if left-to-right 6806 showMonthAfterYear: tru
vendor: 26,326 bytes, lines 6806-7504
6806e, // True if the year select precedes month, false for month then year 6807 yearSuffix: "" // Additional text to append to the year in the month headers 6808 }; 6809 this._defaults = { // Global defaults for all the date picker instances 6810 showOn: "focus", // "focus" for popup on focus, 6811 // "button" for trigger button, or "both" for either 6812 showAnim: "fadeIn", // Name of jQuery animation for popup 6813 showOptions: {}, // Options for enhanced animations 6814 defaultDate: null, // Used when field is blank: actual date, 6815 // +/-number for offset from today, null for today 6816 appendText: "", // Display text following the input box, e.g. showing the format 6817 buttonText: "...", // Text for trigger button 6818 buttonImage: "", // URL for trigger button image 6819 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 6820 hideIfNoPrevNext: false, // True to hide next/previous month links 6821 // if not applicable, false to just disable them 6822 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 6823 gotoCurrent: false, // True if today link goes back to current selection instead 6824 changeMonth: false, // True if month can be selected directly, false if only prev/next 6825 changeYear: false, // True if year can be selected directly, false if only prev/next 6826 yearRange: "c-10:c+10", // Range of years to display in drop-down, 6827 // either relative to today's year (-nn:+nn), relative to currently displayed year 6828 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 6829 showOtherMonths: false, // True to show dates in other months, false to leave blank 6830 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 6831 showWeek: false, // True to show week of the year, false to not show it 6832 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 6833 // takes a Date and returns the number of the week for it 6834 shortYearCutoff: "+10", // Short year values < this are in the current century, 6835 // > this are in the previous century, 6836 // string value starting with "+" for current year + value 6837 minDate: null, // The earliest selectable date, or null for no limit 6838 maxDate: null, // The latest selectable date, or null for no limit 6839 duration: "fast", // Duration of display/closure 6840 beforeShowDay: null, // Function that takes a date and returns an array with 6841 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 6842 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 6843 beforeShow: null, // Function that takes an input field and 6844 // returns a set of custom settings for the date picker 6845 onSelect: null, // Define a callback function when a date is selected 6846 onChangeMonthYear: null, // Define a callback function when the month or year is changed 6847 onClose: null, // Define a callback function when the datepicker is closed 6848 numberOfMonths: 1, // Number of months to show at a time 6849 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 6850 stepMonths: 1, // Number of months to step back/forward 6851 stepBigMonths: 12, // Number of months to step back/forward for the big links 6852 altField: "", // Selector for an alternate field to store selected dates into 6853 altFormat: "", // The date format to use for the alternate field 6854 constrainInput: true, // The input is constrained by the current date format 6855 showButtonPanel: false, // True to show button panel, false to not show it 6856 autoSize: false, // True to size the input for the date format, false to leave as is 6857 disabled: false // The initial disabled state 6858 }; 6859 $.extend(this._defaults, this.regional[""]); 6860 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 6861} 6862 6863$.extend(Datepicker.prototype, { 6864 /* Class name added to elements to indicate already configured with a date picker. */ 6865 markerClassName: "hasDatepicker", 6866 6867 //Keep track of the maximum number of rows displayed (see #7043) 6868 maxRows: 4, 6869 6870 // TODO rename to "widget" when switching to widget factory 6871 _widgetDatepicker: function() { 6872 return this.dpDiv; 6873 }, 6874 6875 /* Override the default settings for all instances of the date picker. 6876 * @param settings object - the new settings to use as defaults (anonymous object) 6877 * @return the manager object 6878 */ 6879 setDefaults: function(settings) { 6880 extendRemove(this._defaults, settings || {}); 6881 return this; 6882 }, 6883 6884 /* Attach the date picker to a jQuery selection. 6885 * @param target element - the target input field or division or span 6886 * @param settings object - the new settings to use for this date picker instance (anonymous) 6887 */ 6888 _attachDatepicker: function(target, settings) { 6889 var nodeName, inline, inst; 6890 nodeName = target.nodeName.toLowerCase(); 6891 inline = (nodeName === "div" || nodeName === "span"); 6892 if (!target.id) { 6893 this.uuid += 1; 6894 target.id = "dp" + this.uuid; 6895 } 6896 inst = this._newInst($(target), inline); 6897 inst.settings = $.extend({}, settings || {}); 6898 if (nodeName === "input") { 6899 this._connectDatepicker(target, inst); 6900 } else if (inline) { 6901 this._inlineDatepicker(target, inst); 6902 } 6903 }, 6904 6905 /* Create a new instance object. */ 6906 _newInst: function(target, inline) { 6907 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 6908 return {id: id, input: target, // associated target 6909 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 6910 drawMonth: 0, drawYear: 0, // month being drawn 6911 inline: inline, // is datepicker inline or not 6912 dpDiv: (!inline ? this.dpDiv : // presentation div 6913 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 6914 }, 6915 6916 /* Attach the date picker to an input field. */ 6917 _connectDatepicker: function(target, inst) { 6918 var input = $(target); 6919 inst.append = $([]); 6920 inst.trigger = $([]); 6921 if (input.hasClass(this.markerClassName)) { 6922 return; 6923 } 6924 this._attachments(input, inst); 6925 input.addClass(this.markerClassName).keydown(this._doKeyDown). 6926 keypress(this._doKeyPress).keyup(this._doKeyUp); 6927 this._autoSize(inst); 6928 $.data(target, PROP_NAME, inst); 6929 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 6930 if( inst.settings.disabled ) { 6931 this._disableDatepicker( target ); 6932 } 6933 }, 6934 6935 /* Make attachments based on settings. */ 6936 _attachments: function(input, inst) { 6937 var showOn, buttonText, buttonImage, 6938 appendText = this._get(inst, "appendText"), 6939 isRTL = this._get(inst, "isRTL"); 6940 6941 if (inst.append) { 6942 inst.append.remove(); 6943 } 6944 if (appendText) { 6945 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 6946 input[isRTL ? "before" : "after"](inst.append); 6947 } 6948 6949 input.unbind("focus", this._showDatepicker); 6950 6951 if (inst.trigger) { 6952 inst.trigger.remove(); 6953 } 6954 6955 showOn = this._get(inst, "showOn"); 6956 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 6957 input.focus(this._showDatepicker); 6958 } 6959 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 6960 buttonText = this._get(inst, "buttonText"); 6961 buttonImage = this._get(inst, "buttonImage"); 6962 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 6963 $("<img/>").addClass(this._triggerClass). 6964 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 6965 $("<button type='button'></button>").addClass(this._triggerClass). 6966 html(!buttonImage ? buttonText : $("<img/>").attr( 6967 { src:buttonImage, alt:buttonText, title:buttonText }))); 6968 input[isRTL ? "before" : "after"](inst.trigger); 6969 inst.trigger.click(function() { 6970 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 6971 $.datepicker._hideDatepicker(); 6972 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 6973 $.datepicker._hideDatepicker(); 6974 $.datepicker._showDatepicker(input[0]); 6975 } else { 6976 $.datepicker._showDatepicker(input[0]); 6977 } 6978 return false; 6979 }); 6980 } 6981 }, 6982 6983 /* Apply the maximum length for the date format. */ 6984 _autoSize: function(inst) { 6985 if (this._get(inst, "autoSize") && !inst.inline) { 6986 var findMax, max, maxI, i, 6987 date = new Date(2009, 12 - 1, 20), // Ensure double digits 6988 dateFormat = this._get(inst, "dateFormat"); 6989 6990 if (dateFormat.match(/[DM]/)) { 6991 findMax = function(names) { 6992 max = 0; 6993 maxI = 0; 6994 for (i = 0; i < names.length; i++) { 6995 if (names[i].length > max) { 6996 max = names[i].length; 6997 maxI = i; 6998 } 6999 } 7000 return maxI; 7001 }; 7002 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7003 "monthNames" : "monthNamesShort")))); 7004 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7005 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7006 } 7007 inst.input.attr("size", this._formatDate(inst, date).length); 7008 } 7009 }, 7010 7011 /* Attach an inline date picker to a div. */ 7012 _inlineDatepicker: function(target, inst) { 7013 var divSpan = $(target); 7014 if (divSpan.hasClass(this.markerClassName)) { 7015 return; 7016 } 7017 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7018 $.data(target, PROP_NAME, inst); 7019 this._setDate(inst, this._getDefaultDate(inst), true); 7020 this._updateDatepicker(inst); 7021 this._updateAlternate(inst); 7022 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7023 if( inst.settings.disabled ) { 7024 this._disableDatepicker( target ); 7025 } 7026 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7027 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7028 inst.dpDiv.css( "display", "block" ); 7029 }, 7030 7031 /* Pop-up the date picker in a "dialog" box. 7032 * @param input element - ignored 7033 * @param date string or Date - the initial date to display 7034 * @param onSelect function - the function to call when a date is selected 7035 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7036 * @param pos int[2] - coordinates for the dialog's position within the screen or 7037 * event - with x/y coordinates or 7038 * leave empty for default (screen centre) 7039 * @return the manager object 7040 */ 7041 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7042 var id, browserWidth, browserHeight, scrollX, scrollY, 7043 inst = this._dialogInst; // internal instance 7044 7045 if (!inst) { 7046 this.uuid += 1; 7047 id = "dp" + this.uuid; 7048 this._dialogInput = $("<input type='text' id='" + id + 7049 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7050 this._dialogInput.keydown(this._doKeyDown); 7051 $("body").append(this._dialogInput); 7052 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7053 inst.settings = {}; 7054 $.data(this._dialogInput[0], PROP_NAME, inst); 7055 } 7056 extendRemove(inst.settings, settings || {}); 7057 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7058 this._dialogInput.val(date); 7059 7060 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7061 if (!this._pos) { 7062 browserWidth = document.documentElement.clientWidth; 7063 browserHeight = document.documentElement.clientHeight; 7064 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7065 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7066 this._pos = // should use actual width/height below 7067 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7068 } 7069 7070 // move input on screen for focus, but hidden behind dialog 7071 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7072 inst.settings.onSelect = onSelect; 7073 this._inDialog = true; 7074 this.dpDiv.addClass(this._dialogClass); 7075 this._showDatepicker(this._dialogInput[0]); 7076 if ($.blockUI) { 7077 $.blockUI(this.dpDiv); 7078 } 7079 $.data(this._dialogInput[0], PROP_NAME, inst); 7080 return this; 7081 }, 7082 7083 /* Detach a datepicker from its control. 7084 * @param target element - the target input field or division or span 7085 */ 7086 _destroyDatepicker: function(target) { 7087 var nodeName, 7088 $target = $(target), 7089 inst = $.data(target, PROP_NAME); 7090 7091 if (!$target.hasClass(this.markerClassName)) { 7092 return; 7093 } 7094 7095 nodeName = target.nodeName.toLowerCase(); 7096 $.removeData(target, PROP_NAME); 7097 if (nodeName === "input") { 7098 inst.append.remove(); 7099 inst.trigger.remove(); 7100 $target.removeClass(this.markerClassName). 7101 unbind("focus", this._showDatepicker). 7102 unbind("keydown", this._doKeyDown). 7103 unbind("keypress", this._doKeyPress). 7104 unbind("keyup", this._doKeyUp); 7105 } else if (nodeName === "div" || nodeName === "span") { 7106 $target.removeClass(this.markerClassName).empty(); 7107 } 7108 }, 7109 7110 /* Enable the date picker to a jQuery selection. 7111 * @param target element - the target input field or division or span 7112 */ 7113 _enableDatepicker: function(target) { 7114 var nodeName, inline, 7115 $target = $(target), 7116 inst = $.data(target, PROP_NAME); 7117 7118 if (!$target.hasClass(this.markerClassName)) { 7119 return; 7120 } 7121 7122 nodeName = target.nodeName.toLowerCase(); 7123 if (nodeName === "input") { 7124 target.disabled = false; 7125 inst.trigger.filter("button"). 7126 each(function() { this.disabled = false; }).end(). 7127 filter("img").css({opacity: "1.0", cursor: ""}); 7128 } else if (nodeName === "div" || nodeName === "span") { 7129 inline = $target.children("." + this._inlineClass); 7130 inline.children().removeClass("ui-state-disabled"); 7131 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7132 prop("disabled", false); 7133 } 7134 this._disabledInputs = $.map(this._disabledInputs, 7135 function(value) { return (value === target ? null : value); }); // delete entry 7136 }, 7137 7138 /* Disable the date picker to a jQuery selection. 7139 * @param target element - the target input field or division or span 7140 */ 7141 _disableDatepicker: function(target) { 7142 var nodeName, inline, 7143 $target = $(target), 7144 inst = $.data(target, PROP_NAME); 7145 7146 if (!$target.hasClass(this.markerClassName)) { 7147 return; 7148 } 7149 7150 nodeName = target.nodeName.toLowerCase(); 7151 if (nodeName === "input") { 7152 target.disabled = true; 7153 inst.trigger.filter("button"). 7154 each(function() { this.disabled = true; }).end(). 7155 filter("img").css({opacity: "0.5", cursor: "default"}); 7156 } else if (nodeName === "div" || nodeName === "span") { 7157 inline = $target.children("." + this._inlineClass); 7158 inline.children().addClass("ui-state-disabled"); 7159 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7160 prop("disabled", true); 7161 } 7162 this._disabledInputs = $.map(this._disabledInputs, 7163 function(value) { return (value === target ? null : value); }); // delete entry 7164 this._disabledInputs[this._disabledInputs.length] = target; 7165 }, 7166 7167 /* Is the first field in a jQuery collection disabled as a datepicker? 7168 * @param target element - the target input field or division or span 7169 * @return boolean - true if disabled, false if enabled 7170 */ 7171 _isDisabledDatepicker: function(target) { 7172 if (!target) { 7173 return false; 7174 } 7175 for (var i = 0; i < this._disabledInputs.length; i++) { 7176 if (this._disabledInputs[i] === target) { 7177 return true; 7178 } 7179 } 7180 return false; 7181 }, 7182 7183 /* Retrieve the instance data for the target control. 7184 * @param target element - the target input field or division or span 7185 * @return object - the associated instance data 7186 * @throws error if a jQuery problem getting data 7187 */ 7188 _getInst: function(target) { 7189 try { 7190 return $.data(target, PROP_NAME); 7191 } 7192 catch (err) { 7193 throw "Missing instance data for this datepicker"; 7194 } 7195 }, 7196 7197 /* Update or retrieve the settings for a date picker attached to an input field or division. 7198 * @param target element - the target input field or division or span 7199 * @param name object - the new settings to update or 7200 * string - the name of the setting to change or retrieve, 7201 * when retrieving also "all" for all instance settings or 7202 * "defaults" for all global defaults 7203 * @param value any - the new value for the setting 7204 * (omit if above is an object or to retrieve a value) 7205 */ 7206 _optionDatepicker: function(target, name, value) { 7207 var settings, date, minDate, maxDate, 7208 inst = this._getInst(target); 7209 7210 if (arguments.length === 2 && typeof name === "string") { 7211 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 7212 (inst ? (name === "all" ? $.extend({}, inst.settings) : 7213 this._get(inst, name)) : null)); 7214 } 7215 7216 settings = name || {}; 7217 if (typeof name === "string") { 7218 settings = {}; 7219 settings[name] = value; 7220 } 7221 7222 if (inst) { 7223 if (this._curInst === inst) { 7224 this._hideDatepicker(); 7225 } 7226 7227 date = this._getDateDatepicker(target, true); 7228 minDate = this._getMinMaxDate(inst, "min"); 7229 maxDate = this._getMinMaxDate(inst, "max"); 7230 extendRemove(inst.settings, settings); 7231 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7232 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 7233 inst.settings.minDate = this._formatDate(inst, minDate); 7234 } 7235 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 7236 inst.settings.maxDate = this._formatDate(inst, maxDate); 7237 } 7238 if ( "disabled" in settings ) { 7239 if ( settings.disabled ) { 7240 this._disableDatepicker(target); 7241 } else { 7242 this._enableDatepicker(target); 7243 } 7244 } 7245 this._attachments($(target), inst); 7246 this._autoSize(inst); 7247 this._setDate(inst, date); 7248 this._updateAlternate(inst); 7249 this._updateDatepicker(inst); 7250 } 7251 }, 7252 7253 // change method deprecated 7254 _changeDatepicker: function(target, name, value) { 7255 this._optionDatepicker(target, name, value); 7256 }, 7257 7258 /* Redraw the date picker attached to an input field or division. 7259 * @param target element - the target input field or division or span 7260 */ 7261 _refreshDatepicker: function(target) { 7262 var inst = this._getInst(target); 7263 if (inst) { 7264 this._updateDatepicker(inst); 7265 } 7266 }, 7267 7268 /* Set the dates for a jQuery selection. 7269 * @param target element - the target input field or division or span 7270 * @param date Date - the new date 7271 */ 7272 _setDateDatepicker: function(target, date) { 7273 var inst = this._getInst(target); 7274 if (inst) { 7275 this._setDate(inst, date); 7276 this._updateDatepicker(inst); 7277 this._updateAlternate(inst); 7278 } 7279 }, 7280 7281 /* Get the date(s) for the first entry in a jQuery selection. 7282 * @param target element - the target input field or division or span 7283 * @param noDefault boolean - true if no default date is to be used 7284 * @return Date - the current date 7285 */ 7286 _getDateDatepicker: function(target, noDefault) { 7287 var inst = this._getInst(target); 7288 if (inst && !inst.inline) { 7289 this._setDateFromField(inst, noDefault); 7290 } 7291 return (inst ? this._getDate(inst) : null); 7292 }, 7293 7294 /* Handle keystrokes. */ 7295 _doKeyDown: function(event) { 7296 var onSelect, dateStr, sel, 7297 inst = $.datepicker._getInst(event.target), 7298 handled = true, 7299 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 7300 7301 inst._keyEvent = true; 7302 if ($.datepicker._datepickerShowing) { 7303 switch (event.keyCode) { 7304 case 9: $.datepicker._hideDatepicker(); 7305 handled = false; 7306 break; // hide on tab out 7307 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 7308 $.datepicker._currentClass + ")", inst.dpDiv); 7309 if (sel[0]) { 7310 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 7311 } 7312 7313 onSelect = $.datepicker._get(inst, "onSelect"); 7314 if (onSelect) { 7315 dateStr = $.datepicker._formatDate(inst); 7316 7317 // trigger custom callback 7318 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 7319 } else { 7320 $.datepicker._hideDatepicker(); 7321 } 7322 7323 return false; // don't submit the form 7324 case 27: $.datepicker._hideDatepicker(); 7325 break; // hide on escape 7326 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7327 -$.datepicker._get(inst, "stepBigMonths") : 7328 -$.datepicker._get(inst, "stepMonths")), "M"); 7329 break; // previous month/year on page up/+ ctrl 7330 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7331 +$.datepicker._get(inst, "stepBigMonths") : 7332 +$.datepicker._get(inst, "stepMonths")), "M"); 7333 break; // next month/year on page down/+ ctrl 7334 case 35: if (event.ctrlKey || event.metaKey) { 7335 $.datepicker._clearDate(event.target); 7336 } 7337 handled = event.ctrlKey || event.metaKey; 7338 break; // clear on ctrl or command +end 7339 case 36: if (event.ctrlKey || event.metaKey) { 7340 $.datepicker._gotoToday(event.target); 7341 } 7342 handled = event.ctrlKey || event.metaKey; 7343 break; // current on ctrl or command +home 7344 case 37: if (event.ctrlKey || event.metaKey) { 7345 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 7346 } 7347 handled = event.ctrlKey || event.metaKey; 7348 // -1 day on ctrl or command +left 7349 if (event.originalEvent.altKey) { 7350 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7351 -$.datepicker._get(inst, "stepBigMonths") : 7352 -$.datepicker._get(inst, "stepMonths")), "M"); 7353 } 7354 // next month/year on alt +left on Mac 7355 break; 7356 case 38: if (event.ctrlKey || event.metaKey) { 7357 $.datepicker._adjustDate(event.target, -7, "D"); 7358 } 7359 handled = event.ctrlKey || event.metaKey; 7360 break; // -1 week on ctrl or command +up 7361 case 39: if (event.ctrlKey || event.metaKey) { 7362 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 7363 } 7364 handled = event.ctrlKey || event.metaKey; 7365 // +1 day on ctrl or command +right 7366 if (event.originalEvent.altKey) { 7367 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7368 +$.datepicker._get(inst, "stepBigMonths") : 7369 +$.datepicker._get(inst, "stepMonths")), "M"); 7370 } 7371 // next month/year on alt +right 7372 break; 7373 case 40: if (event.ctrlKey || event.metaKey) { 7374 $.datepicker._adjustDate(event.target, +7, "D"); 7375 } 7376 handled = event.ctrlKey || event.metaKey; 7377 break; // +1 week on ctrl or command +down 7378 default: handled = false; 7379 } 7380 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 7381 $.datepicker._showDatepicker(this); 7382 } else { 7383 handled = false; 7384 } 7385 7386 if (handled) { 7387 event.preventDefault(); 7388 event.stopPropagation(); 7389 } 7390 }, 7391 7392 /* Filter entered characters - based on date format. */ 7393 _doKeyPress: function(event) { 7394 var chars, chr, 7395 inst = $.datepicker._getInst(event.target); 7396 7397 if ($.datepicker._get(inst, "constrainInput")) { 7398 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 7399 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 7400 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 7401 } 7402 }, 7403 7404 /* Synchronise manual entry and field/alternate field. */ 7405 _doKeyUp: function(event) { 7406 var date, 7407 inst = $.datepicker._getInst(event.target); 7408 7409 if (inst.input.val() !== inst.lastVal) { 7410 try { 7411 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 7412 (inst.input ? inst.input.val() : null), 7413 $.datepicker._getFormatConfig(inst)); 7414 7415 if (date) { // only if valid 7416 $.datepicker._setDateFromField(inst); 7417 $.datepicker._updateAlternate(inst); 7418 $.datepicker._updateDatepicker(inst); 7419 } 7420 } 7421 catch (err) { 7422 } 7423 } 7424 return true; 7425 }, 7426 7427 /* Pop-up the date picker for a given input field. 7428 * If false returned from beforeShow event handler do not show. 7429 * @param input element - the input field attached to the date picker or 7430 * event - if triggered by focus 7431 */ 7432 _showDatepicker: function(input) { 7433 input = input.target || input; 7434 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 7435 input = $("input", input.parentNode)[0]; 7436 } 7437 7438 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 7439 return; 7440 } 7441 7442 var inst, beforeShow, beforeShowSettings, isFixed, 7443 offset, showAnim, duration; 7444 7445 inst = $.datepicker._getInst(input); 7446 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 7447 $.datepicker._curInst.dpDiv.stop(true, true); 7448 if ( inst && $.datepicker._datepickerShowing ) { 7449 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 7450 } 7451 } 7452 7453 beforeShow = $.datepicker._get(inst, "beforeShow"); 7454 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7455 if(beforeShowSettings === false){ 7456 return; 7457 } 7458 extendRemove(inst.settings, beforeShowSettings); 7459 7460 inst.lastVal = null; 7461 $.datepicker._lastInput = input; 7462 $.datepicker._setDateFromField(inst); 7463 7464 if ($.datepicker._inDialog) { // hide cursor 7465 input.value = ""; 7466 } 7467 if (!$.datepicker._pos) { // position below input 7468 $.datepicker._pos = $.datepicker._findPos(input); 7469 $.datepicker._pos[1] += input.offsetHeight; // add the height 7470 } 7471 7472 isFixed = false; 7473 $(input).parents().each(function() { 7474 isFixed |= $(this).css("position") === "fixed"; 7475 return !isFixed; 7476 }); 7477 7478 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 7479 $.datepicker._pos = null; 7480 //to avoid flashes on Firefox 7481 inst.dpDiv.empty(); 7482 // determine sizing offscreen 7483 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 7484 $.datepicker._updateDatepicker(inst); 7485 // fix width for dynamic number of date pickers 7486 // and adjust position before showing 7487 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7488 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 7489 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 7490 left: offset.left + "px", top: offset.top + "px"}); 7491 7492 if (!inst.inline) { 7493 showAnim = $.datepicker._get(inst, "showAnim"); 7494 duration = $.datepicker._get(inst, "duration"); 7495 inst.dpDiv.zIndex($(input).zIndex()+1); 7496 $.datepicker._datepickerShowing = true; 7497 7498 if ( $.effects && $.effects.effect[ showAnim ] ) { 7499 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 7500 } else { 7501 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 7502 } 7503 7504 if (
vendor: 1,611 bytes, lines 7504-7545
7504inst.input.is(":visible") && !inst.input.is(":disabled")) { 7505 inst.input.focus(); 7506 } 7507 $.datepicker._curInst = inst; 7508 } 7509 }, 7510 7511 /* Generate the date picker content. */ 7512 _updateDatepicker: function(inst) { 7513 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 7514 instActive = inst; // for delegate hover events 7515 inst.dpDiv.empty().append(this._generateHTML(inst)); 7516 this._attachHandlers(inst); 7517 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 7518 7519 var origyearshtml, 7520 numMonths = this._getNumberOfMonths(inst), 7521 cols = numMonths[1], 7522 width = 17; 7523 7524 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 7525 if (cols > 1) { 7526 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 7527 } 7528 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 7529 "Class"]("ui-datepicker-multi"); 7530 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 7531 "Class"]("ui-datepicker-rtl"); 7532 7533 // #6694 - don't focus the input if it's already focused 7534 // this breaks the change event in IE 7535 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 7536 inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) { 7537 inst.input.focus(); 7538 } 7539 7540 // deffered render of the years select (to avoid flashes on Firefox) 7541 if( inst.yearshtml ){ 7542 origyearshtml = inst.yearshtml; 7543 setTimeout(function(){ 7544 //assure that inst.yearshtml didn't change. 7545 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7546 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 7547 } 7548 origyearshtml = inst.yearshtml = null; 7549 }, 0); 7550 } 7551 }, 7552 7553 /* Retrieve the size of left and top borders for an element. 7554 * @param elem (jQuery object) the element of interest 7555 * @return (number[2]) the left and top borders 7556 */ 7557 _getBorders: function(elem) { 7558 var convert = function(value) { 7559 return {thin: 1, medium: 2, thick: 3}[value] || value; 7560 }; 7561 return [parseFloat(convert(elem.css("border-left-width"))), 7562 parseFloat(convert(elem.css("border-top-width")))]
vendor: 23,574 bytes, lines 7562-8309
7562; 7563 }, 7564 7565 /* Check positioning to remain on screen. */ 7566 _checkOffset: function(inst, offset, isFixed) { 7567 var dpWidth = inst.dpDiv.outerWidth(), 7568 dpHeight = inst.dpDiv.outerHeight(), 7569 inputWidth = inst.input ? inst.input.outerWidth() : 0, 7570 inputHeight = inst.input ? inst.input.outerHeight() : 0, 7571 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 7572 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 7573 7574 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 7575 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 7576 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 7577 7578 // now check if datepicker is showing outside window viewport - move to a better place if so. 7579 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 7580 Math.abs(offset.left + dpWidth - viewWidth) : 0); 7581 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 7582 Math.abs(dpHeight + inputHeight) : 0); 7583 7584 return offset; 7585 }, 7586 7587 /* Find an object's position on the screen. */ 7588 _findPos: function(obj) { 7589 var position, 7590 inst = this._getInst(obj), 7591 isRTL = this._get(inst, "isRTL"); 7592 7593 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 7594 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 7595 } 7596 7597 position = $(obj).offset(); 7598 return [position.left, position.top]; 7599 }, 7600 7601 /* Hide the date picker from view. 7602 * @param input element - the input field attached to the date picker 7603 */ 7604 _hideDatepicker: function(input) { 7605 var showAnim, duration, postProcess, onClose, 7606 inst = this._curInst; 7607 7608 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 7609 return; 7610 } 7611 7612 if (this._datepickerShowing) { 7613 showAnim = this._get(inst, "showAnim"); 7614 duration = this._get(inst, "duration"); 7615 postProcess = function() { 7616 $.datepicker._tidyDialog(inst); 7617 }; 7618 7619 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 7620 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 7621 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 7622 } else { 7623 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 7624 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 7625 } 7626 7627 if (!showAnim) { 7628 postProcess(); 7629 } 7630 this._datepickerShowing = false; 7631 7632 onClose = this._get(inst, "onClose"); 7633 if (onClose) { 7634 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 7635 } 7636 7637 this._lastInput = null; 7638 if (this._inDialog) { 7639 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 7640 if ($.blockUI) { 7641 $.unblockUI(); 7642 $("body").append(this.dpDiv); 7643 } 7644 } 7645 this._inDialog = false; 7646 } 7647 }, 7648 7649 /* Tidy up after a dialog display. */ 7650 _tidyDialog: function(inst) { 7651 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 7652 }, 7653 7654 /* Close date picker if clicked elsewhere. */ 7655 _checkExternalClick: function(event) { 7656 if (!$.datepicker._curInst) { 7657 return; 7658 } 7659 7660 var $target = $(event.target), 7661 inst = $.datepicker._getInst($target[0]); 7662 7663 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 7664 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 7665 !$target.hasClass($.datepicker.markerClassName) && 7666 !$target.closest("." + $.datepicker._triggerClass).length && 7667 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 7668 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 7669 $.datepicker._hideDatepicker(); 7670 } 7671 }, 7672 7673 /* Adjust one of the date sub-fields. */ 7674 _adjustDate: function(id, offset, period) { 7675 var target = $(id), 7676 inst = this._getInst(target[0]); 7677 7678 if (this._isDisabledDatepicker(target[0])) { 7679 return; 7680 } 7681 this._adjustInstDate(inst, offset + 7682 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 7683 period); 7684 this._updateDatepicker(inst); 7685 }, 7686 7687 /* Action for current link. */ 7688 _gotoToday: function(id) { 7689 var date, 7690 target = $(id), 7691 inst = this._getInst(target[0]); 7692 7693 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 7694 inst.selectedDay = inst.currentDay; 7695 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 7696 inst.drawYear = inst.selectedYear = inst.currentYear; 7697 } else { 7698 date = new Date(); 7699 inst.selectedDay = date.getDate(); 7700 inst.drawMonth = inst.selectedMonth = date.getMonth(); 7701 inst.drawYear = inst.selectedYear = date.getFullYear(); 7702 } 7703 this._notifyChange(inst); 7704 this._adjustDate(target); 7705 }, 7706 7707 /* Action for selecting a new month/year. */ 7708 _selectMonthYear: function(id, select, period) { 7709 var target = $(id), 7710 inst = this._getInst(target[0]); 7711 7712 inst["selected" + (period === "M" ? "Month" : "Year")] = 7713 inst["draw" + (period === "M" ? "Month" : "Year")] = 7714 parseInt(select.options[select.selectedIndex].value,10); 7715 7716 this._notifyChange(inst); 7717 this._adjustDate(target); 7718 }, 7719 7720 /* Action for selecting a day. */ 7721 _selectDay: function(id, month, year, td) { 7722 var inst, 7723 target = $(id); 7724 7725 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 7726 return; 7727 } 7728 7729 inst = this._getInst(target[0]); 7730 inst.selectedDay = inst.currentDay = $("a", td).html(); 7731 inst.selectedMonth = inst.currentMonth = month; 7732 inst.selectedYear = inst.currentYear = year; 7733 this._selectDate(id, this._formatDate(inst, 7734 inst.currentDay, inst.currentMonth, inst.currentYear)); 7735 }, 7736 7737 /* Erase the input field and hide the date picker. */ 7738 _clearDate: function(id) { 7739 var target = $(id); 7740 this._selectDate(target, ""); 7741 }, 7742 7743 /* Update the input field with the selected date. */ 7744 _selectDate: function(id, dateStr) { 7745 var onSelect, 7746 target = $(id), 7747 inst = this._getInst(target[0]); 7748 7749 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 7750 if (inst.input) { 7751 inst.input.val(dateStr); 7752 } 7753 this._updateAlternate(inst); 7754 7755 onSelect = this._get(inst, "onSelect"); 7756 if (onSelect) { 7757 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 7758 } else if (inst.input) { 7759 inst.input.trigger("change"); // fire the change event 7760 } 7761 7762 if (inst.inline){ 7763 this._updateDatepicker(inst); 7764 } else { 7765 this._hideDatepicker(); 7766 this._lastInput = inst.input[0]; 7767 if (typeof(inst.input[0]) !== "object") { 7768 inst.input.focus(); // restore focus 7769 } 7770 this._lastInput = null; 7771 } 7772 }, 7773 7774 /* Update any alternate field to synchronise with the main field. */ 7775 _updateAlternate: function(inst) { 7776 var altFormat, date, dateStr, 7777 altField = this._get(inst, "altField"); 7778 7779 if (altField) { // update alternate field too 7780 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 7781 date = this._getDate(inst); 7782 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 7783 $(altField).each(function() { $(this).val(dateStr); }); 7784 } 7785 }, 7786 7787 /* Set as beforeShowDay function to prevent selection of weekends. 7788 * @param date Date - the date to customise 7789 * @return [boolean, string] - is this date selectable?, what is its CSS class? 7790 */ 7791 noWeekends: function(date) { 7792 var day = date.getDay(); 7793 return [(day > 0 && day < 6), ""]; 7794 }, 7795 7796 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 7797 * @param date Date - the date to get the week for 7798 * @return number - the number of the week within the year that contains this date 7799 */ 7800 iso8601Week: function(date) { 7801 var time, 7802 checkDate = new Date(date.getTime()); 7803 7804 // Find Thursday of this week starting on Monday 7805 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 7806 7807 time = checkDate.getTime(); 7808 checkDate.setMonth(0); // Compare with Jan 1 7809 checkDate.setDate(1); 7810 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 7811 }, 7812 7813 /* Parse a string value into a date object. 7814 * See formatDate below for the possible formats. 7815 * 7816 * @param format string - the expected format of the date 7817 * @param value string - the date in the above format 7818 * @param settings Object - attributes include: 7819 * shortYearCutoff number - the cutoff year for determining the century (optional) 7820 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 7821 * dayNames string[7] - names of the days from Sunday (optional) 7822 * monthNamesShort string[12] - abbreviated names of the months (optional) 7823 * monthNames string[12] - names of the months (optional) 7824 * @return Date - the extracted date value or null if value is blank 7825 */ 7826 parseDate: function (format, value, settings) { 7827 if (format == null || value == null) { 7828 throw "Invalid arguments"; 7829 } 7830 7831 value = (typeof value === "object" ? value.toString() : value + ""); 7832 if (value === "") { 7833 return null; 7834 } 7835 7836 var iFormat, dim, extra, 7837 iValue = 0, 7838 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 7839 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 7840 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 7841 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 7842 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 7843 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 7844 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 7845 year = -1, 7846 month = -1, 7847 day = -1, 7848 doy = -1, 7849 literal = false, 7850 date, 7851 // Check whether a format character is doubled 7852 lookAhead = function(match) { 7853 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 7854 if (matches) { 7855 iFormat++; 7856 } 7857 return matches; 7858 }, 7859 // Extract a number from the string value 7860 getNumber = function(match) { 7861 var isDoubled = lookAhead(match), 7862 size = (match === "@" ? 14 : (match === "!" ? 20 : 7863 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 7864 digits = new RegExp("^\\d{1," + size + "}"), 7865 num = value.substring(iValue).match(digits); 7866 if (!num) { 7867 throw "Missing number at position " + iValue; 7868 } 7869 iValue += num[0].length; 7870 return parseInt(num[0], 10); 7871 }, 7872 // Extract a name from the string value and convert to an index 7873 getName = function(match, shortNames, longNames) { 7874 var index = -1, 7875 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 7876 return [ [k, v] ]; 7877 }).sort(function (a, b) { 7878 return -(a[1].length - b[1].length); 7879 }); 7880 7881 $.each(names, function (i, pair) { 7882 var name = pair[1]; 7883 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 7884 index = pair[0]; 7885 iValue += name.length; 7886 return false; 7887 } 7888 }); 7889 if (index !== -1) { 7890 return index + 1; 7891 } else { 7892 throw "Unknown name at position " + iValue; 7893 } 7894 }, 7895 // Confirm that a literal character matches the string value 7896 checkLiteral = function() { 7897 if (value.charAt(iValue) !== format.charAt(iFormat)) { 7898 throw "Unexpected literal at position " + iValue; 7899 } 7900 iValue++; 7901 }; 7902 7903 for (iFormat = 0; iFormat < format.length; iFormat++) { 7904 if (literal) { 7905 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 7906 literal = false; 7907 } else { 7908 checkLiteral(); 7909 } 7910 } else { 7911 switch (format.charAt(iFormat)) { 7912 case "d": 7913 day = getNumber("d"); 7914 break; 7915 case "D": 7916 getName("D", dayNamesShort, dayNames); 7917 break; 7918 case "o": 7919 doy = getNumber("o"); 7920 break; 7921 case "m": 7922 month = getNumber("m"); 7923 break; 7924 case "M": 7925 month = getName("M", monthNamesShort, monthNames); 7926 break; 7927 case "y": 7928 year = getNumber("y"); 7929 break; 7930 case "@": 7931 date = new Date(getNumber("@")); 7932 year = date.getFullYear(); 7933 month = date.getMonth() + 1; 7934 day = date.getDate(); 7935 break; 7936 case "!": 7937 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 7938 year = date.getFullYear(); 7939 month = date.getMonth() + 1; 7940 day = date.getDate(); 7941 break; 7942 case "'": 7943 if (lookAhead("'")){ 7944 checkLiteral(); 7945 } else { 7946 literal = true; 7947 } 7948 break; 7949 default: 7950 checkLiteral(); 7951 } 7952 } 7953 } 7954 7955 if (iValue < value.length){ 7956 extra = value.substr(iValue); 7957 if (!/^\s+/.test(extra)) { 7958 throw "Extra/unparsed characters found in date: " + extra; 7959 } 7960 } 7961 7962 if (year === -1) { 7963 year = new Date().getFullYear(); 7964 } else if (year < 100) { 7965 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 7966 (year <= shortYearCutoff ? 0 : -100); 7967 } 7968 7969 if (doy > -1) { 7970 month = 1; 7971 day = doy; 7972 do { 7973 dim = this._getDaysInMonth(year, month - 1); 7974 if (day <= dim) { 7975 break; 7976 } 7977 month++; 7978 day -= dim; 7979 } while (true); 7980 } 7981 7982 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 7983 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 7984 throw "Invalid date"; // E.g. 31/02/00 7985 } 7986 return date; 7987 }, 7988 7989 /* Standard date formats. */ 7990 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 7991 COOKIE: "D, dd M yy", 7992 ISO_8601: "yy-mm-dd", 7993 RFC_822: "D, d M y", 7994 RFC_850: "DD, dd-M-y", 7995 RFC_1036: "D, d M y", 7996 RFC_1123: "D, d M yy", 7997 RFC_2822: "D, d M yy", 7998 RSS: "D, d M y", // RFC 822 7999 TICKS: "!", 8000 TIMESTAMP: "@", 8001 W3C: "yy-mm-dd", // ISO 8601 8002 8003 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8004 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8005 8006 /* Format a date object into a string value. 8007 * The format can be combinations of the following: 8008 * d - day of month (no leading zero) 8009 * dd - day of month (two digit) 8010 * o - day of year (no leading zeros) 8011 * oo - day of year (three digit) 8012 * D - day name short 8013 * DD - day name long 8014 * m - month of year (no leading zero) 8015 * mm - month of year (two digit) 8016 * M - month name short 8017 * MM - month name long 8018 * y - year (two digit) 8019 * yy - year (four digit) 8020 * @ - Unix timestamp (ms since 01/01/1970) 8021 * ! - Windows ticks (100ns since 01/01/0001) 8022 * "..." - literal text 8023 * '' - single quote 8024 * 8025 * @param format string - the desired format of the date 8026 * @param date Date - the date value to format 8027 * @param settings Object - attributes include: 8028 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8029 * dayNames string[7] - names of the days from Sunday (optional) 8030 * monthNamesShort string[12] - abbreviated names of the months (optional) 8031 * monthNames string[12] - names of the months (optional) 8032 * @return string - the date in the above format 8033 */ 8034 formatDate: function (format, date, settings) { 8035 if (!date) { 8036 return ""; 8037 } 8038 8039 var iFormat, 8040 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8041 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8042 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8043 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8044 // Check whether a format character is doubled 8045 lookAhead = function(match) { 8046 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8047 if (matches) { 8048 iFormat++; 8049 } 8050 return matches; 8051 }, 8052 // Format a number, with leading zero if necessary 8053 formatNumber = function(match, value, len) { 8054 var num = "" + value; 8055 if (lookAhead(match)) { 8056 while (num.length < len) { 8057 num = "0" + num; 8058 } 8059 } 8060 return num; 8061 }, 8062 // Format a name, short or long as requested 8063 formatName = function(match, value, shortNames, longNames) { 8064 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8065 }, 8066 output = "", 8067 literal = false; 8068 8069 if (date) { 8070 for (iFormat = 0; iFormat < format.length; iFormat++) { 8071 if (literal) { 8072 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8073 literal = false; 8074 } else { 8075 output += format.charAt(iFormat); 8076 } 8077 } else { 8078 switch (format.charAt(iFormat)) { 8079 case "d": 8080 output += formatNumber("d", date.getDate(), 2); 8081 break; 8082 case "D": 8083 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8084 break; 8085 case "o": 8086 output += formatNumber("o", 8087 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8088 break; 8089 case "m": 8090 output += formatNumber("m", date.getMonth() + 1, 2); 8091 break; 8092 case "M": 8093 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8094 break; 8095 case "y": 8096 output += (lookAhead("y") ? date.getFullYear() : 8097 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8098 break; 8099 case "@": 8100 output += date.getTime(); 8101 break; 8102 case "!": 8103 output += date.getTime() * 10000 + this._ticksTo1970; 8104 break; 8105 case "'": 8106 if (lookAhead("'")) { 8107 output += "'"; 8108 } else { 8109 literal = true; 8110 } 8111 break; 8112 default: 8113 output += format.charAt(iFormat); 8114 } 8115 } 8116 } 8117 } 8118 return output; 8119 }, 8120 8121 /* Extract all possible characters from the date format. */ 8122 _possibleChars: function (format) { 8123 var iFormat, 8124 chars = "", 8125 literal = false, 8126 // Check whether a format character is doubled 8127 lookAhead = function(match) { 8128 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8129 if (matches) { 8130 iFormat++; 8131 } 8132 return matches; 8133 }; 8134 8135 for (iFormat = 0; iFormat < format.length; iFormat++) { 8136 if (literal) { 8137 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8138 literal = false; 8139 } else { 8140 chars += format.charAt(iFormat); 8141 } 8142 } else { 8143 switch (format.charAt(iFormat)) { 8144 case "d": case "m": case "y": case "@": 8145 chars += "0123456789"; 8146 break; 8147 case "D": case "M": 8148 return null; // Accept anything 8149 case "'": 8150 if (lookAhead("'")) { 8151 chars += "'"; 8152 } else { 8153 literal = true; 8154 } 8155 break; 8156 default: 8157 chars += format.charAt(iFormat); 8158 } 8159 } 8160 } 8161 return chars; 8162 }, 8163 8164 /* Get a setting value, defaulting if necessary. */ 8165 _get: function(inst, name) { 8166 return inst.settings[name] !== undefined ? 8167 inst.settings[name] : this._defaults[name]; 8168 }, 8169 8170 /* Parse existing date and initialise date picker. */ 8171 _setDateFromField: function(inst, noDefault) { 8172 if (inst.input.val() === inst.lastVal) { 8173 return; 8174 } 8175 8176 var dateFormat = this._get(inst, "dateFormat"), 8177 dates = inst.lastVal = inst.input ? inst.input.val() : null, 8178 defaultDate = this._getDefaultDate(inst), 8179 date = defaultDate, 8180 settings = this._getFormatConfig(inst); 8181 8182 try { 8183 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8184 } catch (event) { 8185 dates = (noDefault ? "" : dates); 8186 } 8187 inst.selectedDay = date.getDate(); 8188 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8189 inst.drawYear = inst.selectedYear = date.getFullYear(); 8190 inst.currentDay = (dates ? date.getDate() : 0); 8191 inst.currentMonth = (dates ? date.getMonth() : 0); 8192 inst.currentYear = (dates ? date.getFullYear() : 0); 8193 this._adjustInstDate(inst); 8194 }, 8195 8196 /* Retrieve the default date shown on opening. */ 8197 _getDefaultDate: function(inst) { 8198 return this._restrictMinMax(inst, 8199 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 8200 }, 8201 8202 /* A date may be specified as an exact value or a relative one. */ 8203 _determineDate: function(inst, date, defaultDate) { 8204 var offsetNumeric = function(offset) { 8205 var date = new Date(); 8206 date.setDate(date.getDate() + offset); 8207 return date; 8208 }, 8209 offsetString = function(offset) { 8210 try { 8211 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8212 offset, $.datepicker._getFormatConfig(inst)); 8213 } 8214 catch (e) { 8215 // Ignore 8216 } 8217 8218 var date = (offset.toLowerCase().match(/^c/) ? 8219 $.datepicker._getDate(inst) : null) || new Date(), 8220 year = date.getFullYear(), 8221 month = date.getMonth(), 8222 day = date.getDate(), 8223 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 8224 matches = pattern.exec(offset); 8225 8226 while (matches) { 8227 switch (matches[2] || "d") { 8228 case "d" : case "D" : 8229 day += parseInt(matches[1],10); break; 8230 case "w" : case "W" : 8231 day += parseInt(matches[1],10) * 7; break; 8232 case "m" : case "M" : 8233 month += parseInt(matches[1],10); 8234 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8235 break; 8236 case "y": case "Y" : 8237 year += parseInt(matches[1],10); 8238 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8239 break; 8240 } 8241 matches = pattern.exec(offset); 8242 } 8243 return new Date(year, month, day); 8244 }, 8245 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 8246 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 8247 8248 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 8249 if (newDate) { 8250 newDate.setHours(0); 8251 newDate.setMinutes(0); 8252 newDate.setSeconds(0); 8253 newDate.setMilliseconds(0); 8254 } 8255 return this._daylightSavingAdjust(newDate); 8256 }, 8257 8258 /* Handle switch to/from daylight saving. 8259 * Hours may be non-zero on daylight saving cut-over: 8260 * > 12 when midnight changeover, but then cannot generate 8261 * midnight datetime, so jump to 1AM, otherwise reset. 8262 * @param date (Date) the date to check 8263 * @return (Date) the corrected date 8264 */ 8265 _daylightSavingAdjust: function(date) { 8266 if (!date) { 8267 return null; 8268 } 8269 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 8270 return date; 8271 }, 8272 8273 /* Set the date(s) directly. */ 8274 _setDate: function(inst, date, noChange) { 8275 var clear = !date, 8276 origMonth = inst.selectedMonth, 8277 origYear = inst.selectedYear, 8278 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 8279 8280 inst.selectedDay = inst.currentDay = newDate.getDate(); 8281 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8282 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8283 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 8284 this._notifyChange(inst); 8285 } 8286 this._adjustInstDate(inst); 8287 if (inst.input) { 8288 inst.input.val(clear ? "" : this._formatDate(inst)); 8289 } 8290 }, 8291 8292 /* Retrieve the date(s) directly. */ 8293 _getDate: function(inst) { 8294 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 8295 this._daylightSavingAdjust(new Date( 8296 inst.currentYear, inst.currentMonth, inst.currentDay))); 8297 return startDate; 8298 }, 8299 8300 /* Attach the onxxx handlers. These are declared statically so 8301 * they work with static code transformers like Caja. 8302 */ 8303 _attachHandlers: function(inst) { 8304 var stepMonths = this._get(inst, "stepMonths"), 8305 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 8306 inst.dpDiv.find("[data-handler]").map(function () { 8307 var handler = { 8308 prev: function () { 8309
8309window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M"); 8310 }, 8311 next: function () { 8312 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M"); 8313 }, 8314 hide: function () { 8315 window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker(); 8316 }, 8317 today: function () { 8318 window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id); 8319 }, 8320 selectDay: function () { 8321 window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 8322 return false; 8323 }, 8324 selectMonth: function () { 8325 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M"); 8326 return false; 8327 }, 8328 selectYear: function () { 8329 window["DP_jQuery_" + dpuuid]
vendor: 12,158 bytes, lines 8329-8557
8329.datepicker._selectMonthYear(id, this, "Y"); 8330 return false; 8331 } 8332 }; 8333 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 8334 }); 8335 }, 8336 8337 /* Generate the HTML for the current state of the date picker. */ 8338 _generateHTML: function(inst) { 8339 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 8340 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 8341 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 8342 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 8343 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 8344 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 8345 tempDate = new Date(), 8346 today = this._daylightSavingAdjust( 8347 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 8348 isRTL = this._get(inst, "isRTL"), 8349 showButtonPanel = this._get(inst, "showButtonPanel"), 8350 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 8351 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 8352 numMonths = this._getNumberOfMonths(inst), 8353 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 8354 stepMonths = this._get(inst, "stepMonths"), 8355 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 8356 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 8357 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 8358 minDate = this._getMinMaxDate(inst, "min"), 8359 maxDate = this._getMinMaxDate(inst, "max"), 8360 drawMonth = inst.drawMonth - showCurrentAtPos, 8361 drawYear = inst.drawYear; 8362 8363 if (drawMonth < 0) { 8364 drawMonth += 12; 8365 drawYear--; 8366 } 8367 if (maxDate) { 8368 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 8369 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 8370 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 8371 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 8372 drawMonth--; 8373 if (drawMonth < 0) { 8374 drawMonth = 11; 8375 drawYear--; 8376 } 8377 } 8378 } 8379 inst.drawMonth = drawMonth; 8380 inst.drawYear = drawYear; 8381 8382 prevText = this._get(inst, "prevText"); 8383 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 8384 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 8385 this._getFormatConfig(inst))); 8386 8387 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 8388 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 8389 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 8390 (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>")); 8391 8392 nextText = this._get(inst, "nextText"); 8393 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 8394 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 8395 this._getFormatConfig(inst))); 8396 8397 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 8398 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 8399 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 8400 (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>")); 8401 8402 currentText = this._get(inst, "currentText"); 8403 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 8404 currentText = (!navigationAsDateFormat ? currentText : 8405 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 8406 8407 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'>" + 8408 this._get(inst, "closeText") + "</button>" : ""); 8409 8410 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 8411 (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'" + 8412 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 8413 8414 firstDay = parseInt(this._get(inst, "firstDay"),10); 8415 firstDay = (isNaN(firstDay) ? 0 : firstDay); 8416 8417 showWeek = this._get(inst, "showWeek"); 8418 dayNames = this._get(inst, "dayNames"); 8419 dayNamesMin = this._get(inst, "dayNamesMin"); 8420 monthNames = this._get(inst, "monthNames"); 8421 monthNamesShort = this._get(inst, "monthNamesShort"); 8422 beforeShowDay = this._get(inst, "beforeShowDay"); 8423 showOtherMonths = this._get(inst, "showOtherMonths"); 8424 selectOtherMonths = this._get(inst, "selectOtherMonths"); 8425 defaultDate = this._getDefaultDate(inst); 8426 html = ""; 8427 dow; 8428 for (row = 0; row < numMonths[0]; row++) { 8429 group = ""; 8430 this.maxRows = 4; 8431 for (col = 0; col < numMonths[1]; col++) { 8432 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 8433 cornerClass = " ui-corner-all"; 8434 calender = ""; 8435 if (isMultiMonth) { 8436 calender += "<div class='ui-datepicker-group"; 8437 if (numMonths[1] > 1) { 8438 switch (col) { 8439 case 0: calender += " ui-datepicker-group-first"; 8440 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 8441 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 8442 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 8443 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 8444 } 8445 } 8446 calender += "'>"; 8447 } 8448 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 8449 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 8450 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 8451 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 8452 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 8453 "</div><table class='ui-datepicker-calendar'><thead>" + 8454 "<tr>"; 8455 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 8456 for (dow = 0; dow < 7; dow++) { // days of the week 8457 day = (dow + firstDay) % 7; 8458 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 8459 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 8460 } 8461 calender += thead + "</tr></thead><tbody>"; 8462 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 8463 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 8464 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 8465 } 8466 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 8467 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 8468 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 8469 this.maxRows = numRows; 8470 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8471 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 8472 calender += "<tr>"; 8473 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 8474 this._get(inst, "calculateWeek")(printDate) + "</td>"); 8475 for (dow = 0; dow < 7; dow++) { // create date picker days 8476 daySettings = (beforeShowDay ? 8477 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 8478 otherMonth = (printDate.getMonth() !== drawMonth); 8479 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 8480 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 8481 tbody += "<td class='" + 8482 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 8483 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 8484 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 8485 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 8486 // or defaultDate is current printedDate and defaultDate is selectedDate 8487 " " + this._dayOverClass : "") + // highlight selected day 8488 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 8489 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 8490 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 8491 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 8492 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 8493 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 8494 (otherMonth && !showOtherMonths ? " " : // display for other months 8495 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 8496 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 8497 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 8498 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 8499 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 8500 printDate.setDate(printDate.getDate() + 1); 8501 printDate = this._daylightSavingAdjust(printDate); 8502 } 8503 calender += tbody + "</tr>"; 8504 } 8505 drawMonth++; 8506 if (drawMonth > 11) { 8507 drawMonth = 0; 8508 drawYear++; 8509 } 8510 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 8511 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 8512 group += calender; 8513 } 8514 html += group; 8515 } 8516 html += buttonPanel; 8517 inst._keyEvent = false; 8518 return html; 8519 }, 8520 8521 /* Generate the month and year header. */ 8522 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 8523 secondary, monthNames, monthNamesShort) { 8524 8525 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 8526 changeMonth = this._get(inst, "changeMonth"), 8527 changeYear = this._get(inst, "changeYear"), 8528 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 8529 html = "<div class='ui-datepicker-title'>", 8530 monthHtml = ""; 8531 8532 // month selection 8533 if (secondary || !changeMonth) { 8534 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 8535 } else { 8536 inMinYear = (minDate && minDate.getFullYear() === drawYear); 8537 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 8538 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 8539 for ( month = 0; month < 12; month++) { 8540 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 8541 monthHtml += "<option value='" + month + "'" + 8542 (month === drawMonth ? " selected='selected'" : "") + 8543 ">" + monthNamesShort[month] + "</option>"; 8544 } 8545 } 8546 monthHtml += "</select>"; 8547 } 8548 8549 if (!showMonthAfterYear) { 8550 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 8551 } 8552 8553 // year selection 8554 if ( !inst.yearshtml ) { 8555 inst.yearshtml = ""; 8556 if (secondary || !changeYear) { 8557 html += "<span class='ui-datepicker-year'>" + drawYear + "
8557å¹´
vendor: 8,716 bytes, lines 8557-8792
8557</span>"; 8558 } else { 8559 // determine range of years to display 8560 years = this._get(inst, "yearRange").split(":"); 8561 thisYear = new Date().getFullYear(); 8562 determineYear = function(value) { 8563 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 8564 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 8565 parseInt(value, 10))); 8566 return (isNaN(year) ? thisYear : year); 8567 }; 8568 year = determineYear(years[0]); 8569 endYear = Math.max(year, determineYear(years[1] || "")); 8570 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 8571 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 8572 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 8573 for (; year <= endYear; year++) { 8574 inst.yearshtml += "<option value='" + year + "'" + 8575 (year === drawYear ? " selected='selected'" : "") + 8576 ">" + year + "</option>"; 8577 } 8578 inst.yearshtml += "</select>"; 8579 8580 html += inst.yearshtml; 8581 inst.yearshtml = null; 8582 } 8583 } 8584 8585 html += this._get(inst, "yearSuffix"); 8586 if (showMonthAfterYear) { 8587 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 8588 } 8589 html += "</div>"; // Close datepicker_header 8590 return html; 8591 }, 8592 8593 /* Adjust one of the date sub-fields. */ 8594 _adjustInstDate: function(inst, offset, period) { 8595 var year = inst.drawYear + (period === "Y" ? offset : 0), 8596 month = inst.drawMonth + (period === "M" ? offset : 0), 8597 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 8598 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 8599 8600 inst.selectedDay = date.getDate(); 8601 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8602 inst.drawYear = inst.selectedYear = date.getFullYear(); 8603 if (period === "M" || period === "Y") { 8604 this._notifyChange(inst); 8605 } 8606 }, 8607 8608 /* Ensure a date is within any min/max bounds. */ 8609 _restrictMinMax: function(inst, date) { 8610 var minDate = this._getMinMaxDate(inst, "min"), 8611 maxDate = this._getMinMaxDate(inst, "max"), 8612 newDate = (minDate && date < minDate ? minDate : date); 8613 return (maxDate && newDate > maxDate ? maxDate : newDate); 8614 }, 8615 8616 /* Notify change of month/year. */ 8617 _notifyChange: function(inst) { 8618 var onChange = this._get(inst, "onChangeMonthYear"); 8619 if (onChange) { 8620 onChange.apply((inst.input ? inst.input[0] : null), 8621 [inst.selectedYear, inst.selectedMonth + 1, inst]); 8622 } 8623 }, 8624 8625 /* Determine the number of months to show. */ 8626 _getNumberOfMonths: function(inst) { 8627 var numMonths = this._get(inst, "numberOfMonths"); 8628 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 8629 }, 8630 8631 /* Determine the current maximum date - ensure no time components are set. */ 8632 _getMinMaxDate: function(inst, minMax) { 8633 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 8634 }, 8635 8636 /* Find the number of days in a given month. */ 8637 _getDaysInMonth: function(year, month) { 8638 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 8639 }, 8640 8641 /* Find the day of the week of the first of a month. */ 8642 _getFirstDayOfMonth: function(year, month) { 8643 return new Date(year, month, 1).getDay(); 8644 }, 8645 8646 /* Determines if we should allow a "next/prev" month display change. */ 8647 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 8648 var numMonths = this._getNumberOfMonths(inst), 8649 date = this._daylightSavingAdjust(new Date(curYear, 8650 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 8651 8652 if (offset < 0) { 8653 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 8654 } 8655 return this._isInRange(inst, date); 8656 }, 8657 8658 /* Is the given date in the accepted range? */ 8659 _isInRange: function(inst, date) { 8660 var yearSplit, currentYear, 8661 minDate = this._getMinMaxDate(inst, "min"), 8662 maxDate = this._getMinMaxDate(inst, "max"), 8663 minYear = null, 8664 maxYear = null, 8665 years = this._get(inst, "yearRange"); 8666 if (years){ 8667 yearSplit = years.split(":"); 8668 currentYear = new Date().getFullYear(); 8669 minYear = parseInt(yearSplit[0], 10); 8670 maxYear = parseInt(yearSplit[1], 10); 8671 if ( yearSplit[0].match(/[+\-].*/) ) { 8672 minYear += currentYear; 8673 } 8674 if ( yearSplit[1].match(/[+\-].*/) ) { 8675 maxYear += currentYear; 8676 } 8677 } 8678 8679 return ((!minDate || date.getTime() >= minDate.getTime()) && 8680 (!maxDate || date.getTime() <= maxDate.getTime()) && 8681 (!minYear || date.getFullYear() >= minYear) && 8682 (!maxYear || date.getFullYear() <= maxYear)); 8683 }, 8684 8685 /* Provide the configuration settings for formatting/parsing. */ 8686 _getFormatConfig: function(inst) { 8687 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 8688 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 8689 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 8690 return {shortYearCutoff: shortYearCutoff, 8691 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 8692 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 8693 }, 8694 8695 /* Format the given date for display. */ 8696 _formatDate: function(inst, day, month, year) { 8697 if (!day) { 8698 inst.currentDay = inst.selectedDay; 8699 inst.currentMonth = inst.selectedMonth; 8700 inst.currentYear = inst.selectedYear; 8701 } 8702 var date = (day ? (typeof day === "object" ? day : 8703 this._daylightSavingAdjust(new Date(year, month, day))) : 8704 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 8705 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 8706 } 8707}); 8708 8709/* 8710 * Bind hover events for datepicker elements. 8711 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 8712 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 8713 */ 8714function bindHover(dpDiv) { 8715 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 8716 return dpDiv.delegate(selector, "mouseout", function() { 8717 $(this).removeClass("ui-state-hover"); 8718 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 8719 $(this).removeClass("ui-datepicker-prev-hover"); 8720 } 8721 if (this.className.indexOf("ui-datepicker-next") !== -1) { 8722 $(this).removeClass("ui-datepicker-next-hover"); 8723 } 8724 }) 8725 .delegate(selector, "mouseover", function(){ 8726 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 8727 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 8728 $(this).addClass("ui-state-hover"); 8729 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 8730 $(this).addClass("ui-datepicker-prev-hover"); 8731 } 8732 if (this.className.indexOf("ui-datepicker-next") !== -1) { 8733 $(this).addClass("ui-datepicker-next-hover"); 8734 } 8735 } 8736 }); 8737} 8738 8739/* jQuery extend now ignores nulls! */ 8740function extendRemove(target, props) { 8741 $.extend(target, props); 8742 for (var name in props) { 8743 if (props[name] == null) { 8744 target[name] = props[name]; 8745 } 8746 } 8747 return target; 8748} 8749 8750/* Invoke the datepicker functionality. 8751 @param options string - a command, optionally followed by additional parameters or 8752 Object - settings for attaching new datepicker functionality 8753 @return jQuery object */ 8754$.fn.datepicker = function(options){ 8755 8756 /* Verify an empty collection wasn't passed - Fixes #6976 */ 8757 if ( !this.length ) { 8758 return this; 8759 } 8760 8761 /* Initialise the date picker. */ 8762 if (!$.datepicker.initialized) { 8763 $(document).mousedown($.datepicker._checkExternalClick); 8764 $.datepicker.initialized = true; 8765 } 8766 8767 /* Append datepicker main container to body if not exist. */ 8768 if ($("#"+$.datepicker._mainDivId).length === 0) { 8769 $("body").append($.datepicker.dpDiv); 8770 } 8771 8772 var otherArgs = Array.prototype.slice.call(arguments, 1); 8773 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 8774 return $.datepicker["_" + options + "Datepicker"]. 8775 apply($.datepicker, [this[0]].concat(otherArgs)); 8776 } 8777 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 8778 return $.datepicker["_" + options + "Datepicker"]. 8779 apply($.datepicker, [this[0]].concat(otherArgs)); 8780 } 8781 return this.each(function() { 8782 typeof options === "string" ? 8783 $.datepicker["_" + options + "Datepicker"]. 8784 apply($.datepicker, [this].concat(otherArgs)) : 8785 $.datepicker._attachDatepicker(this, options); 8786 }); 8787}; 8788 8789$.datepicker = new Datepicker(); // singleton instance 8790$.datepicker.initialized = false; 8791$.datepicker.uuid = new Date().getTime(); 8792$.datepicker.version = "1.10.
vendor: 17,646 bytes, lines 8792-9499
87921"; 8793 8794// Workaround for #4055 8795// Add another global to avoid noConflict issues with inline event handlers 8796window["DP_jQuery_" + dpuuid] = $; 8797 8798})(jQuery); 8799(function( $, undefined ) { 8800 8801var sizeRelatedOptions = { 8802 buttons: true, 8803 height: true, 8804 maxHeight: true, 8805 maxWidth: true, 8806 minHeight: true, 8807 minWidth: true, 8808 width: true 8809 }, 8810 resizableRelatedOptions = { 8811 maxHeight: true, 8812 maxWidth: true, 8813 minHeight: true, 8814 minWidth: true 8815 }; 8816 8817$.widget( "ui.dialog", { 8818 version: "1.10.1", 8819 options: { 8820 appendTo: "body", 8821 autoOpen: true, 8822 buttons: [], 8823 closeOnEscape: true, 8824 closeText: "close", 8825 dialogClass: "", 8826 draggable: true, 8827 hide: null, 8828 height: "auto", 8829 maxHeight: null, 8830 maxWidth: null, 8831 minHeight: 150, 8832 minWidth: 150, 8833 modal: false, 8834 position: { 8835 my: "center", 8836 at: "center", 8837 of: window, 8838 collision: "fit", 8839 // Ensure the titlebar is always visible 8840 using: function( pos ) { 8841 var topOffset = $( this ).css( pos ).offset().top; 8842 if ( topOffset < 0 ) { 8843 $( this ).css( "top", pos.top - topOffset ); 8844 } 8845 } 8846 }, 8847 resizable: true, 8848 show: null, 8849 title: null, 8850 width: 300, 8851 8852 // callbacks 8853 beforeClose: null, 8854 close: null, 8855 drag: null, 8856 dragStart: null, 8857 dragStop: null, 8858 focus: null, 8859 open: null, 8860 resize: null, 8861 resizeStart: null, 8862 resizeStop: null 8863 }, 8864 8865 _create: function() { 8866 this.originalCss = { 8867 display: this.element[0].style.display, 8868 width: this.element[0].style.width, 8869 minHeight: this.element[0].style.minHeight, 8870 maxHeight: this.element[0].style.maxHeight, 8871 height: this.element[0].style.height 8872 }; 8873 this.originalPosition = { 8874 parent: this.element.parent(), 8875 index: this.element.parent().children().index( this.element ) 8876 }; 8877 this.originalTitle = this.element.attr("title"); 8878 this.options.title = this.options.title || this.originalTitle; 8879 8880 this._createWrapper(); 8881 8882 this.element 8883 .show() 8884 .removeAttr("title") 8885 .addClass("ui-dialog-content ui-widget-content") 8886 .appendTo( this.uiDialog ); 8887 8888 this._createTitlebar(); 8889 this._createButtonPane(); 8890 8891 if ( this.options.draggable && $.fn.draggable ) { 8892 this._makeDraggable(); 8893 } 8894 if ( this.options.resizable && $.fn.resizable ) { 8895 this._makeResizable(); 8896 } 8897 8898 this._isOpen = false; 8899 }, 8900 8901 _init: function() { 8902 if ( this.options.autoOpen ) { 8903 this.open(); 8904 } 8905 }, 8906 8907 _appendTo: function() { 8908 var element = this.options.appendTo; 8909 if ( element && (element.jquery || element.nodeType) ) { 8910 return $( element ); 8911 } 8912 return this.document.find( element || "body" ).eq( 0 ); 8913 }, 8914 8915 _destroy: function() { 8916 var next, 8917 originalPosition = this.originalPosition; 8918 8919 this._destroyOverlay(); 8920 8921 this.element 8922 .removeUniqueId() 8923 .removeClass("ui-dialog-content ui-widget-content") 8924 .css( this.originalCss ) 8925 // Without detaching first, the following becomes really slow 8926 .detach(); 8927 8928 this.uiDialog.stop( true, true ).remove(); 8929 8930 if ( this.originalTitle ) { 8931 this.element.attr( "title", this.originalTitle ); 8932 } 8933 8934 next = originalPosition.parent.children().eq( originalPosition.index ); 8935 // Don't try to place the dialog next to itself (#8613) 8936 if ( next.length && next[0] !== this.element[0] ) { 8937 next.before( this.element ); 8938 } else { 8939 originalPosition.parent.append( this.element ); 8940 } 8941 }, 8942 8943 widget: function() { 8944 return this.uiDialog; 8945 }, 8946 8947 disable: $.noop, 8948 enable: $.noop, 8949 8950 close: function( event ) { 8951 var that = this; 8952 8953 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 8954 return; 8955 } 8956 8957 this._isOpen = false; 8958 this._destroyOverlay(); 8959 8960 if ( !this.opener.filter(":focusable").focus().length ) { 8961 // Hiding a focused element doesn't trigger blur in WebKit 8962 // so in case we have nothing to focus on, explicitly blur the active element 8963 // https://bugs.webkit.org/show_bug.cgi?id=47182 8964 $( this.document[0].activeElement ).blur(); 8965 } 8966 8967 this._hide( this.uiDialog, this.options.hide, function() { 8968 that._trigger( "close", event ); 8969 }); 8970 }, 8971 8972 isOpen: function() { 8973 return this._isOpen; 8974 }, 8975 8976 moveToTop: function() { 8977 this._moveToTop(); 8978 }, 8979 8980 _moveToTop: function( event, silent ) { 8981 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 8982 if ( moved && !silent ) { 8983 this._trigger( "focus", event ); 8984 } 8985 return moved; 8986 }, 8987 8988 open: function() { 8989 var that = this; 8990 if ( this._isOpen ) { 8991 if ( this._moveToTop() ) { 8992 this._focusTabbable(); 8993 } 8994 return; 8995 } 8996 8997 this._isOpen = true; 8998 this.opener = $( this.document[0].activeElement ); 8999 9000 this._size(); 9001 this._position(); 9002 this._createOverlay(); 9003 this._moveToTop( null, true ); 9004 this._show( this.uiDialog, this.options.show, function() { 9005 that._focusTabbable(); 9006 that._trigger("focus"); 9007 }); 9008 9009 this._trigger("open"); 9010 }, 9011 9012 _focusTabbable: function() { 9013 // Set focus to the first match: 9014 // 1. First element inside the dialog matching [autofocus] 9015 // 2. Tabbable element inside the content element 9016 // 3. Tabbable element inside the buttonpane 9017 // 4. The close button 9018 // 5. The dialog itself 9019 var hasFocus = this.element.find("[autofocus]"); 9020 if ( !hasFocus.length ) { 9021 hasFocus = this.element.find(":tabbable"); 9022 } 9023 if ( !hasFocus.length ) { 9024 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9025 } 9026 if ( !hasFocus.length ) { 9027 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9028 } 9029 if ( !hasFocus.length ) { 9030 hasFocus = this.uiDialog; 9031 } 9032 hasFocus.eq( 0 ).focus(); 9033 }, 9034 9035 _keepFocus: function( event ) { 9036 function checkFocus() { 9037 var activeElement = this.document[0].activeElement, 9038 isActive = this.uiDialog[0] === activeElement || 9039 $.contains( this.uiDialog[0], activeElement ); 9040 if ( !isActive ) { 9041 this._focusTabbable(); 9042 } 9043 } 9044 event.preventDefault(); 9045 checkFocus.call( this ); 9046 // support: IE 9047 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9048 // so we check again later 9049 this._delay( checkFocus ); 9050 }, 9051 9052 _createWrapper: function() { 9053 this.uiDialog = $("<div>") 9054 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9055 this.options.dialogClass ) 9056 .hide() 9057 .attr({ 9058 // Setting tabIndex makes the div focusable 9059 tabIndex: -1, 9060 role: "dialog" 9061 }) 9062 .appendTo( this._appendTo() ); 9063 9064 this._on( this.uiDialog, { 9065 keydown: function( event ) { 9066 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9067 event.keyCode === $.ui.keyCode.ESCAPE ) { 9068 event.preventDefault(); 9069 this.close( event ); 9070 return; 9071 } 9072 9073 // prevent tabbing out of dialogs 9074 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9075 return; 9076 } 9077 var tabbables = this.uiDialog.find(":tabbable"), 9078 first = tabbables.filter(":first"), 9079 last = tabbables.filter(":last"); 9080 9081 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9082 first.focus( 1 ); 9083 event.preventDefault(); 9084 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9085 last.focus( 1 ); 9086 event.preventDefault(); 9087 } 9088 }, 9089 mousedown: function( event ) { 9090 if ( this._moveToTop( event ) ) { 9091 this._focusTabbable(); 9092 } 9093 } 9094 }); 9095 9096 // We assume that any existing aria-describedby attribute means 9097 // that the dialog content is marked up properly 9098 // otherwise we brute force the content as the description 9099 if ( !this.element.find("[aria-describedby]").length ) { 9100 this.uiDialog.attr({ 9101 "aria-describedby": this.element.uniqueId().attr("id") 9102 }); 9103 } 9104 }, 9105 9106 _createTitlebar: function() { 9107 var uiDialogTitle; 9108 9109 this.uiDialogTitlebar = $("<div>") 9110 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9111 .prependTo( this.uiDialog ); 9112 this._on( this.uiDialogTitlebar, { 9113 mousedown: function( event ) { 9114 // Don't prevent click on close button (#8838) 9115 // Focusing a dialog that is partially scrolled out of view 9116 // causes the browser to scroll it into view, preventing the click event 9117 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9118 // Dialog isn't getting focus when dragging (#8063) 9119 this.uiDialog.focus(); 9120 } 9121 } 9122 }); 9123 9124 this.uiDialogTitlebarClose = $("<button></button>") 9125 .button({ 9126 label: this.options.closeText, 9127 icons: { 9128 primary: "ui-icon-closethick" 9129 }, 9130 text: false 9131 }) 9132 .addClass("ui-dialog-titlebar-close") 9133 .appendTo( this.uiDialogTitlebar ); 9134 this._on( this.uiDialogTitlebarClose, { 9135 click: function( event ) { 9136 event.preventDefault(); 9137 this.close( event ); 9138 } 9139 }); 9140 9141 uiDialogTitle = $("<span>") 9142 .uniqueId() 9143 .addClass("ui-dialog-title") 9144 .prependTo( this.uiDialogTitlebar ); 9145 this._title( uiDialogTitle ); 9146 9147 this.uiDialog.attr({ 9148 "aria-labelledby": uiDialogTitle.attr("id") 9149 }); 9150 }, 9151 9152 _title: function( title ) { 9153 if ( !this.options.title ) { 9154 title.html(" "); 9155 } 9156 title.text( this.options.title ); 9157 }, 9158 9159 _createButtonPane: function() { 9160 this.uiDialogButtonPane = $("<div>") 9161 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9162 9163 this.uiButtonSet = $("<div>") 9164 .addClass("ui-dialog-buttonset") 9165 .appendTo( this.uiDialogButtonPane ); 9166 9167 this._createButtons(); 9168 }, 9169 9170 _createButtons: function() { 9171 var that = this, 9172 buttons = this.options.buttons; 9173 9174 // if we already have a button pane, remove it 9175 this.uiDialogButtonPane.remove(); 9176 this.uiButtonSet.empty(); 9177 9178 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 9179 this.uiDialog.removeClass("ui-dialog-buttons"); 9180 return; 9181 } 9182 9183 $.each( buttons, function( name, props ) { 9184 var click, buttonOptions; 9185 props = $.isFunction( props ) ? 9186 { click: props, text: name } : 9187 props; 9188 // Default to a non-submitting button 9189 props = $.extend( { type: "button" }, props ); 9190 // Change the context for the click callback to be the main element 9191 click = props.click; 9192 props.click = function() { 9193 click.apply( that.element[0], arguments ); 9194 }; 9195 buttonOptions = { 9196 icons: props.icons, 9197 text: props.showText 9198 }; 9199 delete props.icons; 9200 delete props.showText; 9201 $( "<button></button>", props ) 9202 .button( buttonOptions ) 9203 .appendTo( that.uiButtonSet ); 9204 }); 9205 this.uiDialog.addClass("ui-dialog-buttons"); 9206 this.uiDialogButtonPane.appendTo( this.uiDialog ); 9207 }, 9208 9209 _makeDraggable: function() { 9210 var that = this, 9211 options = this.options; 9212 9213 function filteredUi( ui ) { 9214 return { 9215 position: ui.position, 9216 offset: ui.offset 9217 }; 9218 } 9219 9220 this.uiDialog.draggable({ 9221 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 9222 handle: ".ui-dialog-titlebar", 9223 containment: "document", 9224 start: function( event, ui ) { 9225 $( this ).addClass("ui-dialog-dragging"); 9226 that._blockFrames(); 9227 that._trigger( "dragStart", event, filteredUi( ui ) ); 9228 }, 9229 drag: function( event, ui ) { 9230 that._trigger( "drag", event, filteredUi( ui ) ); 9231 }, 9232 stop: function( event, ui ) { 9233 options.position = [ 9234 ui.position.left - that.document.scrollLeft(), 9235 ui.position.top - that.document.scrollTop() 9236 ]; 9237 $( this ).removeClass("ui-dialog-dragging"); 9238 that._unblockFrames(); 9239 that._trigger( "dragStop", event, filteredUi( ui ) ); 9240 } 9241 }); 9242 }, 9243 9244 _makeResizable: function() { 9245 var that = this, 9246 options = this.options, 9247 handles = options.resizable, 9248 // .ui-resizable has position: relative defined in the stylesheet 9249 // but dialogs have to use absolute or fixed positioning 9250 position = this.uiDialog.css("position"), 9251 resizeHandles = typeof handles === "string" ? 9252 handles : 9253 "n,e,s,w,se,sw,ne,nw"; 9254 9255 function filteredUi( ui ) { 9256 return { 9257 originalPosition: ui.originalPosition, 9258 originalSize: ui.originalSize, 9259 position: ui.position, 9260 size: ui.size 9261 }; 9262 } 9263 9264 this.uiDialog.resizable({ 9265 cancel: ".ui-dialog-content", 9266 containment: "document", 9267 alsoResize: this.element, 9268 maxWidth: options.maxWidth, 9269 maxHeight: options.maxHeight, 9270 minWidth: options.minWidth, 9271 minHeight: this._minHeight(), 9272 handles: resizeHandles, 9273 start: function( event, ui ) { 9274 $( this ).addClass("ui-dialog-resizing"); 9275 that._blockFrames(); 9276 that._trigger( "resizeStart", event, filteredUi( ui ) ); 9277 }, 9278 resize: function( event, ui ) { 9279 that._trigger( "resize", event, filteredUi( ui ) ); 9280 }, 9281 stop: function( event, ui ) { 9282 options.height = $( this ).height(); 9283 options.width = $( this ).width(); 9284 $( this ).removeClass("ui-dialog-resizing"); 9285 that._unblockFrames(); 9286 that._trigger( "resizeStop", event, filteredUi( ui ) ); 9287 } 9288 }) 9289 .css( "position", position ); 9290 }, 9291 9292 _minHeight: function() { 9293 var options = this.options; 9294 9295 return options.height === "auto" ? 9296 options.minHeight : 9297 Math.min( options.minHeight, options.height ); 9298 }, 9299 9300 _position: function() { 9301 // Need to show the dialog to get the actual offset in the position plugin 9302 var isVisible = this.uiDialog.is(":visible"); 9303 if ( !isVisible ) { 9304 this.uiDialog.show(); 9305 } 9306 this.uiDialog.position( this.options.position ); 9307 if ( !isVisible ) { 9308 this.uiDialog.hide(); 9309 } 9310 }, 9311 9312 _setOptions: function( options ) { 9313 var that = this, 9314 resize = false, 9315 resizableOptions = {}; 9316 9317 $.each( options, function( key, value ) { 9318 that._setOption( key, value ); 9319 9320 if ( key in sizeRelatedOptions ) { 9321 resize = true; 9322 } 9323 if ( key in resizableRelatedOptions ) { 9324 resizableOptions[ key ] = value; 9325 } 9326 }); 9327 9328 if ( resize ) { 9329 this._size(); 9330 this._position(); 9331 } 9332 if ( this.uiDialog.is(":data(ui-resizable)") ) { 9333 this.uiDialog.resizable( "option", resizableOptions ); 9334 } 9335 }, 9336 9337 _setOption: function( key, value ) { 9338 /*jshint maxcomplexity:15*/ 9339 var isDraggable, isResizable, 9340 uiDialog = this.uiDialog; 9341 9342 if ( key === "dialogClass" ) { 9343 uiDialog 9344 .removeClass( this.options.dialogClass ) 9345 .addClass( value ); 9346 } 9347 9348 if ( key === "disabled" ) { 9349 return; 9350 } 9351 9352 this._super( key, value ); 9353 9354 if ( key === "appendTo" ) { 9355 this.uiDialog.appendTo( this._appendTo() ); 9356 } 9357 9358 if ( key === "buttons" ) { 9359 this._createButtons(); 9360 } 9361 9362 if ( key === "closeText" ) { 9363 this.uiDialogTitlebarClose.button({ 9364 // Ensure that we always pass a string 9365 label: "" + value 9366 }); 9367 } 9368 9369 if ( key === "draggable" ) { 9370 isDraggable = uiDialog.is(":data(ui-draggable)"); 9371 if ( isDraggable && !value ) { 9372 uiDialog.draggable("destroy"); 9373 } 9374 9375 if ( !isDraggable && value ) { 9376 this._makeDraggable(); 9377 } 9378 } 9379 9380 if ( key === "position" ) { 9381 this._position(); 9382 } 9383 9384 if ( key === "resizable" ) { 9385 // currently resizable, becoming non-resizable 9386 isResizable = uiDialog.is(":data(ui-resizable)"); 9387 if ( isResizable && !value ) { 9388 uiDialog.resizable("destroy"); 9389 } 9390 9391 // currently resizable, changing handles 9392 if ( isResizable && typeof value === "string" ) { 9393 uiDialog.resizable( "option", "handles", value ); 9394 } 9395 9396 // currently non-resizable, becoming resizable 9397 if ( !isResizable && value !== false ) { 9398 this._makeResizable(); 9399 } 9400 } 9401 9402 if ( key === "title" ) { 9403 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 9404 } 9405 }, 9406 9407 _size: function() { 9408 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9409 // divs will both have width and height set, so we need to reset them 9410 var nonContentHeight, minContentHeight, maxContentHeight, 9411 options = this.options; 9412 9413 // Reset content sizing 9414 this.element.show().css({ 9415 width: "auto", 9416 minHeight: 0, 9417 maxHeight: "none", 9418 height: 0 9419 }); 9420 9421 if ( options.minWidth > options.width ) { 9422 options.width = options.minWidth; 9423 } 9424 9425 // reset wrapper sizing 9426 // determine the height of all the non-content elements 9427 nonContentHeight = this.uiDialog.css({ 9428 height: "auto", 9429 width: options.width 9430 }) 9431 .outerHeight(); 9432 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 9433 maxContentHeight = typeof options.maxHeight === "number" ? 9434 Math.max( 0, options.maxHeight - nonContentHeight ) : 9435 "none"; 9436 9437 if ( options.height === "auto" ) { 9438 this.element.css({ 9439 minHeight: minContentHeight, 9440 maxHeight: maxContentHeight, 9441 height: "auto" 9442 }); 9443 } else { 9444 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 9445 } 9446 9447 if (this.uiDialog.is(":data(ui-resizable)") ) { 9448 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 9449 } 9450 }, 9451 9452 _blockFrames: function() { 9453 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 9454 var iframe = $( this ); 9455 9456 return $( "<div>" ) 9457 .css({ 9458 position: "absolute", 9459 width: iframe.outerWidth(), 9460 height: iframe.outerHeight() 9461 }) 9462 .appendTo( iframe.parent() ) 9463 .offset( iframe.offset() )[0]; 9464 }); 9465 }, 9466 9467 _unblockFrames: function() { 9468 if ( this.iframeBlocks ) { 9469 this.iframeBlocks.remove(); 9470 delete this.iframeBlocks; 9471 } 9472 }, 9473 9474 _createOverlay: function() { 9475 if ( !this.options.modal ) { 9476 return; 9477 } 9478 9479 if ( !$.ui.dialog.overlayInstances ) { 9480 // Prevent use of anchors and inputs. 9481 // We use a delay in case the overlay is created from an 9482 // event that we're going to be cancelling. (#2804) 9483 this._delay(function() { 9484 // Handle .dialog().dialog("close") (#4065) 9485 if ( $.ui.dialog.overlayInstances ) { 9486 this.document.bind( "focusin.dialog", function( event ) { 9487 if ( !$( event.target ).closest(".ui-dialog").length && 9488 // TODO: Remove hack when datepicker implements 9489 // the .ui-front logic (#8989) 9490 !$( event.target ).closest(".ui-datepicker").length ) { 9491 event.preventDefault(); 9492 $(".ui-dialog:visible:last .ui-dialog-content") 9493 .data("ui-dialog")._focusTabbable(); 9494 } 9495 }); 9496 } 9497 }); 9498 } 9499
9500 this.overlay = $("<div>") 9501 .addClass("ui-widget-overlay ui-front") 9502 .appendTo( this._appendTo() ); 9503 this._on( this.overlay, { 9504 mousedown: "_keepFocus" 9505 }); 9506 $.ui.dialog.overlayInstances++; 9507 }, 9508 9509 _destroyOverlay: function() { 9510 if ( !this.options.modal ) { 9511 return; 9512 } 9513 9514 if ( this.overlay ) { 9515 $.ui.dialog.overlayInstances--; 9516 9517 if ( !$.ui.dialog.overlayInstances ) { 9518 this.document.unbind( "focusin.dialog" ); 9519 } 9520 this.overlay.remove(); 9521 this.overlay = null; 9522 } 9523 } 9524}); 9525 9526$.ui.dialog.overlayInstances = 0; 9527 9528// DEPRECATED 9529if ( $.uiBackCompat !== false ) { 9530 // position option with array notation 9531 // just override with old implementation 9532 $.widget( "ui.dialog", $.ui.dialog, { 9533 _position: function() { 9534 var position = this.options.position, 9535 myAt = [], 9536 offset = [ 0, 0 ], 9537 isVisible; 9538 9539 if ( position ) { 9540 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 9541 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 9542 if ( myAt.length === 1 ) { 9543 myAt[1] = myAt[0]; 9544 } 9545 9546 $.each( [ "left", "top" ], function( i, offsetPosition ) { 9547 if ( +myAt[ i ] === myAt[ i ] ) { 9548 offset[ i ] = myAt[ i ]; 9549 myAt[ i ] = offsetPosition; 9550 } 9551 }); 9552 9553 position = { 9554 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 9555 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 9556 at: myAt.join(" ") 9557 }; 9558 } 9559 9560 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 9561 } else { 9562 position = $.ui.dialog.prototype.options.position; 9563 } 9564 9565 // need to show the dialog to get the actual offset in the position plugin 9566 isVisible = this.uiDialog.is(":visible"); 9567 if ( !isVisible ) { 9568 this.uiDialog.show(); 9569 } 9570 this.uiDialog.position( position ); 9571 if ( !isVisible ) { 9572 this.uiDialog.hide(); 9573 } 9574 } 9575 }); 9576} 9577 9578}( jQuery ) ); 9579(function( $, undefined ) { 9580 9581$.widget( "ui.menu", { 9582 version: "1.10.1", 9583 defaultElement: "<ul>", 9584 delay: 300, 9585 options: { 9586 icons: { 9587 submenu: "ui-icon-carat-1-e" 9588 }, 9589 menus: "ul", 9590 position: { 9591 my: "left top", 9592 at: "right top" 9593 }, 9594 role: "menu", 9595 9596 // callbacks 9597 blur: null, 9598 focus: null, 9599 select: null 9600 }, 9601 9602 _create: function() { 9603 this.activeMenu = this.element; 9604 // flag used to prevent firing of the click handler 9605 // as the event bubbles up through nested menus 9606 this.mouseHandled = false; 9607 this.element 9608 .uniqueId() 9609 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9610 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 9611 .attr({ 9612 role: this.options.role, 9613 tabIndex: 0 9614 }) 9615 // need to catch all clicks on disabled menu 9616 // not possible through _on 9617 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 9618 if ( this.options.disabled ) { 9619 event.preventDefault(); 9620 } 9621 }, this )); 9622 9623 if ( this.options.disabled ) { 9624 this.element 9625 .addClass( "ui-state-disabled" ) 9626 .attr( "aria-disabled", "true" ); 9627 } 9628 9629 this._on({ 9630 // Prevent focus from sticking to links inside menu after clicking 9631 // them (focus should always stay on UL during navigation). 9632 "mousedown .ui-menu-item > a": function( event ) { 9633 event.preventDefault(); 9634 }, 9635 "click .ui-state-disabled > a": function( event ) { 9636 event.preventDefault(); 9637 }, 9638 "click .ui-menu-item:has(a)": function( event ) { 9639 var target = $( event.target ).closest( ".ui-menu-item" ); 9640 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 9641 this.mouseHandled = true; 9642 9643 this.select( event ); 9644 // Open submenu on click 9645 if ( target.has( ".ui-menu" ).length ) { 9646 this.expand( event ); 9647 } else if ( !this.element.is( ":focus" ) ) { 9648 // Redirect focus to the menu 9649 this.element.trigger( "focus", [ true ] ); 9650 9651 // If the active item is on the top level, let it stay active. 9652 // Otherwise, blur the active item since it is no longer visible. 9653 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 9654 clearTimeout( this.timer ); 9655 } 9656 } 9657 } 9658 }, 9659 "mouseenter .ui-menu-item": function( event ) { 9660 var target = $( event.currentTarget ); 9661 // Remove ui-state-active class from siblings of the newly focused menu item 9662 // to avoid a jump caused by adjacent elements both having a class with a border 9663 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 9664 this.focus( event, target ); 9665 }, 9666 mouseleave: "collapseAll", 9667 "mouseleave .ui-menu": "collapseAll", 9668 focus: function( event, keepActiveItem ) { 9669 // If there's already an active item, keep it active 9670 // If not, activate the first item 9671 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 9672 9673 if ( !keepActiveItem ) { 9674 this.focus( event, item ); 9675 } 9676 }, 9677 blur: function( event ) { 9678 this._delay(function() { 9679 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 9680 this.collapseAll( event ); 9681 } 9682 }); 9683 }, 9684 keydown: "_keydown" 9685 }); 9686 9687 this.refresh(); 9688
vendor: 133,497 bytes, lines 9689-14903
9689 // Clicks outside of a menu collapse any open menus 9690 this._on( this.document, { 9691 click: function( event ) { 9692 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 9693 this.collapseAll( event ); 9694 } 9695 9696 // Reset the mouseHandled flag 9697 this.mouseHandled = false; 9698 } 9699 }); 9700 }, 9701 9702 _destroy: function() { 9703 // Destroy (sub)menus 9704 this.element 9705 .removeAttr( "aria-activedescendant" ) 9706 .find( ".ui-menu" ).addBack() 9707 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 9708 .removeAttr( "role" ) 9709 .removeAttr( "tabIndex" ) 9710 .removeAttr( "aria-labelledby" ) 9711 .removeAttr( "aria-expanded" ) 9712 .removeAttr( "aria-hidden" ) 9713 .removeAttr( "aria-disabled" ) 9714 .removeUniqueId() 9715 .show(); 9716 9717 // Destroy menu items 9718 this.element.find( ".ui-menu-item" ) 9719 .removeClass( "ui-menu-item" ) 9720 .removeAttr( "role" ) 9721 .removeAttr( "aria-disabled" ) 9722 .children( "a" ) 9723 .removeUniqueId() 9724 .removeClass( "ui-corner-all ui-state-hover" ) 9725 .removeAttr( "tabIndex" ) 9726 .removeAttr( "role" ) 9727 .removeAttr( "aria-haspopup" ) 9728 .children().each( function() { 9729 var elem = $( this ); 9730 if ( elem.data( "ui-menu-submenu-carat" ) ) { 9731 elem.remove(); 9732 } 9733 }); 9734 9735 // Destroy menu dividers 9736 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 9737 }, 9738 9739 _keydown: function( event ) { 9740 /*jshint maxcomplexity:20*/ 9741 var match, prev, character, skip, regex, 9742 preventDefault = true; 9743 9744 function escape( value ) { 9745 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 9746 } 9747 9748 switch ( event.keyCode ) { 9749 case $.ui.keyCode.PAGE_UP: 9750 this.previousPage( event ); 9751 break; 9752 case $.ui.keyCode.PAGE_DOWN: 9753 this.nextPage( event ); 9754 break; 9755 case $.ui.keyCode.HOME: 9756 this._move( "first", "first", event ); 9757 break; 9758 case $.ui.keyCode.END: 9759 this._move( "last", "last", event ); 9760 break; 9761 case $.ui.keyCode.UP: 9762 this.previous( event ); 9763 break; 9764 case $.ui.keyCode.DOWN: 9765 this.next( event ); 9766 break; 9767 case $.ui.keyCode.LEFT: 9768 this.collapse( event ); 9769 break; 9770 case $.ui.keyCode.RIGHT: 9771 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 9772 this.expand( event ); 9773 } 9774 break; 9775 case $.ui.keyCode.ENTER: 9776 case $.ui.keyCode.SPACE: 9777 this._activate( event ); 9778 break; 9779 case $.ui.keyCode.ESCAPE: 9780 this.collapse( event ); 9781 break; 9782 default: 9783 preventDefault = false; 9784 prev = this.previousFilter || ""; 9785 character = String.fromCharCode( event.keyCode ); 9786 skip = false; 9787 9788 clearTimeout( this.filterTimer ); 9789 9790 if ( character === prev ) { 9791 skip = true; 9792 } else { 9793 character = prev + character; 9794 } 9795 9796 regex = new RegExp( "^" + escape( character ), "i" ); 9797 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9798 return regex.test( $( this ).children( "a" ).text() ); 9799 }); 9800 match = skip && match.index( this.active.next() ) !== -1 ? 9801 this.active.nextAll( ".ui-menu-item" ) : 9802 match; 9803 9804 // If no matches on the current filter, reset to the last character pressed 9805 // to move down the menu to the first item that starts with that character 9806 if ( !match.length ) { 9807 character = String.fromCharCode( event.keyCode ); 9808 regex = new RegExp( "^" + escape( character ), "i" ); 9809 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 9810 return regex.test( $( this ).children( "a" ).text() ); 9811 }); 9812 } 9813 9814 if ( match.length ) { 9815 this.focus( event, match ); 9816 if ( match.length > 1 ) { 9817 this.previousFilter = character; 9818 this.filterTimer = this._delay(function() { 9819 delete this.previousFilter; 9820 }, 1000 ); 9821 } else { 9822 delete this.previousFilter; 9823 } 9824 } else { 9825 delete this.previousFilter; 9826 } 9827 } 9828 9829 if ( preventDefault ) { 9830 event.preventDefault(); 9831 } 9832 }, 9833 9834 _activate: function( event ) { 9835 if ( !this.active.is( ".ui-state-disabled" ) ) { 9836 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 9837 this.expand( event ); 9838 } else { 9839 this.select( event ); 9840 } 9841 } 9842 }, 9843 9844 refresh: function() { 9845 var menus, 9846 icon = this.options.icons.submenu, 9847 submenus = this.element.find( this.options.menus ); 9848 9849 // Initialize nested menus 9850 submenus.filter( ":not(.ui-menu)" ) 9851 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 9852 .hide() 9853 .attr({ 9854 role: this.options.role, 9855 "aria-hidden": "true", 9856 "aria-expanded": "false" 9857 }) 9858 .each(function() { 9859 var menu = $( this ), 9860 item = menu.prev( "a" ), 9861 submenuCarat = $( "<span>" ) 9862 .addClass( "ui-menu-icon ui-icon " + icon ) 9863 .data( "ui-menu-submenu-carat", true ); 9864 9865 item 9866 .attr( "aria-haspopup", "true" ) 9867 .prepend( submenuCarat ); 9868 menu.attr( "aria-labelledby", item.attr( "id" ) ); 9869 }); 9870 9871 menus = submenus.add( this.element ); 9872 9873 // Don't refresh list items that are already adapted 9874 menus.children( ":not(.ui-menu-item):has(a)" ) 9875 .addClass( "ui-menu-item" ) 9876 .attr( "role", "presentation" ) 9877 .children( "a" ) 9878 .uniqueId() 9879 .addClass( "ui-corner-all" ) 9880 .attr({ 9881 tabIndex: -1, 9882 role: this._itemRole() 9883 }); 9884 9885 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 9886 menus.children( ":not(.ui-menu-item)" ).each(function() { 9887 var item = $( this ); 9888 // hyphen, em dash, en dash 9889 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 9890 item.addClass( "ui-widget-content ui-menu-divider" ); 9891 } 9892 }); 9893 9894 // Add aria-disabled attribute to any disabled menu item 9895 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 9896 9897 // If the active item has been removed, blur the menu 9898 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 9899 this.blur(); 9900 } 9901 }, 9902 9903 _itemRole: function() { 9904 return { 9905 menu: "menuitem", 9906 listbox: "option" 9907 }[ this.options.role ]; 9908 }, 9909 9910 _setOption: function( key, value ) { 9911 if ( key === "icons" ) { 9912 this.element.find( ".ui-menu-icon" ) 9913 .removeClass( this.options.icons.submenu ) 9914 .addClass( value.submenu ); 9915 } 9916 this._super( key, value ); 9917 }, 9918 9919 focus: function( event, item ) { 9920 var nested, focused; 9921 this.blur( event, event && event.type === "focus" ); 9922 9923 this._scrollIntoView( item ); 9924 9925 this.active = item.first(); 9926 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 9927 // Only update aria-activedescendant if there's a role 9928 // otherwise we assume focus is managed elsewhere 9929 if ( this.options.role ) { 9930 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 9931 } 9932 9933 // Highlight active parent menu item, if any 9934 this.active 9935 .parent() 9936 .closest( ".ui-menu-item" ) 9937 .children( "a:first" ) 9938 .addClass( "ui-state-active" ); 9939 9940 if ( event && event.type === "keydown" ) { 9941 this._close(); 9942 } else { 9943 this.timer = this._delay(function() { 9944 this._close(); 9945 }, this.delay ); 9946 } 9947 9948 nested = item.children( ".ui-menu" ); 9949 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 9950 this._startOpening(nested); 9951 } 9952 this.activeMenu = item.parent(); 9953 9954 this._trigger( "focus", event, { item: item } ); 9955 }, 9956 9957 _scrollIntoView: function( item ) { 9958 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 9959 if ( this._hasScroll() ) { 9960 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 9961 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 9962 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 9963 scroll = this.activeMenu.scrollTop(); 9964 elementHeight = this.activeMenu.height(); 9965 itemHeight = item.height(); 9966 9967 if ( offset < 0 ) { 9968 this.activeMenu.scrollTop( scroll + offset ); 9969 } else if ( offset + itemHeight > elementHeight ) { 9970 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 9971 } 9972 } 9973 }, 9974 9975 blur: function( event, fromFocus ) { 9976 if ( !fromFocus ) { 9977 clearTimeout( this.timer ); 9978 } 9979 9980 if ( !this.active ) { 9981 return; 9982 } 9983 9984 this.active.children( "a" ).removeClass( "ui-state-focus" ); 9985 this.active = null; 9986 9987 this._trigger( "blur", event, { item: this.active } ); 9988 }, 9989 9990 _startOpening: function( submenu ) { 9991 clearTimeout( this.timer ); 9992 9993 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 9994 // shift in the submenu position when mousing over the carat icon 9995 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 9996 return; 9997 } 9998 9999 this.timer = this._delay(function() { 10000 this._close(); 10001 this._open( submenu ); 10002 }, this.delay ); 10003 }, 10004 10005 _open: function( submenu ) { 10006 var position = $.extend({ 10007 of: this.active 10008 }, this.options.position ); 10009 10010 clearTimeout( this.timer ); 10011 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 10012 .hide() 10013 .attr( "aria-hidden", "true" ); 10014 10015 submenu 10016 .show() 10017 .removeAttr( "aria-hidden" ) 10018 .attr( "aria-expanded", "true" ) 10019 .position( position ); 10020 }, 10021 10022 collapseAll: function( event, all ) { 10023 clearTimeout( this.timer ); 10024 this.timer = this._delay(function() { 10025 // If we were passed an event, look for the submenu that contains the event 10026 var currentMenu = all ? this.element : 10027 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 10028 10029 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 10030 if ( !currentMenu.length ) { 10031 currentMenu = this.element; 10032 } 10033 10034 this._close( currentMenu ); 10035 10036 this.blur( event ); 10037 this.activeMenu = currentMenu; 10038 }, this.delay ); 10039 }, 10040 10041 // With no arguments, closes the currently active menu - if nothing is active 10042 // it closes all menus. If passed an argument, it will search for menus BELOW 10043 _close: function( startMenu ) { 10044 if ( !startMenu ) { 10045 startMenu = this.active ? this.active.parent() : this.element; 10046 } 10047 10048 startMenu 10049 .find( ".ui-menu" ) 10050 .hide() 10051 .attr( "aria-hidden", "true" ) 10052 .attr( "aria-expanded", "false" ) 10053 .end() 10054 .find( "a.ui-state-active" ) 10055 .removeClass( "ui-state-active" ); 10056 }, 10057 10058 collapse: function( event ) { 10059 var newItem = this.active && 10060 this.active.parent().closest( ".ui-menu-item", this.element ); 10061 if ( newItem && newItem.length ) { 10062 this._close(); 10063 this.focus( event, newItem ); 10064 } 10065 }, 10066 10067 expand: function( event ) { 10068 var newItem = this.active && 10069 this.active 10070 .children( ".ui-menu " ) 10071 .children( ".ui-menu-item" ) 10072 .first(); 10073 10074 if ( newItem && newItem.length ) { 10075 this._open( newItem.parent() ); 10076 10077 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 10078 this._delay(function() { 10079 this.focus( event, newItem ); 10080 }); 10081 } 10082 }, 10083 10084 next: function( event ) { 10085 this._move( "next", "first", event ); 10086 }, 10087 10088 previous: function( event ) { 10089 this._move( "prev", "last", event ); 10090 }, 10091 10092 isFirstItem: function() { 10093 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 10094 }, 10095 10096 isLastItem: function() { 10097 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 10098 }, 10099 10100 _move: function( direction, filter, event ) { 10101 var next; 10102 if ( this.active ) { 10103 if ( direction === "first" || direction === "last" ) { 10104 next = this.active 10105 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 10106 .eq( -1 ); 10107 } else { 10108 next = this.active 10109 [ direction + "All" ]( ".ui-menu-item" ) 10110 .eq( 0 ); 10111 } 10112 } 10113 if ( !next || !next.length || !this.active ) { 10114 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 10115 } 10116 10117 this.focus( event, next ); 10118 }, 10119 10120 nextPage: function( event ) { 10121 var item, base, height; 10122 10123 if ( !this.active ) { 10124 this.next( event ); 10125 return; 10126 } 10127 if ( this.isLastItem() ) { 10128 return; 10129 } 10130 if ( this._hasScroll() ) { 10131 base = this.active.offset().top; 10132 height = this.element.height(); 10133 this.active.nextAll( ".ui-menu-item" ).each(function() { 10134 item = $( this ); 10135 return item.offset().top - base - height < 0; 10136 }); 10137 10138 this.focus( event, item ); 10139 } else { 10140 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 10141 [ !this.active ? "first" : "last" ]() ); 10142 } 10143 }, 10144 10145 previousPage: function( event ) { 10146 var item, base, height; 10147 if ( !this.active ) { 10148 this.next( event ); 10149 return; 10150 } 10151 if ( this.isFirstItem() ) { 10152 return; 10153 } 10154 if ( this._hasScroll() ) { 10155 base = this.active.offset().top; 10156 height = this.element.height(); 10157 this.active.prevAll( ".ui-menu-item" ).each(function() { 10158 item = $( this ); 10159 return item.offset().top - base + height > 0; 10160 }); 10161 10162 this.focus( event, item ); 10163 } else { 10164 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 10165 } 10166 }, 10167 10168 _hasScroll: function() { 10169 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 10170 }, 10171 10172 select: function( event ) { 10173 // TODO: It should never be possible to not have an active item at this 10174 // point, but the tests don't trigger mouseenter before click. 10175 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 10176 var ui = { item: this.active }; 10177 if ( !this.active.has( ".ui-menu" ).length ) { 10178 this.collapseAll( event, true ); 10179 } 10180 this._trigger( "select", event, ui ); 10181 } 10182}); 10183 10184}( jQuery )); 10185(function( $, undefined ) { 10186 10187$.widget( "ui.progressbar", { 10188 version: "1.10.1", 10189 options: { 10190 max: 100, 10191 value: 0, 10192 10193 change: null, 10194 complete: null 10195 }, 10196 10197 min: 0, 10198 10199 _create: function() { 10200 // Constrain initial value 10201 this.oldValue = this.options.value = this._constrainedValue(); 10202 10203 this.element 10204 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10205 .attr({ 10206 // Only set static values, aria-valuenow and aria-valuemax are 10207 // set inside _refreshValue() 10208 role: "progressbar", 10209 "aria-valuemin": this.min 10210 }); 10211 10212 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10213 .appendTo( this.element ); 10214 10215 this._refreshValue(); 10216 }, 10217 10218 _destroy: function() { 10219 this.element 10220 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10221 .removeAttr( "role" ) 10222 .removeAttr( "aria-valuemin" ) 10223 .removeAttr( "aria-valuemax" ) 10224 .removeAttr( "aria-valuenow" ); 10225 10226 this.valueDiv.remove(); 10227 }, 10228 10229 value: function( newValue ) { 10230 if ( newValue === undefined ) { 10231 return this.options.value; 10232 } 10233 10234 this.options.value = this._constrainedValue( newValue ); 10235 this._refreshValue(); 10236 }, 10237 10238 _constrainedValue: function( newValue ) { 10239 if ( newValue === undefined ) { 10240 newValue = this.options.value; 10241 } 10242 10243 this.indeterminate = newValue === false; 10244 10245 // sanitize value 10246 if ( typeof newValue !== "number" ) { 10247 newValue = 0; 10248 } 10249 10250 return this.indeterminate ? false : 10251 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10252 }, 10253 10254 _setOptions: function( options ) { 10255 // Ensure "value" option is set after other values (like max) 10256 var value = options.value; 10257 delete options.value; 10258 10259 this._super( options ); 10260 10261 this.options.value = this._constrainedValue( value ); 10262 this._refreshValue(); 10263 }, 10264 10265 _setOption: function( key, value ) { 10266 if ( key === "max" ) { 10267 // Don't allow a max less than min 10268 value = Math.max( this.min, value ); 10269 } 10270 10271 this._super( key, value ); 10272 }, 10273 10274 _percentage: function() { 10275 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 10276 }, 10277 10278 _refreshValue: function() { 10279 var value = this.options.value, 10280 percentage = this._percentage(); 10281 10282 this.valueDiv 10283 .toggle( this.indeterminate || value > this.min ) 10284 .toggleClass( "ui-corner-right", value === this.options.max ) 10285 .width( percentage.toFixed(0) + "%" ); 10286 10287 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 10288 10289 if ( this.indeterminate ) { 10290 this.element.removeAttr( "aria-valuenow" ); 10291 if ( !this.overlayDiv ) { 10292 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 10293 } 10294 } else { 10295 this.element.attr({ 10296 "aria-valuemax": this.options.max, 10297 "aria-valuenow": value 10298 }); 10299 if ( this.overlayDiv ) { 10300 this.overlayDiv.remove(); 10301 this.overlayDiv = null; 10302 } 10303 } 10304 10305 if ( this.oldValue !== value ) { 10306 this.oldValue = value; 10307 this._trigger( "change" ); 10308 } 10309 if ( value === this.options.max ) { 10310 this._trigger( "complete" ); 10311 } 10312 } 10313}); 10314 10315})( jQuery ); 10316(function( $, undefined ) { 10317 10318// number of pages in a slider 10319// (how many times can you page up/down to go through the whole range) 10320var numPages = 5; 10321 10322$.widget( "ui.slider", $.ui.mouse, { 10323 version: "1.10.1", 10324 widgetEventPrefix: "slide", 10325 10326 options: { 10327 animate: false, 10328 distance: 0, 10329 max: 100, 10330 min: 0, 10331 orientation: "horizontal", 10332 range: false, 10333 step: 1, 10334 value: 0, 10335 values: null, 10336 10337 // callbacks 10338 change: null, 10339 slide: null, 10340 start: null, 10341 stop: null 10342 }, 10343 10344 _create: function() { 10345 this._keySliding = false; 10346 this._mouseSliding = false; 10347 this._animateOff = true; 10348 this._handleIndex = null; 10349 this._detectOrientation(); 10350 this._mouseInit(); 10351 10352 this.element 10353 .addClass( "ui-slider" + 10354 " ui-slider-" + this.orientation + 10355 " ui-widget" + 10356 " ui-widget-content" + 10357 " ui-corner-all"); 10358 10359 this._refresh(); 10360 this._setOption( "disabled", this.options.disabled ); 10361 10362 this._animateOff = false; 10363 }, 10364 10365 _refresh: function() { 10366 this._createRange(); 10367 this._createHandles(); 10368 this._setupEvents(); 10369 this._refreshValue(); 10370 }, 10371 10372 _createHandles: function() { 10373 var i, handleCount, 10374 options = this.options, 10375 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 10376 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 10377 handles = []; 10378 10379 handleCount = ( options.values && options.values.length ) || 1; 10380 10381 if ( existingHandles.length > handleCount ) { 10382 existingHandles.slice( handleCount ).remove(); 10383 existingHandles = existingHandles.slice( 0, handleCount ); 10384 } 10385 10386 for ( i = existingHandles.length; i < handleCount; i++ ) { 10387 handles.push( handle ); 10388 } 10389 10390 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 10391 10392 this.handle = this.handles.eq( 0 ); 10393 10394 this.handles.each(function( i ) { 10395 $( this ).data( "ui-slider-handle-index", i ); 10396 }); 10397 }, 10398 10399 _createRange: function() { 10400 var options = this.options, 10401 classes = ""; 10402 10403 if ( options.range ) { 10404 if ( options.range === true ) { 10405 if ( !options.values ) { 10406 options.values = [ this._valueMin(), this._valueMin() ]; 10407 } else if ( options.values.length && options.values.length !== 2 ) { 10408 options.values = [ options.values[0], options.values[0] ]; 10409 } else if ( $.isArray( options.values ) ) { 10410 options.values = options.values.slice(0); 10411 } 10412 } 10413 10414 if ( !this.range || !this.range.length ) { 10415 this.range = $( "<div></div>" ) 10416 .appendTo( this.element ); 10417 10418 classes = "ui-slider-range" + 10419 // note: this isn't the most fittingly semantic framework class for this element, 10420 // but worked best visually with a variety of themes 10421 " ui-widget-header ui-corner-all"; 10422 } else { 10423 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 10424 // Handle range switching from true to min/max 10425 .css({ 10426 "left": "", 10427 "bottom": "" 10428 }); 10429 } 10430 10431 this.range.addClass( classes + 10432 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 10433 } else { 10434 this.range = $([]); 10435 } 10436 }, 10437 10438 _setupEvents: function() { 10439 var elements = this.handles.add( this.range ).filter( "a" ); 10440 this._off( elements ); 10441 this._on( elements, this._handleEvents ); 10442 this._hoverable( elements ); 10443 this._focusable( elements ); 10444 }, 10445 10446 _destroy: function() { 10447 this.handles.remove(); 10448 this.range.remove(); 10449 10450 this.element 10451 .removeClass( "ui-slider" + 10452 " ui-slider-horizontal" + 10453 " ui-slider-vertical" + 10454 " ui-widget" + 10455 " ui-widget-content" + 10456 " ui-corner-all" ); 10457 10458 this._mouseDestroy(); 10459 }, 10460 10461 _mouseCapture: function( event ) { 10462 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 10463 that = this, 10464 o = this.options; 10465 10466 if ( o.disabled ) { 10467 return false; 10468 } 10469 10470 this.elementSize = { 10471 width: this.element.outerWidth(), 10472 height: this.element.outerHeight() 10473 }; 10474 this.elementOffset = this.element.offset(); 10475 10476 position = { x: event.pageX, y: event.pageY }; 10477 normValue = this._normValueFromMouse( position ); 10478 distance = this._valueMax() - this._valueMin() + 1; 10479 this.handles.each(function( i ) { 10480 var thisDistance = Math.abs( normValue - that.values(i) ); 10481 if (( distance > thisDistance ) || 10482 ( distance === thisDistance && 10483 (i === that._lastChangedValue || that.values(i) === o.min ))) { 10484 distance = thisDistance; 10485 closestHandle = $( this ); 10486 index = i; 10487 } 10488 }); 10489 10490 allowed = this._start( event, index ); 10491 if ( allowed === false ) { 10492 return false; 10493 } 10494 this._mouseSliding = true; 10495 10496 this._handleIndex = index; 10497 10498 closestHandle 10499 .addClass( "ui-state-active" ) 10500 .focus(); 10501 10502 offset = closestHandle.offset(); 10503 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 10504 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 10505 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 10506 top: event.pageY - offset.top - 10507 ( closestHandle.height() / 2 ) - 10508 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 10509 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 10510 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 10511 }; 10512 10513 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 10514 this._slide( event, index, normValue ); 10515 } 10516 this._animateOff = true; 10517 return true; 10518 }, 10519 10520 _mouseStart: function() { 10521 return true; 10522 }, 10523 10524 _mouseDrag: function( event ) { 10525 var position = { x: event.pageX, y: event.pageY }, 10526 normValue = this._normValueFromMouse( position ); 10527 10528 this._slide( event, this._handleIndex, normValue ); 10529 10530 return false; 10531 }, 10532 10533 _mouseStop: function( event ) { 10534 this.handles.removeClass( "ui-state-active" ); 10535 this._mouseSliding = false; 10536 10537 this._stop( event, this._handleIndex ); 10538 this._change( event, this._handleIndex ); 10539 10540 this._handleIndex = null; 10541 this._clickOffset = null; 10542 this._animateOff = false; 10543 10544 return false; 10545 }, 10546 10547 _detectOrientation: function() { 10548 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 10549 }, 10550 10551 _normValueFromMouse: function( position ) { 10552 var pixelTotal, 10553 pixelMouse, 10554 percentMouse, 10555 valueTotal, 10556 valueMouse; 10557 10558 if ( this.orientation === "horizontal" ) { 10559 pixelTotal = this.elementSize.width; 10560 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 10561 } else { 10562 pixelTotal = this.elementSize.height; 10563 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 10564 } 10565 10566 percentMouse = ( pixelMouse / pixelTotal ); 10567 if ( percentMouse > 1 ) { 10568 percentMouse = 1; 10569 } 10570 if ( percentMouse < 0 ) { 10571 percentMouse = 0; 10572 } 10573 if ( this.orientation === "vertical" ) { 10574 percentMouse = 1 - percentMouse; 10575 } 10576 10577 valueTotal = this._valueMax() - this._valueMin(); 10578 valueMouse = this._valueMin() + percentMouse * valueTotal; 10579 10580 return this._trimAlignValue( valueMouse ); 10581 }, 10582 10583 _start: function( event, index ) { 10584 var uiHash = { 10585 handle: this.handles[ index ], 10586 value: this.value() 10587 }; 10588 if ( this.options.values && this.options.values.length ) { 10589 uiHash.value = this.values( index ); 10590 uiHash.values = this.values(); 10591 } 10592 return this._trigger( "start", event, uiHash ); 10593 }, 10594 10595 _slide: function( event, index, newVal ) { 10596 var otherVal, 10597 newValues, 10598 allowed; 10599 10600 if ( this.options.values && this.options.values.length ) { 10601 otherVal = this.values( index ? 0 : 1 ); 10602 10603 if ( ( this.options.values.length === 2 && this.options.range === true ) && 10604 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 10605 ) { 10606 newVal = otherVal; 10607 } 10608 10609 if ( newVal !== this.values( index ) ) { 10610 newValues = this.values(); 10611 newValues[ index ] = newVal; 10612 // A slide can be canceled by returning false from the slide callback 10613 allowed = this._trigger( "slide", event, { 10614 handle: this.handles[ index ], 10615 value: newVal, 10616 values: newValues 10617 } ); 10618 otherVal = this.values( index ? 0 : 1 ); 10619 if ( allowed !== false ) { 10620 this.values( index, newVal, true ); 10621 } 10622 } 10623 } else { 10624 if ( newVal !== this.value() ) { 10625 // A slide can be canceled by returning false from the slide callback 10626 allowed = this._trigger( "slide", event, { 10627 handle: this.handles[ index ], 10628 value: newVal 10629 } ); 10630 if ( allowed !== false ) { 10631 this.value( newVal ); 10632 } 10633 } 10634 } 10635 }, 10636 10637 _stop: function( event, index ) { 10638 var uiHash = { 10639 handle: this.handles[ index ], 10640 value: this.value() 10641 }; 10642 if ( this.options.values && this.options.values.length ) { 10643 uiHash.value = this.values( index ); 10644 uiHash.values = this.values(); 10645 } 10646 10647 this._trigger( "stop", event, uiHash ); 10648 }, 10649 10650 _change: function( event, index ) { 10651 if ( !this._keySliding && !this._mouseSliding ) { 10652 var uiHash = { 10653 handle: this.handles[ index ], 10654 value: this.value() 10655 }; 10656 if ( this.options.values && this.options.values.length ) { 10657 uiHash.value = this.values( index ); 10658 uiHash.values = this.values(); 10659 } 10660 10661 //store the last changed value index for reference when handles overlap 10662 this._lastChangedValue = index; 10663 10664 this._trigger( "change", event, uiHash ); 10665 } 10666 }, 10667 10668 value: function( newValue ) { 10669 if ( arguments.length ) { 10670 this.options.value = this._trimAlignValue( newValue ); 10671 this._refreshValue(); 10672 this._change( null, 0 ); 10673 return; 10674 } 10675 10676 return this._value(); 10677 }, 10678 10679 values: function( index, newValue ) { 10680 var vals, 10681 newValues, 10682 i; 10683 10684 if ( arguments.length > 1 ) { 10685 this.options.values[ index ] = this._trimAlignValue( newValue ); 10686 this._refreshValue(); 10687 this._change( null, index ); 10688 return; 10689 } 10690 10691 if ( arguments.length ) { 10692 if ( $.isArray( arguments[ 0 ] ) ) { 10693 vals = this.options.values; 10694 newValues = arguments[ 0 ]; 10695 for ( i = 0; i < vals.length; i += 1 ) { 10696 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 10697 this._change( null, i ); 10698 } 10699 this._refreshValue(); 10700 } else { 10701 if ( this.options.values && this.options.values.length ) { 10702 return this._values( index ); 10703 } else { 10704 return this.value(); 10705 } 10706 } 10707 } else { 10708 return this._values(); 10709 } 10710 }, 10711 10712 _setOption: function( key, value ) { 10713 var i, 10714 valsLength = 0; 10715 10716 if ( key === "range" && this.options.range === true ) { 10717 if ( value === "min" ) { 10718 this.options.value = this._values( 0 ); 10719 this.options.values = null; 10720 } else if ( value === "max" ) { 10721 this.options.value = this._values( this.options.values.length-1 ); 10722 this.options.values = null; 10723 } 10724 } 10725 10726 if ( $.isArray( this.options.values ) ) { 10727 valsLength = this.options.values.length; 10728 } 10729 10730 $.Widget.prototype._setOption.apply( this, arguments ); 10731 10732 switch ( key ) { 10733 case "orientation": 10734 this._detectOrientation(); 10735 this.element 10736 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 10737 .addClass( "ui-slider-" + this.orientation ); 10738 this._refreshValue(); 10739 break; 10740 case "value": 10741 this._animateOff = true; 10742 this._refreshValue(); 10743 this._change( null, 0 ); 10744 this._animateOff = false; 10745 break; 10746 case "values": 10747 this._animateOff = true; 10748 this._refreshValue(); 10749 for ( i = 0; i < valsLength; i += 1 ) { 10750 this._change( null, i ); 10751 } 10752 this._animateOff = false; 10753 break; 10754 case "min": 10755 case "max": 10756 this._animateOff = true; 10757 this._refreshValue(); 10758 this._animateOff = false; 10759 break; 10760 case "range": 10761 this._animateOff = true; 10762 this._refresh(); 10763 this._animateOff = false; 10764 break; 10765 } 10766 }, 10767 10768 //internal value getter 10769 // _value() returns value trimmed by min and max, aligned by step 10770 _value: function() { 10771 var val = this.options.value; 10772 val = this._trimAlignValue( val ); 10773 10774 return val; 10775 }, 10776 10777 //internal values getter 10778 // _values() returns array of values trimmed by min and max, aligned by step 10779 // _values( index ) returns single value trimmed by min and max, aligned by step 10780 _values: function( index ) { 10781 var val, 10782 vals, 10783 i; 10784 10785 if ( arguments.length ) { 10786 val = this.options.values[ index ]; 10787 val = this._trimAlignValue( val ); 10788 10789 return val; 10790 } else if ( this.options.values && this.options.values.length ) { 10791 // .slice() creates a copy of the array 10792 // this copy gets trimmed by min and max and then returned 10793 vals = this.options.values.slice(); 10794 for ( i = 0; i < vals.length; i+= 1) { 10795 vals[ i ] = this._trimAlignValue( vals[ i ] ); 10796 } 10797 10798 return vals; 10799 } else { 10800 return []; 10801 } 10802 }, 10803 10804 // returns the step-aligned value that val is closest to, between (inclusive) min and max 10805 _trimAlignValue: function( val ) { 10806 if ( val <= this._valueMin() ) { 10807 return this._valueMin(); 10808 } 10809 if ( val >= this._valueMax() ) { 10810 return this._valueMax(); 10811 } 10812 var step = ( this.options.step > 0 ) ? this.options.step : 1, 10813 valModStep = (val - this._valueMin()) % step, 10814 alignValue = val - valModStep; 10815 10816 if ( Math.abs(valModStep) * 2 >= step ) { 10817 alignValue += ( valModStep > 0 ) ? step : ( -step ); 10818 } 10819 10820 // Since JavaScript has problems with large floats, round 10821 // the final value to 5 digits after the decimal point (see #4124) 10822 return parseFloat( alignValue.toFixed(5) ); 10823 }, 10824 10825 _valueMin: function() { 10826 return this.options.min; 10827 }, 10828 10829 _valueMax: function() { 10830 return this.options.max; 10831 }, 10832 10833 _refreshValue: function() { 10834 var lastValPercent, valPercent, value, valueMin, valueMax, 10835 oRange = this.options.range, 10836 o = this.options, 10837 that = this, 10838 animate = ( !this._animateOff ) ? o.animate : false, 10839 _set = {}; 10840 10841 if ( this.options.values && this.options.values.length ) { 10842 this.handles.each(function( i ) { 10843 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 10844 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10845 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10846 if ( that.options.range === true ) { 10847 if ( that.orientation === "horizontal" ) { 10848 if ( i === 0 ) { 10849 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 10850 } 10851 if ( i === 1 ) { 10852 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10853 } 10854 } else { 10855 if ( i === 0 ) { 10856 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 10857 } 10858 if ( i === 1 ) { 10859 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 10860 } 10861 } 10862 } 10863 lastValPercent = valPercent; 10864 }); 10865 } else { 10866 value = this.value(); 10867 valueMin = this._valueMin(); 10868 valueMax = this._valueMax(); 10869 valPercent = ( valueMax !== valueMin ) ? 10870 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 10871 0; 10872 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 10873 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 10874 10875 if ( oRange === "min" && this.orientation === "horizontal" ) { 10876 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 10877 } 10878 if ( oRange === "max" && this.orientation === "horizontal" ) { 10879 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10880 } 10881 if ( oRange === "min" && this.orientation === "vertical" ) { 10882 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 10883 } 10884 if ( oRange === "max" && this.orientation === "vertical" ) { 10885 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 10886 } 10887 } 10888 }, 10889 10890 _handleEvents: { 10891 keydown: function( event ) { 10892 /*jshint maxcomplexity:25*/ 10893 var allowed, curVal, newVal, step, 10894 index = $( event.target ).data( "ui-slider-handle-index" ); 10895 10896 switch ( event.keyCode ) { 10897 case $.ui.keyCode.HOME: 10898 case $.ui.keyCode.END: 10899 case $.ui.keyCode.PAGE_UP: 10900 case $.ui.keyCode.PAGE_DOWN: 10901 case $.ui.keyCode.UP: 10902 case $.ui.keyCode.RIGHT: 10903 case $.ui.keyCode.DOWN: 10904 case $.ui.keyCode.LEFT: 10905 event.preventDefault(); 10906 if ( !this._keySliding ) { 10907 this._keySliding = true; 10908 $( event.target ).addClass( "ui-state-active" ); 10909 allowed = this._start( event, index ); 10910 if ( allowed === false ) { 10911 return; 10912 } 10913 } 10914 break; 10915 } 10916 10917 step = this.options.step; 10918 if ( this.options.values && this.options.values.length ) { 10919 curVal = newVal = this.values( index ); 10920 } else { 10921 curVal = newVal = this.value(); 10922 } 10923 10924 switch ( event.keyCode ) { 10925 case $.ui.keyCode.HOME: 10926 newVal = this._valueMin(); 10927 break; 10928 case $.ui.keyCode.END: 10929 newVal = this._valueMax(); 10930 break; 10931 case $.ui.keyCode.PAGE_UP: 10932 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 10933 break; 10934 case $.ui.keyCode.PAGE_DOWN: 10935 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 10936 break; 10937 case $.ui.keyCode.UP: 10938 case $.ui.keyCode.RIGHT: 10939 if ( curVal === this._valueMax() ) { 10940 return; 10941 } 10942 newVal = this._trimAlignValue( curVal + step ); 10943 break; 10944 case $.ui.keyCode.DOWN: 10945 case $.ui.keyCode.LEFT: 10946 if ( curVal === this._valueMin() ) { 10947 return; 10948 } 10949 newVal = this._trimAlignValue( curVal - step ); 10950 break; 10951 } 10952 10953 this._slide( event, index, newVal ); 10954 }, 10955 click: function( event ) { 10956 event.preventDefault(); 10957 }, 10958 keyup: function( event ) { 10959 var index = $( event.target ).data( "ui-slider-handle-index" ); 10960 10961 if ( this._keySliding ) { 10962 this._keySliding = false; 10963 this._stop( event, index ); 10964 this._change( event, index ); 10965 $( event.target ).removeClass( "ui-state-active" ); 10966 } 10967 } 10968 } 10969 10970}); 10971 10972}(jQuery)); 10973(function( $ ) { 10974 10975function modifier( fn ) { 10976 return function() { 10977 var previous = this.element.val(); 10978 fn.apply( this, arguments ); 10979 this._refresh(); 10980 if ( previous !== this.element.val() ) { 10981 this._trigger( "change" ); 10982 } 10983 }; 10984} 10985 10986$.widget( "ui.spinner", { 10987 version: "1.10.1", 10988 defaultElement: "<input>", 10989 widgetEventPrefix: "spin", 10990 options: { 10991 culture: null, 10992 icons: { 10993 down: "ui-icon-triangle-1-s", 10994 up: "ui-icon-triangle-1-n" 10995 }, 10996 incremental: true, 10997 max: null, 10998 min: null, 10999 numberFormat: null, 11000 page: 10, 11001 step: 1, 11002 11003 change: null, 11004 spin: null, 11005 start: null, 11006 stop: null 11007 }, 11008 11009 _create: function() { 11010 // handle string values that need to be parsed 11011 this._setOption( "max", this.options.max ); 11012 this._setOption( "min", this.options.min ); 11013 this._setOption( "step", this.options.step ); 11014 11015 // format the value, but don't constrain 11016 this._value( this.element.val(), true ); 11017 11018 this._draw(); 11019 this._on( this._events ); 11020 this._refresh(); 11021 11022 // turning off autocomplete prevents the browser from remembering the 11023 // value when navigating through history, so we re-enable autocomplete 11024 // if the page is unloaded before the widget is destroyed. #7790 11025 this._on( this.window, { 11026 beforeunload: function() { 11027 this.element.removeAttr( "autocomplete" ); 11028 } 11029 }); 11030 }, 11031 11032 _getCreateOptions: function() { 11033 var options = {}, 11034 element = this.element; 11035 11036 $.each( [ "min", "max", "step" ], function( i, option ) { 11037 var value = element.attr( option ); 11038 if ( value !== undefined && value.length ) { 11039 options[ option ] = value; 11040 } 11041 }); 11042 11043 return options; 11044 }, 11045 11046 _events: { 11047 keydown: function( event ) { 11048 if ( this._start( event ) && this._keydown( event ) ) { 11049 event.preventDefault(); 11050 } 11051 }, 11052 keyup: "_stop", 11053 focus: function() { 11054 this.previous = this.element.val(); 11055 }, 11056 blur: function( event ) { 11057 if ( this.cancelBlur ) { 11058 delete this.cancelBlur; 11059 return; 11060 } 11061 11062 this._refresh(); 11063 if ( this.previous !== this.element.val() ) { 11064 this._trigger( "change", event ); 11065 } 11066 }, 11067 mousewheel: function( event, delta ) { 11068 if ( !delta ) { 11069 return; 11070 } 11071 if ( !this.spinning && !this._start( event ) ) { 11072 return false; 11073 } 11074 11075 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 11076 clearTimeout( this.mousewheelTimer ); 11077 this.mousewheelTimer = this._delay(function() { 11078 if ( this.spinning ) { 11079 this._stop( event ); 11080 } 11081 }, 100 ); 11082 event.preventDefault(); 11083 }, 11084 "mousedown .ui-spinner-button": function( event ) { 11085 var previous; 11086 11087 // We never want the buttons to have focus; whenever the user is 11088 // interacting with the spinner, the focus should be on the input. 11089 // If the input is focused then this.previous is properly set from 11090 // when the input first received focus. If the input is not focused 11091 // then we need to set this.previous based on the value before spinning. 11092 previous = this.element[0] === this.document[0].activeElement ? 11093 this.previous : this.element.val(); 11094 function checkFocus() { 11095 var isActive = this.element[0] === this.document[0].activeElement; 11096 if ( !isActive ) { 11097 this.element.focus(); 11098 this.previous = previous; 11099 // support: IE 11100 // IE sets focus asynchronously, so we need to check if focus 11101 // moved off of the input because the user clicked on the button. 11102 this._delay(function() { 11103 this.previous = previous; 11104 }); 11105 } 11106 } 11107 11108 // ensure focus is on (or stays on) the text field 11109 event.preventDefault(); 11110 checkFocus.call( this ); 11111 11112 // support: IE 11113 // IE doesn't prevent moving focus even with event.preventDefault() 11114 // so we set a flag to know when we should ignore the blur event 11115 // and check (again) if focus moved off of the input. 11116 this.cancelBlur = true; 11117 this._delay(function() { 11118 delete this.cancelBlur; 11119 checkFocus.call( this ); 11120 }); 11121 11122 if ( this._start( event ) === false ) { 11123 return; 11124 } 11125 11126 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11127 }, 11128 "mouseup .ui-spinner-button": "_stop", 11129 "mouseenter .ui-spinner-button": function( event ) { 11130 // button will add ui-state-active if mouse was down while mouseleave and kept down 11131 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 11132 return; 11133 } 11134 11135 if ( this._start( event ) === false ) { 11136 return false; 11137 } 11138 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11139 }, 11140 // TODO: do we really want to consider this a stop? 11141 // shouldn't we just stop the repeater and wait until mouseup before 11142 // we trigger the stop event? 11143 "mouseleave .ui-spinner-button": "_stop" 11144 }, 11145 11146 _draw: function() { 11147 var uiSpinner = this.uiSpinner = this.element 11148 .addClass( "ui-spinner-input" ) 11149 .attr( "autocomplete", "off" ) 11150 .wrap( this._uiSpinnerHtml() ) 11151 .parent() 11152 // add buttons 11153 .append( this._buttonHtml() ); 11154 11155 this.element.attr( "role", "spinbutton" ); 11156 11157 // button bindings 11158 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 11159 .attr( "tabIndex", -1 ) 11160 .button() 11161 .removeClass( "ui-corner-all" ); 11162 11163 // IE 6 doesn't understand height: 50% for the buttons 11164 // unless the wrapper has an explicit height 11165 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 11166 uiSpinner.height() > 0 ) { 11167 uiSpinner.height( uiSpinner.height() ); 11168 } 11169 11170 // disable spinner if element was already disabled 11171 if ( this.options.disabled ) { 11172 this.disable(); 11173 } 11174 }, 11175 11176 _keydown: function( event ) { 11177 var options = this.options, 11178 keyCode = $.ui.keyCode; 11179 11180 switch ( event.keyCode ) { 11181 case keyCode.UP: 11182 this._repeat( null, 1, event ); 11183 return true; 11184 case keyCode.DOWN: 11185 this._repeat( null, -1, event ); 11186 return true; 11187 case keyCode.PAGE_UP: 11188 this._repeat( null, options.page, event ); 11189 return true; 11190 case keyCode.PAGE_DOWN: 11191 this._repeat( null, -options.page, event ); 11192 return true; 11193 } 11194 11195 return false; 11196 }, 11197 11198 _uiSpinnerHtml: function() { 11199 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 11200 }, 11201 11202 _buttonHtml: function() { 11203 return "" + 11204 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 11205 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 11206 "</a>" + 11207 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 11208 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 11209 "</a>"; 11210 }, 11211 11212 _start: function( event ) { 11213 if ( !this.spinning && this._trigger( "start", event ) === false ) { 11214 return false; 11215 } 11216 11217 if ( !this.counter ) { 11218 this.counter = 1; 11219 } 11220 this.spinning = true; 11221 return true; 11222 }, 11223 11224 _repeat: function( i, steps, event ) { 11225 i = i || 500; 11226 11227 clearTimeout( this.timer ); 11228 this.timer = this._delay(function() { 11229 this._repeat( 40, steps, event ); 11230 }, i ); 11231 11232 this._spin( steps * this.options.step, event ); 11233 }, 11234 11235 _spin: function( step, event ) { 11236 var value = this.value() || 0; 11237 11238 if ( !this.counter ) { 11239 this.counter = 1; 11240 } 11241 11242 value = this._adjustValue( value + step * this._increment( this.counter ) ); 11243 11244 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 11245 this._value( value ); 11246 this.counter++; 11247 } 11248 }, 11249 11250 _increment: function( i ) { 11251 var incremental = this.options.incremental; 11252 11253 if ( incremental ) { 11254 return $.isFunction( incremental ) ? 11255 incremental( i ) : 11256 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 11257 } 11258 11259 return 1; 11260 }, 11261 11262 _precision: function() { 11263 var precision = this._precisionOf( this.options.step ); 11264 if ( this.options.min !== null ) { 11265 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 11266 } 11267 return precision; 11268 }, 11269 11270 _precisionOf: function( num ) { 11271 var str = num.toString(), 11272 decimal = str.indexOf( "." ); 11273 return decimal === -1 ? 0 : str.length - decimal - 1; 11274 }, 11275 11276 _adjustValue: function( value ) { 11277 var base, aboveMin, 11278 options = this.options; 11279 11280 // make sure we're at a valid step 11281 // - find out where we are relative to the base (min or 0) 11282 base = options.min !== null ? options.min : 0; 11283 aboveMin = value - base; 11284 // - round to the nearest step 11285 aboveMin = Math.round(aboveMin / options.step) * options.step; 11286 // - rounding is based on 0, so adjust back to our base 11287 value = base + aboveMin; 11288 11289 // fix precision from bad JS floating point math 11290 value = parseFloat( value.toFixed( this._precision() ) ); 11291 11292 // clamp the value 11293 if ( options.max !== null && value > options.max) { 11294 return options.max; 11295 } 11296 if ( options.min !== null && value < options.min ) { 11297 return options.min; 11298 } 11299 11300 return value; 11301 }, 11302 11303 _stop: function( event ) { 11304 if ( !this.spinning ) { 11305 return; 11306 } 11307 11308 clearTimeout( this.timer ); 11309 clearTimeout( this.mousewheelTimer ); 11310 this.counter = 0; 11311 this.spinning = false; 11312 this._trigger( "stop", event ); 11313 }, 11314 11315 _setOption: function( key, value ) { 11316 if ( key === "culture" || key === "numberFormat" ) { 11317 var prevValue = this._parse( this.element.val() ); 11318 this.options[ key ] = value; 11319 this.element.val( this._format( prevValue ) ); 11320 return; 11321 } 11322 11323 if ( key === "max" || key === "min" || key === "step" ) { 11324 if ( typeof value === "string" ) { 11325 value = this._parse( value ); 11326 } 11327 } 11328 if ( key === "icons" ) { 11329 this.buttons.first().find( ".ui-icon" ) 11330 .removeClass( this.options.icons.up ) 11331 .addClass( value.up ); 11332 this.buttons.last().find( ".ui-icon" ) 11333 .removeClass( this.options.icons.down ) 11334 .addClass( value.down ); 11335 } 11336 11337 this._super( key, value ); 11338 11339 if ( key === "disabled" ) { 11340 if ( value ) { 11341 this.element.prop( "disabled", true ); 11342 this.buttons.button( "disable" ); 11343 } else { 11344 this.element.prop( "disabled", false ); 11345 this.buttons.button( "enable" ); 11346 } 11347 } 11348 }, 11349 11350 _setOptions: modifier(function( options ) { 11351 this._super( options ); 11352 this._value( this.element.val() ); 11353 }), 11354 11355 _parse: function( val ) { 11356 if ( typeof val === "string" && val !== "" ) { 11357 val = window.Globalize && this.options.numberFormat ? 11358 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 11359 } 11360 return val === "" || isNaN( val ) ? null : val; 11361 }, 11362 11363 _format: function( value ) { 11364 if ( value === "" ) { 11365 return ""; 11366 } 11367 return window.Globalize && this.options.numberFormat ? 11368 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 11369 value; 11370 }, 11371 11372 _refresh: function() { 11373 this.element.attr({ 11374 "aria-valuemin": this.options.min, 11375 "aria-valuemax": this.options.max, 11376 // TODO: what should we do with values that can't be parsed? 11377 "aria-valuenow": this._parse( this.element.val() ) 11378 }); 11379 }, 11380 11381 // update the value without triggering change 11382 _value: function( value, allowAny ) { 11383 var parsed; 11384 if ( value !== "" ) { 11385 parsed = this._parse( value ); 11386 if ( parsed !== null ) { 11387 if ( !allowAny ) { 11388 parsed = this._adjustValue( parsed ); 11389 } 11390 value = this._format( parsed ); 11391 } 11392 } 11393 this.element.val( value ); 11394 this._refresh(); 11395 }, 11396 11397 _destroy: function() { 11398 this.element 11399 .removeClass( "ui-spinner-input" ) 11400 .prop( "disabled", false ) 11401 .removeAttr( "autocomplete" ) 11402 .removeAttr( "role" ) 11403 .removeAttr( "aria-valuemin" ) 11404 .removeAttr( "aria-valuemax" ) 11405 .removeAttr( "aria-valuenow" ); 11406 this.uiSpinner.replaceWith( this.element ); 11407 }, 11408 11409 stepUp: modifier(function( steps ) { 11410 this._stepUp( steps ); 11411 }), 11412 _stepUp: function( steps ) { 11413 if ( this._start() ) { 11414 this._spin( (steps || 1) * this.options.step ); 11415 this._stop(); 11416 } 11417 }, 11418 11419 stepDown: modifier(function( steps ) { 11420 this._stepDown( steps ); 11421 }), 11422 _stepDown: function( steps ) { 11423 if ( this._start() ) { 11424 this._spin( (steps || 1) * -this.options.step ); 11425 this._stop(); 11426 } 11427 }, 11428 11429 pageUp: modifier(function( pages ) { 11430 this._stepUp( (pages || 1) * this.options.page ); 11431 }), 11432 11433 pageDown: modifier(function( pages ) { 11434 this._stepDown( (pages || 1) * this.options.page ); 11435 }), 11436 11437 value: function( newVal ) { 11438 if ( !arguments.length ) { 11439 return this._parse( this.element.val() ); 11440 } 11441 modifier( this._value ).call( this, newVal ); 11442 }, 11443 11444 widget: function() { 11445 return this.uiSpinner; 11446 } 11447}); 11448 11449}( jQuery ) ); 11450(function( $, undefined ) { 11451 11452var tabId = 0, 11453 rhash = /#.*$/; 11454 11455function getNextTabId() { 11456 return ++tabId; 11457} 11458 11459function isLocal( anchor ) { 11460 return anchor.hash.length > 1 && 11461 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 11462 decodeURIComponent( location.href.replace( rhash, "" ) ); 11463} 11464 11465$.widget( "ui.tabs", { 11466 version: "1.10.1", 11467 delay: 300, 11468 options: { 11469 active: null, 11470 collapsible: false, 11471 event: "click", 11472 heightStyle: "content", 11473 hide: null, 11474 show: null, 11475 11476 // callbacks 11477 activate: null, 11478 beforeActivate: null, 11479 beforeLoad: null, 11480 load: null 11481 }, 11482 11483 _create: function() { 11484 var that = this, 11485 options = this.options; 11486 11487 this.running = false; 11488 11489 this.element 11490 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 11491 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 11492 // Prevent users from focusing disabled tabs via click 11493 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 11494 if ( $( this ).is( ".ui-state-disabled" ) ) { 11495 event.preventDefault(); 11496 } 11497 }) 11498 // support: IE <9 11499 // Preventing the default action in mousedown doesn't prevent IE 11500 // from focusing the element, so if the anchor gets focused, blur. 11501 // We don't have to worry about focusing the previously focused 11502 // element since clicking on a non-focusable element should focus 11503 // the body anyway. 11504 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 11505 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 11506 this.blur(); 11507 } 11508 }); 11509 11510 this._processTabs(); 11511 options.active = this._initialActive(); 11512 11513 // Take disabling tabs via class attribute from HTML 11514 // into account and update option properly. 11515 if ( $.isArray( options.disabled ) ) { 11516 options.disabled = $.unique( options.disabled.concat( 11517 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 11518 return that.tabs.index( li ); 11519 }) 11520 ) ).sort(); 11521 } 11522 11523 // check for length avoids error when initializing empty list 11524 if ( this.options.active !== false && this.anchors.length ) { 11525 this.active = this._findActive( options.active ); 11526 } else { 11527 this.active = $(); 11528 } 11529 11530 this._refresh(); 11531 11532 if ( this.active.length ) { 11533 this.load( options.active ); 11534 } 11535 }, 11536 11537 _initialActive: function() { 11538 var active = this.options.active, 11539 collapsible = this.options.collapsible, 11540 locationHash = location.hash.substring( 1 ); 11541 11542 if ( active === null ) { 11543 // check the fragment identifier in the URL 11544 if ( locationHash ) { 11545 this.tabs.each(function( i, tab ) { 11546 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 11547 active = i; 11548 return false; 11549 } 11550 }); 11551 } 11552 11553 // check for a tab marked active via a class 11554 if ( active === null ) { 11555 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 11556 } 11557 11558 // no active tab, set to false 11559 if ( active === null || active === -1 ) { 11560 active = this.tabs.length ? 0 : false; 11561 } 11562 } 11563 11564 // handle numbers: negative, out of range 11565 if ( active !== false ) { 11566 active = this.tabs.index( this.tabs.eq( active ) ); 11567 if ( active === -1 ) { 11568 active = collapsible ? false : 0; 11569 } 11570 } 11571 11572 // don't allow collapsible: false and active: false 11573 if ( !collapsible && active === false && this.anchors.length ) { 11574 active = 0; 11575 } 11576 11577 return active; 11578 }, 11579 11580 _getCreateEventData: function() { 11581 return { 11582 tab: this.active, 11583 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 11584 }; 11585 }, 11586 11587 _tabKeydown: function( event ) { 11588 /*jshint maxcomplexity:15*/ 11589 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 11590 selectedIndex = this.tabs.index( focusedTab ), 11591 goingForward = true; 11592 11593 if ( this._handlePageNav( event ) ) { 11594 return; 11595 } 11596 11597 switch ( event.keyCode ) { 11598 case $.ui.keyCode.RIGHT: 11599 case $.ui.keyCode.DOWN: 11600 selectedIndex++; 11601 break; 11602 case $.ui.keyCode.UP: 11603 case $.ui.keyCode.LEFT: 11604 goingForward = false; 11605 selectedIndex--; 11606 break; 11607 case $.ui.keyCode.END: 11608 selectedIndex = this.anchors.length - 1; 11609 break; 11610 case $.ui.keyCode.HOME: 11611 selectedIndex = 0; 11612 break; 11613 case $.ui.keyCode.SPACE: 11614 // Activate only, no collapsing 11615 event.preventDefault(); 11616 clearTimeout( this.activating ); 11617 this._activate( selectedIndex ); 11618 return; 11619 case $.ui.keyCode.ENTER: 11620 // Toggle (cancel delayed activation, allow collapsing) 11621 event.preventDefault(); 11622 clearTimeout( this.activating ); 11623 // Determine if we should collapse or activate 11624 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 11625 return; 11626 default: 11627 return; 11628 } 11629 11630 // Focus the appropriate tab, based on which key was pressed 11631 event.preventDefault(); 11632 clearTimeout( this.activating ); 11633 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 11634 11635 // Navigating with control key will prevent automatic activation 11636 if ( !event.ctrlKey ) { 11637 // Update aria-selected immediately so that AT think the tab is already selected. 11638 // Otherwise AT may confuse the user by stating that they need to activate the tab, 11639 // but the tab will already be activated by the time the announcement finishes. 11640 focusedTab.attr( "aria-selected", "false" ); 11641 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 11642 11643 this.activating = this._delay(function() { 11644 this.option( "active", selectedIndex ); 11645 }, this.delay ); 11646 } 11647 }, 11648 11649 _panelKeydown: function( event ) { 11650 if ( this._handlePageNav( event ) ) { 11651 return; 11652 } 11653 11654 // Ctrl+up moves focus to the current tab 11655 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 11656 event.preventDefault(); 11657 this.active.focus(); 11658 } 11659 }, 11660 11661 // Alt+page up/down moves focus to the previous/next tab (and activates) 11662 _handlePageNav: function( event ) { 11663 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 11664 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 11665 return true; 11666 } 11667 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 11668 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 11669 return true; 11670 } 11671 }, 11672 11673 _findNextTab: function( index, goingForward ) { 11674 var lastTabIndex = this.tabs.length - 1; 11675 11676 function constrain() { 11677 if ( index > lastTabIndex ) { 11678 index = 0; 11679 } 11680 if ( index < 0 ) { 11681 index = lastTabIndex; 11682 } 11683 return index; 11684 } 11685 11686 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 11687 index = goingForward ? index + 1 : index - 1; 11688 } 11689 11690 return index; 11691 }, 11692 11693 _focusNextTab: function( index, goingForward ) { 11694 index = this._findNextTab( index, goingForward ); 11695 this.tabs.eq( index ).focus(); 11696 return index; 11697 }, 11698 11699 _setOption: function( key, value ) { 11700 if ( key === "active" ) { 11701 // _activate() will handle invalid values and update this.options 11702 this._activate( value ); 11703 return; 11704 } 11705 11706 if ( key === "disabled" ) { 11707 // don't use the widget factory's disabled handling 11708 this._setupDisabled( value ); 11709 return; 11710 } 11711 11712 this._super( key, value); 11713 11714 if ( key === "collapsible" ) { 11715 this.element.toggleClass( "ui-tabs-collapsible", value ); 11716 // Setting collapsible: false while collapsed; open first panel 11717 if ( !value && this.options.active === false ) { 11718 this._activate( 0 ); 11719 } 11720 } 11721 11722 if ( key === "event" ) { 11723 this._setupEvents( value ); 11724 } 11725 11726 if ( key === "heightStyle" ) { 11727 this._setupHeightStyle( value ); 11728 } 11729 }, 11730 11731 _tabId: function( tab ) { 11732 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 11733 }, 11734 11735 _sanitizeSelector: function( hash ) { 11736 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 11737 }, 11738 11739 refresh: function() { 11740 var options = this.options, 11741 lis = this.tablist.children( ":has(a[href])" ); 11742 11743 // get disabled tabs from class attribute from HTML 11744 // this will get converted to a boolean if needed in _refresh() 11745 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 11746 return lis.index( tab ); 11747 }); 11748 11749 this._processTabs(); 11750 11751 // was collapsed or no tabs 11752 if ( options.active === false || !this.anchors.length ) { 11753 options.active = false; 11754 this.active = $(); 11755 // was active, but active tab is gone 11756 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 11757 // all remaining tabs are disabled 11758 if ( this.tabs.length === options.disabled.length ) { 11759 options.active = false; 11760 this.active = $(); 11761 // activate previous tab 11762 } else { 11763 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 11764 } 11765 // was active, active tab still exists 11766 } else { 11767 // make sure active index is correct 11768 options.active = this.tabs.index( this.active ); 11769 } 11770 11771 this._refresh(); 11772 }, 11773 11774 _refresh: function() { 11775 this._setupDisabled( this.options.disabled ); 11776 this._setupEvents( this.options.event ); 11777 this._setupHeightStyle( this.options.heightStyle ); 11778 11779 this.tabs.not( this.active ).attr({ 11780 "aria-selected": "false", 11781 tabIndex: -1 11782 }); 11783 this.panels.not( this._getPanelForTab( this.active ) ) 11784 .hide() 11785 .attr({ 11786 "aria-expanded": "false", 11787 "aria-hidden": "true" 11788 }); 11789 11790 // Make sure one tab is in the tab order 11791 if ( !this.active.length ) { 11792 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 11793 } else { 11794 this.active 11795 .addClass( "ui-tabs-active ui-state-active" ) 11796 .attr({ 11797 "aria-selected": "true", 11798 tabIndex: 0 11799 }); 11800 this._getPanelForTab( this.active ) 11801 .show() 11802 .attr({ 11803 "aria-expanded": "true", 11804 "aria-hidden": "false" 11805 }); 11806 } 11807 }, 11808 11809 _processTabs: function() { 11810 var that = this; 11811 11812 this.tablist = this._getList() 11813 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 11814 .attr( "role", "tablist" ); 11815 11816 this.tabs = this.tablist.find( "> li:has(a[href])" ) 11817 .addClass( "ui-state-default ui-corner-top" ) 11818 .attr({ 11819 role: "tab", 11820 tabIndex: -1 11821 }); 11822 11823 this.anchors = this.tabs.map(function() { 11824 return $( "a", this )[ 0 ]; 11825 }) 11826 .addClass( "ui-tabs-anchor" ) 11827 .attr({ 11828 role: "presentation", 11829 tabIndex: -1 11830 }); 11831 11832 this.panels = $(); 11833 11834 this.anchors.each(function( i, anchor ) { 11835 var selector, panel, panelId, 11836 anchorId = $( anchor ).uniqueId().attr( "id" ), 11837 tab = $( anchor ).closest( "li" ), 11838 originalAriaControls = tab.attr( "aria-controls" ); 11839 11840 // inline tab 11841 if ( isLocal( anchor ) ) { 11842 selector = anchor.hash; 11843 panel = that.element.find( that._sanitizeSelector( selector ) ); 11844 // remote tab 11845 } else { 11846 panelId = that._tabId( tab ); 11847 selector = "#" + panelId; 11848 panel = that.element.find( selector ); 11849 if ( !panel.length ) { 11850 panel = that._createPanel( panelId ); 11851 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 11852 } 11853 panel.attr( "aria-live", "polite" ); 11854 } 11855 11856 if ( panel.length) { 11857 that.panels = that.panels.add( panel ); 11858 } 11859 if ( originalAriaControls ) { 11860 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 11861 } 11862 tab.attr({ 11863 "aria-controls": selector.substring( 1 ), 11864 "aria-labelledby": anchorId 11865 }); 11866 panel.attr( "aria-labelledby", anchorId ); 11867 }); 11868 11869 this.panels 11870 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11871 .attr( "role", "tabpanel" ); 11872 }, 11873 11874 // allow overriding how to find the list for rare usage scenarios (#7715) 11875 _getList: function() { 11876 return this.element.find( "ol,ul" ).eq( 0 ); 11877 }, 11878 11879 _createPanel: function( id ) { 11880 return $( "<div>" ) 11881 .attr( "id", id ) 11882 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 11883 .data( "ui-tabs-destroy", true ); 11884 }, 11885 11886 _setupDisabled: function( disabled ) { 11887 if ( $.isArray( disabled ) ) { 11888 if ( !disabled.length ) { 11889 disabled = false; 11890 } else if ( disabled.length === this.anchors.length ) { 11891 disabled = true; 11892 } 11893 } 11894 11895 // disable tabs 11896 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 11897 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 11898 $( li ) 11899 .addClass( "ui-state-disabled" ) 11900 .attr( "aria-disabled", "true" ); 11901 } else { 11902 $( li ) 11903 .removeClass( "ui-state-disabled" ) 11904 .removeAttr( "aria-disabled" ); 11905 } 11906 } 11907 11908 this.options.disabled = disabled; 11909 }, 11910 11911 _setupEvents: function( event ) { 11912 var events = { 11913 click: function( event ) { 11914 event.preventDefault(); 11915 } 11916 }; 11917 if ( event ) { 11918 $.each( event.split(" "), function( index, eventName ) { 11919 events[ eventName ] = "_eventHandler"; 11920 }); 11921 } 11922 11923 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 11924 this._on( this.anchors, events ); 11925 this._on( this.tabs, { keydown: "_tabKeydown" } ); 11926 this._on( this.panels, { keydown: "_panelKeydown" } ); 11927 11928 this._focusable( this.tabs ); 11929 this._hoverable( this.tabs ); 11930 }, 11931 11932 _setupHeightStyle: function( heightStyle ) { 11933 var maxHeight, 11934 parent = this.element.parent(); 11935 11936 if ( heightStyle === "fill" ) { 11937 maxHeight = parent.height(); 11938 maxHeight -= this.element.outerHeight() - this.element.height(); 11939 11940 this.element.siblings( ":visible" ).each(function() { 11941 var elem = $( this ), 11942 position = elem.css( "position" ); 11943 11944 if ( position === "absolute" || position === "fixed" ) { 11945 return; 11946 } 11947 maxHeight -= elem.outerHeight( true ); 11948 }); 11949 11950 this.element.children().not( this.panels ).each(function() { 11951 maxHeight -= $( this ).outerHeight( true ); 11952 }); 11953 11954 this.panels.each(function() { 11955 $( this ).height( Math.max( 0, maxHeight - 11956 $( this ).innerHeight() + $( this ).height() ) ); 11957 }) 11958 .css( "overflow", "auto" ); 11959 } else if ( heightStyle === "auto" ) { 11960 maxHeight = 0; 11961 this.panels.each(function() { 11962 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 11963 }).height( maxHeight ); 11964 } 11965 }, 11966 11967 _eventHandler: function( event ) { 11968 var options = this.options, 11969 active = this.active, 11970 anchor = $( event.currentTarget ), 11971 tab = anchor.closest( "li" ), 11972 clickedIsActive = tab[ 0 ] === active[ 0 ], 11973 collapsing = clickedIsActive && options.collapsible, 11974 toShow = collapsing ? $() : this._getPanelForTab( tab ), 11975 toHide = !active.length ? $() : this._getPanelForTab( active ), 11976 eventData = { 11977 oldTab: active, 11978 oldPanel: toHide, 11979 newTab: collapsing ? $() : tab, 11980 newPanel: toShow 11981 }; 11982 11983 event.preventDefault(); 11984 11985 if ( tab.hasClass( "ui-state-disabled" ) || 11986 // tab is already loading 11987 tab.hasClass( "ui-tabs-loading" ) || 11988 // can't switch durning an animation 11989 this.running || 11990 // click on active header, but not collapsible 11991 ( clickedIsActive && !options.collapsible ) || 11992 // allow canceling activation 11993 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 11994 return; 11995 } 11996 11997 options.active = collapsing ? false : this.tabs.index( tab ); 11998 11999 this.active = clickedIsActive ? $() : tab; 12000 if ( this.xhr ) { 12001 this.xhr.abort(); 12002 } 12003 12004 if ( !toHide.length && !toShow.length ) { 12005 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 12006 } 12007 12008 if ( toShow.length ) { 12009 this.load( this.tabs.index( tab ), event ); 12010 } 12011 this._toggle( event, eventData ); 12012 }, 12013 12014 // handles show/hide for selecting tabs 12015 _toggle: function( event, eventData ) { 12016 var that = this, 12017 toShow = eventData.newPanel, 12018 toHide = eventData.oldPanel; 12019 12020 this.running = true; 12021 12022 function complete() { 12023 that.running = false; 12024 that._trigger( "activate", event, eventData ); 12025 } 12026 12027 function show() { 12028 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 12029 12030 if ( toShow.length && that.options.show ) { 12031 that._show( toShow, that.options.show, complete ); 12032 } else { 12033 toShow.show(); 12034 complete(); 12035 } 12036 } 12037 12038 // start out by hiding, then showing, then completing 12039 if ( toHide.length && this.options.hide ) { 12040 this._hide( toHide, this.options.hide, function() { 12041 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12042 show(); 12043 }); 12044 } else { 12045 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12046 toHide.hide(); 12047 show(); 12048 } 12049 12050 toHide.attr({ 12051 "aria-expanded": "false", 12052 "aria-hidden": "true" 12053 }); 12054 eventData.oldTab.attr( "aria-selected", "false" ); 12055 // If we're switching tabs, remove the old tab from the tab order. 12056 // If we're opening from collapsed state, remove the previous tab from the tab order. 12057 // If we're collapsing, then keep the collapsing tab in the tab order. 12058 if ( toShow.length && toHide.length ) { 12059 eventData.oldTab.attr( "tabIndex", -1 ); 12060 } else if ( toShow.length ) { 12061 this.tabs.filter(function() { 12062 return $( this ).attr( "tabIndex" ) === 0; 12063 }) 12064 .attr( "tabIndex", -1 ); 12065 } 12066 12067 toShow.attr({ 12068 "aria-expanded": "true", 12069 "aria-hidden": "false" 12070 }); 12071 eventData.newTab.attr({ 12072 "aria-selected": "true", 12073 tabIndex: 0 12074 }); 12075 }, 12076 12077 _activate: function( index ) { 12078 var anchor, 12079 active = this._findActive( index ); 12080 12081 // trying to activate the already active panel 12082 if ( active[ 0 ] === this.active[ 0 ] ) { 12083 return; 12084 } 12085 12086 // trying to collapse, simulate a click on the current active header 12087 if ( !active.length ) { 12088 active = this.active; 12089 } 12090 12091 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 12092 this._eventHandler({ 12093 target: anchor, 12094 currentTarget: anchor, 12095 preventDefault: $.noop 12096 }); 12097 }, 12098 12099 _findActive: function( index ) { 12100 return index === false ? $() : this.tabs.eq( index ); 12101 }, 12102 12103 _getIndex: function( index ) { 12104 // meta-function to give users option to provide a href string instead of a numerical index. 12105 if ( typeof index === "string" ) { 12106 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 12107 } 12108 12109 return index; 12110 }, 12111 12112 _destroy: function() { 12113 if ( this.xhr ) { 12114 this.xhr.abort(); 12115 } 12116 12117 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 12118 12119 this.tablist 12120 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 12121 .removeAttr( "role" ); 12122 12123 this.anchors 12124 .removeClass( "ui-tabs-anchor" ) 12125 .removeAttr( "role" ) 12126 .removeAttr( "tabIndex" ) 12127 .removeUniqueId(); 12128 12129 this.tabs.add( this.panels ).each(function() { 12130 if ( $.data( this, "ui-tabs-destroy" ) ) { 12131 $( this ).remove(); 12132 } else { 12133 $( this ) 12134 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 12135 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 12136 .removeAttr( "tabIndex" ) 12137 .removeAttr( "aria-live" ) 12138 .removeAttr( "aria-busy" ) 12139 .removeAttr( "aria-selected" ) 12140 .removeAttr( "aria-labelledby" ) 12141 .removeAttr( "aria-hidden" ) 12142 .removeAttr( "aria-expanded" ) 12143 .removeAttr( "role" ); 12144 } 12145 }); 12146 12147 this.tabs.each(function() { 12148 var li = $( this ), 12149 prev = li.data( "ui-tabs-aria-controls" ); 12150 if ( prev ) { 12151 li 12152 .attr( "aria-controls", prev ) 12153 .removeData( "ui-tabs-aria-controls" ); 12154 } else { 12155 li.removeAttr( "aria-controls" ); 12156 } 12157 }); 12158 12159 this.panels.show(); 12160 12161 if ( this.options.heightStyle !== "content" ) { 12162 this.panels.css( "height", "" ); 12163 } 12164 }, 12165 12166 enable: function( index ) { 12167 var disabled = this.options.disabled; 12168 if ( disabled === false ) { 12169 return; 12170 } 12171 12172 if ( index === undefined ) { 12173 disabled = false; 12174 } else { 12175 index = this._getIndex( index ); 12176 if ( $.isArray( disabled ) ) { 12177 disabled = $.map( disabled, function( num ) { 12178 return num !== index ? num : null; 12179 }); 12180 } else { 12181 disabled = $.map( this.tabs, function( li, num ) { 12182 return num !== index ? num : null; 12183 }); 12184 } 12185 } 12186 this._setupDisabled( disabled ); 12187 }, 12188 12189 disable: function( index ) { 12190 var disabled = this.options.disabled; 12191 if ( disabled === true ) { 12192 return; 12193 } 12194 12195 if ( index === undefined ) { 12196 disabled = true; 12197 } else { 12198 index = this._getIndex( index ); 12199 if ( $.inArray( index, disabled ) !== -1 ) { 12200 return; 12201 } 12202 if ( $.isArray( disabled ) ) { 12203 disabled = $.merge( [ index ], disabled ).sort(); 12204 } else { 12205 disabled = [ index ]; 12206 } 12207 } 12208 this._setupDisabled( disabled ); 12209 }, 12210 12211 load: function( index, event ) { 12212 index = this._getIndex( index ); 12213 var that = this, 12214 tab = this.tabs.eq( index ), 12215 anchor = tab.find( ".ui-tabs-anchor" ), 12216 panel = this._getPanelForTab( tab ), 12217 eventData = { 12218 tab: tab, 12219 panel: panel 12220 }; 12221 12222 // not remote 12223 if ( isLocal( anchor[ 0 ] ) ) { 12224 return; 12225 } 12226 12227 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 12228 12229 // support: jQuery <1.8 12230 // jQuery <1.8 returns false if the request is canceled in beforeSend, 12231 // but as of 1.8, $.ajax() always returns a jqXHR object. 12232 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 12233 tab.addClass( "ui-tabs-loading" ); 12234 panel.attr( "aria-busy", "true" ); 12235 12236 this.xhr 12237 .success(function( response ) { 12238 // support: jQuery <1.8 12239 // http://bugs.jquery.com/ticket/11778 12240 setTimeout(function() { 12241 panel.html( response ); 12242 that._trigger( "load", event, eventData ); 12243 }, 1 ); 12244 }) 12245 .complete(function( jqXHR, status ) { 12246 // support: jQuery <1.8 12247 // http://bugs.jquery.com/ticket/11778 12248 setTimeout(function() { 12249 if ( status === "abort" ) { 12250 that.panels.stop( false, true ); 12251 } 12252 12253 tab.removeClass( "ui-tabs-loading" ); 12254 panel.removeAttr( "aria-busy" ); 12255 12256 if ( jqXHR === that.xhr ) { 12257 delete that.xhr; 12258 } 12259 }, 1 ); 12260 }); 12261 } 12262 }, 12263 12264 _ajaxSettings: function( anchor, event, eventData ) { 12265 var that = this; 12266 return { 12267 url: anchor.attr( "href" ), 12268 beforeSend: function( jqXHR, settings ) { 12269 return that._trigger( "beforeLoad", event, 12270 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 12271 } 12272 }; 12273 }, 12274 12275 _getPanelForTab: function( tab ) { 12276 var id = $( tab ).attr( "aria-controls" ); 12277 return this.element.find( this._sanitizeSelector( "#" + id ) ); 12278 } 12279}); 12280 12281})( jQuery ); 12282(function( $ ) { 12283 12284var increments = 0; 12285 12286function addDescribedBy( elem, id ) { 12287 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 12288 describedby.push( id ); 12289 elem 12290 .data( "ui-tooltip-id", id ) 12291 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 12292} 12293 12294function removeDescribedBy( elem ) { 12295 var id = elem.data( "ui-tooltip-id" ), 12296 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 12297 index = $.inArray( id, describedby ); 12298 if ( index !== -1 ) { 12299 describedby.splice( index, 1 ); 12300 } 12301 12302 elem.removeData( "ui-tooltip-id" ); 12303 describedby = $.trim( describedby.join( " " ) ); 12304 if ( describedby ) { 12305 elem.attr( "aria-describedby", describedby ); 12306 } else { 12307 elem.removeAttr( "aria-describedby" ); 12308 } 12309} 12310 12311$.widget( "ui.tooltip", { 12312 version: "1.10.1", 12313 options: { 12314 content: function() { 12315 // support: IE<9, Opera in jQuery <1.7 12316 // .text() can't accept undefined, so coerce to a string 12317 var title = $( this ).attr( "title" ) || ""; 12318 // Escape title, since we're going from an attribute to raw HTML 12319 return $( "<a>" ).text( title ).html(); 12320 }, 12321 hide: true, 12322 // Disabled elements have inconsistent behavior across browsers (#8661) 12323 items: "[title]:not([disabled])", 12324 position: { 12325 my: "left top+15", 12326 at: "left bottom", 12327 collision: "flipfit flip" 12328 }, 12329 show: true, 12330 tooltipClass: null, 12331 track: false, 12332 12333 // callbacks 12334 close: null, 12335 open: null 12336 }, 12337 12338 _create: function() { 12339 this._on({ 12340 mouseover: "open", 12341 focusin: "open" 12342 }); 12343 12344 // IDs of generated tooltips, needed for destroy 12345 this.tooltips = {}; 12346 // IDs of parent tooltips where we removed the title attribute 12347 this.parents = {}; 12348 12349 if ( this.options.disabled ) { 12350 this._disable(); 12351 } 12352 }, 12353 12354 _setOption: function( key, value ) { 12355 var that = this; 12356 12357 if ( key === "disabled" ) { 12358 this[ value ? "_disable" : "_enable" ](); 12359 this.options[ key ] = value; 12360 // disable element style changes 12361 return; 12362 } 12363 12364 this._super( key, value ); 12365 12366 if ( key === "content" ) { 12367 $.each( this.tooltips, function( id, element ) { 12368 that._updateContent( element ); 12369 }); 12370 } 12371 }, 12372 12373 _disable: function() { 12374 var that = this; 12375 12376 // close open tooltips 12377 $.each( this.tooltips, function( id, element ) { 12378 var event = $.Event( "blur" ); 12379 event.target = event.currentTarget = element[0]; 12380 that.close( event, true ); 12381 }); 12382 12383 // remove title attributes to prevent native tooltips 12384 this.element.find( this.options.items ).addBack().each(function() { 12385 var element = $( this ); 12386 if ( element.is( "[title]" ) ) { 12387 element 12388 .data( "ui-tooltip-title", element.attr( "title" ) ) 12389 .attr( "title", "" ); 12390 } 12391 }); 12392 }, 12393 12394 _enable: function() { 12395 // restore title attributes 12396 this.element.find( this.options.items ).addBack().each(function() { 12397 var element = $( this ); 12398 if ( element.data( "ui-tooltip-title" ) ) { 12399 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12400 } 12401 }); 12402 }, 12403 12404 open: function( event ) { 12405 var that = this, 12406 target = $( event ? event.target : this.element ) 12407 // we need closest here due to mouseover bubbling, 12408 // but always pointing at the same event target 12409 .closest( this.options.items ); 12410 12411 // No element to show a tooltip for or the tooltip is already open 12412 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 12413 return; 12414 } 12415 12416 if ( target.attr( "title" ) ) { 12417 target.data( "ui-tooltip-title", target.attr( "title" ) ); 12418 } 12419 12420 target.data( "ui-tooltip-open", true ); 12421 12422 // kill parent tooltips, custom or native, for hover 12423 if ( event && event.type === "mouseover" ) { 12424 target.parents().each(function() { 12425 var parent = $( this ), 12426 blurEvent; 12427 if ( parent.data( "ui-tooltip-open" ) ) { 12428 blurEvent = $.Event( "blur" ); 12429 blurEvent.target = blurEvent.currentTarget = this; 12430 that.close( blurEvent, true ); 12431 } 12432 if ( parent.attr( "title" ) ) { 12433 parent.uniqueId(); 12434 that.parents[ this.id ] = { 12435 element: this, 12436 title: parent.attr( "title" ) 12437 }; 12438 parent.attr( "title", "" ); 12439 } 12440 }); 12441 } 12442 12443 this._updateContent( target, event ); 12444 }, 12445 12446 _updateContent: function( target, event ) { 12447 var content, 12448 contentOption = this.options.content, 12449 that = this, 12450 eventType = event ? event.type : null; 12451 12452 if ( typeof contentOption === "string" ) { 12453 return this._open( event, target, contentOption ); 12454 } 12455 12456 content = contentOption.call( target[0], function( response ) { 12457 // ignore async response if tooltip was closed already 12458 if ( !target.data( "ui-tooltip-open" ) ) { 12459 return; 12460 } 12461 // IE may instantly serve a cached response for ajax requests 12462 // delay this call to _open so the other call to _open runs first 12463 that._delay(function() { 12464 // jQuery creates a special event for focusin when it doesn't 12465 // exist natively. To improve performance, the native event 12466 // object is reused and the type is changed. Therefore, we can't 12467 // rely on the type being correct after the event finished 12468 // bubbling, so we set it back to the previous value. (#8740) 12469 if ( event ) { 12470 event.type = eventType; 12471 } 12472 this._open( event, target, response ); 12473 }); 12474 }); 12475 if ( content ) { 12476 this._open( event, target, content ); 12477 } 12478 }, 12479 12480 _open: function( event, target, content ) { 12481 var tooltip, events, delayedShow, 12482 positionOption = $.extend( {}, this.options.position ); 12483 12484 if ( !content ) { 12485 return; 12486 } 12487 12488 // Content can be updated multiple times. If the tooltip already 12489 // exists, then just update the content and bail. 12490 tooltip = this._find( target ); 12491 if ( tooltip.length ) { 12492 tooltip.find( ".ui-tooltip-content" ).html( content ); 12493 return; 12494 } 12495 12496 // if we have a title, clear it to prevent the native tooltip 12497 // we have to check first to avoid defining a title if none exists 12498 // (we don't want to cause an element to start matching [title]) 12499 // 12500 // We use removeAttr only for key events, to allow IE to export the correct 12501 // accessible attributes. For mouse events, set to empty string to avoid 12502 // native tooltip showing up (happens only when removing inside mouseover). 12503 if ( target.is( "[title]" ) ) { 12504 if ( event && event.type === "mouseover" ) { 12505 target.attr( "title", "" ); 12506 } else { 12507 target.removeAttr( "title" ); 12508 } 12509 } 12510 12511 tooltip = this._tooltip( target ); 12512 addDescribedBy( target, tooltip.attr( "id" ) ); 12513 tooltip.find( ".ui-tooltip-content" ).html( content ); 12514 12515 function position( event ) { 12516 positionOption.of = event; 12517 if ( tooltip.is( ":hidden" ) ) { 12518 return; 12519 } 12520 tooltip.position( positionOption ); 12521 } 12522 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 12523 this._on( this.document, { 12524 mousemove: position 12525 }); 12526 // trigger once to override element-relative positioning 12527 position( event ); 12528 } else { 12529 tooltip.position( $.extend({ 12530 of: target 12531 }, this.options.position ) ); 12532 } 12533 12534 tooltip.hide(); 12535 12536 this._show( tooltip, this.options.show ); 12537 // Handle tracking tooltips that are shown with a delay (#8644). As soon 12538 // as the tooltip is visible, position the tooltip using the most recent 12539 // event. 12540 if ( this.options.show && this.options.show.delay ) { 12541 delayedShow = this.delayedShow = setInterval(function() { 12542 if ( tooltip.is( ":visible" ) ) { 12543 position( positionOption.of ); 12544 clearInterval( delayedShow ); 12545 } 12546 }, $.fx.interval ); 12547 } 12548 12549 this._trigger( "open", event, { tooltip: tooltip } ); 12550 12551 events = { 12552 keyup: function( event ) { 12553 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 12554 var fakeEvent = $.Event(event); 12555 fakeEvent.currentTarget = target[0]; 12556 this.close( fakeEvent, true ); 12557 } 12558 }, 12559 remove: function() { 12560 this._removeTooltip( tooltip ); 12561 } 12562 }; 12563 if ( !event || event.type === "mouseover" ) { 12564 events.mouseleave = "close"; 12565 } 12566 if ( !event || event.type === "focusin" ) { 12567 events.focusout = "close"; 12568 } 12569 this._on( true, target, events ); 12570 }, 12571 12572 close: function( event ) { 12573 var that = this, 12574 target = $( event ? event.currentTarget : this.element ), 12575 tooltip = this._find( target ); 12576 12577 // disabling closes the tooltip, so we need to track when we're closing 12578 // to avoid an infinite loop in case the tooltip becomes disabled on close 12579 if ( this.closing ) { 12580 return; 12581 } 12582 12583 // Clear the interval for delayed tracking tooltips 12584 clearInterval( this.delayedShow ); 12585 12586 // only set title if we had one before (see comment in _open()) 12587 if ( target.data( "ui-tooltip-title" ) ) { 12588 target.attr( "title", target.data( "ui-tooltip-title" ) ); 12589 } 12590 12591 removeDescribedBy( target ); 12592 12593 tooltip.stop( true ); 12594 this._hide( tooltip, this.options.hide, function() { 12595 that._removeTooltip( $( this ) ); 12596 }); 12597 12598 target.removeData( "ui-tooltip-open" ); 12599 this._off( target, "mouseleave focusout keyup" ); 12600 // Remove 'remove' binding only on delegated targets 12601 if ( target[0] !== this.element[0] ) { 12602 this._off( target, "remove" ); 12603 } 12604 this._off( this.document, "mousemove" ); 12605 12606 if ( event && event.type === "mouseleave" ) { 12607 $.each( this.parents, function( id, parent ) { 12608 $( parent.element ).attr( "title", parent.title ); 12609 delete that.parents[ id ]; 12610 }); 12611 } 12612 12613 this.closing = true; 12614 this._trigger( "close", event, { tooltip: tooltip } ); 12615 this.closing = false; 12616 }, 12617 12618 _tooltip: function( element ) { 12619 var id = "ui-tooltip-" + increments++, 12620 tooltip = $( "<div>" ) 12621 .attr({ 12622 id: id, 12623 role: "tooltip" 12624 }) 12625 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 12626 ( this.options.tooltipClass || "" ) ); 12627 $( "<div>" ) 12628 .addClass( "ui-tooltip-content" ) 12629 .appendTo( tooltip ); 12630 tooltip.appendTo( this.document[0].body ); 12631 this.tooltips[ id ] = element; 12632 return tooltip; 12633 }, 12634 12635 _find: function( target ) { 12636 var id = target.data( "ui-tooltip-id" ); 12637 return id ? $( "#" + id ) : $(); 12638 }, 12639 12640 _removeTooltip: function( tooltip ) { 12641 tooltip.remove(); 12642 delete this.tooltips[ tooltip.attr( "id" ) ]; 12643 }, 12644 12645 _destroy: function() { 12646 var that = this; 12647 12648 // close open tooltips 12649 $.each( this.tooltips, function( id, element ) { 12650 // Delegate to close method to handle common cleanup 12651 var event = $.Event( "blur" ); 12652 event.target = event.currentTarget = element[0]; 12653 that.close( event, true ); 12654 12655 // Remove immediately; destroying an open tooltip doesn't use the 12656 // hide animation 12657 $( "#" + id ).remove(); 12658 12659 // Restore the title 12660 if ( element.data( "ui-tooltip-title" ) ) { 12661 element.attr( "title", element.data( "ui-tooltip-title" ) ); 12662 element.removeData( "ui-tooltip-title" ); 12663 } 12664 }); 12665 } 12666}); 12667 12668}( jQuery ) ); 12669;(jQuery.effects || (function($, undefined) { 12670 12671var dataSpace = "ui-effects-"; 12672 12673$.effects = { 12674 effect: {} 12675}; 12676 12677/*! 12678 * jQuery Color Animations v2.1.2 12679 * https://github.com/jquery/jquery-color 12680 * 12681 * Copyright 2013 jQuery Foundation and other contributors 12682 * Released under the MIT license. 12683 * http://jquery.org/license 12684 * 12685 * Date: Wed Jan 16 08:47:09 2013 -0600 12686 */ 12687(function( jQuery, undefined ) { 12688 12689 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 12690 12691 // plusequals test for += 100 -= 100 12692 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 12693 // a set of RE's that can match strings and generate color tuples. 12694 stringParsers = [{ 12695 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12696 parse: function( execResult ) { 12697 return [ 12698 execResult[ 1 ], 12699 execResult[ 2 ], 12700 execResult[ 3 ], 12701 execResult[ 4 ] 12702 ]; 12703 } 12704 }, { 12705 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12706 parse: function( execResult ) { 12707 return [ 12708 execResult[ 1 ] * 2.55, 12709 execResult[ 2 ] * 2.55, 12710 execResult[ 3 ] * 2.55, 12711 execResult[ 4 ] 12712 ]; 12713 } 12714 }, { 12715 // this regex ignores A-F because it's compared against an already lowercased string 12716 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 12717 parse: function( execResult ) { 12718 return [ 12719 parseInt( execResult[ 1 ], 16 ), 12720 parseInt( execResult[ 2 ], 16 ), 12721 parseInt( execResult[ 3 ], 16 ) 12722 ]; 12723 } 12724 }, { 12725 // this regex ignores A-F because it's compared against an already lowercased string 12726 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 12727 parse: function( execResult ) { 12728 return [ 12729 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 12730 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 12731 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 12732 ]; 12733 } 12734 }, { 12735 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12736 space: "hsla", 12737 parse: function( execResult ) { 12738 return [ 12739 execResult[ 1 ], 12740 execResult[ 2 ] / 100, 12741 execResult[ 3 ] / 100, 12742 execResult[ 4 ] 12743 ]; 12744 } 12745 }], 12746 12747 // jQuery.Color( ) 12748 color = jQuery.Color = function( color, green, blue, alpha ) { 12749 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 12750 }, 12751 spaces = { 12752 rgba: { 12753 props: { 12754 red: { 12755 idx: 0, 12756 type: "byte" 12757 }, 12758 green: { 12759 idx: 1, 12760 type: "byte" 12761 }, 12762 blue: { 12763 idx: 2, 12764 type: "byte" 12765 } 12766 } 12767 }, 12768 12769 hsla: { 12770 props: { 12771 hue: { 12772 idx: 0, 12773 type: "degrees" 12774 }, 12775 saturation: { 12776 idx: 1, 12777 type: "percent" 12778 }, 12779 lightness: { 12780 idx: 2, 12781 type: "percent" 12782 } 12783 } 12784 } 12785 }, 12786 propTypes = { 12787 "byte": { 12788 floor: true, 12789 max: 255 12790 }, 12791 "percent": { 12792 max: 1 12793 }, 12794 "degrees": { 12795 mod: 360, 12796 floor: true 12797 } 12798 }, 12799 support = color.support = {}, 12800 12801 // element for support tests 12802 supportElem = jQuery( "<p>" )[ 0 ], 12803 12804 // colors = jQuery.Color.names 12805 colors, 12806 12807 // local aliases of functions called often 12808 each = jQuery.each; 12809 12810// determine rgba support immediately 12811supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 12812support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 12813 12814// define cache name and alpha properties 12815// for rgba and hsla spaces 12816each( spaces, function( spaceName, space ) { 12817 space.cache = "_" + spaceName; 12818 space.props.alpha = { 12819 idx: 3, 12820 type: "percent", 12821 def: 1 12822 }; 12823}); 12824 12825function clamp( value, prop, allowEmpty ) { 12826 var type = propTypes[ prop.type ] || {}; 12827 12828 if ( value == null ) { 12829 return (allowEmpty || !prop.def) ? null : prop.def; 12830 } 12831 12832 // ~~ is an short way of doing floor for positive numbers 12833 value = type.floor ? ~~value : parseFloat( value ); 12834 12835 // IE will pass in empty strings as value for alpha, 12836 // which will hit this case 12837 if ( isNaN( value ) ) { 12838 return prop.def; 12839 } 12840 12841 if ( type.mod ) { 12842 // we add mod before modding to make sure that negatives values 12843 // get converted properly: -10 -> 350 12844 return (value + type.mod) % type.mod; 12845 } 12846 12847 // for now all property types without mod have min and max 12848 return 0 > value ? 0 : type.max < value ? type.max : value; 12849} 12850 12851function stringParse( string ) { 12852 var inst = color(), 12853 rgba = inst._rgba = []; 12854 12855 string = string.toLowerCase(); 12856 12857 each( stringParsers, function( i, parser ) { 12858 var parsed, 12859 match = parser.re.exec( string ), 12860 values = match && parser.parse( match ), 12861 spaceName = parser.space || "rgba"; 12862 12863 if ( values ) { 12864 parsed = inst[ spaceName ]( values ); 12865 12866 // if this was an rgba parse the assignment might happen twice 12867 // oh well.... 12868 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12869 rgba = inst._rgba = parsed._rgba; 12870 12871 // exit each( stringParsers ) here because we matched 12872 return false; 12873 } 12874 }); 12875 12876 // Found a stringParser that handled it 12877 if ( rgba.length ) { 12878 12879 // if this came from a parsed string, force "transparent" when alpha is 0 12880 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12881 if ( rgba.join() === "0,0,0,0" ) { 12882 jQuery.extend( rgba, colors.transparent ); 12883 } 12884 return inst; 12885 } 12886 12887 // named colors 12888 return colors[ string ]; 12889} 12890 12891color.fn = jQuery.extend( color.prototype, { 12892 parse: function( red, green, blue, alpha ) { 12893 if ( red === undefined ) { 12894 this._rgba = [ null, null, null, null ]; 12895 return this; 12896 } 12897 if ( red.jquery || red.nodeType ) { 12898 red = jQuery( red ).css( green ); 12899 green = undefined; 12900 } 12901 12902 var inst = this, 12903 type = jQuery.type( red ), 12904 rgba = this._rgba = []; 12905 12906 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12907 if ( green !== undefined ) { 12908 red = [ red, green, blue, alpha ]; 12909 type = "array"; 12910 } 12911 12912 if ( type === "string" ) { 12913 return this.parse( stringParse( red ) || colors._default ); 12914 } 12915 12916 if ( type === "array" ) { 12917 each( spaces.rgba.props, function( key, prop ) { 12918 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 12919 }); 12920 return this; 12921 } 12922 12923 if ( type === "object" ) { 12924 if ( red instanceof color ) { 12925 each( spaces, function( spaceName, space ) { 12926 if ( red[ space.cache ] ) { 12927 inst[ space.cache ] = red[ space.cache ].slice(); 12928 } 12929 }); 12930 } else { 12931 each( spaces, function( spaceName, space ) { 12932 var cache = space.cache; 12933 each( space.props, function( key, prop ) { 12934 12935 // if the cache doesn't exist, and we know how to convert 12936 if ( !inst[ cache ] && space.to ) { 12937 12938 // if the value was null, we don't need to copy it 12939 // if the key was alpha, we don't need to copy it either 12940 if ( key === "alpha" || red[ key ] == null ) { 12941 return; 12942 } 12943 inst[ cache ] = space.to( inst._rgba ); 12944 } 12945 12946 // this is the only case where we allow nulls for ALL properties. 12947 // call clamp with alwaysAllowEmpty 12948 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 12949 }); 12950 12951 // everything defined but alpha? 12952 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 12953 // use the default of 1 12954 inst[ cache ][ 3 ] = 1; 12955 if ( space.from ) { 12956 inst._rgba = space.from( inst[ cache ] ); 12957 } 12958 } 12959 }); 12960 } 12961 return this; 12962 } 12963 }, 12964 is: function( compare ) { 12965 var is = color( compare ), 12966 same = true, 12967 inst = this; 12968 12969 each( spaces, function( _, space ) { 12970 var localCache, 12971 isCache = is[ space.cache ]; 12972 if (isCache) { 12973 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 12974 each( space.props, function( _, prop ) { 12975 if ( isCache[ prop.idx ] != null ) { 12976 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 12977 return same; 12978 } 12979 }); 12980 } 12981 return same; 12982 }); 12983 return same; 12984 }, 12985 _space: function() { 12986 var used = [], 12987 inst = this; 12988 each( spaces, function( spaceName, space ) { 12989 if ( inst[ space.cache ] ) { 12990 used.push( spaceName ); 12991 } 12992 }); 12993 return used.pop(); 12994 }, 12995 transition: function( other, distance ) { 12996 var end = color( other ), 12997 spaceName = end._space(), 12998 space = spaces[ spaceName ], 12999 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 13000 start = startColor[ space.cache ] || space.to( startColor._rgba ), 13001 result = start.slice(); 13002 13003 end = end[ space.cache ]; 13004 each( space.props, function( key, prop ) { 13005 var index = prop.idx, 13006 startValue = start[ index ], 13007 endValue = end[ index ], 13008 type = propTypes[ prop.type ] || {}; 13009 13010 // if null, don't override start value 13011 if ( endValue === null ) { 13012 return; 13013 } 13014 // if null - use end 13015 if ( startValue === null ) { 13016 result[ index ] = endValue; 13017 } else { 13018 if ( type.mod ) { 13019 if ( endValue - startValue > type.mod / 2 ) { 13020 startValue += type.mod; 13021 } else if ( startValue - endValue > type.mod / 2 ) { 13022 startValue -= type.mod; 13023 } 13024 } 13025 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 13026 } 13027 }); 13028 return this[ spaceName ]( result ); 13029 }, 13030 blend: function( opaque ) { 13031 // if we are already opaque - return ourself 13032 if ( this._rgba[ 3 ] === 1 ) { 13033 return this; 13034 } 13035 13036 var rgb = this._rgba.slice(), 13037 a = rgb.pop(), 13038 blend = color( opaque )._rgba; 13039 13040 return color( jQuery.map( rgb, function( v, i ) { 13041 return ( 1 - a ) * blend[ i ] + a * v; 13042 })); 13043 }, 13044 toRgbaString: function() { 13045 var prefix = "rgba(", 13046 rgba = jQuery.map( this._rgba, function( v, i ) { 13047 return v == null ? ( i > 2 ? 1 : 0 ) : v; 13048 }); 13049 13050 if ( rgba[ 3 ] === 1 ) { 13051 rgba.pop(); 13052 prefix = "rgb("; 13053 } 13054 13055 return prefix + rgba.join() + ")"; 13056 }, 13057 toHslaString: function() { 13058 var prefix = "hsla(", 13059 hsla = jQuery.map( this.hsla(), function( v, i ) { 13060 if ( v == null ) { 13061 v = i > 2 ? 1 : 0; 13062 } 13063 13064 // catch 1 and 2 13065 if ( i && i < 3 ) { 13066 v = Math.round( v * 100 ) + "%"; 13067 } 13068 return v; 13069 }); 13070 13071 if ( hsla[ 3 ] === 1 ) { 13072 hsla.pop(); 13073 prefix = "hsl("; 13074 } 13075 return prefix + hsla.join() + ")"; 13076 }, 13077 toHexString: function( includeAlpha ) { 13078 var rgba = this._rgba.slice(), 13079 alpha = rgba.pop(); 13080 13081 if ( includeAlpha ) { 13082 rgba.push( ~~( alpha * 255 ) ); 13083 } 13084 13085 return "#" + jQuery.map( rgba, function( v ) { 13086 13087 // default to 0 when nulls exist 13088 v = ( v || 0 ).toString( 16 ); 13089 return v.length === 1 ? "0" + v : v; 13090 }).join(""); 13091 }, 13092 toString: function() { 13093 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 13094 } 13095}); 13096color.fn.parse.prototype = color.fn; 13097 13098// hsla conversions adapted from: 13099// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 13100 13101function hue2rgb( p, q, h ) { 13102 h = ( h + 1 ) % 1; 13103 if ( h * 6 < 1 ) { 13104 return p + (q - p) * h * 6; 13105 } 13106 if ( h * 2 < 1) { 13107 return q; 13108 } 13109 if ( h * 3 < 2 ) { 13110 return p + (q - p) * ((2/3) - h) * 6; 13111 } 13112 return p; 13113} 13114 13115spaces.hsla.to = function ( rgba ) { 13116 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 13117 return [ null, null, null, rgba[ 3 ] ]; 13118 } 13119 var r = rgba[ 0 ] / 255, 13120 g = rgba[ 1 ] / 255, 13121 b = rgba[ 2 ] / 255, 13122 a = rgba[ 3 ], 13123 max = Math.max( r, g, b ), 13124 min = Math.min( r, g, b ), 13125 diff = max - min, 13126 add = max + min, 13127 l = add * 0.5, 13128 h, s; 13129 13130 if ( min === max ) { 13131 h = 0; 13132 } else if ( r === max ) { 13133 h = ( 60 * ( g - b ) / diff ) + 360; 13134 } else if ( g === max ) { 13135 h = ( 60 * ( b - r ) / diff ) + 120; 13136 } else { 13137 h = ( 60 * ( r - g ) / diff ) + 240; 13138 } 13139 13140 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 13141 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 13142 if ( diff === 0 ) { 13143 s = 0; 13144 } else if ( l <= 0.5 ) { 13145 s = diff / add; 13146 } else { 13147 s = diff / ( 2 - add ); 13148 } 13149 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 13150}; 13151 13152spaces.hsla.from = function ( hsla ) { 13153 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 13154 return [ null, null, null, hsla[ 3 ] ]; 13155 } 13156 var h = hsla[ 0 ] / 360, 13157 s = hsla[ 1 ], 13158 l = hsla[ 2 ], 13159 a = hsla[ 3 ], 13160 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 13161 p = 2 * l - q; 13162 13163 return [ 13164 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 13165 Math.round( hue2rgb( p, q, h ) * 255 ), 13166 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 13167 a 13168 ]; 13169}; 13170 13171 13172each( spaces, function( spaceName, space ) { 13173 var props = space.props, 13174 cache = space.cache, 13175 to = space.to, 13176 from = space.from; 13177 13178 // makes rgba() and hsla() 13179 color.fn[ spaceName ] = function( value ) { 13180 13181 // generate a cache for this space if it doesn't exist 13182 if ( to && !this[ cache ] ) { 13183 this[ cache ] = to( this._rgba ); 13184 } 13185 if ( value === undefined ) { 13186 return this[ cache ].slice(); 13187 } 13188 13189 var ret, 13190 type = jQuery.type( value ), 13191 arr = ( type === "array" || type === "object" ) ? value : arguments, 13192 local = this[ cache ].slice(); 13193 13194 each( props, function( key, prop ) { 13195 var val = arr[ type === "object" ? key : prop.idx ]; 13196 if ( val == null ) { 13197 val = local[ prop.idx ]; 13198 } 13199 local[ prop.idx ] = clamp( val, prop ); 13200 }); 13201 13202 if ( from ) { 13203 ret = color( from( local ) ); 13204 ret[ cache ] = local; 13205 return ret; 13206 } else { 13207 return color( local ); 13208 } 13209 }; 13210 13211 // makes red() green() blue() alpha() hue() saturation() lightness() 13212 each( props, function( key, prop ) { 13213 // alpha is included in more than one space 13214 if ( color.fn[ key ] ) { 13215 return; 13216 } 13217 color.fn[ key ] = function( value ) { 13218 var vtype = jQuery.type( value ), 13219 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 13220 local = this[ fn ](), 13221 cur = local[ prop.idx ], 13222 match; 13223 13224 if ( vtype === "undefined" ) { 13225 return cur; 13226 } 13227 13228 if ( vtype === "function" ) { 13229 value = value.call( this, cur ); 13230 vtype = jQuery.type( value ); 13231 } 13232 if ( value == null && prop.empty ) { 13233 return this; 13234 } 13235 if ( vtype === "string" ) { 13236 match = rplusequals.exec( value ); 13237 if ( match ) { 13238 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 13239 } 13240 } 13241 local[ prop.idx ] = value; 13242 return this[ fn ]( local ); 13243 }; 13244 }); 13245}); 13246 13247// add cssHook and .fx.step function for each named hook. 13248// accept a space separated string of properties 13249color.hook = function( hook ) { 13250 var hooks = hook.split( " " ); 13251 each( hooks, function( i, hook ) { 13252 jQuery.cssHooks[ hook ] = { 13253 set: function( elem, value ) { 13254 var parsed, curElem, 13255 backgroundColor = ""; 13256 13257 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 13258 value = color( parsed || value ); 13259 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 13260 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 13261 while ( 13262 (backgroundColor === "" || backgroundColor === "transparent") && 13263 curElem && curElem.style 13264 ) { 13265 try { 13266 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 13267 curElem = curElem.parentNode; 13268 } catch ( e ) { 13269 } 13270 } 13271 13272 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 13273 backgroundColor : 13274 "_default" ); 13275 } 13276 13277 value = value.toRgbaString(); 13278 } 13279 try { 13280 elem.style[ hook ] = value; 13281 } catch( e ) { 13282 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 13283 } 13284 } 13285 }; 13286 jQuery.fx.step[ hook ] = function( fx ) { 13287 if ( !fx.colorInit ) { 13288 fx.start = color( fx.elem, hook ); 13289 fx.end = color( fx.end ); 13290 fx.colorInit = true; 13291 } 13292 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 13293 }; 13294 }); 13295 13296}; 13297 13298color.hook( stepHooks ); 13299 13300jQuery.cssHooks.borderColor = { 13301 expand: function( value ) { 13302 var expanded = {}; 13303 13304 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 13305 expanded[ "border" + part + "Color" ] = value; 13306 }); 13307 return expanded; 13308 } 13309}; 13310 13311// Basic color names only. 13312// Usage of any of the other color names requires adding yourself or including 13313// jquery.color.svg-names.js. 13314colors = jQuery.Color.names = { 13315 // 4.1. Basic color keywords 13316 aqua: "#00ffff", 13317 black: "#000000", 13318 blue: "#0000ff", 13319 fuchsia: "#ff00ff", 13320 gray: "#808080", 13321 green: "#008000", 13322 lime: "#00ff00", 13323 maroon: "#800000", 13324 navy: "#000080", 13325 olive: "#808000", 13326 purple: "#800080", 13327 red: "#ff0000", 13328 silver: "#c0c0c0", 13329 teal: "#008080", 13330 white: "#ffffff", 13331 yellow: "#ffff00", 13332 13333 // 4.2.3. "transparent" color keyword 13334 transparent: [ null, null, null, 0 ], 13335 13336 _default: "#ffffff" 13337}; 13338 13339})( jQuery ); 13340 13341 13342/******************************************************************************/ 13343/****************************** CLASS ANIMATIONS ******************************/ 13344/******************************************************************************/ 13345(function() { 13346 13347var classAnimationActions = [ "add", "remove", "toggle" ], 13348 shorthandStyles = { 13349 border: 1, 13350 borderBottom: 1, 13351 borderColor: 1, 13352 borderLeft: 1, 13353 borderRight: 1, 13354 borderTop: 1, 13355 borderWidth: 1, 13356 margin: 1, 13357 padding: 1 13358 }; 13359 13360$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 13361 $.fx.step[ prop ] = function( fx ) { 13362 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 13363 jQuery.style( fx.elem, prop, fx.end ); 13364 fx.setAttr = true; 13365 } 13366 }; 13367}); 13368 13369function getElementStyles( elem ) { 13370 var key, len, 13371 style = elem.ownerDocument.defaultView ? 13372 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 13373 elem.currentStyle, 13374 styles = {}; 13375 13376 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 13377 len = style.length; 13378 while ( len-- ) { 13379 key = style[ len ]; 13380 if ( typeof style[ key ] === "string" ) { 13381 styles[ $.camelCase( key ) ] = style[ key ]; 13382 } 13383 } 13384 // support: Opera, IE <9 13385 } else { 13386 for ( key in style ) { 13387 if ( typeof style[ key ] === "string" ) { 13388 styles[ key ] = style[ key ]; 13389 } 13390 } 13391 } 13392 13393 return styles; 13394} 13395 13396 13397function styleDifference( oldStyle, newStyle ) { 13398 var diff = {}, 13399 name, value; 13400 13401 for ( name in newStyle ) { 13402 value = newStyle[ name ]; 13403 if ( oldStyle[ name ] !== value ) { 13404 if ( !shorthandStyles[ name ] ) { 13405 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 13406 diff[ name ] = value; 13407 } 13408 } 13409 } 13410 } 13411 13412 return diff; 13413} 13414 13415// support: jQuery <1.8 13416if ( !$.fn.addBack ) { 13417 $.fn.addBack = function( selector ) { 13418 return this.add( selector == null ? 13419 this.prevObject : this.prevObject.filter( selector ) 13420 ); 13421 }; 13422} 13423 13424$.effects.animateClass = function( value, duration, easing, callback ) { 13425 var o = $.speed( duration, easing, callback ); 13426 13427 return this.queue( function() { 13428 var animated = $( this ), 13429 baseClass = animated.attr( "class" ) || "", 13430 applyClassChange, 13431 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 13432 13433 // map the animated objects to store the original styles. 13434 allAnimations = allAnimations.map(function() { 13435 var el = $( this ); 13436 return { 13437 el: el, 13438 start: getElementStyles( this ) 13439 }; 13440 }); 13441 13442 // apply class change 13443 applyClassChange = function() { 13444 $.each( classAnimationActions, function(i, action) { 13445 if ( value[ action ] ) { 13446 animated[ action + "Class" ]( value[ action ] ); 13447 } 13448 }); 13449 }; 13450 applyClassChange(); 13451 13452 // map all animated objects again - calculate new styles and diff 13453 allAnimations = allAnimations.map(function() { 13454 this.end = getElementStyles( this.el[ 0 ] ); 13455 this.diff = styleDifference( this.start, this.end ); 13456 return this; 13457 }); 13458 13459 // apply original class 13460 animated.attr( "class", baseClass ); 13461 13462 // map all animated objects again - this time collecting a promise 13463 allAnimations = allAnimations.map(function() { 13464 var styleInfo = this, 13465 dfd = $.Deferred(), 13466 opts = $.extend({}, o, { 13467 queue: false, 13468 complete: function() { 13469 dfd.resolve( styleInfo ); 13470 } 13471 }); 13472 13473 this.el.animate( this.diff, opts ); 13474 return dfd.promise(); 13475 }); 13476 13477 // once all animations have completed: 13478 $.when.apply( $, allAnimations.get() ).done(function() { 13479 13480 // set the final class 13481 applyClassChange(); 13482 13483 // for each animated element, 13484 // clear all css properties that were animated 13485 $.each( arguments, function() { 13486 var el = this.el; 13487 $.each( this.diff, function(key) { 13488 el.css( key, "" ); 13489 }); 13490 }); 13491 13492 // this is guarnteed to be there if you use jQuery.speed() 13493 // it also handles dequeuing the next anim... 13494 o.complete.call( animated[ 0 ] ); 13495 }); 13496 }); 13497}; 13498 13499$.fn.extend({ 13500 _addClass: $.fn.addClass, 13501 addClass: function( classNames, speed, easing, callback ) { 13502 return speed ? 13503 $.effects.animateClass.call( this, 13504 { add: classNames }, speed, easing, callback ) : 13505 this._addClass( classNames ); 13506 }, 13507 13508 _removeClass: $.fn.removeClass, 13509 removeClass: function( classNames, speed, easing, callback ) { 13510 return arguments.length > 1 ? 13511 $.effects.animateClass.call( this, 13512 { remove: classNames }, speed, easing, callback ) : 13513 this._removeClass.apply( this, arguments ); 13514 }, 13515 13516 _toggleClass: $.fn.toggleClass, 13517 toggleClass: function( classNames, force, speed, easing, callback ) { 13518 if ( typeof force === "boolean" || force === undefined ) { 13519 if ( !speed ) { 13520 // without speed parameter 13521 return this._toggleClass( classNames, force ); 13522 } else { 13523 return $.effects.animateClass.call( this, 13524 (force ? { add: classNames } : { remove: classNames }), 13525 speed, easing, callback ); 13526 } 13527 } else { 13528 // without force parameter 13529 return $.effects.animateClass.call( this, 13530 { toggle: classNames }, force, speed, easing ); 13531 } 13532 }, 13533 13534 switchClass: function( remove, add, speed, easing, callback) { 13535 return $.effects.animateClass.call( this, { 13536 add: add, 13537 remove: remove 13538 }, speed, easing, callback ); 13539 } 13540}); 13541 13542})(); 13543 13544/******************************************************************************/ 13545/*********************************** EFFECTS **********************************/ 13546/******************************************************************************/ 13547 13548(function() { 13549 13550$.extend( $.effects, { 13551 version: "1.10.1", 13552 13553 // Saves a set of properties in a data storage 13554 save: function( element, set ) { 13555 for( var i=0; i < set.length; i++ ) { 13556 if ( set[ i ] !== null ) { 13557 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 13558 } 13559 } 13560 }, 13561 13562 // Restores a set of previously saved properties from a data storage 13563 restore: function( element, set ) { 13564 var val, i; 13565 for( i=0; i < set.length; i++ ) { 13566 if ( set[ i ] !== null ) { 13567 val = element.data( dataSpace + set[ i ] ); 13568 // support: jQuery 1.6.2 13569 // http://bugs.jquery.com/ticket/9917 13570 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 13571 // We can't differentiate between "" and 0 here, so we just assume 13572 // empty string since it's likely to be a more common value... 13573 if ( val === undefined ) { 13574 val = ""; 13575 } 13576 element.css( set[ i ], val ); 13577 } 13578 } 13579 }, 13580 13581 setMode: function( el, mode ) { 13582 if (mode === "toggle") { 13583 mode = el.is( ":hidden" ) ? "show" : "hide"; 13584 } 13585 return mode; 13586 }, 13587 13588 // Translates a [top,left] array into a baseline value 13589 // this should be a little more flexible in the future to handle a string & hash 13590 getBaseline: function( origin, original ) { 13591 var y, x; 13592 switch ( origin[ 0 ] ) { 13593 case "top": y = 0; break; 13594 case "middle": y = 0.5; break; 13595 case "bottom": y = 1; break; 13596 default: y = origin[ 0 ] / original.height; 13597 } 13598 switch ( origin[ 1 ] ) { 13599 case "left": x = 0; break; 13600 case "center": x = 0.5; break; 13601 case "right": x = 1; break; 13602 default: x = origin[ 1 ] / original.width; 13603 } 13604 return { 13605 x: x, 13606 y: y 13607 }; 13608 }, 13609 13610 // Wraps the element around a wrapper that copies position properties 13611 createWrapper: function( element ) { 13612 13613 // if the element is already wrapped, return it 13614 if ( element.parent().is( ".ui-effects-wrapper" )) { 13615 return element.parent(); 13616 } 13617 13618 // wrap the element 13619 var props = { 13620 width: element.outerWidth(true), 13621 height: element.outerHeight(true), 13622 "float": element.css( "float" ) 13623 }, 13624 wrapper = $( "<div></div>" ) 13625 .addClass( "ui-effects-wrapper" ) 13626 .css({ 13627 fontSize: "100%", 13628 background: "transparent", 13629 border: "none", 13630 margin: 0, 13631 padding: 0 13632 }), 13633 // Store the size in case width/height are defined in % - Fixes #5245 13634 size = { 13635 width: element.width(), 13636 height: element.height() 13637 }, 13638 active = document.activeElement; 13639 13640 // support: Firefox 13641 // Firefox incorrectly exposes anonymous content 13642 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 13643 try { 13644 active.id; 13645 } catch( e ) { 13646 active = document.body; 13647 } 13648 13649 element.wrap( wrapper ); 13650 13651 // Fixes #7595 - Elements lose focus when wrapped. 13652 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13653 $( active ).focus(); 13654 } 13655 13656 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 13657 13658 // transfer positioning properties to the wrapper 13659 if ( element.css( "position" ) === "static" ) { 13660 wrapper.css({ position: "relative" }); 13661 element.css({ position: "relative" }); 13662 } else { 13663 $.extend( props, { 13664 position: element.css( "position" ), 13665 zIndex: element.css( "z-index" ) 13666 }); 13667 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 13668 props[ pos ] = element.css( pos ); 13669 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 13670 props[ pos ] = "auto"; 13671 } 13672 }); 13673 element.css({ 13674 position: "relative", 13675 top: 0, 13676 left: 0, 13677 right: "auto", 13678 bottom: "auto" 13679 }); 13680 } 13681 element.css(size); 13682 13683 return wrapper.css( props ).show(); 13684 }, 13685 13686 removeWrapper: function( element ) { 13687 var active = document.activeElement; 13688 13689 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13690 element.parent().replaceWith( element ); 13691 13692 // Fixes #7595 - Elements lose focus when wrapped. 13693 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13694 $( active ).focus(); 13695 } 13696 } 13697 13698 13699 return element; 13700 }, 13701 13702 setTransition: function( element, list, factor, value ) { 13703 value = value || {}; 13704 $.each( list, function( i, x ) { 13705 var unit = element.cssUnit( x ); 13706 if ( unit[ 0 ] > 0 ) { 13707 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13708 } 13709 }); 13710 return value; 13711 } 13712}); 13713 13714// return an effect options object for the given parameters: 13715function _normalizeArguments( effect, options, speed, callback ) { 13716 13717 // allow passing all options as the first parameter 13718 if ( $.isPlainObject( effect ) ) { 13719 options = effect; 13720 effect = effect.effect; 13721 } 13722 13723 // convert to an object 13724 effect = { effect: effect }; 13725 13726 // catch (effect, null, ...) 13727 if ( options == null ) { 13728 options = {}; 13729 } 13730 13731 // catch (effect, callback) 13732 if ( $.isFunction( options ) ) { 13733 callback = options; 13734 speed = null; 13735 options = {}; 13736 } 13737 13738 // catch (effect, speed, ?) 13739 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13740 callback = speed; 13741 speed = options; 13742 options = {}; 13743 } 13744 13745 // catch (effect, options, callback) 13746 if ( $.isFunction( speed ) ) { 13747 callback = speed; 13748 speed = null; 13749 } 13750 13751 // add options to effect 13752 if ( options ) { 13753 $.extend( effect, options ); 13754 } 13755 13756 speed = speed || options.duration; 13757 effect.duration = $.fx.off ? 0 : 13758 typeof speed === "number" ? speed : 13759 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13760 $.fx.speeds._default; 13761 13762 effect.complete = callback || options.complete; 13763 13764 return effect; 13765} 13766 13767function standardSpeed( speed ) { 13768 // valid standard speeds 13769 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 13770 return true; 13771 } 13772 13773 // invalid strings - treat as "normal" speed 13774 return typeof speed === "string" && !$.effects.effect[ speed ]; 13775} 13776 13777$.fn.extend({ 13778 effect: function( /* effect, options, speed, callback */ ) { 13779 var args = _normalizeArguments.apply( this, arguments ), 13780 mode = args.mode, 13781 queue = args.queue, 13782 effectMethod = $.effects.effect[ args.effect ]; 13783 13784 if ( $.fx.off || !effectMethod ) { 13785 // delegate to the original method (e.g., .show()) if possible 13786 if ( mode ) { 13787 return this[ mode ]( args.duration, args.complete ); 13788 } else { 13789 return this.each( function() { 13790 if ( args.complete ) { 13791 args.complete.call( this ); 13792 } 13793 }); 13794 } 13795 } 13796 13797 function run( next ) { 13798 var elem = $( this ), 13799 complete = args.complete, 13800 mode = args.mode; 13801 13802 function done() { 13803 if ( $.isFunction( complete ) ) { 13804 complete.call( elem[0] ); 13805 } 13806 if ( $.isFunction( next ) ) { 13807 next(); 13808 } 13809 } 13810 13811 // if the element is hiddden and mode is hide, 13812 // or element is visible and mode is show 13813 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13814 done(); 13815 } else { 13816 effectMethod.call( elem[0], args, done ); 13817 } 13818 } 13819 13820 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 13821 }, 13822 13823 _show: $.fn.show, 13824 show: function( speed ) { 13825 if ( standardSpeed( speed ) ) { 13826 return this._show.apply( this, arguments ); 13827 } else { 13828 var args = _normalizeArguments.apply( this, arguments ); 13829 args.mode = "show"; 13830 return this.effect.call( this, args ); 13831 } 13832 }, 13833 13834 _hide: $.fn.hide, 13835 hide: function( speed ) { 13836 if ( standardSpeed( speed ) ) { 13837 return this._hide.apply( this, arguments ); 13838 } else { 13839 var args = _normalizeArguments.apply( this, arguments ); 13840 args.mode = "hide"; 13841 return this.effect.call( this, args ); 13842 } 13843 }, 13844 13845 // jQuery core overloads toggle and creates _toggle 13846 __toggle: $.fn.toggle, 13847 toggle: function( speed ) { 13848 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 13849 return this.__toggle.apply( this, arguments ); 13850 } else { 13851 var args = _normalizeArguments.apply( this, arguments ); 13852 args.mode = "toggle"; 13853 return this.effect.call( this, args ); 13854 } 13855 }, 13856 13857 // helper functions 13858 cssUnit: function(key) { 13859 var style = this.css( key ), 13860 val = []; 13861 13862 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13863 if ( style.indexOf( unit ) > 0 ) { 13864 val = [ parseFloat( style ), unit ]; 13865 } 13866 }); 13867 return val; 13868 } 13869}); 13870 13871})(); 13872 13873/******************************************************************************/ 13874/*********************************** EASING ***********************************/ 13875/******************************************************************************/ 13876 13877(function() { 13878 13879// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 13880 13881var baseEasings = {}; 13882 13883$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13884 baseEasings[ name ] = function( p ) { 13885 return Math.pow( p, i + 2 ); 13886 }; 13887}); 13888 13889$.extend( baseEasings, { 13890 Sine: function ( p ) { 13891 return 1 - Math.cos( p * Math.PI / 2 ); 13892 }, 13893 Circ: function ( p ) { 13894 return 1 - Math.sqrt( 1 - p * p ); 13895 }, 13896 Elastic: function( p ) { 13897 return p === 0 || p === 1 ? p : 13898 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 13899 }, 13900 Back: function( p ) { 13901 return p * p * ( 3 * p - 2 ); 13902 }, 13903 Bounce: function ( p ) { 13904 var pow2, 13905 bounce = 4; 13906 13907 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 13908 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 13909 } 13910}); 13911 13912$.each( baseEasings, function( name, easeIn ) { 13913 $.easing[ "easeIn" + name ] = easeIn; 13914 $.easing[ "easeOut" + name ] = function( p ) { 13915 return 1 - easeIn( 1 - p ); 13916 }; 13917 $.easing[ "easeInOut" + name ] = function( p ) { 13918 return p < 0.5 ? 13919 easeIn( p * 2 ) / 2 : 13920 1 - easeIn( p * -2 + 2 ) / 2; 13921 }; 13922}); 13923 13924})(); 13925 13926})(jQuery)); 13927(function( $, undefined ) { 13928 13929var rvertical = /up|down|vertical/, 13930 rpositivemotion = /up|left|vertical|horizontal/; 13931 13932$.effects.effect.blind = function( o, done ) { 13933 // Create element 13934 var el = $( this ), 13935 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13936 mode = $.effects.setMode( el, o.mode || "hide" ), 13937 direction = o.direction || "up", 13938 vertical = rvertical.test( direction ), 13939 ref = vertical ? "height" : "width", 13940 ref2 = vertical ? "top" : "left", 13941 motion = rpositivemotion.test( direction ), 13942 animation = {}, 13943 show = mode === "show", 13944 wrapper, distance, margin; 13945 13946 // if already wrapped, the wrapper's properties are my property. #6245 13947 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 13948 $.effects.save( el.parent(), props ); 13949 } else { 13950 $.effects.save( el, props ); 13951 } 13952 el.show(); 13953 wrapper = $.effects.createWrapper( el ).css({ 13954 overflow: "hidden" 13955 }); 13956 13957 distance = wrapper[ ref ](); 13958 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 13959 13960 animation[ ref ] = show ? distance : 0; 13961 if ( !motion ) { 13962 el 13963 .css( vertical ? "bottom" : "right", 0 ) 13964 .css( vertical ? "top" : "left", "auto" ) 13965 .css({ position: "absolute" }); 13966 13967 animation[ ref2 ] = show ? margin : distance + margin; 13968 } 13969 13970 // start at 0 if we are showing 13971 if ( show ) { 13972 wrapper.css( ref, 0 ); 13973 if ( ! motion ) { 13974 wrapper.css( ref2, margin + distance ); 13975 } 13976 } 13977 13978 // Animate 13979 wrapper.animate( animation, { 13980 duration: o.duration, 13981 easing: o.easing, 13982 queue: false, 13983 complete: function() { 13984 if ( mode === "hide" ) { 13985 el.hide(); 13986 } 13987 $.effects.restore( el, props ); 13988 $.effects.removeWrapper( el ); 13989 done(); 13990 } 13991 }); 13992 13993}; 13994 13995})(jQuery); 13996(function( $, undefined ) { 13997 13998$.effects.effect.bounce = function( o, done ) { 13999 var el = $( this ), 14000 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14001 14002 // defaults: 14003 mode = $.effects.setMode( el, o.mode || "effect" ), 14004 hide = mode === "hide", 14005 show = mode === "show", 14006 direction = o.direction || "up", 14007 distance = o.distance, 14008 times = o.times || 5, 14009 14010 // number of internal animations 14011 anims = times * 2 + ( show || hide ? 1 : 0 ), 14012 speed = o.duration / anims, 14013 easing = o.easing, 14014 14015 // utility: 14016 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14017 motion = ( direction === "up" || direction === "left" ), 14018 i, 14019 upAnim, 14020 downAnim, 14021 14022 // we will need to re-assemble the queue to stack our animations in place 14023 queue = el.queue(), 14024 queuelen = queue.length; 14025 14026 // Avoid touching opacity to prevent clearType and PNG issues in IE 14027 if ( show || hide ) { 14028 props.push( "opacity" ); 14029 } 14030 14031 $.effects.save( el, props ); 14032 el.show(); 14033 $.effects.createWrapper( el ); // Create Wrapper 14034 14035 // default distance for the BIGGEST bounce is the outer Distance / 3 14036 if ( !distance ) { 14037 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 14038 } 14039 14040 if ( show ) { 14041 downAnim = { opacity: 1 }; 14042 downAnim[ ref ] = 0; 14043 14044 // if we are showing, force opacity 0 and set the initial position 14045 // then do the "first" animation 14046 el.css( "opacity", 0 ) 14047 .css( ref, motion ? -distance * 2 : distance * 2 ) 14048 .animate( downAnim, speed, easing ); 14049 } 14050 14051 // start at the smallest distance if we are hiding 14052 if ( hide ) { 14053 distance = distance / Math.pow( 2, times - 1 ); 14054 } 14055 14056 downAnim = {}; 14057 downAnim[ ref ] = 0; 14058 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 14059 for ( i = 0; i < times; i++ ) { 14060 upAnim = {}; 14061 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14062 14063 el.animate( upAnim, speed, easing ) 14064 .animate( downAnim, speed, easing ); 14065 14066 distance = hide ? distance * 2 : distance / 2; 14067 } 14068 14069 // Last Bounce when Hiding 14070 if ( hide ) { 14071 upAnim = { opacity: 0 }; 14072 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14073 14074 el.animate( upAnim, speed, easing ); 14075 } 14076 14077 el.queue(function() { 14078 if ( hide ) { 14079 el.hide(); 14080 } 14081 $.effects.restore( el, props ); 14082 $.effects.removeWrapper( el ); 14083 done(); 14084 }); 14085 14086 // inject all the animations we just queued to be first in line (after "inprogress") 14087 if ( queuelen > 1) { 14088 queue.splice.apply( queue, 14089 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14090 } 14091 el.dequeue(); 14092 14093}; 14094 14095})(jQuery); 14096(function( $, undefined ) { 14097 14098$.effects.effect.clip = function( o, done ) { 14099 // Create element 14100 var el = $( this ), 14101 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14102 mode = $.effects.setMode( el, o.mode || "hide" ), 14103 show = mode === "show", 14104 direction = o.direction || "vertical", 14105 vert = direction === "vertical", 14106 size = vert ? "height" : "width", 14107 position = vert ? "top" : "left", 14108 animation = {}, 14109 wrapper, animate, distance; 14110 14111 // Save & Show 14112 $.effects.save( el, props ); 14113 el.show(); 14114 14115 // Create Wrapper 14116 wrapper = $.effects.createWrapper( el ).css({ 14117 overflow: "hidden" 14118 }); 14119 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 14120 distance = animate[ size ](); 14121 14122 // Shift 14123 if ( show ) { 14124 animate.css( size, 0 ); 14125 animate.css( position, distance / 2 ); 14126 } 14127 14128 // Create Animation Object: 14129 animation[ size ] = show ? distance : 0; 14130 animation[ position ] = show ? 0 : distance / 2; 14131 14132 // Animate 14133 animate.animate( animation, { 14134 queue: false, 14135 duration: o.duration, 14136 easing: o.easing, 14137 complete: function() { 14138 if ( !show ) { 14139 el.hide(); 14140 } 14141 $.effects.restore( el, props ); 14142 $.effects.removeWrapper( el ); 14143 done(); 14144 } 14145 }); 14146 14147}; 14148 14149})(jQuery); 14150(function( $, undefined ) { 14151 14152$.effects.effect.drop = function( o, done ) { 14153 14154 var el = $( this ), 14155 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 14156 mode = $.effects.setMode( el, o.mode || "hide" ), 14157 show = mode === "show", 14158 direction = o.direction || "left", 14159 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14160 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 14161 animation = { 14162 opacity: show ? 1 : 0 14163 }, 14164 distance; 14165 14166 // Adjust 14167 $.effects.save( el, props ); 14168 el.show(); 14169 $.effects.createWrapper( el ); 14170 14171 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 14172 14173 if ( show ) { 14174 el 14175 .css( "opacity", 0 ) 14176 .css( ref, motion === "pos" ? -distance : distance ); 14177 } 14178 14179 // Animation 14180 animation[ ref ] = ( show ? 14181 ( motion === "pos" ? "+=" : "-=" ) : 14182 ( motion === "pos" ? "-=" : "+=" ) ) + 14183 distance; 14184 14185 // Animate 14186 el.animate( animation, { 14187 queue: false, 14188 duration: o.duration, 14189 easing: o.easing, 14190 complete: function() { 14191 if ( mode === "hide" ) { 14192 el.hide(); 14193 } 14194 $.effects.restore( el, props ); 14195 $.effects.removeWrapper( el ); 14196 done(); 14197 } 14198 }); 14199}; 14200 14201})(jQuery); 14202(function( $, undefined ) { 14203 14204$.effects.effect.explode = function( o, done ) { 14205 14206 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 14207 cells = rows, 14208 el = $( this ), 14209 mode = $.effects.setMode( el, o.mode || "hide" ), 14210 show = mode === "show", 14211 14212 // show and then visibility:hidden the element before calculating offset 14213 offset = el.show().css( "visibility", "hidden" ).offset(), 14214 14215 // width and height of a piece 14216 width = Math.ceil( el.outerWidth() / cells ), 14217 height = Math.ceil( el.outerHeight() / rows ), 14218 pieces = [], 14219 14220 // loop 14221 i, j, left, top, mx, my; 14222 14223 // children animate complete: 14224 function childComplete() { 14225 pieces.push( this ); 14226 if ( pieces.length === rows * cells ) { 14227 animComplete(); 14228 } 14229 } 14230 14231 // clone the element for each row and cell. 14232 for( i = 0; i < rows ; i++ ) { // ===> 14233 top = offset.top + i * height; 14234 my = i - ( rows - 1 ) / 2 ; 14235 14236 for( j = 0; j < cells ; j++ ) { // ||| 14237 left = offset.left + j * width; 14238 mx = j - ( cells - 1 ) / 2 ; 14239 14240 // Create a clone of the now hidden main element that will be absolute positioned 14241 // within a wrapper div off the -left and -top equal to size of our pieces 14242 el 14243 .clone() 14244 .appendTo( "body" ) 14245 .wrap( "<div></div>" ) 14246 .css({ 14247 position: "absolute", 14248 visibility: "visible", 14249 left: -j * width, 14250 top: -i * height 14251 }) 14252 14253 // select the wrapper - make it overflow: hidden and absolute positioned based on 14254 // where the original was located +left and +top equal to the size of pieces 14255 .parent() 14256 .addClass( "ui-effects-explode" ) 14257 .css({ 14258 position: "absolute", 14259 overflow: "hidden", 14260 width: width, 14261 height: height, 14262 left: left + ( show ? mx * width : 0 ), 14263 top: top + ( show ? my * height : 0 ), 14264 opacity: show ? 0 : 1 14265 }).animate({ 14266 left: left + ( show ? 0 : mx * width ), 14267 top: top + ( show ? 0 : my * height ), 14268 opacity: show ? 1 : 0 14269 }, o.duration || 500, o.easing, childComplete ); 14270 } 14271 } 14272 14273 function animComplete() { 14274 el.css({ 14275 visibility: "visible" 14276 }); 14277 $( pieces ).remove(); 14278 if ( !show ) { 14279 el.hide(); 14280 } 14281 done(); 14282 } 14283}; 14284 14285})(jQuery); 14286(function( $, undefined ) { 14287 14288$.effects.effect.fade = function( o, done ) { 14289 var el = $( this ), 14290 mode = $.effects.setMode( el, o.mode || "toggle" ); 14291 14292 el.animate({ 14293 opacity: mode 14294 }, { 14295 queue: false, 14296 duration: o.duration, 14297 easing: o.easing, 14298 complete: done 14299 }); 14300}; 14301 14302})( jQuery ); 14303(function( $, undefined ) { 14304 14305$.effects.effect.fold = function( o, done ) { 14306 14307 // Create element 14308 var el = $( this ), 14309 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14310 mode = $.effects.setMode( el, o.mode || "hide" ), 14311 show = mode === "show", 14312 hide = mode === "hide", 14313 size = o.size || 15, 14314 percent = /([0-9]+)%/.exec( size ), 14315 horizFirst = !!o.horizFirst, 14316 widthFirst = show !== horizFirst, 14317 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 14318 duration = o.duration / 2, 14319 wrapper, distance, 14320 animation1 = {}, 14321 animation2 = {}; 14322 14323 $.effects.save( el, props ); 14324 el.show(); 14325 14326 // Create Wrapper 14327 wrapper = $.effects.createWrapper( el ).css({ 14328 overflow: "hidden" 14329 }); 14330 distance = widthFirst ? 14331 [ wrapper.width(), wrapper.height() ] : 14332 [ wrapper.height(), wrapper.width() ]; 14333 14334 if ( percent ) { 14335 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 14336 } 14337 if ( show ) { 14338 wrapper.css( horizFirst ? { 14339 height: 0, 14340 width: size 14341 } : { 14342 height: size, 14343 width: 0 14344 }); 14345 } 14346 14347 // Animation 14348 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 14349 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 14350 14351 // Animate 14352 wrapper 14353 .animate( animation1, duration, o.easing ) 14354 .animate( animation2, duration, o.easing, function() { 14355 if ( hide ) { 14356 el.hide(); 14357 } 14358 $.effects.restore( el, props ); 14359 $.effects.removeWrapper( el ); 14360 done(); 14361 }); 14362 14363}; 14364 14365})(jQuery); 14366(function( $, undefined ) { 14367 14368$.effects.effect.highlight = function( o, done ) { 14369 var elem = $( this ), 14370 props = [ "backgroundImage", "backgroundColor", "opacity" ], 14371 mode = $.effects.setMode( elem, o.mode || "show" ), 14372 animation = { 14373 backgroundColor: elem.css( "backgroundColor" ) 14374 }; 14375 14376 if (mode === "hide") { 14377 animation.opacity = 0; 14378 } 14379 14380 $.effects.save( elem, props ); 14381 14382 elem 14383 .show() 14384 .css({ 14385 backgroundImage: "none", 14386 backgroundColor: o.color || "#ffff99" 14387 }) 14388 .animate( animation, { 14389 queue: false, 14390 duration: o.duration, 14391 easing: o.easing, 14392 complete: function() { 14393 if ( mode === "hide" ) { 14394 elem.hide(); 14395 } 14396 $.effects.restore( elem, props ); 14397 done(); 14398 } 14399 }); 14400}; 14401 14402})(jQuery); 14403(function( $, undefined ) { 14404 14405$.effects.effect.pulsate = function( o, done ) { 14406 var elem = $( this ), 14407 mode = $.effects.setMode( elem, o.mode || "show" ), 14408 show = mode === "show", 14409 hide = mode === "hide", 14410 showhide = ( show || mode === "hide" ), 14411 14412 // showing or hiding leaves of the "last" animation 14413 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 14414 duration = o.duration / anims, 14415 animateTo = 0, 14416 queue = elem.queue(), 14417 queuelen = queue.length, 14418 i; 14419 14420 if ( show || !elem.is(":visible")) { 14421 elem.css( "opacity", 0 ).show(); 14422 animateTo = 1; 14423 } 14424 14425 // anims - 1 opacity "toggles" 14426 for ( i = 1; i < anims; i++ ) { 14427 elem.animate({ 14428 opacity: animateTo 14429 }, duration, o.easing ); 14430 animateTo = 1 - animateTo; 14431 } 14432 14433 elem.animate({ 14434 opacity: animateTo 14435 }, duration, o.easing); 14436 14437 elem.queue(function() { 14438 if ( hide ) { 14439 elem.hide(); 14440 } 14441 done(); 14442 }); 14443 14444 // We just queued up "anims" animations, we need to put them next in the queue 14445 if ( queuelen > 1 ) { 14446 queue.splice.apply( queue, 14447 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14448 } 14449 elem.dequeue(); 14450}; 14451 14452})(jQuery); 14453(function( $, undefined ) { 14454 14455$.effects.effect.puff = function( o, done ) { 14456 var elem = $( this ), 14457 mode = $.effects.setMode( elem, o.mode || "hide" ), 14458 hide = mode === "hide", 14459 percent = parseInt( o.percent, 10 ) || 150, 14460 factor = percent / 100, 14461 original = { 14462 height: elem.height(), 14463 width: elem.width(), 14464 outerHeight: elem.outerHeight(), 14465 outerWidth: elem.outerWidth() 14466 }; 14467 14468 $.extend( o, { 14469 effect: "scale", 14470 queue: false, 14471 fade: true, 14472 mode: mode, 14473 complete: done, 14474 percent: hide ? percent : 100, 14475 from: hide ? 14476 original : 14477 { 14478 height: original.height * factor, 14479 width: original.width * factor, 14480 outerHeight: original.outerHeight * factor, 14481 outerWidth: original.outerWidth * factor 14482 } 14483 }); 14484 14485 elem.effect( o ); 14486}; 14487 14488$.effects.effect.scale = function( o, done ) { 14489 14490 // Create element 14491 var el = $( this ), 14492 options = $.extend( true, {}, o ), 14493 mode = $.effects.setMode( el, o.mode || "effect" ), 14494 percent = parseInt( o.percent, 10 ) || 14495 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 14496 direction = o.direction || "both", 14497 origin = o.origin, 14498 original = { 14499 height: el.height(), 14500 width: el.width(), 14501 outerHeight: el.outerHeight(), 14502 outerWidth: el.outerWidth() 14503 }, 14504 factor = { 14505 y: direction !== "horizontal" ? (percent / 100) : 1, 14506 x: direction !== "vertical" ? (percent / 100) : 1 14507 }; 14508 14509 // We are going to pass this effect to the size effect: 14510 options.effect = "size"; 14511 options.queue = false; 14512 options.complete = done; 14513 14514 // Set default origin and restore for show/hide 14515 if ( mode !== "effect" ) { 14516 options.origin = origin || ["middle","center"]; 14517 options.restore = true; 14518 } 14519 14520 options.from = o.from || ( mode === "show" ? { 14521 height: 0, 14522 width: 0, 14523 outerHeight: 0, 14524 outerWidth: 0 14525 } : original ); 14526 options.to = { 14527 height: original.height * factor.y, 14528 width: original.width * factor.x, 14529 outerHeight: original.outerHeight * factor.y, 14530 outerWidth: original.outerWidth * factor.x 14531 }; 14532 14533 // Fade option to support puff 14534 if ( options.fade ) { 14535 if ( mode === "show" ) { 14536 options.from.opacity = 0; 14537 options.to.opacity = 1; 14538 } 14539 if ( mode === "hide" ) { 14540 options.from.opacity = 1; 14541 options.to.opacity = 0; 14542 } 14543 } 14544 14545 // Animate 14546 el.effect( options ); 14547 14548}; 14549 14550$.effects.effect.size = function( o, done ) { 14551 14552 // Create element 14553 var original, baseline, factor, 14554 el = $( this ), 14555 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 14556 14557 // Always restore 14558 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 14559 14560 // Copy for children 14561 props2 = [ "width", "height", "overflow" ], 14562 cProps = [ "fontSize" ], 14563 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 14564 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 14565 14566 // Set options 14567 mode = $.effects.setMode( el, o.mode || "effect" ), 14568 restore = o.restore || mode !== "effect", 14569 scale = o.scale || "both", 14570 origin = o.origin || [ "middle", "center" ], 14571 position = el.css( "position" ), 14572 props = restore ? props0 : props1, 14573 zero = { 14574 height: 0, 14575 width: 0, 14576 outerHeight: 0, 14577 outerWidth: 0 14578 }; 14579 14580 if ( mode === "show" ) { 14581 el.show(); 14582 } 14583 original = { 14584 height: el.height(), 14585 width: el.width(), 14586 outerHeight: el.outerHeight(), 14587 outerWidth: el.outerWidth() 14588 }; 14589 14590 if ( o.mode === "toggle" && mode === "show" ) { 14591 el.from = o.to || zero; 14592 el.to = o.from || original; 14593 } else { 14594 el.from = o.from || ( mode === "show" ? zero : original ); 14595 el.to = o.to || ( mode === "hide" ? zero : original ); 14596 } 14597 14598 // Set scaling factor 14599 factor = { 14600 from: { 14601 y: el.from.height / original.height, 14602 x: el.from.width / original.width 14603 }, 14604 to: { 14605 y: el.to.height / original.height, 14606 x: el.to.width / original.width 14607 } 14608 }; 14609 14610 // Scale the css box 14611 if ( scale === "box" || scale === "both" ) { 14612 14613 // Vertical props scaling 14614 if ( factor.from.y !== factor.to.y ) { 14615 props = props.concat( vProps ); 14616 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 14617 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 14618 } 14619 14620 // Horizontal props scaling 14621 if ( factor.from.x !== factor.to.x ) { 14622 props = props.concat( hProps ); 14623 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 14624 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 14625 } 14626 } 14627 14628 // Scale the content 14629 if ( scale === "content" || scale === "both" ) { 14630 14631 // Vertical props scaling 14632 if ( factor.from.y !== factor.to.y ) { 14633 props = props.concat( cProps ).concat( props2 ); 14634 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 14635 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 14636 } 14637 } 14638 14639 $.effects.save( el, props ); 14640 el.show(); 14641 $.effects.createWrapper( el ); 14642 el.css( "overflow", "hidden" ).css( el.from ); 14643 14644 // Adjust 14645 if (origin) { // Calculate baseline shifts 14646 baseline = $.effects.getBaseline( origin, original ); 14647 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 14648 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 14649 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 14650 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 14651 } 14652 el.css( el.from ); // set top & left 14653 14654 // Animate 14655 if ( scale === "content" || scale === "both" ) { // Scale the children 14656 14657 // Add margins/font-size 14658 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 14659 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 14660 props2 = props0.concat(vProps).concat(hProps); 14661 14662 el.find( "*[width]" ).each( function(){ 14663 var child = $( this ), 14664 c_original = { 14665 height: child.height(), 14666 width: child.width(), 14667 outerHeight: child.outerHeight(), 14668 outerWidth: child.outerWidth() 14669 }; 14670 if (restore) { 14671 $.effects.save(child, props2); 14672 } 14673 14674 child.from = { 14675 height: c_original.height * factor.from.y, 14676 width: c_original.width * factor.from.x, 14677 outerHeight: c_original.outerHeight * factor.from.y, 14678 outerWidth: c_original.outerWidth * factor.from.x 14679 }; 14680 child.to = { 14681 height: c_original.height * factor.to.y, 14682 width: c_original.width * factor.to.x, 14683 outerHeight: c_original.height * factor.to.y, 14684 outerWidth: c_original.width * factor.to.x 14685 }; 14686 14687 // Vertical props scaling 14688 if ( factor.from.y !== factor.to.y ) { 14689 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 14690 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 14691 } 14692 14693 // Horizontal props scaling 14694 if ( factor.from.x !== factor.to.x ) { 14695 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 14696 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 14697 } 14698 14699 // Animate children 14700 child.css( child.from ); 14701 child.animate( child.to, o.duration, o.easing, function() { 14702 14703 // Restore children 14704 if ( restore ) { 14705 $.effects.restore( child, props2 ); 14706 } 14707 }); 14708 }); 14709 } 14710 14711 // Animate 14712 el.animate( el.to, { 14713 queue: false, 14714 duration: o.duration, 14715 easing: o.easing, 14716 complete: function() { 14717 if ( el.to.opacity === 0 ) { 14718 el.css( "opacity", el.from.opacity ); 14719 } 14720 if( mode === "hide" ) { 14721 el.hide(); 14722 } 14723 $.effects.restore( el, props ); 14724 if ( !restore ) { 14725 14726 // we need to calculate our new positioning based on the scaling 14727 if ( position === "static" ) { 14728 el.css({ 14729 position: "relative", 14730 top: el.to.top, 14731 left: el.to.left 14732 }); 14733 } else { 14734 $.each([ "top", "left" ], function( idx, pos ) { 14735 el.css( pos, function( _, str ) { 14736 var val = parseInt( str, 10 ), 14737 toRef = idx ? el.to.left : el.to.top; 14738 14739 // if original was "auto", recalculate the new value from wrapper 14740 if ( str === "auto" ) { 14741 return toRef + "px"; 14742 } 14743 14744 return val + toRef + "px"; 14745 }); 14746 }); 14747 } 14748 } 14749 14750 $.effects.removeWrapper( el ); 14751 done(); 14752 } 14753 }); 14754 14755}; 14756 14757})(jQuery); 14758(function( $, undefined ) { 14759 14760$.effects.effect.shake = function( o, done ) { 14761 14762 var el = $( this ), 14763 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14764 mode = $.effects.setMode( el, o.mode || "effect" ), 14765 direction = o.direction || "left", 14766 distance = o.distance || 20, 14767 times = o.times || 3, 14768 anims = times * 2 + 1, 14769 speed = Math.round(o.duration/anims), 14770 ref = (direction === "up" || direction === "down") ? "top" : "left", 14771 positiveMotion = (direction === "up" || direction === "left"), 14772 animation = {}, 14773 animation1 = {}, 14774 animation2 = {}, 14775 i, 14776 14777 // we will need to re-assemble the queue to stack our animations in place 14778 queue = el.queue(), 14779 queuelen = queue.length; 14780 14781 $.effects.save( el, props ); 14782 el.show(); 14783 $.effects.createWrapper( el ); 14784 14785 // Animation 14786 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 14787 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 14788 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 14789 14790 // Animate 14791 el.animate( animation, speed, o.easing ); 14792 14793 // Shakes 14794 for ( i = 1; i < times; i++ ) { 14795 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 14796 } 14797 el 14798 .animate( animation1, speed, o.easing ) 14799 .animate( animation, speed / 2, o.easing ) 14800 .queue(function() { 14801 if ( mode === "hide" ) { 14802 el.hide(); 14803 } 14804 $.effects.restore( el, props ); 14805 $.effects.removeWrapper( el ); 14806 done(); 14807 }); 14808 14809 // inject all the animations we just queued to be first in line (after "inprogress") 14810 if ( queuelen > 1) { 14811 queue.splice.apply( queue, 14812 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 14813 } 14814 el.dequeue(); 14815 14816}; 14817 14818})(jQuery); 14819(function( $, undefined ) { 14820 14821$.effects.effect.slide = function( o, done ) { 14822 14823 // Create element 14824 var el = $( this ), 14825 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 14826 mode = $.effects.setMode( el, o.mode || "show" ), 14827 show = mode === "show", 14828 direction = o.direction || "left", 14829 ref = (direction === "up" || direction === "down") ? "top" : "left", 14830 positiveMotion = (direction === "up" || direction === "left"), 14831 distance, 14832 animation = {}; 14833 14834 // Adjust 14835 $.effects.save( el, props ); 14836 el.show(); 14837 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 14838 14839 $.effects.createWrapper( el ).css({ 14840 overflow: "hidden" 14841 }); 14842 14843 if ( show ) { 14844 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 14845 } 14846 14847 // Animation 14848 animation[ ref ] = ( show ? 14849 ( positiveMotion ? "+=" : "-=") : 14850 ( positiveMotion ? "-=" : "+=")) + 14851 distance; 14852 14853 // Animate 14854 el.animate( animation, { 14855 queue: false, 14856 duration: o.duration, 14857 easing: o.easing, 14858 complete: function() { 14859 if ( mode === "hide" ) { 14860 el.hide(); 14861 } 14862 $.effects.restore( el, props ); 14863 $.effects.removeWrapper( el ); 14864 done(); 14865 } 14866 }); 14867}; 14868 14869})(jQuery); 14870(function( $, undefined ) { 14871 14872$.effects.effect.transfer = function( o, done ) { 14873 var elem = $( this ), 14874 target = $( o.to ), 14875 targetFixed = target.css( "position" ) === "fixed", 14876 body = $("body"), 14877 fixTop = targetFixed ? body.scrollTop() : 0, 14878 fixLeft = targetFixed ? body.scrollLeft() : 0, 14879 endPosition = target.offset(), 14880 animation = { 14881 top: endPosition.top - fixTop , 14882 left: endPosition.left - fixLeft , 14883 height: target.innerHeight(), 14884 width: target.innerWidth() 14885 }, 14886 startPosition = elem.offset(), 14887 transfer = $( "<div class='ui-effects-transfer'></div>" ) 14888 .appendTo( document.body ) 14889 .addClass( o.className ) 14890 .css({ 14891 top: startPosition.top - fixTop , 14892 left: startPosition.left - fixLeft , 14893 height: elem.innerHeight(), 14894 width: elem.innerWidth(), 14895 position: targetFixed ? "fixed" : "absolute" 14896 }) 14897 .animate( animation, o.duration, o.easing, function() { 14898 transfer.remove(); 14899 done(); 14900 }); 14901}; 14902 14903})(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.