vendor: 9,731 bytes, lines 1-351
1/*! jQuery UI - v1.10.2 - 2013-04-04 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js 4* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11/*// $.ui might exist from components with no dependencies, e.g., $.ui.position 12*/ 13$.ui = $.ui || {}; 14 15$.extend( $.ui, { 16 version: "1.10.2", 17 18 keyCode: { 19 BACKSPACE: 8, 20 COMMA: 188, 21 DELETE: 46, 22 DOWN: 40, 23 END: 35, 24 ENTER: 13, 25 ESCAPE: 27, 26 HOME: 36, 27 LEFT: 37, 28 NUMPAD_ADD: 107, 29 NUMPAD_DECIMAL: 110, 30 NUMPAD_DIVIDE: 111, 31 NUMPAD_ENTER: 108, 32 NUMPAD_MULTIPLY: 106, 33 NUMPAD_SUBTRACT: 109, 34 PAGE_DOWN: 34, 35 PAGE_UP: 33, 36 PERIOD: 190, 37 RIGHT: 39, 38 SPACE: 32, 39 TAB: 9, 40 UP: 38 41 } 42}); 43 44/*// plugins 45*/ 46$.fn.extend({ 47 focus: (function( orig ) { 48 return function( delay, fn ) { 49 return typeof delay === "number" ? 50 this.each(function() { 51 var elem = this; 52 setTimeout(function() { 53 $( elem ).focus(); 54 if ( fn ) { 55 fn.call( elem ); 56 } 57 }, delay ); 58 }) : 59 orig.apply( this, arguments ); 60 }; 61 })( $.fn.focus ), 62 63 scrollParent: function() { 64 var scrollParent; 65 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 66 scrollParent = this.parents().filter(function() { 67 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 68 }).eq(0); 69 } else { 70 scrollParent = this.parents().filter(function() { 71 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 72 }).eq(0); 73 } 74 75 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 76 }, 77 78 zIndex: function( zIndex ) { 79 if ( zIndex !== undefined ) { 80 return this.css( "zIndex", zIndex ); 81 } 82 83 if ( this.length ) { 84 var elem = $( this[ 0 ] ), position, value; 85 while ( elem.length && elem[ 0 ] !== document ) { 86 /*// Ignore z-index if position is set to a value where z-index is ignored by the browser 87*/ 88 /*// This makes behavior of this function consistent across browsers 89*/ 90 /*// WebKit always returns auto if the element is positioned 91*/ 92 position = elem.css( "position" ); 93 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 94 /*// IE returns 0 when zIndex is not specified 95*/ 96 /*// other browsers return a string 97*/ 98 /*// we ignore the case of nested elements with an explicit value of 0 99*/ 100 /*// <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 101*/ 102 value = parseInt( elem.css( "zIndex" ), 10 ); 103 if ( !isNaN( value ) && value !== 0 ) { 104 return value; 105 } 106 } 107 elem = elem.parent(); 108 } 109 } 110 111 return 0; 112 }, 113 114 uniqueId: function() { 115 return this.each(function() { 116 if ( !this.id ) { 117 this.id = "ui-id-" + (++uuid); 118 } 119 }); 120 }, 121 122 removeUniqueId: function() { 123 return this.each(function() { 124 if ( runiqueId.test( this.id ) ) { 125 $( this ).removeAttr( "id" ); 126 } 127 }); 128 } 129}); 130 131/*// selectors 132*/ 133function focusable( element, isTabIndexNotNaN ) { 134 var map, mapName, img, 135 nodeName = element.nodeName.toLowerCase(); 136 if ( "area" === nodeName ) { 137 map = element.parentNode; 138 mapName = map.name; 139 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 140 return false; 141 } 142 img = $( "img[usemap=#" + mapName + "]" )[0]; 143 return !!img && visible( img ); 144 } 145 return ( /input|select|textarea|button|object/.test( nodeName ) ? 146 !element.disabled : 147 "a" === nodeName ? 148 element.href || isTabIndexNotNaN : 149 isTabIndexNotNaN) && 150 /*// the element and all of its ancestors must be visible 151*/ 152 visible( element ); 153} 154 155function visible( element ) { 156 return $.expr.filters.visible( element ) && 157 !$( element ).parents().addBack().filter(function() { 158 return $.css( this, "visibility" ) === "hidden"; 159 }).length; 160} 161 162$.extend( $.expr[ ":" ], { 163 data: $.expr.createPseudo ? 164 $.expr.createPseudo(function( dataName ) { 165 return function( elem ) { 166 return !!$.data( elem, dataName ); 167 }; 168 }) : 169 /*// support: jQuery <1.8 170*/ 171 function( elem, i, match ) { 172 return !!$.data( elem, match[ 3 ] ); 173 }, 174 175 focusable: function( element ) { 176 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 177 }, 178 179 tabbable: function( element ) { 180 var tabIndex = $.attr( element, "tabindex" ), 181 isTabIndexNaN = isNaN( tabIndex ); 182 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 183 } 184}); 185 186/*// support: jQuery <1.8 187*/ 188if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 189 $.each( [ "Width", "Height" ], function( i, name ) { 190 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 191 type = name.toLowerCase(), 192 orig = { 193 innerWidth: $.fn.innerWidth, 194 innerHeight: $.fn.innerHeight, 195 outerWidth: $.fn.outerWidth, 196 outerHeight: $.fn.outerHeight 197 }; 198 199 function reduce( elem, size, border, margin ) { 200 $.each( side, function() { 201 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 202 if ( border ) { 203 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 204 } 205 if ( margin ) { 206 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 207 } 208 }); 209 return size; 210 } 211 212 $.fn[ "inner" + name ] = function( size ) { 213 if ( size === undefined ) { 214 return orig[ "inner" + name ].call( this ); 215 } 216 217 return this.each(function() { 218 $( this ).css( type, reduce( this, size ) + "px" ); 219 }); 220 }; 221 222 $.fn[ "outer" + name] = function( size, margin ) { 223 if ( typeof size !== "number" ) { 224 return orig[ "outer" + name ].call( this, size ); 225 } 226 227 return this.each(function() { 228 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 229 }); 230 }; 231 }); 232} 233 234/*// support: jQuery <1.8 235*/ 236if ( !$.fn.addBack ) { 237 $.fn.addBack = function( selector ) { 238 return this.add( selector == null ? 239 this.prevObject : this.prevObject.filter( selector ) 240 ); 241 }; 242} 243 244/*// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 245*/ 246if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 247 $.fn.removeData = (function( removeData ) { 248 return function( key ) { 249 if ( arguments.length ) { 250 return removeData.call( this, $.camelCase( key ) ); 251 } else { 252 return removeData.call( this ); 253 } 254 }; 255 })( $.fn.removeData ); 256} 257 258 259 260 261 262/*// deprecated 263*/ 264$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 265 266$.support.selectstart = "onselectstart" in document.createElement( "div" ); 267$.fn.extend({ 268 disableSelection: function() { 269 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 270 ".ui-disableSelection", function( event ) { 271 event.preventDefault(); 272 }); 273 }, 274 275 enableSelection: function() { 276 return this.unbind( ".ui-disableSelection" ); 277 } 278}); 279 280$.extend( $.ui, { 281 /*// $.ui.plugin is deprecated. Use the proxy pattern instead. 282*/ 283 plugin: { 284 add: function( module, option, set ) { 285 var i, 286 proto = $.ui[ module ].prototype; 287 for ( i in set ) { 288 proto.plugins[ i ] = proto.plugins[ i ] || []; 289 proto.plugins[ i ].push( [ option, set[ i ] ] ); 290 } 291 }, 292 call: function( instance, name, args ) { 293 var i, 294 set = instance.plugins[ name ]; 295 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 296 return; 297 } 298 299 for ( i = 0; i < set.length; i++ ) { 300 if ( instance.options[ set[ i ][ 0 ] ] ) { 301 set[ i ][ 1 ].apply( instance.element, args ); 302 } 303 } 304 } 305 }, 306 307 /*// only used by resizable 308*/ 309 hasScroll: function( el, a ) { 310 311 //If overflow is hidden, the element might have extra content, but the user wants to hide it 312 if ( $( el ).css( "overflow" ) === "hidden") { 313 return false; 314 } 315 316 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 317 has = false; 318 319 if ( el[ scroll ] > 0 ) { 320 return true; 321 } 322 323 /*// TODO: determine which cases actually cause this to happen 324*/ 325 /*// if the element doesn't have the scroll set, see if it's possible to 326*/ 327 /*// set the scroll 328*/ 329 el[ scroll ] = 1; 330 has = ( el[ scroll ] > 0 ); 331 el[ scroll ] = 0; 332 return has; 333 } 334}); 335 336})( jQuery ); 337(function( $, undefined ) { 338 339var uuid = 0, 340 slice = Array.prototype.slice, 341 _cleanData = $.cleanData; 342$.cleanData = function( elems ) { 343 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 344 try { 345 $( elem ).triggerHandler( "remove" ); 346 /*// http://bugs.jquery.com/ticket/8235 347*/ 348 } catch( e ) {} 349 } 350 _cleanData( elems ); 351};
vendor: 15,043 bytes, lines 352-885
352 353$.widget = function( name, base, prototype ) { 354 var fullName, existingConstructor, constructor, basePrototype, 355 /*// proxiedPrototype allows the provided prototype to remain unmodified 356*/ 357 /*// so that it can be used as a mixin for multiple widgets (#8876) 358*/ 359 proxiedPrototype = {}, 360 namespace = name.split( "." )[ 0 ]; 361 362 name = name.split( "." )[ 1 ]; 363 fullName = namespace + "-" + name; 364 365 if ( !prototype ) { 366 prototype = base; 367 base = $.Widget; 368 } 369 370 /*// create selector for plugin 371*/ 372 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 373 return !!$.data( elem, fullName ); 374 }; 375 376 $[ namespace ] = $[ namespace ] || {}; 377 existingConstructor = $[ namespace ][ name ]; 378 constructor = $[ namespace ][ name ] = function( options, element ) { 379 /*// allow instantiation without "new" keyword 380*/ 381 if ( !this._createWidget ) { 382 return new constructor( options, element ); 383 } 384 385 /*// allow instantiation without initializing for simple inheritance 386*/ 387 /*// must use "new" keyword (the code above always passes args) 388*/ 389 if ( arguments.length ) { 390 this._createWidget( options, element ); 391 } 392 }; 393 /*// extend with the existing constructor to carry over any static properties 394*/ 395 $.extend( constructor, existingConstructor, { 396 version: prototype.version, 397 /*// copy the object used to create the prototype in case we need to 398*/ 399 /*// redefine the widget later 400*/ 401 _proto: $.extend( {}, prototype ), 402 /*// track widgets that inherit from this widget in case this widget is 403*/ 404 /*// redefined after a widget inherits from it 405*/ 406 _childConstructors: [] 407 }); 408 409 basePrototype = new base(); 410 /*// we need to make the options hash a property directly on the new instance 411*/ 412 /*// otherwise we'll modify the options hash on the prototype that we're 413*/ 414 /*// inheriting from 415*/ 416 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 417 $.each( prototype, function( prop, value ) { 418 if ( !$.isFunction( value ) ) { 419 proxiedPrototype[ prop ] = value; 420 return; 421 } 422 proxiedPrototype[ prop ] = (function() { 423 var _super = function() { 424 return base.prototype[ prop ].apply( this, arguments ); 425 }, 426 _superApply = function( args ) { 427 return base.prototype[ prop ].apply( this, args ); 428 }; 429 return function() { 430 var __super = this._super, 431 __superApply = this._superApply, 432 returnValue; 433 434 this._super = _super; 435 this._superApply = _superApply; 436 437 returnValue = value.apply( this, arguments ); 438 439 this._super = __super; 440 this._superApply = __superApply; 441 442 return returnValue; 443 }; 444 })(); 445 }); 446 constructor.prototype = $.widget.extend( basePrototype, { 447 /*// TODO: remove support for widgetEventPrefix 448*/ 449 /*// always use the name + a colon as the prefix, e.g., draggable:start 450*/ 451 /*// don't prefix for widgets that aren't DOM-based 452*/ 453 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 454 }, proxiedPrototype, { 455 constructor: constructor, 456 namespace: namespace, 457 widgetName: name, 458 widgetFullName: fullName 459 }); 460 461 /*// If this widget is being redefined then we need to find all widgets that 462*/ 463 /*// are inheriting from it and redefine all of them so that they inherit from 464*/ 465 /*// the new version of this widget. We're essentially trying to replace one 466*/ 467 /*// level in the prototype chain. 468*/ 469 if ( existingConstructor ) { 470 $.each( existingConstructor._childConstructors, function( i, child ) { 471 var childPrototype = child.prototype; 472 473 /*// redefine the child widget using the same prototype that was 474*/ 475 /*// originally used, but inherit from the new version of the base 476*/ 477 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 478 }); 479 /*// remove the list of existing child constructors from the old constructor 480*/ 481 /*// so the old child constructors can be garbage collected 482*/ 483 delete existingConstructor._childConstructors; 484 } else { 485 base._childConstructors.push( constructor ); 486 } 487 488 $.widget.bridge( name, constructor ); 489}; 490 491$.widget.extend = function( target ) { 492 var input = slice.call( arguments, 1 ), 493 inputIndex = 0, 494 inputLength = input.length, 495 key, 496 value; 497 for ( ; inputIndex < inputLength; inputIndex++ ) { 498 for ( key in input[ inputIndex ] ) { 499 value = input[ inputIndex ][ key ]; 500 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 501 /*// Clone objects 502*/ 503 if ( $.isPlainObject( value ) ) { 504 target[ key ] = $.isPlainObject( target[ key ] ) ? 505 $.widget.extend( {}, target[ key ], value ) : 506 /*// Don't extend strings, arrays, etc. with objects 507*/ 508 $.widget.extend( {}, value ); 509 /*// Copy everything else by reference 510*/ 511 } else { 512 target[ key ] = value; 513 } 514 } 515 } 516 } 517 return target; 518}; 519 520$.widget.bridge = function( name, object ) { 521 var fullName = object.prototype.widgetFullName || name; 522 $.fn[ name ] = function( options ) { 523 var isMethodCall = typeof options === "string", 524 args = slice.call( arguments, 1 ), 525 returnValue = this; 526 527 /*// allow multiple hashes to be passed on init 528*/ 529 options = !isMethodCall && args.length ? 530 $.widget.extend.apply( null, [ options ].concat(args) ) : 531 options; 532 533 if ( isMethodCall ) { 534 this.each(function() { 535 var methodValue, 536 instance = $.data( this, fullName ); 537 if ( !instance ) { 538 return $.error( "cannot call methods on " + name + " prior to initialization; " + 539 "attempted to call method '" + options + "'" ); 540 } 541 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 542 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 543 } 544 methodValue = instance[ options ].apply( instance, args ); 545 if ( methodValue !== instance && methodValue !== undefined ) { 546 returnValue = methodValue && methodValue.jquery ? 547 returnValue.pushStack( methodValue.get() ) : 548 methodValue; 549 return false; 550 } 551 }); 552 } else { 553 this.each(function() { 554 var instance = $.data( this, fullName ); 555 if ( instance ) { 556 instance.option( options || {} )._init(); 557 } else { 558 $.data( this, fullName, new object( options, this ) ); 559 } 560 }); 561 } 562 563 return returnValue; 564 }; 565}; 566 567$.Widget = function( /* options, element */ ) {}; 568$.Widget._childConstructors = []; 569 570$.Widget.prototype = { 571 widgetName: "widget", 572 widgetEventPrefix: "", 573 defaultElement: "<div>", 574 options: { 575 disabled: false, 576 577 /*// callbacks 578*/ 579 create: null 580 }, 581 _createWidget: function( options, element ) { 582 element = $( element || this.defaultElement || this )[ 0 ]; 583 this.element = $( element ); 584 this.uuid = uuid++; 585 this.eventNamespace = "." + this.widgetName + this.uuid; 586 this.options = $.widget.extend( {}, 587 this.options, 588 this._getCreateOptions(), 589 options ); 590 591 this.bindings = $(); 592 this.hoverable = $(); 593 this.focusable = $(); 594 595 if ( element !== this ) { 596 $.data( element, this.widgetFullName, this ); 597 this._on( true, this.element, { 598 remove: function( event ) { 599 if ( event.target === element ) { 600 this.destroy(); 601 } 602 } 603 }); 604 this.document = $( element.style ? 605 /*// element within the document 606*/ 607 element.ownerDocument : 608 /*// element is window or document 609*/ 610 element.document || element ); 611 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 612 } 613 614 this._create(); 615 this._trigger( "create", null, this._getCreateEventData() ); 616 this._init(); 617 }, 618 _getCreateOptions: $.noop, 619 _getCreateEventData: $.noop, 620 _create: $.noop, 621 _init: $.noop, 622 623 destroy: function() { 624 this._destroy(); 625 /*// we can probably remove the unbind calls in 2.0 626*/ 627 /*// all event bindings should go through this._on() 628*/ 629 this.element 630 .unbind( this.eventNamespace ) 631 /*// 1.9 BC for #7810 632*/ 633 /*// TODO remove dual storage 634*/ 635 .removeData( this.widgetName ) 636 .removeData( this.widgetFullName ) 637 /*// support: jquery <1.6.3 638*/ 639 /*// http://bugs.jquery.com/ticket/9413 640*/ 641 .removeData( $.camelCase( this.widgetFullName ) ); 642 this.widget() 643 .unbind( this.eventNamespace ) 644 .removeAttr( "aria-disabled" ) 645 .removeClass( 646 this.widgetFullName + "-disabled " + 647 "ui-state-disabled" ); 648 649 /*// clean up events and states 650*/ 651 this.bindings.unbind( this.eventNamespace ); 652 this.hoverable.removeClass( "ui-state-hover" ); 653 this.focusable.removeClass( "ui-state-focus" ); 654 }, 655 _destroy: $.noop, 656 657 widget: function() { 658 return this.element; 659 }, 660 661 option: function( key, value ) { 662 var options = key, 663 parts, 664 curOption, 665 i; 666 667 if ( arguments.length === 0 ) { 668 /*// don't return a reference to the internal hash 669*/ 670 return $.widget.extend( {}, this.options ); 671 } 672 673 if ( typeof key === "string" ) { 674 /*// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 675*/ 676 options = {}; 677 parts = key.split( "." ); 678 key = parts.shift(); 679 if ( parts.length ) { 680 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 681 for ( i = 0; i < parts.length - 1; i++ ) { 682 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 683 curOption = curOption[ parts[ i ] ]; 684 } 685 key = parts.pop(); 686 if ( value === undefined ) { 687 return curOption[ key ] === undefined ? null : curOption[ key ]; 688 } 689 curOption[ key ] = value; 690 } else { 691 if ( value === undefined ) { 692 return this.options[ key ] === undefined ? null : this.options[ key ]; 693 } 694 options[ key ] = value; 695 } 696 } 697 698 this._setOptions( options ); 699 700 return this; 701 }, 702 _setOptions: function( options ) { 703 var key; 704 705 for ( key in options ) { 706 this._setOption( key, options[ key ] ); 707 } 708 709 return this; 710 }, 711 _setOption: function( key, value ) { 712 this.options[ key ] = value; 713 714 if ( key === "disabled" ) { 715 this.widget() 716 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 717 .attr( "aria-disabled", value ); 718 this.hoverable.removeClass( "ui-state-hover" ); 719 this.focusable.removeClass( "ui-state-focus" ); 720 } 721 722 return this; 723 }, 724 725 enable: function() { 726 return this._setOption( "disabled", false ); 727 }, 728 disable: function() { 729 return this._setOption( "disabled", true ); 730 }, 731 732 _on: function( suppressDisabledCheck, element, handlers ) { 733 var delegateElement, 734 instance = this; 735 736 /*// no suppressDisabledCheck flag, shuffle arguments 737*/ 738 if ( typeof suppressDisabledCheck !== "boolean" ) { 739 handlers = element; 740 element = suppressDisabledCheck; 741 suppressDisabledCheck = false; 742 } 743 744 /*// no element argument, shuffle and use this.element 745*/ 746 if ( !handlers ) { 747 handlers = element; 748 element = this.element; 749 delegateElement = this.widget(); 750 } else { 751 /*// accept selectors, DOM elements 752*/ 753 element = delegateElement = $( element ); 754 this.bindings = this.bindings.add( element ); 755 } 756 757 $.each( handlers, function( event, handler ) { 758 function handlerProxy() { 759 /*// allow widgets to customize the disabled handling 760*/ 761 /*// - disabled as an array instead of boolean 762*/ 763 /*// - disabled class as method for disabling individual parts 764*/ 765 if ( !suppressDisabledCheck && 766 ( instance.options.disabled === true || 767 $( this ).hasClass( "ui-state-disabled" ) ) ) { 768 return; 769 } 770 return ( typeof handler === "string" ? instance[ handler ] : handler ) 771 .apply( instance, arguments ); 772 } 773 774 /*// copy the guid so direct unbinding works 775*/ 776 if ( typeof handler !== "string" ) { 777 handlerProxy.guid = handler.guid = 778 handler.guid || handlerProxy.guid || $.guid++; 779 } 780 781 var match = event.match( /^(\w+)\s*(.*)$/ ), 782 eventName = match[1] + instance.eventNamespace, 783 selector = match[2]; 784 if ( selector ) { 785 delegateElement.delegate( selector, eventName, handlerProxy ); 786 } else { 787 element.bind( eventName, handlerProxy ); 788 } 789 }); 790 }, 791 792 _off: function( element, eventName ) { 793 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 794 element.unbind( eventName ).undelegate( eventName ); 795 }, 796 797 _delay: function( handler, delay ) { 798 function handlerProxy() { 799 return ( typeof handler === "string" ? instance[ handler ] : handler ) 800 .apply( instance, arguments ); 801 } 802 var instance = this; 803 return setTimeout( handlerProxy, delay || 0 ); 804 }, 805 806 _hoverable: function( element ) { 807 this.hoverable = this.hoverable.add( element ); 808 this._on( element, { 809 mouseenter: function( event ) { 810 $( event.currentTarget ).addClass( "ui-state-hover" ); 811 }, 812 mouseleave: function( event ) { 813 $( event.currentTarget ).removeClass( "ui-state-hover" ); 814 } 815 }); 816 }, 817 818 _focusable: function( element ) { 819 this.focusable = this.focusable.add( element ); 820 this._on( element, { 821 focusin: function( event ) { 822 $( event.currentTarget ).addClass( "ui-state-focus" ); 823 }, 824 focusout: function( event ) { 825 $( event.currentTarget ).removeClass( "ui-state-focus" ); 826 } 827 }); 828 }, 829 830 _trigger: function( type, event, data ) { 831 var prop, orig, 832 callback = this.options[ type ]; 833 834 data = data || {}; 835 event = $.Event( event ); 836 event.type = ( type === this.widgetEventPrefix ? 837 type : 838 this.widgetEventPrefix + type ).toLowerCase(); 839 /*// the original event may come from any element 840*/ 841 /*// so we need to reset the target on the new event 842*/ 843 event.target = this.element[ 0 ]; 844 845 /*// copy original event properties over to the new event 846*/ 847 orig = event.originalEvent; 848 if ( orig ) { 849 for ( prop in orig ) { 850 if ( !( prop in event ) ) { 851 event[ prop ] = orig[ prop ]; 852 } 853 } 854 } 855 856 this.element.trigger( event, data ); 857 return !( $.isFunction( callback ) && 858 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 859 event.isDefaultPrevented() ); 860 } 861}; 862 863$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 864 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 865 if ( typeof options === "string" ) { 866 options = { effect: options }; 867 } 868 var hasOptions, 869 effectName = !options ? 870 method : 871 options === true || typeof options === "number" ? 872 defaultEffect : 873 options.effect || defaultEffect; 874 options = options || {}; 875 if ( typeof options === "number" ) { 876 options = { duration: options }; 877 } 878 hasOptions = !$.isEmptyObject( options ); 879 options.complete = callback; 880 if ( options.delay ) { 881 element.delay( options.delay ); 882 } 883 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 884 element[ method ]( options ); 885 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 52,999 bytes, lines 886-2529
886 element[ effectName ]( options.duration, options.easing, callback ); 887 } else { 888 element.queue(function( next ) { 889 $( this )[ method ](); 890 if ( callback ) { 891 callback.call( element[ 0 ] ); 892 } 893 next(); 894 }); 895 } 896 }; 897}); 898 899})( jQuery ); 900(function( $, undefined ) { 901 902var mouseHandled = false; 903$( document ).mouseup( function() { 904 mouseHandled = false; 905}); 906 907$.widget("ui.mouse", { 908 version: "1.10.2", 909 options: { 910 cancel: "input,textarea,button,select,option", 911 distance: 1, 912 delay: 0 913 }, 914 _mouseInit: function() { 915 var that = this; 916 917 this.element 918 .bind("mousedown."+this.widgetName, function(event) { 919 return that._mouseDown(event); 920 }) 921 .bind("click."+this.widgetName, function(event) { 922 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 923 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 924 event.stopImmediatePropagation(); 925 return false; 926 } 927 }); 928 929 this.started = false; 930 }, 931 932 /*// TODO: make sure destroying one instance of mouse doesn't mess with 933*/ 934 /*// other instances of mouse 935*/ 936 _mouseDestroy: function() { 937 this.element.unbind("."+this.widgetName); 938 if ( this._mouseMoveDelegate ) { 939 $(document) 940 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 941 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 942 } 943 }, 944 945 _mouseDown: function(event) { 946 /*// don't let more than one widget handle mouseStart 947*/ 948 if( mouseHandled ) { return; } 949 950 /*// we may have missed mouseup (out of window) 951*/ 952 (this._mouseStarted && this._mouseUp(event)); 953 954 this._mouseDownEvent = event; 955 956 var that = this, 957 btnIsLeft = (event.which === 1), 958 /*// event.target.nodeName works around a bug in IE 8 with 959*/ 960 /*// disabled inputs (#7620) 961*/ 962 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 963 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 964 return true; 965 } 966 967 this.mouseDelayMet = !this.options.delay; 968 if (!this.mouseDelayMet) { 969 this._mouseDelayTimer = setTimeout(function() { 970 that.mouseDelayMet = true; 971 }, this.options.delay); 972 } 973 974 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 975 this._mouseStarted = (this._mouseStart(event) !== false); 976 if (!this._mouseStarted) { 977 event.preventDefault(); 978 return true; 979 } 980 } 981 982 /*// Click event may never have fired (Gecko & Opera) 983*/ 984 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 985 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 986 } 987 988 /*// these delegates are required to keep context 989*/ 990 this._mouseMoveDelegate = function(event) { 991 return that._mouseMove(event); 992 }; 993 this._mouseUpDelegate = function(event) { 994 return that._mouseUp(event); 995 }; 996 $(document) 997 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 998 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 999 1000 event.preventDefault(); 1001 1002 mouseHandled = true; 1003 return true; 1004 }, 1005 1006 _mouseMove: function(event) { 1007 /*// IE mouseup check - mouseup happened when mouse was out of window 1008*/ 1009 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 1010 return this._mouseUp(event); 1011 } 1012 1013 if (this._mouseStarted) { 1014 this._mouseDrag(event); 1015 return event.preventDefault(); 1016 } 1017 1018 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 1019 this._mouseStarted = 1020 (this._mouseStart(this._mouseDownEvent, event) !== false); 1021 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 1022 } 1023 1024 return !this._mouseStarted; 1025 }, 1026 1027 _mouseUp: function(event) { 1028 $(document) 1029 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 1030 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 1031 1032 if (this._mouseStarted) { 1033 this._mouseStarted = false; 1034 1035 if (event.target === this._mouseDownEvent.target) { 1036 $.data(event.target, this.widgetName + ".preventClickEvent", true); 1037 } 1038 1039 this._mouseStop(event); 1040 } 1041 1042 return false; 1043 }, 1044 1045 _mouseDistanceMet: function(event) { 1046 return (Math.max( 1047 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1048 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1049 ) >= this.options.distance 1050 ); 1051 }, 1052 1053 _mouseDelayMet: function(/* event */) { 1054 return this.mouseDelayMet; 1055 }, 1056 1057 /*// These are placeholder methods, to be overriden by extending plugin 1058*/ 1059 _mouseStart: function(/* event */) {}, 1060 _mouseDrag: function(/* event */) {}, 1061 _mouseStop: function(/* event */) {}, 1062 _mouseCapture: function(/* event */) { return true; } 1063}); 1064 1065})(jQuery); 1066(function( $, undefined ) { 1067 1068$.ui = $.ui || {}; 1069 1070var cachedScrollbarWidth, 1071 max = Math.max, 1072 abs = Math.abs, 1073 round = Math.round, 1074 rhorizontal = /left|center|right/, 1075 rvertical = /top|center|bottom/, 1076 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 1077 rposition = /^\w+/, 1078 rpercent = /%$/, 1079 _position = $.fn.position; 1080 1081function getOffsets( offsets, width, height ) { 1082 return [ 1083 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1084 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1085 ]; 1086} 1087 1088function parseCss( element, property ) { 1089 return parseInt( $.css( element, property ), 10 ) || 0; 1090} 1091 1092function getDimensions( elem ) { 1093 var raw = elem[0]; 1094 if ( raw.nodeType === 9 ) { 1095 return { 1096 width: elem.width(), 1097 height: elem.height(), 1098 offset: { top: 0, left: 0 } 1099 }; 1100 } 1101 if ( $.isWindow( raw ) ) { 1102 return { 1103 width: elem.width(), 1104 height: elem.height(), 1105 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1106 }; 1107 } 1108 if ( raw.preventDefault ) { 1109 return { 1110 width: 0, 1111 height: 0, 1112 offset: { top: raw.pageY, left: raw.pageX } 1113 }; 1114 } 1115 return { 1116 width: elem.outerWidth(), 1117 height: elem.outerHeight(), 1118 offset: elem.offset() 1119 }; 1120} 1121 1122$.position = { 1123 scrollbarWidth: function() { 1124 if ( cachedScrollbarWidth !== undefined ) { 1125 return cachedScrollbarWidth; 1126 } 1127 var w1, w2, 1128 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1129 innerDiv = div.children()[0]; 1130 1131 $( "body" ).append( div ); 1132 w1 = innerDiv.offsetWidth; 1133 div.css( "overflow", "scroll" ); 1134 1135 w2 = innerDiv.offsetWidth; 1136 1137 if ( w1 === w2 ) { 1138 w2 = div[0].clientWidth; 1139 } 1140 1141 div.remove(); 1142 1143 return (cachedScrollbarWidth = w1 - w2); 1144 }, 1145 getScrollInfo: function( within ) { 1146 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 1147 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 1148 hasOverflowX = overflowX === "scroll" || 1149 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1150 hasOverflowY = overflowY === "scroll" || 1151 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1152 return { 1153 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1154 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1155 }; 1156 }, 1157 getWithinInfo: function( element ) { 1158 var withinElement = $( element || window ), 1159 isWindow = $.isWindow( withinElement[0] ); 1160 return { 1161 element: withinElement, 1162 isWindow: isWindow, 1163 offset: withinElement.offset() || { left: 0, top: 0 }, 1164 scrollLeft: withinElement.scrollLeft(), 1165 scrollTop: withinElement.scrollTop(), 1166 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1167 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1168 }; 1169 } 1170}; 1171 1172$.fn.position = function( options ) { 1173 if ( !options || !options.of ) { 1174 return _position.apply( this, arguments ); 1175 } 1176 1177 /*// make a copy, we don't want to modify arguments 1178*/ 1179 options = $.extend( {}, options ); 1180 1181 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1182 target = $( options.of ), 1183 within = $.position.getWithinInfo( options.within ), 1184 scrollInfo = $.position.getScrollInfo( within ), 1185 collision = ( options.collision || "flip" ).split( " " ), 1186 offsets = {}; 1187 1188 dimensions = getDimensions( target ); 1189 if ( target[0].preventDefault ) { 1190 /*// force left top to allow flipping 1191*/ 1192 options.at = "left top"; 1193 } 1194 targetWidth = dimensions.width; 1195 targetHeight = dimensions.height; 1196 targetOffset = dimensions.offset; 1197 /*// clone to reuse original targetOffset later 1198*/ 1199 basePosition = $.extend( {}, targetOffset ); 1200 1201 /*// force my and at to have valid horizontal and vertical positions 1202*/ 1203 /*// if a value is missing or invalid, it will be converted to center 1204*/ 1205 $.each( [ "my", "at" ], function() { 1206 var pos = ( options[ this ] || "" ).split( " " ), 1207 horizontalOffset, 1208 verticalOffset; 1209 1210 if ( pos.length === 1) { 1211 pos = rhorizontal.test( pos[ 0 ] ) ? 1212 pos.concat( [ "center" ] ) : 1213 rvertical.test( pos[ 0 ] ) ? 1214 [ "center" ].concat( pos ) : 1215 [ "center", "center" ]; 1216 } 1217 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1218 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1219 1220 /*// calculate offsets 1221*/ 1222 horizontalOffset = roffset.exec( pos[ 0 ] ); 1223 verticalOffset = roffset.exec( pos[ 1 ] ); 1224 offsets[ this ] = [ 1225 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1226 verticalOffset ? verticalOffset[ 0 ] : 0 1227 ]; 1228 1229 /*// reduce to just the positions without the offsets 1230*/ 1231 options[ this ] = [ 1232 rposition.exec( pos[ 0 ] )[ 0 ], 1233 rposition.exec( pos[ 1 ] )[ 0 ] 1234 ]; 1235 }); 1236 1237 /*// normalize collision option 1238*/ 1239 if ( collision.length === 1 ) { 1240 collision[ 1 ] = collision[ 0 ]; 1241 } 1242 1243 if ( options.at[ 0 ] === "right" ) { 1244 basePosition.left += targetWidth; 1245 } else if ( options.at[ 0 ] === "center" ) { 1246 basePosition.left += targetWidth / 2; 1247 } 1248 1249 if ( options.at[ 1 ] === "bottom" ) { 1250 basePosition.top += targetHeight; 1251 } else if ( options.at[ 1 ] === "center" ) { 1252 basePosition.top += targetHeight / 2; 1253 } 1254 1255 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1256 basePosition.left += atOffset[ 0 ]; 1257 basePosition.top += atOffset[ 1 ]; 1258 1259 return this.each(function() { 1260 var collisionPosition, using, 1261 elem = $( this ), 1262 elemWidth = elem.outerWidth(), 1263 elemHeight = elem.outerHeight(), 1264 marginLeft = parseCss( this, "marginLeft" ), 1265 marginTop = parseCss( this, "marginTop" ), 1266 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1267 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1268 position = $.extend( {}, basePosition ), 1269 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1270 1271 if ( options.my[ 0 ] === "right" ) { 1272 position.left -= elemWidth; 1273 } else if ( options.my[ 0 ] === "center" ) { 1274 position.left -= elemWidth / 2; 1275 } 1276 1277 if ( options.my[ 1 ] === "bottom" ) { 1278 position.top -= elemHeight; 1279 } else if ( options.my[ 1 ] === "center" ) { 1280 position.top -= elemHeight / 2; 1281 } 1282 1283 position.left += myOffset[ 0 ]; 1284 position.top += myOffset[ 1 ]; 1285 1286 /*// if the browser doesn't support fractions, then round for consistent results 1287*/ 1288 if ( !$.support.offsetFractions ) { 1289 position.left = round( position.left ); 1290 position.top = round( position.top ); 1291 } 1292 1293 collisionPosition = { 1294 marginLeft: marginLeft, 1295 marginTop: marginTop 1296 }; 1297 1298 $.each( [ "left", "top" ], function( i, dir ) { 1299 if ( $.ui.position[ collision[ i ] ] ) { 1300 $.ui.position[ collision[ i ] ][ dir ]( position, { 1301 targetWidth: targetWidth, 1302 targetHeight: targetHeight, 1303 elemWidth: elemWidth, 1304 elemHeight: elemHeight, 1305 collisionPosition: collisionPosition, 1306 collisionWidth: collisionWidth, 1307 collisionHeight: collisionHeight, 1308 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1309 my: options.my, 1310 at: options.at, 1311 within: within, 1312 elem : elem 1313 }); 1314 } 1315 }); 1316 1317 if ( options.using ) { 1318 /*// adds feedback as second argument to using callback, if present 1319*/ 1320 using = function( props ) { 1321 var left = targetOffset.left - position.left, 1322 right = left + targetWidth - elemWidth, 1323 top = targetOffset.top - position.top, 1324 bottom = top + targetHeight - elemHeight, 1325 feedback = { 1326 target: { 1327 element: target, 1328 left: targetOffset.left, 1329 top: targetOffset.top, 1330 width: targetWidth, 1331 height: targetHeight 1332 }, 1333 element: { 1334 element: elem, 1335 left: position.left, 1336 top: position.top, 1337 width: elemWidth, 1338 height: elemHeight 1339 }, 1340 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1341 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1342 }; 1343 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1344 feedback.horizontal = "center"; 1345 } 1346 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1347 feedback.vertical = "middle"; 1348 } 1349 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1350 feedback.important = "horizontal"; 1351 } else { 1352 feedback.important = "vertical"; 1353 } 1354 options.using.call( this, props, feedback ); 1355 }; 1356 } 1357 1358 elem.offset( $.extend( position, { using: using } ) ); 1359 }); 1360}; 1361 1362$.ui.position = { 1363 fit: { 1364 left: function( position, data ) { 1365 var within = data.within, 1366 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1367 outerWidth = within.width, 1368 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1369 overLeft = withinOffset - collisionPosLeft, 1370 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1371 newOverRight; 1372 1373 /*// element is wider than within 1374*/ 1375 if ( data.collisionWidth > outerWidth ) { 1376 /*// element is initially over the left side of within 1377*/ 1378 if ( overLeft > 0 && overRight <= 0 ) { 1379 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1380 position.left += overLeft - newOverRight; 1381 /*// element is initially over right side of within 1382*/ 1383 } else if ( overRight > 0 && overLeft <= 0 ) { 1384 position.left = withinOffset; 1385 /*// element is initially over both left and right sides of within 1386*/ 1387 } else { 1388 if ( overLeft > overRight ) { 1389 position.left = withinOffset + outerWidth - data.collisionWidth; 1390 } else { 1391 position.left = withinOffset; 1392 } 1393 } 1394 /*// too far left -> align with left edge 1395*/ 1396 } else if ( overLeft > 0 ) { 1397 position.left += overLeft; 1398 /*// too far right -> align with right edge 1399*/ 1400 } else if ( overRight > 0 ) { 1401 position.left -= overRight; 1402 /*// adjust based on position and margin 1403*/ 1404 } else { 1405 position.left = max( position.left - collisionPosLeft, position.left ); 1406 } 1407 }, 1408 top: function( position, data ) { 1409 var within = data.within, 1410 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1411 outerHeight = data.within.height, 1412 collisionPosTop = position.top - data.collisionPosition.marginTop, 1413 overTop = withinOffset - collisionPosTop, 1414 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1415 newOverBottom; 1416 1417 /*// element is taller than within 1418*/ 1419 if ( data.collisionHeight > outerHeight ) { 1420 /*// element is initially over the top of within 1421*/ 1422 if ( overTop > 0 && overBottom <= 0 ) { 1423 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1424 position.top += overTop - newOverBottom; 1425 /*// element is initially over bottom of within 1426*/ 1427 } else if ( overBottom > 0 && overTop <= 0 ) { 1428 position.top = withinOffset; 1429 /*// element is initially over both top and bottom of within 1430*/ 1431 } else { 1432 if ( overTop > overBottom ) { 1433 position.top = withinOffset + outerHeight - data.collisionHeight; 1434 } else { 1435 position.top = withinOffset; 1436 } 1437 } 1438 /*// too far up -> align with top 1439*/ 1440 } else if ( overTop > 0 ) { 1441 position.top += overTop; 1442 /*// too far down -> align with bottom edge 1443*/ 1444 } else if ( overBottom > 0 ) { 1445 position.top -= overBottom; 1446 /*// adjust based on position and margin 1447*/ 1448 } else { 1449 position.top = max( position.top - collisionPosTop, position.top ); 1450 } 1451 } 1452 }, 1453 flip: { 1454 left: function( position, data ) { 1455 var within = data.within, 1456 withinOffset = within.offset.left + within.scrollLeft, 1457 outerWidth = within.width, 1458 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1459 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1460 overLeft = collisionPosLeft - offsetLeft, 1461 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1462 myOffset = data.my[ 0 ] === "left" ? 1463 -data.elemWidth : 1464 data.my[ 0 ] === "right" ? 1465 data.elemWidth : 1466 0, 1467 atOffset = data.at[ 0 ] === "left" ? 1468 data.targetWidth : 1469 data.at[ 0 ] === "right" ? 1470 -data.targetWidth : 1471 0, 1472 offset = -2 * data.offset[ 0 ], 1473 newOverRight, 1474 newOverLeft; 1475 1476 if ( overLeft < 0 ) { 1477 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1478 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1479 position.left += myOffset + atOffset + offset; 1480 } 1481 } 1482 else if ( overRight > 0 ) { 1483 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1484 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1485 position.left += myOffset + atOffset + offset; 1486 } 1487 } 1488 }, 1489 top: function( position, data ) { 1490 var within = data.within, 1491 withinOffset = within.offset.top + within.scrollTop, 1492 outerHeight = within.height, 1493 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1494 collisionPosTop = position.top - data.collisionPosition.marginTop, 1495 overTop = collisionPosTop - offsetTop, 1496 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1497 top = data.my[ 1 ] === "top", 1498 myOffset = top ? 1499 -data.elemHeight : 1500 data.my[ 1 ] === "bottom" ? 1501 data.elemHeight : 1502 0, 1503 atOffset = data.at[ 1 ] === "top" ? 1504 data.targetHeight : 1505 data.at[ 1 ] === "bottom" ? 1506 -data.targetHeight : 1507 0, 1508 offset = -2 * data.offset[ 1 ], 1509 newOverTop, 1510 newOverBottom; 1511 if ( overTop < 0 ) { 1512 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1513 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1514 position.top += myOffset + atOffset + offset; 1515 } 1516 } 1517 else if ( overBottom > 0 ) { 1518 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1519 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1520 position.top += myOffset + atOffset + offset; 1521 } 1522 } 1523 } 1524 }, 1525 flipfit: { 1526 left: function() { 1527 $.ui.position.flip.left.apply( this, arguments ); 1528 $.ui.position.fit.left.apply( this, arguments ); 1529 }, 1530 top: function() { 1531 $.ui.position.flip.top.apply( this, arguments ); 1532 $.ui.position.fit.top.apply( this, arguments ); 1533 } 1534 } 1535}; 1536 1537/*// fraction support test 1538*/ 1539(function () { 1540 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1541 body = document.getElementsByTagName( "body" )[ 0 ], 1542 div = document.createElement( "div" ); 1543 1544 //Create a "fake body" for testing based on method used in jQuery.support 1545 testElement = document.createElement( body ? "div" : "body" ); 1546 testElementStyle = { 1547 visibility: "hidden", 1548 width: 0, 1549 height: 0, 1550 border: 0, 1551 margin: 0, 1552 background: "none" 1553 }; 1554 if ( body ) { 1555 $.extend( testElementStyle, { 1556 position: "absolute", 1557 left: "-1000px", 1558 top: "-1000px" 1559 }); 1560 } 1561 for ( i in testElementStyle ) { 1562 testElement.style[ i ] = testElementStyle[ i ]; 1563 } 1564 testElement.appendChild( div ); 1565 testElementParent = body || document.documentElement; 1566 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1567 1568 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1569 1570 offsetLeft = $( div ).offset().left; 1571 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1572 1573 testElement.innerHTML = ""; 1574 testElementParent.removeChild( testElement ); 1575})(); 1576 1577}( jQuery ) ); 1578(function( $, undefined ) { 1579 1580$.widget("ui.draggable", $.ui.mouse, { 1581 version: "1.10.2", 1582 widgetEventPrefix: "drag", 1583 options: { 1584 addClasses: true, 1585 appendTo: "parent", 1586 axis: false, 1587 connectToSortable: false, 1588 containment: false, 1589 cursor: "auto", 1590 cursorAt: false, 1591 grid: false, 1592 handle: false, 1593 helper: "original", 1594 iframeFix: false, 1595 opacity: false, 1596 refreshPositions: false, 1597 revert: false, 1598 revertDuration: 500, 1599 scope: "default", 1600 scroll: true, 1601 scrollSensitivity: 20, 1602 scrollSpeed: 20, 1603 snap: false, 1604 snapMode: "both", 1605 snapTolerance: 20, 1606 stack: false, 1607 zIndex: false, 1608 1609 /*// callbacks 1610*/ 1611 drag: null, 1612 start: null, 1613 stop: null 1614 }, 1615 _create: function() { 1616 1617 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1618 this.element[0].style.position = "relative"; 1619 } 1620 if (this.options.addClasses){ 1621 this.element.addClass("ui-draggable"); 1622 } 1623 if (this.options.disabled){ 1624 this.element.addClass("ui-draggable-disabled"); 1625 } 1626 1627 this._mouseInit(); 1628 1629 }, 1630 1631 _destroy: function() { 1632 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1633 this._mouseDestroy(); 1634 }, 1635 1636 _mouseCapture: function(event) { 1637 1638 var o = this.options; 1639 1640 /*// among others, prevent a drag on a resizable-handle 1641*/ 1642 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1643 return false; 1644 } 1645 1646 //Quit if we're not on a valid handle 1647 this.handle = this._getHandle(event); 1648 if (!this.handle) { 1649 return false; 1650 } 1651 1652 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1653 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1654 .css({ 1655 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1656 position: "absolute", opacity: "0.001", zIndex: 1000 1657 }) 1658 .css($(this).offset()) 1659 .appendTo("body"); 1660 }); 1661 1662 return true; 1663 1664 }, 1665 1666 _mouseStart: function(event) { 1667 1668 var o = this.options; 1669 1670 //Create and append the visible helper 1671 this.helper = this._createHelper(event); 1672 1673 this.helper.addClass("ui-draggable-dragging"); 1674 1675 //Cache the helper size 1676 this._cacheHelperProportions(); 1677 1678 //If ddmanager is used for droppables, set the global draggable 1679 if($.ui.ddmanager) { 1680 $.ui.ddmanager.current = this; 1681 } 1682 1683 /* 1684 * - Position generation - 1685 * This block generates everything position related - it's the core of draggables. 1686 */ 1687 1688 //Cache the margins of the original element 1689 this._cacheMargins(); 1690 1691 //Store the helper's css position 1692 this.cssPosition = this.helper.css("position"); 1693 this.scrollParent = this.helper.scrollParent(); 1694 1695 //The element's absolute position on the page minus margins 1696 this.offset = this.positionAbs = this.element.offset(); 1697 this.offset = { 1698 top: this.offset.top - this.margins.top, 1699 left: this.offset.left - this.margins.left 1700 }; 1701 1702 $.extend(this.offset, { 1703 click: { //Where the click happened, relative to the element 1704 left: event.pageX - this.offset.left, 1705 top: event.pageY - this.offset.top 1706 }, 1707 parent: this._getParentOffset(), 1708 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1709 }); 1710 1711 //Generate the original position 1712 this.originalPosition = this.position = this._generatePosition(event); 1713 this.originalPageX = event.pageX; 1714 this.originalPageY = event.pageY; 1715 1716 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1717 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1718 1719 //Set a containment if given in the options 1720 if(o.containment) { 1721 this._setContainment(); 1722 } 1723 1724 //Trigger event + callbacks 1725 if(this._trigger("start", event) === false) { 1726 this._clear(); 1727 return false; 1728 } 1729 1730 //Recache the helper size 1731 this._cacheHelperProportions(); 1732 1733 //Prepare the droppable offsets 1734 if ($.ui.ddmanager && !o.dropBehaviour) { 1735 $.ui.ddmanager.prepareOffsets(this, event); 1736 } 1737 1738 1739 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1740 1741 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1742 if ( $.ui.ddmanager ) { 1743 $.ui.ddmanager.dragStart(this, event); 1744 } 1745 1746 return true; 1747 }, 1748 1749 _mouseDrag: function(event, noPropagation) { 1750 1751 //Compute the helpers position 1752 this.position = this._generatePosition(event); 1753 this.positionAbs = this._convertPositionTo("absolute"); 1754 1755 //Call plugins and callbacks and use the resulting position if something is returned 1756 if (!noPropagation) { 1757 var ui = this._uiHash(); 1758 if(this._trigger("drag", event, ui) === false) { 1759 this._mouseUp({}); 1760 return false; 1761 } 1762 this.position = ui.position; 1763 } 1764 1765 if(!this.options.axis || this.options.axis !== "y") { 1766 this.helper[0].style.left = this.position.left+"px"; 1767 } 1768 if(!this.options.axis || this.options.axis !== "x") { 1769 this.helper[0].style.top = this.position.top+"px"; 1770 } 1771 if($.ui.ddmanager) { 1772 $.ui.ddmanager.drag(this, event); 1773 } 1774 1775 return false; 1776 }, 1777 1778 _mouseStop: function(event) { 1779 1780 //If we are using droppables, inform the manager about the drop 1781 var element, 1782 that = this, 1783 elementInDom = false, 1784 dropped = false; 1785 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1786 dropped = $.ui.ddmanager.drop(this, event); 1787 } 1788 1789 //if a drop comes from outside (a sortable) 1790 if(this.dropped) { 1791 dropped = this.dropped; 1792 this.dropped = false; 1793 } 1794 1795 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1796 element = this.element[0]; 1797 while ( element && (element = element.parentNode) ) { 1798 if (element === document ) { 1799 elementInDom = true; 1800 } 1801 } 1802 if ( !elementInDom && this.options.helper === "original" ) { 1803 return false; 1804 } 1805 1806 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))) { 1807 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1808 if(that._trigger("stop", event) !== false) { 1809 that._clear(); 1810 } 1811 }); 1812 } else { 1813 if(this._trigger("stop", event) !== false) { 1814 this._clear(); 1815 } 1816 } 1817 1818 return false; 1819 }, 1820 1821 _mouseUp: function(event) { 1822 //Remove frame helpers 1823 $("div.ui-draggable-iframeFix").each(function() { 1824 this.parentNode.removeChild(this); 1825 }); 1826 1827 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1828 if( $.ui.ddmanager ) { 1829 $.ui.ddmanager.dragStop(this, event); 1830 } 1831 1832 return $.ui.mouse.prototype._mouseUp.call(this, event); 1833 }, 1834 1835 cancel: function() { 1836 1837 if(this.helper.is(".ui-draggable-dragging")) { 1838 this._mouseUp({}); 1839 } else { 1840 this._clear(); 1841 } 1842 1843 return this; 1844 1845 }, 1846 1847 _getHandle: function(event) { 1848 return this.options.handle ? 1849 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1850 true; 1851 }, 1852 1853 _createHelper: function(event) { 1854 1855 var o = this.options, 1856 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1857 1858 if(!helper.parents("body").length) { 1859 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1860 } 1861 1862 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1863 helper.css("position", "absolute"); 1864 } 1865 1866 return helper; 1867 1868 }, 1869 1870 _adjustOffsetFromHelper: function(obj) { 1871 if (typeof obj === "string") { 1872 obj = obj.split(" "); 1873 } 1874 if ($.isArray(obj)) { 1875 obj = {left: +obj[0], top: +obj[1] || 0}; 1876 } 1877 if ("left" in obj) { 1878 this.offset.click.left = obj.left + this.margins.left; 1879 } 1880 if ("right" in obj) { 1881 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1882 } 1883 if ("top" in obj) { 1884 this.offset.click.top = obj.top + this.margins.top; 1885 } 1886 if ("bottom" in obj) { 1887 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1888 } 1889 }, 1890 1891 _getParentOffset: function() { 1892 1893 //Get the offsetParent and cache its position 1894 this.offsetParent = this.helper.offsetParent(); 1895 var po = this.offsetParent.offset(); 1896 1897 /*// This is a special case where we need to modify a offset calculated on start, since the following happened: 1898*/ 1899 /*// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1900*/ 1901 /*// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1902*/ 1903 /*// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1904*/ 1905 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1906 po.left += this.scrollParent.scrollLeft(); 1907 po.top += this.scrollParent.scrollTop(); 1908 } 1909 1910 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1911 //Ugly IE fix 1912 if((this.offsetParent[0] === document.body) || 1913 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1914 po = { top: 0, left: 0 }; 1915 } 1916 1917 return { 1918 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 1919 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1920 }; 1921 1922 }, 1923 1924 _getRelativeOffset: function() { 1925 1926 if(this.cssPosition === "relative") { 1927 var p = this.element.position(); 1928 return { 1929 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1930 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1931 }; 1932 } else { 1933 return { top: 0, left: 0 }; 1934 } 1935 1936 }, 1937 1938 _cacheMargins: function() { 1939 this.margins = { 1940 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1941 top: (parseInt(this.element.css("marginTop"),10) || 0), 1942 right: (parseInt(this.element.css("marginRight"),10) || 0), 1943 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1944 }; 1945 }, 1946 1947 _cacheHelperProportions: function() { 1948 this.helperProportions = { 1949 width: this.helper.outerWidth(), 1950 height: this.helper.outerHeight() 1951 }; 1952 }, 1953 1954 _setContainment: function() { 1955 1956 var over, c, ce, 1957 o = this.options; 1958 1959 if(o.containment === "parent") { 1960 o.containment = this.helper[0].parentNode; 1961 } 1962 if(o.containment === "document" || o.containment === "window") { 1963 this.containment = [ 1964 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1965 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1966 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 1967 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1968 ]; 1969 } 1970 1971 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { 1972 c = $(o.containment); 1973 ce = c[0]; 1974 1975 if(!ce) { 1976 return; 1977 } 1978 1979 over = ($(ce).css("overflow") !== "hidden"); 1980 1981 this.containment = [ 1982 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1983 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1984 (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderRightWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, 1985 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderBottomWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom 1986 ]; 1987 this.relative_container = c; 1988 1989 } else if(o.containment.constructor === Array) { 1990 this.containment = o.containment; 1991 } 1992 1993 }, 1994 1995 _convertPositionTo: function(d, pos) { 1996 1997 if(!pos) { 1998 pos = this.position; 1999 } 2000 2001 var mod = d === "absolute" ? 1 : -1, 2002 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); 2003 2004 return { 2005 top: ( 2006 pos.top + /*// The absolute mouse position 2007*/ 2008 this.offset.relative.top * mod + /*// Only for relative positioned nodes: Relative offset from element to offset parent 2009*/ 2010 this.offset.parent.top * mod - /*// The offsetParent's offset without borders (offset + border) 2011*/ 2012 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 2013 ), 2014 left: ( 2015 pos.left + /*// The absolute mouse position 2016*/ 2017 this.offset.relative.left * mod + /*// Only for relative positioned nodes: Relative offset from element to offset parent 2018*/ 2019 this.offset.parent.left * mod - /*// The offsetParent's offset without borders (offset + border) 2020*/ 2021 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 2022 ) 2023 }; 2024 2025 }, 2026 2027 _generatePosition: function(event) { 2028 2029 var containment, co, top, left, 2030 o = this.options, 2031 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 2032 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), 2033 pageX = event.pageX, 2034 pageY = event.pageY; 2035 2036 /* 2037 * - Position constraining - 2038 * Constrain the position to a mix of grid, containment. 2039 */ 2040 2041 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 2042 if(this.containment) { 2043 if (this.relative_container){ 2044 co = this.relative_container.offset(); 2045 containment = [ this.containment[0] + co.left, 2046 this.containment[1] + co.top, 2047 this.containment[2] + co.left, 2048 this.containment[3] + co.top ]; 2049 } 2050 else { 2051 containment = this.containment; 2052 } 2053 2054 if(event.pageX - this.offset.click.left < containment[0]) { 2055 pageX = containment[0] + this.offset.click.left; 2056 } 2057 if(event.pageY - this.offset.click.top < containment[1]) { 2058 pageY = containment[1] + this.offset.click.top; 2059 } 2060 if(event.pageX - this.offset.click.left > containment[2]) { 2061 pageX = containment[2] + this.offset.click.left; 2062 } 2063 if(event.pageY - this.offset.click.top > containment[3]) { 2064 pageY = containment[3] + this.offset.click.top; 2065 } 2066 } 2067 2068 if(o.grid) { 2069 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 2070 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 2071 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; 2072 2073 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 2074 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; 2075 } 2076 2077 } 2078 2079 return { 2080 top: ( 2081 pageY - /*// The absolute mouse position 2082*/ 2083 this.offset.click.top - /*// Click offset (relative to the element) 2084*/ 2085 this.offset.relative.top - /*// Only for relative positioned nodes: Relative offset from element to offset parent 2086*/ 2087 this.offset.parent.top + /*// The offsetParent's offset without borders (offset + border) 2088*/ 2089 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 2090 ), 2091 left: ( 2092 pageX - /*// The absolute mouse position 2093*/ 2094 this.offset.click.left - /*// Click offset (relative to the element) 2095*/ 2096 this.offset.relative.left - /*// Only for relative positioned nodes: Relative offset from element to offset parent 2097*/ 2098 this.offset.parent.left + /*// The offsetParent's offset without borders (offset + border) 2099*/ 2100 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 2101 ) 2102 }; 2103 2104 }, 2105 2106 _clear: function() { 2107 this.helper.removeClass("ui-draggable-dragging"); 2108 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 2109 this.helper.remove(); 2110 } 2111 this.helper = null; 2112 this.cancelHelperRemoval = false; 2113 }, 2114 2115 /*// From now on bulk stuff - mainly helpers 2116*/ 2117 2118 _trigger: function(type, event, ui) { 2119 ui = ui || this._uiHash(); 2120 $.ui.plugin.call(this, type, [event, ui]); 2121 //The absolute position has to be recalculated after plugins 2122 if(type === "drag") { 2123 this.positionAbs = this._convertPositionTo("absolute"); 2124 } 2125 return $.Widget.prototype._trigger.call(this, type, event, ui); 2126 }, 2127 2128 plugins: {}, 2129 2130 _uiHash: function() { 2131 return { 2132 helper: this.helper, 2133 position: this.position, 2134 originalPosition: this.originalPosition, 2135 offset: this.positionAbs 2136 }; 2137 } 2138 2139}); 2140 2141$.ui.plugin.add("draggable", "connectToSortable", { 2142 start: function(event, ui) { 2143 2144 var inst = $(this).data("ui-draggable"), o = inst.options, 2145 uiSortable = $.extend({}, ui, { item: inst.element }); 2146 inst.sortables = []; 2147 $(o.connectToSortable).each(function() { 2148 var sortable = $.data(this, "ui-sortable"); 2149 if (sortable && !sortable.options.disabled) { 2150 inst.sortables.push({ 2151 instance: sortable, 2152 shouldRevert: sortable.options.revert 2153 }); 2154 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). 2155*/ 2156 sortable._trigger("activate", event, uiSortable); 2157 } 2158 }); 2159 2160 }, 2161 stop: function(event, ui) { 2162 2163 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 2164 var inst = $(this).data("ui-draggable"), 2165 uiSortable = $.extend({}, ui, { item: inst.element }); 2166 2167 $.each(inst.sortables, function() { 2168 if(this.instance.isOver) { 2169 2170 this.instance.isOver = 0; 2171 2172 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 2173 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 2174 2175 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 2176 if(this.shouldRevert) { 2177 this.instance.options.revert = this.shouldRevert; 2178 } 2179 2180 //Trigger the stop of the sortable 2181 this.instance._mouseStop(event); 2182 2183 this.instance.options.helper = this.instance.options._helper; 2184 2185 //If the helper has been the original item, restore properties in the sortable 2186 if(inst.options.helper === "original") { 2187 this.instance.currentItem.css({ top: "auto", left: "auto" }); 2188 } 2189 2190 } else { 2191 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 2192 this.instance._trigger("deactivate", event, uiSortable); 2193 } 2194 2195 }); 2196 2197 }, 2198 drag: function(event, ui) { 2199 2200 var inst = $(this).data("ui-draggable"), that = this; 2201 2202 $.each(inst.sortables, function() { 2203 2204 var innermostIntersecting = false, 2205 thisSortable = this; 2206 2207 //Copy over some variables to allow calling the sortable's native _intersectsWith 2208 this.instance.positionAbs = inst.positionAbs; 2209 this.instance.helperProportions = inst.helperProportions; 2210 this.instance.offset.click = inst.offset.click; 2211 2212 if(this.instance._intersectsWith(this.instance.containerCache)) { 2213 innermostIntersecting = true; 2214 $.each(inst.sortables, function () { 2215 this.instance.positionAbs = inst.positionAbs; 2216 this.instance.helperProportions = inst.helperProportions; 2217 this.instance.offset.click = inst.offset.click; 2218 if (this !== thisSortable && 2219 this.instance._intersectsWith(this.instance.containerCache) && 2220 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 2221 ) { 2222 innermostIntersecting = false; 2223 } 2224 return innermostIntersecting; 2225 }); 2226 } 2227 2228 2229 if(innermostIntersecting) { 2230 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 2231 if(!this.instance.isOver) { 2232 2233 this.instance.isOver = 1; 2234 //Now we fake the start of dragging for the sortable instance, 2235 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 2236 //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) 2237 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 2238 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 2239 this.instance.options.helper = function() { return ui.helper[0]; }; 2240 2241 event.target = this.instance.currentItem[0]; 2242 this.instance._mouseCapture(event, true); 2243 this.instance._mouseStart(event, true, true); 2244 2245 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 2246 this.instance.offset.click.top = inst.offset.click.top; 2247 this.instance.offset.click.left = inst.offset.click.left; 2248 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 2249 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 2250 2251 inst._trigger("toSortable", event); 2252 inst.dropped = this.instance.element; //draggable revert needs that 2253 //hack so receive/update callbacks work (mostly) 2254 inst.currentItem = inst.element; 2255 this.instance.fromOutside = inst; 2256 2257 } 2258 2259 //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 2260 if(this.instance.currentItem) { 2261 this.instance._mouseDrag(event); 2262 } 2263 2264 } else { 2265 2266 //If it doesn't intersect with the sortable, and it intersected before, 2267 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 2268 if(this.instance.isOver) { 2269 2270 this.instance.isOver = 0; 2271 this.instance.cancelHelperRemoval = true; 2272 2273 //Prevent reverting on this forced stop 2274 this.instance.options.revert = false; 2275 2276 /*// The out event needs to be triggered independently 2277*/ 2278 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 2279 2280 this.instance._mouseStop(event, true); 2281 this.instance.options.helper = this.instance.options._helper; 2282 2283 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 2284 this.instance.currentItem.remove(); 2285 if(this.instance.placeholder) { 2286 this.instance.placeholder.remove(); 2287 } 2288 2289 inst._trigger("fromSortable", event); 2290 inst.dropped = false; //draggable revert needs that 2291 } 2292 2293 } 2294 2295 }); 2296 2297 } 2298}); 2299 2300$.ui.plugin.add("draggable", "cursor", { 2301 start: function() { 2302 var t = $("body"), o = $(this).data("ui-draggable").options; 2303 if (t.css("cursor")) { 2304 o._cursor = t.css("cursor"); 2305 } 2306 t.css("cursor", o.cursor); 2307 }, 2308 stop: function() { 2309 var o = $(this).data("ui-draggable").options; 2310 if (o._cursor) { 2311 $("body").css("cursor", o._cursor); 2312 } 2313 } 2314}); 2315 2316$.ui.plugin.add("draggable", "opacity", { 2317 start: function(event, ui) { 2318 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2319 if(t.css("opacity")) { 2320 o._opacity = t.css("opacity"); 2321 } 2322 t.css("opacity", o.opacity); 2323 }, 2324 stop: function(event, ui) { 2325 var o = $(this).data("ui-draggable").options; 2326 if(o._opacity) { 2327 $(ui.helper).css("opacity", o._opacity); 2328 } 2329 } 2330}); 2331 2332$.ui.plugin.add("draggable", "scroll", { 2333 start: function() { 2334 var i = $(this).data("ui-draggable"); 2335 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2336 i.overflowOffset = i.scrollParent.offset(); 2337 } 2338 }, 2339 drag: function( event ) { 2340 2341 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 2342 2343 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 2344 2345 if(!o.axis || o.axis !== "x") { 2346 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 2347 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 2348 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 2349 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 2350 } 2351 } 2352 2353 if(!o.axis || o.axis !== "y") { 2354 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 2355 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 2356 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 2357 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 2358 } 2359 } 2360 2361 } else { 2362 2363 if(!o.axis || o.axis !== "x") { 2364 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 2365 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 2366 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 2367 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 2368 } 2369 } 2370 2371 if(!o.axis || o.axis !== "y") { 2372 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 2373 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 2374 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 2375 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 2376 } 2377 } 2378 2379 } 2380 2381 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 2382 $.ui.ddmanager.prepareOffsets(i, event); 2383 } 2384 2385 } 2386}); 2387 2388$.ui.plugin.add("draggable", "snap", { 2389 start: function() { 2390 2391 var i = $(this).data("ui-draggable"), 2392 o = i.options; 2393 2394 i.snapElements = []; 2395 2396 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 2397 var $t = $(this), 2398 $o = $t.offset(); 2399 if(this !== i.element[0]) { 2400 i.snapElements.push({ 2401 item: this, 2402 width: $t.outerWidth(), height: $t.outerHeight(), 2403 top: $o.top, left: $o.left 2404 }); 2405 } 2406 }); 2407 2408 }, 2409 drag: function(event, ui) { 2410 2411 var ts, bs, ls, rs, l, r, t, b, i, first, 2412 inst = $(this).data("ui-draggable"), 2413 o = inst.options, 2414 d = o.snapTolerance, 2415 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 2416 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 2417 2418 for (i = inst.snapElements.length - 1; i >= 0; i--){ 2419 2420 l = inst.snapElements[i].left; 2421 r = l + inst.snapElements[i].width; 2422 t = inst.snapElements[i].top; 2423 b = t + inst.snapElements[i].height; 2424 2425 //Yes, I know, this is insane ;) 2426 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))) { 2427 if(inst.snapElements[i].snapping) { 2428 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2429 } 2430 inst.snapElements[i].snapping = false; 2431 continue; 2432 } 2433 2434 if(o.snapMode !== "inner") { 2435 ts = Math.abs(t - y2) <= d; 2436 bs = Math.abs(b - y1) <= d; 2437 ls = Math.abs(l - x2) <= d; 2438 rs = Math.abs(r - x1) <= d; 2439 if(ts) { 2440 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2441 } 2442 if(bs) { 2443 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 2444 } 2445 if(ls) { 2446 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 2447 } 2448 if(rs) { 2449 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 2450 } 2451 } 2452 2453 first = (ts || bs || ls || rs); 2454 2455 if(o.snapMode !== "outer") { 2456 ts = Math.abs(t - y1) <= d; 2457 bs = Math.abs(b - y2) <= d; 2458 ls = Math.abs(l - x1) <= d; 2459 rs = Math.abs(r - x2) <= d; 2460 if(ts) { 2461 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 2462 } 2463 if(bs) { 2464 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 2465 } 2466 if(ls) { 2467 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 2468 } 2469 if(rs) { 2470 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 2471 } 2472 } 2473 2474 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 2475 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 2476 } 2477 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 2478 2479 } 2480 2481 } 2482}); 2483 2484$.ui.plugin.add("draggable", "stack", { 2485 start: function() { 2486 var min, 2487 o = this.data("ui-draggable").options, 2488 group = $.makeArray($(o.stack)).sort(function(a,b) { 2489 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 2490 }); 2491 2492 if (!group.length) { return; } 2493 2494 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 2495 $(group).each(function(i) { 2496 $(this).css("zIndex", min + i); 2497 }); 2498 this.css("zIndex", (min + group.length)); 2499 } 2500}); 2501 2502$.ui.plugin.add("draggable", "zIndex", { 2503 start: function(event, ui) { 2504 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 2505 if(t.css("zIndex")) { 2506 o._zIndex = t.css("zIndex"); 2507 } 2508 t.css("zIndex", o.zIndex); 2509 }, 2510 stop: function(event, ui) { 2511 var o = $(this).data("ui-draggable").options; 2512 if(o._zIndex) { 2513 $(ui.helper).css("zIndex", o._zIndex); 2514 } 2515 } 2516}); 2517 2518})(jQuery); 2519(function( $, undefined ) { 2520 2521function isOverAxis( x, reference, size ) { 2522 return ( x > reference ) && ( x < ( reference + size ) ); 2523} 2524 2525$.widget("ui.droppable", { 2526 version: "1.10.2", 2527 widgetEventPrefix: "drop", 2528 options: { 2529 accept: "*",
2530 activeClass: false, 2531 addClasses: true, 2532 greedy: false, 2533 hoverClass: false, 2534 scope: "default", 2535 tolerance: "intersect", 2536 2537 /*// callbacks 2538*/ 2539 activate: null, 2540 deactivate: null, 2541 drop: null, 2542 out: null, 2543 over: null 2544 }, 2545 _create: function() { 2546 2547 var o = this.options, 2548 accept = o.accept; 2549 2550 this.isover = false; 2551 this.isout = true; 2552 2553 this.accept = $.isFunction(accept) ? accept : function(d) { 2554 return d.is(accept); 2555 }; 2556 2557 //Store the droppable's proportions 2558 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 2559 2560 /*// Add the reference and positions to the manager 2561*/ 2562 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 2563 $.ui.ddmanager.droppables[o.scope].push(this); 2564 2565 (o.addClasses && this.element.addClass("ui-droppable")); 2566 2567 }, 2568 2569 _destroy: function() { 2570 var i = 0, 2571 drop = $.ui.ddmanager.droppables[this.options.scope]; 2572 2573 for ( ; i < drop.length; i++ ) { 2574 if ( drop[i] === this ) { 2575 drop.splice(i, 1); 2576 } 2577 } 2578 2579 this.element.removeClass("ui-droppable ui-droppable-disabled"); 2580 }, 2581 2582 _setOption: function(key, value) { 2583 2584 if(key === "accept") { 2585 this.accept = $.isFunction(value) ? value : function(d) { 2586 return d.is(value); 2587 }; 2588 } 2589 $.Widget.prototype._setOption.apply(this, arguments); 2590 }, 2591 2592 _activate: function(event) { 2593 var draggable = $.ui.ddmanager.current; 2594 if(this.options.activeClass) { 2595 this.element.addClass(this.options.activeClass); 2596 } 2597 if(draggable){ 2598 this._trigger("activate", event, this.ui(draggable)); 2599 } 2600 }, 2601 2602 _deactivate: function(event) { 2603 var draggable = $.ui.ddmanager.current; 2604 if(this.options.activeClass) { 2605 this.element.removeClass(this.options.activeClass); 2606 } 2607 if(draggable){ 2608 this._trigger("deactivate", event, this.ui(draggable)); 2609 } 2610 }, 2611 2612 _over: function(event) { 2613 2614 var draggable = $.ui.ddmanager.current; 2615 2616 /*// Bail if draggable and droppable are same element 2617*/ 2618 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2619 return; 2620 } 2621 2622 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2623 if(this.options.hoverClass) { 2624 this.element.addClass(this.options.hoverClass); 2625 } 2626 this._trigger("over", event, this.ui(draggable)); 2627 } 2628 2629 }, 2630 2631 _out: function(event) { 2632 2633 var draggable = $.ui.ddmanager.current; 2634 2635 /*// Bail if draggable and droppable are same element 2636*/ 2637 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2638 return; 2639 } 2640 2641 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2642 if(this.options.hoverClass) { 2643 this.element.removeClass(this.options.hoverClass); 2644 } 2645 this._trigger("out", event, this.ui(draggable)); 2646 } 2647 2648 }, 2649 2650 _drop: function(event,custom) { 2651 2652 var draggable = custom || $.ui.ddmanager.current, 2653 childrenIntersection = false; 2654 2655 /*// Bail if draggable and droppable are same element 2656*/ 2657 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2658 return false; 2659 } 2660 2661 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2662 var inst = $.data(this, "ui-droppable"); 2663 if( 2664 inst.options.greedy && 2665 !inst.options.disabled && 2666 inst.options.scope === draggable.options.scope && 2667 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2668 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2669 ) { childrenIntersection = true; return false; } 2670 }); 2671 if(childrenIntersection) { 2672 return false; 2673 } 2674 2675 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2676 if(this.options.activeClass) { 2677 this.element.removeClass(this.options.activeClass); 2678 } 2679 if(this.options.hoverClass) { 2680 this.element.removeClass(this.options.hoverClass); 2681 } 2682 this._trigger("drop", event, this.ui(draggable)); 2683 return this.element; 2684 } 2685 2686 return false; 2687 2688 }, 2689 2690 ui: function(c) { 2691 return { 2692 draggable: (c.currentItem || c.element), 2693 helper: c.helper, 2694 position: c.position, 2695 offset: c.positionAbs 2696 }; 2697 } 2698 2699}); 2700 2701$.ui.intersect = function(draggable, droppable, toleranceMode) { 2702 2703 if (!droppable.offset) { 2704 return false; 2705 } 2706 2707 var draggableLeft, draggableTop, 2708 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2709 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2710 l = droppable.offset.left, r = l + droppable.proportions.width, 2711 t = droppable.offset.top, b = t + droppable.proportions.height; 2712 2713 switch (toleranceMode) { 2714 case "fit":
vendor: 22,155 bytes, lines 2715-3474
2715 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2716 case "intersect": 2717 return (l < x1 + (draggable.helperProportions.width / 2) && /*// Right Half 2718*/ 2719 x2 - (draggable.helperProportions.width / 2) < r && /*// Left Half 2720*/ 2721 t < y1 + (draggable.helperProportions.height / 2) && /*// Bottom Half 2722*/ 2723 y2 - (draggable.helperProportions.height / 2) < b ); /*// Top Half 2724*/ 2725 case "pointer": 2726 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2727 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2728 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2729 case "touch": 2730 return ( 2731 (y1 >= t && y1 <= b) || /*// Top edge touching 2732*/ 2733 (y2 >= t && y2 <= b) || /*// Bottom edge touching 2734*/ 2735 (y1 < t && y2 > b) /*// Surrounded vertically 2736*/ 2737 ) && ( 2738 (x1 >= l && x1 <= r) || /*// Left edge touching 2739*/ 2740 (x2 >= l && x2 <= r) || /*// Right edge touching 2741*/ 2742 (x1 < l && x2 > r) /*// Surrounded horizontally 2743*/ 2744 ); 2745 default: 2746 return false; 2747 } 2748 2749}; 2750 2751/* 2752 This manager tracks offsets of draggables and droppables 2753*/ 2754$.ui.ddmanager = { 2755 current: null, 2756 droppables: { "default": [] }, 2757 prepareOffsets: function(t, event) { 2758 2759 var i, j, 2760 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2761 type = event ? event.type : null, /*// workaround for #2317 2762*/ 2763 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2764 2765 droppablesLoop: for (i = 0; i < m.length; i++) { 2766 2767 //No disabled and non-accepted 2768 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2769 continue; 2770 } 2771 2772 /*// Filter out elements in the current dragged item 2773*/ 2774 for (j=0; j < list.length; j++) { 2775 if(list[j] === m[i].element[0]) { 2776 m[i].proportions.height = 0; 2777 continue droppablesLoop; 2778 } 2779 } 2780 2781 m[i].visible = m[i].element.css("display") !== "none"; 2782 if(!m[i].visible) { 2783 continue; 2784 } 2785 2786 //Activate the droppable if used directly from draggables 2787 if(type === "mousedown") { 2788 m[i]._activate.call(m[i], event); 2789 } 2790 2791 m[i].offset = m[i].element.offset(); 2792 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2793 2794 } 2795 2796 }, 2797 drop: function(draggable, event) { 2798 2799 var dropped = false; 2800 /*// Create a copy of the droppables in case the list changes during the drop (#9116) 2801*/ 2802 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2803 2804 if(!this.options) { 2805 return; 2806 } 2807 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2808 dropped = this._drop.call(this, event) || dropped; 2809 } 2810 2811 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2812 this.isout = true; 2813 this.isover = false; 2814 this._deactivate.call(this, event); 2815 } 2816 2817 }); 2818 return dropped; 2819 2820 }, 2821 dragStart: function( draggable, event ) { 2822 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2823 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2824 if( !draggable.options.refreshPositions ) { 2825 $.ui.ddmanager.prepareOffsets( draggable, event ); 2826 } 2827 }); 2828 }, 2829 drag: function(draggable, event) { 2830 2831 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2832 if(draggable.options.refreshPositions) { 2833 $.ui.ddmanager.prepareOffsets(draggable, event); 2834 } 2835 2836 //Run through all droppables and check their positions based on specific tolerance options 2837 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2838 2839 if(this.options.disabled || this.greedyChild || !this.visible) { 2840 return; 2841 } 2842 2843 var parentInstance, scope, parent, 2844 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2845 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2846 if(!c) { 2847 return; 2848 } 2849 2850 if (this.options.greedy) { 2851 /*// find droppable parents with same scope 2852*/ 2853 scope = this.options.scope; 2854 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2855 return $.data(this, "ui-droppable").options.scope === scope; 2856 }); 2857 2858 if (parent.length) { 2859 parentInstance = $.data(parent[0], "ui-droppable"); 2860 parentInstance.greedyChild = (c === "isover"); 2861 } 2862 } 2863 2864 /*// we just moved into a greedy child 2865*/ 2866 if (parentInstance && c === "isover") { 2867 parentInstance.isover = false; 2868 parentInstance.isout = true; 2869 parentInstance._out.call(parentInstance, event); 2870 } 2871 2872 this[c] = true; 2873 this[c === "isout" ? "isover" : "isout"] = false; 2874 this[c === "isover" ? "_over" : "_out"].call(this, event); 2875 2876 /*// we just moved out of a greedy child 2877*/ 2878 if (parentInstance && c === "isout") { 2879 parentInstance.isout = false; 2880 parentInstance.isover = true; 2881 parentInstance._over.call(parentInstance, event); 2882 } 2883 }); 2884 2885 }, 2886 dragStop: function( draggable, event ) { 2887 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2888 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2889 if( !draggable.options.refreshPositions ) { 2890 $.ui.ddmanager.prepareOffsets( draggable, event ); 2891 } 2892 } 2893}; 2894 2895})(jQuery); 2896(function( $, undefined ) { 2897 2898function num(v) { 2899 return parseInt(v, 10) || 0; 2900} 2901 2902function isNumber(value) { 2903 return !isNaN(parseInt(value, 10)); 2904} 2905 2906$.widget("ui.resizable", $.ui.mouse, { 2907 version: "1.10.2", 2908 widgetEventPrefix: "resize", 2909 options: { 2910 alsoResize: false, 2911 animate: false, 2912 animateDuration: "slow", 2913 animateEasing: "swing", 2914 aspectRatio: false, 2915 autoHide: false, 2916 containment: false, 2917 ghost: false, 2918 grid: false, 2919 handles: "e,s,se", 2920 helper: false, 2921 maxHeight: null, 2922 maxWidth: null, 2923 minHeight: 10, 2924 minWidth: 10, 2925 /*// See #7960 2926*/ 2927 zIndex: 90, 2928 2929 /*// callbacks 2930*/ 2931 resize: null, 2932 start: null, 2933 stop: null 2934 }, 2935 _create: function() { 2936 2937 var n, i, handle, axis, hname, 2938 that = this, 2939 o = this.options; 2940 this.element.addClass("ui-resizable"); 2941 2942 $.extend(this, { 2943 _aspectRatio: !!(o.aspectRatio), 2944 aspectRatio: o.aspectRatio, 2945 originalElement: this.element, 2946 _proportionallyResizeElements: [], 2947 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2948 }); 2949 2950 //Wrap the element if it cannot hold child nodes 2951 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2952 2953 //Create a wrapper element and set the wrapper to the new current internal element 2954 this.element.wrap( 2955 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2956 position: this.element.css("position"), 2957 width: this.element.outerWidth(), 2958 height: this.element.outerHeight(), 2959 top: this.element.css("top"), 2960 left: this.element.css("left") 2961 }) 2962 ); 2963 2964 //Overwrite the original this.element 2965 this.element = this.element.parent().data( 2966 "ui-resizable", this.element.data("ui-resizable") 2967 ); 2968 2969 this.elementIsWrapper = true; 2970 2971 //Move margins to the wrapper 2972 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2973 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2974 2975 //Prevent Safari textarea resize 2976 this.originalResizeStyle = this.originalElement.css("resize"); 2977 this.originalElement.css("resize", "none"); 2978 2979 //Push the actual element to our proportionallyResize internal array 2980 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2981 2982 /*// avoid IE jump (hard set the margin) 2983*/ 2984 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2985 2986 /*// fix handlers offset 2987*/ 2988 this._proportionallyResize(); 2989 2990 } 2991 2992 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" }); 2993 if(this.handles.constructor === String) { 2994 2995 if ( this.handles === "all") { 2996 this.handles = "n,e,s,w,se,sw,ne,nw"; 2997 } 2998 2999 n = this.handles.split(","); 3000 this.handles = {}; 3001 3002 for(i = 0; i < n.length; i++) { 3003 3004 handle = $.trim(n[i]); 3005 hname = "ui-resizable-"+handle; 3006 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 3007 3008 /*// Apply zIndex to all handles - see #7960 3009*/ 3010 axis.css({ zIndex: o.zIndex }); 3011 3012 //TODO : What's going on here? 3013 if ("se" === handle) { 3014 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 3015 } 3016 3017 //Insert into internal handles object and append to element 3018 this.handles[handle] = ".ui-resizable-"+handle; 3019 this.element.append(axis); 3020 } 3021 3022 } 3023 3024 this._renderAxis = function(target) { 3025 3026 var i, axis, padPos, padWrapper; 3027 3028 target = target || this.element; 3029 3030 for(i in this.handles) { 3031 3032 if(this.handles[i].constructor === String) { 3033 this.handles[i] = $(this.handles[i], this.element).show(); 3034 } 3035 3036 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 3037 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 3038 3039 axis = $(this.handles[i], this.element); 3040 3041 //Checking the correct pad and border 3042 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 3043 3044 //The padding type i have to apply... 3045 padPos = [ "padding", 3046 /ne|nw|n/.test(i) ? "Top" : 3047 /se|sw|s/.test(i) ? "Bottom" : 3048 /^e$/.test(i) ? "Right" : "Left" ].join(""); 3049 3050 target.css(padPos, padWrapper); 3051 3052 this._proportionallyResize(); 3053 3054 } 3055 3056 //TODO: What's that good for? There's not anything to be executed left 3057 if(!$(this.handles[i]).length) { 3058 continue; 3059 } 3060 } 3061 }; 3062 3063 //TODO: make renderAxis a prototype function 3064 this._renderAxis(this.element); 3065 3066 this._handles = $(".ui-resizable-handle", this.element) 3067 .disableSelection(); 3068 3069 //Matching axis name 3070 this._handles.mouseover(function() { 3071 if (!that.resizing) { 3072 if (this.className) { 3073 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 3074 } 3075 //Axis, default = se 3076 that.axis = axis && axis[1] ? axis[1] : "se"; 3077 } 3078 }); 3079 3080 //If we want to auto hide the elements 3081 if (o.autoHide) { 3082 this._handles.hide(); 3083 $(this.element) 3084 .addClass("ui-resizable-autohide") 3085 .mouseenter(function() { 3086 if (o.disabled) { 3087 return; 3088 } 3089 $(this).removeClass("ui-resizable-autohide"); 3090 that._handles.show(); 3091 }) 3092 .mouseleave(function(){ 3093 if (o.disabled) { 3094 return; 3095 } 3096 if (!that.resizing) { 3097 $(this).addClass("ui-resizable-autohide"); 3098 that._handles.hide(); 3099 } 3100 }); 3101 } 3102 3103 //Initialize the mouse interaction 3104 this._mouseInit(); 3105 3106 }, 3107 3108 _destroy: function() { 3109 3110 this._mouseDestroy(); 3111 3112 var wrapper, 3113 _destroy = function(exp) { 3114 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 3115 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 3116 }; 3117 3118 //TODO: Unwrap at same DOM position 3119 if (this.elementIsWrapper) { 3120 _destroy(this.element); 3121 wrapper = this.element; 3122 this.originalElement.css({ 3123 position: wrapper.css("position"), 3124 width: wrapper.outerWidth(), 3125 height: wrapper.outerHeight(), 3126 top: wrapper.css("top"), 3127 left: wrapper.css("left") 3128 }).insertAfter( wrapper ); 3129 wrapper.remove(); 3130 } 3131 3132 this.originalElement.css("resize", this.originalResizeStyle); 3133 _destroy(this.originalElement); 3134 3135 return this; 3136 }, 3137 3138 _mouseCapture: function(event) { 3139 var i, handle, 3140 capture = false; 3141 3142 for (i in this.handles) { 3143 handle = $(this.handles[i])[0]; 3144 if (handle === event.target || $.contains(handle, event.target)) { 3145 capture = true; 3146 } 3147 } 3148 3149 return !this.options.disabled && capture; 3150 }, 3151 3152 _mouseStart: function(event) { 3153 3154 var curleft, curtop, cursor, 3155 o = this.options, 3156 iniPos = this.element.position(), 3157 el = this.element; 3158 3159 this.resizing = true; 3160 3161 /*// bugfix for http://dev.jquery.com/ticket/1749 3162*/ 3163 if ( (/absolute/).test( el.css("position") ) ) { 3164 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 3165 } else if (el.is(".ui-draggable")) { 3166 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 3167 } 3168 3169 this._renderProxy(); 3170 3171 curleft = num(this.helper.css("left")); 3172 curtop = num(this.helper.css("top")); 3173 3174 if (o.containment) { 3175 curleft += $(o.containment).scrollLeft() || 0; 3176 curtop += $(o.containment).scrollTop() || 0; 3177 } 3178 3179 //Store needed variables 3180 this.offset = this.helper.offset(); 3181 this.position = { left: curleft, top: curtop }; 3182 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 3183 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 3184 this.originalPosition = { left: curleft, top: curtop }; 3185 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 3186 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 3187 3188 //Aspect Ratio 3189 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 3190 3191 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 3192 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 3193 3194 el.addClass("ui-resizable-resizing"); 3195 this._propagate("start", event); 3196 return true; 3197 }, 3198 3199 _mouseDrag: function(event) { 3200 3201 //Increase performance, avoid regex 3202 var data, 3203 el = this.helper, props = {}, 3204 smp = this.originalMousePosition, 3205 a = this.axis, 3206 prevTop = this.position.top, 3207 prevLeft = this.position.left, 3208 prevWidth = this.size.width, 3209 prevHeight = this.size.height, 3210 dx = (event.pageX-smp.left)||0, 3211 dy = (event.pageY-smp.top)||0, 3212 trigger = this._change[a]; 3213 3214 if (!trigger) { 3215 return false; 3216 } 3217 3218 /*// Calculate the attrs that will be change 3219*/ 3220 data = trigger.apply(this, [event, dx, dy]); 3221 3222 /*// Put this in the mouseDrag handler since the user can start pressing shift while resizing 3223*/ 3224 this._updateVirtualBoundaries(event.shiftKey); 3225 if (this._aspectRatio || event.shiftKey) { 3226 data = this._updateRatio(data, event); 3227 } 3228 3229 data = this._respectSize(data, event); 3230 3231 this._updateCache(data); 3232 3233 /*// plugins callbacks need to be called first 3234*/ 3235 this._propagate("resize", event); 3236 3237 if (this.position.top !== prevTop) { 3238 props.top = this.position.top + "px"; 3239 } 3240 if (this.position.left !== prevLeft) { 3241 props.left = this.position.left + "px"; 3242 } 3243 if (this.size.width !== prevWidth) { 3244 props.width = this.size.width + "px"; 3245 } 3246 if (this.size.height !== prevHeight) { 3247 props.height = this.size.height + "px"; 3248 } 3249 el.css(props); 3250 3251 if (!this._helper && this._proportionallyResizeElements.length) { 3252 this._proportionallyResize(); 3253 } 3254 3255 /*// Call the user callback if the element was resized 3256*/ 3257 if ( ! $.isEmptyObject(props) ) { 3258 this._trigger("resize", event, this.ui()); 3259 } 3260 3261 return false; 3262 }, 3263 3264 _mouseStop: function(event) { 3265 3266 this.resizing = false; 3267 var pr, ista, soffseth, soffsetw, s, left, top, 3268 o = this.options, that = this; 3269 3270 if(this._helper) { 3271 3272 pr = this._proportionallyResizeElements; 3273 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 3274 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 3275 soffsetw = ista ? 0 : that.sizeDiff.width; 3276 3277 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 3278 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 3279 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3280 3281 if (!o.animate) { 3282 this.element.css($.extend(s, { top: top, left: left })); 3283 } 3284 3285 that.helper.height(that.size.height); 3286 that.helper.width(that.size.width); 3287 3288 if (this._helper && !o.animate) { 3289 this._proportionallyResize(); 3290 } 3291 } 3292 3293 $("body").css("cursor", "auto"); 3294 3295 this.element.removeClass("ui-resizable-resizing"); 3296 3297 this._propagate("stop", event); 3298 3299 if (this._helper) { 3300 this.helper.remove(); 3301 } 3302 3303 return false; 3304 3305 }, 3306 3307 _updateVirtualBoundaries: function(forceAspectRatio) { 3308 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 3309 o = this.options; 3310 3311 b = { 3312 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 3313 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 3314 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 3315 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 3316 }; 3317 3318 if(this._aspectRatio || forceAspectRatio) { 3319 /*// We want to create an enclosing box whose aspect ration is the requested one 3320*/ 3321 /*// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 3322*/ 3323 pMinWidth = b.minHeight * this.aspectRatio; 3324 pMinHeight = b.minWidth / this.aspectRatio; 3325 pMaxWidth = b.maxHeight * this.aspectRatio; 3326 pMaxHeight = b.maxWidth / this.aspectRatio; 3327 3328 if(pMinWidth > b.minWidth) { 3329 b.minWidth = pMinWidth; 3330 } 3331 if(pMinHeight > b.minHeight) { 3332 b.minHeight = pMinHeight; 3333 } 3334 if(pMaxWidth < b.maxWidth) { 3335 b.maxWidth = pMaxWidth; 3336 } 3337 if(pMaxHeight < b.maxHeight) { 3338 b.maxHeight = pMaxHeight; 3339 } 3340 } 3341 this._vBoundaries = b; 3342 }, 3343 3344 _updateCache: function(data) { 3345 this.offset = this.helper.offset(); 3346 if (isNumber(data.left)) { 3347 this.position.left = data.left; 3348 } 3349 if (isNumber(data.top)) { 3350 this.position.top = data.top; 3351 } 3352 if (isNumber(data.height)) { 3353 this.size.height = data.height; 3354 } 3355 if (isNumber(data.width)) { 3356 this.size.width = data.width; 3357 } 3358 }, 3359 3360 _updateRatio: function( data ) { 3361 3362 var cpos = this.position, 3363 csize = this.size, 3364 a = this.axis; 3365 3366 if (isNumber(data.height)) { 3367 data.width = (data.height * this.aspectRatio); 3368 } else if (isNumber(data.width)) { 3369 data.height = (data.width / this.aspectRatio); 3370 } 3371 3372 if (a === "sw") { 3373 data.left = cpos.left + (csize.width - data.width); 3374 data.top = null; 3375 } 3376 if (a === "nw") { 3377 data.top = cpos.top + (csize.height - data.height); 3378 data.left = cpos.left + (csize.width - data.width); 3379 } 3380 3381 return data; 3382 }, 3383 3384 _respectSize: function( data ) { 3385 3386 var o = this._vBoundaries, 3387 a = this.axis, 3388 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 3389 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 3390 dw = this.originalPosition.left + this.originalSize.width, 3391 dh = this.position.top + this.size.height, 3392 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 3393 if (isminw) { 3394 data.width = o.minWidth; 3395 } 3396 if (isminh) { 3397 data.height = o.minHeight; 3398 } 3399 if (ismaxw) { 3400 data.width = o.maxWidth; 3401 } 3402 if (ismaxh) { 3403 data.height = o.maxHeight; 3404 } 3405 3406 if (isminw && cw) { 3407 data.left = dw - o.minWidth; 3408 } 3409 if (ismaxw && cw) { 3410 data.left = dw - o.maxWidth; 3411 } 3412 if (isminh && ch) { 3413 data.top = dh - o.minHeight; 3414 } 3415 if (ismaxh && ch) { 3416 data.top = dh - o.maxHeight; 3417 } 3418 3419 /*// fixing jump error on top/left - bug #2330 3420*/ 3421 if (!data.width && !data.height && !data.left && data.top) { 3422 data.top = null; 3423 } else if (!data.width && !data.height && !data.top && data.left) { 3424 data.left = null; 3425 } 3426 3427 return data; 3428 }, 3429 3430 _proportionallyResize: function() { 3431 3432 if (!this._proportionallyResizeElements.length) { 3433 return; 3434 } 3435 3436 var i, j, borders, paddings, prel, 3437 element = this.helper || this.element; 3438 3439 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 3440 3441 prel = this._proportionallyResizeElements[i]; 3442 3443 if (!this.borderDif) { 3444 this.borderDif = []; 3445 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 3446 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 3447 3448 for ( j = 0; j < borders.length; j++ ) { 3449 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 3450 } 3451 } 3452 3453 prel.css({ 3454 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 3455 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 3456 }); 3457 3458 } 3459 3460 }, 3461 3462 _renderProxy: function() { 3463 3464 var el = this.element, o = this.options; 3465 this.elementOffset = el.offset(); 3466 3467 if(this._helper) { 3468 3469 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 3470 3471 this.helper.addClass(this._helper).css({ 3472 width: this.element.outerWidth() - 1, 3473 height: this.element.outerHeight() - 1, 3474 position: "absolute",
vendor: 1,348 bytes, lines 3475-3518
3475 left: this.elementOffset.left +"px", 3476 top: this.elementOffset.top +"px", 3477 zIndex: ++o.zIndex //TODO: Don't modify option 3478 }); 3479 3480 this.helper 3481 .appendTo("body") 3482 .disableSelection(); 3483 3484 } else { 3485 this.helper = this.element; 3486 } 3487 3488 }, 3489 3490 _change: { 3491 e: function(event, dx) { 3492 return { width: this.originalSize.width + dx }; 3493 }, 3494 w: function(event, dx) { 3495 var cs = this.originalSize, sp = this.originalPosition; 3496 return { left: sp.left + dx, width: cs.width - dx }; 3497 }, 3498 n: function(event, dx, dy) { 3499 var cs = this.originalSize, sp = this.originalPosition; 3500 return { top: sp.top + dy, height: cs.height - dy }; 3501 }, 3502 s: function(event, dx, dy) { 3503 return { height: this.originalSize.height + dy }; 3504 }, 3505 se: function(event, dx, dy) { 3506 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3507 }, 3508 sw: function(event, dx, dy) { 3509 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3510 }, 3511 ne: function(event, dx, dy) { 3512 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 3513 }, 3514 nw: function(event, dx, dy) { 3515 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 3516 } 3517 }, 3518
vendor: 104,212 bytes, lines 3519-7083
3519 _propagate: function(n, event) { 3520 $.ui.plugin.call(this, n, [event, this.ui()]); 3521 (n !== "resize" && this._trigger(n, event, this.ui())); 3522 }, 3523 3524 plugins: {}, 3525 3526 ui: function() { 3527 return { 3528 originalElement: this.originalElement, 3529 element: this.element, 3530 helper: this.helper, 3531 position: this.position, 3532 size: this.size, 3533 originalSize: this.originalSize, 3534 originalPosition: this.originalPosition 3535 }; 3536 } 3537 3538}); 3539 3540/* 3541 * Resizable Extensions 3542 */ 3543 3544$.ui.plugin.add("resizable", "animate", { 3545 3546 stop: function( event ) { 3547 var that = $(this).data("ui-resizable"), 3548 o = that.options, 3549 pr = that._proportionallyResizeElements, 3550 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 3551 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 3552 soffsetw = ista ? 0 : that.sizeDiff.width, 3553 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 3554 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 3555 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 3556 3557 that.element.animate( 3558 $.extend(style, top && left ? { top: top, left: left } : {}), { 3559 duration: o.animateDuration, 3560 easing: o.animateEasing, 3561 step: function() { 3562 3563 var data = { 3564 width: parseInt(that.element.css("width"), 10), 3565 height: parseInt(that.element.css("height"), 10), 3566 top: parseInt(that.element.css("top"), 10), 3567 left: parseInt(that.element.css("left"), 10) 3568 }; 3569 3570 if (pr && pr.length) { 3571 $(pr[0]).css({ width: data.width, height: data.height }); 3572 } 3573 3574 /*// propagating resize, and updating values for each animation step 3575*/ 3576 that._updateCache(data); 3577 that._propagate("resize", event); 3578 3579 } 3580 } 3581 ); 3582 } 3583 3584}); 3585 3586$.ui.plugin.add("resizable", "containment", { 3587 3588 start: function() { 3589 var element, p, co, ch, cw, width, height, 3590 that = $(this).data("ui-resizable"), 3591 o = that.options, 3592 el = that.element, 3593 oc = o.containment, 3594 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 3595 3596 if (!ce) { 3597 return; 3598 } 3599 3600 that.containerElement = $(ce); 3601 3602 if (/document/.test(oc) || oc === document) { 3603 that.containerOffset = { left: 0, top: 0 }; 3604 that.containerPosition = { left: 0, top: 0 }; 3605 3606 that.parentData = { 3607 element: $(document), left: 0, top: 0, 3608 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 3609 }; 3610 } 3611 3612 /*// i'm a node, so compute top, left, right, bottom 3613*/ 3614 else { 3615 element = $(ce); 3616 p = []; 3617 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 3618 3619 that.containerOffset = element.offset(); 3620 that.containerPosition = element.position(); 3621 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 3622 3623 co = that.containerOffset; 3624 ch = that.containerSize.height; 3625 cw = that.containerSize.width; 3626 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 3627 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 3628 3629 that.parentData = { 3630 element: ce, left: co.left, top: co.top, width: width, height: height 3631 }; 3632 } 3633 }, 3634 3635 resize: function( event ) { 3636 var woset, hoset, isParent, isOffsetRelative, 3637 that = $(this).data("ui-resizable"), 3638 o = that.options, 3639 co = that.containerOffset, cp = that.position, 3640 pRatio = that._aspectRatio || event.shiftKey, 3641 cop = { top:0, left:0 }, ce = that.containerElement; 3642 3643 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 3644 cop = co; 3645 } 3646 3647 if (cp.left < (that._helper ? co.left : 0)) { 3648 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 3649 if (pRatio) { 3650 that.size.height = that.size.width / that.aspectRatio; 3651 } 3652 that.position.left = o.helper ? co.left : 0; 3653 } 3654 3655 if (cp.top < (that._helper ? co.top : 0)) { 3656 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3657 if (pRatio) { 3658 that.size.width = that.size.height * that.aspectRatio; 3659 } 3660 that.position.top = that._helper ? co.top : 0; 3661 } 3662 3663 that.offset.left = that.parentData.left+that.position.left; 3664 that.offset.top = that.parentData.top+that.position.top; 3665 3666 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3667 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3668 3669 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3670 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3671 3672 if(isParent && isOffsetRelative) { 3673 woset -= that.parentData.left; 3674 } 3675 3676 if (woset + that.size.width >= that.parentData.width) { 3677 that.size.width = that.parentData.width - woset; 3678 if (pRatio) { 3679 that.size.height = that.size.width / that.aspectRatio; 3680 } 3681 } 3682 3683 if (hoset + that.size.height >= that.parentData.height) { 3684 that.size.height = that.parentData.height - hoset; 3685 if (pRatio) { 3686 that.size.width = that.size.height * that.aspectRatio; 3687 } 3688 } 3689 }, 3690 3691 stop: function(){ 3692 var that = $(this).data("ui-resizable"), 3693 o = that.options, 3694 co = that.containerOffset, 3695 cop = that.containerPosition, 3696 ce = that.containerElement, 3697 helper = $(that.helper), 3698 ho = helper.offset(), 3699 w = helper.outerWidth() - that.sizeDiff.width, 3700 h = helper.outerHeight() - that.sizeDiff.height; 3701 3702 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3703 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3704 } 3705 3706 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3707 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3708 } 3709 3710 } 3711}); 3712 3713$.ui.plugin.add("resizable", "alsoResize", { 3714 3715 start: function () { 3716 var that = $(this).data("ui-resizable"), 3717 o = that.options, 3718 _store = function (exp) { 3719 $(exp).each(function() { 3720 var el = $(this); 3721 el.data("ui-resizable-alsoresize", { 3722 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3723 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3724 }); 3725 }); 3726 }; 3727 3728 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3729 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3730 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3731 }else{ 3732 _store(o.alsoResize); 3733 } 3734 }, 3735 3736 resize: function (event, ui) { 3737 var that = $(this).data("ui-resizable"), 3738 o = that.options, 3739 os = that.originalSize, 3740 op = that.originalPosition, 3741 delta = { 3742 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3743 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3744 }, 3745 3746 _alsoResize = function (exp, c) { 3747 $(exp).each(function() { 3748 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3749 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3750 3751 $.each(css, function (i, prop) { 3752 var sum = (start[prop]||0) + (delta[prop]||0); 3753 if (sum && sum >= 0) { 3754 style[prop] = sum || null; 3755 } 3756 }); 3757 3758 el.css(style); 3759 }); 3760 }; 3761 3762 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3763 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3764 }else{ 3765 _alsoResize(o.alsoResize); 3766 } 3767 }, 3768 3769 stop: function () { 3770 $(this).removeData("resizable-alsoresize"); 3771 } 3772}); 3773 3774$.ui.plugin.add("resizable", "ghost", { 3775 3776 start: function() { 3777 3778 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3779 3780 that.ghost = that.originalElement.clone(); 3781 that.ghost 3782 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3783 .addClass("ui-resizable-ghost") 3784 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3785 3786 that.ghost.appendTo(that.helper); 3787 3788 }, 3789 3790 resize: function(){ 3791 var that = $(this).data("ui-resizable"); 3792 if (that.ghost) { 3793 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3794 } 3795 }, 3796 3797 stop: function() { 3798 var that = $(this).data("ui-resizable"); 3799 if (that.ghost && that.helper) { 3800 that.helper.get(0).removeChild(that.ghost.get(0)); 3801 } 3802 } 3803 3804}); 3805 3806$.ui.plugin.add("resizable", "grid", { 3807 3808 resize: function() { 3809 var that = $(this).data("ui-resizable"), 3810 o = that.options, 3811 cs = that.size, 3812 os = that.originalSize, 3813 op = that.originalPosition, 3814 a = that.axis, 3815 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3816 gridX = (grid[0]||1), 3817 gridY = (grid[1]||1), 3818 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3819 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3820 newWidth = os.width + ox, 3821 newHeight = os.height + oy, 3822 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3823 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3824 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3825 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3826 3827 o.grid = grid; 3828 3829 if (isMinWidth) { 3830 newWidth = newWidth + gridX; 3831 } 3832 if (isMinHeight) { 3833 newHeight = newHeight + gridY; 3834 } 3835 if (isMaxWidth) { 3836 newWidth = newWidth - gridX; 3837 } 3838 if (isMaxHeight) { 3839 newHeight = newHeight - gridY; 3840 } 3841 3842 if (/^(se|s|e)$/.test(a)) { 3843 that.size.width = newWidth; 3844 that.size.height = newHeight; 3845 } else if (/^(ne)$/.test(a)) { 3846 that.size.width = newWidth; 3847 that.size.height = newHeight; 3848 that.position.top = op.top - oy; 3849 } else if (/^(sw)$/.test(a)) { 3850 that.size.width = newWidth; 3851 that.size.height = newHeight; 3852 that.position.left = op.left - ox; 3853 } else { 3854 that.size.width = newWidth; 3855 that.size.height = newHeight; 3856 that.position.top = op.top - oy; 3857 that.position.left = op.left - ox; 3858 } 3859 } 3860 3861}); 3862 3863})(jQuery); 3864(function( $, undefined ) { 3865 3866$.widget("ui.selectable", $.ui.mouse, { 3867 version: "1.10.2", 3868 options: { 3869 appendTo: "body", 3870 autoRefresh: true, 3871 distance: 0, 3872 filter: "*", 3873 tolerance: "touch", 3874 3875 /*// callbacks 3876*/ 3877 selected: null, 3878 selecting: null, 3879 start: null, 3880 stop: null, 3881 unselected: null, 3882 unselecting: null 3883 }, 3884 _create: function() { 3885 var selectees, 3886 that = this; 3887 3888 this.element.addClass("ui-selectable"); 3889 3890 this.dragged = false; 3891 3892 /*// cache selectee children based on filter 3893*/ 3894 this.refresh = function() { 3895 selectees = $(that.options.filter, that.element[0]); 3896 selectees.addClass("ui-selectee"); 3897 selectees.each(function() { 3898 var $this = $(this), 3899 pos = $this.offset(); 3900 $.data(this, "selectable-item", { 3901 element: this, 3902 $element: $this, 3903 left: pos.left, 3904 top: pos.top, 3905 right: pos.left + $this.outerWidth(), 3906 bottom: pos.top + $this.outerHeight(), 3907 startselected: false, 3908 selected: $this.hasClass("ui-selected"), 3909 selecting: $this.hasClass("ui-selecting"), 3910 unselecting: $this.hasClass("ui-unselecting") 3911 }); 3912 }); 3913 }; 3914 this.refresh(); 3915 3916 this.selectees = selectees.addClass("ui-selectee"); 3917 3918 this._mouseInit(); 3919 3920 this.helper = $("<div class='ui-selectable-helper'></div>"); 3921 }, 3922 3923 _destroy: function() { 3924 this.selectees 3925 .removeClass("ui-selectee") 3926 .removeData("selectable-item"); 3927 this.element 3928 .removeClass("ui-selectable ui-selectable-disabled"); 3929 this._mouseDestroy(); 3930 }, 3931 3932 _mouseStart: function(event) { 3933 var that = this, 3934 options = this.options; 3935 3936 this.opos = [event.pageX, event.pageY]; 3937 3938 if (this.options.disabled) { 3939 return; 3940 } 3941 3942 this.selectees = $(options.filter, this.element[0]); 3943 3944 this._trigger("start", event); 3945 3946 $(options.appendTo).append(this.helper); 3947 /*// position helper (lasso) 3948*/ 3949 this.helper.css({ 3950 "left": event.pageX, 3951 "top": event.pageY, 3952 "width": 0, 3953 "height": 0 3954 }); 3955 3956 if (options.autoRefresh) { 3957 this.refresh(); 3958 } 3959 3960 this.selectees.filter(".ui-selected").each(function() { 3961 var selectee = $.data(this, "selectable-item"); 3962 selectee.startselected = true; 3963 if (!event.metaKey && !event.ctrlKey) { 3964 selectee.$element.removeClass("ui-selected"); 3965 selectee.selected = false; 3966 selectee.$element.addClass("ui-unselecting"); 3967 selectee.unselecting = true; 3968 /*// selectable UNSELECTING callback 3969*/ 3970 that._trigger("unselecting", event, { 3971 unselecting: selectee.element 3972 }); 3973 } 3974 }); 3975 3976 $(event.target).parents().addBack().each(function() { 3977 var doSelect, 3978 selectee = $.data(this, "selectable-item"); 3979 if (selectee) { 3980 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3981 selectee.$element 3982 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3983 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3984 selectee.unselecting = !doSelect; 3985 selectee.selecting = doSelect; 3986 selectee.selected = doSelect; 3987 /*// selectable (UN)SELECTING callback 3988*/ 3989 if (doSelect) { 3990 that._trigger("selecting", event, { 3991 selecting: selectee.element 3992 }); 3993 } else { 3994 that._trigger("unselecting", event, { 3995 unselecting: selectee.element 3996 }); 3997 } 3998 return false; 3999 } 4000 }); 4001 4002 }, 4003 4004 _mouseDrag: function(event) { 4005 4006 this.dragged = true; 4007 4008 if (this.options.disabled) { 4009 return; 4010 } 4011 4012 var tmp, 4013 that = this, 4014 options = this.options, 4015 x1 = this.opos[0], 4016 y1 = this.opos[1], 4017 x2 = event.pageX, 4018 y2 = event.pageY; 4019 4020 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 4021 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 4022 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 4023 4024 this.selectees.each(function() { 4025 var selectee = $.data(this, "selectable-item"), 4026 hit = false; 4027 4028 //prevent helper from being selected if appendTo: selectable 4029 if (!selectee || selectee.element === that.element[0]) { 4030 return; 4031 } 4032 4033 if (options.tolerance === "touch") { 4034 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 4035 } else if (options.tolerance === "fit") { 4036 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 4037 } 4038 4039 if (hit) { 4040 /*// SELECT 4041*/ 4042 if (selectee.selected) { 4043 selectee.$element.removeClass("ui-selected"); 4044 selectee.selected = false; 4045 } 4046 if (selectee.unselecting) { 4047 selectee.$element.removeClass("ui-unselecting"); 4048 selectee.unselecting = false; 4049 } 4050 if (!selectee.selecting) { 4051 selectee.$element.addClass("ui-selecting"); 4052 selectee.selecting = true; 4053 /*// selectable SELECTING callback 4054*/ 4055 that._trigger("selecting", event, { 4056 selecting: selectee.element 4057 }); 4058 } 4059 } else { 4060 /*// UNSELECT 4061*/ 4062 if (selectee.selecting) { 4063 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 4064 selectee.$element.removeClass("ui-selecting"); 4065 selectee.selecting = false; 4066 selectee.$element.addClass("ui-selected"); 4067 selectee.selected = true; 4068 } else { 4069 selectee.$element.removeClass("ui-selecting"); 4070 selectee.selecting = false; 4071 if (selectee.startselected) { 4072 selectee.$element.addClass("ui-unselecting"); 4073 selectee.unselecting = true; 4074 } 4075 /*// selectable UNSELECTING callback 4076*/ 4077 that._trigger("unselecting", event, { 4078 unselecting: selectee.element 4079 }); 4080 } 4081 } 4082 if (selectee.selected) { 4083 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 4084 selectee.$element.removeClass("ui-selected"); 4085 selectee.selected = false; 4086 4087 selectee.$element.addClass("ui-unselecting"); 4088 selectee.unselecting = true; 4089 /*// selectable UNSELECTING callback 4090*/ 4091 that._trigger("unselecting", event, { 4092 unselecting: selectee.element 4093 }); 4094 } 4095 } 4096 } 4097 }); 4098 4099 return false; 4100 }, 4101 4102 _mouseStop: function(event) { 4103 var that = this; 4104 4105 this.dragged = false; 4106 4107 $(".ui-unselecting", this.element[0]).each(function() { 4108 var selectee = $.data(this, "selectable-item"); 4109 selectee.$element.removeClass("ui-unselecting"); 4110 selectee.unselecting = false; 4111 selectee.startselected = false; 4112 that._trigger("unselected", event, { 4113 unselected: selectee.element 4114 }); 4115 }); 4116 $(".ui-selecting", this.element[0]).each(function() { 4117 var selectee = $.data(this, "selectable-item"); 4118 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 4119 selectee.selecting = false; 4120 selectee.selected = true; 4121 selectee.startselected = true; 4122 that._trigger("selected", event, { 4123 selected: selectee.element 4124 }); 4125 }); 4126 this._trigger("stop", event); 4127 4128 this.helper.remove(); 4129 4130 return false; 4131 } 4132 4133}); 4134 4135})(jQuery); 4136(function( $, undefined ) { 4137 4138/*jshint loopfunc: true */ 4139 4140function isOverAxis( x, reference, size ) { 4141 return ( x > reference ) && ( x < ( reference + size ) ); 4142} 4143 4144function isFloating(item) { 4145 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 4146} 4147 4148$.widget("ui.sortable", $.ui.mouse, { 4149 version: "1.10.2", 4150 widgetEventPrefix: "sort", 4151 ready: false, 4152 options: { 4153 appendTo: "parent", 4154 axis: false, 4155 connectWith: false, 4156 containment: false, 4157 cursor: "auto", 4158 cursorAt: false, 4159 dropOnEmpty: true, 4160 forcePlaceholderSize: false, 4161 forceHelperSize: false, 4162 grid: false, 4163 handle: false, 4164 helper: "original", 4165 items: "> *", 4166 opacity: false, 4167 placeholder: false, 4168 revert: false, 4169 scroll: true, 4170 scrollSensitivity: 20, 4171 scrollSpeed: 20, 4172 scope: "default", 4173 tolerance: "intersect", 4174 zIndex: 1000, 4175 4176 /*// callbacks 4177*/ 4178 activate: null, 4179 beforeStop: null, 4180 change: null, 4181 deactivate: null, 4182 out: null, 4183 over: null, 4184 receive: null, 4185 remove: null, 4186 sort: null, 4187 start: null, 4188 stop: null, 4189 update: null 4190 }, 4191 _create: function() { 4192 4193 var o = this.options; 4194 this.containerCache = {}; 4195 this.element.addClass("ui-sortable"); 4196 4197 //Get the items 4198 this.refresh(); 4199 4200 //Let's determine if the items are being displayed horizontally 4201 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 4202 4203 //Let's determine the parent's offset 4204 this.offset = this.element.offset(); 4205 4206 //Initialize mouse events for interaction 4207 this._mouseInit(); 4208 4209 //We're ready to go 4210 this.ready = true; 4211 4212 }, 4213 4214 _destroy: function() { 4215 this.element 4216 .removeClass("ui-sortable ui-sortable-disabled"); 4217 this._mouseDestroy(); 4218 4219 for ( var i = this.items.length - 1; i >= 0; i-- ) { 4220 this.items[i].item.removeData(this.widgetName + "-item"); 4221 } 4222 4223 return this; 4224 }, 4225 4226 _setOption: function(key, value){ 4227 if ( key === "disabled" ) { 4228 this.options[ key ] = value; 4229 4230 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 4231 } else { 4232 /*// Don't call widget base _setOption for disable as it adds ui-state-disabled class 4233*/ 4234 $.Widget.prototype._setOption.apply(this, arguments); 4235 } 4236 }, 4237 4238 _mouseCapture: function(event, overrideHandle) { 4239 var currentItem = null, 4240 validHandle = false, 4241 that = this; 4242 4243 if (this.reverting) { 4244 return false; 4245 } 4246 4247 if(this.options.disabled || this.options.type === "static") { 4248 return false; 4249 } 4250 4251 //We have to refresh the items data once first 4252 this._refreshItems(event); 4253 4254 //Find out if the clicked node (or one of its parents) is a actual item in this.items 4255 $(event.target).parents().each(function() { 4256 if($.data(this, that.widgetName + "-item") === that) { 4257 currentItem = $(this); 4258 return false; 4259 } 4260 }); 4261 if($.data(event.target, that.widgetName + "-item") === that) { 4262 currentItem = $(event.target); 4263 } 4264 4265 if(!currentItem) { 4266 return false; 4267 } 4268 if(this.options.handle && !overrideHandle) { 4269 $(this.options.handle, currentItem).find("*").addBack().each(function() { 4270 if(this === event.target) { 4271 validHandle = true; 4272 } 4273 }); 4274 if(!validHandle) { 4275 return false; 4276 } 4277 } 4278 4279 this.currentItem = currentItem; 4280 this._removeCurrentsFromItems(); 4281 return true; 4282 4283 }, 4284 4285 _mouseStart: function(event, overrideHandle, noActivation) { 4286 4287 var i, body, 4288 o = this.options; 4289 4290 this.currentContainer = this; 4291 4292 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 4293 this.refreshPositions(); 4294 4295 //Create and append the visible helper 4296 this.helper = this._createHelper(event); 4297 4298 //Cache the helper size 4299 this._cacheHelperProportions(); 4300 4301 /* 4302 * - Position generation - 4303 * This block generates everything position related - it's the core of draggables. 4304 */ 4305 4306 //Cache the margins of the original element 4307 this._cacheMargins(); 4308 4309 //Get the next scrolling parent 4310 this.scrollParent = this.helper.scrollParent(); 4311 4312 //The element's absolute position on the page minus margins 4313 this.offset = this.currentItem.offset(); 4314 this.offset = { 4315 top: this.offset.top - this.margins.top, 4316 left: this.offset.left - this.margins.left 4317 }; 4318 4319 $.extend(this.offset, { 4320 click: { //Where the click happened, relative to the element 4321 left: event.pageX - this.offset.left, 4322 top: event.pageY - this.offset.top 4323 }, 4324 parent: this._getParentOffset(), 4325 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 4326 }); 4327 4328 /*// Only after we got the offset, we can change the helper's position to absolute 4329*/ 4330 /*// TODO: Still need to figure out a way to make relative sorting possible 4331*/ 4332 this.helper.css("position", "absolute"); 4333 this.cssPosition = this.helper.css("position"); 4334 4335 //Generate the original position 4336 this.originalPosition = this._generatePosition(event); 4337 this.originalPageX = event.pageX; 4338 this.originalPageY = event.pageY; 4339 4340 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 4341 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 4342 4343 //Cache the former DOM position 4344 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 4345 4346 //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 4347 if(this.helper[0] !== this.currentItem[0]) { 4348 this.currentItem.hide(); 4349 } 4350 4351 //Create the placeholder 4352 this._createPlaceholder(); 4353 4354 //Set a containment if given in the options 4355 if(o.containment) { 4356 this._setContainment(); 4357 } 4358 4359 if( o.cursor && o.cursor !== "auto" ) { /*// cursor option 4360*/ 4361 body = this.document.find( "body" ); 4362 4363 /*// support: IE 4364*/ 4365 this.storedCursor = body.css( "cursor" ); 4366 body.css( "cursor", o.cursor ); 4367 4368 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 4369 } 4370 4371 if(o.opacity) { /*// opacity option 4372*/ 4373 if (this.helper.css("opacity")) { 4374 this._storedOpacity = this.helper.css("opacity"); 4375 } 4376 this.helper.css("opacity", o.opacity); 4377 } 4378 4379 if(o.zIndex) { /*// zIndex option 4380*/ 4381 if (this.helper.css("zIndex")) { 4382 this._storedZIndex = this.helper.css("zIndex"); 4383 } 4384 this.helper.css("zIndex", o.zIndex); 4385 } 4386 4387 //Prepare scrolling 4388 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4389 this.overflowOffset = this.scrollParent.offset(); 4390 } 4391 4392 //Call callbacks 4393 this._trigger("start", event, this._uiHash()); 4394 4395 //Recache the helper size 4396 if(!this._preserveHelperProportions) { 4397 this._cacheHelperProportions(); 4398 } 4399 4400 4401 //Post "activate" events to possible containers 4402 if( !noActivation ) { 4403 for ( i = this.containers.length - 1; i >= 0; i-- ) { 4404 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 4405 } 4406 } 4407 4408 //Prepare possible droppables 4409 if($.ui.ddmanager) { 4410 $.ui.ddmanager.current = this; 4411 } 4412 4413 if ($.ui.ddmanager && !o.dropBehaviour) { 4414 $.ui.ddmanager.prepareOffsets(this, event); 4415 } 4416 4417 this.dragging = true; 4418 4419 this.helper.addClass("ui-sortable-helper"); 4420 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 4421 return true; 4422 4423 }, 4424 4425 _mouseDrag: function(event) { 4426 var i, item, itemElement, intersection, 4427 o = this.options, 4428 scrolled = false; 4429 4430 //Compute the helpers position 4431 this.position = this._generatePosition(event); 4432 this.positionAbs = this._convertPositionTo("absolute"); 4433 4434 if (!this.lastPositionAbs) { 4435 this.lastPositionAbs = this.positionAbs; 4436 } 4437 4438 //Do scrolling 4439 if(this.options.scroll) { 4440 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 4441 4442 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 4443 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 4444 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 4445 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 4446 } 4447 4448 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 4449 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 4450 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 4451 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 4452 } 4453 4454 } else { 4455 4456 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 4457 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4458 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 4459 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4460 } 4461 4462 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 4463 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4464 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 4465 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4466 } 4467 4468 } 4469 4470 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 4471 $.ui.ddmanager.prepareOffsets(this, event); 4472 } 4473 } 4474 4475 //Regenerate the absolute position used for position checks 4476 this.positionAbs = this._convertPositionTo("absolute"); 4477 4478 //Set the helper position 4479 if(!this.options.axis || this.options.axis !== "y") { 4480 this.helper[0].style.left = this.position.left+"px"; 4481 } 4482 if(!this.options.axis || this.options.axis !== "x") { 4483 this.helper[0].style.top = this.position.top+"px"; 4484 } 4485 4486 //Rearrange 4487 for (i = this.items.length - 1; i >= 0; i--) { 4488 4489 //Cache variables and intersection, continue if no intersection 4490 item = this.items[i]; 4491 itemElement = item.item[0]; 4492 intersection = this._intersectsWithPointer(item); 4493 if (!intersection) { 4494 continue; 4495 } 4496 4497 /*// Only put the placeholder inside the current Container, skip all 4498*/ 4499 /*// items form other containers. This works because when moving 4500*/ 4501 /*// an item from one container to another the 4502*/ 4503 /*// currentContainer is switched before the placeholder is moved. 4504*/ 4505 // 4506 /*// Without this moving items in "sub-sortables" can cause the placeholder to jitter 4507*/ 4508 /*// beetween the outer and inner container. 4509*/ 4510 if (item.instance !== this.currentContainer) { 4511 continue; 4512 } 4513 4514 /*// cannot intersect with itself 4515*/ 4516 /*// no useless actions that have been done before 4517*/ 4518 /*// no action if the item moved is the parent of the item checked 4519*/ 4520 if (itemElement !== this.currentItem[0] && 4521 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 4522 !$.contains(this.placeholder[0], itemElement) && 4523 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 4524 ) { 4525 4526 this.direction = intersection === 1 ? "down" : "up"; 4527 4528 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 4529 this._rearrange(event, item); 4530 } else { 4531 break; 4532 } 4533 4534 this._trigger("change", event, this._uiHash()); 4535 break; 4536 } 4537 } 4538 4539 //Post events to containers 4540 this._contactContainers(event); 4541 4542 //Interconnect with droppables 4543 if($.ui.ddmanager) { 4544 $.ui.ddmanager.drag(this, event); 4545 } 4546 4547 //Call callbacks 4548 this._trigger("sort", event, this._uiHash()); 4549 4550 this.lastPositionAbs = this.positionAbs; 4551 return false; 4552 4553 }, 4554 4555 _mouseStop: function(event, noPropagation) { 4556 4557 if(!event) { 4558 return; 4559 } 4560 4561 //If we are using droppables, inform the manager about the drop 4562 if ($.ui.ddmanager && !this.options.dropBehaviour) { 4563 $.ui.ddmanager.drop(this, event); 4564 } 4565 4566 if(this.options.revert) { 4567 var that = this, 4568 cur = this.placeholder.offset(), 4569 axis = this.options.axis, 4570 animation = {}; 4571 4572 if ( !axis || axis === "x" ) { 4573 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 4574 } 4575 if ( !axis || axis === "y" ) { 4576 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 4577 } 4578 this.reverting = true; 4579 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 4580 that._clear(event); 4581 }); 4582 } else { 4583 this._clear(event, noPropagation); 4584 } 4585 4586 return false; 4587 4588 }, 4589 4590 cancel: function() { 4591 4592 if(this.dragging) { 4593 4594 this._mouseUp({ target: null }); 4595 4596 if(this.options.helper === "original") { 4597 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4598 } else { 4599 this.currentItem.show(); 4600 } 4601 4602 //Post deactivating events to containers 4603 for (var i = this.containers.length - 1; i >= 0; i--){ 4604 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 4605 if(this.containers[i].containerCache.over) { 4606 this.containers[i]._trigger("out", null, this._uiHash(this)); 4607 this.containers[i].containerCache.over = 0; 4608 } 4609 } 4610 4611 } 4612 4613 if (this.placeholder) { 4614 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4615 if(this.placeholder[0].parentNode) { 4616 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4617 } 4618 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 4619 this.helper.remove(); 4620 } 4621 4622 $.extend(this, { 4623 helper: null, 4624 dragging: false, 4625 reverting: false, 4626 _noFinalSort: null 4627 }); 4628 4629 if(this.domPosition.prev) { 4630 $(this.domPosition.prev).after(this.currentItem); 4631 } else { 4632 $(this.domPosition.parent).prepend(this.currentItem); 4633 } 4634 } 4635 4636 return this; 4637 4638 }, 4639 4640 serialize: function(o) { 4641 4642 var items = this._getItemsAsjQuery(o && o.connected), 4643 str = []; 4644 o = o || {}; 4645 4646 $(items).each(function() { 4647 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 4648 if (res) { 4649 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 4650 } 4651 }); 4652 4653 if(!str.length && o.key) { 4654 str.push(o.key + "="); 4655 } 4656 4657 return str.join("&"); 4658 4659 }, 4660 4661 toArray: function(o) { 4662 4663 var items = this._getItemsAsjQuery(o && o.connected), 4664 ret = []; 4665 4666 o = o || {}; 4667 4668 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 4669 return ret; 4670 4671 }, 4672 4673 /* Be careful with the following core functions */ 4674 _intersectsWith: function(item) { 4675 4676 var x1 = this.positionAbs.left, 4677 x2 = x1 + this.helperProportions.width, 4678 y1 = this.positionAbs.top, 4679 y2 = y1 + this.helperProportions.height, 4680 l = item.left, 4681 r = l + item.width, 4682 t = item.top, 4683 b = t + item.height, 4684 dyClick = this.offset.click.top, 4685 dxClick = this.offset.click.left, 4686 isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4687 4688 if ( this.options.tolerance === "pointer" || 4689 this.options.forcePointerForContainers || 4690 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4691 ) { 4692 return isOverElement; 4693 } else { 4694 4695 return (l < x1 + (this.helperProportions.width / 2) && /*// Right Half 4696*/ 4697 x2 - (this.helperProportions.width / 2) < r && /*// Left Half 4698*/ 4699 t < y1 + (this.helperProportions.height / 2) && /*// Bottom Half 4700*/ 4701 y2 - (this.helperProportions.height / 2) < b ); /*// Top Half 4702*/ 4703 4704 } 4705 }, 4706 4707 _intersectsWithPointer: function(item) { 4708 4709 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4710 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4711 isOverElement = isOverElementHeight && isOverElementWidth, 4712 verticalDirection = this._getDragVerticalDirection(), 4713 horizontalDirection = this._getDragHorizontalDirection(); 4714 4715 if (!isOverElement) { 4716 return false; 4717 } 4718 4719 return this.floating ? 4720 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4721 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4722 4723 }, 4724 4725 _intersectsWithSides: function(item) { 4726 4727 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4728 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4729 verticalDirection = this._getDragVerticalDirection(), 4730 horizontalDirection = this._getDragHorizontalDirection(); 4731 4732 if (this.floating && horizontalDirection) { 4733 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4734 } else { 4735 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4736 } 4737 4738 }, 4739 4740 _getDragVerticalDirection: function() { 4741 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4742 return delta !== 0 && (delta > 0 ? "down" : "up"); 4743 }, 4744 4745 _getDragHorizontalDirection: function() { 4746 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4747 return delta !== 0 && (delta > 0 ? "right" : "left"); 4748 }, 4749 4750 refresh: function(event) { 4751 this._refreshItems(event); 4752 this.refreshPositions(); 4753 return this; 4754 }, 4755 4756 _connectWith: function() { 4757 var options = this.options; 4758 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4759 }, 4760 4761 _getItemsAsjQuery: function(connected) { 4762 4763 var i, j, cur, inst, 4764 items = [], 4765 queries = [], 4766 connectWith = this._connectWith(); 4767 4768 if(connectWith && connected) { 4769 for (i = connectWith.length - 1; i >= 0; i--){ 4770 cur = $(connectWith[i]); 4771 for ( j = cur.length - 1; j >= 0; j--){ 4772 inst = $.data(cur[j], this.widgetFullName); 4773 if(inst && inst !== this && !inst.options.disabled) { 4774 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]); 4775 } 4776 } 4777 } 4778 } 4779 4780 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]); 4781 4782 for (i = queries.length - 1; i >= 0; i--){ 4783 queries[i][0].each(function() { 4784 items.push(this); 4785 }); 4786 } 4787 4788 return $(items); 4789 4790 }, 4791 4792 _removeCurrentsFromItems: function() { 4793 4794 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4795 4796 this.items = $.grep(this.items, function (item) { 4797 for (var j=0; j < list.length; j++) { 4798 if(list[j] === item.item[0]) { 4799 return false; 4800 } 4801 } 4802 return true; 4803 }); 4804 4805 }, 4806 4807 _refreshItems: function(event) { 4808 4809 this.items = []; 4810 this.containers = [this]; 4811 4812 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4813 items = this.items, 4814 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4815 connectWith = this._connectWith(); 4816 4817 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4818 for (i = connectWith.length - 1; i >= 0; i--){ 4819 cur = $(connectWith[i]); 4820 for (j = cur.length - 1; j >= 0; j--){ 4821 inst = $.data(cur[j], this.widgetFullName); 4822 if(inst && inst !== this && !inst.options.disabled) { 4823 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4824 this.containers.push(inst); 4825 } 4826 } 4827 } 4828 } 4829 4830 for (i = queries.length - 1; i >= 0; i--) { 4831 targetData = queries[i][1]; 4832 _queries = queries[i][0]; 4833 4834 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4835 item = $(_queries[j]); 4836 4837 item.data(this.widgetName + "-item", targetData); /*// Data for target checking (mouse manager) 4838*/ 4839 4840 items.push({ 4841 item: item, 4842 instance: targetData, 4843 width: 0, height: 0, 4844 left: 0, top: 0 4845 }); 4846 } 4847 } 4848 4849 }, 4850 4851 refreshPositions: function(fast) { 4852 4853 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4854 if(this.offsetParent && this.helper) { 4855 this.offset.parent = this._getParentOffset(); 4856 } 4857 4858 var i, item, t, p; 4859 4860 for (i = this.items.length - 1; i >= 0; i--){ 4861 item = this.items[i]; 4862 4863 //We ignore calculating positions of all connected containers when we're not over them 4864 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4865 continue; 4866 } 4867 4868 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4869 4870 if (!fast) { 4871 item.width = t.outerWidth(); 4872 item.height = t.outerHeight(); 4873 } 4874 4875 p = t.offset(); 4876 item.left = p.left; 4877 item.top = p.top; 4878 } 4879 4880 if(this.options.custom && this.options.custom.refreshContainers) { 4881 this.options.custom.refreshContainers.call(this); 4882 } else { 4883 for (i = this.containers.length - 1; i >= 0; i--){ 4884 p = this.containers[i].element.offset(); 4885 this.containers[i].containerCache.left = p.left; 4886 this.containers[i].containerCache.top = p.top; 4887 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4888 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4889 } 4890 } 4891 4892 return this; 4893 }, 4894 4895 _createPlaceholder: function(that) { 4896 that = that || this; 4897 var className, 4898 o = that.options; 4899 4900 if(!o.placeholder || o.placeholder.constructor === String) { 4901 className = o.placeholder; 4902 o.placeholder = { 4903 element: function() { 4904 4905 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4906 element = $( that.document[0].createElement( nodeName ) ) 4907 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4908 .removeClass("ui-sortable-helper"); 4909 4910 if ( nodeName === "tr" ) { 4911 /*// Use a high colspan to force the td to expand the full 4912*/ 4913 /*// width of the table (browsers are smart enough to 4914*/ 4915 /*// handle this properly) 4916*/ 4917 element.append( "<td colspan='99'> </td>" ); 4918 } else if ( nodeName === "img" ) { 4919 element.attr( "src", that.currentItem.attr( "src" ) ); 4920 } 4921 4922 if ( !className ) { 4923 element.css( "visibility", "hidden" ); 4924 } 4925 4926 return element; 4927 }, 4928 update: function(container, p) { 4929 4930 /*// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4931*/ 4932 /*// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4933*/ 4934 if(className && !o.forcePlaceholderSize) { 4935 return; 4936 } 4937 4938 //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 4939 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4940 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4941 } 4942 }; 4943 } 4944 4945 //Create the placeholder 4946 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4947 4948 //Append it after the actual current item 4949 that.currentItem.after(that.placeholder); 4950 4951 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4952 o.placeholder.update(that, that.placeholder); 4953 4954 }, 4955 4956 _contactContainers: function(event) { 4957 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4958 innermostContainer = null, 4959 innermostIndex = null; 4960 4961 /*// get innermost container that intersects with item 4962*/ 4963 for (i = this.containers.length - 1; i >= 0; i--) { 4964 4965 /*// never consider a container that's located within the item itself 4966*/ 4967 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4968 continue; 4969 } 4970 4971 if(this._intersectsWith(this.containers[i].containerCache)) { 4972 4973 /*// if we've already found a container and it's more "inner" than this, then continue 4974*/ 4975 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4976 continue; 4977 } 4978 4979 innermostContainer = this.containers[i]; 4980 innermostIndex = i; 4981 4982 } else { 4983 /*// container doesn't intersect. trigger "out" event if necessary 4984*/ 4985 if(this.containers[i].containerCache.over) { 4986 this.containers[i]._trigger("out", event, this._uiHash(this)); 4987 this.containers[i].containerCache.over = 0; 4988 } 4989 } 4990 4991 } 4992 4993 /*// if no intersecting containers found, return 4994*/ 4995 if(!innermostContainer) { 4996 return; 4997 } 4998 4999 /*// move the item into the container if it's not there already 5000*/ 5001 if(this.containers.length === 1) { 5002 if (!this.containers[innermostIndex].containerCache.over) { 5003 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5004 this.containers[innermostIndex].containerCache.over = 1; 5005 } 5006 } else { 5007 5008 //When entering a new container, we will find the item with the least distance and append our item near it 5009 dist = 10000; 5010 itemWithLeastDistance = null; 5011 floating = innermostContainer.floating || isFloating(this.currentItem); 5012 posProperty = floating ? "left" : "top"; 5013 sizeProperty = floating ? "width" : "height"; 5014 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 5015 for (j = this.items.length - 1; j >= 0; j--) { 5016 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 5017 continue; 5018 } 5019 if(this.items[j].item[0] === this.currentItem[0]) { 5020 continue; 5021 } 5022 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 5023 continue; 5024 } 5025 cur = this.items[j].item.offset()[posProperty]; 5026 nearBottom = false; 5027 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 5028 nearBottom = true; 5029 cur += this.items[j][sizeProperty]; 5030 } 5031 5032 if(Math.abs(cur - base) < dist) { 5033 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 5034 this.direction = nearBottom ? "up": "down"; 5035 } 5036 } 5037 5038 //Check if dropOnEmpty is enabled 5039 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 5040 return; 5041 } 5042 5043 if(this.currentContainer === this.containers[innermostIndex]) { 5044 return; 5045 } 5046 5047 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 5048 this._trigger("change", event, this._uiHash()); 5049 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 5050 this.currentContainer = this.containers[innermostIndex]; 5051 5052 //Update the placeholder 5053 this.options.placeholder.update(this.currentContainer, this.placeholder); 5054 5055 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 5056 this.containers[innermostIndex].containerCache.over = 1; 5057 } 5058 5059 5060 }, 5061 5062 _createHelper: function(event) { 5063 5064 var o = this.options, 5065 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 5066 5067 //Add the helper to the DOM if that didn't happen already 5068 if(!helper.parents("body").length) { 5069 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 5070 } 5071 5072 if(helper[0] === this.currentItem[0]) { 5073 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") }; 5074 } 5075 5076 if(!helper[0].style.width || o.forceHelperSize) { 5077 helper.width(this.currentItem.width()); 5078 } 5079 if(!helper[0].style.height || o.forceHelperSize) { 5080 helper.height(this.currentItem.height()); 5081 } 5082 5083 return helper; 5084 5085 }, 5086 5087 _adjustOffsetFromHelper: function(obj) { 5088 if (typeof obj === "string") { 5089 obj = obj.split(" "); 5090 } 5091 if ($.isArray(obj)) { 5092 obj = {left: +obj[0], top: +obj[1] || 0}; 5093 } 5094 if ("left" in obj) { 5095 this.offset.click.left = obj.left + this.margins.left; 5096 } 5097 if ("right" in obj) { 5098 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 5099 } 5100 if ("top" in obj) { 5101 this.offset.click.top = obj.top + this.margins.top; 5102 } 5103 if ("bottom" in obj) { 5104 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 5105 } 5106 }, 5107 5108 _getParentOffset: function() { 5109 5110 5111 //Get the offsetParent and cache its position 5112 this.offsetParent = this.helper.offsetParent(); 5113 var po = this.offsetParent.offset(); 5114 5115 /*// This is a special case where we need to modify a offset calculated on start, since the following happened: 5116*/ 5117 /*// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 5118*/ 5119 /*// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 5120*/ 5121 /*// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 5122*/ 5123 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 5124 po.left += this.scrollParent.scrollLeft(); 5125 po.top += this.scrollParent.scrollTop(); 5126 } 5127 5128 /*// This needs to be actually done for all browsers, since pageX/pageY includes this information 5129*/ 5130 /*// with an ugly IE fix 5131*/ 5132 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 5133 po = { top: 0, left: 0 }; 5134 } 5135 5136 return { 5137 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 5138 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 5139 }; 5140 5141 }, 5142 5143 _getRelativeOffset: function() { 5144 5145 if(this.cssPosition === "relative") { 5146 var p = this.currentItem.position(); 5147 return { 5148 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 5149 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 5150 }; 5151 } else { 5152 return { top: 0, left: 0 }; 5153 } 5154 5155 }, 5156 5157 _cacheMargins: function() { 5158 this.margins = { 5159 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 5160 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 5161 }; 5162 }, 5163 5164 _cacheHelperProportions: function() { 5165 this.helperProportions = { 5166 width: this.helper.outerWidth(), 5167 height: this.helper.outerHeight() 5168 }; 5169 }, 5170 5171 _setContainment: function() { 5172 5173 var ce, co, over, 5174 o = this.options; 5175 if(o.containment === "parent") { 5176 o.containment = this.helper[0].parentNode; 5177 } 5178 if(o.containment === "document" || o.containment === "window") { 5179 this.containment = [ 5180 0 - this.offset.relative.left - this.offset.parent.left, 5181 0 - this.offset.relative.top - this.offset.parent.top, 5182 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 5183 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 5184 ]; 5185 } 5186 5187 if(!(/^(document|window|parent)$/).test(o.containment)) { 5188 ce = $(o.containment)[0]; 5189 co = $(o.containment).offset(); 5190 over = ($(ce).css("overflow") !== "hidden"); 5191 5192 this.containment = [ 5193 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 5194 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 5195 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, 5196 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 5197 ]; 5198 } 5199 5200 }, 5201 5202 _convertPositionTo: function(d, pos) { 5203 5204 if(!pos) { 5205 pos = this.position; 5206 } 5207 var mod = d === "absolute" ? 1 : -1, 5208 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 5209 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 5210 5211 return { 5212 top: ( 5213 pos.top + /*// The absolute mouse position 5214*/ 5215 this.offset.relative.top * mod + /*// Only for relative positioned nodes: Relative offset from element to offset parent 5216*/ 5217 this.offset.parent.top * mod - /*// The offsetParent's offset without borders (offset + border) 5218*/ 5219 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 5220 ), 5221 left: ( 5222 pos.left + /*// The absolute mouse position 5223*/ 5224 this.offset.relative.left * mod + /*// Only for relative positioned nodes: Relative offset from element to offset parent 5225*/ 5226 this.offset.parent.left * mod - /*// The offsetParent's offset without borders (offset + border) 5227*/ 5228 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 5229 ) 5230 }; 5231 5232 }, 5233 5234 _generatePosition: function(event) { 5235 5236 var top, left, 5237 o = this.options, 5238 pageX = event.pageX, 5239 pageY = event.pageY, 5240 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); 5241 5242 /*// This is another very weird special case that only happens for relative elements: 5243*/ 5244 /*// 1. If the css position is relative 5245*/ 5246 /*// 2. and the scroll parent is the document or similar to the offset parent 5247*/ 5248 /*// we have to refresh the relative offset during the scroll so there are no jumps 5249*/ 5250 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 5251 this.offset.relative = this._getRelativeOffset(); 5252 } 5253 5254 /* 5255 * - Position constraining - 5256 * Constrain the position to a mix of grid, containment. 5257 */ 5258 5259 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 5260 5261 if(this.containment) { 5262 if(event.pageX - this.offset.click.left < this.containment[0]) { 5263 pageX = this.containment[0] + this.offset.click.left; 5264 } 5265 if(event.pageY - this.offset.click.top < this.containment[1]) { 5266 pageY = this.containment[1] + this.offset.click.top; 5267 } 5268 if(event.pageX - this.offset.click.left > this.containment[2]) { 5269 pageX = this.containment[2] + this.offset.click.left; 5270 } 5271 if(event.pageY - this.offset.click.top > this.containment[3]) { 5272 pageY = this.containment[3] + this.offset.click.top; 5273 } 5274 } 5275 5276 if(o.grid) { 5277 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 5278 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; 5279 5280 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 5281 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; 5282 } 5283 5284 } 5285 5286 return { 5287 top: ( 5288 pageY - /*// The absolute mouse position 5289*/ 5290 this.offset.click.top - /*// Click offset (relative to the element) 5291*/ 5292 this.offset.relative.top - /*// Only for relative positioned nodes: Relative offset from element to offset parent 5293*/ 5294 this.offset.parent.top + /*// The offsetParent's offset without borders (offset + border) 5295*/ 5296 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 5297 ), 5298 left: ( 5299 pageX - /*// The absolute mouse position 5300*/ 5301 this.offset.click.left - /*// Click offset (relative to the element) 5302*/ 5303 this.offset.relative.left - /*// Only for relative positioned nodes: Relative offset from element to offset parent 5304*/ 5305 this.offset.parent.left + /*// The offsetParent's offset without borders (offset + border) 5306*/ 5307 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 5308 ) 5309 }; 5310 5311 }, 5312 5313 _rearrange: function(event, i, a, hardRefresh) { 5314 5315 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)); 5316 5317 //Various things done here to improve the performance: 5318 /*// 1. we create a setTimeout, that calls refreshPositions 5319*/ 5320 /*// 2. on the instance, we have a counter variable, that get's higher after every append 5321*/ 5322 /*// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 5323*/ 5324 /*// 4. this lets only the last addition to the timeout stack through 5325*/ 5326 this.counter = this.counter ? ++this.counter : 1; 5327 var counter = this.counter; 5328 5329 this._delay(function() { 5330 if(counter === this.counter) { 5331 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 5332 } 5333 }); 5334 5335 }, 5336 5337 _clear: function(event, noPropagation) { 5338 5339 this.reverting = false; 5340 /*// We delay all events that have to be triggered to after the point where the placeholder has been removed and 5341*/ 5342 /*// everything else normalized again 5343*/ 5344 var i, 5345 delayedTriggers = []; 5346 5347 /*// We first have to update the dom position of the actual currentItem 5348*/ 5349 /*// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 5350*/ 5351 if(!this._noFinalSort && this.currentItem.parent().length) { 5352 this.placeholder.before(this.currentItem); 5353 } 5354 this._noFinalSort = null; 5355 5356 if(this.helper[0] === this.currentItem[0]) { 5357 for(i in this._storedCSS) { 5358 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 5359 this._storedCSS[i] = ""; 5360 } 5361 } 5362 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 5363 } else { 5364 this.currentItem.show(); 5365 } 5366 5367 if(this.fromOutside && !noPropagation) { 5368 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 5369 } 5370 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 5371 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 5372 } 5373 5374 /*// Check if the items Container has Changed and trigger appropriate 5375*/ 5376 /*// events. 5377*/ 5378 if (this !== this.currentContainer) { 5379 if(!noPropagation) { 5380 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 5381 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5382 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 5383 } 5384 } 5385 5386 5387 //Post events to containers 5388 for (i = this.containers.length - 1; i >= 0; i--){ 5389 if(!noPropagation) { 5390 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 5391 } 5392 if(this.containers[i].containerCache.over) { 5393 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 5394 this.containers[i].containerCache.over = 0; 5395 } 5396 } 5397 5398 //Do what was originally in plugins 5399 if ( this.storedCursor ) { 5400 this.document.find( "body" ).css( "cursor", this.storedCursor ); 5401 this.storedStylesheet.remove(); 5402 } 5403 if(this._storedOpacity) { 5404 this.helper.css("opacity", this._storedOpacity); 5405 } 5406 if(this._storedZIndex) { 5407 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 5408 } 5409 5410 this.dragging = false; 5411 if(this.cancelHelperRemoval) { 5412 if(!noPropagation) { 5413 this._trigger("beforeStop", event, this._uiHash()); 5414 for (i=0; i < delayedTriggers.length; i++) { 5415 delayedTriggers[i].call(this, event); 5416 } //Trigger all delayed events 5417 this._trigger("stop", event, this._uiHash()); 5418 } 5419 5420 this.fromOutside = false; 5421 return false; 5422 } 5423 5424 if(!noPropagation) { 5425 this._trigger("beforeStop", event, this._uiHash()); 5426 } 5427 5428 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 5429 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 5430 5431 if(this.helper[0] !== this.currentItem[0]) { 5432 this.helper.remove(); 5433 } 5434 this.helper = null; 5435 5436 if(!noPropagation) { 5437 for (i=0; i < delayedTriggers.length; i++) { 5438 delayedTriggers[i].call(this, event); 5439 } //Trigger all delayed events 5440 this._trigger("stop", event, this._uiHash()); 5441 } 5442 5443 this.fromOutside = false; 5444 return true; 5445 5446 }, 5447 5448 _trigger: function() { 5449 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 5450 this.cancel(); 5451 } 5452 }, 5453 5454 _uiHash: function(_inst) { 5455 var inst = _inst || this; 5456 return { 5457 helper: inst.helper, 5458 placeholder: inst.placeholder || $([]), 5459 position: inst.position, 5460 originalPosition: inst.originalPosition, 5461 offset: inst.positionAbs, 5462 item: inst.currentItem, 5463 sender: _inst ? _inst.element : null 5464 }; 5465 } 5466 5467}); 5468 5469})(jQuery); 5470(function( $, undefined ) { 5471 5472var uid = 0, 5473 hideProps = {}, 5474 showProps = {}; 5475 5476hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 5477 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 5478showProps.height = showProps.paddingTop = showProps.paddingBottom = 5479 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 5480 5481$.widget( "ui.accordion", { 5482 version: "1.10.2", 5483 options: { 5484 active: 0, 5485 animate: {}, 5486 collapsible: false, 5487 event: "click", 5488 header: "> li > :first-child,> :not(li):even", 5489 heightStyle: "auto", 5490 icons: { 5491 activeHeader: "ui-icon-triangle-1-s", 5492 header: "ui-icon-triangle-1-e" 5493 }, 5494 5495 /*// callbacks 5496*/ 5497 activate: null, 5498 beforeActivate: null 5499 }, 5500 5501 _create: function() { 5502 var options = this.options; 5503 this.prevShow = this.prevHide = $(); 5504 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 5505 /*// ARIA 5506*/ 5507 .attr( "role", "tablist" ); 5508 5509 /*// don't allow collapsible: false and active: false / null 5510*/ 5511 if ( !options.collapsible && (options.active === false || options.active == null) ) { 5512 options.active = 0; 5513 } 5514 5515 this._processPanels(); 5516 /*// handle negative values 5517*/ 5518 if ( options.active < 0 ) { 5519 options.active += this.headers.length; 5520 } 5521 this._refresh(); 5522 }, 5523 5524 _getCreateEventData: function() { 5525 return { 5526 header: this.active, 5527 panel: !this.active.length ? $() : this.active.next(), 5528 content: !this.active.length ? $() : this.active.next() 5529 }; 5530 }, 5531 5532 _createIcons: function() { 5533 var icons = this.options.icons; 5534 if ( icons ) { 5535 $( "<span>" ) 5536 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 5537 .prependTo( this.headers ); 5538 this.active.children( ".ui-accordion-header-icon" ) 5539 .removeClass( icons.header ) 5540 .addClass( icons.activeHeader ); 5541 this.headers.addClass( "ui-accordion-icons" ); 5542 } 5543 }, 5544 5545 _destroyIcons: function() { 5546 this.headers 5547 .removeClass( "ui-accordion-icons" ) 5548 .children( ".ui-accordion-header-icon" ) 5549 .remove(); 5550 }, 5551 5552 _destroy: function() { 5553 var contents; 5554 5555 /*// clean up main element 5556*/ 5557 this.element 5558 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 5559 .removeAttr( "role" ); 5560 5561 /*// clean up headers 5562*/ 5563 this.headers 5564 .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" ) 5565 .removeAttr( "role" ) 5566 .removeAttr( "aria-selected" ) 5567 .removeAttr( "aria-controls" ) 5568 .removeAttr( "tabIndex" ) 5569 .each(function() { 5570 if ( /^ui-accordion/.test( this.id ) ) { 5571 this.removeAttribute( "id" ); 5572 } 5573 }); 5574 this._destroyIcons(); 5575 5576 /*// clean up content panels 5577*/ 5578 contents = this.headers.next() 5579 .css( "display", "" ) 5580 .removeAttr( "role" ) 5581 .removeAttr( "aria-expanded" ) 5582 .removeAttr( "aria-hidden" ) 5583 .removeAttr( "aria-labelledby" ) 5584 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 5585 .each(function() { 5586 if ( /^ui-accordion/.test( this.id ) ) { 5587 this.removeAttribute( "id" ); 5588 } 5589 }); 5590 if ( this.options.heightStyle !== "content" ) { 5591 contents.css( "height", "" ); 5592 } 5593 }, 5594 5595 _setOption: function( key, value ) { 5596 if ( key === "active" ) { 5597 /*// _activate() will handle invalid values and update this.options 5598*/ 5599 this._activate( value ); 5600 return; 5601 } 5602 5603 if ( key === "event" ) { 5604 if ( this.options.event ) { 5605 this._off( this.headers, this.options.event ); 5606 } 5607 this._setupEvents( value ); 5608 } 5609 5610 this._super( key, value ); 5611 5612 /*// setting collapsible: false while collapsed; open first panel 5613*/ 5614 if ( key === "collapsible" && !value && this.options.active === false ) { 5615 this._activate( 0 ); 5616 } 5617 5618 if ( key === "icons" ) { 5619 this._destroyIcons(); 5620 if ( value ) { 5621 this._createIcons(); 5622 } 5623 } 5624 5625 /*// #5332 - opacity doesn't cascade to positioned elements in IE 5626*/ 5627 /*// so we need to add the disabled class to the headers and panels 5628*/ 5629 if ( key === "disabled" ) { 5630 this.headers.add( this.headers.next() ) 5631 .toggleClass( "ui-state-disabled", !!value ); 5632 } 5633 }, 5634 5635 _keydown: function( event ) { 5636 /*jshint maxcomplexity:15*/ 5637 if ( event.altKey || event.ctrlKey ) { 5638 return; 5639 } 5640 5641 var keyCode = $.ui.keyCode, 5642 length = this.headers.length, 5643 currentIndex = this.headers.index( event.target ), 5644 toFocus = false; 5645 5646 switch ( event.keyCode ) { 5647 case keyCode.RIGHT: 5648 case keyCode.DOWN: 5649 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5650 break; 5651 case keyCode.LEFT: 5652 case keyCode.UP: 5653 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5654 break; 5655 case keyCode.SPACE: 5656 case keyCode.ENTER: 5657 this._eventHandler( event ); 5658 break; 5659 case keyCode.HOME: 5660 toFocus = this.headers[ 0 ]; 5661 break; 5662 case keyCode.END: 5663 toFocus = this.headers[ length - 1 ]; 5664 break; 5665 } 5666 5667 if ( toFocus ) { 5668 $( event.target ).attr( "tabIndex", -1 ); 5669 $( toFocus ).attr( "tabIndex", 0 ); 5670 toFocus.focus(); 5671 event.preventDefault(); 5672 } 5673 }, 5674 5675 _panelKeyDown : function( event ) { 5676 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5677 $( event.currentTarget ).prev().focus(); 5678 } 5679 }, 5680 5681 refresh: function() { 5682 var options = this.options; 5683 this._processPanels(); 5684 5685 /*// was collapsed or no panel 5686*/ 5687 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 5688 options.active = false; 5689 this.active = $(); 5690 /*// active false only when collapsible is true 5691*/ 5692 } if ( options.active === false ) { 5693 this._activate( 0 ); 5694 /*// was active, but active panel is gone 5695*/ 5696 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5697 /*// all remaining panel are disabled 5698*/ 5699 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 5700 options.active = false; 5701 this.active = $(); 5702 /*// activate previous panel 5703*/ 5704 } else { 5705 this._activate( Math.max( 0, options.active - 1 ) ); 5706 } 5707 /*// was active, active panel still exists 5708*/ 5709 } else { 5710 /*// make sure active index is correct 5711*/ 5712 options.active = this.headers.index( this.active ); 5713 } 5714 5715 this._destroyIcons(); 5716 5717 this._refresh(); 5718 }, 5719 5720 _processPanels: function() { 5721 this.headers = this.element.find( this.options.header ) 5722 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 5723 5724 this.headers.next() 5725 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 5726 .filter(":not(.ui-accordion-content-active)") 5727 .hide(); 5728 }, 5729 5730 _refresh: function() { 5731 var maxHeight, 5732 options = this.options, 5733 heightStyle = options.heightStyle, 5734 parent = this.element.parent(), 5735 accordionId = this.accordionId = "ui-accordion-" + 5736 (this.element.attr( "id" ) || ++uid); 5737 5738 this.active = this._findActive( options.active ) 5739 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 5740 .removeClass( "ui-corner-all" ); 5741 this.active.next() 5742 .addClass( "ui-accordion-content-active" ) 5743 .show(); 5744 5745 this.headers 5746 .attr( "role", "tab" ) 5747 .each(function( i ) { 5748 var header = $( this ), 5749 headerId = header.attr( "id" ), 5750 panel = header.next(), 5751 panelId = panel.attr( "id" ); 5752 if ( !headerId ) { 5753 headerId = accordionId + "-header-" + i; 5754 header.attr( "id", headerId ); 5755 } 5756 if ( !panelId ) { 5757 panelId = accordionId + "-panel-" + i; 5758 panel.attr( "id", panelId ); 5759 } 5760 header.attr( "aria-controls", panelId ); 5761 panel.attr( "aria-labelledby", headerId ); 5762 }) 5763 .next() 5764 .attr( "role", "tabpanel" ); 5765 5766 this.headers 5767 .not( this.active ) 5768 .attr({ 5769 "aria-selected": "false", 5770 tabIndex: -1 5771 }) 5772 .next() 5773 .attr({ 5774 "aria-expanded": "false", 5775 "aria-hidden": "true" 5776 }) 5777 .hide(); 5778 5779 /*// make sure at least one header is in the tab order 5780*/ 5781 if ( !this.active.length ) { 5782 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5783 } else { 5784 this.active.attr({ 5785 "aria-selected": "true", 5786 tabIndex: 0 5787 }) 5788 .next() 5789 .attr({ 5790 "aria-expanded": "true", 5791 "aria-hidden": "false" 5792 }); 5793 } 5794 5795 this._createIcons(); 5796 5797 this._setupEvents( options.event ); 5798 5799 if ( heightStyle === "fill" ) { 5800 maxHeight = parent.height(); 5801 this.element.siblings( ":visible" ).each(function() { 5802 var elem = $( this ), 5803 position = elem.css( "position" ); 5804 5805 if ( position === "absolute" || position === "fixed" ) { 5806 return; 5807 } 5808 maxHeight -= elem.outerHeight( true ); 5809 }); 5810 5811 this.headers.each(function() { 5812 maxHeight -= $( this ).outerHeight( true ); 5813 }); 5814 5815 this.headers.next() 5816 .each(function() { 5817 $( this ).height( Math.max( 0, maxHeight - 5818 $( this ).innerHeight() + $( this ).height() ) ); 5819 }) 5820 .css( "overflow", "auto" ); 5821 } else if ( heightStyle === "auto" ) { 5822 maxHeight = 0; 5823 this.headers.next() 5824 .each(function() { 5825 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5826 }) 5827 .height( maxHeight ); 5828 } 5829 }, 5830 5831 _activate: function( index ) { 5832 var active = this._findActive( index )[ 0 ]; 5833 5834 /*// trying to activate the already active panel 5835*/ 5836 if ( active === this.active[ 0 ] ) { 5837 return; 5838 } 5839 5840 /*// trying to collapse, simulate a click on the currently active header 5841*/ 5842 active = active || this.active[ 0 ]; 5843 5844 this._eventHandler({ 5845 target: active, 5846 currentTarget: active, 5847 preventDefault: $.noop 5848 }); 5849 }, 5850 5851 _findActive: function( selector ) { 5852 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5853 }, 5854 5855 _setupEvents: function( event ) { 5856 var events = { 5857 keydown: "_keydown" 5858 }; 5859 if ( event ) { 5860 $.each( event.split(" "), function( index, eventName ) { 5861 events[ eventName ] = "_eventHandler"; 5862 }); 5863 } 5864 5865 this._off( this.headers.add( this.headers.next() ) ); 5866 this._on( this.headers, events ); 5867 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 5868 this._hoverable( this.headers ); 5869 this._focusable( this.headers ); 5870 }, 5871 5872 _eventHandler: function( event ) { 5873 var options = this.options, 5874 active = this.active, 5875 clicked = $( event.currentTarget ), 5876 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5877 collapsing = clickedIsActive && options.collapsible, 5878 toShow = collapsing ? $() : clicked.next(), 5879 toHide = active.next(), 5880 eventData = { 5881 oldHeader: active, 5882 oldPanel: toHide, 5883 newHeader: collapsing ? $() : clicked, 5884 newPanel: toShow 5885 }; 5886 5887 event.preventDefault(); 5888 5889 if ( 5890 /*// click on active header, but not collapsible 5891*/ 5892 ( clickedIsActive && !options.collapsible ) || 5893 /*// allow canceling activation 5894*/ 5895 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5896 return; 5897 } 5898 5899 options.active = collapsing ? false : this.headers.index( clicked ); 5900 5901 /*// when the call to ._toggle() comes after the class changes 5902*/ 5903 /*// it causes a very odd bug in IE 8 (see #6720) 5904*/ 5905 this.active = clickedIsActive ? $() : clicked; 5906 this._toggle( eventData ); 5907 5908 /*// switch classes 5909*/ 5910 /*// corner classes on the previously active header stay after the animation 5911*/ 5912 active.removeClass( "ui-accordion-header-active ui-state-active" ); 5913 if ( options.icons ) { 5914 active.children( ".ui-accordion-header-icon" ) 5915 .removeClass( options.icons.activeHeader ) 5916 .addClass( options.icons.header ); 5917 } 5918 5919 if ( !clickedIsActive ) { 5920 clicked 5921 .removeClass( "ui-corner-all" ) 5922 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 5923 if ( options.icons ) { 5924 clicked.children( ".ui-accordion-header-icon" ) 5925 .removeClass( options.icons.header ) 5926 .addClass( options.icons.activeHeader ); 5927 } 5928 5929 clicked 5930 .next() 5931 .addClass( "ui-accordion-content-active" ); 5932 } 5933 }, 5934 5935 _toggle: function( data ) { 5936 var toShow = data.newPanel, 5937 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5938 5939 /*// handle activating a panel during the animation for another activation 5940*/ 5941 this.prevShow.add( this.prevHide ).stop( true, true ); 5942 this.prevShow = toShow; 5943 this.prevHide = toHide; 5944 5945 if ( this.options.animate ) { 5946 this._animate( toShow, toHide, data ); 5947 } else { 5948 toHide.hide(); 5949 toShow.show(); 5950 this._toggleComplete( data ); 5951 } 5952 5953 toHide.attr({ 5954 "aria-expanded": "false", 5955 "aria-hidden": "true" 5956 }); 5957 toHide.prev().attr( "aria-selected", "false" ); 5958 /*// if we're switching panels, remove the old header from the tab order 5959*/ 5960 /*// if we're opening from collapsed state, remove the previous header from the tab order 5961*/ 5962 /*// if we're collapsing, then keep the collapsing header in the tab order 5963*/ 5964 if ( toShow.length && toHide.length ) { 5965 toHide.prev().attr( "tabIndex", -1 ); 5966 } else if ( toShow.length ) { 5967 this.headers.filter(function() { 5968 return $( this ).attr( "tabIndex" ) === 0; 5969 }) 5970 .attr( "tabIndex", -1 ); 5971 } 5972 5973 toShow 5974 .attr({ 5975 "aria-expanded": "true", 5976 "aria-hidden": "false" 5977 }) 5978 .prev() 5979 .attr({ 5980 "aria-selected": "true", 5981 tabIndex: 0 5982 }); 5983 }, 5984 5985 _animate: function( toShow, toHide, data ) { 5986 var total, easing, duration, 5987 that = this, 5988 adjust = 0, 5989 down = toShow.length && 5990 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5991 animate = this.options.animate || {}, 5992 options = down && animate.down || animate, 5993 complete = function() { 5994 that._toggleComplete( data ); 5995 }; 5996 5997 if ( typeof options === "number" ) { 5998 duration = options; 5999 } 6000 if ( typeof options === "string" ) { 6001 easing = options; 6002 } 6003 /*// fall back from options to animation in case of partial down settings 6004*/ 6005 easing = easing || options.easing || animate.easing; 6006 duration = duration || options.duration || animate.duration; 6007 6008 if ( !toHide.length ) { 6009 return toShow.animate( showProps, duration, easing, complete ); 6010 } 6011 if ( !toShow.length ) { 6012 return toHide.animate( hideProps, duration, easing, complete ); 6013 } 6014 6015 total = toShow.show().outerHeight(); 6016 toHide.animate( hideProps, { 6017 duration: duration, 6018 easing: easing, 6019 step: function( now, fx ) { 6020 fx.now = Math.round( now ); 6021 } 6022 }); 6023 toShow 6024 .hide() 6025 .animate( showProps, { 6026 duration: duration, 6027 easing: easing, 6028 complete: complete, 6029 step: function( now, fx ) { 6030 fx.now = Math.round( now ); 6031 if ( fx.prop !== "height" ) { 6032 adjust += fx.now; 6033 } else if ( that.options.heightStyle !== "content" ) { 6034 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6035 adjust = 0; 6036 } 6037 } 6038 }); 6039 }, 6040 6041 _toggleComplete: function( data ) { 6042 var toHide = data.oldPanel; 6043 6044 toHide 6045 .removeClass( "ui-accordion-content-active" ) 6046 .prev() 6047 .removeClass( "ui-corner-top" ) 6048 .addClass( "ui-corner-all" ); 6049 6050 /*// Work around for rendering bug in IE (#5421) 6051*/ 6052 if ( toHide.length ) { 6053 toHide.parent()[0].className = toHide.parent()[0].className; 6054 } 6055 6056 this._trigger( "activate", null, data ); 6057 } 6058}); 6059 6060})( jQuery ); 6061(function( $, undefined ) { 6062 6063/*// used to prevent race conditions with remote data sources 6064*/ 6065var requestIndex = 0; 6066 6067$.widget( "ui.autocomplete", { 6068 version: "1.10.2", 6069 defaultElement: "<input>", 6070 options: { 6071 appendTo: null, 6072 autoFocus: false, 6073 delay: 300, 6074 minLength: 1, 6075 position: { 6076 my: "left top", 6077 at: "left bottom", 6078 collision: "none" 6079 }, 6080 source: null, 6081 6082 /*// callbacks 6083*/ 6084 change: null, 6085 close: null, 6086 focus: null, 6087 open: null, 6088 response: null, 6089 search: null, 6090 select: null 6091 }, 6092 6093 pending: 0, 6094 6095 _create: function() { 6096 /*// Some browsers only repeat keydown events, not keypress events, 6097*/ 6098 /*// so we use the suppressKeyPress flag to determine if we've already 6099*/ 6100 /*// handled the keydown event. #7269 6101*/ 6102 /*// Unfortunately the code for & in keypress is the same as the up arrow, 6103*/ 6104 /*// so we use the suppressKeyPressRepeat flag to avoid handling keypress 6105*/ 6106 /*// events when we know the keydown event was used to modify the 6107*/ 6108 /*// search term. #7799 6109*/ 6110 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6111 nodeName = this.element[0].nodeName.toLowerCase(), 6112 isTextarea = nodeName === "textarea", 6113 isInput = nodeName === "input"; 6114 6115 this.isMultiLine = 6116 /*// Textareas are always multi-line 6117*/ 6118 isTextarea ? true : 6119 /*// Inputs are always single-line, even if inside a contentEditable element 6120*/ 6121 /*// IE also treats inputs as contentEditable 6122*/ 6123 isInput ? false : 6124 /*// All other element types are determined by whether or not they're contentEditable 6125*/ 6126 this.element.prop( "isContentEditable" ); 6127 6128 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6129 this.isNewMenu = true; 6130 6131 this.element 6132 .addClass( "ui-autocomplete-input" ) 6133 .attr( "autocomplete", "off" ); 6134 6135 this._on( this.element, { 6136 keydown: function( event ) { 6137 /*jshint maxcomplexity:15*/ 6138 if ( this.element.prop( "readOnly" ) ) { 6139 suppressKeyPress = true; 6140 suppressInput = true; 6141 suppressKeyPressRepeat = true; 6142 return; 6143 } 6144 6145 suppressKeyPress = false; 6146 suppressInput = false; 6147 suppressKeyPressRepeat = false; 6148 var keyCode = $.ui.keyCode; 6149 switch( event.keyCode ) { 6150 case keyCode.PAGE_UP: 6151 suppressKeyPress = true; 6152 this._move( "previousPage", event ); 6153 break; 6154 case keyCode.PAGE_DOWN: 6155 suppressKeyPress = true; 6156 this._move( "nextPage", event ); 6157 break; 6158 case keyCode.UP: 6159 suppressKeyPress = true; 6160 this._keyEvent( "previous", event ); 6161 break; 6162 case keyCode.DOWN: 6163 suppressKeyPress = true; 6164 this._keyEvent( "next", event ); 6165 break; 6166 case keyCode.ENTER: 6167 case keyCode.NUMPAD_ENTER: 6168 /*// when menu is open and has focus 6169*/ 6170 if ( this.menu.active ) { 6171 /*// #6055 - Opera still allows the keypress to occur 6172*/ 6173 /*// which causes forms to submit 6174*/ 6175 suppressKeyPress = true; 6176 event.preventDefault(); 6177 this.menu.select( event ); 6178 } 6179 break; 6180 case keyCode.TAB: 6181 if ( this.menu.active ) { 6182 this.menu.select( event ); 6183 } 6184 break; 6185 case keyCode.ESCAPE: 6186 if ( this.menu.element.is( ":visible" ) ) { 6187 this._value( this.term ); 6188 this.close( event ); 6189 /*// Different browsers have different default behavior for escape 6190*/ 6191 /*// Single press can mean undo or clear 6192*/ 6193 /*// Double press in IE means clear the whole form 6194*/ 6195 event.preventDefault(); 6196 } 6197 break; 6198 default: 6199 suppressKeyPressRepeat = true; 6200 /*// search timeout should be triggered before the input value is changed 6201*/ 6202 this._searchTimeout( event ); 6203 break; 6204 } 6205 }, 6206 keypress: function( event ) { 6207 if ( suppressKeyPress ) { 6208 suppressKeyPress = false; 6209 event.preventDefault(); 6210 return; 6211 } 6212 if ( suppressKeyPressRepeat ) { 6213 return; 6214 } 6215 6216 /*// replicate some key handlers to allow them to repeat in Firefox and Opera 6217*/ 6218 var keyCode = $.ui.keyCode; 6219 switch( event.keyCode ) { 6220 case keyCode.PAGE_UP: 6221 this._move( "previousPage", event ); 6222 break; 6223 case keyCode.PAGE_DOWN: 6224 this._move( "nextPage", event ); 6225 break; 6226 case keyCode.UP: 6227 this._keyEvent( "previous", event ); 6228 break; 6229 case keyCode.DOWN: 6230 this._keyEvent( "next", event ); 6231 break; 6232 } 6233 }, 6234 input: function( event ) { 6235 if ( suppressInput ) { 6236 suppressInput = false; 6237 event.preventDefault(); 6238 return; 6239 } 6240 this._searchTimeout( event ); 6241 }, 6242 focus: function() { 6243 this.selectedItem = null; 6244 this.previous = this._value(); 6245 }, 6246 blur: function( event ) { 6247 if ( this.cancelBlur ) { 6248 delete this.cancelBlur; 6249 return; 6250 } 6251 6252 clearTimeout( this.searching ); 6253 this.close( event ); 6254 this._change( event ); 6255 } 6256 }); 6257 6258 this._initSource(); 6259 this.menu = $( "<ul>" ) 6260 .addClass( "ui-autocomplete ui-front" ) 6261 .appendTo( this._appendTo() ) 6262 .menu({ 6263 /*// custom key handling for now 6264*/ 6265 input: $(), 6266 /*// disable ARIA support, the live region takes care of that 6267*/ 6268 role: null 6269 }) 6270 .hide() 6271 .data( "ui-menu" ); 6272 6273 this._on( this.menu.element, { 6274 mousedown: function( event ) { 6275 /*// prevent moving focus out of the text field 6276*/ 6277 event.preventDefault(); 6278 6279 /*// IE doesn't prevent moving focus even with event.preventDefault() 6280*/ 6281 /*// so we set a flag to know when we should ignore the blur event 6282*/ 6283 this.cancelBlur = true; 6284 this._delay(function() { 6285 delete this.cancelBlur; 6286 }); 6287 6288 /*// clicking on the scrollbar causes focus to shift to the body 6289*/ 6290 /*// but we can't detect a mouseup or a click immediately afterward 6291*/ 6292 /*// so we have to track the next mousedown and close the menu if 6293*/ 6294 /*// the user clicks somewhere outside of the autocomplete 6295*/ 6296 var menuElement = this.menu.element[ 0 ]; 6297 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6298 this._delay(function() { 6299 var that = this; 6300 this.document.one( "mousedown", function( event ) { 6301 if ( event.target !== that.element[ 0 ] && 6302 event.target !== menuElement && 6303 !$.contains( menuElement, event.target ) ) { 6304 that.close(); 6305 } 6306 }); 6307 }); 6308 } 6309 }, 6310 menufocus: function( event, ui ) { 6311 /*// support: Firefox 6312*/ 6313 /*// Prevent accidental activation of menu items in Firefox (#7024 #9118) 6314*/ 6315 if ( this.isNewMenu ) { 6316 this.isNewMenu = false; 6317 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6318 this.menu.blur(); 6319 6320 this.document.one( "mousemove", function() { 6321 $( event.target ).trigger( event.originalEvent ); 6322 }); 6323 6324 return; 6325 } 6326 } 6327 6328 var item = ui.item.data( "ui-autocomplete-item" ); 6329 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6330 /*// use value to match what will end up in the input, if it was a key event 6331*/ 6332 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6333 this._value( item.value ); 6334 } 6335 } else { 6336 /*// Normally the input is populated with the item's value as the 6337*/ 6338 /*// menu is navigated, causing screen readers to notice a change and 6339*/ 6340 /*// announce the item. Since the focus event was canceled, this doesn't 6341*/ 6342 /*// happen, so we update the live region so that screen readers can 6343*/ 6344 /*// still notice the change and announce it. 6345*/ 6346 this.liveRegion.text( item.value ); 6347 } 6348 }, 6349 menuselect: function( event, ui ) { 6350 var item = ui.item.data( "ui-autocomplete-item" ), 6351 previous = this.previous; 6352 6353 /*// only trigger when focus was lost (click on menu) 6354*/ 6355 if ( this.element[0] !== this.document[0].activeElement ) { 6356 this.element.focus(); 6357 this.previous = previous; 6358 /*// #6109 - IE triggers two focus events and the second 6359*/ 6360 /*// is asynchronous, so we need to reset the previous 6361*/ 6362 /*// term synchronously and asynchronously :-( 6363*/ 6364 this._delay(function() { 6365 this.previous = previous; 6366 this.selectedItem = item; 6367 }); 6368 } 6369 6370 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6371 this._value( item.value ); 6372 } 6373 /*// reset the term after the select event 6374*/ 6375 /*// this allows custom select handling to work properly 6376*/ 6377 this.term = this._value(); 6378 6379 this.close( event ); 6380 this.selectedItem = item; 6381 } 6382 }); 6383 6384 this.liveRegion = $( "<span>", { 6385 role: "status", 6386 "aria-live": "polite" 6387 }) 6388 .addClass( "ui-helper-hidden-accessible" ) 6389 .insertBefore( this.element ); 6390 6391 /*// turning off autocomplete prevents the browser from remembering the 6392*/ 6393 /*// value when navigating through history, so we re-enable autocomplete 6394*/ 6395 /*// if the page is unloaded before the widget is destroyed. #7790 6396*/ 6397 this._on( this.window, { 6398 beforeunload: function() { 6399 this.element.removeAttr( "autocomplete" ); 6400 } 6401 }); 6402 }, 6403 6404 _destroy: function() { 6405 clearTimeout( this.searching ); 6406 this.element 6407 .removeClass( "ui-autocomplete-input" ) 6408 .removeAttr( "autocomplete" ); 6409 this.menu.element.remove(); 6410 this.liveRegion.remove(); 6411 }, 6412 6413 _setOption: function( key, value ) { 6414 this._super( key, value ); 6415 if ( key === "source" ) { 6416 this._initSource(); 6417 } 6418 if ( key === "appendTo" ) { 6419 this.menu.element.appendTo( this._appendTo() ); 6420 } 6421 if ( key === "disabled" && value && this.xhr ) { 6422 this.xhr.abort(); 6423 } 6424 }, 6425 6426 _appendTo: function() { 6427 var element = this.options.appendTo; 6428 6429 if ( element ) { 6430 element = element.jquery || element.nodeType ? 6431 $( element ) : 6432 this.document.find( element ).eq( 0 ); 6433 } 6434 6435 if ( !element ) { 6436 element = this.element.closest( ".ui-front" ); 6437 } 6438 6439 if ( !element.length ) { 6440 element = this.document[0].body; 6441 } 6442 6443 return element; 6444 }, 6445 6446 _initSource: function() { 6447 var array, url, 6448 that = this; 6449 if ( $.isArray(this.options.source) ) { 6450 array = this.options.source; 6451 this.source = function( request, response ) { 6452 response( $.ui.autocomplete.filter( array, request.term ) ); 6453 }; 6454 } else if ( typeof this.options.source === "string" ) { 6455 url = this.options.source; 6456 this.source = function( request, response ) { 6457 if ( that.xhr ) { 6458 that.xhr.abort(); 6459 } 6460 that.xhr = $.ajax({ 6461 url: url, 6462 data: request, 6463 dataType: "json", 6464 success: function( data ) { 6465 response( data ); 6466 }, 6467 error: function() { 6468 response( [] ); 6469 } 6470 }); 6471 }; 6472 } else { 6473 this.source = this.options.source; 6474 } 6475 }, 6476 6477 _searchTimeout: function( event ) { 6478 clearTimeout( this.searching ); 6479 this.searching = this._delay(function() { 6480 /*// only search if the value has changed 6481*/ 6482 if ( this.term !== this._value() ) { 6483 this.selectedItem = null; 6484 this.search( null, event ); 6485 } 6486 }, this.options.delay ); 6487 }, 6488 6489 search: function( value, event ) { 6490 value = value != null ? value : this._value(); 6491 6492 /*// always save the actual value, not the one passed as an argument 6493*/ 6494 this.term = this._value(); 6495 6496 if ( value.length < this.options.minLength ) { 6497 return this.close( event ); 6498 } 6499 6500 if ( this._trigger( "search", event ) === false ) { 6501 return; 6502 } 6503 6504 return this._search( value ); 6505 }, 6506 6507 _search: function( value ) { 6508 this.pending++; 6509 this.element.addClass( "ui-autocomplete-loading" ); 6510 this.cancelSearch = false; 6511 6512 this.source( { term: value }, this._response() ); 6513 }, 6514 6515 _response: function() { 6516 var that = this, 6517 index = ++requestIndex; 6518 6519 return function( content ) { 6520 if ( index === requestIndex ) { 6521 that.__response( content ); 6522 } 6523 6524 that.pending--; 6525 if ( !that.pending ) { 6526 that.element.removeClass( "ui-autocomplete-loading" ); 6527 } 6528 }; 6529 }, 6530 6531 __response: function( content ) { 6532 if ( content ) { 6533 content = this._normalize( content ); 6534 } 6535 this._trigger( "response", null, { content: content } ); 6536 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6537 this._suggest( content ); 6538 this._trigger( "open" ); 6539 } else { 6540 /*// use ._close() instead of .close() so we don't cancel future searches 6541*/ 6542 this._close(); 6543 } 6544 }, 6545 6546 close: function( event ) { 6547 this.cancelSearch = true; 6548 this._close( event ); 6549 }, 6550 6551 _close: function( event ) { 6552 if ( this.menu.element.is( ":visible" ) ) { 6553 this.menu.element.hide(); 6554 this.menu.blur(); 6555 this.isNewMenu = true; 6556 this._trigger( "close", event ); 6557 } 6558 }, 6559 6560 _change: function( event ) { 6561 if ( this.previous !== this._value() ) { 6562 this._trigger( "change", event, { item: this.selectedItem } ); 6563 } 6564 }, 6565 6566 _normalize: function( items ) { 6567 /*// assume all items have the right format when the first item is complete 6568*/ 6569 if ( items.length && items[0].label && items[0].value ) { 6570 return items; 6571 } 6572 return $.map( items, function( item ) { 6573 if ( typeof item === "string" ) { 6574 return { 6575 label: item, 6576 value: item 6577 }; 6578 } 6579 return $.extend({ 6580 label: item.label || item.value, 6581 value: item.value || item.label 6582 }, item ); 6583 }); 6584 }, 6585 6586 _suggest: function( items ) { 6587 var ul = this.menu.element.empty(); 6588 this._renderMenu( ul, items ); 6589 this.isNewMenu = true; 6590 this.menu.refresh(); 6591 6592 /*// size and position menu 6593*/ 6594 ul.show(); 6595 this._resizeMenu(); 6596 ul.position( $.extend({ 6597 of: this.element 6598 }, this.options.position )); 6599 6600 if ( this.options.autoFocus ) { 6601 this.menu.next(); 6602 } 6603 }, 6604 6605 _resizeMenu: function() { 6606 var ul = this.menu.element; 6607 ul.outerWidth( Math.max( 6608 /*// Firefox wraps long text (possibly a rounding bug) 6609*/ 6610 /*// so we add 1px to avoid the wrapping (#7513) 6611*/ 6612 ul.width( "" ).outerWidth() + 1, 6613 this.element.outerWidth() 6614 ) ); 6615 }, 6616 6617 _renderMenu: function( ul, items ) { 6618 var that = this; 6619 $.each( items, function( index, item ) { 6620 that._renderItemData( ul, item ); 6621 }); 6622 }, 6623 6624 _renderItemData: function( ul, item ) { 6625 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6626 }, 6627 6628 _renderItem: function( ul, item ) { 6629 return $( "<li>" ) 6630 .append( $( "<a>" ).text( item.label ) ) 6631 .appendTo( ul ); 6632 }, 6633 6634 _move: function( direction, event ) { 6635 if ( !this.menu.element.is( ":visible" ) ) { 6636 this.search( null, event ); 6637 return; 6638 } 6639 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6640 this.menu.isLastItem() && /^next/.test( direction ) ) { 6641 this._value( this.term ); 6642 this.menu.blur(); 6643 return; 6644 } 6645 this.menu[ direction ]( event ); 6646 }, 6647 6648 widget: function() { 6649 return this.menu.element; 6650 }, 6651 6652 _value: function() { 6653 return this.valueMethod.apply( this.element, arguments ); 6654 }, 6655 6656 _keyEvent: function( keyEvent, event ) { 6657 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6658 this._move( keyEvent, event ); 6659 6660 /*// prevents moving cursor to beginning/end of the text field in some browsers 6661*/ 6662 event.preventDefault(); 6663 } 6664 } 6665}); 6666 6667$.extend( $.ui.autocomplete, { 6668 escapeRegex: function( value ) { 6669 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 6670 }, 6671 filter: function(array, term) { 6672 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 6673 return $.grep( array, function(value) { 6674 return matcher.test( value.label || value.value || value ); 6675 }); 6676 } 6677}); 6678 6679 6680/*// live region extension, adding a `messages` option 6681*/ 6682/*// NOTE: This is an experimental API. We are still investigating 6683*/ 6684/*// a full solution for string manipulation and internationalization. 6685*/ 6686$.widget( "ui.autocomplete", $.ui.autocomplete, { 6687 options: { 6688 messages: { 6689 noResults: "", 6690 results: function( amount ) { 6691 return amount + ( amount > 1 ? " results are" : " result is" ) + 6692 " available, use up and down arrow keys to navigate."; 6693 } 6694 } 6695 }, 6696 6697 __response: function( content ) { 6698 var message; 6699 this._superApply( arguments ); 6700 if ( this.options.disabled || this.cancelSearch ) { 6701 return; 6702 } 6703 if ( content && content.length ) { 6704 message = this.options.messages.results( content.length ); 6705 } else { 6706 message = this.options.messages.noResults; 6707 } 6708 this.liveRegion.text( message ); 6709 } 6710}); 6711 6712}( jQuery )); 6713(function( $, undefined ) { 6714 6715var lastActive, startXPos, startYPos, clickDragged, 6716 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 6717 stateClasses = "ui-state-hover ui-state-active ", 6718 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", 6719 formResetHandler = function() { 6720 var buttons = $( this ).find( ":ui-button" ); 6721 setTimeout(function() { 6722 buttons.button( "refresh" ); 6723 }, 1 ); 6724 }, 6725 radioGroup = function( radio ) { 6726 var name = radio.name, 6727 form = radio.form, 6728 radios = $( [] ); 6729 if ( name ) { 6730 name = name.replace( /'/g, "\\'" ); 6731 if ( form ) { 6732 radios = $( form ).find( "[name='" + name + "']" ); 6733 } else { 6734 radios = $( "[name='" + name + "']", radio.ownerDocument ) 6735 .filter(function() { 6736 return !this.form; 6737 }); 6738 } 6739 } 6740 return radios; 6741 }; 6742 6743$.widget( "ui.button", { 6744 version: "1.10.2", 6745 defaultElement: "<button>", 6746 options: { 6747 disabled: null, 6748 text: true, 6749 label: null, 6750 icons: { 6751 primary: null, 6752 secondary: null 6753 } 6754 }, 6755 _create: function() { 6756 this.element.closest( "form" ) 6757 .unbind( "reset" + this.eventNamespace ) 6758 .bind( "reset" + this.eventNamespace, formResetHandler ); 6759 6760 if ( typeof this.options.disabled !== "boolean" ) { 6761 this.options.disabled = !!this.element.prop( "disabled" ); 6762 } else { 6763 this.element.prop( "disabled", this.options.disabled ); 6764 } 6765 6766 this._determineButtonType(); 6767 this.hasTitle = !!this.buttonElement.attr( "title" ); 6768 6769 var that = this, 6770 options = this.options, 6771 toggleButton = this.type === "checkbox" || this.type === "radio", 6772 activeClass = !toggleButton ? "ui-state-active" : "", 6773 focusClass = "ui-state-focus"; 6774 6775 if ( options.label === null ) { 6776 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 6777 } 6778 6779 this._hoverable( this.buttonElement ); 6780 6781 this.buttonElement 6782 .addClass( baseClasses ) 6783 .attr( "role", "button" ) 6784 .bind( "mouseenter" + this.eventNamespace, function() { 6785 if ( options.disabled ) { 6786 return; 6787 } 6788 if ( this === lastActive ) { 6789 $( this ).addClass( "ui-state-active" ); 6790 } 6791 }) 6792 .bind( "mouseleave" + this.eventNamespace, function() { 6793 if ( options.disabled ) { 6794 return; 6795 } 6796 $( this ).removeClass( activeClass ); 6797 }) 6798 .bind( "click" + this.eventNamespace, function( event ) { 6799 if ( options.disabled ) { 6800 event.preventDefault(); 6801 event.stopImmediatePropagation(); 6802 } 6803 }); 6804 6805 this.element 6806 .bind( "focus" + this.eventNamespace, function() { 6807 /*// no need to check disabled, focus won't be triggered anyway 6808*/ 6809 that.buttonElement.addClass( focusClass ); 6810 }) 6811 .bind( "blur" + this.eventNamespace, function() { 6812 that.buttonElement.removeClass( focusClass ); 6813 }); 6814 6815 if ( toggleButton ) { 6816 this.element.bind( "change" + this.eventNamespace, function() { 6817 if ( clickDragged ) { 6818 return; 6819 } 6820 that.refresh(); 6821 }); 6822 /*// if mouse moves between mousedown and mouseup (drag) set clickDragged flag 6823*/ 6824 /*// prevents issue where button state changes but checkbox/radio checked state 6825*/ 6826 /*// does not in Firefox (see ticket #6970) 6827*/ 6828 this.buttonElement 6829 .bind( "mousedown" + this.eventNamespace, function( event ) { 6830 if ( options.disabled ) { 6831 return; 6832 } 6833 clickDragged = false; 6834 startXPos = event.pageX; 6835 startYPos = event.pageY; 6836 }) 6837 .bind( "mouseup" + this.eventNamespace, function( event ) { 6838 if ( options.disabled ) { 6839 return; 6840 } 6841 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 6842 clickDragged = true; 6843 } 6844 }); 6845 } 6846 6847 if ( this.type === "checkbox" ) { 6848 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6849 if ( options.disabled || clickDragged ) { 6850 return false; 6851 } 6852 }); 6853 } else if ( this.type === "radio" ) { 6854 this.buttonElement.bind( "click" + this.eventNamespace, function() { 6855 if ( options.disabled || clickDragged ) { 6856 return false; 6857 } 6858 $( this ).addClass( "ui-state-active" ); 6859 that.buttonElement.attr( "aria-pressed", "true" ); 6860 6861 var radio = that.element[ 0 ]; 6862 radioGroup( radio ) 6863 .not( radio ) 6864 .map(function() { 6865 return $( this ).button( "widget" )[ 0 ]; 6866 }) 6867 .removeClass( "ui-state-active" ) 6868 .attr( "aria-pressed", "false" ); 6869 }); 6870 } else { 6871 this.buttonElement 6872 .bind( "mousedown" + this.eventNamespace, function() { 6873 if ( options.disabled ) { 6874 return false; 6875 } 6876 $( this ).addClass( "ui-state-active" ); 6877 lastActive = this; 6878 that.document.one( "mouseup", function() { 6879 lastActive = null; 6880 }); 6881 }) 6882 .bind( "mouseup" + this.eventNamespace, function() { 6883 if ( options.disabled ) { 6884 return false; 6885 } 6886 $( this ).removeClass( "ui-state-active" ); 6887 }) 6888 .bind( "keydown" + this.eventNamespace, function(event) { 6889 if ( options.disabled ) { 6890 return false; 6891 } 6892 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 6893 $( this ).addClass( "ui-state-active" ); 6894 } 6895 }) 6896 /*// see #8559, we bind to blur here in case the button element loses 6897*/ 6898 /*// focus between keydown and keyup, it would be left in an "active" state 6899*/ 6900 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 6901 $( this ).removeClass( "ui-state-active" ); 6902 }); 6903 6904 if ( this.buttonElement.is("a") ) { 6905 this.buttonElement.keyup(function(event) { 6906 if ( event.keyCode === $.ui.keyCode.SPACE ) { 6907 /*// TODO pass through original event correctly (just as 2nd argument doesn't work) 6908*/ 6909 $( this ).click(); 6910 } 6911 }); 6912 } 6913 } 6914 6915 /*// TODO: pull out $.Widget's handling for the disabled option into 6916*/ 6917 /*// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 6918*/ 6919 /*// be overridden by individual plugins 6920*/ 6921 this._setOption( "disabled", options.disabled ); 6922 this._resetButton(); 6923 }, 6924 6925 _determineButtonType: function() { 6926 var ancestor, labelSelector, checked; 6927 6928 if ( this.element.is("[type=checkbox]") ) { 6929 this.type = "checkbox"; 6930 } else if ( this.element.is("[type=radio]") ) { 6931 this.type = "radio"; 6932 } else if ( this.element.is("input") ) { 6933 this.type = "input"; 6934 } else { 6935 this.type = "button"; 6936 } 6937 6938 if ( this.type === "checkbox" || this.type === "radio" ) { 6939 /*// we don't search against the document in case the element 6940*/ 6941 /*// is disconnected from the DOM 6942*/ 6943 ancestor = this.element.parents().last(); 6944 labelSelector = "label[for='" + this.element.attr("id") + "']"; 6945 this.buttonElement = ancestor.find( labelSelector ); 6946 if ( !this.buttonElement.length ) { 6947 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 6948 this.buttonElement = ancestor.filter( labelSelector ); 6949 if ( !this.buttonElement.length ) { 6950 this.buttonElement = ancestor.find( labelSelector ); 6951 } 6952 } 6953 this.element.addClass( "ui-helper-hidden-accessible" ); 6954 6955 checked = this.element.is( ":checked" ); 6956 if ( checked ) { 6957 this.buttonElement.addClass( "ui-state-active" ); 6958 } 6959 this.buttonElement.prop( "aria-pressed", checked ); 6960 } else { 6961 this.buttonElement = this.element; 6962 } 6963 }, 6964 6965 widget: function() { 6966 return this.buttonElement; 6967 }, 6968 6969 _destroy: function() { 6970 this.element 6971 .removeClass( "ui-helper-hidden-accessible" ); 6972 this.buttonElement 6973 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 6974 .removeAttr( "role" ) 6975 .removeAttr( "aria-pressed" ) 6976 .html( this.buttonElement.find(".ui-button-text").html() ); 6977 6978 if ( !this.hasTitle ) { 6979 this.buttonElement.removeAttr( "title" ); 6980 } 6981 }, 6982 6983 _setOption: function( key, value ) { 6984 this._super( key, value ); 6985 if ( key === "disabled" ) { 6986 if ( value ) { 6987 this.element.prop( "disabled", true ); 6988 } else { 6989 this.element.prop( "disabled", false ); 6990 } 6991 return; 6992 } 6993 this._resetButton(); 6994 }, 6995 6996 refresh: function() { 6997 //See #8237 & #8828 6998 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 6999 7000 if ( isDisabled !== this.options.disabled ) { 7001 this._setOption( "disabled", isDisabled ); 7002 } 7003 if ( this.type === "radio" ) { 7004 radioGroup( this.element[0] ).each(function() { 7005 if ( $( this ).is( ":checked" ) ) { 7006 $( this ).button( "widget" ) 7007 .addClass( "ui-state-active" ) 7008 .attr( "aria-pressed", "true" ); 7009 } else { 7010 $( this ).button( "widget" ) 7011 .removeClass( "ui-state-active" ) 7012 .attr( "aria-pressed", "false" ); 7013 } 7014 }); 7015 } else if ( this.type === "checkbox" ) { 7016 if ( this.element.is( ":checked" ) ) { 7017 this.buttonElement 7018 .addClass( "ui-state-active" ) 7019 .attr( "aria-pressed", "true" ); 7020 } else { 7021 this.buttonElement 7022 .removeClass( "ui-state-active" ) 7023 .attr( "aria-pressed", "false" ); 7024 } 7025 } 7026 }, 7027 7028 _resetButton: function() { 7029 if ( this.type === "input" ) { 7030 if ( this.options.label ) { 7031 this.element.val( this.options.label ); 7032 } 7033 return; 7034 } 7035 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7036 buttonText = $( "<span></span>", this.document[0] ) 7037 .addClass( "ui-button-text" ) 7038 .html( this.options.label ) 7039 .appendTo( buttonElement.empty() ) 7040 .text(), 7041 icons = this.options.icons, 7042 multipleIcons = icons.primary && icons.secondary, 7043 buttonClasses = []; 7044 7045 if ( icons.primary || icons.secondary ) { 7046 if ( this.options.text ) { 7047 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7048 } 7049 7050 if ( icons.primary ) { 7051 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7052 } 7053 7054 if ( icons.secondary ) { 7055 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7056 } 7057 7058 if ( !this.options.text ) { 7059 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7060 7061 if ( !this.hasTitle ) { 7062 buttonElement.attr( "title", $.trim( buttonText ) ); 7063 } 7064 } 7065 } else { 7066 buttonClasses.push( "ui-button-text-only" ); 7067 } 7068 buttonElement.addClass( buttonClasses.join( " " ) ); 7069 } 7070}); 7071 7072$.widget( "ui.buttonset", { 7073 version: "1.10.2", 7074 options: { 7075 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7076 }, 7077 7078 _create: function() { 7079 this.element.addClass( "ui-buttonset" ); 7080 }, 7081 7082 _init: function() { 7083 this.refresh();
vendor: 4,314 bytes, lines 7084-7205
7084 }, 7085 7086 _setOption: function( key, value ) { 7087 if ( key === "disabled" ) { 7088 this.buttons.button( "option", key, value ); 7089 } 7090 7091 this._super( key, value ); 7092 }, 7093 7094 refresh: function() { 7095 var rtl = this.element.css( "direction" ) === "rtl"; 7096 7097 this.buttons = this.element.find( this.options.items ) 7098 .filter( ":ui-button" ) 7099 .button( "refresh" ) 7100 .end() 7101 .not( ":ui-button" ) 7102 .button() 7103 .end() 7104 .map(function() { 7105 return $( this ).button( "widget" )[ 0 ]; 7106 }) 7107 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7108 .filter( ":first" ) 7109 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7110 .end() 7111 .filter( ":last" ) 7112 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7113 .end() 7114 .end(); 7115 }, 7116 7117 _destroy: function() { 7118 this.element.removeClass( "ui-buttonset" ); 7119 this.buttons 7120 .map(function() { 7121 return $( this ).button( "widget" )[ 0 ]; 7122 }) 7123 .removeClass( "ui-corner-left ui-corner-right" ) 7124 .end() 7125 .button( "destroy" ); 7126 } 7127}); 7128 7129}( jQuery ) ); 7130(function( $, undefined ) { 7131 7132$.extend($.ui, { datepicker: { version: "1.10.2" } }); 7133 7134var PROP_NAME = "datepicker", 7135 dpuuid = new Date().getTime(), 7136 instActive; 7137 7138/* Date picker manager. 7139 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7140 Settings for (groups of) date pickers are maintained in an instance object, 7141 allowing multiple different settings on the same page. */ 7142 7143function Datepicker() { 7144 this._curInst = null; /*// The current instance in use 7145*/ 7146 this._keyEvent = false; /*// If the last event was a key event 7147*/ 7148 this._disabledInputs = []; /*// List of date picker inputs that have been disabled 7149*/ 7150 this._datepickerShowing = false; /*// True if the popup picker is showing , false if not 7151*/ 7152 this._inDialog = false; /*// True if showing within a "dialog", false if not 7153*/ 7154 this._mainDivId = "ui-datepicker-div"; /*// The ID of the main datepicker division 7155*/ 7156 this._inlineClass = "ui-datepicker-inline"; /*// The name of the inline marker class 7157*/ 7158 this._appendClass = "ui-datepicker-append"; /*// The name of the append marker class 7159*/ 7160 this._triggerClass = "ui-datepicker-trigger"; /*// The name of the trigger marker class 7161*/ 7162 this._dialogClass = "ui-datepicker-dialog"; /*// The name of the dialog marker class 7163*/ 7164 this._disableClass = "ui-datepicker-disabled"; /*// The name of the disabled covering marker class 7165*/ 7166 this._unselectableClass = "ui-datepicker-unselectable"; /*// The name of the unselectable cell marker class 7167*/ 7168 this._currentClass = "ui-datepicker-current-day"; /*// The name of the current day marker class 7169*/ 7170 this._dayOverClass = "ui-datepicker-days-cell-over"; /*// The name of the day hover marker class 7171*/ 7172 this.regional = []; /*// Available regional settings, indexed by language code 7173*/ 7174 this.regional[""] = { /*// Default regional settings 7175*/ 7176 closeText: "Done", /*// Display text for close link 7177*/ 7178 prevText: "Prev", /*// Display text for previous month link 7179*/ 7180 nextText: "Next", /*// Display text for next month link 7181*/ 7182 currentText: "Today", /*// Display text for current month link 7183*/ 7184 monthNames: ["January","February","March","April","May","June", 7185 "July","August","September","October","November","December"], /*// Names of months for drop-down and formatting 7186*/ 7187 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], /*// For formatting 7188*/ 7189 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], /*// For formatting 7190*/ 7191 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], /*// For formatting 7192*/ 7193 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], /*// Column headings for days starting at Sunday 7194*/ 7195 weekHeader: "Wk", /*// Column header for week of the year 7196*/ 7197 dateFormat: "mm/dd/yy", /*// See format options on parseDate 7198*/ 7199 firstDay: 0, /*// The first day of the week, Sun = 0, Mon = 1, ... 7200*/ 7201 isRTL: false, /*// True if right-to-left language, false if left-to-right 7202*/ 7203 showMonthAfterYear: false, /*// True if the year select precedes month, false for month then year 7204*/ 7205 yearSuffix: "" /*// Additional text to append to the year in the month headers
vendor: 7,017 bytes, lines 7206-7396
7206*/ 7207 }; 7208 this._defaults = { /*// Global defaults for all the date picker instances 7209*/ 7210 showOn: "focus", /*// "focus" for popup on focus, 7211*/ 7212 /*// "button" for trigger button, or "both" for either 7213*/ 7214 showAnim: "fadeIn", /*// Name of jQuery animation for popup 7215*/ 7216 showOptions: {}, /*// Options for enhanced animations 7217*/ 7218 defaultDate: null, /*// Used when field is blank: actual date, 7219*/ 7220 /*// +/-number for offset from today, null for today 7221*/ 7222 appendText: "", /*// Display text following the input box, e.g. showing the format 7223*/ 7224 buttonText: "...", /*// Text for trigger button 7225*/ 7226 buttonImage: "", /*// URL for trigger button image 7227*/ 7228 buttonImageOnly: false, /*// True if the image appears alone, false if it appears on a button 7229*/ 7230 hideIfNoPrevNext: false, /*// True to hide next/previous month links 7231*/ 7232 /*// if not applicable, false to just disable them 7233*/ 7234 navigationAsDateFormat: false, /*// True if date formatting applied to prev/today/next links 7235*/ 7236 gotoCurrent: false, /*// True if today link goes back to current selection instead 7237*/ 7238 changeMonth: false, /*// True if month can be selected directly, false if only prev/next 7239*/ 7240 changeYear: false, /*// True if year can be selected directly, false if only prev/next 7241*/ 7242 yearRange: "c-10:c+10", /*// Range of years to display in drop-down, 7243*/ 7244 /*// either relative to today's year (-nn:+nn), relative to currently displayed year 7245*/ 7246 /*// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7247*/ 7248 showOtherMonths: false, /*// True to show dates in other months, false to leave blank 7249*/ 7250 selectOtherMonths: false, /*// True to allow selection of dates in other months, false for unselectable 7251*/ 7252 showWeek: false, /*// True to show week of the year, false to not show it 7253*/ 7254 calculateWeek: this.iso8601Week, /*// How to calculate the week of the year, 7255*/ 7256 /*// takes a Date and returns the number of the week for it 7257*/ 7258 shortYearCutoff: "+10", /*// Short year values < this are in the current century, 7259*/ 7260 /*// > this are in the previous century, 7261*/ 7262 /*// string value starting with "+" for current year + value 7263*/ 7264 minDate: null, /*// The earliest selectable date, or null for no limit 7265*/ 7266 maxDate: null, /*// The latest selectable date, or null for no limit 7267*/ 7268 duration: "fast", /*// Duration of display/closure 7269*/ 7270 beforeShowDay: null, /*// Function that takes a date and returns an array with 7271*/ 7272 /*// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7273*/ 7274 /*// [2] = cell title (optional), e.g. $.datepicker.noWeekends 7275*/ 7276 beforeShow: null, /*// Function that takes an input field and 7277*/ 7278 /*// returns a set of custom settings for the date picker 7279*/ 7280 onSelect: null, /*// Define a callback function when a date is selected 7281*/ 7282 onChangeMonthYear: null, /*// Define a callback function when the month or year is changed 7283*/ 7284 onClose: null, /*// Define a callback function when the datepicker is closed 7285*/ 7286 numberOfMonths: 1, /*// Number of months to show at a time 7287*/ 7288 showCurrentAtPos: 0, /*// The position in multipe months at which to show the current month (starting at 0) 7289*/ 7290 stepMonths: 1, /*// Number of months to step back/forward 7291*/ 7292 stepBigMonths: 12, /*// Number of months to step back/forward for the big links 7293*/ 7294 altField: "", /*// Selector for an alternate field to store selected dates into 7295*/ 7296 altFormat: "", /*// The date format to use for the alternate field 7297*/ 7298 constrainInput: true, /*// The input is constrained by the current date format 7299*/ 7300 showButtonPanel: false, /*// True to show button panel, false to not show it 7301*/ 7302 autoSize: false, /*// True to size the input for the date format, false to leave as is 7303*/ 7304 disabled: false /*// The initial disabled state 7305*/ 7306 }; 7307 $.extend(this._defaults, this.regional[""]); 7308 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7309} 7310 7311$.extend(Datepicker.prototype, { 7312 /* Class name added to elements to indicate already configured with a date picker. */ 7313 markerClassName: "hasDatepicker", 7314 7315 //Keep track of the maximum number of rows displayed (see #7043) 7316 maxRows: 4, 7317 7318 /*// TODO rename to "widget" when switching to widget factory 7319*/ 7320 _widgetDatepicker: function() { 7321 return this.dpDiv; 7322 }, 7323 7324 /* Override the default settings for all instances of the date picker. 7325 * @param settings object - the new settings to use as defaults (anonymous object) 7326 * @return the manager object 7327 */ 7328 setDefaults: function(settings) { 7329 extendRemove(this._defaults, settings || {}); 7330 return this; 7331 }, 7332 7333 /* Attach the date picker to a jQuery selection. 7334 * @param target element - the target input field or division or span 7335 * @param settings object - the new settings to use for this date picker instance (anonymous) 7336 */ 7337 _attachDatepicker: function(target, settings) { 7338 var nodeName, inline, inst; 7339 nodeName = target.nodeName.toLowerCase(); 7340 inline = (nodeName === "div" || nodeName === "span"); 7341 if (!target.id) { 7342 this.uuid += 1; 7343 target.id = "dp" + this.uuid; 7344 } 7345 inst = this._newInst($(target), inline); 7346 inst.settings = $.extend({}, settings || {}); 7347 if (nodeName === "input") { 7348 this._connectDatepicker(target, inst); 7349 } else if (inline) { 7350 this._inlineDatepicker(target, inst); 7351 } 7352 }, 7353 7354 /* Create a new instance object. */ 7355 _newInst: function(target, inline) { 7356 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); /*// escape jQuery meta chars 7357*/ 7358 return {id: id, input: target, /*// associated target 7359*/ 7360 selectedDay: 0, selectedMonth: 0, selectedYear: 0, /*// current selection 7361*/ 7362 drawMonth: 0, drawYear: 0, /*// month being drawn 7363*/ 7364 inline: inline, /*// is datepicker inline or not 7365*/ 7366 dpDiv: (!inline ? this.dpDiv : /*// presentation div 7367*/ 7368 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7369 }, 7370 7371 /* Attach the date picker to an input field. */ 7372 _connectDatepicker: function(target, inst) { 7373 var input = $(target); 7374 inst.append = $([]); 7375 inst.trigger = $([]); 7376 if (input.hasClass(this.markerClassName)) { 7377 return; 7378 } 7379 this._attachments(input, inst); 7380 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7381 keypress(this._doKeyPress).keyup(this._doKeyUp); 7382 this._autoSize(inst); 7383 $.data(target, PROP_NAME, inst); 7384 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7385 if( inst.settings.disabled ) { 7386 this._disableDatepicker( target ); 7387 } 7388 }, 7389 7390 /* Make attachments based on settings. */ 7391 _attachments: function(input, inst) { 7392 var showOn, buttonText, buttonImage, 7393 appendText = this._get(inst, "appendText"), 7394 isRTL = this._get(inst, "isRTL"); 7395 7396 if (inst.append) {
vendor: 5,981 bytes, lines 7397-7560
7397 inst.append.remove(); 7398 } 7399 if (appendText) { 7400 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7401 input[isRTL ? "before" : "after"](inst.append); 7402 } 7403 7404 input.unbind("focus", this._showDatepicker); 7405 7406 if (inst.trigger) { 7407 inst.trigger.remove(); 7408 } 7409 7410 showOn = this._get(inst, "showOn"); 7411 if (showOn === "focus" || showOn === "both") { /*// pop-up date picker when in the marked field 7412*/ 7413 input.focus(this._showDatepicker); 7414 } 7415 if (showOn === "button" || showOn === "both") { /*// pop-up date picker when button clicked 7416*/ 7417 buttonText = this._get(inst, "buttonText"); 7418 buttonImage = this._get(inst, "buttonImage"); 7419 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7420 $("<img/>").addClass(this._triggerClass). 7421 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7422 $("<button type='button'></button>").addClass(this._triggerClass). 7423 html(!buttonImage ? buttonText : $("<img/>").attr( 7424 { src:buttonImage, alt:buttonText, title:buttonText }))); 7425 input[isRTL ? "before" : "after"](inst.trigger); 7426 inst.trigger.click(function() { 7427 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7428 $.datepicker._hideDatepicker(); 7429 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7430 $.datepicker._hideDatepicker(); 7431 $.datepicker._showDatepicker(input[0]); 7432 } else { 7433 $.datepicker._showDatepicker(input[0]); 7434 } 7435 return false; 7436 }); 7437 } 7438 }, 7439 7440 /* Apply the maximum length for the date format. */ 7441 _autoSize: function(inst) { 7442 if (this._get(inst, "autoSize") && !inst.inline) { 7443 var findMax, max, maxI, i, 7444 date = new Date(2009, 12 - 1, 20), /*// Ensure double digits 7445*/ 7446 dateFormat = this._get(inst, "dateFormat"); 7447 7448 if (dateFormat.match(/[DM]/)) { 7449 findMax = function(names) { 7450 max = 0; 7451 maxI = 0; 7452 for (i = 0; i < names.length; i++) { 7453 if (names[i].length > max) { 7454 max = names[i].length; 7455 maxI = i; 7456 } 7457 } 7458 return maxI; 7459 }; 7460 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7461 "monthNames" : "monthNamesShort")))); 7462 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7463 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7464 } 7465 inst.input.attr("size", this._formatDate(inst, date).length); 7466 } 7467 }, 7468 7469 /* Attach an inline date picker to a div. */ 7470 _inlineDatepicker: function(target, inst) { 7471 var divSpan = $(target); 7472 if (divSpan.hasClass(this.markerClassName)) { 7473 return; 7474 } 7475 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7476 $.data(target, PROP_NAME, inst); 7477 this._setDate(inst, this._getDefaultDate(inst), true); 7478 this._updateDatepicker(inst); 7479 this._updateAlternate(inst); 7480 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7481 if( inst.settings.disabled ) { 7482 this._disableDatepicker( target ); 7483 } 7484 /*// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7485*/ 7486 /*// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7487*/ 7488 inst.dpDiv.css( "display", "block" ); 7489 }, 7490 7491 /* Pop-up the date picker in a "dialog" box. 7492 * @param input element - ignored 7493 * @param date string or Date - the initial date to display 7494 * @param onSelect function - the function to call when a date is selected 7495 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7496 * @param pos int[2] - coordinates for the dialog's position within the screen or 7497 * event - with x/y coordinates or 7498 * leave empty for default (screen centre) 7499 * @return the manager object 7500 */ 7501 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7502 var id, browserWidth, browserHeight, scrollX, scrollY, 7503 inst = this._dialogInst; /*// internal instance 7504*/ 7505 7506 if (!inst) { 7507 this.uuid += 1; 7508 id = "dp" + this.uuid; 7509 this._dialogInput = $("<input type='text' id='" + id + 7510 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7511 this._dialogInput.keydown(this._doKeyDown); 7512 $("body").append(this._dialogInput); 7513 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7514 inst.settings = {}; 7515 $.data(this._dialogInput[0], PROP_NAME, inst); 7516 } 7517 extendRemove(inst.settings, settings || {}); 7518 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7519 this._dialogInput.val(date); 7520 7521 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7522 if (!this._pos) { 7523 browserWidth = document.documentElement.clientWidth; 7524 browserHeight = document.documentElement.clientHeight; 7525 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7526 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7527 this._pos = /*// should use actual width/height below 7528*/ 7529 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7530 } 7531 7532 /*// move input on screen for focus, but hidden behind dialog 7533*/ 7534 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7535 inst.settings.onSelect = onSelect; 7536 this._inDialog = true; 7537 this.dpDiv.addClass(this._dialogClass); 7538 this._showDatepicker(this._dialogInput[0]); 7539 if ($.blockUI) { 7540 $.blockUI(this.dpDiv); 7541 } 7542 $.data(this._dialogInput[0], PROP_NAME, inst); 7543 return this; 7544 }, 7545 7546 /* Detach a datepicker from its control. 7547 * @param target element - the target input field or division or span 7548 */ 7549 _destroyDatepicker: function(target) { 7550 var nodeName, 7551 $target = $(target), 7552 inst = $.data(target, PROP_NAME); 7553 7554 if (!$target.hasClass(this.markerClassName)) { 7555 return; 7556 } 7557 7558 nodeName = target.nodeName.toLowerCase(); 7559 $.removeData(target, PROP_NAME); 7560 if (nodeName === "input") {
vendor: 10,224 bytes, lines 7561-7861
7561 inst.append.remove(); 7562 inst.trigger.remove(); 7563 $target.removeClass(this.markerClassName). 7564 unbind("focus", this._showDatepicker). 7565 unbind("keydown", this._doKeyDown). 7566 unbind("keypress", this._doKeyPress). 7567 unbind("keyup", this._doKeyUp); 7568 } else if (nodeName === "div" || nodeName === "span") { 7569 $target.removeClass(this.markerClassName).empty(); 7570 } 7571 }, 7572 7573 /* Enable the date picker to a jQuery selection. 7574 * @param target element - the target input field or division or span 7575 */ 7576 _enableDatepicker: function(target) { 7577 var nodeName, inline, 7578 $target = $(target), 7579 inst = $.data(target, PROP_NAME); 7580 7581 if (!$target.hasClass(this.markerClassName)) { 7582 return; 7583 } 7584 7585 nodeName = target.nodeName.toLowerCase(); 7586 if (nodeName === "input") { 7587 target.disabled = false; 7588 inst.trigger.filter("button"). 7589 each(function() { this.disabled = false; }).end(). 7590 filter("img").css({opacity: "1.0", cursor: ""}); 7591 } else if (nodeName === "div" || nodeName === "span") { 7592 inline = $target.children("." + this._inlineClass); 7593 inline.children().removeClass("ui-state-disabled"); 7594 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7595 prop("disabled", false); 7596 } 7597 this._disabledInputs = $.map(this._disabledInputs, 7598 function(value) { return (value === target ? null : value); }); /*// delete entry 7599*/ 7600 }, 7601 7602 /* Disable the date picker to a jQuery selection. 7603 * @param target element - the target input field or division or span 7604 */ 7605 _disableDatepicker: function(target) { 7606 var nodeName, inline, 7607 $target = $(target), 7608 inst = $.data(target, PROP_NAME); 7609 7610 if (!$target.hasClass(this.markerClassName)) { 7611 return; 7612 } 7613 7614 nodeName = target.nodeName.toLowerCase(); 7615 if (nodeName === "input") { 7616 target.disabled = true; 7617 inst.trigger.filter("button"). 7618 each(function() { this.disabled = true; }).end(). 7619 filter("img").css({opacity: "0.5", cursor: "default"}); 7620 } else if (nodeName === "div" || nodeName === "span") { 7621 inline = $target.children("." + this._inlineClass); 7622 inline.children().addClass("ui-state-disabled"); 7623 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7624 prop("disabled", true); 7625 } 7626 this._disabledInputs = $.map(this._disabledInputs, 7627 function(value) { return (value === target ? null : value); }); /*// delete entry 7628*/ 7629 this._disabledInputs[this._disabledInputs.length] = target; 7630 }, 7631 7632 /* Is the first field in a jQuery collection disabled as a datepicker? 7633 * @param target element - the target input field or division or span 7634 * @return boolean - true if disabled, false if enabled 7635 */ 7636 _isDisabledDatepicker: function(target) { 7637 if (!target) { 7638 return false; 7639 } 7640 for (var i = 0; i < this._disabledInputs.length; i++) { 7641 if (this._disabledInputs[i] === target) { 7642 return true; 7643 } 7644 } 7645 return false; 7646 }, 7647 7648 /* Retrieve the instance data for the target control. 7649 * @param target element - the target input field or division or span 7650 * @return object - the associated instance data 7651 * @throws error if a jQuery problem getting data 7652 */ 7653 _getInst: function(target) { 7654 try { 7655 return $.data(target, PROP_NAME); 7656 } 7657 catch (err) { 7658 throw "Missing instance data for this datepicker"; 7659 } 7660 }, 7661 7662 /* Update or retrieve the settings for a date picker attached to an input field or division. 7663 * @param target element - the target input field or division or span 7664 * @param name object - the new settings to update or 7665 * string - the name of the setting to change or retrieve, 7666 * when retrieving also "all" for all instance settings or 7667 * "defaults" for all global defaults 7668 * @param value any - the new value for the setting 7669 * (omit if above is an object or to retrieve a value) 7670 */ 7671 _optionDatepicker: function(target, name, value) { 7672 var settings, date, minDate, maxDate, 7673 inst = this._getInst(target); 7674 7675 if (arguments.length === 2 && typeof name === "string") { 7676 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 7677 (inst ? (name === "all" ? $.extend({}, inst.settings) : 7678 this._get(inst, name)) : null)); 7679 } 7680 7681 settings = name || {}; 7682 if (typeof name === "string") { 7683 settings = {}; 7684 settings[name] = value; 7685 } 7686 7687 if (inst) { 7688 if (this._curInst === inst) { 7689 this._hideDatepicker(); 7690 } 7691 7692 date = this._getDateDatepicker(target, true); 7693 minDate = this._getMinMaxDate(inst, "min"); 7694 maxDate = this._getMinMaxDate(inst, "max"); 7695 extendRemove(inst.settings, settings); 7696 /*// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 7697*/ 7698 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 7699 inst.settings.minDate = this._formatDate(inst, minDate); 7700 } 7701 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 7702 inst.settings.maxDate = this._formatDate(inst, maxDate); 7703 } 7704 if ( "disabled" in settings ) { 7705 if ( settings.disabled ) { 7706 this._disableDatepicker(target); 7707 } else { 7708 this._enableDatepicker(target); 7709 } 7710 } 7711 this._attachments($(target), inst); 7712 this._autoSize(inst); 7713 this._setDate(inst, date); 7714 this._updateAlternate(inst); 7715 this._updateDatepicker(inst); 7716 } 7717 }, 7718 7719 /*// change method deprecated 7720*/ 7721 _changeDatepicker: function(target, name, value) { 7722 this._optionDatepicker(target, name, value); 7723 }, 7724 7725 /* Redraw the date picker attached to an input field or division. 7726 * @param target element - the target input field or division or span 7727 */ 7728 _refreshDatepicker: function(target) { 7729 var inst = this._getInst(target); 7730 if (inst) { 7731 this._updateDatepicker(inst); 7732 } 7733 }, 7734 7735 /* Set the dates for a jQuery selection. 7736 * @param target element - the target input field or division or span 7737 * @param date Date - the new date 7738 */ 7739 _setDateDatepicker: function(target, date) { 7740 var inst = this._getInst(target); 7741 if (inst) { 7742 this._setDate(inst, date); 7743 this._updateDatepicker(inst); 7744 this._updateAlternate(inst); 7745 } 7746 }, 7747 7748 /* Get the date(s) for the first entry in a jQuery selection. 7749 * @param target element - the target input field or division or span 7750 * @param noDefault boolean - true if no default date is to be used 7751 * @return Date - the current date 7752 */ 7753 _getDateDatepicker: function(target, noDefault) { 7754 var inst = this._getInst(target); 7755 if (inst && !inst.inline) { 7756 this._setDateFromField(inst, noDefault); 7757 } 7758 return (inst ? this._getDate(inst) : null); 7759 }, 7760 7761 /* Handle keystrokes. */ 7762 _doKeyDown: function(event) { 7763 var onSelect, dateStr, sel, 7764 inst = $.datepicker._getInst(event.target), 7765 handled = true, 7766 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 7767 7768 inst._keyEvent = true; 7769 if ($.datepicker._datepickerShowing) { 7770 switch (event.keyCode) { 7771 case 9: $.datepicker._hideDatepicker(); 7772 handled = false; 7773 break; /*// hide on tab out 7774*/ 7775 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 7776 $.datepicker._currentClass + ")", inst.dpDiv); 7777 if (sel[0]) { 7778 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 7779 } 7780 7781 onSelect = $.datepicker._get(inst, "onSelect"); 7782 if (onSelect) { 7783 dateStr = $.datepicker._formatDate(inst); 7784 7785 /*// trigger custom callback 7786*/ 7787 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 7788 } else { 7789 $.datepicker._hideDatepicker(); 7790 } 7791 7792 return false; /*// don't submit the form 7793*/ 7794 case 27: $.datepicker._hideDatepicker(); 7795 break; /*// hide on escape 7796*/ 7797 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7798 -$.datepicker._get(inst, "stepBigMonths") : 7799 -$.datepicker._get(inst, "stepMonths")), "M"); 7800 break; /*// previous month/year on page up/+ ctrl 7801*/ 7802 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7803 +$.datepicker._get(inst, "stepBigMonths") : 7804 +$.datepicker._get(inst, "stepMonths")), "M"); 7805 break; /*// next month/year on page down/+ ctrl 7806*/ 7807 case 35: if (event.ctrlKey || event.metaKey) { 7808 $.datepicker._clearDate(event.target); 7809 } 7810 handled = event.ctrlKey || event.metaKey; 7811 break; /*// clear on ctrl or command +end 7812*/ 7813 case 36: if (event.ctrlKey || event.metaKey) { 7814 $.datepicker._gotoToday(event.target); 7815 } 7816 handled = event.ctrlKey || event.metaKey; 7817 break; /*// current on ctrl or command +home 7818*/ 7819 case 37: if (event.ctrlKey || event.metaKey) { 7820 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 7821 } 7822 handled = event.ctrlKey || event.metaKey; 7823 /*// -1 day on ctrl or command +left 7824*/ 7825 if (event.originalEvent.altKey) { 7826 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7827 -$.datepicker._get(inst, "stepBigMonths") : 7828 -$.datepicker._get(inst, "stepMonths")), "M"); 7829 } 7830 /*// next month/year on alt +left on Mac 7831*/ 7832 break; 7833 case 38: if (event.ctrlKey || event.metaKey) { 7834 $.datepicker._adjustDate(event.target, -7, "D"); 7835 } 7836 handled = event.ctrlKey || event.metaKey; 7837 break; /*// -1 week on ctrl or command +up 7838*/ 7839 case 39: if (event.ctrlKey || event.metaKey) { 7840 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 7841 } 7842 handled = event.ctrlKey || event.metaKey; 7843 /*// +1 day on ctrl or command +right 7844*/ 7845 if (event.originalEvent.altKey) { 7846 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 7847 +$.datepicker._get(inst, "stepBigMonths") : 7848 +$.datepicker._get(inst, "stepMonths")), "M"); 7849 } 7850 /*// next month/year on alt +right 7851*/ 7852 break; 7853 case 40: if (event.ctrlKey || event.metaKey) { 7854 $.datepicker._adjustDate(event.target, +7, "D"); 7855 } 7856 handled = event.ctrlKey || event.metaKey; 7857 break; /*// +1 week on ctrl or command +down 7858*/ 7859 default: handled = false; 7860 } 7861 }
vendor: 11,496 bytes, lines 7861-8205
7861 else if (event.keyCode === 36 && event.ctrlKey) { /*// display the date picker on ctrl+home 7862*/ 7863 $.datepicker._showDatepicker(this); 7864 } else { 7865 handled = false; 7866 } 7867 7868 if (handled) { 7869 event.preventDefault(); 7870 event.stopPropagation(); 7871 } 7872 }, 7873 7874 /* Filter entered characters - based on date format. */ 7875 _doKeyPress: function(event) { 7876 var chars, chr, 7877 inst = $.datepicker._getInst(event.target); 7878 7879 if ($.datepicker._get(inst, "constrainInput")) { 7880 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 7881 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 7882 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 7883 } 7884 }, 7885 7886 /* Synchronise manual entry and field/alternate field. */ 7887 _doKeyUp: function(event) { 7888 var date, 7889 inst = $.datepicker._getInst(event.target); 7890 7891 if (inst.input.val() !== inst.lastVal) { 7892 try { 7893 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 7894 (inst.input ? inst.input.val() : null), 7895 $.datepicker._getFormatConfig(inst)); 7896 7897 if (date) { /*// only if valid 7898*/ 7899 $.datepicker._setDateFromField(inst); 7900 $.datepicker._updateAlternate(inst); 7901 $.datepicker._updateDatepicker(inst); 7902 } 7903 } 7904 catch (err) { 7905 } 7906 } 7907 return true; 7908 }, 7909 7910 /* Pop-up the date picker for a given input field. 7911 * If false returned from beforeShow event handler do not show. 7912 * @param input element - the input field attached to the date picker or 7913 * event - if triggered by focus 7914 */ 7915 _showDatepicker: function(input) { 7916 input = input.target || input; 7917 if (input.nodeName.toLowerCase() !== "input") { /*// find from button/image trigger 7918*/ 7919 input = $("input", input.parentNode)[0]; 7920 } 7921 7922 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { /*// already here 7923*/ 7924 return; 7925 } 7926 7927 var inst, beforeShow, beforeShowSettings, isFixed, 7928 offset, showAnim, duration; 7929 7930 inst = $.datepicker._getInst(input); 7931 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 7932 $.datepicker._curInst.dpDiv.stop(true, true); 7933 if ( inst && $.datepicker._datepickerShowing ) { 7934 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 7935 } 7936 } 7937 7938 beforeShow = $.datepicker._get(inst, "beforeShow"); 7939 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 7940 if(beforeShowSettings === false){ 7941 return; 7942 } 7943 extendRemove(inst.settings, beforeShowSettings); 7944 7945 inst.lastVal = null; 7946 $.datepicker._lastInput = input; 7947 $.datepicker._setDateFromField(inst); 7948 7949 if ($.datepicker._inDialog) { /*// hide cursor 7950*/ 7951 input.value = ""; 7952 } 7953 if (!$.datepicker._pos) { /*// position below input 7954*/ 7955 $.datepicker._pos = $.datepicker._findPos(input); 7956 $.datepicker._pos[1] += input.offsetHeight; /*// add the height 7957*/ 7958 } 7959 7960 isFixed = false; 7961 $(input).parents().each(function() { 7962 isFixed |= $(this).css("position") === "fixed"; 7963 return !isFixed; 7964 }); 7965 7966 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 7967 $.datepicker._pos = null; 7968 //to avoid flashes on Firefox 7969 inst.dpDiv.empty(); 7970 /*// determine sizing offscreen 7971*/ 7972 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 7973 $.datepicker._updateDatepicker(inst); 7974 /*// fix width for dynamic number of date pickers 7975*/ 7976 /*// and adjust position before showing 7977*/ 7978 offset = $.datepicker._checkOffset(inst, offset, isFixed); 7979 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 7980 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 7981 left: offset.left + "px", top: offset.top + "px"}); 7982 7983 if (!inst.inline) { 7984 showAnim = $.datepicker._get(inst, "showAnim"); 7985 duration = $.datepicker._get(inst, "duration"); 7986 inst.dpDiv.zIndex($(input).zIndex()+1); 7987 $.datepicker._datepickerShowing = true; 7988 7989 if ( $.effects && $.effects.effect[ showAnim ] ) { 7990 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 7991 } else { 7992 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 7993 } 7994 7995 if (inst.input.is(":visible") && !inst.input.is(":disabled")) { 7996 inst.input.focus(); 7997 } 7998 $.datepicker._curInst = inst; 7999 } 8000 }, 8001 8002 /* Generate the date picker content. */ 8003 _updateDatepicker: function(inst) { 8004 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8005 instActive = inst; /*// for delegate hover events 8006*/ 8007 inst.dpDiv.empty().append(this._generateHTML(inst)); 8008 this._attachHandlers(inst); 8009 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8010 8011 var origyearshtml, 8012 numMonths = this._getNumberOfMonths(inst), 8013 cols = numMonths[1], 8014 width = 17; 8015 8016 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8017 if (cols > 1) { 8018 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8019 } 8020 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8021 "Class"]("ui-datepicker-multi"); 8022 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8023 "Class"]("ui-datepicker-rtl"); 8024 8025 /*// #6694 - don't focus the input if it's already focused 8026*/ 8027 /*// this breaks the change event in IE 8028*/ 8029 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 8030 inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) { 8031 inst.input.focus(); 8032 } 8033 8034 /*// deffered render of the years select (to avoid flashes on Firefox) 8035*/ 8036 if( inst.yearshtml ){ 8037 origyearshtml = inst.yearshtml; 8038 setTimeout(function(){ 8039 //assure that inst.yearshtml didn't change. 8040 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8041 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8042 } 8043 origyearshtml = inst.yearshtml = null; 8044 }, 0); 8045 } 8046 }, 8047 8048 /* Retrieve the size of left and top borders for an element. 8049 * @param elem (jQuery object) the element of interest 8050 * @return (number[2]) the left and top borders 8051 */ 8052 _getBorders: function(elem) { 8053 var convert = function(value) { 8054 return {thin: 1, medium: 2, thick: 3}[value] || value; 8055 }; 8056 return [parseFloat(convert(elem.css("border-left-width"))), 8057 parseFloat(convert(elem.css("border-top-width")))]; 8058 }, 8059 8060 /* Check positioning to remain on screen. */ 8061 _checkOffset: function(inst, offset, isFixed) { 8062 var dpWidth = inst.dpDiv.outerWidth(), 8063 dpHeight = inst.dpDiv.outerHeight(), 8064 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8065 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8066 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8067 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8068 8069 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8070 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8071 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8072 8073 /*// now check if datepicker is showing outside window viewport - move to a better place if so. 8074*/ 8075 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8076 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8077 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8078 Math.abs(dpHeight + inputHeight) : 0); 8079 8080 return offset; 8081 }, 8082 8083 /* Find an object's position on the screen. */ 8084 _findPos: function(obj) { 8085 var position, 8086 inst = this._getInst(obj), 8087 isRTL = this._get(inst, "isRTL"); 8088 8089 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8090 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8091 } 8092 8093 position = $(obj).offset(); 8094 return [position.left, position.top]; 8095 }, 8096 8097 /* Hide the date picker from view. 8098 * @param input element - the input field attached to the date picker 8099 */ 8100 _hideDatepicker: function(input) { 8101 var showAnim, duration, postProcess, onClose, 8102 inst = this._curInst; 8103 8104 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 8105 return; 8106 } 8107 8108 if (this._datepickerShowing) { 8109 showAnim = this._get(inst, "showAnim"); 8110 duration = this._get(inst, "duration"); 8111 postProcess = function() { 8112 $.datepicker._tidyDialog(inst); 8113 }; 8114 8115 /*// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8116*/ 8117 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8118 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8119 } else { 8120 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8121 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8122 } 8123 8124 if (!showAnim) { 8125 postProcess(); 8126 } 8127 this._datepickerShowing = false; 8128 8129 onClose = this._get(inst, "onClose"); 8130 if (onClose) { 8131 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8132 } 8133 8134 this._lastInput = null; 8135 if (this._inDialog) { 8136 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8137 if ($.blockUI) { 8138 $.unblockUI(); 8139 $("body").append(this.dpDiv); 8140 } 8141 } 8142 this._inDialog = false; 8143 } 8144 }, 8145 8146 /* Tidy up after a dialog display. */ 8147 _tidyDialog: function(inst) { 8148 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8149 }, 8150 8151 /* Close date picker if clicked elsewhere. */ 8152 _checkExternalClick: function(event) { 8153 if (!$.datepicker._curInst) { 8154 return; 8155 } 8156 8157 var $target = $(event.target), 8158 inst = $.datepicker._getInst($target[0]); 8159 8160 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8161 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8162 !$target.hasClass($.datepicker.markerClassName) && 8163 !$target.closest("." + $.datepicker._triggerClass).length && 8164 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8165 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8166 $.datepicker._hideDatepicker(); 8167 } 8168 }, 8169 8170 /* Adjust one of the date sub-fields. */ 8171 _adjustDate: function(id, offset, period) { 8172 var target = $(id), 8173 inst = this._getInst(target[0]); 8174 8175 if (this._isDisabledDatepicker(target[0])) { 8176 return; 8177 } 8178 this._adjustInstDate(inst, offset + 8179 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), /*// undo positioning 8180*/ 8181 period); 8182 this._updateDatepicker(inst); 8183 }, 8184 8185 /* Action for current link. */ 8186 _gotoToday: function(id) { 8187 var date, 8188 target = $(id), 8189 inst = this._getInst(target[0]); 8190 8191 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8192 inst.selectedDay = inst.currentDay; 8193 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8194 inst.drawYear = inst.selectedYear = inst.currentYear; 8195 } else { 8196 date = new Date(); 8197 inst.selectedDay = date.getDate(); 8198 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8199 inst.drawYear = inst.selectedYear = date.getFullYear(); 8200 } 8201 this._notifyChange(inst); 8202 this._adjustDate(target); 8203 }, 8204 8205 /* Action for selecting a new month/year. */
vendor: 4,603 bytes, lines 8206-8343
8206 _selectMonthYear: function(id, select, period) { 8207 var target = $(id), 8208 inst = this._getInst(target[0]); 8209 8210 inst["selected" + (period === "M" ? "Month" : "Year")] = 8211 inst["draw" + (period === "M" ? "Month" : "Year")] = 8212 parseInt(select.options[select.selectedIndex].value,10); 8213 8214 this._notifyChange(inst); 8215 this._adjustDate(target); 8216 }, 8217 8218 /* Action for selecting a day. */ 8219 _selectDay: function(id, month, year, td) { 8220 var inst, 8221 target = $(id); 8222 8223 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8224 return; 8225 } 8226 8227 inst = this._getInst(target[0]); 8228 inst.selectedDay = inst.currentDay = $("a", td).html(); 8229 inst.selectedMonth = inst.currentMonth = month; 8230 inst.selectedYear = inst.currentYear = year; 8231 this._selectDate(id, this._formatDate(inst, 8232 inst.currentDay, inst.currentMonth, inst.currentYear)); 8233 }, 8234 8235 /* Erase the input field and hide the date picker. */ 8236 _clearDate: function(id) { 8237 var target = $(id); 8238 this._selectDate(target, ""); 8239 }, 8240 8241 /* Update the input field with the selected date. */ 8242 _selectDate: function(id, dateStr) { 8243 var onSelect, 8244 target = $(id), 8245 inst = this._getInst(target[0]); 8246 8247 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8248 if (inst.input) { 8249 inst.input.val(dateStr); 8250 } 8251 this._updateAlternate(inst); 8252 8253 onSelect = this._get(inst, "onSelect"); 8254 if (onSelect) { 8255 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); /*// trigger custom callback 8256*/ 8257 } else if (inst.input) { 8258 inst.input.trigger("change"); /*// fire the change event 8259*/ 8260 } 8261 8262 if (inst.inline){ 8263 this._updateDatepicker(inst); 8264 } else { 8265 this._hideDatepicker(); 8266 this._lastInput = inst.input[0]; 8267 if (typeof(inst.input[0]) !== "object") { 8268 inst.input.focus(); /*// restore focus 8269*/ 8270 } 8271 this._lastInput = null; 8272 } 8273 }, 8274 8275 /* Update any alternate field to synchronise with the main field. */ 8276 _updateAlternate: function(inst) { 8277 var altFormat, date, dateStr, 8278 altField = this._get(inst, "altField"); 8279 8280 if (altField) { /*// update alternate field too 8281*/ 8282 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8283 date = this._getDate(inst); 8284 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8285 $(altField).each(function() { $(this).val(dateStr); }); 8286 } 8287 }, 8288 8289 /* Set as beforeShowDay function to prevent selection of weekends. 8290 * @param date Date - the date to customise 8291 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8292 */ 8293 noWeekends: function(date) { 8294 var day = date.getDay(); 8295 return [(day > 0 && day < 6), ""]; 8296 }, 8297 8298 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8299 * @param date Date - the date to get the week for 8300 * @return number - the number of the week within the year that contains this date 8301 */ 8302 iso8601Week: function(date) { 8303 var time, 8304 checkDate = new Date(date.getTime()); 8305 8306 /*// Find Thursday of this week starting on Monday 8307*/ 8308 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8309 8310 time = checkDate.getTime(); 8311 checkDate.setMonth(0); /*// Compare with Jan 1 8312*/ 8313 checkDate.setDate(1); 8314 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8315 }, 8316 8317 /* Parse a string value into a date object. 8318 * See formatDate below for the possible formats. 8319 * 8320 * @param format string - the expected format of the date 8321 * @param value string - the date in the above format 8322 * @param settings Object - attributes include: 8323 * shortYearCutoff number - the cutoff year for determining the century (optional) 8324 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8325 * dayNames string[7] - names of the days from Sunday (optional) 8326 * monthNamesShort string[12] - abbreviated names of the months (optional) 8327 * monthNames string[12] - names of the months (optional) 8328 * @return Date - the extracted date value or null if value is blank 8329 */ 8330 parseDate: function (format, value, settings) { 8331 if (format == null || value == null) { 8332 throw "Invalid arguments"; 8333 } 8334 8335 value = (typeof value === "object" ? value.toString() : value + ""); 8336 if (value === "") { 8337 return null; 8338 } 8339 8340 var iFormat, dim, extra, 8341 iValue = 0, 8342 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8343 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,438 bytes, lines 8343-8536
8343: 8344 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8345 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8346 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8347 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8348 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8349 year = -1, 8350 month = -1, 8351 day = -1, 8352 doy = -1, 8353 literal = false, 8354 date, 8355 /*// Check whether a format character is doubled 8356*/ 8357 lookAhead = function(match) { 8358 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8359 if (matches) { 8360 iFormat++; 8361 } 8362 return matches; 8363 }, 8364 /*// Extract a number from the string value 8365*/ 8366 getNumber = function(match) { 8367 var isDoubled = lookAhead(match), 8368 size = (match === "@" ? 14 : (match === "!" ? 20 : 8369 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8370 digits = new RegExp("^\\d{1," + size + "}"), 8371 num = value.substring(iValue).match(digits); 8372 if (!num) { 8373 throw "Missing number at position " + iValue; 8374 } 8375 iValue += num[0].length; 8376 return parseInt(num[0], 10); 8377 }, 8378 /*// Extract a name from the string value and convert to an index 8379*/ 8380 getName = function(match, shortNames, longNames) { 8381 var index = -1, 8382 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8383 return [ [k, v] ]; 8384 }).sort(function (a, b) { 8385 return -(a[1].length - b[1].length); 8386 }); 8387 8388 $.each(names, function (i, pair) { 8389 var name = pair[1]; 8390 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8391 index = pair[0]; 8392 iValue += name.length; 8393 return false; 8394 } 8395 }); 8396 if (index !== -1) { 8397 return index + 1; 8398 } else { 8399 throw "Unknown name at position " + iValue; 8400 } 8401 }, 8402 /*// Confirm that a literal character matches the string value 8403*/ 8404 checkLiteral = function() { 8405 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8406 throw "Unexpected literal at position " + iValue; 8407 } 8408 iValue++; 8409 }; 8410 8411 for (iFormat = 0; iFormat < format.length; iFormat++) { 8412 if (literal) { 8413 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8414 literal = false; 8415 } else { 8416 checkLiteral(); 8417 } 8418 } else { 8419 switch (format.charAt(iFormat)) { 8420 case "d": 8421 day = getNumber("d"); 8422 break; 8423 case "D": 8424 getName("D", dayNamesShort, dayNames); 8425 break; 8426 case "o": 8427 doy = getNumber("o"); 8428 break; 8429 case "m": 8430 month = getNumber("m"); 8431 break; 8432 case "M": 8433 month = getName("M", monthNamesShort, monthNames); 8434 break; 8435 case "y": 8436 year = getNumber("y"); 8437 break; 8438 case "@": 8439 date = new Date(getNumber("@")); 8440 year = date.getFullYear(); 8441 month = date.getMonth() + 1; 8442 day = date.getDate(); 8443 break; 8444 case "!": 8445 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8446 year = date.getFullYear(); 8447 month = date.getMonth() + 1; 8448 day = date.getDate(); 8449 break; 8450 case "'": 8451 if (lookAhead("'")){ 8452 checkLiteral(); 8453 } else { 8454 literal = true; 8455 } 8456 break; 8457 default: 8458 checkLiteral(); 8459 } 8460 } 8461 } 8462 8463 if (iValue < value.length){ 8464 extra = value.substr(iValue); 8465 if (!/^\s+/.test(extra)) { 8466 throw "Extra/unparsed characters found in date: " + extra; 8467 } 8468 } 8469 8470 if (year === -1) { 8471 year = new Date().getFullYear(); 8472 } else if (year < 100) { 8473 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8474 (year <= shortYearCutoff ? 0 : -100); 8475 } 8476 8477 if (doy > -1) { 8478 month = 1; 8479 day = doy; 8480 do { 8481 dim = this._getDaysInMonth(year, month - 1); 8482 if (day <= dim) { 8483 break; 8484 } 8485 month++; 8486 day -= dim; 8487 } while (true); 8488 } 8489 8490 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8491 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8492 throw "Invalid date"; /*// E.g. 31/02/00 8493*/ 8494 } 8495 return date; 8496 }, 8497 8498 /* Standard date formats. */ 8499 ATOM: "yy-mm-dd", /*// RFC 3339 (ISO 8601) 8500*/ 8501 COOKIE: "D, dd M yy", 8502 ISO_8601: "yy-mm-dd", 8503 RFC_822: "D, d M y", 8504 RFC_850: "DD, dd-M-y", 8505 RFC_1036: "D, d M y", 8506 RFC_1123: "D, d M yy", 8507 RFC_2822: "D, d M yy", 8508 RSS: "D, d M y", /*// RFC 822 8509*/ 8510 TICKS: "!", 8511 TIMESTAMP: "@", 8512 W3C: "yy-mm-dd", /*// ISO 8601 8513*/ 8514 8515 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8516 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8517 8518 /* Format a date object into a string value. 8519 * The format can be combinations of the following: 8520 * d - day of month (no leading zero) 8521 * dd - day of month (two digit) 8522 * o - day of year (no leading zeros) 8523 * oo - day of year (three digit) 8524 * D - day name short 8525 * DD - day name long 8526 * m - month of year (no leading zero) 8527 * mm - month of year (two digit) 8528 * M - month name short 8529 * MM - month name long 8530 * y - year (two digit) 8531 * yy - year (four digit) 8532 * @ - Unix timestamp (ms since 01/01/1970) 8533 * ! - Windows ticks (100ns since 01/01/0001) 8534 * "..." - literal text 8535 * '' - single quote 8536 *
vendor: 9,286 bytes, lines 8537-8823
8537 * @param format string - the desired format of the date 8538 * @param date Date - the date value to format 8539 * @param settings Object - attributes include: 8540 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8541 * dayNames string[7] - names of the days from Sunday (optional) 8542 * monthNamesShort string[12] - abbreviated names of the months (optional) 8543 * monthNames string[12] - names of the months (optional) 8544 * @return string - the date in the above format 8545 */ 8546 formatDate: function (format, date, settings) { 8547 if (!date) { 8548 return ""; 8549 } 8550 8551 var iFormat, 8552 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8553 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8554 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8555 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8556 /*// Check whether a format character is doubled 8557*/ 8558 lookAhead = function(match) { 8559 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8560 if (matches) { 8561 iFormat++; 8562 } 8563 return matches; 8564 }, 8565 /*// Format a number, with leading zero if necessary 8566*/ 8567 formatNumber = function(match, value, len) { 8568 var num = "" + value; 8569 if (lookAhead(match)) { 8570 while (num.length < len) { 8571 num = "0" + num; 8572 } 8573 } 8574 return num; 8575 }, 8576 /*// Format a name, short or long as requested 8577*/ 8578 formatName = function(match, value, shortNames, longNames) { 8579 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8580 }, 8581 output = "", 8582 literal = false; 8583 8584 if (date) { 8585 for (iFormat = 0; iFormat < format.length; iFormat++) { 8586 if (literal) { 8587 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8588 literal = false; 8589 } else { 8590 output += format.charAt(iFormat); 8591 } 8592 } else { 8593 switch (format.charAt(iFormat)) { 8594 case "d": 8595 output += formatNumber("d", date.getDate(), 2); 8596 break; 8597 case "D": 8598 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8599 break; 8600 case "o": 8601 output += formatNumber("o", 8602 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8603 break; 8604 case "m": 8605 output += formatNumber("m", date.getMonth() + 1, 2); 8606 break; 8607 case "M": 8608 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8609 break; 8610 case "y": 8611 output += (lookAhead("y") ? date.getFullYear() : 8612 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8613 break; 8614 case "@": 8615 output += date.getTime(); 8616 break; 8617 case "!": 8618 output += date.getTime() * 10000 + this._ticksTo1970; 8619 break; 8620 case "'": 8621 if (lookAhead("'")) { 8622 output += "'"; 8623 } else { 8624 literal = true; 8625 } 8626 break; 8627 default: 8628 output += format.charAt(iFormat); 8629 } 8630 } 8631 } 8632 } 8633 return output; 8634 }, 8635 8636 /* Extract all possible characters from the date format. */ 8637 _possibleChars: function (format) { 8638 var iFormat, 8639 chars = "", 8640 literal = false, 8641 /*// Check whether a format character is doubled 8642*/ 8643 lookAhead = function(match) { 8644 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8645 if (matches) { 8646 iFormat++; 8647 } 8648 return matches; 8649 }; 8650 8651 for (iFormat = 0; iFormat < format.length; iFormat++) { 8652 if (literal) { 8653 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8654 literal = false; 8655 } else { 8656 chars += format.charAt(iFormat); 8657 } 8658 } else { 8659 switch (format.charAt(iFormat)) { 8660 case "d": case "m": case "y": case "@": 8661 chars += "0123456789"; 8662 break; 8663 case "D": case "M": 8664 return null; /*// Accept anything 8665*/ 8666 case "'": 8667 if (lookAhead("'")) { 8668 chars += "'"; 8669 } else { 8670 literal = true; 8671 } 8672 break; 8673 default: 8674 chars += format.charAt(iFormat); 8675 } 8676 } 8677 } 8678 return chars; 8679 }, 8680 8681 /* Get a setting value, defaulting if necessary. */ 8682 _get: function(inst, name) { 8683 return inst.settings[name] !== undefined ? 8684 inst.settings[name] : this._defaults[name]; 8685 }, 8686 8687 /* Parse existing date and initialise date picker. */ 8688 _setDateFromField: function(inst, noDefault) { 8689 if (inst.input.val() === inst.lastVal) { 8690 return; 8691 } 8692 8693 var dateFormat = this._get(inst, "dateFormat"), 8694 dates = inst.lastVal = inst.input ? inst.input.val() : null, 8695 defaultDate = this._getDefaultDate(inst), 8696 date = defaultDate, 8697 settings = this._getFormatConfig(inst); 8698 8699 try { 8700 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 8701 } catch (event) { 8702 dates = (noDefault ? "" : dates); 8703 } 8704 inst.selectedDay = date.getDate(); 8705 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8706 inst.drawYear = inst.selectedYear = date.getFullYear(); 8707 inst.currentDay = (dates ? date.getDate() : 0); 8708 inst.currentMonth = (dates ? date.getMonth() : 0); 8709 inst.currentYear = (dates ? date.getFullYear() : 0); 8710 this._adjustInstDate(inst); 8711 }, 8712 8713 /* Retrieve the default date shown on opening. */ 8714 _getDefaultDate: function(inst) { 8715 return this._restrictMinMax(inst, 8716 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 8717 }, 8718 8719 /* A date may be specified as an exact value or a relative one. */ 8720 _determineDate: function(inst, date, defaultDate) { 8721 var offsetNumeric = function(offset) { 8722 var date = new Date(); 8723 date.setDate(date.getDate() + offset); 8724 return date; 8725 }, 8726 offsetString = function(offset) { 8727 try { 8728 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8729 offset, $.datepicker._getFormatConfig(inst)); 8730 } 8731 catch (e) { 8732 /*// Ignore 8733*/ 8734 } 8735 8736 var date = (offset.toLowerCase().match(/^c/) ? 8737 $.datepicker._getDate(inst) : null) || new Date(), 8738 year = date.getFullYear(), 8739 month = date.getMonth(), 8740 day = date.getDate(), 8741 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 8742 matches = pattern.exec(offset); 8743 8744 while (matches) { 8745 switch (matches[2] || "d") { 8746 case "d" : case "D" : 8747 day += parseInt(matches[1],10); break; 8748 case "w" : case "W" : 8749 day += parseInt(matches[1],10) * 7; break; 8750 case "m" : case "M" : 8751 month += parseInt(matches[1],10); 8752 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8753 break; 8754 case "y": case "Y" : 8755 year += parseInt(matches[1],10); 8756 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 8757 break; 8758 } 8759 matches = pattern.exec(offset); 8760 } 8761 return new Date(year, month, day); 8762 }, 8763 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 8764 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 8765 8766 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 8767 if (newDate) { 8768 newDate.setHours(0); 8769 newDate.setMinutes(0); 8770 newDate.setSeconds(0); 8771 newDate.setMilliseconds(0); 8772 } 8773 return this._daylightSavingAdjust(newDate); 8774 }, 8775 8776 /* Handle switch to/from daylight saving. 8777 * Hours may be non-zero on daylight saving cut-over: 8778 * > 12 when midnight changeover, but then cannot generate 8779 * midnight datetime, so jump to 1AM, otherwise reset. 8780 * @param date (Date) the date to check 8781 * @return (Date) the corrected date 8782 */ 8783 _daylightSavingAdjust: function(date) { 8784 if (!date) { 8785 return null; 8786 } 8787 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 8788 return date; 8789 }, 8790 8791 /* Set the date(s) directly. */ 8792 _setDate: function(inst, date, noChange) { 8793 var clear = !date, 8794 origMonth = inst.selectedMonth, 8795 origYear = inst.selectedYear, 8796 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 8797 8798 inst.selectedDay = inst.currentDay = newDate.getDate(); 8799 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 8800 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 8801 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 8802 this._notifyChange(inst); 8803 } 8804 this._adjustInstDate(inst); 8805 if (inst.input) { 8806 inst.input.val(clear ? "" : this._formatDate(inst)); 8807 } 8808 }, 8809 8810 /* Retrieve the date(s) directly. */ 8811 _getDate: function(inst) { 8812 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 8813 this._daylightSavingAdjust(new Date( 8814 inst.currentYear, inst.currentMonth, inst.currentDay))); 8815 return startDate; 8816 }, 8817 8818 /* Attach the onxxx handlers. These are declared statically so 8819 * they work with static code transformers like Caja. 8820 */ 8821 _attachHandlers: function(inst) { 8822 var stepMonths = this._get(inst, "stepMonths"), 8823 id = "#" + inst.id.replace( /\\\\/g, "\\" );
vendor: 39,835 bytes, lines 8824-10044
8824 inst.dpDiv.find("[data-handler]").map(function () { 8825 var handler = { 8826 prev: function () { 8827 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M"); 8828 }, 8829 next: function () { 8830 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M"); 8831 }, 8832 hide: function () { 8833 window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker(); 8834 }, 8835 today: function () { 8836 window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id); 8837 }, 8838 selectDay: function () { 8839 window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 8840 return false; 8841 }, 8842 selectMonth: function () { 8843 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M"); 8844 return false; 8845 }, 8846 selectYear: function () { 8847 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y"); 8848 return false; 8849 } 8850 }; 8851 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 8852 }); 8853 }, 8854 8855 /* Generate the HTML for the current state of the date picker. */ 8856 _generateHTML: function(inst) { 8857 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 8858 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 8859 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 8860 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 8861 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 8862 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 8863 tempDate = new Date(), 8864 today = this._daylightSavingAdjust( 8865 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), /*// clear time 8866*/ 8867 isRTL = this._get(inst, "isRTL"), 8868 showButtonPanel = this._get(inst, "showButtonPanel"), 8869 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 8870 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 8871 numMonths = this._getNumberOfMonths(inst), 8872 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 8873 stepMonths = this._get(inst, "stepMonths"), 8874 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 8875 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 8876 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 8877 minDate = this._getMinMaxDate(inst, "min"), 8878 maxDate = this._getMinMaxDate(inst, "max"), 8879 drawMonth = inst.drawMonth - showCurrentAtPos, 8880 drawYear = inst.drawYear; 8881 8882 if (drawMonth < 0) { 8883 drawMonth += 12; 8884 drawYear--; 8885 } 8886 if (maxDate) { 8887 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 8888 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 8889 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 8890 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 8891 drawMonth--; 8892 if (drawMonth < 0) { 8893 drawMonth = 11; 8894 drawYear--; 8895 } 8896 } 8897 } 8898 inst.drawMonth = drawMonth; 8899 inst.drawYear = drawYear; 8900 8901 prevText = this._get(inst, "prevText"); 8902 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 8903 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 8904 this._getFormatConfig(inst))); 8905 8906 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 8907 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 8908 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 8909 (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>")); 8910 8911 nextText = this._get(inst, "nextText"); 8912 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 8913 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 8914 this._getFormatConfig(inst))); 8915 8916 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 8917 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 8918 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 8919 (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>")); 8920 8921 currentText = this._get(inst, "currentText"); 8922 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 8923 currentText = (!navigationAsDateFormat ? currentText : 8924 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 8925 8926 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'>" + 8927 this._get(inst, "closeText") + "</button>" : ""); 8928 8929 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 8930 (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'" + 8931 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 8932 8933 firstDay = parseInt(this._get(inst, "firstDay"),10); 8934 firstDay = (isNaN(firstDay) ? 0 : firstDay); 8935 8936 showWeek = this._get(inst, "showWeek"); 8937 dayNames = this._get(inst, "dayNames"); 8938 dayNamesMin = this._get(inst, "dayNamesMin"); 8939 monthNames = this._get(inst, "monthNames"); 8940 monthNamesShort = this._get(inst, "monthNamesShort"); 8941 beforeShowDay = this._get(inst, "beforeShowDay"); 8942 showOtherMonths = this._get(inst, "showOtherMonths"); 8943 selectOtherMonths = this._get(inst, "selectOtherMonths"); 8944 defaultDate = this._getDefaultDate(inst); 8945 html = ""; 8946 dow; 8947 for (row = 0; row < numMonths[0]; row++) { 8948 group = ""; 8949 this.maxRows = 4; 8950 for (col = 0; col < numMonths[1]; col++) { 8951 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 8952 cornerClass = " ui-corner-all"; 8953 calender = ""; 8954 if (isMultiMonth) { 8955 calender += "<div class='ui-datepicker-group"; 8956 if (numMonths[1] > 1) { 8957 switch (col) { 8958 case 0: calender += " ui-datepicker-group-first"; 8959 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 8960 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 8961 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 8962 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 8963 } 8964 } 8965 calender += "'>"; 8966 } 8967 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 8968 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 8969 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 8970 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 8971 row > 0 || col > 0, monthNames, monthNamesShort) + /*// draw month headers 8972*/ 8973 "</div><table class='ui-datepicker-calendar'><thead>" + 8974 "<tr>"; 8975 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 8976 for (dow = 0; dow < 7; dow++) { /*// days of the week 8977*/ 8978 day = (dow + firstDay) % 7; 8979 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 8980 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 8981 } 8982 calender += thead + "</tr></thead><tbody>"; 8983 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 8984 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 8985 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 8986 } 8987 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 8988 curRows = Math.ceil((leadDays + daysInMonth) / 7); /*// calculate the number of rows to generate 8989*/ 8990 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 8991 this.maxRows = numRows; 8992 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 8993 for (dRow = 0; dRow < numRows; dRow++) { /*// create date picker rows 8994*/ 8995 calender += "<tr>"; 8996 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 8997 this._get(inst, "calculateWeek")(printDate) + "</td>"); 8998 for (dow = 0; dow < 7; dow++) { /*// create date picker days 8999*/ 9000 daySettings = (beforeShowDay ? 9001 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9002 otherMonth = (printDate.getMonth() !== drawMonth); 9003 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9004 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9005 tbody += "<td class='" + 9006 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + /*// highlight weekends 9007*/ 9008 (otherMonth ? " ui-datepicker-other-month" : "") + /*// highlight days from other months 9009*/ 9010 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || /*// user pressed key 9011*/ 9012 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9013 /*// or defaultDate is current printedDate and defaultDate is selectedDate 9014*/ 9015 " " + this._dayOverClass : "") + /*// highlight selected day 9016*/ 9017 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + /*// highlight unselectable days 9018*/ 9019 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + /*// highlight custom dates 9020*/ 9021 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + /*// highlight selected day 9022*/ 9023 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + /*// highlight today (if different) 9024*/ 9025 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + /*// cell title 9026*/ 9027 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + /*// actions 9028*/ 9029 (otherMonth && !showOtherMonths ? " " : /*// display for other months 9030*/ 9031 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9032 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9033 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + /*// highlight selected day 9034*/ 9035 (otherMonth ? " ui-priority-secondary" : "") + /*// distinguish dates from other months 9036*/ 9037 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; /*// display selectable date 9038*/ 9039 printDate.setDate(printDate.getDate() + 1); 9040 printDate = this._daylightSavingAdjust(printDate); 9041 } 9042 calender += tbody + "</tr>"; 9043 } 9044 drawMonth++; 9045 if (drawMonth > 11) { 9046 drawMonth = 0; 9047 drawYear++; 9048 } 9049 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9050 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9051 group += calender; 9052 } 9053 html += group; 9054 } 9055 html += buttonPanel; 9056 inst._keyEvent = false; 9057 return html; 9058 }, 9059 9060 /* Generate the month and year header. */ 9061 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9062 secondary, monthNames, monthNamesShort) { 9063 9064 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9065 changeMonth = this._get(inst, "changeMonth"), 9066 changeYear = this._get(inst, "changeYear"), 9067 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9068 html = "<div class='ui-datepicker-title'>", 9069 monthHtml = ""; 9070 9071 /*// month selection 9072*/ 9073 if (secondary || !changeMonth) { 9074 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9075 } else { 9076 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9077 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9078 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9079 for ( month = 0; month < 12; month++) { 9080 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9081 monthHtml += "<option value='" + month + "'" + 9082 (month === drawMonth ? " selected='selected'" : "") + 9083 ">" + monthNamesShort[month] + "</option>"; 9084 } 9085 } 9086 monthHtml += "</select>"; 9087 } 9088 9089 if (!showMonthAfterYear) { 9090 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9091 } 9092 9093 /*// year selection 9094*/ 9095 if ( !inst.yearshtml ) { 9096 inst.yearshtml = ""; 9097 if (secondary || !changeYear) { 9098 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9099 } else { 9100 /*// determine range of years to display 9101*/ 9102 years = this._get(inst, "yearRange").split(":"); 9103 thisYear = new Date().getFullYear(); 9104 determineYear = function(value) { 9105 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9106 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9107 parseInt(value, 10))); 9108 return (isNaN(year) ? thisYear : year); 9109 }; 9110 year = determineYear(years[0]); 9111 endYear = Math.max(year, determineYear(years[1] || "")); 9112 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9113 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9114 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9115 for (; year <= endYear; year++) { 9116 inst.yearshtml += "<option value='" + year + "'" + 9117 (year === drawYear ? " selected='selected'" : "") + 9118 ">" + year + "</option>"; 9119 } 9120 inst.yearshtml += "</select>"; 9121 9122 html += inst.yearshtml; 9123 inst.yearshtml = null; 9124 } 9125 } 9126 9127 html += this._get(inst, "yearSuffix"); 9128 if (showMonthAfterYear) { 9129 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9130 } 9131 html += "</div>"; /*// Close datepicker_header 9132*/ 9133 return html; 9134 }, 9135 9136 /* Adjust one of the date sub-fields. */ 9137 _adjustInstDate: function(inst, offset, period) { 9138 var year = inst.drawYear + (period === "Y" ? offset : 0), 9139 month = inst.drawMonth + (period === "M" ? offset : 0), 9140 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9141 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9142 9143 inst.selectedDay = date.getDate(); 9144 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9145 inst.drawYear = inst.selectedYear = date.getFullYear(); 9146 if (period === "M" || period === "Y") { 9147 this._notifyChange(inst); 9148 } 9149 }, 9150 9151 /* Ensure a date is within any min/max bounds. */ 9152 _restrictMinMax: function(inst, date) { 9153 var minDate = this._getMinMaxDate(inst, "min"), 9154 maxDate = this._getMinMaxDate(inst, "max"), 9155 newDate = (minDate && date < minDate ? minDate : date); 9156 return (maxDate && newDate > maxDate ? maxDate : newDate); 9157 }, 9158 9159 /* Notify change of month/year. */ 9160 _notifyChange: function(inst) { 9161 var onChange = this._get(inst, "onChangeMonthYear"); 9162 if (onChange) { 9163 onChange.apply((inst.input ? inst.input[0] : null), 9164 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9165 } 9166 }, 9167 9168 /* Determine the number of months to show. */ 9169 _getNumberOfMonths: function(inst) { 9170 var numMonths = this._get(inst, "numberOfMonths"); 9171 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9172 }, 9173 9174 /* Determine the current maximum date - ensure no time components are set. */ 9175 _getMinMaxDate: function(inst, minMax) { 9176 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9177 }, 9178 9179 /* Find the number of days in a given month. */ 9180 _getDaysInMonth: function(year, month) { 9181 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9182 }, 9183 9184 /* Find the day of the week of the first of a month. */ 9185 _getFirstDayOfMonth: function(year, month) { 9186 return new Date(year, month, 1).getDay(); 9187 }, 9188 9189 /* Determines if we should allow a "next/prev" month display change. */ 9190 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9191 var numMonths = this._getNumberOfMonths(inst), 9192 date = this._daylightSavingAdjust(new Date(curYear, 9193 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9194 9195 if (offset < 0) { 9196 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9197 } 9198 return this._isInRange(inst, date); 9199 }, 9200 9201 /* Is the given date in the accepted range? */ 9202 _isInRange: function(inst, date) { 9203 var yearSplit, currentYear, 9204 minDate = this._getMinMaxDate(inst, "min"), 9205 maxDate = this._getMinMaxDate(inst, "max"), 9206 minYear = null, 9207 maxYear = null, 9208 years = this._get(inst, "yearRange"); 9209 if (years){ 9210 yearSplit = years.split(":"); 9211 currentYear = new Date().getFullYear(); 9212 minYear = parseInt(yearSplit[0], 10); 9213 maxYear = parseInt(yearSplit[1], 10); 9214 if ( yearSplit[0].match(/[+\-].*/) ) { 9215 minYear += currentYear; 9216 } 9217 if ( yearSplit[1].match(/[+\-].*/) ) { 9218 maxYear += currentYear; 9219 } 9220 } 9221 9222 return ((!minDate || date.getTime() >= minDate.getTime()) && 9223 (!maxDate || date.getTime() <= maxDate.getTime()) && 9224 (!minYear || date.getFullYear() >= minYear) && 9225 (!maxYear || date.getFullYear() <= maxYear)); 9226 }, 9227 9228 /* Provide the configuration settings for formatting/parsing. */ 9229 _getFormatConfig: function(inst) { 9230 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9231 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9232 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9233 return {shortYearCutoff: shortYearCutoff, 9234 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9235 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9236 }, 9237 9238 /* Format the given date for display. */ 9239 _formatDate: function(inst, day, month, year) { 9240 if (!day) { 9241 inst.currentDay = inst.selectedDay; 9242 inst.currentMonth = inst.selectedMonth; 9243 inst.currentYear = inst.selectedYear; 9244 } 9245 var date = (day ? (typeof day === "object" ? day : 9246 this._daylightSavingAdjust(new Date(year, month, day))) : 9247 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9248 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9249 } 9250}); 9251 9252/* 9253 * Bind hover events for datepicker elements. 9254 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9255 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9256 */ 9257function bindHover(dpDiv) { 9258 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9259 return dpDiv.delegate(selector, "mouseout", function() { 9260 $(this).removeClass("ui-state-hover"); 9261 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9262 $(this).removeClass("ui-datepicker-prev-hover"); 9263 } 9264 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9265 $(this).removeClass("ui-datepicker-next-hover"); 9266 } 9267 }) 9268 .delegate(selector, "mouseover", function(){ 9269 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9270 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9271 $(this).addClass("ui-state-hover"); 9272 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9273 $(this).addClass("ui-datepicker-prev-hover"); 9274 } 9275 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9276 $(this).addClass("ui-datepicker-next-hover"); 9277 } 9278 } 9279 }); 9280} 9281 9282/* jQuery extend now ignores nulls! */ 9283function extendRemove(target, props) { 9284 $.extend(target, props); 9285 for (var name in props) { 9286 if (props[name] == null) { 9287 target[name] = props[name]; 9288 } 9289 } 9290 return target; 9291} 9292 9293/* Invoke the datepicker functionality. 9294 @param options string - a command, optionally followed by additional parameters or 9295 Object - settings for attaching new datepicker functionality 9296 @return jQuery object */ 9297$.fn.datepicker = function(options){ 9298 9299 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9300 if ( !this.length ) { 9301 return this; 9302 } 9303 9304 /* Initialise the date picker. */ 9305 if (!$.datepicker.initialized) { 9306 $(document).mousedown($.datepicker._checkExternalClick); 9307 $.datepicker.initialized = true; 9308 } 9309 9310 /* Append datepicker main container to body if not exist. */ 9311 if ($("#"+$.datepicker._mainDivId).length === 0) { 9312 $("body").append($.datepicker.dpDiv); 9313 } 9314 9315 var otherArgs = Array.prototype.slice.call(arguments, 1); 9316 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9317 return $.datepicker["_" + options + "Datepicker"]. 9318 apply($.datepicker, [this[0]].concat(otherArgs)); 9319 } 9320 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9321 return $.datepicker["_" + options + "Datepicker"]. 9322 apply($.datepicker, [this[0]].concat(otherArgs)); 9323 } 9324 return this.each(function() { 9325 typeof options === "string" ? 9326 $.datepicker["_" + options + "Datepicker"]. 9327 apply($.datepicker, [this].concat(otherArgs)) : 9328 $.datepicker._attachDatepicker(this, options); 9329 }); 9330}; 9331 9332$.datepicker = new Datepicker(); /*// singleton instance 9333*/ 9334$.datepicker.initialized = false; 9335$.datepicker.uuid = new Date().getTime(); 9336$.datepicker.version = "1.10.2"; 9337 9338/*// Workaround for #4055 9339*/ 9340/*// Add another global to avoid noConflict issues with inline event handlers 9341*/ 9342window["DP_jQuery_" + dpuuid] = $; 9343 9344})(jQuery); 9345(function( $, undefined ) { 9346 9347var sizeRelatedOptions = { 9348 buttons: true, 9349 height: true, 9350 maxHeight: true, 9351 maxWidth: true, 9352 minHeight: true, 9353 minWidth: true, 9354 width: true 9355 }, 9356 resizableRelatedOptions = { 9357 maxHeight: true, 9358 maxWidth: true, 9359 minHeight: true, 9360 minWidth: true 9361 }; 9362 9363$.widget( "ui.dialog", { 9364 version: "1.10.2", 9365 options: { 9366 appendTo: "body", 9367 autoOpen: true, 9368 buttons: [], 9369 closeOnEscape: true, 9370 closeText: "close", 9371 dialogClass: "", 9372 draggable: true, 9373 hide: null, 9374 height: "auto", 9375 maxHeight: null, 9376 maxWidth: null, 9377 minHeight: 150, 9378 minWidth: 150, 9379 modal: false, 9380 position: { 9381 my: "center", 9382 at: "center", 9383 of: window, 9384 collision: "fit", 9385 /*// Ensure the titlebar is always visible 9386*/ 9387 using: function( pos ) { 9388 var topOffset = $( this ).css( pos ).offset().top; 9389 if ( topOffset < 0 ) { 9390 $( this ).css( "top", pos.top - topOffset ); 9391 } 9392 } 9393 }, 9394 resizable: true, 9395 show: null, 9396 title: null, 9397 width: 300, 9398 9399 /*// callbacks 9400*/ 9401 beforeClose: null, 9402 close: null, 9403 drag: null, 9404 dragStart: null, 9405 dragStop: null, 9406 focus: null, 9407 open: null, 9408 resize: null, 9409 resizeStart: null, 9410 resizeStop: null 9411 }, 9412 9413 _create: function() { 9414 this.originalCss = { 9415 display: this.element[0].style.display, 9416 width: this.element[0].style.width, 9417 minHeight: this.element[0].style.minHeight, 9418 maxHeight: this.element[0].style.maxHeight, 9419 height: this.element[0].style.height 9420 }; 9421 this.originalPosition = { 9422 parent: this.element.parent(), 9423 index: this.element.parent().children().index( this.element ) 9424 }; 9425 this.originalTitle = this.element.attr("title"); 9426 this.options.title = this.options.title || this.originalTitle; 9427 9428 this._createWrapper(); 9429 9430 this.element 9431 .show() 9432 .removeAttr("title") 9433 .addClass("ui-dialog-content ui-widget-content") 9434 .appendTo( this.uiDialog ); 9435 9436 this._createTitlebar(); 9437 this._createButtonPane(); 9438 9439 if ( this.options.draggable && $.fn.draggable ) { 9440 this._makeDraggable(); 9441 } 9442 if ( this.options.resizable && $.fn.resizable ) { 9443 this._makeResizable(); 9444 } 9445 9446 this._isOpen = false; 9447 }, 9448 9449 _init: function() { 9450 if ( this.options.autoOpen ) { 9451 this.open(); 9452 } 9453 }, 9454 9455 _appendTo: function() { 9456 var element = this.options.appendTo; 9457 if ( element && (element.jquery || element.nodeType) ) { 9458 return $( element ); 9459 } 9460 return this.document.find( element || "body" ).eq( 0 ); 9461 }, 9462 9463 _destroy: function() { 9464 var next, 9465 originalPosition = this.originalPosition; 9466 9467 this._destroyOverlay(); 9468 9469 this.element 9470 .removeUniqueId() 9471 .removeClass("ui-dialog-content ui-widget-content") 9472 .css( this.originalCss ) 9473 /*// Without detaching first, the following becomes really slow 9474*/ 9475 .detach(); 9476 9477 this.uiDialog.stop( true, true ).remove(); 9478 9479 if ( this.originalTitle ) { 9480 this.element.attr( "title", this.originalTitle ); 9481 } 9482 9483 next = originalPosition.parent.children().eq( originalPosition.index ); 9484 /*// Don't try to place the dialog next to itself (#8613) 9485*/ 9486 if ( next.length && next[0] !== this.element[0] ) { 9487 next.before( this.element ); 9488 } else { 9489 originalPosition.parent.append( this.element ); 9490 } 9491 }, 9492 9493 widget: function() { 9494 return this.uiDialog; 9495 }, 9496 9497 disable: $.noop, 9498 enable: $.noop, 9499 9500 close: function( event ) { 9501 var that = this; 9502 9503 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9504 return; 9505 } 9506 9507 this._isOpen = false; 9508 this._destroyOverlay(); 9509 9510 if ( !this.opener.filter(":focusable").focus().length ) { 9511 /*// Hiding a focused element doesn't trigger blur in WebKit 9512*/ 9513 /*// so in case we have nothing to focus on, explicitly blur the active element 9514*/ 9515 /*// https://bugs.webkit.org/show_bug.cgi?id=47182 9516*/ 9517 $( this.document[0].activeElement ).blur(); 9518 } 9519 9520 this._hide( this.uiDialog, this.options.hide, function() { 9521 that._trigger( "close", event ); 9522 }); 9523 }, 9524 9525 isOpen: function() { 9526 return this._isOpen; 9527 }, 9528 9529 moveToTop: function() { 9530 this._moveToTop(); 9531 }, 9532 9533 _moveToTop: function( event, silent ) { 9534 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9535 if ( moved && !silent ) { 9536 this._trigger( "focus", event ); 9537 } 9538 return moved; 9539 }, 9540 9541 open: function() { 9542 var that = this; 9543 if ( this._isOpen ) { 9544 if ( this._moveToTop() ) { 9545 this._focusTabbable(); 9546 } 9547 return; 9548 } 9549 9550 this._isOpen = true; 9551 this.opener = $( this.document[0].activeElement ); 9552 9553 this._size(); 9554 this._position(); 9555 this._createOverlay(); 9556 this._moveToTop( null, true ); 9557 this._show( this.uiDialog, this.options.show, function() { 9558 that._focusTabbable(); 9559 that._trigger("focus"); 9560 }); 9561 9562 this._trigger("open"); 9563 }, 9564 9565 _focusTabbable: function() { 9566 /*// Set focus to the first match: 9567*/ 9568 /*// 1. First element inside the dialog matching [autofocus] 9569*/ 9570 /*// 2. Tabbable element inside the content element 9571*/ 9572 /*// 3. Tabbable element inside the buttonpane 9573*/ 9574 /*// 4. The close button 9575*/ 9576 /*// 5. The dialog itself 9577*/ 9578 var hasFocus = this.element.find("[autofocus]"); 9579 if ( !hasFocus.length ) { 9580 hasFocus = this.element.find(":tabbable"); 9581 } 9582 if ( !hasFocus.length ) { 9583 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9584 } 9585 if ( !hasFocus.length ) { 9586 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9587 } 9588 if ( !hasFocus.length ) { 9589 hasFocus = this.uiDialog; 9590 } 9591 hasFocus.eq( 0 ).focus(); 9592 }, 9593 9594 _keepFocus: function( event ) { 9595 function checkFocus() { 9596 var activeElement = this.document[0].activeElement, 9597 isActive = this.uiDialog[0] === activeElement || 9598 $.contains( this.uiDialog[0], activeElement ); 9599 if ( !isActive ) { 9600 this._focusTabbable(); 9601 } 9602 } 9603 event.preventDefault(); 9604 checkFocus.call( this ); 9605 /*// support: IE 9606*/ 9607 /*// IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9608*/ 9609 /*// so we check again later 9610*/ 9611 this._delay( checkFocus ); 9612 }, 9613 9614 _createWrapper: function() { 9615 this.uiDialog = $("<div>") 9616 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9617 this.options.dialogClass ) 9618 .hide() 9619 .attr({ 9620 /*// Setting tabIndex makes the div focusable 9621*/ 9622 tabIndex: -1, 9623 role: "dialog" 9624 }) 9625 .appendTo( this._appendTo() ); 9626 9627 this._on( this.uiDialog, { 9628 keydown: function( event ) { 9629 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9630 event.keyCode === $.ui.keyCode.ESCAPE ) { 9631 event.preventDefault(); 9632 this.close( event ); 9633 return; 9634 } 9635 9636 /*// prevent tabbing out of dialogs 9637*/ 9638 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9639 return; 9640 } 9641 var tabbables = this.uiDialog.find(":tabbable"), 9642 first = tabbables.filter(":first"), 9643 last = tabbables.filter(":last"); 9644 9645 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9646 first.focus( 1 ); 9647 event.preventDefault(); 9648 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9649 last.focus( 1 ); 9650 event.preventDefault(); 9651 } 9652 }, 9653 mousedown: function( event ) { 9654 if ( this._moveToTop( event ) ) { 9655 this._focusTabbable(); 9656 } 9657 } 9658 }); 9659 9660 /*// We assume that any existing aria-describedby attribute means 9661*/ 9662 /*// that the dialog content is marked up properly 9663*/ 9664 /*// otherwise we brute force the content as the description 9665*/ 9666 if ( !this.element.find("[aria-describedby]").length ) { 9667 this.uiDialog.attr({ 9668 "aria-describedby": this.element.uniqueId().attr("id") 9669 }); 9670 } 9671 }, 9672 9673 _createTitlebar: function() { 9674 var uiDialogTitle; 9675 9676 this.uiDialogTitlebar = $("<div>") 9677 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9678 .prependTo( this.uiDialog ); 9679 this._on( this.uiDialogTitlebar, { 9680 mousedown: function( event ) { 9681 /*// Don't prevent click on close button (#8838) 9682*/ 9683 /*// Focusing a dialog that is partially scrolled out of view 9684*/ 9685 /*// causes the browser to scroll it into view, preventing the click event 9686*/ 9687 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9688 /*// Dialog isn't getting focus when dragging (#8063) 9689*/ 9690 this.uiDialog.focus(); 9691 } 9692 } 9693 }); 9694 9695 this.uiDialogTitlebarClose = $("<button></button>") 9696 .button({ 9697 label: this.options.closeText, 9698 icons: { 9699 primary: "ui-icon-closethick" 9700 }, 9701 text: false 9702 }) 9703 .addClass("ui-dialog-titlebar-close") 9704 .appendTo( this.uiDialogTitlebar ); 9705 this._on( this.uiDialogTitlebarClose, { 9706 click: function( event ) { 9707 event.preventDefault(); 9708 this.close( event ); 9709 } 9710 }); 9711 9712 uiDialogTitle = $("<span>") 9713 .uniqueId() 9714 .addClass("ui-dialog-title") 9715 .prependTo( this.uiDialogTitlebar ); 9716 this._title( uiDialogTitle ); 9717 9718 this.uiDialog.attr({ 9719 "aria-labelledby": uiDialogTitle.attr("id") 9720 }); 9721 }, 9722 9723 _title: function( title ) { 9724 if ( !this.options.title ) { 9725 title.html(" "); 9726 } 9727 title.text( this.options.title ); 9728 }, 9729 9730 _createButtonPane: function() { 9731 this.uiDialogButtonPane = $("<div>") 9732 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9733 9734 this.uiButtonSet = $("<div>") 9735 .addClass("ui-dialog-buttonset") 9736 .appendTo( this.uiDialogButtonPane ); 9737 9738 this._createButtons(); 9739 }, 9740 9741 _createButtons: function() { 9742 var that = this, 9743 buttons = this.options.buttons; 9744 9745 /*// if we already have a button pane, remove it 9746*/ 9747 this.uiDialogButtonPane.remove(); 9748 this.uiButtonSet.empty(); 9749 9750 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 9751 this.uiDialog.removeClass("ui-dialog-buttons"); 9752 return; 9753 } 9754 9755 $.each( buttons, function( name, props ) { 9756 var click, buttonOptions; 9757 props = $.isFunction( props ) ? 9758 { click: props, text: name } : 9759 props; 9760 /*// Default to a non-submitting button 9761*/ 9762 props = $.extend( { type: "button" }, props ); 9763 /*// Change the context for the click callback to be the main element 9764*/ 9765 click = props.click; 9766 props.click = function() { 9767 click.apply( that.element[0], arguments ); 9768 }; 9769 buttonOptions = { 9770 icons: props.icons, 9771 text: props.showText 9772 }; 9773 delete props.icons; 9774 delete props.showText; 9775 $( "<button></button>", props ) 9776 .button( buttonOptions ) 9777 .appendTo( that.uiButtonSet ); 9778 }); 9779 this.uiDialog.addClass("ui-dialog-buttons"); 9780 this.uiDialogButtonPane.appendTo( this.uiDialog ); 9781 }, 9782 9783 _makeDraggable: function() { 9784 var that = this, 9785 options = this.options; 9786 9787 function filteredUi( ui ) { 9788 return { 9789 position: ui.position, 9790 offset: ui.offset 9791 }; 9792 } 9793 9794 this.uiDialog.draggable({ 9795 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 9796 handle: ".ui-dialog-titlebar", 9797 containment: "document", 9798 start: function( event, ui ) { 9799 $( this ).addClass("ui-dialog-dragging"); 9800 that._blockFrames(); 9801 that._trigger( "dragStart", event, filteredUi( ui ) ); 9802 }, 9803 drag: function( event, ui ) { 9804 that._trigger( "drag", event, filteredUi( ui ) ); 9805 }, 9806 stop: function( event, ui ) { 9807 options.position = [ 9808 ui.position.left - that.document.scrollLeft(), 9809 ui.position.top - that.document.scrollTop() 9810 ]; 9811 $( this ).removeClass("ui-dialog-dragging"); 9812 that._unblockFrames(); 9813 that._trigger( "dragStop", event, filteredUi( ui ) ); 9814 } 9815 }); 9816 }, 9817 9818 _makeResizable: function() { 9819 var that = this, 9820 options = this.options, 9821 handles = options.resizable, 9822 /*// .ui-resizable has position: relative defined in the stylesheet 9823*/ 9824 /*// but dialogs have to use absolute or fixed positioning 9825*/ 9826 position = this.uiDialog.css("position"), 9827 resizeHandles = typeof handles === "string" ? 9828 handles : 9829 "n,e,s,w,se,sw,ne,nw"; 9830 9831 function filteredUi( ui ) { 9832 return { 9833 originalPosition: ui.originalPosition, 9834 originalSize: ui.originalSize, 9835 position: ui.position, 9836 size: ui.size 9837 }; 9838 } 9839 9840 this.uiDialog.resizable({ 9841 cancel: ".ui-dialog-content", 9842 containment: "document", 9843 alsoResize: this.element, 9844 maxWidth: options.maxWidth, 9845 maxHeight: options.maxHeight, 9846 minWidth: options.minWidth, 9847 minHeight: this._minHeight(), 9848 handles: resizeHandles, 9849 start: function( event, ui ) { 9850 $( this ).addClass("ui-dialog-resizing"); 9851 that._blockFrames(); 9852 that._trigger( "resizeStart", event, filteredUi( ui ) ); 9853 }, 9854 resize: function( event, ui ) { 9855 that._trigger( "resize", event, filteredUi( ui ) ); 9856 }, 9857 stop: function( event, ui ) { 9858 options.height = $( this ).height(); 9859 options.width = $( this ).width(); 9860 $( this ).removeClass("ui-dialog-resizing"); 9861 that._unblockFrames(); 9862 that._trigger( "resizeStop", event, filteredUi( ui ) ); 9863 } 9864 }) 9865 .css( "position", position ); 9866 }, 9867 9868 _minHeight: function() { 9869 var options = this.options; 9870 9871 return options.height === "auto" ? 9872 options.minHeight : 9873 Math.min( options.minHeight, options.height ); 9874 }, 9875 9876 _position: function() { 9877 /*// Need to show the dialog to get the actual offset in the position plugin 9878*/ 9879 var isVisible = this.uiDialog.is(":visible"); 9880 if ( !isVisible ) { 9881 this.uiDialog.show(); 9882 } 9883 this.uiDialog.position( this.options.position ); 9884 if ( !isVisible ) { 9885 this.uiDialog.hide(); 9886 } 9887 }, 9888 9889 _setOptions: function( options ) { 9890 var that = this, 9891 resize = false, 9892 resizableOptions = {}; 9893 9894 $.each( options, function( key, value ) { 9895 that._setOption( key, value ); 9896 9897 if ( key in sizeRelatedOptions ) { 9898 resize = true; 9899 } 9900 if ( key in resizableRelatedOptions ) { 9901 resizableOptions[ key ] = value; 9902 } 9903 }); 9904 9905 if ( resize ) { 9906 this._size(); 9907 this._position(); 9908 } 9909 if ( this.uiDialog.is(":data(ui-resizable)") ) { 9910 this.uiDialog.resizable( "option", resizableOptions ); 9911 } 9912 }, 9913 9914 _setOption: function( key, value ) { 9915 /*jshint maxcomplexity:15*/ 9916 var isDraggable, isResizable, 9917 uiDialog = this.uiDialog; 9918 9919 if ( key === "dialogClass" ) { 9920 uiDialog 9921 .removeClass( this.options.dialogClass ) 9922 .addClass( value ); 9923 } 9924 9925 if ( key === "disabled" ) { 9926 return; 9927 } 9928 9929 this._super( key, value ); 9930 9931 if ( key === "appendTo" ) { 9932 this.uiDialog.appendTo( this._appendTo() ); 9933 } 9934 9935 if ( key === "buttons" ) { 9936 this._createButtons(); 9937 } 9938 9939 if ( key === "closeText" ) { 9940 this.uiDialogTitlebarClose.button({ 9941 /*// Ensure that we always pass a string 9942*/ 9943 label: "" + value 9944 }); 9945 } 9946 9947 if ( key === "draggable" ) { 9948 isDraggable = uiDialog.is(":data(ui-draggable)"); 9949 if ( isDraggable && !value ) { 9950 uiDialog.draggable("destroy"); 9951 } 9952 9953 if ( !isDraggable && value ) { 9954 this._makeDraggable(); 9955 } 9956 } 9957 9958 if ( key === "position" ) { 9959 this._position(); 9960 } 9961 9962 if ( key === "resizable" ) { 9963 /*// currently resizable, becoming non-resizable 9964*/ 9965 isResizable = uiDialog.is(":data(ui-resizable)"); 9966 if ( isResizable && !value ) { 9967 uiDialog.resizable("destroy"); 9968 } 9969 9970 /*// currently resizable, changing handles 9971*/ 9972 if ( isResizable && typeof value === "string" ) { 9973 uiDialog.resizable( "option", "handles", value ); 9974 } 9975 9976 /*// currently non-resizable, becoming resizable 9977*/ 9978 if ( !isResizable && value !== false ) { 9979 this._makeResizable(); 9980 } 9981 } 9982 9983 if ( key === "title" ) { 9984 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 9985 } 9986 }, 9987 9988 _size: function() { 9989 /*// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9990*/ 9991 /*// divs will both have width and height set, so we need to reset them 9992*/ 9993 var nonContentHeight, minContentHeight, maxContentHeight, 9994 options = this.options; 9995 9996 /*// Reset content sizing 9997*/ 9998 this.element.show().css({ 9999 width: "auto", 10000 minHeight: 0, 10001 maxHeight: "none", 10002 height: 0 10003 }); 10004 10005 if ( options.minWidth > options.width ) { 10006 options.width = options.minWidth; 10007 } 10008 10009 /*// reset wrapper sizing 10010*/ 10011 /*// determine the height of all the non-content elements 10012*/ 10013 nonContentHeight = this.uiDialog.css({ 10014 height: "auto", 10015 width: options.width 10016 }) 10017 .outerHeight(); 10018 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10019 maxContentHeight = typeof options.maxHeight === "number" ? 10020 Math.max( 0, options.maxHeight - nonContentHeight ) : 10021 "none"; 10022 10023 if ( options.height === "auto" ) { 10024 this.element.css({ 10025 minHeight: minContentHeight, 10026 maxHeight: maxContentHeight, 10027 height: "auto" 10028 }); 10029 } else { 10030 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10031 } 10032 10033 if (this.uiDialog.is(":data(ui-resizable)") ) { 10034 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10035 } 10036 }, 10037 10038 _blockFrames: function() { 10039 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10040 var iframe = $( this ); 10041 10042 return $( "<div>" ) 10043 .css({ 10044 position: "absolute",
10045 width: iframe.outerWidth(), 10046 height: iframe.outerHeight() 10047 }) 10048 .appendTo( iframe.parent() ) 10049 .offset( iframe.offset() )[0]; 10050 }); 10051 }, 10052 10053 _unblockFrames: function() { 10054 if ( this.iframeBlocks ) { 10055 this.iframeBlocks.remove(); 10056 delete this.iframeBlocks; 10057 } 10058 }, 10059 10060 _allowInteraction: function( event ) { 10061 if ( $( event.target ).closest(".ui-dialog").length ) { 10062 return true; 10063 } 10064 10065 /*// TODO: Remove hack when datepicker implements 10066*/ 10067 /*// the .ui-front logic (#8989) 10068*/ 10069 return !!$( event.target ).closest(".ui-datepicker").length; 10070 }, 10071 10072 _createOverlay: function() { 10073 if ( !this.options.modal ) { 10074 return; 10075 } 10076 10077 var that = this, 10078 widgetFullName = this.widgetFullName; 10079 if ( !$.ui.dialog.overlayInstances ) { 10080 /*// Prevent use of anchors and inputs. 10081*/ 10082 /*// We use a delay in case the overlay is created from an 10083*/ 10084 /*// event that we're going to be cancelling. (#2804) 10085*/ 10086 this._delay(function() { 10087 /*// Handle .dialog().dialog("close") (#4065) 10088*/ 10089 if ( $.ui.dialog.overlayInstances ) { 10090 this.document.bind( "focusin.dialog", function( event ) { 10091 if ( !that._allowInteraction( event ) ) { 10092 event.preventDefault(); 10093 $(".ui-dialog:visible:last .ui-dialog-content") 10094 .data( widgetFullName )._focusTabbable(); 10095 } 10096 }); 10097 } 10098 }); 10099 } 10100 10101 this.overlay = $("<div>") 10102 .addClass("ui-widget-overlay ui-front") 10103 .appendTo( this._appendTo() ); 10104 this._on( this.overlay, { 10105 mousedown: "_keepFocus" 10106 }); 10107 $.ui.dialog.overlayInstances++; 10108 }, 10109 10110 _destroyOverlay: function() { 10111 if ( !this.options.modal ) { 10112 return; 10113 } 10114 10115 if ( this.overlay ) { 10116 $.ui.dialog.overlayInstances--; 10117 10118 if ( !$.ui.dialog.overlayInstances ) { 10119 this.document.unbind( "focusin.dialog" ); 10120 } 10121 this.overlay.remove(); 10122 this.overlay = null; 10123 } 10124 } 10125}); 10126 10127$.ui.dialog.overlayInstances = 0; 10128 10129/*// DEPRECATED 10130*/ 10131if ( $.uiBackCompat !== false ) { 10132 /*// position option with array notation 10133*/ 10134 /*// just override with old implementation 10135*/ 10136 $.widget( "ui.dialog", $.ui.dialog, { 10137 _position: function() { 10138 var position = this.options.position, 10139 myAt = [], 10140 offset = [ 0, 0 ], 10141 isVisible; 10142 10143 if ( position ) { 10144 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10145 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10146 if ( myAt.length === 1 ) { 10147 myAt[1] = myAt[0]; 10148 } 10149 10150 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10151 if ( +myAt[ i ] === myAt[ i ] ) { 10152 offset[ i ] = myAt[ i ]; 10153 myAt[ i ] = offsetPosition; 10154 } 10155 }); 10156 10157 position = { 10158 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10159 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10160 at: myAt.join(" ") 10161 }; 10162 } 10163 10164 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10165 } else { 10166 position = $.ui.dialog.prototype.options.position; 10167 } 10168 10169 /*// need to show the dialog to get the actual offset in the position plugin 10170*/ 10171 isVisible = this.uiDialog.is(":visible"); 10172 if ( !isVisible ) { 10173 this.uiDialog.show(); 10174 } 10175 this.uiDialog.position( position ); 10176 if ( !isVisible ) { 10177 this.uiDialog.hide(); 10178 } 10179 } 10180 }); 10181} 10182 10183}( jQuery ) ); 10184(function( $, undefined ) { 10185 10186$.widget( "ui.menu", { 10187 version: "1.10.2", 10188 defaultElement: "<ul>", 10189 delay: 300, 10190 options: { 10191 icons: { 10192 submenu: "ui-icon-carat-1-e" 10193 }, 10194 menus: "ul", 10195 position: { 10196 my: "left top", 10197 at: "right top" 10198 }, 10199 role: "menu", 10200 10201 /*// callbacks 10202*/ 10203 blur: null, 10204 focus: null, 10205 select: null 10206 }, 10207 10208 _create: function() { 10209 this.activeMenu = this.element; 10210 /*// flag used to prevent firing of the click handler 10211*/ 10212 /*// as the event bubbles up through nested menus 10213*/ 10214 this.mouseHandled = false; 10215 this.element 10216 .uniqueId() 10217 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 10218 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 10219 .attr({ 10220 role: this.options.role, 10221 tabIndex: 0 10222 }) 10223 /*// need to catch all clicks on disabled menu 10224*/ 10225 /*// not possible through _on 10226*/ 10227 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 10228 if ( this.options.disabled ) { 10229 event.preventDefault(); 10230 } 10231 }, this )); 10232 10233 if ( this.options.disabled ) { 10234 this.element 10235 .addClass( "ui-state-disabled" ) 10236 .attr( "aria-disabled", "true" ); 10237 } 10238 10239 this._on({ 10240 /*// Prevent focus from sticking to links inside menu after clicking 10241*/ 10242 /*// them (focus should always stay on UL during navigation). 10243*/ 10244 "mousedown .ui-menu-item > a": function( event ) { 10245 event.preventDefault(); 10246 }, 10247 "click .ui-state-disabled > a": function( event ) { 10248 event.preventDefault(); 10249 }, 10250 "click .ui-menu-item:has(a)": function( event ) { 10251 var target = $( event.target ).closest( ".ui-menu-item" ); 10252 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 10253 this.mouseHandled = true; 10254 10255 this.select( event ); 10256 /*// Open submenu on click 10257*/ 10258 if ( target.has( ".ui-menu" ).length ) { 10259 this.expand( event ); 10260 } else if ( !this.element.is( ":focus" ) ) { 10261 /*// Redirect focus to the menu 10262*/ 10263 this.element.trigger( "focus", [ true ] ); 10264 10265 /*// If the active item is on the top level, let it stay active. 10266*/ 10267 /*// Otherwise, blur the active item since it is no longer visible. 10268*/ 10269 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 10270 clearTimeout( this.timer ); 10271 } 10272 } 10273 } 10274 }, 10275 "mouseenter .ui-menu-item": function( event ) { 10276 var target = $( event.currentTarget ); 10277 /*// Remove ui-state-active class from siblings of the newly focused menu item 10278*/ 10279 /*// to avoid a jump caused by adjacent elements both having a class with a border 10280*/ 10281 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 10282 this.focus( event, target ); 10283 }, 10284 mouseleave: "collapseAll", 10285 "mouseleave .ui-menu": "collapseAll", 10286 focus: function( event, keepActiveItem ) { 10287 /*// If there's already an active item, keep it active 10288*/ 10289 /*// If not, activate the first item 10290*/ 10291 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 10292 10293 if ( !keepActiveItem ) { 10294 this.focus( event, item ); 10295 } 10296 }, 10297 blur: function( event ) { 10298 this._delay(function() { 10299 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 10300 this.collapseAll( event ); 10301 } 10302 }); 10303 }, 10304 keydown: "_keydown" 10305 }); 10306 10307 this.refresh();
vendor: 141,224 bytes, lines 10308-15909
10308 10309 /*// Clicks outside of a menu collapse any open menus 10310*/ 10311 this._on( this.document, { 10312 click: function( event ) { 10313 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 10314 this.collapseAll( event ); 10315 } 10316 10317 /*// Reset the mouseHandled flag 10318*/ 10319 this.mouseHandled = false; 10320 } 10321 }); 10322 }, 10323 10324 _destroy: function() { 10325 /*// Destroy (sub)menus 10326*/ 10327 this.element 10328 .removeAttr( "aria-activedescendant" ) 10329 .find( ".ui-menu" ).addBack() 10330 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 10331 .removeAttr( "role" ) 10332 .removeAttr( "tabIndex" ) 10333 .removeAttr( "aria-labelledby" ) 10334 .removeAttr( "aria-expanded" ) 10335 .removeAttr( "aria-hidden" ) 10336 .removeAttr( "aria-disabled" ) 10337 .removeUniqueId() 10338 .show(); 10339 10340 /*// Destroy menu items 10341*/ 10342 this.element.find( ".ui-menu-item" ) 10343 .removeClass( "ui-menu-item" ) 10344 .removeAttr( "role" ) 10345 .removeAttr( "aria-disabled" ) 10346 .children( "a" ) 10347 .removeUniqueId() 10348 .removeClass( "ui-corner-all ui-state-hover" ) 10349 .removeAttr( "tabIndex" ) 10350 .removeAttr( "role" ) 10351 .removeAttr( "aria-haspopup" ) 10352 .children().each( function() { 10353 var elem = $( this ); 10354 if ( elem.data( "ui-menu-submenu-carat" ) ) { 10355 elem.remove(); 10356 } 10357 }); 10358 10359 /*// Destroy menu dividers 10360*/ 10361 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 10362 }, 10363 10364 _keydown: function( event ) { 10365 /*jshint maxcomplexity:20*/ 10366 var match, prev, character, skip, regex, 10367 preventDefault = true; 10368 10369 function escape( value ) { 10370 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 10371 } 10372 10373 switch ( event.keyCode ) { 10374 case $.ui.keyCode.PAGE_UP: 10375 this.previousPage( event ); 10376 break; 10377 case $.ui.keyCode.PAGE_DOWN: 10378 this.nextPage( event ); 10379 break; 10380 case $.ui.keyCode.HOME: 10381 this._move( "first", "first", event ); 10382 break; 10383 case $.ui.keyCode.END: 10384 this._move( "last", "last", event ); 10385 break; 10386 case $.ui.keyCode.UP: 10387 this.previous( event ); 10388 break; 10389 case $.ui.keyCode.DOWN: 10390 this.next( event ); 10391 break; 10392 case $.ui.keyCode.LEFT: 10393 this.collapse( event ); 10394 break; 10395 case $.ui.keyCode.RIGHT: 10396 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 10397 this.expand( event ); 10398 } 10399 break; 10400 case $.ui.keyCode.ENTER: 10401 case $.ui.keyCode.SPACE: 10402 this._activate( event ); 10403 break; 10404 case $.ui.keyCode.ESCAPE: 10405 this.collapse( event ); 10406 break; 10407 default: 10408 preventDefault = false; 10409 prev = this.previousFilter || ""; 10410 character = String.fromCharCode( event.keyCode ); 10411 skip = false; 10412 10413 clearTimeout( this.filterTimer ); 10414 10415 if ( character === prev ) { 10416 skip = true; 10417 } else { 10418 character = prev + character; 10419 } 10420 10421 regex = new RegExp( "^" + escape( character ), "i" ); 10422 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 10423 return regex.test( $( this ).children( "a" ).text() ); 10424 }); 10425 match = skip && match.index( this.active.next() ) !== -1 ? 10426 this.active.nextAll( ".ui-menu-item" ) : 10427 match; 10428 10429 /*// If no matches on the current filter, reset to the last character pressed 10430*/ 10431 /*// to move down the menu to the first item that starts with that character 10432*/ 10433 if ( !match.length ) { 10434 character = String.fromCharCode( event.keyCode ); 10435 regex = new RegExp( "^" + escape( character ), "i" ); 10436 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 10437 return regex.test( $( this ).children( "a" ).text() ); 10438 }); 10439 } 10440 10441 if ( match.length ) { 10442 this.focus( event, match ); 10443 if ( match.length > 1 ) { 10444 this.previousFilter = character; 10445 this.filterTimer = this._delay(function() { 10446 delete this.previousFilter; 10447 }, 1000 ); 10448 } else { 10449 delete this.previousFilter; 10450 } 10451 } else { 10452 delete this.previousFilter; 10453 } 10454 } 10455 10456 if ( preventDefault ) { 10457 event.preventDefault(); 10458 } 10459 }, 10460 10461 _activate: function( event ) { 10462 if ( !this.active.is( ".ui-state-disabled" ) ) { 10463 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 10464 this.expand( event ); 10465 } else { 10466 this.select( event ); 10467 } 10468 } 10469 }, 10470 10471 refresh: function() { 10472 var menus, 10473 icon = this.options.icons.submenu, 10474 submenus = this.element.find( this.options.menus ); 10475 10476 /*// Initialize nested menus 10477*/ 10478 submenus.filter( ":not(.ui-menu)" ) 10479 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 10480 .hide() 10481 .attr({ 10482 role: this.options.role, 10483 "aria-hidden": "true", 10484 "aria-expanded": "false" 10485 }) 10486 .each(function() { 10487 var menu = $( this ), 10488 item = menu.prev( "a" ), 10489 submenuCarat = $( "<span>" ) 10490 .addClass( "ui-menu-icon ui-icon " + icon ) 10491 .data( "ui-menu-submenu-carat", true ); 10492 10493 item 10494 .attr( "aria-haspopup", "true" ) 10495 .prepend( submenuCarat ); 10496 menu.attr( "aria-labelledby", item.attr( "id" ) ); 10497 }); 10498 10499 menus = submenus.add( this.element ); 10500 10501 /*// Don't refresh list items that are already adapted 10502*/ 10503 menus.children( ":not(.ui-menu-item):has(a)" ) 10504 .addClass( "ui-menu-item" ) 10505 .attr( "role", "presentation" ) 10506 .children( "a" ) 10507 .uniqueId() 10508 .addClass( "ui-corner-all" ) 10509 .attr({ 10510 tabIndex: -1, 10511 role: this._itemRole() 10512 }); 10513 10514 /*// Initialize unlinked menu-items containing spaces and/or dashes only as dividers 10515*/ 10516 menus.children( ":not(.ui-menu-item)" ).each(function() { 10517 var item = $( this ); 10518 /*// hyphen, em dash, en dash 10519*/ 10520 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 10521 item.addClass( "ui-widget-content ui-menu-divider" ); 10522 } 10523 }); 10524 10525 /*// Add aria-disabled attribute to any disabled menu item 10526*/ 10527 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 10528 10529 /*// If the active item has been removed, blur the menu 10530*/ 10531 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 10532 this.blur(); 10533 } 10534 }, 10535 10536 _itemRole: function() { 10537 return { 10538 menu: "menuitem", 10539 listbox: "option" 10540 }[ this.options.role ]; 10541 }, 10542 10543 _setOption: function( key, value ) { 10544 if ( key === "icons" ) { 10545 this.element.find( ".ui-menu-icon" ) 10546 .removeClass( this.options.icons.submenu ) 10547 .addClass( value.submenu ); 10548 } 10549 this._super( key, value ); 10550 }, 10551 10552 focus: function( event, item ) { 10553 var nested, focused; 10554 this.blur( event, event && event.type === "focus" ); 10555 10556 this._scrollIntoView( item ); 10557 10558 this.active = item.first(); 10559 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 10560 /*// Only update aria-activedescendant if there's a role 10561*/ 10562 /*// otherwise we assume focus is managed elsewhere 10563*/ 10564 if ( this.options.role ) { 10565 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 10566 } 10567 10568 /*// Highlight active parent menu item, if any 10569*/ 10570 this.active 10571 .parent() 10572 .closest( ".ui-menu-item" ) 10573 .children( "a:first" ) 10574 .addClass( "ui-state-active" ); 10575 10576 if ( event && event.type === "keydown" ) { 10577 this._close(); 10578 } else { 10579 this.timer = this._delay(function() { 10580 this._close(); 10581 }, this.delay ); 10582 } 10583 10584 nested = item.children( ".ui-menu" ); 10585 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 10586 this._startOpening(nested); 10587 } 10588 this.activeMenu = item.parent(); 10589 10590 this._trigger( "focus", event, { item: item } ); 10591 }, 10592 10593 _scrollIntoView: function( item ) { 10594 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 10595 if ( this._hasScroll() ) { 10596 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 10597 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 10598 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 10599 scroll = this.activeMenu.scrollTop(); 10600 elementHeight = this.activeMenu.height(); 10601 itemHeight = item.height(); 10602 10603 if ( offset < 0 ) { 10604 this.activeMenu.scrollTop( scroll + offset ); 10605 } else if ( offset + itemHeight > elementHeight ) { 10606 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 10607 } 10608 } 10609 }, 10610 10611 blur: function( event, fromFocus ) { 10612 if ( !fromFocus ) { 10613 clearTimeout( this.timer ); 10614 } 10615 10616 if ( !this.active ) { 10617 return; 10618 } 10619 10620 this.active.children( "a" ).removeClass( "ui-state-focus" ); 10621 this.active = null; 10622 10623 this._trigger( "blur", event, { item: this.active } ); 10624 }, 10625 10626 _startOpening: function( submenu ) { 10627 clearTimeout( this.timer ); 10628 10629 /*// Don't open if already open fixes a Firefox bug that caused a .5 pixel 10630*/ 10631 /*// shift in the submenu position when mousing over the carat icon 10632*/ 10633 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 10634 return; 10635 } 10636 10637 this.timer = this._delay(function() { 10638 this._close(); 10639 this._open( submenu ); 10640 }, this.delay ); 10641 }, 10642 10643 _open: function( submenu ) { 10644 var position = $.extend({ 10645 of: this.active 10646 }, this.options.position ); 10647 10648 clearTimeout( this.timer ); 10649 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 10650 .hide() 10651 .attr( "aria-hidden", "true" ); 10652 10653 submenu 10654 .show() 10655 .removeAttr( "aria-hidden" ) 10656 .attr( "aria-expanded", "true" ) 10657 .position( position ); 10658 }, 10659 10660 collapseAll: function( event, all ) { 10661 clearTimeout( this.timer ); 10662 this.timer = this._delay(function() { 10663 /*// If we were passed an event, look for the submenu that contains the event 10664*/ 10665 var currentMenu = all ? this.element : 10666 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 10667 10668 /*// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 10669*/ 10670 if ( !currentMenu.length ) { 10671 currentMenu = this.element; 10672 } 10673 10674 this._close( currentMenu ); 10675 10676 this.blur( event ); 10677 this.activeMenu = currentMenu; 10678 }, this.delay ); 10679 }, 10680 10681 /*// With no arguments, closes the currently active menu - if nothing is active 10682*/ 10683 /*// it closes all menus. If passed an argument, it will search for menus BELOW 10684*/ 10685 _close: function( startMenu ) { 10686 if ( !startMenu ) { 10687 startMenu = this.active ? this.active.parent() : this.element; 10688 } 10689 10690 startMenu 10691 .find( ".ui-menu" ) 10692 .hide() 10693 .attr( "aria-hidden", "true" ) 10694 .attr( "aria-expanded", "false" ) 10695 .end() 10696 .find( "a.ui-state-active" ) 10697 .removeClass( "ui-state-active" ); 10698 }, 10699 10700 collapse: function( event ) { 10701 var newItem = this.active && 10702 this.active.parent().closest( ".ui-menu-item", this.element ); 10703 if ( newItem && newItem.length ) { 10704 this._close(); 10705 this.focus( event, newItem ); 10706 } 10707 }, 10708 10709 expand: function( event ) { 10710 var newItem = this.active && 10711 this.active 10712 .children( ".ui-menu " ) 10713 .children( ".ui-menu-item" ) 10714 .first(); 10715 10716 if ( newItem && newItem.length ) { 10717 this._open( newItem.parent() ); 10718 10719 /*// Delay so Firefox will not hide activedescendant change in expanding submenu from AT 10720*/ 10721 this._delay(function() { 10722 this.focus( event, newItem ); 10723 }); 10724 } 10725 }, 10726 10727 next: function( event ) { 10728 this._move( "next", "first", event ); 10729 }, 10730 10731 previous: function( event ) { 10732 this._move( "prev", "last", event ); 10733 }, 10734 10735 isFirstItem: function() { 10736 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 10737 }, 10738 10739 isLastItem: function() { 10740 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 10741 }, 10742 10743 _move: function( direction, filter, event ) { 10744 var next; 10745 if ( this.active ) { 10746 if ( direction === "first" || direction === "last" ) { 10747 next = this.active 10748 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 10749 .eq( -1 ); 10750 } else { 10751 next = this.active 10752 [ direction + "All" ]( ".ui-menu-item" ) 10753 .eq( 0 ); 10754 } 10755 } 10756 if ( !next || !next.length || !this.active ) { 10757 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 10758 } 10759 10760 this.focus( event, next ); 10761 }, 10762 10763 nextPage: function( event ) { 10764 var item, base, height; 10765 10766 if ( !this.active ) { 10767 this.next( event ); 10768 return; 10769 } 10770 if ( this.isLastItem() ) { 10771 return; 10772 } 10773 if ( this._hasScroll() ) { 10774 base = this.active.offset().top; 10775 height = this.element.height(); 10776 this.active.nextAll( ".ui-menu-item" ).each(function() { 10777 item = $( this ); 10778 return item.offset().top - base - height < 0; 10779 }); 10780 10781 this.focus( event, item ); 10782 } else { 10783 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 10784 [ !this.active ? "first" : "last" ]() ); 10785 } 10786 }, 10787 10788 previousPage: function( event ) { 10789 var item, base, height; 10790 if ( !this.active ) { 10791 this.next( event ); 10792 return; 10793 } 10794 if ( this.isFirstItem() ) { 10795 return; 10796 } 10797 if ( this._hasScroll() ) { 10798 base = this.active.offset().top; 10799 height = this.element.height(); 10800 this.active.prevAll( ".ui-menu-item" ).each(function() { 10801 item = $( this ); 10802 return item.offset().top - base + height > 0; 10803 }); 10804 10805 this.focus( event, item ); 10806 } else { 10807 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 10808 } 10809 }, 10810 10811 _hasScroll: function() { 10812 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 10813 }, 10814 10815 select: function( event ) { 10816 /*// TODO: It should never be possible to not have an active item at this 10817*/ 10818 /*// point, but the tests don't trigger mouseenter before click. 10819*/ 10820 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 10821 var ui = { item: this.active }; 10822 if ( !this.active.has( ".ui-menu" ).length ) { 10823 this.collapseAll( event, true ); 10824 } 10825 this._trigger( "select", event, ui ); 10826 } 10827}); 10828 10829}( jQuery )); 10830(function( $, undefined ) { 10831 10832$.widget( "ui.progressbar", { 10833 version: "1.10.2", 10834 options: { 10835 max: 100, 10836 value: 0, 10837 10838 change: null, 10839 complete: null 10840 }, 10841 10842 min: 0, 10843 10844 _create: function() { 10845 /*// Constrain initial value 10846*/ 10847 this.oldValue = this.options.value = this._constrainedValue(); 10848 10849 this.element 10850 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10851 .attr({ 10852 /*// Only set static values, aria-valuenow and aria-valuemax are 10853*/ 10854 /*// set inside _refreshValue() 10855*/ 10856 role: "progressbar", 10857 "aria-valuemin": this.min 10858 }); 10859 10860 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 10861 .appendTo( this.element ); 10862 10863 this._refreshValue(); 10864 }, 10865 10866 _destroy: function() { 10867 this.element 10868 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 10869 .removeAttr( "role" ) 10870 .removeAttr( "aria-valuemin" ) 10871 .removeAttr( "aria-valuemax" ) 10872 .removeAttr( "aria-valuenow" ); 10873 10874 this.valueDiv.remove(); 10875 }, 10876 10877 value: function( newValue ) { 10878 if ( newValue === undefined ) { 10879 return this.options.value; 10880 } 10881 10882 this.options.value = this._constrainedValue( newValue ); 10883 this._refreshValue(); 10884 }, 10885 10886 _constrainedValue: function( newValue ) { 10887 if ( newValue === undefined ) { 10888 newValue = this.options.value; 10889 } 10890 10891 this.indeterminate = newValue === false; 10892 10893 /*// sanitize value 10894*/ 10895 if ( typeof newValue !== "number" ) { 10896 newValue = 0; 10897 } 10898 10899 return this.indeterminate ? false : 10900 Math.min( this.options.max, Math.max( this.min, newValue ) ); 10901 }, 10902 10903 _setOptions: function( options ) { 10904 /*// Ensure "value" option is set after other values (like max) 10905*/ 10906 var value = options.value; 10907 delete options.value; 10908 10909 this._super( options ); 10910 10911 this.options.value = this._constrainedValue( value ); 10912 this._refreshValue(); 10913 }, 10914 10915 _setOption: function( key, value ) { 10916 if ( key === "max" ) { 10917 /*// Don't allow a max less than min 10918*/ 10919 value = Math.max( this.min, value ); 10920 } 10921 10922 this._super( key, value ); 10923 }, 10924 10925 _percentage: function() { 10926 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 10927 }, 10928 10929 _refreshValue: function() { 10930 var value = this.options.value, 10931 percentage = this._percentage(); 10932 10933 this.valueDiv 10934 .toggle( this.indeterminate || value > this.min ) 10935 .toggleClass( "ui-corner-right", value === this.options.max ) 10936 .width( percentage.toFixed(0) + "%" ); 10937 10938 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 10939 10940 if ( this.indeterminate ) { 10941 this.element.removeAttr( "aria-valuenow" ); 10942 if ( !this.overlayDiv ) { 10943 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 10944 } 10945 } else { 10946 this.element.attr({ 10947 "aria-valuemax": this.options.max, 10948 "aria-valuenow": value 10949 }); 10950 if ( this.overlayDiv ) { 10951 this.overlayDiv.remove(); 10952 this.overlayDiv = null; 10953 } 10954 } 10955 10956 if ( this.oldValue !== value ) { 10957 this.oldValue = value; 10958 this._trigger( "change" ); 10959 } 10960 if ( value === this.options.max ) { 10961 this._trigger( "complete" ); 10962 } 10963 } 10964}); 10965 10966})( jQuery ); 10967(function( $, undefined ) { 10968 10969/*// number of pages in a slider 10970*/ 10971/*// (how many times can you page up/down to go through the whole range) 10972*/ 10973var numPages = 5; 10974 10975$.widget( "ui.slider", $.ui.mouse, { 10976 version: "1.10.2", 10977 widgetEventPrefix: "slide", 10978 10979 options: { 10980 animate: false, 10981 distance: 0, 10982 max: 100, 10983 min: 0, 10984 orientation: "horizontal", 10985 range: false, 10986 step: 1, 10987 value: 0, 10988 values: null, 10989 10990 /*// callbacks 10991*/ 10992 change: null, 10993 slide: null, 10994 start: null, 10995 stop: null 10996 }, 10997 10998 _create: function() { 10999 this._keySliding = false; 11000 this._mouseSliding = false; 11001 this._animateOff = true; 11002 this._handleIndex = null; 11003 this._detectOrientation(); 11004 this._mouseInit(); 11005 11006 this.element 11007 .addClass( "ui-slider" + 11008 " ui-slider-" + this.orientation + 11009 " ui-widget" + 11010 " ui-widget-content" + 11011 " ui-corner-all"); 11012 11013 this._refresh(); 11014 this._setOption( "disabled", this.options.disabled ); 11015 11016 this._animateOff = false; 11017 }, 11018 11019 _refresh: function() { 11020 this._createRange(); 11021 this._createHandles(); 11022 this._setupEvents(); 11023 this._refreshValue(); 11024 }, 11025 11026 _createHandles: function() { 11027 var i, handleCount, 11028 options = this.options, 11029 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 11030 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 11031 handles = []; 11032 11033 handleCount = ( options.values && options.values.length ) || 1; 11034 11035 if ( existingHandles.length > handleCount ) { 11036 existingHandles.slice( handleCount ).remove(); 11037 existingHandles = existingHandles.slice( 0, handleCount ); 11038 } 11039 11040 for ( i = existingHandles.length; i < handleCount; i++ ) { 11041 handles.push( handle ); 11042 } 11043 11044 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 11045 11046 this.handle = this.handles.eq( 0 ); 11047 11048 this.handles.each(function( i ) { 11049 $( this ).data( "ui-slider-handle-index", i ); 11050 }); 11051 }, 11052 11053 _createRange: function() { 11054 var options = this.options, 11055 classes = ""; 11056 11057 if ( options.range ) { 11058 if ( options.range === true ) { 11059 if ( !options.values ) { 11060 options.values = [ this._valueMin(), this._valueMin() ]; 11061 } else if ( options.values.length && options.values.length !== 2 ) { 11062 options.values = [ options.values[0], options.values[0] ]; 11063 } else if ( $.isArray( options.values ) ) { 11064 options.values = options.values.slice(0); 11065 } 11066 } 11067 11068 if ( !this.range || !this.range.length ) { 11069 this.range = $( "<div></div>" ) 11070 .appendTo( this.element ); 11071 11072 classes = "ui-slider-range" + 11073 /*// note: this isn't the most fittingly semantic framework class for this element, 11074*/ 11075 /*// but worked best visually with a variety of themes 11076*/ 11077 " ui-widget-header ui-corner-all"; 11078 } else { 11079 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 11080 /*// Handle range switching from true to min/max 11081*/ 11082 .css({ 11083 "left": "", 11084 "bottom": "" 11085 }); 11086 } 11087 11088 this.range.addClass( classes + 11089 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 11090 } else { 11091 this.range = $([]); 11092 } 11093 }, 11094 11095 _setupEvents: function() { 11096 var elements = this.handles.add( this.range ).filter( "a" ); 11097 this._off( elements ); 11098 this._on( elements, this._handleEvents ); 11099 this._hoverable( elements ); 11100 this._focusable( elements ); 11101 }, 11102 11103 _destroy: function() { 11104 this.handles.remove(); 11105 this.range.remove(); 11106 11107 this.element 11108 .removeClass( "ui-slider" + 11109 " ui-slider-horizontal" + 11110 " ui-slider-vertical" + 11111 " ui-widget" + 11112 " ui-widget-content" + 11113 " ui-corner-all" ); 11114 11115 this._mouseDestroy(); 11116 }, 11117 11118 _mouseCapture: function( event ) { 11119 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 11120 that = this, 11121 o = this.options; 11122 11123 if ( o.disabled ) { 11124 return false; 11125 } 11126 11127 this.elementSize = { 11128 width: this.element.outerWidth(), 11129 height: this.element.outerHeight() 11130 }; 11131 this.elementOffset = this.element.offset(); 11132 11133 position = { x: event.pageX, y: event.pageY }; 11134 normValue = this._normValueFromMouse( position ); 11135 distance = this._valueMax() - this._valueMin() + 1; 11136 this.handles.each(function( i ) { 11137 var thisDistance = Math.abs( normValue - that.values(i) ); 11138 if (( distance > thisDistance ) || 11139 ( distance === thisDistance && 11140 (i === that._lastChangedValue || that.values(i) === o.min ))) { 11141 distance = thisDistance; 11142 closestHandle = $( this ); 11143 index = i; 11144 } 11145 }); 11146 11147 allowed = this._start( event, index ); 11148 if ( allowed === false ) { 11149 return false; 11150 } 11151 this._mouseSliding = true; 11152 11153 this._handleIndex = index; 11154 11155 closestHandle 11156 .addClass( "ui-state-active" ) 11157 .focus(); 11158 11159 offset = closestHandle.offset(); 11160 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 11161 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 11162 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 11163 top: event.pageY - offset.top - 11164 ( closestHandle.height() / 2 ) - 11165 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 11166 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 11167 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 11168 }; 11169 11170 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 11171 this._slide( event, index, normValue ); 11172 } 11173 this._animateOff = true; 11174 return true; 11175 }, 11176 11177 _mouseStart: function() { 11178 return true; 11179 }, 11180 11181 _mouseDrag: function( event ) { 11182 var position = { x: event.pageX, y: event.pageY }, 11183 normValue = this._normValueFromMouse( position ); 11184 11185 this._slide( event, this._handleIndex, normValue ); 11186 11187 return false; 11188 }, 11189 11190 _mouseStop: function( event ) { 11191 this.handles.removeClass( "ui-state-active" ); 11192 this._mouseSliding = false; 11193 11194 this._stop( event, this._handleIndex ); 11195 this._change( event, this._handleIndex ); 11196 11197 this._handleIndex = null; 11198 this._clickOffset = null; 11199 this._animateOff = false; 11200 11201 return false; 11202 }, 11203 11204 _detectOrientation: function() { 11205 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 11206 }, 11207 11208 _normValueFromMouse: function( position ) { 11209 var pixelTotal, 11210 pixelMouse, 11211 percentMouse, 11212 valueTotal, 11213 valueMouse; 11214 11215 if ( this.orientation === "horizontal" ) { 11216 pixelTotal = this.elementSize.width; 11217 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 11218 } else { 11219 pixelTotal = this.elementSize.height; 11220 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 11221 } 11222 11223 percentMouse = ( pixelMouse / pixelTotal ); 11224 if ( percentMouse > 1 ) { 11225 percentMouse = 1; 11226 } 11227 if ( percentMouse < 0 ) { 11228 percentMouse = 0; 11229 } 11230 if ( this.orientation === "vertical" ) { 11231 percentMouse = 1 - percentMouse; 11232 } 11233 11234 valueTotal = this._valueMax() - this._valueMin(); 11235 valueMouse = this._valueMin() + percentMouse * valueTotal; 11236 11237 return this._trimAlignValue( valueMouse ); 11238 }, 11239 11240 _start: function( event, index ) { 11241 var uiHash = { 11242 handle: this.handles[ index ], 11243 value: this.value() 11244 }; 11245 if ( this.options.values && this.options.values.length ) { 11246 uiHash.value = this.values( index ); 11247 uiHash.values = this.values(); 11248 } 11249 return this._trigger( "start", event, uiHash ); 11250 }, 11251 11252 _slide: function( event, index, newVal ) { 11253 var otherVal, 11254 newValues, 11255 allowed; 11256 11257 if ( this.options.values && this.options.values.length ) { 11258 otherVal = this.values( index ? 0 : 1 ); 11259 11260 if ( ( this.options.values.length === 2 && this.options.range === true ) && 11261 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 11262 ) { 11263 newVal = otherVal; 11264 } 11265 11266 if ( newVal !== this.values( index ) ) { 11267 newValues = this.values(); 11268 newValues[ index ] = newVal; 11269 /*// A slide can be canceled by returning false from the slide callback 11270*/ 11271 allowed = this._trigger( "slide", event, { 11272 handle: this.handles[ index ], 11273 value: newVal, 11274 values: newValues 11275 } ); 11276 otherVal = this.values( index ? 0 : 1 ); 11277 if ( allowed !== false ) { 11278 this.values( index, newVal, true ); 11279 } 11280 } 11281 } else { 11282 if ( newVal !== this.value() ) { 11283 /*// A slide can be canceled by returning false from the slide callback 11284*/ 11285 allowed = this._trigger( "slide", event, { 11286 handle: this.handles[ index ], 11287 value: newVal 11288 } ); 11289 if ( allowed !== false ) { 11290 this.value( newVal ); 11291 } 11292 } 11293 } 11294 }, 11295 11296 _stop: function( event, index ) { 11297 var uiHash = { 11298 handle: this.handles[ index ], 11299 value: this.value() 11300 }; 11301 if ( this.options.values && this.options.values.length ) { 11302 uiHash.value = this.values( index ); 11303 uiHash.values = this.values(); 11304 } 11305 11306 this._trigger( "stop", event, uiHash ); 11307 }, 11308 11309 _change: function( event, index ) { 11310 if ( !this._keySliding && !this._mouseSliding ) { 11311 var uiHash = { 11312 handle: this.handles[ index ], 11313 value: this.value() 11314 }; 11315 if ( this.options.values && this.options.values.length ) { 11316 uiHash.value = this.values( index ); 11317 uiHash.values = this.values(); 11318 } 11319 11320 //store the last changed value index for reference when handles overlap 11321 this._lastChangedValue = index; 11322 11323 this._trigger( "change", event, uiHash ); 11324 } 11325 }, 11326 11327 value: function( newValue ) { 11328 if ( arguments.length ) { 11329 this.options.value = this._trimAlignValue( newValue ); 11330 this._refreshValue(); 11331 this._change( null, 0 ); 11332 return; 11333 } 11334 11335 return this._value(); 11336 }, 11337 11338 values: function( index, newValue ) { 11339 var vals, 11340 newValues, 11341 i; 11342 11343 if ( arguments.length > 1 ) { 11344 this.options.values[ index ] = this._trimAlignValue( newValue ); 11345 this._refreshValue(); 11346 this._change( null, index ); 11347 return; 11348 } 11349 11350 if ( arguments.length ) { 11351 if ( $.isArray( arguments[ 0 ] ) ) { 11352 vals = this.options.values; 11353 newValues = arguments[ 0 ]; 11354 for ( i = 0; i < vals.length; i += 1 ) { 11355 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 11356 this._change( null, i ); 11357 } 11358 this._refreshValue(); 11359 } else { 11360 if ( this.options.values && this.options.values.length ) { 11361 return this._values( index ); 11362 } else { 11363 return this.value(); 11364 } 11365 } 11366 } else { 11367 return this._values(); 11368 } 11369 }, 11370 11371 _setOption: function( key, value ) { 11372 var i, 11373 valsLength = 0; 11374 11375 if ( key === "range" && this.options.range === true ) { 11376 if ( value === "min" ) { 11377 this.options.value = this._values( 0 ); 11378 this.options.values = null; 11379 } else if ( value === "max" ) { 11380 this.options.value = this._values( this.options.values.length-1 ); 11381 this.options.values = null; 11382 } 11383 } 11384 11385 if ( $.isArray( this.options.values ) ) { 11386 valsLength = this.options.values.length; 11387 } 11388 11389 $.Widget.prototype._setOption.apply( this, arguments ); 11390 11391 switch ( key ) { 11392 case "orientation": 11393 this._detectOrientation(); 11394 this.element 11395 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 11396 .addClass( "ui-slider-" + this.orientation ); 11397 this._refreshValue(); 11398 break; 11399 case "value": 11400 this._animateOff = true; 11401 this._refreshValue(); 11402 this._change( null, 0 ); 11403 this._animateOff = false; 11404 break; 11405 case "values": 11406 this._animateOff = true; 11407 this._refreshValue(); 11408 for ( i = 0; i < valsLength; i += 1 ) { 11409 this._change( null, i ); 11410 } 11411 this._animateOff = false; 11412 break; 11413 case "min": 11414 case "max": 11415 this._animateOff = true; 11416 this._refreshValue(); 11417 this._animateOff = false; 11418 break; 11419 case "range": 11420 this._animateOff = true; 11421 this._refresh(); 11422 this._animateOff = false; 11423 break; 11424 } 11425 }, 11426 11427 //internal value getter 11428 /*// _value() returns value trimmed by min and max, aligned by step 11429*/ 11430 _value: function() { 11431 var val = this.options.value; 11432 val = this._trimAlignValue( val ); 11433 11434 return val; 11435 }, 11436 11437 //internal values getter 11438 /*// _values() returns array of values trimmed by min and max, aligned by step 11439*/ 11440 /*// _values( index ) returns single value trimmed by min and max, aligned by step 11441*/ 11442 _values: function( index ) { 11443 var val, 11444 vals, 11445 i; 11446 11447 if ( arguments.length ) { 11448 val = this.options.values[ index ]; 11449 val = this._trimAlignValue( val ); 11450 11451 return val; 11452 } else if ( this.options.values && this.options.values.length ) { 11453 /*// .slice() creates a copy of the array 11454*/ 11455 /*// this copy gets trimmed by min and max and then returned 11456*/ 11457 vals = this.options.values.slice(); 11458 for ( i = 0; i < vals.length; i+= 1) { 11459 vals[ i ] = this._trimAlignValue( vals[ i ] ); 11460 } 11461 11462 return vals; 11463 } else { 11464 return []; 11465 } 11466 }, 11467 11468 /*// returns the step-aligned value that val is closest to, between (inclusive) min and max 11469*/ 11470 _trimAlignValue: function( val ) { 11471 if ( val <= this._valueMin() ) { 11472 return this._valueMin(); 11473 } 11474 if ( val >= this._valueMax() ) { 11475 return this._valueMax(); 11476 } 11477 var step = ( this.options.step > 0 ) ? this.options.step : 1, 11478 valModStep = (val - this._valueMin()) % step, 11479 alignValue = val - valModStep; 11480 11481 if ( Math.abs(valModStep) * 2 >= step ) { 11482 alignValue += ( valModStep > 0 ) ? step : ( -step ); 11483 } 11484 11485 /*// Since JavaScript has problems with large floats, round 11486*/ 11487 /*// the final value to 5 digits after the decimal point (see #4124) 11488*/ 11489 return parseFloat( alignValue.toFixed(5) ); 11490 }, 11491 11492 _valueMin: function() { 11493 return this.options.min; 11494 }, 11495 11496 _valueMax: function() { 11497 return this.options.max; 11498 }, 11499 11500 _refreshValue: function() { 11501 var lastValPercent, valPercent, value, valueMin, valueMax, 11502 oRange = this.options.range, 11503 o = this.options, 11504 that = this, 11505 animate = ( !this._animateOff ) ? o.animate : false, 11506 _set = {}; 11507 11508 if ( this.options.values && this.options.values.length ) { 11509 this.handles.each(function( i ) { 11510 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 11511 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 11512 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 11513 if ( that.options.range === true ) { 11514 if ( that.orientation === "horizontal" ) { 11515 if ( i === 0 ) { 11516 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 11517 } 11518 if ( i === 1 ) { 11519 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 11520 } 11521 } else { 11522 if ( i === 0 ) { 11523 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 11524 } 11525 if ( i === 1 ) { 11526 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 11527 } 11528 } 11529 } 11530 lastValPercent = valPercent; 11531 }); 11532 } else { 11533 value = this.value(); 11534 valueMin = this._valueMin(); 11535 valueMax = this._valueMax(); 11536 valPercent = ( valueMax !== valueMin ) ? 11537 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 11538 0; 11539 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 11540 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 11541 11542 if ( oRange === "min" && this.orientation === "horizontal" ) { 11543 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 11544 } 11545 if ( oRange === "max" && this.orientation === "horizontal" ) { 11546 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 11547 } 11548 if ( oRange === "min" && this.orientation === "vertical" ) { 11549 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 11550 } 11551 if ( oRange === "max" && this.orientation === "vertical" ) { 11552 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 11553 } 11554 } 11555 }, 11556 11557 _handleEvents: { 11558 keydown: function( event ) { 11559 /*jshint maxcomplexity:25*/ 11560 var allowed, curVal, newVal, step, 11561 index = $( event.target ).data( "ui-slider-handle-index" ); 11562 11563 switch ( event.keyCode ) { 11564 case $.ui.keyCode.HOME: 11565 case $.ui.keyCode.END: 11566 case $.ui.keyCode.PAGE_UP: 11567 case $.ui.keyCode.PAGE_DOWN: 11568 case $.ui.keyCode.UP: 11569 case $.ui.keyCode.RIGHT: 11570 case $.ui.keyCode.DOWN: 11571 case $.ui.keyCode.LEFT: 11572 event.preventDefault(); 11573 if ( !this._keySliding ) { 11574 this._keySliding = true; 11575 $( event.target ).addClass( "ui-state-active" ); 11576 allowed = this._start( event, index ); 11577 if ( allowed === false ) { 11578 return; 11579 } 11580 } 11581 break; 11582 } 11583 11584 step = this.options.step; 11585 if ( this.options.values && this.options.values.length ) { 11586 curVal = newVal = this.values( index ); 11587 } else { 11588 curVal = newVal = this.value(); 11589 } 11590 11591 switch ( event.keyCode ) { 11592 case $.ui.keyCode.HOME: 11593 newVal = this._valueMin(); 11594 break; 11595 case $.ui.keyCode.END: 11596 newVal = this._valueMax(); 11597 break; 11598 case $.ui.keyCode.PAGE_UP: 11599 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 11600 break; 11601 case $.ui.keyCode.PAGE_DOWN: 11602 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 11603 break; 11604 case $.ui.keyCode.UP: 11605 case $.ui.keyCode.RIGHT: 11606 if ( curVal === this._valueMax() ) { 11607 return; 11608 } 11609 newVal = this._trimAlignValue( curVal + step ); 11610 break; 11611 case $.ui.keyCode.DOWN: 11612 case $.ui.keyCode.LEFT: 11613 if ( curVal === this._valueMin() ) { 11614 return; 11615 } 11616 newVal = this._trimAlignValue( curVal - step ); 11617 break; 11618 } 11619 11620 this._slide( event, index, newVal ); 11621 }, 11622 click: function( event ) { 11623 event.preventDefault(); 11624 }, 11625 keyup: function( event ) { 11626 var index = $( event.target ).data( "ui-slider-handle-index" ); 11627 11628 if ( this._keySliding ) { 11629 this._keySliding = false; 11630 this._stop( event, index ); 11631 this._change( event, index ); 11632 $( event.target ).removeClass( "ui-state-active" ); 11633 } 11634 } 11635 } 11636 11637}); 11638 11639}(jQuery)); 11640(function( $ ) { 11641 11642function modifier( fn ) { 11643 return function() { 11644 var previous = this.element.val(); 11645 fn.apply( this, arguments ); 11646 this._refresh(); 11647 if ( previous !== this.element.val() ) { 11648 this._trigger( "change" ); 11649 } 11650 }; 11651} 11652 11653$.widget( "ui.spinner", { 11654 version: "1.10.2", 11655 defaultElement: "<input>", 11656 widgetEventPrefix: "spin", 11657 options: { 11658 culture: null, 11659 icons: { 11660 down: "ui-icon-triangle-1-s", 11661 up: "ui-icon-triangle-1-n" 11662 }, 11663 incremental: true, 11664 max: null, 11665 min: null, 11666 numberFormat: null, 11667 page: 10, 11668 step: 1, 11669 11670 change: null, 11671 spin: null, 11672 start: null, 11673 stop: null 11674 }, 11675 11676 _create: function() { 11677 /*// handle string values that need to be parsed 11678*/ 11679 this._setOption( "max", this.options.max ); 11680 this._setOption( "min", this.options.min ); 11681 this._setOption( "step", this.options.step ); 11682 11683 /*// format the value, but don't constrain 11684*/ 11685 this._value( this.element.val(), true ); 11686 11687 this._draw(); 11688 this._on( this._events ); 11689 this._refresh(); 11690 11691 /*// turning off autocomplete prevents the browser from remembering the 11692*/ 11693 /*// value when navigating through history, so we re-enable autocomplete 11694*/ 11695 /*// if the page is unloaded before the widget is destroyed. #7790 11696*/ 11697 this._on( this.window, { 11698 beforeunload: function() { 11699 this.element.removeAttr( "autocomplete" ); 11700 } 11701 }); 11702 }, 11703 11704 _getCreateOptions: function() { 11705 var options = {}, 11706 element = this.element; 11707 11708 $.each( [ "min", "max", "step" ], function( i, option ) { 11709 var value = element.attr( option ); 11710 if ( value !== undefined && value.length ) { 11711 options[ option ] = value; 11712 } 11713 }); 11714 11715 return options; 11716 }, 11717 11718 _events: { 11719 keydown: function( event ) { 11720 if ( this._start( event ) && this._keydown( event ) ) { 11721 event.preventDefault(); 11722 } 11723 }, 11724 keyup: "_stop", 11725 focus: function() { 11726 this.previous = this.element.val(); 11727 }, 11728 blur: function( event ) { 11729 if ( this.cancelBlur ) { 11730 delete this.cancelBlur; 11731 return; 11732 } 11733 11734 this._stop(); 11735 this._refresh(); 11736 if ( this.previous !== this.element.val() ) { 11737 this._trigger( "change", event ); 11738 } 11739 }, 11740 mousewheel: function( event, delta ) { 11741 if ( !delta ) { 11742 return; 11743 } 11744 if ( !this.spinning && !this._start( event ) ) { 11745 return false; 11746 } 11747 11748 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 11749 clearTimeout( this.mousewheelTimer ); 11750 this.mousewheelTimer = this._delay(function() { 11751 if ( this.spinning ) { 11752 this._stop( event ); 11753 } 11754 }, 100 ); 11755 event.preventDefault(); 11756 }, 11757 "mousedown .ui-spinner-button": function( event ) { 11758 var previous; 11759 11760 /*// We never want the buttons to have focus; whenever the user is 11761*/ 11762 /*// interacting with the spinner, the focus should be on the input. 11763*/ 11764 /*// If the input is focused then this.previous is properly set from 11765*/ 11766 /*// when the input first received focus. If the input is not focused 11767*/ 11768 /*// then we need to set this.previous based on the value before spinning. 11769*/ 11770 previous = this.element[0] === this.document[0].activeElement ? 11771 this.previous : this.element.val(); 11772 function checkFocus() { 11773 var isActive = this.element[0] === this.document[0].activeElement; 11774 if ( !isActive ) { 11775 this.element.focus(); 11776 this.previous = previous; 11777 /*// support: IE 11778*/ 11779 /*// IE sets focus asynchronously, so we need to check if focus 11780*/ 11781 /*// moved off of the input because the user clicked on the button. 11782*/ 11783 this._delay(function() { 11784 this.previous = previous; 11785 }); 11786 } 11787 } 11788 11789 /*// ensure focus is on (or stays on) the text field 11790*/ 11791 event.preventDefault(); 11792 checkFocus.call( this ); 11793 11794 /*// support: IE 11795*/ 11796 /*// IE doesn't prevent moving focus even with event.preventDefault() 11797*/ 11798 /*// so we set a flag to know when we should ignore the blur event 11799*/ 11800 /*// and check (again) if focus moved off of the input. 11801*/ 11802 this.cancelBlur = true; 11803 this._delay(function() { 11804 delete this.cancelBlur; 11805 checkFocus.call( this ); 11806 }); 11807 11808 if ( this._start( event ) === false ) { 11809 return; 11810 } 11811 11812 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11813 }, 11814 "mouseup .ui-spinner-button": "_stop", 11815 "mouseenter .ui-spinner-button": function( event ) { 11816 /*// button will add ui-state-active if mouse was down while mouseleave and kept down 11817*/ 11818 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 11819 return; 11820 } 11821 11822 if ( this._start( event ) === false ) { 11823 return false; 11824 } 11825 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 11826 }, 11827 /*// TODO: do we really want to consider this a stop? 11828*/ 11829 /*// shouldn't we just stop the repeater and wait until mouseup before 11830*/ 11831 /*// we trigger the stop event? 11832*/ 11833 "mouseleave .ui-spinner-button": "_stop" 11834 }, 11835 11836 _draw: function() { 11837 var uiSpinner = this.uiSpinner = this.element 11838 .addClass( "ui-spinner-input" ) 11839 .attr( "autocomplete", "off" ) 11840 .wrap( this._uiSpinnerHtml() ) 11841 .parent() 11842 /*// add buttons 11843*/ 11844 .append( this._buttonHtml() ); 11845 11846 this.element.attr( "role", "spinbutton" ); 11847 11848 /*// button bindings 11849*/ 11850 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 11851 .attr( "tabIndex", -1 ) 11852 .button() 11853 .removeClass( "ui-corner-all" ); 11854 11855 /*// IE 6 doesn't understand height: 50% for the buttons 11856*/ 11857 /*// unless the wrapper has an explicit height 11858*/ 11859 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 11860 uiSpinner.height() > 0 ) { 11861 uiSpinner.height( uiSpinner.height() ); 11862 } 11863 11864 /*// disable spinner if element was already disabled 11865*/ 11866 if ( this.options.disabled ) { 11867 this.disable(); 11868 } 11869 }, 11870 11871 _keydown: function( event ) { 11872 var options = this.options, 11873 keyCode = $.ui.keyCode; 11874 11875 switch ( event.keyCode ) { 11876 case keyCode.UP: 11877 this._repeat( null, 1, event ); 11878 return true; 11879 case keyCode.DOWN: 11880 this._repeat( null, -1, event ); 11881 return true; 11882 case keyCode.PAGE_UP: 11883 this._repeat( null, options.page, event ); 11884 return true; 11885 case keyCode.PAGE_DOWN: 11886 this._repeat( null, -options.page, event ); 11887 return true; 11888 } 11889 11890 return false; 11891 }, 11892 11893 _uiSpinnerHtml: function() { 11894 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 11895 }, 11896 11897 _buttonHtml: function() { 11898 return "" + 11899 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 11900 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 11901 "</a>" + 11902 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 11903 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 11904 "</a>"; 11905 }, 11906 11907 _start: function( event ) { 11908 if ( !this.spinning && this._trigger( "start", event ) === false ) { 11909 return false; 11910 } 11911 11912 if ( !this.counter ) { 11913 this.counter = 1; 11914 } 11915 this.spinning = true; 11916 return true; 11917 }, 11918 11919 _repeat: function( i, steps, event ) { 11920 i = i || 500; 11921 11922 clearTimeout( this.timer ); 11923 this.timer = this._delay(function() { 11924 this._repeat( 40, steps, event ); 11925 }, i ); 11926 11927 this._spin( steps * this.options.step, event ); 11928 }, 11929 11930 _spin: function( step, event ) { 11931 var value = this.value() || 0; 11932 11933 if ( !this.counter ) { 11934 this.counter = 1; 11935 } 11936 11937 value = this._adjustValue( value + step * this._increment( this.counter ) ); 11938 11939 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 11940 this._value( value ); 11941 this.counter++; 11942 } 11943 }, 11944 11945 _increment: function( i ) { 11946 var incremental = this.options.incremental; 11947 11948 if ( incremental ) { 11949 return $.isFunction( incremental ) ? 11950 incremental( i ) : 11951 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 11952 } 11953 11954 return 1; 11955 }, 11956 11957 _precision: function() { 11958 var precision = this._precisionOf( this.options.step ); 11959 if ( this.options.min !== null ) { 11960 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 11961 } 11962 return precision; 11963 }, 11964 11965 _precisionOf: function( num ) { 11966 var str = num.toString(), 11967 decimal = str.indexOf( "." ); 11968 return decimal === -1 ? 0 : str.length - decimal - 1; 11969 }, 11970 11971 _adjustValue: function( value ) { 11972 var base, aboveMin, 11973 options = this.options; 11974 11975 /*// make sure we're at a valid step 11976*/ 11977 /*// - find out where we are relative to the base (min or 0) 11978*/ 11979 base = options.min !== null ? options.min : 0; 11980 aboveMin = value - base; 11981 /*// - round to the nearest step 11982*/ 11983 aboveMin = Math.round(aboveMin / options.step) * options.step; 11984 /*// - rounding is based on 0, so adjust back to our base 11985*/ 11986 value = base + aboveMin; 11987 11988 /*// fix precision from bad JS floating point math 11989*/ 11990 value = parseFloat( value.toFixed( this._precision() ) ); 11991 11992 /*// clamp the value 11993*/ 11994 if ( options.max !== null && value > options.max) { 11995 return options.max; 11996 } 11997 if ( options.min !== null && value < options.min ) { 11998 return options.min; 11999 } 12000 12001 return value; 12002 }, 12003 12004 _stop: function( event ) { 12005 if ( !this.spinning ) { 12006 return; 12007 } 12008 12009 clearTimeout( this.timer ); 12010 clearTimeout( this.mousewheelTimer ); 12011 this.counter = 0; 12012 this.spinning = false; 12013 this._trigger( "stop", event ); 12014 }, 12015 12016 _setOption: function( key, value ) { 12017 if ( key === "culture" || key === "numberFormat" ) { 12018 var prevValue = this._parse( this.element.val() ); 12019 this.options[ key ] = value; 12020 this.element.val( this._format( prevValue ) ); 12021 return; 12022 } 12023 12024 if ( key === "max" || key === "min" || key === "step" ) { 12025 if ( typeof value === "string" ) { 12026 value = this._parse( value ); 12027 } 12028 } 12029 if ( key === "icons" ) { 12030 this.buttons.first().find( ".ui-icon" ) 12031 .removeClass( this.options.icons.up ) 12032 .addClass( value.up ); 12033 this.buttons.last().find( ".ui-icon" ) 12034 .removeClass( this.options.icons.down ) 12035 .addClass( value.down ); 12036 } 12037 12038 this._super( key, value ); 12039 12040 if ( key === "disabled" ) { 12041 if ( value ) { 12042 this.element.prop( "disabled", true ); 12043 this.buttons.button( "disable" ); 12044 } else { 12045 this.element.prop( "disabled", false ); 12046 this.buttons.button( "enable" ); 12047 } 12048 } 12049 }, 12050 12051 _setOptions: modifier(function( options ) { 12052 this._super( options ); 12053 this._value( this.element.val() ); 12054 }), 12055 12056 _parse: function( val ) { 12057 if ( typeof val === "string" && val !== "" ) { 12058 val = window.Globalize && this.options.numberFormat ? 12059 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 12060 } 12061 return val === "" || isNaN( val ) ? null : val; 12062 }, 12063 12064 _format: function( value ) { 12065 if ( value === "" ) { 12066 return ""; 12067 } 12068 return window.Globalize && this.options.numberFormat ? 12069 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 12070 value; 12071 }, 12072 12073 _refresh: function() { 12074 this.element.attr({ 12075 "aria-valuemin": this.options.min, 12076 "aria-valuemax": this.options.max, 12077 /*// TODO: what should we do with values that can't be parsed? 12078*/ 12079 "aria-valuenow": this._parse( this.element.val() ) 12080 }); 12081 }, 12082 12083 /*// update the value without triggering change 12084*/ 12085 _value: function( value, allowAny ) { 12086 var parsed; 12087 if ( value !== "" ) { 12088 parsed = this._parse( value ); 12089 if ( parsed !== null ) { 12090 if ( !allowAny ) { 12091 parsed = this._adjustValue( parsed ); 12092 } 12093 value = this._format( parsed ); 12094 } 12095 } 12096 this.element.val( value ); 12097 this._refresh(); 12098 }, 12099 12100 _destroy: function() { 12101 this.element 12102 .removeClass( "ui-spinner-input" ) 12103 .prop( "disabled", false ) 12104 .removeAttr( "autocomplete" ) 12105 .removeAttr( "role" ) 12106 .removeAttr( "aria-valuemin" ) 12107 .removeAttr( "aria-valuemax" ) 12108 .removeAttr( "aria-valuenow" ); 12109 this.uiSpinner.replaceWith( this.element ); 12110 }, 12111 12112 stepUp: modifier(function( steps ) { 12113 this._stepUp( steps ); 12114 }), 12115 _stepUp: function( steps ) { 12116 if ( this._start() ) { 12117 this._spin( (steps || 1) * this.options.step ); 12118 this._stop(); 12119 } 12120 }, 12121 12122 stepDown: modifier(function( steps ) { 12123 this._stepDown( steps ); 12124 }), 12125 _stepDown: function( steps ) { 12126 if ( this._start() ) { 12127 this._spin( (steps || 1) * -this.options.step ); 12128 this._stop(); 12129 } 12130 }, 12131 12132 pageUp: modifier(function( pages ) { 12133 this._stepUp( (pages || 1) * this.options.page ); 12134 }), 12135 12136 pageDown: modifier(function( pages ) { 12137 this._stepDown( (pages || 1) * this.options.page ); 12138 }), 12139 12140 value: function( newVal ) { 12141 if ( !arguments.length ) { 12142 return this._parse( this.element.val() ); 12143 } 12144 modifier( this._value ).call( this, newVal ); 12145 }, 12146 12147 widget: function() { 12148 return this.uiSpinner; 12149 } 12150}); 12151 12152}( jQuery ) ); 12153(function( $, undefined ) { 12154 12155var tabId = 0, 12156 rhash = /#.*$/; 12157 12158function getNextTabId() { 12159 return ++tabId; 12160} 12161 12162function isLocal( anchor ) { 12163 return anchor.hash.length > 1 && 12164 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 12165 decodeURIComponent( location.href.replace( rhash, "" ) ); 12166} 12167 12168$.widget( "ui.tabs", { 12169 version: "1.10.2", 12170 delay: 300, 12171 options: { 12172 active: null, 12173 collapsible: false, 12174 event: "click", 12175 heightStyle: "content", 12176 hide: null, 12177 show: null, 12178 12179 /*// callbacks 12180*/ 12181 activate: null, 12182 beforeActivate: null, 12183 beforeLoad: null, 12184 load: null 12185 }, 12186 12187 _create: function() { 12188 var that = this, 12189 options = this.options; 12190 12191 this.running = false; 12192 12193 this.element 12194 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 12195 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 12196 /*// Prevent users from focusing disabled tabs via click 12197*/ 12198 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 12199 if ( $( this ).is( ".ui-state-disabled" ) ) { 12200 event.preventDefault(); 12201 } 12202 }) 12203 /*// support: IE <9 12204*/ 12205 /*// Preventing the default action in mousedown doesn't prevent IE 12206*/ 12207 /*// from focusing the element, so if the anchor gets focused, blur. 12208*/ 12209 /*// We don't have to worry about focusing the previously focused 12210*/ 12211 /*// element since clicking on a non-focusable element should focus 12212*/ 12213 /*// the body anyway. 12214*/ 12215 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 12216 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 12217 this.blur(); 12218 } 12219 }); 12220 12221 this._processTabs(); 12222 options.active = this._initialActive(); 12223 12224 /*// Take disabling tabs via class attribute from HTML 12225*/ 12226 /*// into account and update option properly. 12227*/ 12228 if ( $.isArray( options.disabled ) ) { 12229 options.disabled = $.unique( options.disabled.concat( 12230 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 12231 return that.tabs.index( li ); 12232 }) 12233 ) ).sort(); 12234 } 12235 12236 /*// check for length avoids error when initializing empty list 12237*/ 12238 if ( this.options.active !== false && this.anchors.length ) { 12239 this.active = this._findActive( options.active ); 12240 } else { 12241 this.active = $(); 12242 } 12243 12244 this._refresh(); 12245 12246 if ( this.active.length ) { 12247 this.load( options.active ); 12248 } 12249 }, 12250 12251 _initialActive: function() { 12252 var active = this.options.active, 12253 collapsible = this.options.collapsible, 12254 locationHash = location.hash.substring( 1 ); 12255 12256 if ( active === null ) { 12257 /*// check the fragment identifier in the URL 12258*/ 12259 if ( locationHash ) { 12260 this.tabs.each(function( i, tab ) { 12261 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 12262 active = i; 12263 return false; 12264 } 12265 }); 12266 } 12267 12268 /*// check for a tab marked active via a class 12269*/ 12270 if ( active === null ) { 12271 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 12272 } 12273 12274 /*// no active tab, set to false 12275*/ 12276 if ( active === null || active === -1 ) { 12277 active = this.tabs.length ? 0 : false; 12278 } 12279 } 12280 12281 /*// handle numbers: negative, out of range 12282*/ 12283 if ( active !== false ) { 12284 active = this.tabs.index( this.tabs.eq( active ) ); 12285 if ( active === -1 ) { 12286 active = collapsible ? false : 0; 12287 } 12288 } 12289 12290 /*// don't allow collapsible: false and active: false 12291*/ 12292 if ( !collapsible && active === false && this.anchors.length ) { 12293 active = 0; 12294 } 12295 12296 return active; 12297 }, 12298 12299 _getCreateEventData: function() { 12300 return { 12301 tab: this.active, 12302 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 12303 }; 12304 }, 12305 12306 _tabKeydown: function( event ) { 12307 /*jshint maxcomplexity:15*/ 12308 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 12309 selectedIndex = this.tabs.index( focusedTab ), 12310 goingForward = true; 12311 12312 if ( this._handlePageNav( event ) ) { 12313 return; 12314 } 12315 12316 switch ( event.keyCode ) { 12317 case $.ui.keyCode.RIGHT: 12318 case $.ui.keyCode.DOWN: 12319 selectedIndex++; 12320 break; 12321 case $.ui.keyCode.UP: 12322 case $.ui.keyCode.LEFT: 12323 goingForward = false; 12324 selectedIndex--; 12325 break; 12326 case $.ui.keyCode.END: 12327 selectedIndex = this.anchors.length - 1; 12328 break; 12329 case $.ui.keyCode.HOME: 12330 selectedIndex = 0; 12331 break; 12332 case $.ui.keyCode.SPACE: 12333 /*// Activate only, no collapsing 12334*/ 12335 event.preventDefault(); 12336 clearTimeout( this.activating ); 12337 this._activate( selectedIndex ); 12338 return; 12339 case $.ui.keyCode.ENTER: 12340 /*// Toggle (cancel delayed activation, allow collapsing) 12341*/ 12342 event.preventDefault(); 12343 clearTimeout( this.activating ); 12344 /*// Determine if we should collapse or activate 12345*/ 12346 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 12347 return; 12348 default: 12349 return; 12350 } 12351 12352 /*// Focus the appropriate tab, based on which key was pressed 12353*/ 12354 event.preventDefault(); 12355 clearTimeout( this.activating ); 12356 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 12357 12358 /*// Navigating with control key will prevent automatic activation 12359*/ 12360 if ( !event.ctrlKey ) { 12361 /*// Update aria-selected immediately so that AT think the tab is already selected. 12362*/ 12363 /*// Otherwise AT may confuse the user by stating that they need to activate the tab, 12364*/ 12365 /*// but the tab will already be activated by the time the announcement finishes. 12366*/ 12367 focusedTab.attr( "aria-selected", "false" ); 12368 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 12369 12370 this.activating = this._delay(function() { 12371 this.option( "active", selectedIndex ); 12372 }, this.delay ); 12373 } 12374 }, 12375 12376 _panelKeydown: function( event ) { 12377 if ( this._handlePageNav( event ) ) { 12378 return; 12379 } 12380 12381 /*// Ctrl+up moves focus to the current tab 12382*/ 12383 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 12384 event.preventDefault(); 12385 this.active.focus(); 12386 } 12387 }, 12388 12389 /*// Alt+page up/down moves focus to the previous/next tab (and activates) 12390*/ 12391 _handlePageNav: function( event ) { 12392 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 12393 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 12394 return true; 12395 } 12396 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 12397 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 12398 return true; 12399 } 12400 }, 12401 12402 _findNextTab: function( index, goingForward ) { 12403 var lastTabIndex = this.tabs.length - 1; 12404 12405 function constrain() { 12406 if ( index > lastTabIndex ) { 12407 index = 0; 12408 } 12409 if ( index < 0 ) { 12410 index = lastTabIndex; 12411 } 12412 return index; 12413 } 12414 12415 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 12416 index = goingForward ? index + 1 : index - 1; 12417 } 12418 12419 return index; 12420 }, 12421 12422 _focusNextTab: function( index, goingForward ) { 12423 index = this._findNextTab( index, goingForward ); 12424 this.tabs.eq( index ).focus(); 12425 return index; 12426 }, 12427 12428 _setOption: function( key, value ) { 12429 if ( key === "active" ) { 12430 /*// _activate() will handle invalid values and update this.options 12431*/ 12432 this._activate( value ); 12433 return; 12434 } 12435 12436 if ( key === "disabled" ) { 12437 /*// don't use the widget factory's disabled handling 12438*/ 12439 this._setupDisabled( value ); 12440 return; 12441 } 12442 12443 this._super( key, value); 12444 12445 if ( key === "collapsible" ) { 12446 this.element.toggleClass( "ui-tabs-collapsible", value ); 12447 /*// Setting collapsible: false while collapsed; open first panel 12448*/ 12449 if ( !value && this.options.active === false ) { 12450 this._activate( 0 ); 12451 } 12452 } 12453 12454 if ( key === "event" ) { 12455 this._setupEvents( value ); 12456 } 12457 12458 if ( key === "heightStyle" ) { 12459 this._setupHeightStyle( value ); 12460 } 12461 }, 12462 12463 _tabId: function( tab ) { 12464 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 12465 }, 12466 12467 _sanitizeSelector: function( hash ) { 12468 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 12469 }, 12470 12471 refresh: function() { 12472 var options = this.options, 12473 lis = this.tablist.children( ":has(a[href])" ); 12474 12475 /*// get disabled tabs from class attribute from HTML 12476*/ 12477 /*// this will get converted to a boolean if needed in _refresh() 12478*/ 12479 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 12480 return lis.index( tab ); 12481 }); 12482 12483 this._processTabs(); 12484 12485 /*// was collapsed or no tabs 12486*/ 12487 if ( options.active === false || !this.anchors.length ) { 12488 options.active = false; 12489 this.active = $(); 12490 /*// was active, but active tab is gone 12491*/ 12492 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 12493 /*// all remaining tabs are disabled 12494*/ 12495 if ( this.tabs.length === options.disabled.length ) { 12496 options.active = false; 12497 this.active = $(); 12498 /*// activate previous tab 12499*/ 12500 } else { 12501 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 12502 } 12503 /*// was active, active tab still exists 12504*/ 12505 } else { 12506 /*// make sure active index is correct 12507*/ 12508 options.active = this.tabs.index( this.active ); 12509 } 12510 12511 this._refresh(); 12512 }, 12513 12514 _refresh: function() { 12515 this._setupDisabled( this.options.disabled ); 12516 this._setupEvents( this.options.event ); 12517 this._setupHeightStyle( this.options.heightStyle ); 12518 12519 this.tabs.not( this.active ).attr({ 12520 "aria-selected": "false", 12521 tabIndex: -1 12522 }); 12523 this.panels.not( this._getPanelForTab( this.active ) ) 12524 .hide() 12525 .attr({ 12526 "aria-expanded": "false", 12527 "aria-hidden": "true" 12528 }); 12529 12530 /*// Make sure one tab is in the tab order 12531*/ 12532 if ( !this.active.length ) { 12533 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 12534 } else { 12535 this.active 12536 .addClass( "ui-tabs-active ui-state-active" ) 12537 .attr({ 12538 "aria-selected": "true", 12539 tabIndex: 0 12540 }); 12541 this._getPanelForTab( this.active ) 12542 .show() 12543 .attr({ 12544 "aria-expanded": "true", 12545 "aria-hidden": "false" 12546 }); 12547 } 12548 }, 12549 12550 _processTabs: function() { 12551 var that = this; 12552 12553 this.tablist = this._getList() 12554 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 12555 .attr( "role", "tablist" ); 12556 12557 this.tabs = this.tablist.find( "> li:has(a[href])" ) 12558 .addClass( "ui-state-default ui-corner-top" ) 12559 .attr({ 12560 role: "tab", 12561 tabIndex: -1 12562 }); 12563 12564 this.anchors = this.tabs.map(function() { 12565 return $( "a", this )[ 0 ]; 12566 }) 12567 .addClass( "ui-tabs-anchor" ) 12568 .attr({ 12569 role: "presentation", 12570 tabIndex: -1 12571 }); 12572 12573 this.panels = $(); 12574 12575 this.anchors.each(function( i, anchor ) { 12576 var selector, panel, panelId, 12577 anchorId = $( anchor ).uniqueId().attr( "id" ), 12578 tab = $( anchor ).closest( "li" ), 12579 originalAriaControls = tab.attr( "aria-controls" ); 12580 12581 /*// inline tab 12582*/ 12583 if ( isLocal( anchor ) ) { 12584 selector = anchor.hash; 12585 panel = that.element.find( that._sanitizeSelector( selector ) ); 12586 /*// remote tab 12587*/ 12588 } else { 12589 panelId = that._tabId( tab ); 12590 selector = "#" + panelId; 12591 panel = that.element.find( selector ); 12592 if ( !panel.length ) { 12593 panel = that._createPanel( panelId ); 12594 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 12595 } 12596 panel.attr( "aria-live", "polite" ); 12597 } 12598 12599 if ( panel.length) { 12600 that.panels = that.panels.add( panel ); 12601 } 12602 if ( originalAriaControls ) { 12603 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 12604 } 12605 tab.attr({ 12606 "aria-controls": selector.substring( 1 ), 12607 "aria-labelledby": anchorId 12608 }); 12609 panel.attr( "aria-labelledby", anchorId ); 12610 }); 12611 12612 this.panels 12613 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 12614 .attr( "role", "tabpanel" ); 12615 }, 12616 12617 /*// allow overriding how to find the list for rare usage scenarios (#7715) 12618*/ 12619 _getList: function() { 12620 return this.element.find( "ol,ul" ).eq( 0 ); 12621 }, 12622 12623 _createPanel: function( id ) { 12624 return $( "<div>" ) 12625 .attr( "id", id ) 12626 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 12627 .data( "ui-tabs-destroy", true ); 12628 }, 12629 12630 _setupDisabled: function( disabled ) { 12631 if ( $.isArray( disabled ) ) { 12632 if ( !disabled.length ) { 12633 disabled = false; 12634 } else if ( disabled.length === this.anchors.length ) { 12635 disabled = true; 12636 } 12637 } 12638 12639 /*// disable tabs 12640*/ 12641 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 12642 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 12643 $( li ) 12644 .addClass( "ui-state-disabled" ) 12645 .attr( "aria-disabled", "true" ); 12646 } else { 12647 $( li ) 12648 .removeClass( "ui-state-disabled" ) 12649 .removeAttr( "aria-disabled" ); 12650 } 12651 } 12652 12653 this.options.disabled = disabled; 12654 }, 12655 12656 _setupEvents: function( event ) { 12657 var events = { 12658 click: function( event ) { 12659 event.preventDefault(); 12660 } 12661 }; 12662 if ( event ) { 12663 $.each( event.split(" "), function( index, eventName ) { 12664 events[ eventName ] = "_eventHandler"; 12665 }); 12666 } 12667 12668 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 12669 this._on( this.anchors, events ); 12670 this._on( this.tabs, { keydown: "_tabKeydown" } ); 12671 this._on( this.panels, { keydown: "_panelKeydown" } ); 12672 12673 this._focusable( this.tabs ); 12674 this._hoverable( this.tabs ); 12675 }, 12676 12677 _setupHeightStyle: function( heightStyle ) { 12678 var maxHeight, 12679 parent = this.element.parent(); 12680 12681 if ( heightStyle === "fill" ) { 12682 maxHeight = parent.height(); 12683 maxHeight -= this.element.outerHeight() - this.element.height(); 12684 12685 this.element.siblings( ":visible" ).each(function() { 12686 var elem = $( this ), 12687 position = elem.css( "position" ); 12688 12689 if ( position === "absolute" || position === "fixed" ) { 12690 return; 12691 } 12692 maxHeight -= elem.outerHeight( true ); 12693 }); 12694 12695 this.element.children().not( this.panels ).each(function() { 12696 maxHeight -= $( this ).outerHeight( true ); 12697 }); 12698 12699 this.panels.each(function() { 12700 $( this ).height( Math.max( 0, maxHeight - 12701 $( this ).innerHeight() + $( this ).height() ) ); 12702 }) 12703 .css( "overflow", "auto" ); 12704 } else if ( heightStyle === "auto" ) { 12705 maxHeight = 0; 12706 this.panels.each(function() { 12707 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 12708 }).height( maxHeight ); 12709 } 12710 }, 12711 12712 _eventHandler: function( event ) { 12713 var options = this.options, 12714 active = this.active, 12715 anchor = $( event.currentTarget ), 12716 tab = anchor.closest( "li" ), 12717 clickedIsActive = tab[ 0 ] === active[ 0 ], 12718 collapsing = clickedIsActive && options.collapsible, 12719 toShow = collapsing ? $() : this._getPanelForTab( tab ), 12720 toHide = !active.length ? $() : this._getPanelForTab( active ), 12721 eventData = { 12722 oldTab: active, 12723 oldPanel: toHide, 12724 newTab: collapsing ? $() : tab, 12725 newPanel: toShow 12726 }; 12727 12728 event.preventDefault(); 12729 12730 if ( tab.hasClass( "ui-state-disabled" ) || 12731 /*// tab is already loading 12732*/ 12733 tab.hasClass( "ui-tabs-loading" ) || 12734 /*// can't switch durning an animation 12735*/ 12736 this.running || 12737 /*// click on active header, but not collapsible 12738*/ 12739 ( clickedIsActive && !options.collapsible ) || 12740 /*// allow canceling activation 12741*/ 12742 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 12743 return; 12744 } 12745 12746 options.active = collapsing ? false : this.tabs.index( tab ); 12747 12748 this.active = clickedIsActive ? $() : tab; 12749 if ( this.xhr ) { 12750 this.xhr.abort(); 12751 } 12752 12753 if ( !toHide.length && !toShow.length ) { 12754 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 12755 } 12756 12757 if ( toShow.length ) { 12758 this.load( this.tabs.index( tab ), event ); 12759 } 12760 this._toggle( event, eventData ); 12761 }, 12762 12763 /*// handles show/hide for selecting tabs 12764*/ 12765 _toggle: function( event, eventData ) { 12766 var that = this, 12767 toShow = eventData.newPanel, 12768 toHide = eventData.oldPanel; 12769 12770 this.running = true; 12771 12772 function complete() { 12773 that.running = false; 12774 that._trigger( "activate", event, eventData ); 12775 } 12776 12777 function show() { 12778 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 12779 12780 if ( toShow.length && that.options.show ) { 12781 that._show( toShow, that.options.show, complete ); 12782 } else { 12783 toShow.show(); 12784 complete(); 12785 } 12786 } 12787 12788 /*// start out by hiding, then showing, then completing 12789*/ 12790 if ( toHide.length && this.options.hide ) { 12791 this._hide( toHide, this.options.hide, function() { 12792 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12793 show(); 12794 }); 12795 } else { 12796 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 12797 toHide.hide(); 12798 show(); 12799 } 12800 12801 toHide.attr({ 12802 "aria-expanded": "false", 12803 "aria-hidden": "true" 12804 }); 12805 eventData.oldTab.attr( "aria-selected", "false" ); 12806 /*// If we're switching tabs, remove the old tab from the tab order. 12807*/ 12808 /*// If we're opening from collapsed state, remove the previous tab from the tab order. 12809*/ 12810 /*// If we're collapsing, then keep the collapsing tab in the tab order. 12811*/ 12812 if ( toShow.length && toHide.length ) { 12813 eventData.oldTab.attr( "tabIndex", -1 ); 12814 } else if ( toShow.length ) { 12815 this.tabs.filter(function() { 12816 return $( this ).attr( "tabIndex" ) === 0; 12817 }) 12818 .attr( "tabIndex", -1 ); 12819 } 12820 12821 toShow.attr({ 12822 "aria-expanded": "true", 12823 "aria-hidden": "false" 12824 }); 12825 eventData.newTab.attr({ 12826 "aria-selected": "true", 12827 tabIndex: 0 12828 }); 12829 }, 12830 12831 _activate: function( index ) { 12832 var anchor, 12833 active = this._findActive( index ); 12834 12835 /*// trying to activate the already active panel 12836*/ 12837 if ( active[ 0 ] === this.active[ 0 ] ) { 12838 return; 12839 } 12840 12841 /*// trying to collapse, simulate a click on the current active header 12842*/ 12843 if ( !active.length ) { 12844 active = this.active; 12845 } 12846 12847 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 12848 this._eventHandler({ 12849 target: anchor, 12850 currentTarget: anchor, 12851 preventDefault: $.noop 12852 }); 12853 }, 12854 12855 _findActive: function( index ) { 12856 return index === false ? $() : this.tabs.eq( index ); 12857 }, 12858 12859 _getIndex: function( index ) { 12860 /*// meta-function to give users option to provide a href string instead of a numerical index. 12861*/ 12862 if ( typeof index === "string" ) { 12863 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 12864 } 12865 12866 return index; 12867 }, 12868 12869 _destroy: function() { 12870 if ( this.xhr ) { 12871 this.xhr.abort(); 12872 } 12873 12874 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 12875 12876 this.tablist 12877 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 12878 .removeAttr( "role" ); 12879 12880 this.anchors 12881 .removeClass( "ui-tabs-anchor" ) 12882 .removeAttr( "role" ) 12883 .removeAttr( "tabIndex" ) 12884 .removeUniqueId(); 12885 12886 this.tabs.add( this.panels ).each(function() { 12887 if ( $.data( this, "ui-tabs-destroy" ) ) { 12888 $( this ).remove(); 12889 } else { 12890 $( this ) 12891 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 12892 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 12893 .removeAttr( "tabIndex" ) 12894 .removeAttr( "aria-live" ) 12895 .removeAttr( "aria-busy" ) 12896 .removeAttr( "aria-selected" ) 12897 .removeAttr( "aria-labelledby" ) 12898 .removeAttr( "aria-hidden" ) 12899 .removeAttr( "aria-expanded" ) 12900 .removeAttr( "role" ); 12901 } 12902 }); 12903 12904 this.tabs.each(function() { 12905 var li = $( this ), 12906 prev = li.data( "ui-tabs-aria-controls" ); 12907 if ( prev ) { 12908 li 12909 .attr( "aria-controls", prev ) 12910 .removeData( "ui-tabs-aria-controls" ); 12911 } else { 12912 li.removeAttr( "aria-controls" ); 12913 } 12914 }); 12915 12916 this.panels.show(); 12917 12918 if ( this.options.heightStyle !== "content" ) { 12919 this.panels.css( "height", "" ); 12920 } 12921 }, 12922 12923 enable: function( index ) { 12924 var disabled = this.options.disabled; 12925 if ( disabled === false ) { 12926 return; 12927 } 12928 12929 if ( index === undefined ) { 12930 disabled = false; 12931 } else { 12932 index = this._getIndex( index ); 12933 if ( $.isArray( disabled ) ) { 12934 disabled = $.map( disabled, function( num ) { 12935 return num !== index ? num : null; 12936 }); 12937 } else { 12938 disabled = $.map( this.tabs, function( li, num ) { 12939 return num !== index ? num : null; 12940 }); 12941 } 12942 } 12943 this._setupDisabled( disabled ); 12944 }, 12945 12946 disable: function( index ) { 12947 var disabled = this.options.disabled; 12948 if ( disabled === true ) { 12949 return; 12950 } 12951 12952 if ( index === undefined ) { 12953 disabled = true; 12954 } else { 12955 index = this._getIndex( index ); 12956 if ( $.inArray( index, disabled ) !== -1 ) { 12957 return; 12958 } 12959 if ( $.isArray( disabled ) ) { 12960 disabled = $.merge( [ index ], disabled ).sort(); 12961 } else { 12962 disabled = [ index ]; 12963 } 12964 } 12965 this._setupDisabled( disabled ); 12966 }, 12967 12968 load: function( index, event ) { 12969 index = this._getIndex( index ); 12970 var that = this, 12971 tab = this.tabs.eq( index ), 12972 anchor = tab.find( ".ui-tabs-anchor" ), 12973 panel = this._getPanelForTab( tab ), 12974 eventData = { 12975 tab: tab, 12976 panel: panel 12977 }; 12978 12979 /*// not remote 12980*/ 12981 if ( isLocal( anchor[ 0 ] ) ) { 12982 return; 12983 } 12984 12985 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 12986 12987 /*// support: jQuery <1.8 12988*/ 12989 /*// jQuery <1.8 returns false if the request is canceled in beforeSend, 12990*/ 12991 /*// but as of 1.8, $.ajax() always returns a jqXHR object. 12992*/ 12993 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 12994 tab.addClass( "ui-tabs-loading" ); 12995 panel.attr( "aria-busy", "true" ); 12996 12997 this.xhr 12998 .success(function( response ) { 12999 /*// support: jQuery <1.8 13000*/ 13001 /*// http://bugs.jquery.com/ticket/11778 13002*/ 13003 setTimeout(function() { 13004 panel.html( response ); 13005 that._trigger( "load", event, eventData ); 13006 }, 1 ); 13007 }) 13008 .complete(function( jqXHR, status ) { 13009 /*// support: jQuery <1.8 13010*/ 13011 /*// http://bugs.jquery.com/ticket/11778 13012*/ 13013 setTimeout(function() { 13014 if ( status === "abort" ) { 13015 that.panels.stop( false, true ); 13016 } 13017 13018 tab.removeClass( "ui-tabs-loading" ); 13019 panel.removeAttr( "aria-busy" ); 13020 13021 if ( jqXHR === that.xhr ) { 13022 delete that.xhr; 13023 } 13024 }, 1 ); 13025 }); 13026 } 13027 }, 13028 13029 _ajaxSettings: function( anchor, event, eventData ) { 13030 var that = this; 13031 return { 13032 url: anchor.attr( "href" ), 13033 beforeSend: function( jqXHR, settings ) { 13034 return that._trigger( "beforeLoad", event, 13035 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 13036 } 13037 }; 13038 }, 13039 13040 _getPanelForTab: function( tab ) { 13041 var id = $( tab ).attr( "aria-controls" ); 13042 return this.element.find( this._sanitizeSelector( "#" + id ) ); 13043 } 13044}); 13045 13046})( jQuery ); 13047(function( $ ) { 13048 13049var increments = 0; 13050 13051function addDescribedBy( elem, id ) { 13052 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 13053 describedby.push( id ); 13054 elem 13055 .data( "ui-tooltip-id", id ) 13056 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 13057} 13058 13059function removeDescribedBy( elem ) { 13060 var id = elem.data( "ui-tooltip-id" ), 13061 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 13062 index = $.inArray( id, describedby ); 13063 if ( index !== -1 ) { 13064 describedby.splice( index, 1 ); 13065 } 13066 13067 elem.removeData( "ui-tooltip-id" ); 13068 describedby = $.trim( describedby.join( " " ) ); 13069 if ( describedby ) { 13070 elem.attr( "aria-describedby", describedby ); 13071 } else { 13072 elem.removeAttr( "aria-describedby" ); 13073 } 13074} 13075 13076$.widget( "ui.tooltip", { 13077 version: "1.10.2", 13078 options: { 13079 content: function() { 13080 /*// support: IE<9, Opera in jQuery <1.7 13081*/ 13082 /*// .text() can't accept undefined, so coerce to a string 13083*/ 13084 var title = $( this ).attr( "title" ) || ""; 13085 /*// Escape title, since we're going from an attribute to raw HTML 13086*/ 13087 return $( "<a>" ).text( title ).html(); 13088 }, 13089 hide: true, 13090 /*// Disabled elements have inconsistent behavior across browsers (#8661) 13091*/ 13092 items: "[title]:not([disabled])", 13093 position: { 13094 my: "left top+15", 13095 at: "left bottom", 13096 collision: "flipfit flip" 13097 }, 13098 show: true, 13099 tooltipClass: null, 13100 track: false, 13101 13102 /*// callbacks 13103*/ 13104 close: null, 13105 open: null 13106 }, 13107 13108 _create: function() { 13109 this._on({ 13110 mouseover: "open", 13111 focusin: "open" 13112 }); 13113 13114 /*// IDs of generated tooltips, needed for destroy 13115*/ 13116 this.tooltips = {}; 13117 /*// IDs of parent tooltips where we removed the title attribute 13118*/ 13119 this.parents = {}; 13120 13121 if ( this.options.disabled ) { 13122 this._disable(); 13123 } 13124 }, 13125 13126 _setOption: function( key, value ) { 13127 var that = this; 13128 13129 if ( key === "disabled" ) { 13130 this[ value ? "_disable" : "_enable" ](); 13131 this.options[ key ] = value; 13132 /*// disable element style changes 13133*/ 13134 return; 13135 } 13136 13137 this._super( key, value ); 13138 13139 if ( key === "content" ) { 13140 $.each( this.tooltips, function( id, element ) { 13141 that._updateContent( element ); 13142 }); 13143 } 13144 }, 13145 13146 _disable: function() { 13147 var that = this; 13148 13149 /*// close open tooltips 13150*/ 13151 $.each( this.tooltips, function( id, element ) { 13152 var event = $.Event( "blur" ); 13153 event.target = event.currentTarget = element[0]; 13154 that.close( event, true ); 13155 }); 13156 13157 /*// remove title attributes to prevent native tooltips 13158*/ 13159 this.element.find( this.options.items ).addBack().each(function() { 13160 var element = $( this ); 13161 if ( element.is( "[title]" ) ) { 13162 element 13163 .data( "ui-tooltip-title", element.attr( "title" ) ) 13164 .attr( "title", "" ); 13165 } 13166 }); 13167 }, 13168 13169 _enable: function() { 13170 /*// restore title attributes 13171*/ 13172 this.element.find( this.options.items ).addBack().each(function() { 13173 var element = $( this ); 13174 if ( element.data( "ui-tooltip-title" ) ) { 13175 element.attr( "title", element.data( "ui-tooltip-title" ) ); 13176 } 13177 }); 13178 }, 13179 13180 open: function( event ) { 13181 var that = this, 13182 target = $( event ? event.target : this.element ) 13183 /*// we need closest here due to mouseover bubbling, 13184*/ 13185 /*// but always pointing at the same event target 13186*/ 13187 .closest( this.options.items ); 13188 13189 /*// No element to show a tooltip for or the tooltip is already open 13190*/ 13191 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 13192 return; 13193 } 13194 13195 if ( target.attr( "title" ) ) { 13196 target.data( "ui-tooltip-title", target.attr( "title" ) ); 13197 } 13198 13199 target.data( "ui-tooltip-open", true ); 13200 13201 /*// kill parent tooltips, custom or native, for hover 13202*/ 13203 if ( event && event.type === "mouseover" ) { 13204 target.parents().each(function() { 13205 var parent = $( this ), 13206 blurEvent; 13207 if ( parent.data( "ui-tooltip-open" ) ) { 13208 blurEvent = $.Event( "blur" ); 13209 blurEvent.target = blurEvent.currentTarget = this; 13210 that.close( blurEvent, true ); 13211 } 13212 if ( parent.attr( "title" ) ) { 13213 parent.uniqueId(); 13214 that.parents[ this.id ] = { 13215 element: this, 13216 title: parent.attr( "title" ) 13217 }; 13218 parent.attr( "title", "" ); 13219 } 13220 }); 13221 } 13222 13223 this._updateContent( target, event ); 13224 }, 13225 13226 _updateContent: function( target, event ) { 13227 var content, 13228 contentOption = this.options.content, 13229 that = this, 13230 eventType = event ? event.type : null; 13231 13232 if ( typeof contentOption === "string" ) { 13233 return this._open( event, target, contentOption ); 13234 } 13235 13236 content = contentOption.call( target[0], function( response ) { 13237 /*// ignore async response if tooltip was closed already 13238*/ 13239 if ( !target.data( "ui-tooltip-open" ) ) { 13240 return; 13241 } 13242 /*// IE may instantly serve a cached response for ajax requests 13243*/ 13244 /*// delay this call to _open so the other call to _open runs first 13245*/ 13246 that._delay(function() { 13247 /*// jQuery creates a special event for focusin when it doesn't 13248*/ 13249 /*// exist natively. To improve performance, the native event 13250*/ 13251 /*// object is reused and the type is changed. Therefore, we can't 13252*/ 13253 /*// rely on the type being correct after the event finished 13254*/ 13255 /*// bubbling, so we set it back to the previous value. (#8740) 13256*/ 13257 if ( event ) { 13258 event.type = eventType; 13259 } 13260 this._open( event, target, response ); 13261 }); 13262 }); 13263 if ( content ) { 13264 this._open( event, target, content ); 13265 } 13266 }, 13267 13268 _open: function( event, target, content ) { 13269 var tooltip, events, delayedShow, 13270 positionOption = $.extend( {}, this.options.position ); 13271 13272 if ( !content ) { 13273 return; 13274 } 13275 13276 /*// Content can be updated multiple times. If the tooltip already 13277*/ 13278 /*// exists, then just update the content and bail. 13279*/ 13280 tooltip = this._find( target ); 13281 if ( tooltip.length ) { 13282 tooltip.find( ".ui-tooltip-content" ).html( content ); 13283 return; 13284 } 13285 13286 /*// if we have a title, clear it to prevent the native tooltip 13287*/ 13288 /*// we have to check first to avoid defining a title if none exists 13289*/ 13290 /*// (we don't want to cause an element to start matching [title]) 13291*/ 13292 // 13293 /*// We use removeAttr only for key events, to allow IE to export the correct 13294*/ 13295 /*// accessible attributes. For mouse events, set to empty string to avoid 13296*/ 13297 /*// native tooltip showing up (happens only when removing inside mouseover). 13298*/ 13299 if ( target.is( "[title]" ) ) { 13300 if ( event && event.type === "mouseover" ) { 13301 target.attr( "title", "" ); 13302 } else { 13303 target.removeAttr( "title" ); 13304 } 13305 } 13306 13307 tooltip = this._tooltip( target ); 13308 addDescribedBy( target, tooltip.attr( "id" ) ); 13309 tooltip.find( ".ui-tooltip-content" ).html( content ); 13310 13311 function position( event ) { 13312 positionOption.of = event; 13313 if ( tooltip.is( ":hidden" ) ) { 13314 return; 13315 } 13316 tooltip.position( positionOption ); 13317 } 13318 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 13319 this._on( this.document, { 13320 mousemove: position 13321 }); 13322 /*// trigger once to override element-relative positioning 13323*/ 13324 position( event ); 13325 } else { 13326 tooltip.position( $.extend({ 13327 of: target 13328 }, this.options.position ) ); 13329 } 13330 13331 tooltip.hide(); 13332 13333 this._show( tooltip, this.options.show ); 13334 /*// Handle tracking tooltips that are shown with a delay (#8644). As soon 13335*/ 13336 /*// as the tooltip is visible, position the tooltip using the most recent 13337*/ 13338 /*// event. 13339*/ 13340 if ( this.options.show && this.options.show.delay ) { 13341 delayedShow = this.delayedShow = setInterval(function() { 13342 if ( tooltip.is( ":visible" ) ) { 13343 position( positionOption.of ); 13344 clearInterval( delayedShow ); 13345 } 13346 }, $.fx.interval ); 13347 } 13348 13349 this._trigger( "open", event, { tooltip: tooltip } ); 13350 13351 events = { 13352 keyup: function( event ) { 13353 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 13354 var fakeEvent = $.Event(event); 13355 fakeEvent.currentTarget = target[0]; 13356 this.close( fakeEvent, true ); 13357 } 13358 }, 13359 remove: function() { 13360 this._removeTooltip( tooltip ); 13361 } 13362 }; 13363 if ( !event || event.type === "mouseover" ) { 13364 events.mouseleave = "close"; 13365 } 13366 if ( !event || event.type === "focusin" ) { 13367 events.focusout = "close"; 13368 } 13369 this._on( true, target, events ); 13370 }, 13371 13372 close: function( event ) { 13373 var that = this, 13374 target = $( event ? event.currentTarget : this.element ), 13375 tooltip = this._find( target ); 13376 13377 /*// disabling closes the tooltip, so we need to track when we're closing 13378*/ 13379 /*// to avoid an infinite loop in case the tooltip becomes disabled on close 13380*/ 13381 if ( this.closing ) { 13382 return; 13383 } 13384 13385 /*// Clear the interval for delayed tracking tooltips 13386*/ 13387 clearInterval( this.delayedShow ); 13388 13389 /*// only set title if we had one before (see comment in _open()) 13390*/ 13391 if ( target.data( "ui-tooltip-title" ) ) { 13392 target.attr( "title", target.data( "ui-tooltip-title" ) ); 13393 } 13394 13395 removeDescribedBy( target ); 13396 13397 tooltip.stop( true ); 13398 this._hide( tooltip, this.options.hide, function() { 13399 that._removeTooltip( $( this ) ); 13400 }); 13401 13402 target.removeData( "ui-tooltip-open" ); 13403 this._off( target, "mouseleave focusout keyup" ); 13404 /*// Remove 'remove' binding only on delegated targets 13405*/ 13406 if ( target[0] !== this.element[0] ) { 13407 this._off( target, "remove" ); 13408 } 13409 this._off( this.document, "mousemove" ); 13410 13411 if ( event && event.type === "mouseleave" ) { 13412 $.each( this.parents, function( id, parent ) { 13413 $( parent.element ).attr( "title", parent.title ); 13414 delete that.parents[ id ]; 13415 }); 13416 } 13417 13418 this.closing = true; 13419 this._trigger( "close", event, { tooltip: tooltip } ); 13420 this.closing = false; 13421 }, 13422 13423 _tooltip: function( element ) { 13424 var id = "ui-tooltip-" + increments++, 13425 tooltip = $( "<div>" ) 13426 .attr({ 13427 id: id, 13428 role: "tooltip" 13429 }) 13430 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 13431 ( this.options.tooltipClass || "" ) ); 13432 $( "<div>" ) 13433 .addClass( "ui-tooltip-content" ) 13434 .appendTo( tooltip ); 13435 tooltip.appendTo( this.document[0].body ); 13436 this.tooltips[ id ] = element; 13437 return tooltip; 13438 }, 13439 13440 _find: function( target ) { 13441 var id = target.data( "ui-tooltip-id" ); 13442 return id ? $( "#" + id ) : $(); 13443 }, 13444 13445 _removeTooltip: function( tooltip ) { 13446 tooltip.remove(); 13447 delete this.tooltips[ tooltip.attr( "id" ) ]; 13448 }, 13449 13450 _destroy: function() { 13451 var that = this; 13452 13453 /*// close open tooltips 13454*/ 13455 $.each( this.tooltips, function( id, element ) { 13456 /*// Delegate to close method to handle common cleanup 13457*/ 13458 var event = $.Event( "blur" ); 13459 event.target = event.currentTarget = element[0]; 13460 that.close( event, true ); 13461 13462 /*// Remove immediately; destroying an open tooltip doesn't use the 13463*/ 13464 /*// hide animation 13465*/ 13466 $( "#" + id ).remove(); 13467 13468 /*// Restore the title 13469*/ 13470 if ( element.data( "ui-tooltip-title" ) ) { 13471 element.attr( "title", element.data( "ui-tooltip-title" ) ); 13472 element.removeData( "ui-tooltip-title" ); 13473 } 13474 }); 13475 } 13476}); 13477 13478}( jQuery ) ); 13479(function($, undefined) { 13480 13481var dataSpace = "ui-effects-"; 13482 13483$.effects = { 13484 effect: {} 13485}; 13486 13487/*! 13488 * jQuery Color Animations v2.1.2 13489 * https://github.com/jquery/jquery-color 13490 * 13491 * Copyright 2013 jQuery Foundation and other contributors 13492 * Released under the MIT license. 13493 * http://jquery.org/license 13494 * 13495 * Date: Wed Jan 16 08:47:09 2013 -0600 13496 */ 13497(function( jQuery, undefined ) { 13498 13499 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 13500 13501 /*// plusequals test for += 100 -= 100 13502*/ 13503 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 13504 /*// a set of RE's that can match strings and generate color tuples. 13505*/ 13506 stringParsers = [{ 13507 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13508 parse: function( execResult ) { 13509 return [ 13510 execResult[ 1 ], 13511 execResult[ 2 ], 13512 execResult[ 3 ], 13513 execResult[ 4 ] 13514 ]; 13515 } 13516 }, { 13517 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13518 parse: function( execResult ) { 13519 return [ 13520 execResult[ 1 ] * 2.55, 13521 execResult[ 2 ] * 2.55, 13522 execResult[ 3 ] * 2.55, 13523 execResult[ 4 ] 13524 ]; 13525 } 13526 }, { 13527 /*// this regex ignores A-F because it's compared against an already lowercased string 13528*/ 13529 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 13530 parse: function( execResult ) { 13531 return [ 13532 parseInt( execResult[ 1 ], 16 ), 13533 parseInt( execResult[ 2 ], 16 ), 13534 parseInt( execResult[ 3 ], 16 ) 13535 ]; 13536 } 13537 }, { 13538 /*// this regex ignores A-F because it's compared against an already lowercased string 13539*/ 13540 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 13541 parse: function( execResult ) { 13542 return [ 13543 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 13544 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 13545 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 13546 ]; 13547 } 13548 }, { 13549 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 13550 space: "hsla", 13551 parse: function( execResult ) { 13552 return [ 13553 execResult[ 1 ], 13554 execResult[ 2 ] / 100, 13555 execResult[ 3 ] / 100, 13556 execResult[ 4 ] 13557 ]; 13558 } 13559 }], 13560 13561 /*// jQuery.Color( ) 13562*/ 13563 color = jQuery.Color = function( color, green, blue, alpha ) { 13564 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 13565 }, 13566 spaces = { 13567 rgba: { 13568 props: { 13569 red: { 13570 idx: 0, 13571 type: "byte" 13572 }, 13573 green: { 13574 idx: 1, 13575 type: "byte" 13576 }, 13577 blue: { 13578 idx: 2, 13579 type: "byte" 13580 } 13581 } 13582 }, 13583 13584 hsla: { 13585 props: { 13586 hue: { 13587 idx: 0, 13588 type: "degrees" 13589 }, 13590 saturation: { 13591 idx: 1, 13592 type: "percent" 13593 }, 13594 lightness: { 13595 idx: 2, 13596 type: "percent" 13597 } 13598 } 13599 } 13600 }, 13601 propTypes = { 13602 "byte": { 13603 floor: true, 13604 max: 255 13605 }, 13606 "percent": { 13607 max: 1 13608 }, 13609 "degrees": { 13610 mod: 360, 13611 floor: true 13612 } 13613 }, 13614 support = color.support = {}, 13615 13616 /*// element for support tests 13617*/ 13618 supportElem = jQuery( "<p>" )[ 0 ], 13619 13620 /*// colors = jQuery.Color.names 13621*/ 13622 colors, 13623 13624 /*// local aliases of functions called often 13625*/ 13626 each = jQuery.each; 13627 13628/*// determine rgba support immediately 13629*/ 13630supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 13631support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 13632 13633/*// define cache name and alpha properties 13634*/ 13635/*// for rgba and hsla spaces 13636*/ 13637each( spaces, function( spaceName, space ) { 13638 space.cache = "_" + spaceName; 13639 space.props.alpha = { 13640 idx: 3, 13641 type: "percent", 13642 def: 1 13643 }; 13644}); 13645 13646function clamp( value, prop, allowEmpty ) { 13647 var type = propTypes[ prop.type ] || {}; 13648 13649 if ( value == null ) { 13650 return (allowEmpty || !prop.def) ? null : prop.def; 13651 } 13652 13653 /*// ~~ is an short way of doing floor for positive numbers 13654*/ 13655 value = type.floor ? ~~value : parseFloat( value ); 13656 13657 /*// IE will pass in empty strings as value for alpha, 13658*/ 13659 /*// which will hit this case 13660*/ 13661 if ( isNaN( value ) ) { 13662 return prop.def; 13663 } 13664 13665 if ( type.mod ) { 13666 /*// we add mod before modding to make sure that negatives values 13667*/ 13668 /*// get converted properly: -10 -> 350 13669*/ 13670 return (value + type.mod) % type.mod; 13671 } 13672 13673 /*// for now all property types without mod have min and max 13674*/ 13675 return 0 > value ? 0 : type.max < value ? type.max : value; 13676} 13677 13678function stringParse( string ) { 13679 var inst = color(), 13680 rgba = inst._rgba = []; 13681 13682 string = string.toLowerCase(); 13683 13684 each( stringParsers, function( i, parser ) { 13685 var parsed, 13686 match = parser.re.exec( string ), 13687 values = match && parser.parse( match ), 13688 spaceName = parser.space || "rgba"; 13689 13690 if ( values ) { 13691 parsed = inst[ spaceName ]( values ); 13692 13693 /*// if this was an rgba parse the assignment might happen twice 13694*/ 13695 /*// oh well.... 13696*/ 13697 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 13698 rgba = inst._rgba = parsed._rgba; 13699 13700 /*// exit each( stringParsers ) here because we matched 13701*/ 13702 return false; 13703 } 13704 }); 13705 13706 /*// Found a stringParser that handled it 13707*/ 13708 if ( rgba.length ) { 13709 13710 /*// if this came from a parsed string, force "transparent" when alpha is 0 13711*/ 13712 /*// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 13713*/ 13714 if ( rgba.join() === "0,0,0,0" ) { 13715 jQuery.extend( rgba, colors.transparent ); 13716 } 13717 return inst; 13718 } 13719 13720 /*// named colors 13721*/ 13722 return colors[ string ]; 13723} 13724 13725color.fn = jQuery.extend( color.prototype, { 13726 parse: function( red, green, blue, alpha ) { 13727 if ( red === undefined ) { 13728 this._rgba = [ null, null, null, null ]; 13729 return this; 13730 } 13731 if ( red.jquery || red.nodeType ) { 13732 red = jQuery( red ).css( green ); 13733 green = undefined; 13734 } 13735 13736 var inst = this, 13737 type = jQuery.type( red ), 13738 rgba = this._rgba = []; 13739 13740 /*// more than 1 argument specified - assume ( red, green, blue, alpha ) 13741*/ 13742 if ( green !== undefined ) { 13743 red = [ red, green, blue, alpha ]; 13744 type = "array"; 13745 } 13746 13747 if ( type === "string" ) { 13748 return this.parse( stringParse( red ) || colors._default ); 13749 } 13750 13751 if ( type === "array" ) { 13752 each( spaces.rgba.props, function( key, prop ) { 13753 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 13754 }); 13755 return this; 13756 } 13757 13758 if ( type === "object" ) { 13759 if ( red instanceof color ) { 13760 each( spaces, function( spaceName, space ) { 13761 if ( red[ space.cache ] ) { 13762 inst[ space.cache ] = red[ space.cache ].slice(); 13763 } 13764 }); 13765 } else { 13766 each( spaces, function( spaceName, space ) { 13767 var cache = space.cache; 13768 each( space.props, function( key, prop ) { 13769 13770 /*// if the cache doesn't exist, and we know how to convert 13771*/ 13772 if ( !inst[ cache ] && space.to ) { 13773 13774 /*// if the value was null, we don't need to copy it 13775*/ 13776 /*// if the key was alpha, we don't need to copy it either 13777*/ 13778 if ( key === "alpha" || red[ key ] == null ) { 13779 return; 13780 } 13781 inst[ cache ] = space.to( inst._rgba ); 13782 } 13783 13784 /*// this is the only case where we allow nulls for ALL properties. 13785*/ 13786 /*// call clamp with alwaysAllowEmpty 13787*/ 13788 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 13789 }); 13790 13791 /*// everything defined but alpha? 13792*/ 13793 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 13794 /*// use the default of 1 13795*/ 13796 inst[ cache ][ 3 ] = 1; 13797 if ( space.from ) { 13798 inst._rgba = space.from( inst[ cache ] ); 13799 } 13800 } 13801 }); 13802 } 13803 return this; 13804 } 13805 }, 13806 is: function( compare ) { 13807 var is = color( compare ), 13808 same = true, 13809 inst = this; 13810 13811 each( spaces, function( _, space ) { 13812 var localCache, 13813 isCache = is[ space.cache ]; 13814 if (isCache) { 13815 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 13816 each( space.props, function( _, prop ) { 13817 if ( isCache[ prop.idx ] != null ) { 13818 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 13819 return same; 13820 } 13821 }); 13822 } 13823 return same; 13824 }); 13825 return same; 13826 }, 13827 _space: function() { 13828 var used = [], 13829 inst = this; 13830 each( spaces, function( spaceName, space ) { 13831 if ( inst[ space.cache ] ) { 13832 used.push( spaceName ); 13833 } 13834 }); 13835 return used.pop(); 13836 }, 13837 transition: function( other, distance ) { 13838 var end = color( other ), 13839 spaceName = end._space(), 13840 space = spaces[ spaceName ], 13841 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 13842 start = startColor[ space.cache ] || space.to( startColor._rgba ), 13843 result = start.slice(); 13844 13845 end = end[ space.cache ]; 13846 each( space.props, function( key, prop ) { 13847 var index = prop.idx, 13848 startValue = start[ index ], 13849 endValue = end[ index ], 13850 type = propTypes[ prop.type ] || {}; 13851 13852 /*// if null, don't override start value 13853*/ 13854 if ( endValue === null ) { 13855 return; 13856 } 13857 /*// if null - use end 13858*/ 13859 if ( startValue === null ) { 13860 result[ index ] = endValue; 13861 } else { 13862 if ( type.mod ) { 13863 if ( endValue - startValue > type.mod / 2 ) { 13864 startValue += type.mod; 13865 } else if ( startValue - endValue > type.mod / 2 ) { 13866 startValue -= type.mod; 13867 } 13868 } 13869 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 13870 } 13871 }); 13872 return this[ spaceName ]( result ); 13873 }, 13874 blend: function( opaque ) { 13875 /*// if we are already opaque - return ourself 13876*/ 13877 if ( this._rgba[ 3 ] === 1 ) { 13878 return this; 13879 } 13880 13881 var rgb = this._rgba.slice(), 13882 a = rgb.pop(), 13883 blend = color( opaque )._rgba; 13884 13885 return color( jQuery.map( rgb, function( v, i ) { 13886 return ( 1 - a ) * blend[ i ] + a * v; 13887 })); 13888 }, 13889 toRgbaString: function() { 13890 var prefix = "rgba(", 13891 rgba = jQuery.map( this._rgba, function( v, i ) { 13892 return v == null ? ( i > 2 ? 1 : 0 ) : v; 13893 }); 13894 13895 if ( rgba[ 3 ] === 1 ) { 13896 rgba.pop(); 13897 prefix = "rgb("; 13898 } 13899 13900 return prefix + rgba.join() + ")"; 13901 }, 13902 toHslaString: function() { 13903 var prefix = "hsla(", 13904 hsla = jQuery.map( this.hsla(), function( v, i ) { 13905 if ( v == null ) { 13906 v = i > 2 ? 1 : 0; 13907 } 13908 13909 /*// catch 1 and 2 13910*/ 13911 if ( i && i < 3 ) { 13912 v = Math.round( v * 100 ) + "%"; 13913 } 13914 return v; 13915 }); 13916 13917 if ( hsla[ 3 ] === 1 ) { 13918 hsla.pop(); 13919 prefix = "hsl("; 13920 } 13921 return prefix + hsla.join() + ")"; 13922 }, 13923 toHexString: function( includeAlpha ) { 13924 var rgba = this._rgba.slice(), 13925 alpha = rgba.pop(); 13926 13927 if ( includeAlpha ) { 13928 rgba.push( ~~( alpha * 255 ) ); 13929 } 13930 13931 return "#" + jQuery.map( rgba, function( v ) { 13932 13933 /*// default to 0 when nulls exist 13934*/ 13935 v = ( v || 0 ).toString( 16 ); 13936 return v.length === 1 ? "0" + v : v; 13937 }).join(""); 13938 }, 13939 toString: function() { 13940 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 13941 } 13942}); 13943color.fn.parse.prototype = color.fn; 13944 13945/*// hsla conversions adapted from: 13946*/ 13947/*// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 13948*/ 13949 13950function hue2rgb( p, q, h ) { 13951 h = ( h + 1 ) % 1; 13952 if ( h * 6 < 1 ) { 13953 return p + (q - p) * h * 6; 13954 } 13955 if ( h * 2 < 1) { 13956 return q; 13957 } 13958 if ( h * 3 < 2 ) { 13959 return p + (q - p) * ((2/3) - h) * 6; 13960 } 13961 return p; 13962} 13963 13964spaces.hsla.to = function ( rgba ) { 13965 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 13966 return [ null, null, null, rgba[ 3 ] ]; 13967 } 13968 var r = rgba[ 0 ] / 255, 13969 g = rgba[ 1 ] / 255, 13970 b = rgba[ 2 ] / 255, 13971 a = rgba[ 3 ], 13972 max = Math.max( r, g, b ), 13973 min = Math.min( r, g, b ), 13974 diff = max - min, 13975 add = max + min, 13976 l = add * 0.5, 13977 h, s; 13978 13979 if ( min === max ) { 13980 h = 0; 13981 } else if ( r === max ) { 13982 h = ( 60 * ( g - b ) / diff ) + 360; 13983 } else if ( g === max ) { 13984 h = ( 60 * ( b - r ) / diff ) + 120; 13985 } else { 13986 h = ( 60 * ( r - g ) / diff ) + 240; 13987 } 13988 13989 /*// chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 13990*/ 13991 /*// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 13992*/ 13993 if ( diff === 0 ) { 13994 s = 0; 13995 } else if ( l <= 0.5 ) { 13996 s = diff / add; 13997 } else { 13998 s = diff / ( 2 - add ); 13999 } 14000 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 14001}; 14002 14003spaces.hsla.from = function ( hsla ) { 14004 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 14005 return [ null, null, null, hsla[ 3 ] ]; 14006 } 14007 var h = hsla[ 0 ] / 360, 14008 s = hsla[ 1 ], 14009 l = hsla[ 2 ], 14010 a = hsla[ 3 ], 14011 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 14012 p = 2 * l - q; 14013 14014 return [ 14015 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 14016 Math.round( hue2rgb( p, q, h ) * 255 ), 14017 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 14018 a 14019 ]; 14020}; 14021 14022 14023each( spaces, function( spaceName, space ) { 14024 var props = space.props, 14025 cache = space.cache, 14026 to = space.to, 14027 from = space.from; 14028 14029 /*// makes rgba() and hsla() 14030*/ 14031 color.fn[ spaceName ] = function( value ) { 14032 14033 /*// generate a cache for this space if it doesn't exist 14034*/ 14035 if ( to && !this[ cache ] ) { 14036 this[ cache ] = to( this._rgba ); 14037 } 14038 if ( value === undefined ) { 14039 return this[ cache ].slice(); 14040 } 14041 14042 var ret, 14043 type = jQuery.type( value ), 14044 arr = ( type === "array" || type === "object" ) ? value : arguments, 14045 local = this[ cache ].slice(); 14046 14047 each( props, function( key, prop ) { 14048 var val = arr[ type === "object" ? key : prop.idx ]; 14049 if ( val == null ) { 14050 val = local[ prop.idx ]; 14051 } 14052 local[ prop.idx ] = clamp( val, prop ); 14053 }); 14054 14055 if ( from ) { 14056 ret = color( from( local ) ); 14057 ret[ cache ] = local; 14058 return ret; 14059 } else { 14060 return color( local ); 14061 } 14062 }; 14063 14064 /*// makes red() green() blue() alpha() hue() saturation() lightness() 14065*/ 14066 each( props, function( key, prop ) { 14067 /*// alpha is included in more than one space 14068*/ 14069 if ( color.fn[ key ] ) { 14070 return; 14071 } 14072 color.fn[ key ] = function( value ) { 14073 var vtype = jQuery.type( value ), 14074 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 14075 local = this[ fn ](), 14076 cur = local[ prop.idx ], 14077 match; 14078 14079 if ( vtype === "undefined" ) { 14080 return cur; 14081 } 14082 14083 if ( vtype === "function" ) { 14084 value = value.call( this, cur ); 14085 vtype = jQuery.type( value ); 14086 } 14087 if ( value == null && prop.empty ) { 14088 return this; 14089 } 14090 if ( vtype === "string" ) { 14091 match = rplusequals.exec( value ); 14092 if ( match ) { 14093 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 14094 } 14095 } 14096 local[ prop.idx ] = value; 14097 return this[ fn ]( local ); 14098 }; 14099 }); 14100}); 14101 14102/*// add cssHook and .fx.step function for each named hook. 14103*/ 14104/*// accept a space separated string of properties 14105*/ 14106color.hook = function( hook ) { 14107 var hooks = hook.split( " " ); 14108 each( hooks, function( i, hook ) { 14109 jQuery.cssHooks[ hook ] = { 14110 set: function( elem, value ) { 14111 var parsed, curElem, 14112 backgroundColor = ""; 14113 14114 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 14115 value = color( parsed || value ); 14116 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 14117 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 14118 while ( 14119 (backgroundColor === "" || backgroundColor === "transparent") && 14120 curElem && curElem.style 14121 ) { 14122 try { 14123 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 14124 curElem = curElem.parentNode; 14125 } catch ( e ) { 14126 } 14127 } 14128 14129 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 14130 backgroundColor : 14131 "_default" ); 14132 } 14133 14134 value = value.toRgbaString(); 14135 } 14136 try { 14137 elem.style[ hook ] = value; 14138 } catch( e ) { 14139 /*// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 14140*/ 14141 } 14142 } 14143 }; 14144 jQuery.fx.step[ hook ] = function( fx ) { 14145 if ( !fx.colorInit ) { 14146 fx.start = color( fx.elem, hook ); 14147 fx.end = color( fx.end ); 14148 fx.colorInit = true; 14149 } 14150 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 14151 }; 14152 }); 14153 14154}; 14155 14156color.hook( stepHooks ); 14157 14158jQuery.cssHooks.borderColor = { 14159 expand: function( value ) { 14160 var expanded = {}; 14161 14162 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 14163 expanded[ "border" + part + "Color" ] = value; 14164 }); 14165 return expanded; 14166 } 14167}; 14168 14169/*// Basic color names only. 14170*/ 14171/*// Usage of any of the other color names requires adding yourself or including 14172*/ 14173/*// jquery.color.svg-names.js. 14174*/ 14175colors = jQuery.Color.names = { 14176 /*// 4.1. Basic color keywords 14177*/ 14178 aqua: "#00ffff", 14179 black: "#000000", 14180 blue: "#0000ff", 14181 fuchsia: "#ff00ff", 14182 gray: "#808080", 14183 green: "#008000", 14184 lime: "#00ff00", 14185 maroon: "#800000", 14186 navy: "#000080", 14187 olive: "#808000", 14188 purple: "#800080", 14189 red: "#ff0000", 14190 silver: "#c0c0c0", 14191 teal: "#008080", 14192 white: "#ffffff", 14193 yellow: "#ffff00", 14194 14195 /*// 4.2.3. "transparent" color keyword 14196*/ 14197 transparent: [ null, null, null, 0 ], 14198 14199 _default: "#ffffff" 14200}; 14201 14202})( jQuery ); 14203 14204 14205/******************************************************************************/ 14206/****************************** CLASS ANIMATIONS ******************************/ 14207/******************************************************************************/ 14208(function() { 14209 14210var classAnimationActions = [ "add", "remove", "toggle" ], 14211 shorthandStyles = { 14212 border: 1, 14213 borderBottom: 1, 14214 borderColor: 1, 14215 borderLeft: 1, 14216 borderRight: 1, 14217 borderTop: 1, 14218 borderWidth: 1, 14219 margin: 1, 14220 padding: 1 14221 }; 14222 14223$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 14224 $.fx.step[ prop ] = function( fx ) { 14225 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 14226 jQuery.style( fx.elem, prop, fx.end ); 14227 fx.setAttr = true; 14228 } 14229 }; 14230}); 14231 14232function getElementStyles( elem ) { 14233 var key, len, 14234 style = elem.ownerDocument.defaultView ? 14235 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 14236 elem.currentStyle, 14237 styles = {}; 14238 14239 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 14240 len = style.length; 14241 while ( len-- ) { 14242 key = style[ len ]; 14243 if ( typeof style[ key ] === "string" ) { 14244 styles[ $.camelCase( key ) ] = style[ key ]; 14245 } 14246 } 14247 /*// support: Opera, IE <9 14248*/ 14249 } else { 14250 for ( key in style ) { 14251 if ( typeof style[ key ] === "string" ) { 14252 styles[ key ] = style[ key ]; 14253 } 14254 } 14255 } 14256 14257 return styles; 14258} 14259 14260 14261function styleDifference( oldStyle, newStyle ) { 14262 var diff = {}, 14263 name, value; 14264 14265 for ( name in newStyle ) { 14266 value = newStyle[ name ]; 14267 if ( oldStyle[ name ] !== value ) { 14268 if ( !shorthandStyles[ name ] ) { 14269 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 14270 diff[ name ] = value; 14271 } 14272 } 14273 } 14274 } 14275 14276 return diff; 14277} 14278 14279/*// support: jQuery <1.8 14280*/ 14281if ( !$.fn.addBack ) { 14282 $.fn.addBack = function( selector ) { 14283 return this.add( selector == null ? 14284 this.prevObject : this.prevObject.filter( selector ) 14285 ); 14286 }; 14287} 14288 14289$.effects.animateClass = function( value, duration, easing, callback ) { 14290 var o = $.speed( duration, easing, callback ); 14291 14292 return this.queue( function() { 14293 var animated = $( this ), 14294 baseClass = animated.attr( "class" ) || "", 14295 applyClassChange, 14296 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 14297 14298 /*// map the animated objects to store the original styles. 14299*/ 14300 allAnimations = allAnimations.map(function() { 14301 var el = $( this ); 14302 return { 14303 el: el, 14304 start: getElementStyles( this ) 14305 }; 14306 }); 14307 14308 /*// apply class change 14309*/ 14310 applyClassChange = function() { 14311 $.each( classAnimationActions, function(i, action) { 14312 if ( value[ action ] ) { 14313 animated[ action + "Class" ]( value[ action ] ); 14314 } 14315 }); 14316 }; 14317 applyClassChange(); 14318 14319 /*// map all animated objects again - calculate new styles and diff 14320*/ 14321 allAnimations = allAnimations.map(function() { 14322 this.end = getElementStyles( this.el[ 0 ] ); 14323 this.diff = styleDifference( this.start, this.end ); 14324 return this; 14325 }); 14326 14327 /*// apply original class 14328*/ 14329 animated.attr( "class", baseClass ); 14330 14331 /*// map all animated objects again - this time collecting a promise 14332*/ 14333 allAnimations = allAnimations.map(function() { 14334 var styleInfo = this, 14335 dfd = $.Deferred(), 14336 opts = $.extend({}, o, { 14337 queue: false, 14338 complete: function() { 14339 dfd.resolve( styleInfo ); 14340 } 14341 }); 14342 14343 this.el.animate( this.diff, opts ); 14344 return dfd.promise(); 14345 }); 14346 14347 /*// once all animations have completed: 14348*/ 14349 $.when.apply( $, allAnimations.get() ).done(function() { 14350 14351 /*// set the final class 14352*/ 14353 applyClassChange(); 14354 14355 /*// for each animated element, 14356*/ 14357 /*// clear all css properties that were animated 14358*/ 14359 $.each( arguments, function() { 14360 var el = this.el; 14361 $.each( this.diff, function(key) { 14362 el.css( key, "" ); 14363 }); 14364 }); 14365 14366 /*// this is guarnteed to be there if you use jQuery.speed() 14367*/ 14368 /*// it also handles dequeuing the next anim... 14369*/ 14370 o.complete.call( animated[ 0 ] ); 14371 }); 14372 }); 14373}; 14374 14375$.fn.extend({ 14376 addClass: (function( orig ) { 14377 return function( classNames, speed, easing, callback ) { 14378 return speed ? 14379 $.effects.animateClass.call( this, 14380 { add: classNames }, speed, easing, callback ) : 14381 orig.apply( this, arguments ); 14382 }; 14383 })( $.fn.addClass ), 14384 14385 removeClass: (function( orig ) { 14386 return function( classNames, speed, easing, callback ) { 14387 return arguments.length > 1 ? 14388 $.effects.animateClass.call( this, 14389 { remove: classNames }, speed, easing, callback ) : 14390 orig.apply( this, arguments ); 14391 }; 14392 })( $.fn.removeClass ), 14393 14394 toggleClass: (function( orig ) { 14395 return function( classNames, force, speed, easing, callback ) { 14396 if ( typeof force === "boolean" || force === undefined ) { 14397 if ( !speed ) { 14398 /*// without speed parameter 14399*/ 14400 return orig.apply( this, arguments ); 14401 } else { 14402 return $.effects.animateClass.call( this, 14403 (force ? { add: classNames } : { remove: classNames }), 14404 speed, easing, callback ); 14405 } 14406 } else { 14407 /*// without force parameter 14408*/ 14409 return $.effects.animateClass.call( this, 14410 { toggle: classNames }, force, speed, easing ); 14411 } 14412 }; 14413 })( $.fn.toggleClass ), 14414 14415 switchClass: function( remove, add, speed, easing, callback) { 14416 return $.effects.animateClass.call( this, { 14417 add: add, 14418 remove: remove 14419 }, speed, easing, callback ); 14420 } 14421}); 14422 14423})(); 14424 14425/******************************************************************************/ 14426/*********************************** EFFECTS **********************************/ 14427/******************************************************************************/ 14428 14429(function() { 14430 14431$.extend( $.effects, { 14432 version: "1.10.2", 14433 14434 /*// Saves a set of properties in a data storage 14435*/ 14436 save: function( element, set ) { 14437 for( var i=0; i < set.length; i++ ) { 14438 if ( set[ i ] !== null ) { 14439 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 14440 } 14441 } 14442 }, 14443 14444 /*// Restores a set of previously saved properties from a data storage 14445*/ 14446 restore: function( element, set ) { 14447 var val, i; 14448 for( i=0; i < set.length; i++ ) { 14449 if ( set[ i ] !== null ) { 14450 val = element.data( dataSpace + set[ i ] ); 14451 /*// support: jQuery 1.6.2 14452*/ 14453 /*// http://bugs.jquery.com/ticket/9917 14454*/ 14455 /*// jQuery 1.6.2 incorrectly returns undefined for any falsy value. 14456*/ 14457 /*// We can't differentiate between "" and 0 here, so we just assume 14458*/ 14459 /*// empty string since it's likely to be a more common value... 14460*/ 14461 if ( val === undefined ) { 14462 val = ""; 14463 } 14464 element.css( set[ i ], val ); 14465 } 14466 } 14467 }, 14468 14469 setMode: function( el, mode ) { 14470 if (mode === "toggle") { 14471 mode = el.is( ":hidden" ) ? "show" : "hide"; 14472 } 14473 return mode; 14474 }, 14475 14476 /*// Translates a [top,left] array into a baseline value 14477*/ 14478 /*// this should be a little more flexible in the future to handle a string & hash 14479*/ 14480 getBaseline: function( origin, original ) { 14481 var y, x; 14482 switch ( origin[ 0 ] ) { 14483 case "top": y = 0; break; 14484 case "middle": y = 0.5; break; 14485 case "bottom": y = 1; break; 14486 default: y = origin[ 0 ] / original.height; 14487 } 14488 switch ( origin[ 1 ] ) { 14489 case "left": x = 0; break; 14490 case "center": x = 0.5; break; 14491 case "right": x = 1; break; 14492 default: x = origin[ 1 ] / original.width; 14493 } 14494 return { 14495 x: x, 14496 y: y 14497 }; 14498 }, 14499 14500 /*// Wraps the element around a wrapper that copies position properties 14501*/ 14502 createWrapper: function( element ) { 14503 14504 /*// if the element is already wrapped, return it 14505*/ 14506 if ( element.parent().is( ".ui-effects-wrapper" )) { 14507 return element.parent(); 14508 } 14509 14510 /*// wrap the element 14511*/ 14512 var props = { 14513 width: element.outerWidth(true), 14514 height: element.outerHeight(true), 14515 "float": element.css( "float" ) 14516 }, 14517 wrapper = $( "<div></div>" ) 14518 .addClass( "ui-effects-wrapper" ) 14519 .css({ 14520 fontSize: "100%", 14521 background: "transparent", 14522 border: "none", 14523 margin: 0, 14524 padding: 0 14525 }), 14526 /*// Store the size in case width/height are defined in % - Fixes #5245 14527*/ 14528 size = { 14529 width: element.width(), 14530 height: element.height() 14531 }, 14532 active = document.activeElement; 14533 14534 /*// support: Firefox 14535*/ 14536 /*// Firefox incorrectly exposes anonymous content 14537*/ 14538 /*// https://bugzilla.mozilla.org/show_bug.cgi?id=561664 14539*/ 14540 try { 14541 active.id; 14542 } catch( e ) { 14543 active = document.body; 14544 } 14545 14546 element.wrap( wrapper ); 14547 14548 /*// Fixes #7595 - Elements lose focus when wrapped. 14549*/ 14550 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14551 $( active ).focus(); 14552 } 14553 14554 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 14555 14556 /*// transfer positioning properties to the wrapper 14557*/ 14558 if ( element.css( "position" ) === "static" ) { 14559 wrapper.css({ position: "relative" }); 14560 element.css({ position: "relative" }); 14561 } else { 14562 $.extend( props, { 14563 position: element.css( "position" ), 14564 zIndex: element.css( "z-index" ) 14565 }); 14566 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 14567 props[ pos ] = element.css( pos ); 14568 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 14569 props[ pos ] = "auto"; 14570 } 14571 }); 14572 element.css({ 14573 position: "relative", 14574 top: 0, 14575 left: 0, 14576 right: "auto", 14577 bottom: "auto" 14578 }); 14579 } 14580 element.css(size); 14581 14582 return wrapper.css( props ).show(); 14583 }, 14584 14585 removeWrapper: function( element ) { 14586 var active = document.activeElement; 14587 14588 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 14589 element.parent().replaceWith( element ); 14590 14591 /*// Fixes #7595 - Elements lose focus when wrapped. 14592*/ 14593 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 14594 $( active ).focus(); 14595 } 14596 } 14597 14598 14599 return element; 14600 }, 14601 14602 setTransition: function( element, list, factor, value ) { 14603 value = value || {}; 14604 $.each( list, function( i, x ) { 14605 var unit = element.cssUnit( x ); 14606 if ( unit[ 0 ] > 0 ) { 14607 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 14608 } 14609 }); 14610 return value; 14611 } 14612}); 14613 14614/*// return an effect options object for the given parameters: 14615*/ 14616function _normalizeArguments( effect, options, speed, callback ) { 14617 14618 /*// allow passing all options as the first parameter 14619*/ 14620 if ( $.isPlainObject( effect ) ) { 14621 options = effect; 14622 effect = effect.effect; 14623 } 14624 14625 /*// convert to an object 14626*/ 14627 effect = { effect: effect }; 14628 14629 /*// catch (effect, null, ...) 14630*/ 14631 if ( options == null ) { 14632 options = {}; 14633 } 14634 14635 /*// catch (effect, callback) 14636*/ 14637 if ( $.isFunction( options ) ) { 14638 callback = options; 14639 speed = null; 14640 options = {}; 14641 } 14642 14643 /*// catch (effect, speed, ?) 14644*/ 14645 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 14646 callback = speed; 14647 speed = options; 14648 options = {}; 14649 } 14650 14651 /*// catch (effect, options, callback) 14652*/ 14653 if ( $.isFunction( speed ) ) { 14654 callback = speed; 14655 speed = null; 14656 } 14657 14658 /*// add options to effect 14659*/ 14660 if ( options ) { 14661 $.extend( effect, options ); 14662 } 14663 14664 speed = speed || options.duration; 14665 effect.duration = $.fx.off ? 0 : 14666 typeof speed === "number" ? speed : 14667 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 14668 $.fx.speeds._default; 14669 14670 effect.complete = callback || options.complete; 14671 14672 return effect; 14673} 14674 14675function standardAnimationOption( option ) { 14676 /*// Valid standard speeds (nothing, number, named speed) 14677*/ 14678 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 14679 return true; 14680 } 14681 14682 /*// Invalid strings - treat as "normal" speed 14683*/ 14684 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 14685 return true; 14686 } 14687 14688 /*// Complete callback 14689*/ 14690 if ( $.isFunction( option ) ) { 14691 return true; 14692 } 14693 14694 /*// Options hash (but not naming an effect) 14695*/ 14696 if ( typeof option === "object" && !option.effect ) { 14697 return true; 14698 } 14699 14700 /*// Didn't match any standard API 14701*/ 14702 return false; 14703} 14704 14705$.fn.extend({ 14706 effect: function( /* effect, options, speed, callback */ ) { 14707 var args = _normalizeArguments.apply( this, arguments ), 14708 mode = args.mode, 14709 queue = args.queue, 14710 effectMethod = $.effects.effect[ args.effect ]; 14711 14712 if ( $.fx.off || !effectMethod ) { 14713 /*// delegate to the original method (e.g., .show()) if possible 14714*/ 14715 if ( mode ) { 14716 return this[ mode ]( args.duration, args.complete ); 14717 } else { 14718 return this.each( function() { 14719 if ( args.complete ) { 14720 args.complete.call( this ); 14721 } 14722 }); 14723 } 14724 } 14725 14726 function run( next ) { 14727 var elem = $( this ), 14728 complete = args.complete, 14729 mode = args.mode; 14730 14731 function done() { 14732 if ( $.isFunction( complete ) ) { 14733 complete.call( elem[0] ); 14734 } 14735 if ( $.isFunction( next ) ) { 14736 next(); 14737 } 14738 } 14739 14740 /*// If the element already has the correct final state, delegate to 14741*/ 14742 /*// the core methods so the internal tracking of "olddisplay" works. 14743*/ 14744 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 14745 elem[ mode ](); 14746 done(); 14747 } else { 14748 effectMethod.call( elem[0], args, done ); 14749 } 14750 } 14751 14752 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 14753 }, 14754 14755 show: (function( orig ) { 14756 return function( option ) { 14757 if ( standardAnimationOption( option ) ) { 14758 return orig.apply( this, arguments ); 14759 } else { 14760 var args = _normalizeArguments.apply( this, arguments ); 14761 args.mode = "show"; 14762 return this.effect.call( this, args ); 14763 } 14764 }; 14765 })( $.fn.show ), 14766 14767 hide: (function( orig ) { 14768 return function( option ) { 14769 if ( standardAnimationOption( option ) ) { 14770 return orig.apply( this, arguments ); 14771 } else { 14772 var args = _normalizeArguments.apply( this, arguments ); 14773 args.mode = "hide"; 14774 return this.effect.call( this, args ); 14775 } 14776 }; 14777 })( $.fn.hide ), 14778 14779 toggle: (function( orig ) { 14780 return function( option ) { 14781 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 14782 return orig.apply( this, arguments ); 14783 } else { 14784 var args = _normalizeArguments.apply( this, arguments ); 14785 args.mode = "toggle"; 14786 return this.effect.call( this, args ); 14787 } 14788 }; 14789 })( $.fn.toggle ), 14790 14791 /*// helper functions 14792*/ 14793 cssUnit: function(key) { 14794 var style = this.css( key ), 14795 val = []; 14796 14797 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 14798 if ( style.indexOf( unit ) > 0 ) { 14799 val = [ parseFloat( style ), unit ]; 14800 } 14801 }); 14802 return val; 14803 } 14804}); 14805 14806})(); 14807 14808/******************************************************************************/ 14809/*********************************** EASING ***********************************/ 14810/******************************************************************************/ 14811 14812(function() { 14813 14814/*// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 14815*/ 14816 14817var baseEasings = {}; 14818 14819$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 14820 baseEasings[ name ] = function( p ) { 14821 return Math.pow( p, i + 2 ); 14822 }; 14823}); 14824 14825$.extend( baseEasings, { 14826 Sine: function ( p ) { 14827 return 1 - Math.cos( p * Math.PI / 2 ); 14828 }, 14829 Circ: function ( p ) { 14830 return 1 - Math.sqrt( 1 - p * p ); 14831 }, 14832 Elastic: function( p ) { 14833 return p === 0 || p === 1 ? p : 14834 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 14835 }, 14836 Back: function( p ) { 14837 return p * p * ( 3 * p - 2 ); 14838 }, 14839 Bounce: function ( p ) { 14840 var pow2, 14841 bounce = 4; 14842 14843 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 14844 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 14845 } 14846}); 14847 14848$.each( baseEasings, function( name, easeIn ) { 14849 $.easing[ "easeIn" + name ] = easeIn; 14850 $.easing[ "easeOut" + name ] = function( p ) { 14851 return 1 - easeIn( 1 - p ); 14852 }; 14853 $.easing[ "easeInOut" + name ] = function( p ) { 14854 return p < 0.5 ? 14855 easeIn( p * 2 ) / 2 : 14856 1 - easeIn( p * -2 + 2 ) / 2; 14857 }; 14858}); 14859 14860})(); 14861 14862})(jQuery); 14863(function( $, undefined ) { 14864 14865var rvertical = /up|down|vertical/, 14866 rpositivemotion = /up|left|vertical|horizontal/; 14867 14868$.effects.effect.blind = function( o, done ) { 14869 /*// Create element 14870*/ 14871 var el = $( this ), 14872 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14873 mode = $.effects.setMode( el, o.mode || "hide" ), 14874 direction = o.direction || "up", 14875 vertical = rvertical.test( direction ), 14876 ref = vertical ? "height" : "width", 14877 ref2 = vertical ? "top" : "left", 14878 motion = rpositivemotion.test( direction ), 14879 animation = {}, 14880 show = mode === "show", 14881 wrapper, distance, margin; 14882 14883 /*// if already wrapped, the wrapper's properties are my property. #6245 14884*/ 14885 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 14886 $.effects.save( el.parent(), props ); 14887 } else { 14888 $.effects.save( el, props ); 14889 } 14890 el.show(); 14891 wrapper = $.effects.createWrapper( el ).css({ 14892 overflow: "hidden" 14893 }); 14894 14895 distance = wrapper[ ref ](); 14896 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 14897 14898 animation[ ref ] = show ? distance : 0; 14899 if ( !motion ) { 14900 el 14901 .css( vertical ? "bottom" : "right", 0 ) 14902 .css( vertical ? "top" : "left", "auto" ) 14903 .css({ position: "absolute" }); 14904 14905 animation[ ref2 ] = show ? margin : distance + margin; 14906 } 14907 14908 /*// start at 0 if we are showing 14909*/ 14910 if ( show ) { 14911 wrapper.css( ref, 0 ); 14912 if ( ! motion ) { 14913 wrapper.css( ref2, margin + distance ); 14914 } 14915 } 14916 14917 /*// Animate 14918*/ 14919 wrapper.animate( animation, { 14920 duration: o.duration, 14921 easing: o.easing, 14922 queue: false, 14923 complete: function() { 14924 if ( mode === "hide" ) { 14925 el.hide(); 14926 } 14927 $.effects.restore( el, props ); 14928 $.effects.removeWrapper( el ); 14929 done(); 14930 } 14931 }); 14932 14933}; 14934 14935})(jQuery); 14936(function( $, undefined ) { 14937 14938$.effects.effect.bounce = function( o, done ) { 14939 var el = $( this ), 14940 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 14941 14942 /*// defaults: 14943*/ 14944 mode = $.effects.setMode( el, o.mode || "effect" ), 14945 hide = mode === "hide", 14946 show = mode === "show", 14947 direction = o.direction || "up", 14948 distance = o.distance, 14949 times = o.times || 5, 14950 14951 /*// number of internal animations 14952*/ 14953 anims = times * 2 + ( show || hide ? 1 : 0 ), 14954 speed = o.duration / anims, 14955 easing = o.easing, 14956 14957 /*// utility: 14958*/ 14959 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14960 motion = ( direction === "up" || direction === "left" ), 14961 i, 14962 upAnim, 14963 downAnim, 14964 14965 /*// we will need to re-assemble the queue to stack our animations in place 14966*/ 14967 queue = el.queue(), 14968 queuelen = queue.length; 14969 14970 /*// Avoid touching opacity to prevent clearType and PNG issues in IE 14971*/ 14972 if ( show || hide ) { 14973 props.push( "opacity" ); 14974 } 14975 14976 $.effects.save( el, props ); 14977 el.show(); 14978 $.effects.createWrapper( el ); /*// Create Wrapper 14979*/ 14980 14981 /*// default distance for the BIGGEST bounce is the outer Distance / 3 14982*/ 14983 if ( !distance ) { 14984 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 14985 } 14986 14987 if ( show ) { 14988 downAnim = { opacity: 1 }; 14989 downAnim[ ref ] = 0; 14990 14991 /*// if we are showing, force opacity 0 and set the initial position 14992*/ 14993 /*// then do the "first" animation 14994*/ 14995 el.css( "opacity", 0 ) 14996 .css( ref, motion ? -distance * 2 : distance * 2 ) 14997 .animate( downAnim, speed, easing ); 14998 } 14999 15000 /*// start at the smallest distance if we are hiding 15001*/ 15002 if ( hide ) { 15003 distance = distance / Math.pow( 2, times - 1 ); 15004 } 15005 15006 downAnim = {}; 15007 downAnim[ ref ] = 0; 15008 /*// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 15009*/ 15010 for ( i = 0; i < times; i++ ) { 15011 upAnim = {}; 15012 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15013 15014 el.animate( upAnim, speed, easing ) 15015 .animate( downAnim, speed, easing ); 15016 15017 distance = hide ? distance * 2 : distance / 2; 15018 } 15019 15020 /*// Last Bounce when Hiding 15021*/ 15022 if ( hide ) { 15023 upAnim = { opacity: 0 }; 15024 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15025 15026 el.animate( upAnim, speed, easing ); 15027 } 15028 15029 el.queue(function() { 15030 if ( hide ) { 15031 el.hide(); 15032 } 15033 $.effects.restore( el, props ); 15034 $.effects.removeWrapper( el ); 15035 done(); 15036 }); 15037 15038 /*// inject all the animations we just queued to be first in line (after "inprogress") 15039*/ 15040 if ( queuelen > 1) { 15041 queue.splice.apply( queue, 15042 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15043 } 15044 el.dequeue(); 15045 15046}; 15047 15048})(jQuery); 15049(function( $, undefined ) { 15050 15051$.effects.effect.clip = function( o, done ) { 15052 /*// Create element 15053*/ 15054 var el = $( this ), 15055 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15056 mode = $.effects.setMode( el, o.mode || "hide" ), 15057 show = mode === "show", 15058 direction = o.direction || "vertical", 15059 vert = direction === "vertical", 15060 size = vert ? "height" : "width", 15061 position = vert ? "top" : "left", 15062 animation = {}, 15063 wrapper, animate, distance; 15064 15065 /*// Save & Show 15066*/ 15067 $.effects.save( el, props ); 15068 el.show(); 15069 15070 /*// Create Wrapper 15071*/ 15072 wrapper = $.effects.createWrapper( el ).css({ 15073 overflow: "hidden" 15074 }); 15075 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 15076 distance = animate[ size ](); 15077 15078 /*// Shift 15079*/ 15080 if ( show ) { 15081 animate.css( size, 0 ); 15082 animate.css( position, distance / 2 ); 15083 } 15084 15085 /*// Create Animation Object: 15086*/ 15087 animation[ size ] = show ? distance : 0; 15088 animation[ position ] = show ? 0 : distance / 2; 15089 15090 /*// Animate 15091*/ 15092 animate.animate( animation, { 15093 queue: false, 15094 duration: o.duration, 15095 easing: o.easing, 15096 complete: function() { 15097 if ( !show ) { 15098 el.hide(); 15099 } 15100 $.effects.restore( el, props ); 15101 $.effects.removeWrapper( el ); 15102 done(); 15103 } 15104 }); 15105 15106}; 15107 15108})(jQuery); 15109(function( $, undefined ) { 15110 15111$.effects.effect.drop = function( o, done ) { 15112 15113 var el = $( this ), 15114 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 15115 mode = $.effects.setMode( el, o.mode || "hide" ), 15116 show = mode === "show", 15117 direction = o.direction || "left", 15118 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15119 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 15120 animation = { 15121 opacity: show ? 1 : 0 15122 }, 15123 distance; 15124 15125 /*// Adjust 15126*/ 15127 $.effects.save( el, props ); 15128 el.show(); 15129 $.effects.createWrapper( el ); 15130 15131 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 15132 15133 if ( show ) { 15134 el 15135 .css( "opacity", 0 ) 15136 .css( ref, motion === "pos" ? -distance : distance ); 15137 } 15138 15139 /*// Animation 15140*/ 15141 animation[ ref ] = ( show ? 15142 ( motion === "pos" ? "+=" : "-=" ) : 15143 ( motion === "pos" ? "-=" : "+=" ) ) + 15144 distance; 15145 15146 /*// Animate 15147*/ 15148 el.animate( animation, { 15149 queue: false, 15150 duration: o.duration, 15151 easing: o.easing, 15152 complete: function() { 15153 if ( mode === "hide" ) { 15154 el.hide(); 15155 } 15156 $.effects.restore( el, props ); 15157 $.effects.removeWrapper( el ); 15158 done(); 15159 } 15160 }); 15161}; 15162 15163})(jQuery); 15164(function( $, undefined ) { 15165 15166$.effects.effect.explode = function( o, done ) { 15167 15168 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 15169 cells = rows, 15170 el = $( this ), 15171 mode = $.effects.setMode( el, o.mode || "hide" ), 15172 show = mode === "show", 15173 15174 /*// show and then visibility:hidden the element before calculating offset 15175*/ 15176 offset = el.show().css( "visibility", "hidden" ).offset(), 15177 15178 /*// width and height of a piece 15179*/ 15180 width = Math.ceil( el.outerWidth() / cells ), 15181 height = Math.ceil( el.outerHeight() / rows ), 15182 pieces = [], 15183 15184 /*// loop 15185*/ 15186 i, j, left, top, mx, my; 15187 15188 /*// children animate complete: 15189*/ 15190 function childComplete() { 15191 pieces.push( this ); 15192 if ( pieces.length === rows * cells ) { 15193 animComplete(); 15194 } 15195 } 15196 15197 /*// clone the element for each row and cell. 15198*/ 15199 for( i = 0; i < rows ; i++ ) { /*// ===> 15200*/ 15201 top = offset.top + i * height; 15202 my = i - ( rows - 1 ) / 2 ; 15203 15204 for( j = 0; j < cells ; j++ ) { /*// ||| 15205*/ 15206 left = offset.left + j * width; 15207 mx = j - ( cells - 1 ) / 2 ; 15208 15209 /*// Create a clone of the now hidden main element that will be absolute positioned 15210*/ 15211 /*// within a wrapper div off the -left and -top equal to size of our pieces 15212*/ 15213 el 15214 .clone() 15215 .appendTo( "body" ) 15216 .wrap( "<div></div>" ) 15217 .css({ 15218 position: "absolute", 15219 visibility: "visible", 15220 left: -j * width, 15221 top: -i * height 15222 }) 15223 15224 /*// select the wrapper - make it overflow: hidden and absolute positioned based on 15225*/ 15226 /*// where the original was located +left and +top equal to the size of pieces 15227*/ 15228 .parent() 15229 .addClass( "ui-effects-explode" ) 15230 .css({ 15231 position: "absolute", 15232 overflow: "hidden", 15233 width: width, 15234 height: height, 15235 left: left + ( show ? mx * width : 0 ), 15236 top: top + ( show ? my * height : 0 ), 15237 opacity: show ? 0 : 1 15238 }).animate({ 15239 left: left + ( show ? 0 : mx * width ), 15240 top: top + ( show ? 0 : my * height ), 15241 opacity: show ? 1 : 0 15242 }, o.duration || 500, o.easing, childComplete ); 15243 } 15244 } 15245 15246 function animComplete() { 15247 el.css({ 15248 visibility: "visible" 15249 }); 15250 $( pieces ).remove(); 15251 if ( !show ) { 15252 el.hide(); 15253 } 15254 done(); 15255 } 15256}; 15257 15258})(jQuery); 15259(function( $, undefined ) { 15260 15261$.effects.effect.fade = function( o, done ) { 15262 var el = $( this ), 15263 mode = $.effects.setMode( el, o.mode || "toggle" ); 15264 15265 el.animate({ 15266 opacity: mode 15267 }, { 15268 queue: false, 15269 duration: o.duration, 15270 easing: o.easing, 15271 complete: done 15272 }); 15273}; 15274 15275})( jQuery ); 15276(function( $, undefined ) { 15277 15278$.effects.effect.fold = function( o, done ) { 15279 15280 /*// Create element 15281*/ 15282 var el = $( this ), 15283 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15284 mode = $.effects.setMode( el, o.mode || "hide" ), 15285 show = mode === "show", 15286 hide = mode === "hide", 15287 size = o.size || 15, 15288 percent = /([0-9]+)%/.exec( size ), 15289 horizFirst = !!o.horizFirst, 15290 widthFirst = show !== horizFirst, 15291 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 15292 duration = o.duration / 2, 15293 wrapper, distance, 15294 animation1 = {}, 15295 animation2 = {}; 15296 15297 $.effects.save( el, props ); 15298 el.show(); 15299 15300 /*// Create Wrapper 15301*/ 15302 wrapper = $.effects.createWrapper( el ).css({ 15303 overflow: "hidden" 15304 }); 15305 distance = widthFirst ? 15306 [ wrapper.width(), wrapper.height() ] : 15307 [ wrapper.height(), wrapper.width() ]; 15308 15309 if ( percent ) { 15310 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 15311 } 15312 if ( show ) { 15313 wrapper.css( horizFirst ? { 15314 height: 0, 15315 width: size 15316 } : { 15317 height: size, 15318 width: 0 15319 }); 15320 } 15321 15322 /*// Animation 15323*/ 15324 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 15325 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 15326 15327 /*// Animate 15328*/ 15329 wrapper 15330 .animate( animation1, duration, o.easing ) 15331 .animate( animation2, duration, o.easing, function() { 15332 if ( hide ) { 15333 el.hide(); 15334 } 15335 $.effects.restore( el, props ); 15336 $.effects.removeWrapper( el ); 15337 done(); 15338 }); 15339 15340}; 15341 15342})(jQuery); 15343(function( $, undefined ) { 15344 15345$.effects.effect.highlight = function( o, done ) { 15346 var elem = $( this ), 15347 props = [ "backgroundImage", "backgroundColor", "opacity" ], 15348 mode = $.effects.setMode( elem, o.mode || "show" ), 15349 animation = { 15350 backgroundColor: elem.css( "backgroundColor" ) 15351 }; 15352 15353 if (mode === "hide") { 15354 animation.opacity = 0; 15355 } 15356 15357 $.effects.save( elem, props ); 15358 15359 elem 15360 .show() 15361 .css({ 15362 backgroundImage: "none", 15363 backgroundColor: o.color || "#ffff99" 15364 }) 15365 .animate( animation, { 15366 queue: false, 15367 duration: o.duration, 15368 easing: o.easing, 15369 complete: function() { 15370 if ( mode === "hide" ) { 15371 elem.hide(); 15372 } 15373 $.effects.restore( elem, props ); 15374 done(); 15375 } 15376 }); 15377}; 15378 15379})(jQuery); 15380(function( $, undefined ) { 15381 15382$.effects.effect.pulsate = function( o, done ) { 15383 var elem = $( this ), 15384 mode = $.effects.setMode( elem, o.mode || "show" ), 15385 show = mode === "show", 15386 hide = mode === "hide", 15387 showhide = ( show || mode === "hide" ), 15388 15389 /*// showing or hiding leaves of the "last" animation 15390*/ 15391 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 15392 duration = o.duration / anims, 15393 animateTo = 0, 15394 queue = elem.queue(), 15395 queuelen = queue.length, 15396 i; 15397 15398 if ( show || !elem.is(":visible")) { 15399 elem.css( "opacity", 0 ).show(); 15400 animateTo = 1; 15401 } 15402 15403 /*// anims - 1 opacity "toggles" 15404*/ 15405 for ( i = 1; i < anims; i++ ) { 15406 elem.animate({ 15407 opacity: animateTo 15408 }, duration, o.easing ); 15409 animateTo = 1 - animateTo; 15410 } 15411 15412 elem.animate({ 15413 opacity: animateTo 15414 }, duration, o.easing); 15415 15416 elem.queue(function() { 15417 if ( hide ) { 15418 elem.hide(); 15419 } 15420 done(); 15421 }); 15422 15423 /*// We just queued up "anims" animations, we need to put them next in the queue 15424*/ 15425 if ( queuelen > 1 ) { 15426 queue.splice.apply( queue, 15427 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15428 } 15429 elem.dequeue(); 15430}; 15431 15432})(jQuery); 15433(function( $, undefined ) { 15434 15435$.effects.effect.puff = function( o, done ) { 15436 var elem = $( this ), 15437 mode = $.effects.setMode( elem, o.mode || "hide" ), 15438 hide = mode === "hide", 15439 percent = parseInt( o.percent, 10 ) || 150, 15440 factor = percent / 100, 15441 original = { 15442 height: elem.height(), 15443 width: elem.width(), 15444 outerHeight: elem.outerHeight(), 15445 outerWidth: elem.outerWidth() 15446 }; 15447 15448 $.extend( o, { 15449 effect: "scale", 15450 queue: false, 15451 fade: true, 15452 mode: mode, 15453 complete: done, 15454 percent: hide ? percent : 100, 15455 from: hide ? 15456 original : 15457 { 15458 height: original.height * factor, 15459 width: original.width * factor, 15460 outerHeight: original.outerHeight * factor, 15461 outerWidth: original.outerWidth * factor 15462 } 15463 }); 15464 15465 elem.effect( o ); 15466}; 15467 15468$.effects.effect.scale = function( o, done ) { 15469 15470 /*// Create element 15471*/ 15472 var el = $( this ), 15473 options = $.extend( true, {}, o ), 15474 mode = $.effects.setMode( el, o.mode || "effect" ), 15475 percent = parseInt( o.percent, 10 ) || 15476 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 15477 direction = o.direction || "both", 15478 origin = o.origin, 15479 original = { 15480 height: el.height(), 15481 width: el.width(), 15482 outerHeight: el.outerHeight(), 15483 outerWidth: el.outerWidth() 15484 }, 15485 factor = { 15486 y: direction !== "horizontal" ? (percent / 100) : 1, 15487 x: direction !== "vertical" ? (percent / 100) : 1 15488 }; 15489 15490 /*// We are going to pass this effect to the size effect: 15491*/ 15492 options.effect = "size"; 15493 options.queue = false; 15494 options.complete = done; 15495 15496 /*// Set default origin and restore for show/hide 15497*/ 15498 if ( mode !== "effect" ) { 15499 options.origin = origin || ["middle","center"]; 15500 options.restore = true; 15501 } 15502 15503 options.from = o.from || ( mode === "show" ? { 15504 height: 0, 15505 width: 0, 15506 outerHeight: 0, 15507 outerWidth: 0 15508 } : original ); 15509 options.to = { 15510 height: original.height * factor.y, 15511 width: original.width * factor.x, 15512 outerHeight: original.outerHeight * factor.y, 15513 outerWidth: original.outerWidth * factor.x 15514 }; 15515 15516 /*// Fade option to support puff 15517*/ 15518 if ( options.fade ) { 15519 if ( mode === "show" ) { 15520 options.from.opacity = 0; 15521 options.to.opacity = 1; 15522 } 15523 if ( mode === "hide" ) { 15524 options.from.opacity = 1; 15525 options.to.opacity = 0; 15526 } 15527 } 15528 15529 /*// Animate 15530*/ 15531 el.effect( options ); 15532 15533}; 15534 15535$.effects.effect.size = function( o, done ) { 15536 15537 /*// Create element 15538*/ 15539 var original, baseline, factor, 15540 el = $( this ), 15541 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 15542 15543 /*// Always restore 15544*/ 15545 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 15546 15547 /*// Copy for children 15548*/ 15549 props2 = [ "width", "height", "overflow" ], 15550 cProps = [ "fontSize" ], 15551 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 15552 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 15553 15554 /*// Set options 15555*/ 15556 mode = $.effects.setMode( el, o.mode || "effect" ), 15557 restore = o.restore || mode !== "effect", 15558 scale = o.scale || "both", 15559 origin = o.origin || [ "middle", "center" ], 15560 position = el.css( "position" ), 15561 props = restore ? props0 : props1, 15562 zero = { 15563 height: 0, 15564 width: 0, 15565 outerHeight: 0, 15566 outerWidth: 0 15567 }; 15568 15569 if ( mode === "show" ) { 15570 el.show(); 15571 } 15572 original = { 15573 height: el.height(), 15574 width: el.width(), 15575 outerHeight: el.outerHeight(), 15576 outerWidth: el.outerWidth() 15577 }; 15578 15579 if ( o.mode === "toggle" && mode === "show" ) { 15580 el.from = o.to || zero; 15581 el.to = o.from || original; 15582 } else { 15583 el.from = o.from || ( mode === "show" ? zero : original ); 15584 el.to = o.to || ( mode === "hide" ? zero : original ); 15585 } 15586 15587 /*// Set scaling factor 15588*/ 15589 factor = { 15590 from: { 15591 y: el.from.height / original.height, 15592 x: el.from.width / original.width 15593 }, 15594 to: { 15595 y: el.to.height / original.height, 15596 x: el.to.width / original.width 15597 } 15598 }; 15599 15600 /*// Scale the css box 15601*/ 15602 if ( scale === "box" || scale === "both" ) { 15603 15604 /*// Vertical props scaling 15605*/ 15606 if ( factor.from.y !== factor.to.y ) { 15607 props = props.concat( vProps ); 15608 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 15609 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 15610 } 15611 15612 /*// Horizontal props scaling 15613*/ 15614 if ( factor.from.x !== factor.to.x ) { 15615 props = props.concat( hProps ); 15616 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 15617 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 15618 } 15619 } 15620 15621 /*// Scale the content 15622*/ 15623 if ( scale === "content" || scale === "both" ) { 15624 15625 /*// Vertical props scaling 15626*/ 15627 if ( factor.from.y !== factor.to.y ) { 15628 props = props.concat( cProps ).concat( props2 ); 15629 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 15630 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 15631 } 15632 } 15633 15634 $.effects.save( el, props ); 15635 el.show(); 15636 $.effects.createWrapper( el ); 15637 el.css( "overflow", "hidden" ).css( el.from ); 15638 15639 /*// Adjust 15640*/ 15641 if (origin) { /*// Calculate baseline shifts 15642*/ 15643 baseline = $.effects.getBaseline( origin, original ); 15644 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 15645 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 15646 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 15647 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 15648 } 15649 el.css( el.from ); /*// set top & left 15650*/ 15651 15652 /*// Animate 15653*/ 15654 if ( scale === "content" || scale === "both" ) { /*// Scale the children 15655*/ 15656 15657 /*// Add margins/font-size 15658*/ 15659 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 15660 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 15661 props2 = props0.concat(vProps).concat(hProps); 15662 15663 el.find( "*[width]" ).each( function(){ 15664 var child = $( this ), 15665 c_original = { 15666 height: child.height(), 15667 width: child.width(), 15668 outerHeight: child.outerHeight(), 15669 outerWidth: child.outerWidth() 15670 }; 15671 if (restore) { 15672 $.effects.save(child, props2); 15673 } 15674 15675 child.from = { 15676 height: c_original.height * factor.from.y, 15677 width: c_original.width * factor.from.x, 15678 outerHeight: c_original.outerHeight * factor.from.y, 15679 outerWidth: c_original.outerWidth * factor.from.x 15680 }; 15681 child.to = { 15682 height: c_original.height * factor.to.y, 15683 width: c_original.width * factor.to.x, 15684 outerHeight: c_original.height * factor.to.y, 15685 outerWidth: c_original.width * factor.to.x 15686 }; 15687 15688 /*// Vertical props scaling 15689*/ 15690 if ( factor.from.y !== factor.to.y ) { 15691 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 15692 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 15693 } 15694 15695 /*// Horizontal props scaling 15696*/ 15697 if ( factor.from.x !== factor.to.x ) { 15698 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 15699 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 15700 } 15701 15702 /*// Animate children 15703*/ 15704 child.css( child.from ); 15705 child.animate( child.to, o.duration, o.easing, function() { 15706 15707 /*// Restore children 15708*/ 15709 if ( restore ) { 15710 $.effects.restore( child, props2 ); 15711 } 15712 }); 15713 }); 15714 } 15715 15716 /*// Animate 15717*/ 15718 el.animate( el.to, { 15719 queue: false, 15720 duration: o.duration, 15721 easing: o.easing, 15722 complete: function() { 15723 if ( el.to.opacity === 0 ) { 15724 el.css( "opacity", el.from.opacity ); 15725 } 15726 if( mode === "hide" ) { 15727 el.hide(); 15728 } 15729 $.effects.restore( el, props ); 15730 if ( !restore ) { 15731 15732 /*// we need to calculate our new positioning based on the scaling 15733*/ 15734 if ( position === "static" ) { 15735 el.css({ 15736 position: "relative", 15737 top: el.to.top, 15738 left: el.to.left 15739 }); 15740 } else { 15741 $.each([ "top", "left" ], function( idx, pos ) { 15742 el.css( pos, function( _, str ) { 15743 var val = parseInt( str, 10 ), 15744 toRef = idx ? el.to.left : el.to.top; 15745 15746 /*// if original was "auto", recalculate the new value from wrapper 15747*/ 15748 if ( str === "auto" ) { 15749 return toRef + "px"; 15750 } 15751 15752 return val + toRef + "px"; 15753 }); 15754 }); 15755 } 15756 } 15757 15758 $.effects.removeWrapper( el ); 15759 done(); 15760 } 15761 }); 15762 15763}; 15764 15765})(jQuery); 15766(function( $, undefined ) { 15767 15768$.effects.effect.shake = function( o, done ) { 15769 15770 var el = $( this ), 15771 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 15772 mode = $.effects.setMode( el, o.mode || "effect" ), 15773 direction = o.direction || "left", 15774 distance = o.distance || 20, 15775 times = o.times || 3, 15776 anims = times * 2 + 1, 15777 speed = Math.round(o.duration/anims), 15778 ref = (direction === "up" || direction === "down") ? "top" : "left", 15779 positiveMotion = (direction === "up" || direction === "left"), 15780 animation = {}, 15781 animation1 = {}, 15782 animation2 = {}, 15783 i, 15784 15785 /*// we will need to re-assemble the queue to stack our animations in place 15786*/ 15787 queue = el.queue(), 15788 queuelen = queue.length; 15789 15790 $.effects.save( el, props ); 15791 el.show(); 15792 $.effects.createWrapper( el ); 15793 15794 /*// Animation 15795*/ 15796 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 15797 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 15798 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 15799 15800 /*// Animate 15801*/ 15802 el.animate( animation, speed, o.easing ); 15803 15804 /*// Shakes 15805*/ 15806 for ( i = 1; i < times; i++ ) { 15807 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 15808 } 15809 el 15810 .animate( animation1, speed, o.easing ) 15811 .animate( animation, speed / 2, o.easing ) 15812 .queue(function() { 15813 if ( mode === "hide" ) { 15814 el.hide(); 15815 } 15816 $.effects.restore( el, props ); 15817 $.effects.removeWrapper( el ); 15818 done(); 15819 }); 15820 15821 /*// inject all the animations we just queued to be first in line (after "inprogress") 15822*/ 15823 if ( queuelen > 1) { 15824 queue.splice.apply( queue, 15825 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 15826 } 15827 el.dequeue(); 15828 15829}; 15830 15831})(jQuery); 15832(function( $, undefined ) { 15833 15834$.effects.effect.slide = function( o, done ) { 15835 15836 /*// Create element 15837*/ 15838 var el = $( this ), 15839 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 15840 mode = $.effects.setMode( el, o.mode || "show" ), 15841 show = mode === "show", 15842 direction = o.direction || "left", 15843 ref = (direction === "up" || direction === "down") ? "top" : "left", 15844 positiveMotion = (direction === "up" || direction === "left"), 15845 distance, 15846 animation = {}; 15847 15848 /*// Adjust 15849*/ 15850 $.effects.save( el, props ); 15851 el.show(); 15852 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 15853 15854 $.effects.createWrapper( el ).css({ 15855 overflow: "hidden" 15856 }); 15857 15858 if ( show ) { 15859 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 15860 } 15861 15862 /*// Animation 15863*/ 15864 animation[ ref ] = ( show ? 15865 ( positiveMotion ? "+=" : "-=") : 15866 ( positiveMotion ? "-=" : "+=")) + 15867 distance; 15868 15869 /*// Animate 15870*/ 15871 el.animate( animation, { 15872 queue: false, 15873 duration: o.duration, 15874 easing: o.easing, 15875 complete: function() { 15876 if ( mode === "hide" ) { 15877 el.hide(); 15878 } 15879 $.effects.restore( el, props ); 15880 $.effects.removeWrapper( el ); 15881 done(); 15882 } 15883 }); 15884}; 15885 15886})(jQuery); 15887(function( $, undefined ) { 15888 15889$.effects.effect.transfer = function( o, done ) { 15890 var elem = $( this ), 15891 target = $( o.to ), 15892 targetFixed = target.css( "position" ) === "fixed", 15893 body = $("body"), 15894 fixTop = targetFixed ? body.scrollTop() : 0, 15895 fixLeft = targetFixed ? body.scrollLeft() : 0, 15896 endPosition = target.offset(), 15897 animation = { 15898 top: endPosition.top - fixTop , 15899 left: endPosition.left - fixLeft , 15900 height: target.innerHeight(), 15901 width: target.innerWidth() 15902 }, 15903 startPosition = elem.offset(), 15904 transfer = $( "<div class='ui-effects-transfer'></div>" ) 15905 .appendTo( document.body ) 15906 .addClass( o.className ) 15907 .css({ 15908 top: startPosition.top - fixTop , 15909 left: startPosition.left - fixLeft ,
15910 height: elem.innerHeight(), 15911 width: elem.innerWidth(), 15912 position: targetFixed ? "fixed" : "absolute" 15913 }) 15914 .animate( animation, o.duration, o.easing, function() { 15915 transfer.remove(); 15916 done(); 15917 }); 15918}; 15919 15920})(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.