1/*! jQuery UI - v1.10.2 - 2013-03-14 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 4* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ 5(function( $, undefined ) { 6 7 var uuid = 0, 8 runiqueId = /^ui-id-\d+$/; 9 10// $.ui might exist from components with no dependencies, e.g., $.ui.position 11 $.ui = $.ui || {}; 12 13 $.extend( $.ui, { 14 version: "1.10.2", 15 16 keyCode: { 17 BACKSPACE: 8, 18 COMMA: 188, 19 DELETE: 46, 20 DOWN: 40, 21 END: 35, 22 ENTER: 13, 23 ESCAPE: 27, 24 HOME: 36, 25 LEFT: 37, 26 NUMPAD_ADD: 107, 27 NUMPAD_DECIMAL: 110, 28 NUMPAD_DIVIDE: 111, 29 NUMPAD_ENTER: 108, 30 NUMPAD_MULTIPLY: 106, 31 NUMPAD_SUBTRACT: 109, 32 PAGE_DOWN: 34, 33 PAGE_UP: 33, 34 PERIOD: 190, 35 RIGHT: 39, 36 SPACE: 32, 37 TAB: 9, 38 UP: 38 39 } 40 }); 41 42// plugins 43 $.fn.extend({ 44 focus: (function( orig ) { 45 return function( delay, fn ) { 46 return typeof delay === "number" ? 47 this.each(function() { 48 var elem = this; 49 setTimeout(function() { 50 $( elem ).focus(); 51 if ( fn ) { 52 fn.call( elem ); 53 } 54 }, delay ); 55 }) : 56 orig.apply( this, arguments ); 57 }; 58 })( $.fn.focus ), 59 60 scrollParent: function() { 61 var scrollParent; 62 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 63 scrollParent = this.parents().filter(function() { 64 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 65 }).eq(0); 66 } else { 67 scrollParent = this.parents().filter(function() { 68 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 69 }).eq(0); 70 } 71 72 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 73 }, 74 75 zIndex: function( zIndex ) { 76 if ( zIndex !== undefined ) { 77 return this.css( "zIndex", zIndex ); 78 } 79 80 if ( this.length ) { 81 var elem = $( this[ 0 ] ), position, value; 82 while ( elem.length && elem[ 0 ] !== document ) { 83 // Ignore z-index if position is set to a value where z-index is ignored by the browser 84 // This makes behavior of this function consistent across browsers 85 // WebKit always returns auto if the element is positioned 86 position = elem.css( "position" ); 87 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 88 // IE returns 0 when zIndex is not specified 89 // other browsers return a string 90 // we ignore the case of nested elements with an explicit value of 0 91 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 92 value = parseInt( elem.css( "zIndex" ), 10 ); 93 if ( !isNaN( value ) && value !== 0 ) { 94 return value; 95 } 96 } 97 elem = elem.parent(); 98 } 99 } 100 101 return 0; 102 }, 103 104 uniqueId: function() { 105 return this.each(function() { 106 if ( !this.id ) { 107 this.id = "ui-id-" + (++uuid); 108 } 109 }); 110 }, 111 112 removeUniqueId: function() { 113 return this.each(function() { 114 if ( runiqueId.test( this.id ) ) { 115 $( this ).removeAttr( "id" ); 116 } 117 }); 118 } 119 });
vendor: 45,935 bytes, lines 120-1319
120 121// selectors 122 function focusable( element, isTabIndexNotNaN ) { 123 var map, mapName, img, 124 nodeName = element.nodeName.toLowerCase(); 125 if ( "area" === nodeName ) { 126 map = element.parentNode; 127 mapName = map.name; 128 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 129 return false; 130 } 131 img = $( "img[usemap=#" + mapName + "]" )[0]; 132 return !!img && visible( img ); 133 } 134 return ( /input|select|textarea|button|object/.test( nodeName ) ? 135 !element.disabled : 136 "a" === nodeName ? 137 element.href || isTabIndexNotNaN : 138 isTabIndexNotNaN) && 139 // the element and all of its ancestors must be visible 140 visible( element ); 141 } 142 143 function visible( element ) { 144 return $.expr.filters.visible( element ) && 145 !$( element ).parents().addBack().filter(function() { 146 return $.css( this, "visibility" ) === "hidden"; 147 }).length; 148 } 149 150 $.extend( $.expr[ ":" ], { 151 data: $.expr.createPseudo ? 152 $.expr.createPseudo(function( dataName ) { 153 return function( elem ) { 154 return !!$.data( elem, dataName ); 155 }; 156 }) : 157 // support: jQuery <1.8 158 function( elem, i, match ) { 159 return !!$.data( elem, match[ 3 ] ); 160 }, 161 162 focusable: function( element ) { 163 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 164 }, 165 166 tabbable: function( element ) { 167 var tabIndex = $.attr( element, "tabindex" ), 168 isTabIndexNaN = isNaN( tabIndex ); 169 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 170 } 171 }); 172 173// support: jQuery <1.8 174 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 175 $.each( [ "Width", "Height" ], function( i, name ) { 176 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 177 type = name.toLowerCase(), 178 orig = { 179 innerWidth: $.fn.innerWidth, 180 innerHeight: $.fn.innerHeight, 181 outerWidth: $.fn.outerWidth, 182 outerHeight: $.fn.outerHeight 183 }; 184 185 function reduce( elem, size, border, margin ) { 186 $.each( side, function() { 187 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 188 if ( border ) { 189 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 190 } 191 if ( margin ) { 192 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 193 } 194 }); 195 return size; 196 } 197 198 $.fn[ "inner" + name ] = function( size ) { 199 if ( size === undefined ) { 200 return orig[ "inner" + name ].call( this ); 201 } 202 203 return this.each(function() { 204 $( this ).css( type, reduce( this, size ) + "px" ); 205 }); 206 }; 207 208 $.fn[ "outer" + name] = function( size, margin ) { 209 if ( typeof size !== "number" ) { 210 return orig[ "outer" + name ].call( this, size ); 211 } 212 213 return this.each(function() { 214 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 215 }); 216 }; 217 }); 218 } 219 220// support: jQuery <1.8 221 if ( !$.fn.addBack ) { 222 $.fn.addBack = function( selector ) { 223 return this.add( selector == null ? 224 this.prevObject : this.prevObject.filter( selector ) 225 ); 226 }; 227 } 228 229// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 230 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 231 $.fn.removeData = (function( removeData ) { 232 return function( key ) { 233 if ( arguments.length ) { 234 return removeData.call( this, $.camelCase( key ) ); 235 } else { 236 return removeData.call( this ); 237 } 238 }; 239 })( $.fn.removeData ); 240 } 241 242 243 244 245 246// deprecated 247 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 248 249 $.support.selectstart = "onselectstart" in document.createElement( "div" ); 250 $.fn.extend({ 251 disableSelection: function() { 252 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 253 ".ui-disableSelection", function( event ) { 254 event.preventDefault(); 255 }); 256 }, 257 258 enableSelection: function() { 259 return this.unbind( ".ui-disableSelection" ); 260 } 261 }); 262 263 $.extend( $.ui, { 264 // $.ui.plugin is deprecated. Use the proxy pattern instead. 265 plugin: { 266 add: function( module, option, set ) { 267 var i, 268 proto = $.ui[ module ].prototype; 269 for ( i in set ) { 270 proto.plugins[ i ] = proto.plugins[ i ] || []; 271 proto.plugins[ i ].push( [ option, set[ i ] ] ); 272 } 273 }, 274 call: function( instance, name, args ) { 275 var i, 276 set = instance.plugins[ name ]; 277 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 278 return; 279 } 280 281 for ( i = 0; i < set.length; i++ ) { 282 if ( instance.options[ set[ i ][ 0 ] ] ) { 283 set[ i ][ 1 ].apply( instance.element, args ); 284 } 285 } 286 } 287 }, 288 289 // only used by resizable 290 hasScroll: function( el, a ) { 291 292 //If overflow is hidden, the element might have extra content, but the user wants to hide it 293 if ( $( el ).css( "overflow" ) === "hidden") { 294 return false; 295 } 296 297 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 298 has = false; 299 300 if ( el[ scroll ] > 0 ) { 301 return true; 302 } 303 304 // TODO: determine which cases actually cause this to happen 305 // if the element doesn't have the scroll set, see if it's possible to 306 // set the scroll 307 el[ scroll ] = 1; 308 has = ( el[ scroll ] > 0 ); 309 el[ scroll ] = 0; 310 return has; 311 } 312 }); 313 314})( jQuery ); 315 316(function( $, undefined ) { 317 318 var uuid = 0, 319 slice = Array.prototype.slice, 320 _cleanData = $.cleanData; 321 $.cleanData = function( elems ) { 322 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 323 try { 324 $( elem ).triggerHandler( "remove" ); 325 // http://bugs.jquery.com/ticket/8235 326 } catch( e ) {} 327 } 328 _cleanData( elems ); 329 }; 330 331 $.widget = function( name, base, prototype ) { 332 var fullName, existingConstructor, constructor, basePrototype, 333 // proxiedPrototype allows the provided prototype to remain unmodified 334 // so that it can be used as a mixin for multiple widgets (#8876) 335 proxiedPrototype = {}, 336 namespace = name.split( "." )[ 0 ]; 337 338 name = name.split( "." )[ 1 ]; 339 fullName = namespace + "-" + name; 340 341 if ( !prototype ) { 342 prototype = base; 343 base = $.Widget; 344 } 345 346 // create selector for plugin 347 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 348 return !!$.data( elem, fullName ); 349 }; 350 351 $[ namespace ] = $[ namespace ] || {}; 352 existingConstructor = $[ namespace ][ name ]; 353 constructor = $[ namespace ][ name ] = function( options, element ) { 354 // allow instantiation without "new" keyword 355 if ( !this._createWidget ) { 356 return new constructor( options, element ); 357 } 358 359 // allow instantiation without initializing for simple inheritance 360 // must use "new" keyword (the code above always passes args) 361 if ( arguments.length ) { 362 this._createWidget( options, element ); 363 } 364 }; 365 // extend with the existing constructor to carry over any static properties 366 $.extend( constructor, existingConstructor, { 367 version: prototype.version, 368 // copy the object used to create the prototype in case we need to 369 // redefine the widget later 370 _proto: $.extend( {}, prototype ), 371 // track widgets that inherit from this widget in case this widget is 372 // redefined after a widget inherits from it 373 _childConstructors: [] 374 }); 375 376 basePrototype = new base(); 377 // we need to make the options hash a property directly on the new instance 378 // otherwise we'll modify the options hash on the prototype that we're 379 // inheriting from 380 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 381 $.each( prototype, function( prop, value ) { 382 if ( !$.isFunction( value ) ) { 383 proxiedPrototype[ prop ] = value; 384 return; 385 } 386 proxiedPrototype[ prop ] = (function() { 387 var _super = function() { 388 return base.prototype[ prop ].apply( this, arguments ); 389 }, 390 _superApply = function( args ) { 391 return base.prototype[ prop ].apply( this, args ); 392 }; 393 return function() { 394 var __super = this._super, 395 __superApply = this._superApply, 396 returnValue; 397 398 this._super = _super; 399 this._superApply = _superApply; 400 401 returnValue = value.apply( this, arguments ); 402 403 this._super = __super; 404 this._superApply = __superApply; 405 406 return returnValue; 407 }; 408 })(); 409 }); 410 constructor.prototype = $.widget.extend( basePrototype, { 411 // TODO: remove support for widgetEventPrefix 412 // always use the name + a colon as the prefix, e.g., draggable:start 413 // don't prefix for widgets that aren't DOM-based 414 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 415 }, proxiedPrototype, { 416 constructor: constructor, 417 namespace: namespace, 418 widgetName: name, 419 widgetFullName: fullName 420 }); 421 422 // If this widget is being redefined then we need to find all widgets that 423 // are inheriting from it and redefine all of them so that they inherit from 424 // the new version of this widget. We're essentially trying to replace one 425 // level in the prototype chain. 426 if ( existingConstructor ) { 427 $.each( existingConstructor._childConstructors, function( i, child ) { 428 var childPrototype = child.prototype; 429 430 // redefine the child widget using the same prototype that was 431 // originally used, but inherit from the new version of the base 432 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 433 }); 434 // remove the list of existing child constructors from the old constructor 435 // so the old child constructors can be garbage collected 436 delete existingConstructor._childConstructors; 437 } else { 438 base._childConstructors.push( constructor ); 439 } 440 441 $.widget.bridge( name, constructor ); 442 }; 443 444 $.widget.extend = function( target ) { 445 var input = slice.call( arguments, 1 ), 446 inputIndex = 0, 447 inputLength = input.length, 448 key, 449 value; 450 for ( ; inputIndex < inputLength; inputIndex++ ) { 451 for ( key in input[ inputIndex ] ) { 452 value = input[ inputIndex ][ key ]; 453 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 454 // Clone objects 455 if ( $.isPlainObject( value ) ) { 456 target[ key ] = $.isPlainObject( target[ key ] ) ? 457 $.widget.extend( {}, target[ key ], value ) : 458 // Don't extend strings, arrays, etc. with objects 459 $.widget.extend( {}, value ); 460 // Copy everything else by reference 461 } else { 462 target[ key ] = value; 463 } 464 } 465 } 466 } 467 return target; 468 }; 469 470 $.widget.bridge = function( name, object ) { 471 var fullName = object.prototype.widgetFullName || name; 472 $.fn[ name ] = function( options ) { 473 var isMethodCall = typeof options === "string", 474 args = slice.call( arguments, 1 ), 475 returnValue = this; 476 477 // allow multiple hashes to be passed on init 478 options = !isMethodCall && args.length ? 479 $.widget.extend.apply( null, [ options ].concat(args) ) : 480 options; 481 482 if ( isMethodCall ) { 483 this.each(function() { 484 var methodValue, 485 instance = $.data( this, fullName ); 486 if ( !instance ) { 487 return $.error( "cannot call methods on " + name + " prior to initialization; " + 488 "attempted to call method '" + options + "'" ); 489 } 490 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 491 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 492 } 493 methodValue = instance[ options ].apply( instance, args ); 494 if ( methodValue !== instance && methodValue !== undefined ) { 495 returnValue = methodValue && methodValue.jquery ? 496 returnValue.pushStack( methodValue.get() ) : 497 methodValue; 498 return false; 499 } 500 }); 501 } else { 502 this.each(function() { 503 var instance = $.data( this, fullName ); 504 if ( instance ) { 505 instance.option( options || {} )._init(); 506 } else { 507 $.data( this, fullName, new object( options, this ) ); 508 } 509 }); 510 } 511 512 return returnValue; 513 }; 514 }; 515 516 $.Widget = function( /* options, element */ ) {}; 517 $.Widget._childConstructors = []; 518 519 $.Widget.prototype = { 520 widgetName: "widget", 521 widgetEventPrefix: "", 522 defaultElement: "<div>", 523 options: { 524 disabled: false, 525 526 // callbacks 527 create: null 528 }, 529 _createWidget: function( options, element ) { 530 element = $( element || this.defaultElement || this )[ 0 ]; 531 this.element = $( element ); 532 this.uuid = uuid++; 533 this.eventNamespace = "." + this.widgetName + this.uuid; 534 this.options = $.widget.extend( {}, 535 this.options, 536 this._getCreateOptions(), 537 options ); 538 539 this.bindings = $(); 540 this.hoverable = $(); 541 this.focusable = $(); 542 543 if ( element !== this ) { 544 $.data( element, this.widgetFullName, this ); 545 this._on( true, this.element, { 546 remove: function( event ) { 547 if ( event.target === element ) { 548 this.destroy(); 549 } 550 } 551 }); 552 this.document = $( element.style ? 553 // element within the document 554 element.ownerDocument : 555 // element is window or document 556 element.document || element ); 557 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 558 } 559 560 this._create(); 561 this._trigger( "create", null, this._getCreateEventData() ); 562 this._init(); 563 }, 564 _getCreateOptions: $.noop, 565 _getCreateEventData: $.noop, 566 _create: $.noop, 567 _init: $.noop, 568 569 destroy: function() { 570 this._destroy(); 571 // we can probably remove the unbind calls in 2.0 572 // all event bindings should go through this._on() 573 this.element 574 .unbind( this.eventNamespace ) 575 // 1.9 BC for #7810 576 // TODO remove dual storage 577 .removeData( this.widgetName ) 578 .removeData( this.widgetFullName ) 579 // support: jquery <1.6.3 580 // http://bugs.jquery.com/ticket/9413 581 .removeData( $.camelCase( this.widgetFullName ) ); 582 this.widget() 583 .unbind( this.eventNamespace ) 584 .removeAttr( "aria-disabled" ) 585 .removeClass( 586 this.widgetFullName + "-disabled " + 587 "ui-state-disabled" ); 588 589 // clean up events and states 590 this.bindings.unbind( this.eventNamespace ); 591 this.hoverable.removeClass( "ui-state-hover" ); 592 this.focusable.removeClass( "ui-state-focus" ); 593 }, 594 _destroy: $.noop, 595 596 widget: function() { 597 return this.element; 598 }, 599 600 option: function( key, value ) { 601 var options = key, 602 parts, 603 curOption, 604 i; 605 606 if ( arguments.length === 0 ) { 607 // don't return a reference to the internal hash 608 return $.widget.extend( {}, this.options ); 609 } 610 611 if ( typeof key === "string" ) { 612 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 613 options = {}; 614 parts = key.split( "." ); 615 key = parts.shift(); 616 if ( parts.length ) { 617 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 618 for ( i = 0; i < parts.length - 1; i++ ) { 619 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 620 curOption = curOption[ parts[ i ] ]; 621 } 622 key = parts.pop(); 623 if ( value === undefined ) { 624 return curOption[ key ] === undefined ? null : curOption[ key ]; 625 } 626 curOption[ key ] = value; 627 } else { 628 if ( value === undefined ) { 629 return this.options[ key ] === undefined ? null : this.options[ key ]; 630 } 631 options[ key ] = value; 632 } 633 } 634 635 this._setOptions( options ); 636 637 return this; 638 }, 639 _setOptions: function( options ) { 640 var key; 641 642 for ( key in options ) { 643 this._setOption( key, options[ key ] ); 644 } 645 646 return this; 647 }, 648 _setOption: function( key, value ) { 649 this.options[ key ] = value; 650 651 if ( key === "disabled" ) { 652 this.widget() 653 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 654 .attr( "aria-disabled", value ); 655 this.hoverable.removeClass( "ui-state-hover" ); 656 this.focusable.removeClass( "ui-state-focus" ); 657 } 658 659 return this; 660 }, 661 662 enable: function() { 663 return this._setOption( "disabled", false ); 664 }, 665 disable: function() { 666 return this._setOption( "disabled", true ); 667 }, 668 669 _on: function( suppressDisabledCheck, element, handlers ) { 670 var delegateElement, 671 instance = this; 672 673 // no suppressDisabledCheck flag, shuffle arguments 674 if ( typeof suppressDisabledCheck !== "boolean" ) { 675 handlers = element; 676 element = suppressDisabledCheck; 677 suppressDisabledCheck = false; 678 } 679 680 // no element argument, shuffle and use this.element 681 if ( !handlers ) { 682 handlers = element; 683 element = this.element; 684 delegateElement = this.widget(); 685 } else { 686 // accept selectors, DOM elements 687 element = delegateElement = $( element ); 688 this.bindings = this.bindings.add( element ); 689 } 690 691 $.each( handlers, function( event, handler ) { 692 function handlerProxy() { 693 // allow widgets to customize the disabled handling 694 // - disabled as an array instead of boolean 695 // - disabled class as method for disabling individual parts 696 if ( !suppressDisabledCheck && 697 ( instance.options.disabled === true || 698 $( this ).hasClass( "ui-state-disabled" ) ) ) { 699 return; 700 } 701 return ( typeof handler === "string" ? instance[ handler ] : handler ) 702 .apply( instance, arguments ); 703 } 704 705 // copy the guid so direct unbinding works 706 if ( typeof handler !== "string" ) { 707 handlerProxy.guid = handler.guid = 708 handler.guid || handlerProxy.guid || $.guid++; 709 } 710 711 var match = event.match( /^(\w+)\s*(.*)$/ ), 712 eventName = match[1] + instance.eventNamespace, 713 selector = match[2]; 714 if ( selector ) { 715 delegateElement.delegate( selector, eventName, handlerProxy ); 716 } else { 717 element.bind( eventName, handlerProxy ); 718 } 719 }); 720 }, 721 722 _off: function( element, eventName ) { 723 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 724 element.unbind( eventName ).undelegate( eventName ); 725 }, 726 727 _delay: function( handler, delay ) { 728 function handlerProxy() { 729 return ( typeof handler === "string" ? instance[ handler ] : handler ) 730 .apply( instance, arguments ); 731 } 732 var instance = this; 733 return setTimeout( handlerProxy, delay || 0 ); 734 }, 735 736 _hoverable: function( element ) { 737 this.hoverable = this.hoverable.add( element ); 738 this._on( element, { 739 mouseenter: function( event ) { 740 $( event.currentTarget ).addClass( "ui-state-hover" ); 741 }, 742 mouseleave: function( event ) { 743 $( event.currentTarget ).removeClass( "ui-state-hover" ); 744 } 745 }); 746 }, 747 748 _focusable: function( element ) { 749 this.focusable = this.focusable.add( element ); 750 this._on( element, { 751 focusin: function( event ) { 752 $( event.currentTarget ).addClass( "ui-state-focus" ); 753 }, 754 focusout: function( event ) { 755 $( event.currentTarget ).removeClass( "ui-state-focus" ); 756 } 757 }); 758 }, 759 760 _trigger: function( type, event, data ) { 761 var prop, orig, 762 callback = this.options[ type ]; 763 764 data = data || {}; 765 event = $.Event( event ); 766 event.type = ( type === this.widgetEventPrefix ? 767 type : 768 this.widgetEventPrefix + type ).toLowerCase(); 769 // the original event may come from any element 770 // so we need to reset the target on the new event 771 event.target = this.element[ 0 ]; 772 773 // copy original event properties over to the new event 774 orig = event.originalEvent; 775 if ( orig ) { 776 for ( prop in orig ) { 777 if ( !( prop in event ) ) { 778 event[ prop ] = orig[ prop ]; 779 } 780 } 781 } 782 783 this.element.trigger( event, data ); 784 return !( $.isFunction( callback ) && 785 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 786 event.isDefaultPrevented() ); 787 } 788 }; 789 790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 791 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 792 if ( typeof options === "string" ) { 793 options = { effect: options }; 794 } 795 var hasOptions, 796 effectName = !options ? 797 method : 798 options === true || typeof options === "number" ? 799 defaultEffect : 800 options.effect || defaultEffect; 801 options = options || {}; 802 if ( typeof options === "number" ) { 803 options = { duration: options }; 804 } 805 hasOptions = !$.isEmptyObject( options ); 806 options.complete = callback; 807 if ( options.delay ) { 808 element.delay( options.delay ); 809 } 810 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 811 element[ method ]( options ); 812 } else if ( effectName !== method && element[ effectName ] ) { 813 element[ effectName ]( options.duration, options.easing, callback ); 814 } else { 815 element.queue(function( next ) { 816 $( this )[ method ](); 817 if ( callback ) { 818 callback.call( element[ 0 ] ); 819 } 820 next(); 821 }); 822 } 823 }; 824 }); 825 826})( jQuery ); 827 828(function( $, undefined ) { 829 830 var mouseHandled = false; 831 $( document ).mouseup( function() { 832 mouseHandled = false; 833 }); 834 835 $.widget("ui.mouse", { 836 version: "1.10.2", 837 options: { 838 cancel: "input,textarea,button,select,option", 839 distance: 1, 840 delay: 0 841 }, 842 _mouseInit: function() { 843 var that = this; 844 845 this.element 846 .bind("mousedown."+this.widgetName, function(event) { 847 return that._mouseDown(event); 848 }) 849 .bind("click."+this.widgetName, function(event) { 850 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 851 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 852 event.stopImmediatePropagation(); 853 return false; 854 } 855 }); 856 857 this.started = false; 858 }, 859 860 // TODO: make sure destroying one instance of mouse doesn't mess with 861 // other instances of mouse 862 _mouseDestroy: function() { 863 this.element.unbind("."+this.widgetName); 864 if ( this._mouseMoveDelegate ) { 865 $(document) 866 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 867 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 868 } 869 }, 870 871 _mouseDown: function(event) { 872 // don't let more than one widget handle mouseStart 873 if( mouseHandled ) { return; } 874 875 // we may have missed mouseup (out of window) 876 (this._mouseStarted && this._mouseUp(event)); 877 878 this._mouseDownEvent = event; 879 880 var that = this, 881 btnIsLeft = (event.which === 1), 882 // event.target.nodeName works around a bug in IE 8 with 883 // disabled inputs (#7620) 884 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 885 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 886 return true; 887 } 888 889 this.mouseDelayMet = !this.options.delay; 890 if (!this.mouseDelayMet) { 891 this._mouseDelayTimer = setTimeout(function() { 892 that.mouseDelayMet = true; 893 }, this.options.delay); 894 } 895 896 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 897 this._mouseStarted = (this._mouseStart(event) !== false); 898 if (!this._mouseStarted) { 899 event.preventDefault(); 900 return true; 901 } 902 } 903 904 // Click event may never have fired (Gecko & Opera) 905 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 906 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 907 } 908 909 // these delegates are required to keep context 910 this._mouseMoveDelegate = function(event) { 911 return that._mouseMove(event); 912 }; 913 this._mouseUpDelegate = function(event) { 914 return that._mouseUp(event); 915 }; 916 $(document) 917 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 918 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 919 920 event.preventDefault(); 921 922 mouseHandled = true; 923 return true; 924 }, 925 926 _mouseMove: function(event) { 927 // IE mouseup check - mouseup happened when mouse was out of window 928 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 929 return this._mouseUp(event); 930 } 931 932 if (this._mouseStarted) { 933 this._mouseDrag(event); 934 return event.preventDefault(); 935 } 936 937 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 938 this._mouseStarted = 939 (this._mouseStart(this._mouseDownEvent, event) !== false); 940 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 941 } 942 943 return !this._mouseStarted; 944 }, 945 946 _mouseUp: function(event) { 947 $(document) 948 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 949 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 950 951 if (this._mouseStarted) { 952 this._mouseStarted = false; 953 954 if (event.target === this._mouseDownEvent.target) { 955 $.data(event.target, this.widgetName + ".preventClickEvent", true); 956 } 957 958 this._mouseStop(event); 959 } 960 961 return false; 962 }, 963 964 _mouseDistanceMet: function(event) { 965 return (Math.max( 966 Math.abs(this._mouseDownEvent.pageX - event.pageX), 967 Math.abs(this._mouseDownEvent.pageY - event.pageY) 968 ) >= this.options.distance 969 ); 970 }, 971 972 _mouseDelayMet: function(/* event */) { 973 return this.mouseDelayMet; 974 }, 975 976 // These are placeholder methods, to be overriden by extending plugin 977 _mouseStart: function(/* event */) {}, 978 _mouseDrag: function(/* event */) {}, 979 _mouseStop: function(/* event */) {}, 980 _mouseCapture: function(/* event */) { return true; } 981 }); 982 983})(jQuery); 984 985(function( $, undefined ) { 986 987 $.widget("ui.draggable", $.ui.mouse, { 988 version: "1.10.2", 989 widgetEventPrefix: "drag", 990 options: { 991 addClasses: true, 992 appendTo: "parent", 993 axis: false, 994 connectToSortable: false, 995 containment: false, 996 cursor: "auto", 997 cursorAt: false, 998 grid: false, 999 handle: false, 1000 helper: "original", 1001 iframeFix: false, 1002 opacity: false, 1003 refreshPositions: false, 1004 revert: false, 1005 revertDuration: 500, 1006 scope: "default", 1007 scroll: true, 1008 scrollSensitivity: 20, 1009 scrollSpeed: 20, 1010 snap: false, 1011 snapMode: "both", 1012 snapTolerance: 20, 1013 stack: false, 1014 zIndex: false, 1015 1016 // callbacks 1017 drag: null, 1018 start: null, 1019 stop: null 1020 }, 1021 _create: function() { 1022 1023 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 1024 this.element[0].style.position = "relative"; 1025 } 1026 if (this.options.addClasses){ 1027 this.element.addClass("ui-draggable"); 1028 } 1029 if (this.options.disabled){ 1030 this.element.addClass("ui-draggable-disabled"); 1031 } 1032 1033 this._mouseInit(); 1034 1035 }, 1036 1037 _destroy: function() { 1038 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 1039 this._mouseDestroy(); 1040 }, 1041 1042 _mouseCapture: function(event) { 1043 1044 var o = this.options; 1045 1046 // among others, prevent a drag on a resizable-handle 1047 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 1048 return false; 1049 } 1050 1051 //Quit if we're not on a valid handle 1052 this.handle = this._getHandle(event); 1053 if (!this.handle) { 1054 return false; 1055 } 1056 1057 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 1058 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 1059 .css({ 1060 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 1061 position: "absolute", opacity: "0.001", zIndex: 1000 1062 }) 1063 .css($(this).offset()) 1064 .appendTo("body"); 1065 }); 1066 1067 return true; 1068 1069 }, 1070 1071 _mouseStart: function(event) { 1072 1073 var o = this.options; 1074 1075 //Create and append the visible helper 1076 this.helper = this._createHelper(event); 1077 1078 this.helper.addClass("ui-draggable-dragging"); 1079 1080 //Cache the helper size 1081 this._cacheHelperProportions(); 1082 1083 //If ddmanager is used for droppables, set the global draggable 1084 if($.ui.ddmanager) { 1085 $.ui.ddmanager.current = this; 1086 } 1087 1088 /* 1089 * - Position generation - 1090 * This block generates everything position related - it's the core of draggables. 1091 */ 1092 1093 //Cache the margins of the original element 1094 this._cacheMargins(); 1095 1096 //Store the helper's css position 1097 this.cssPosition = this.helper.css("position"); 1098 this.scrollParent = this.helper.scrollParent(); 1099 1100 //The element's absolute position on the page minus margins 1101 this.offset = this.positionAbs = this.element.offset(); 1102 this.offset = { 1103 top: this.offset.top - this.margins.top, 1104 left: this.offset.left - this.margins.left 1105 }; 1106 1107 $.extend(this.offset, { 1108 click: { //Where the click happened, relative to the element 1109 left: event.pageX - this.offset.left, 1110 top: event.pageY - this.offset.top 1111 }, 1112 parent: this._getParentOffset(), 1113 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 1114 }); 1115 1116 //Generate the original position 1117 this.originalPosition = this.position = this._generatePosition(event); 1118 this.originalPageX = event.pageX; 1119 this.originalPageY = event.pageY; 1120 1121 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 1122 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 1123 1124 //Set a containment if given in the options 1125 if(o.containment) { 1126 this._setContainment(); 1127 } 1128 1129 //Trigger event + callbacks 1130 if(this._trigger("start", event) === false) { 1131 this._clear(); 1132 return false; 1133 } 1134 1135 //Recache the helper size 1136 this._cacheHelperProportions(); 1137 1138 //Prepare the droppable offsets 1139 if ($.ui.ddmanager && !o.dropBehaviour) { 1140 $.ui.ddmanager.prepareOffsets(this, event); 1141 } 1142 1143 1144 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 1145 1146 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 1147 if ( $.ui.ddmanager ) { 1148 $.ui.ddmanager.dragStart(this, event); 1149 } 1150 1151 return true; 1152 }, 1153 1154 _mouseDrag: function(event, noPropagation) { 1155 1156 //Compute the helpers position 1157 this.position = this._generatePosition(event); 1158 this.positionAbs = this._convertPositionTo("absolute"); 1159 1160 //Call plugins and callbacks and use the resulting position if something is returned 1161 if (!noPropagation) { 1162 var ui = this._uiHash(); 1163 if(this._trigger("drag", event, ui) === false) { 1164 this._mouseUp({}); 1165 return false; 1166 } 1167 this.position = ui.position; 1168 } 1169 1170 if(!this.options.axis || this.options.axis !== "y") { 1171 this.helper[0].style.left = this.position.left+"px"; 1172 } 1173 if(!this.options.axis || this.options.axis !== "x") { 1174 this.helper[0].style.top = this.position.top+"px"; 1175 } 1176 if($.ui.ddmanager) { 1177 $.ui.ddmanager.drag(this, event); 1178 } 1179 1180 return false; 1181 }, 1182 1183 _mouseStop: function(event) { 1184 1185 //If we are using droppables, inform the manager about the drop 1186 var element, 1187 that = this, 1188 elementInDom = false, 1189 dropped = false; 1190 if ($.ui.ddmanager && !this.options.dropBehaviour) { 1191 dropped = $.ui.ddmanager.drop(this, event); 1192 } 1193 1194 //if a drop comes from outside (a sortable) 1195 if(this.dropped) { 1196 dropped = this.dropped; 1197 this.dropped = false; 1198 } 1199 1200 //if the original element is no longer in the DOM don't bother to continue (see #8269) 1201 element = this.element[0]; 1202 while ( element && (element = element.parentNode) ) { 1203 if (element === document ) { 1204 elementInDom = true; 1205 } 1206 } 1207 if ( !elementInDom && this.options.helper === "original" ) { 1208 return false; 1209 } 1210 1211 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))) { 1212 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 1213 if(that._trigger("stop", event) !== false) { 1214 that._clear(); 1215 } 1216 }); 1217 } else { 1218 if(this._trigger("stop", event) !== false) { 1219 this._clear(); 1220 } 1221 } 1222 1223 return false; 1224 }, 1225 1226 _mouseUp: function(event) { 1227 //Remove frame helpers 1228 $("div.ui-draggable-iframeFix").each(function() { 1229 this.parentNode.removeChild(this); 1230 }); 1231 1232 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 1233 if( $.ui.ddmanager ) { 1234 $.ui.ddmanager.dragStop(this, event); 1235 } 1236 1237 return $.ui.mouse.prototype._mouseUp.call(this, event); 1238 }, 1239 1240 cancel: function() { 1241 1242 if(this.helper.is(".ui-draggable-dragging")) { 1243 this._mouseUp({}); 1244 } else { 1245 this._clear(); 1246 } 1247 1248 return this; 1249 1250 }, 1251 1252 _getHandle: function(event) { 1253 return this.options.handle ? 1254 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 1255 true; 1256 }, 1257 1258 _createHelper: function(event) { 1259 1260 var o = this.options, 1261 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 1262 1263 if(!helper.parents("body").length) { 1264 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 1265 } 1266 1267 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 1268 helper.css("position", "absolute"); 1269 } 1270 1271 return helper; 1272 1273 }, 1274 1275 _adjustOffsetFromHelper: function(obj) { 1276 if (typeof obj === "string") { 1277 obj = obj.split(" "); 1278 } 1279 if ($.isArray(obj)) { 1280 obj = {left: +obj[0], top: +obj[1] || 0}; 1281 } 1282 if ("left" in obj) { 1283 this.offset.click.left = obj.left + this.margins.left; 1284 } 1285 if ("right" in obj) { 1286 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 1287 } 1288 if ("top" in obj) { 1289 this.offset.click.top = obj.top + this.margins.top; 1290 } 1291 if ("bottom" in obj) { 1292 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 1293 } 1294 }, 1295 1296 _getParentOffset: function() { 1297 1298 //Get the offsetParent and cache its position 1299 this.offsetParent = this.helper.offsetParent(); 1300 var po = this.offsetParent.offset(); 1301 1302 // This is a special case where we need to modify a offset calculated on start, since the following happened: 1303 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 1304 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 1305 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 1306 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 1307 po.left += this.scrollParent.scrollLeft(); 1308 po.top += this.scrollParent.scrollTop(); 1309 } 1310 1311 //This needs to be actually done for all browsers, since pageX/pageY includes this information 1312 //Ugly IE fix 1313 if((this.offsetParent[0] === document.body) || 1314 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 1315 po = { top: 0, left: 0 }; 1316 } 1317 1318 return { 1319 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
vendor: 10,610 bytes, lines 1319-1525
131910) || 0), 1320 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 1321 }; 1322 1323 }, 1324 1325 _getRelativeOffset: function() { 1326 1327 if(this.cssPosition === "relative") { 1328 var p = this.element.position(); 1329 return { 1330 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 1331 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 1332 }; 1333 } else { 1334 return { top: 0, left: 0 }; 1335 } 1336 1337 }, 1338 1339 _cacheMargins: function() { 1340 this.margins = { 1341 left: (parseInt(this.element.css("marginLeft"),10) || 0), 1342 top: (parseInt(this.element.css("marginTop"),10) || 0), 1343 right: (parseInt(this.element.css("marginRight"),10) || 0), 1344 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 1345 }; 1346 }, 1347 1348 _cacheHelperProportions: function() { 1349 this.helperProportions = { 1350 width: this.helper.outerWidth(), 1351 height: this.helper.outerHeight() 1352 }; 1353 }, 1354 1355 _setContainment: function() { 1356 1357 var over, c, ce, 1358 o = this.options; 1359 1360 if(o.containment === "parent") { 1361 o.containment = this.helper[0].parentNode; 1362 } 1363 if(o.containment === "document" || o.containment === "window") { 1364 this.containment = [ 1365 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 1366 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 1367 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 1368 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 1369 ]; 1370 } 1371 1372 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { 1373 c = $(o.containment); 1374 ce = c[0]; 1375 1376 if(!ce) { 1377 return; 1378 } 1379 1380 over = ($(ce).css("overflow") !== "hidden"); 1381 1382 this.containment = [ 1383 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), 1384 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 1385 (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, 1386 (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 1387 ]; 1388 this.relative_container = c; 1389 1390 } else if(o.containment.constructor === Array) { 1391 this.containment = o.containment; 1392 } 1393 1394 }, 1395 1396 _convertPositionTo: function(d, pos) { 1397 1398 if(!pos) { 1399 pos = this.position; 1400 } 1401 1402 var mod = d === "absolute" ? 1 : -1, 1403 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); 1404 1405 return { 1406 top: ( 1407 pos.top + // The absolute mouse position 1408 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1409 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 1410 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 1411 ), 1412 left: ( 1413 pos.left + // The absolute mouse position 1414 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 1415 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 1416 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 1417 ) 1418 }; 1419 1420 }, 1421 1422 _generatePosition: function(event) { 1423 1424 var containment, co, top, left, 1425 o = this.options, 1426 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 1427 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), 1428 pageX = event.pageX, 1429 pageY = event.pageY; 1430 1431 /* 1432 * - Position constraining - 1433 * Constrain the position to a mix of grid, containment. 1434 */ 1435 1436 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 1437 if(this.containment) { 1438 if (this.relative_container){ 1439 co = this.relative_container.offset(); 1440 containment = [ this.containment[0] + co.left, 1441 this.containment[1] + co.top, 1442 this.containment[2] + co.left, 1443 this.containment[3] + co.top ]; 1444 } 1445 else { 1446 containment = this.containment; 1447 } 1448 1449 if(event.pageX - this.offset.click.left < containment[0]) { 1450 pageX = containment[0] + this.offset.click.left; 1451 } 1452 if(event.pageY - this.offset.click.top < containment[1]) { 1453 pageY = containment[1] + this.offset.click.top; 1454 } 1455 if(event.pageX - this.offset.click.left > containment[2]) { 1456 pageX = containment[2] + this.offset.click.left; 1457 } 1458 if(event.pageY - this.offset.click.top > containment[3]) { 1459 pageY = containment[3] + this.offset.click.top; 1460 } 1461 } 1462 1463 if(o.grid) { 1464 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 1465 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 1466 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; 1467 1468 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 1469 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; 1470 } 1471 1472 } 1473 1474 return { 1475 top: ( 1476 pageY - // The absolute mouse position 1477 this.offset.click.top - // Click offset (relative to the element) 1478 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 1479 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 1480 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 1481 ), 1482 left: ( 1483 pageX - // The absolute mouse position 1484 this.offset.click.left - // Click offset (relative to the element) 1485 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 1486 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 1487 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 1488 ) 1489 }; 1490 1491 }, 1492 1493 _clear: function() { 1494 this.helper.removeClass("ui-draggable-dragging"); 1495 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 1496 this.helper.remove(); 1497 } 1498 this.helper = null; 1499 this.cancelHelperRemoval = false; 1500 }, 1501 1502 // From now on bulk stuff - mainly helpers 1503 1504 _trigger: function(type, event, ui) { 1505 ui = ui || this._uiHash(); 1506 $.ui.plugin.call(this, type, [event, ui]); 1507 //The absolute position has to be recalculated after plugins 1508 if(type === "drag") { 1509 this.positionAbs = this._convertPositionTo("absolute"); 1510 } 1511 return $.Widget.prototype._trigger.call(this, type, event, ui); 1512 }, 1513 1514 plugins: {}, 1515 1516 _uiHash: function() { 1517 return { 1518 helper: this.helper, 1519 position: this.position, 1520 originalPosition: this.originalPosition, 1521 offset: this.positionAbs 1522 }; 1523 } 1524 1525 });
1526 1527 $.ui.plugin.add("draggable", "connectToSortable", { 1528 start: function(event, ui) { 1529 1530 var inst = $(this).data("ui-draggable"), o = inst.options, 1531 uiSortable = $.extend({}, ui, { item: inst.element }); 1532 inst.sortables = []; 1533 $(o.connectToSortable).each(function() { 1534 var sortable = $.data(this, "ui-sortable"); 1535 if (sortable && !sortable.options.disabled) { 1536 inst.sortables.push({ 1537 instance: sortable, 1538 shouldRevert: sortable.options.revert 1539 }); 1540 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). 1541 sortable._trigger("activate", event, uiSortable); 1542 } 1543 }); 1544 1545 }, 1546 stop: function(event, ui) { 1547 1548 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 1549 var inst = $(this).data("ui-draggable"), 1550 uiSortable = $.extend({}, ui, { item: inst.element }); 1551 1552 $.each(inst.sortables, function() { 1553 if(this.instance.isOver) { 1554 1555 this.instance.isOver = 0; 1556 1557 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 1558 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 1559 1560 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 1561 if(this.shouldRevert) { 1562 this.instance.options.revert = this.shouldRevert; 1563 } 1564 1565 //Trigger the stop of the sortable 1566 this.instance._mouseStop(event); 1567 1568 this.instance.options.helper = this.instance.options._helper; 1569 1570 //If the helper has been the original item, restore properties in the sortable 1571 if(inst.options.helper === "original") { 1572 this.instance.currentItem.css({ top: "auto", left: "auto" }); 1573 } 1574 1575 } else { 1576 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 1577 this.instance._trigger("deactivate", event, uiSortable); 1578 } 1579 1580 }); 1581 1582 }, 1583 drag: function(event, ui) { 1584 1585 var inst = $(this).data("ui-draggable"), that = this; 1586 1587 $.each(inst.sortables, function() { 1588 1589 var innermostIntersecting = false, 1590 thisSortable = this; 1591 1592 //Copy over some variables to allow calling the sortable's native _intersectsWith 1593 this.instance.positionAbs = inst.positionAbs; 1594 this.instance.helperProportions = inst.helperProportions; 1595 this.instance.offset.click = inst.offset.click; 1596 1597 if(this.instance._intersectsWith(this.instance.containerCache)) { 1598 innermostIntersecting = true; 1599 $.each(inst.sortables, function () { 1600 this.instance.positionAbs = inst.positionAbs; 1601 this.instance.helperProportions = inst.helperProportions; 1602 this.instance.offset.click = inst.offset.click; 1603 if (this !== thisSortable && 1604 this.instance._intersectsWith(this.instance.containerCache) && 1605 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 1606 ) { 1607 innermostIntersecting = false; 1608 } 1609 return innermostIntersecting; 1610 }); 1611 } 1612 1613 1614 if(innermostIntersecting) { 1615 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 1616 if(!this.instance.isOver) { 1617 1618 this.instance.isOver = 1; 1619 //Now we fake the start of dragging for the sortable instance, 1620 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 1621 //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) 1622 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 1623 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 1624 this.instance.options.helper = function() { return ui.helper[0]; }; 1625 1626 event.target = this.instance.currentItem[0]; 1627 this.instance._mouseCapture(event, true); 1628 this.instance._mouseStart(event, true, true); 1629
1630 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 1631 this.instance.offset.click.top = inst.offset.click.top; 1632 this.instance.offset.click.left = inst.offset.click.left; 1633 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 1634 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 1635 1636 inst._trigger("toSortable", event); 1637 inst.dropped = this.instance.element; //draggable revert needs that 1638 //hack so receive/update callbacks work (mostly) 1639 inst.currentItem = inst.element; 1640 this.instance.fromOutside = inst; 1641 1642 } 1643 1644 //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 1645 if(this.instance.currentItem) { 1646 this.instance._mouseDrag(event); 1647 } 1648 1649 } else { 1650 1651 //If it doesn't intersect with the sortable, and it intersected before, 1652 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 1653 if(this.instance.isOver) { 1654 1655 this.instance.isOver = 0; 1656 this.instance.cancelHelperRemoval = true; 1657 1658 //Prevent reverting on this forced stop 1659 this.instance.options.revert = false; 1660 1661 // The out event needs to be triggered independently 1662 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 1663 1664 this.instance._mouseStop(event, true); 1665 this.instance.options.helper = this.instance.options._helper; 1666 1667 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 1668 this.instance.currentItem.remove(); 1669 if(this.instance.placeholder) { 1670 this.instance.placeholder.remove(); 1671 } 1672 1673 inst._trigger("fromSortable", event); 1674 inst.dropped = false; //draggable revert needs that 1675 } 1676 1677 } 1678 1679 }); 1680 1681 } 1682 }); 1683 1684 $.ui.plugin.add("draggable", "cursor", { 1685 start: function() { 1686 var t = $("body"), o = $(this).data("ui-draggable").options; 1687 if (t.css("cursor")) { 1688 o._cursor = t.css("cursor"); 1689 } 1690 t.css("cursor", o.cursor); 1691 }, 1692 stop: function() { 1693 var o = $(this).data("ui-draggable").options; 1694 if (o._cursor) { 1695 $("body").css("cursor", o._cursor); 1696 } 1697 } 1698 }); 1699 1700 $.ui.plugin.add("draggable", "opacity", { 1701 start: function(event, ui) { 1702 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1703 if(t.css("opacity")) { 1704 o._opacity = t.css("opacity"); 1705 } 1706 t.css("opacity", o.opacity); 1707 }, 1708 stop: function(event, ui) { 1709 var o = $(this).data("ui-draggable").options; 1710 if(o._opacity) { 1711 $(ui.helper).css("opacity", o._opacity); 1712 } 1713 } 1714 }); 1715 1716 $.ui.plugin.add("draggable", "scroll", { 1717 start: function() { 1718 var i = $(this).data("ui-draggable"); 1719 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1720 i.overflowOffset = i.scrollParent.offset(); 1721 } 1722 }, 1723 drag: function( event ) { 1724 1725 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 1726 1727 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 1728 1729 if(!o.axis || o.axis !== "x") { 1730 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 1731 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 1732 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 1733 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 1734 } 1735 } 1736 1737 if(!o.axis || o.axis !== "y") { 1738 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 1739 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 1740 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 1741 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 1742 } 1743 } 1744 1745 } else { 1746 1747 if(!o.axis || o.axis !== "x") { 1748 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 1749 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 1750 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 1751 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 1752 } 1753 } 1754 1755 if(!o.axis || o.axis !== "y") { 1756 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 1757 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 1758 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 1759 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 1760 } 1761 } 1762 1763 } 1764 1765 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 1766 $.ui.ddmanager.prepareOffsets(i, event); 1767 } 1768 1769 } 1770 });
vendor: 45,863 bytes, lines 1771-2935
1771 1772 $.ui.plugin.add("draggable", "snap", { 1773 start: function() { 1774 1775 var i = $(this).data("ui-draggable"), 1776 o = i.options; 1777 1778 i.snapElements = []; 1779 1780 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 1781 var $t = $(this), 1782 $o = $t.offset(); 1783 if(this !== i.element[0]) { 1784 i.snapElements.push({ 1785 item: this, 1786 width: $t.outerWidth(), height: $t.outerHeight(), 1787 top: $o.top, left: $o.left 1788 }); 1789 } 1790 }); 1791 1792 }, 1793 drag: function(event, ui) { 1794 1795 var ts, bs, ls, rs, l, r, t, b, i, first, 1796 inst = $(this).data("ui-draggable"), 1797 o = inst.options, 1798 d = o.snapTolerance, 1799 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 1800 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 1801 1802 for (i = inst.snapElements.length - 1; i >= 0; i--){ 1803 1804 l = inst.snapElements[i].left; 1805 r = l + inst.snapElements[i].width; 1806 t = inst.snapElements[i].top; 1807 b = t + inst.snapElements[i].height; 1808 1809 //Yes, I know, this is insane ;) 1810 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))) { 1811 if(inst.snapElements[i].snapping) { 1812 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1813 } 1814 inst.snapElements[i].snapping = false; 1815 continue; 1816 } 1817 1818 if(o.snapMode !== "inner") { 1819 ts = Math.abs(t - y2) <= d; 1820 bs = Math.abs(b - y1) <= d; 1821 ls = Math.abs(l - x2) <= d; 1822 rs = Math.abs(r - x1) <= d; 1823 if(ts) { 1824 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1825 } 1826 if(bs) { 1827 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 1828 } 1829 if(ls) { 1830 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 1831 } 1832 if(rs) { 1833 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 1834 } 1835 } 1836 1837 first = (ts || bs || ls || rs); 1838 1839 if(o.snapMode !== "outer") { 1840 ts = Math.abs(t - y1) <= d; 1841 bs = Math.abs(b - y2) <= d; 1842 ls = Math.abs(l - x1) <= d; 1843 rs = Math.abs(r - x2) <= d; 1844 if(ts) { 1845 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 1846 } 1847 if(bs) { 1848 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 1849 } 1850 if(ls) { 1851 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 1852 } 1853 if(rs) { 1854 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 1855 } 1856 } 1857 1858 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 1859 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 1860 } 1861 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 1862 1863 } 1864 1865 } 1866 }); 1867 1868 $.ui.plugin.add("draggable", "stack", { 1869 start: function() { 1870 var min, 1871 o = this.data("ui-draggable").options, 1872 group = $.makeArray($(o.stack)).sort(function(a,b) { 1873 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 1874 }); 1875 1876 if (!group.length) { return; } 1877 1878 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 1879 $(group).each(function(i) { 1880 $(this).css("zIndex", min + i); 1881 }); 1882 this.css("zIndex", (min + group.length)); 1883 } 1884 }); 1885 1886 $.ui.plugin.add("draggable", "zIndex", { 1887 start: function(event, ui) { 1888 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 1889 if(t.css("zIndex")) { 1890 o._zIndex = t.css("zIndex"); 1891 } 1892 t.css("zIndex", o.zIndex); 1893 }, 1894 stop: function(event, ui) { 1895 var o = $(this).data("ui-draggable").options; 1896 if(o._zIndex) { 1897 $(ui.helper).css("zIndex", o._zIndex); 1898 } 1899 } 1900 }); 1901 1902})(jQuery); 1903 1904(function( $, undefined ) { 1905 1906 function isOverAxis( x, reference, size ) { 1907 return ( x > reference ) && ( x < ( reference + size ) ); 1908 } 1909 1910 $.widget("ui.droppable", { 1911 version: "1.10.2", 1912 widgetEventPrefix: "drop", 1913 options: { 1914 accept: "*", 1915 activeClass: false, 1916 addClasses: true, 1917 greedy: false, 1918 hoverClass: false, 1919 scope: "default", 1920 tolerance: "intersect", 1921 1922 // callbacks 1923 activate: null, 1924 deactivate: null, 1925 drop: null, 1926 out: null, 1927 over: null 1928 }, 1929 _create: function() { 1930 1931 var o = this.options, 1932 accept = o.accept; 1933 1934 this.isover = false; 1935 this.isout = true; 1936 1937 this.accept = $.isFunction(accept) ? accept : function(d) { 1938 return d.is(accept); 1939 }; 1940 1941 //Store the droppable's proportions 1942 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 1943 1944 // Add the reference and positions to the manager 1945 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 1946 $.ui.ddmanager.droppables[o.scope].push(this); 1947 1948 (o.addClasses && this.element.addClass("ui-droppable")); 1949 1950 }, 1951 1952 _destroy: function() { 1953 var i = 0, 1954 drop = $.ui.ddmanager.droppables[this.options.scope]; 1955 1956 for ( ; i < drop.length; i++ ) { 1957 if ( drop[i] === this ) { 1958 drop.splice(i, 1); 1959 } 1960 } 1961 1962 this.element.removeClass("ui-droppable ui-droppable-disabled"); 1963 }, 1964 1965 _setOption: function(key, value) { 1966 1967 if(key === "accept") { 1968 this.accept = $.isFunction(value) ? value : function(d) { 1969 return d.is(value); 1970 }; 1971 } 1972 $.Widget.prototype._setOption.apply(this, arguments); 1973 }, 1974 1975 _activate: function(event) { 1976 var draggable = $.ui.ddmanager.current; 1977 if(this.options.activeClass) { 1978 this.element.addClass(this.options.activeClass); 1979 } 1980 if(draggable){ 1981 this._trigger("activate", event, this.ui(draggable)); 1982 } 1983 }, 1984 1985 _deactivate: function(event) { 1986 var draggable = $.ui.ddmanager.current; 1987 if(this.options.activeClass) { 1988 this.element.removeClass(this.options.activeClass); 1989 } 1990 if(draggable){ 1991 this._trigger("deactivate", event, this.ui(draggable)); 1992 } 1993 }, 1994 1995 _over: function(event) { 1996 1997 var draggable = $.ui.ddmanager.current; 1998 1999 // Bail if draggable and droppable are same element 2000 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2001 return; 2002 } 2003 2004 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2005 if(this.options.hoverClass) { 2006 this.element.addClass(this.options.hoverClass); 2007 } 2008 this._trigger("over", event, this.ui(draggable)); 2009 } 2010 2011 }, 2012 2013 _out: function(event) { 2014 2015 var draggable = $.ui.ddmanager.current; 2016 2017 // Bail if draggable and droppable are same element 2018 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2019 return; 2020 } 2021 2022 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2023 if(this.options.hoverClass) { 2024 this.element.removeClass(this.options.hoverClass); 2025 } 2026 this._trigger("out", event, this.ui(draggable)); 2027 } 2028 2029 }, 2030 2031 _drop: function(event,custom) { 2032 2033 var draggable = custom || $.ui.ddmanager.current, 2034 childrenIntersection = false; 2035 2036 // Bail if draggable and droppable are same element 2037 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 2038 return false; 2039 } 2040 2041 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 2042 var inst = $.data(this, "ui-droppable"); 2043 if( 2044 inst.options.greedy && 2045 !inst.options.disabled && 2046 inst.options.scope === draggable.options.scope && 2047 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 2048 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 2049 ) { childrenIntersection = true; return false; } 2050 }); 2051 if(childrenIntersection) { 2052 return false; 2053 } 2054 2055 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2056 if(this.options.activeClass) { 2057 this.element.removeClass(this.options.activeClass); 2058 } 2059 if(this.options.hoverClass) { 2060 this.element.removeClass(this.options.hoverClass); 2061 } 2062 this._trigger("drop", event, this.ui(draggable)); 2063 return this.element; 2064 } 2065 2066 return false; 2067 2068 }, 2069 2070 ui: function(c) { 2071 return { 2072 draggable: (c.currentItem || c.element), 2073 helper: c.helper, 2074 position: c.position, 2075 offset: c.positionAbs 2076 }; 2077 } 2078 2079 }); 2080 2081 $.ui.intersect = function(draggable, droppable, toleranceMode) { 2082 2083 if (!droppable.offset) { 2084 return false; 2085 } 2086 2087 var draggableLeft, draggableTop, 2088 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 2089 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 2090 l = droppable.offset.left, r = l + droppable.proportions.width, 2091 t = droppable.offset.top, b = t + droppable.proportions.height; 2092 2093 switch (toleranceMode) { 2094 case "fit": 2095 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 2096 case "intersect": 2097 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 2098 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 2099 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 2100 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 2101 case "pointer": 2102 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 2103 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 2104 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 2105 case "touch": 2106 return ( 2107 (y1 >= t && y1 <= b) || // Top edge touching 2108 (y2 >= t && y2 <= b) || // Bottom edge touching 2109 (y1 < t && y2 > b) // Surrounded vertically 2110 ) && ( 2111 (x1 >= l && x1 <= r) || // Left edge touching 2112 (x2 >= l && x2 <= r) || // Right edge touching 2113 (x1 < l && x2 > r) // Surrounded horizontally 2114 ); 2115 default: 2116 return false; 2117 } 2118 2119 }; 2120 2121 /* 2122 This manager tracks offsets of draggables and droppables 2123*/ 2124 $.ui.ddmanager = { 2125 current: null, 2126 droppables: { "default": [] }, 2127 prepareOffsets: function(t, event) { 2128 2129 var i, j, 2130 m = $.ui.ddmanager.droppables[t.options.scope] || [], 2131 type = event ? event.type : null, // workaround for #2317 2132 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 2133 2134 droppablesLoop: for (i = 0; i < m.length; i++) { 2135 2136 //No disabled and non-accepted 2137 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 2138 continue; 2139 } 2140 2141 // Filter out elements in the current dragged item 2142 for (j=0; j < list.length; j++) { 2143 if(list[j] === m[i].element[0]) { 2144 m[i].proportions.height = 0; 2145 continue droppablesLoop; 2146 } 2147 } 2148 2149 m[i].visible = m[i].element.css("display") !== "none"; 2150 if(!m[i].visible) { 2151 continue; 2152 } 2153 2154 //Activate the droppable if used directly from draggables 2155 if(type === "mousedown") { 2156 m[i]._activate.call(m[i], event); 2157 } 2158 2159 m[i].offset = m[i].element.offset(); 2160 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 2161 2162 } 2163 2164 }, 2165 drop: function(draggable, event) { 2166 2167 var dropped = false; 2168 // Create a copy of the droppables in case the list changes during the drop (#9116) 2169 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 2170 2171 if(!this.options) { 2172 return; 2173 } 2174 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 2175 dropped = this._drop.call(this, event) || dropped; 2176 } 2177 2178 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 2179 this.isout = true; 2180 this.isover = false; 2181 this._deactivate.call(this, event); 2182 } 2183 2184 }); 2185 return dropped; 2186 2187 }, 2188 dragStart: function( draggable, event ) { 2189 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 2190 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 2191 if( !draggable.options.refreshPositions ) { 2192 $.ui.ddmanager.prepareOffsets( draggable, event ); 2193 } 2194 }); 2195 }, 2196 drag: function(draggable, event) { 2197 2198 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 2199 if(draggable.options.refreshPositions) { 2200 $.ui.ddmanager.prepareOffsets(draggable, event); 2201 } 2202 2203 //Run through all droppables and check their positions based on specific tolerance options 2204 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 2205 2206 if(this.options.disabled || this.greedyChild || !this.visible) { 2207 return; 2208 } 2209 2210 var parentInstance, scope, parent, 2211 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 2212 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 2213 if(!c) { 2214 return; 2215 } 2216 2217 if (this.options.greedy) { 2218 // find droppable parents with same scope 2219 scope = this.options.scope; 2220 parent = this.element.parents(":data(ui-droppable)").filter(function () { 2221 return $.data(this, "ui-droppable").options.scope === scope; 2222 }); 2223 2224 if (parent.length) { 2225 parentInstance = $.data(parent[0], "ui-droppable"); 2226 parentInstance.greedyChild = (c === "isover"); 2227 } 2228 } 2229 2230 // we just moved into a greedy child 2231 if (parentInstance && c === "isover") { 2232 parentInstance.isover = false; 2233 parentInstance.isout = true; 2234 parentInstance._out.call(parentInstance, event); 2235 } 2236 2237 this[c] = true; 2238 this[c === "isout" ? "isover" : "isout"] = false; 2239 this[c === "isover" ? "_over" : "_out"].call(this, event); 2240 2241 // we just moved out of a greedy child 2242 if (parentInstance && c === "isout") { 2243 parentInstance.isout = false; 2244 parentInstance.isover = true; 2245 parentInstance._over.call(parentInstance, event); 2246 } 2247 }); 2248 2249 }, 2250 dragStop: function( draggable, event ) { 2251 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 2252 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 2253 if( !draggable.options.refreshPositions ) { 2254 $.ui.ddmanager.prepareOffsets( draggable, event ); 2255 } 2256 } 2257 }; 2258 2259})(jQuery); 2260 2261(function( $, undefined ) { 2262 2263 function num(v) { 2264 return parseInt(v, 10) || 0; 2265 } 2266 2267 function isNumber(value) { 2268 return !isNaN(parseInt(value, 10)); 2269 } 2270 2271 $.widget("ui.resizable", $.ui.mouse, { 2272 version: "1.10.2", 2273 widgetEventPrefix: "resize", 2274 options: { 2275 alsoResize: false, 2276 animate: false, 2277 animateDuration: "slow", 2278 animateEasing: "swing", 2279 aspectRatio: false, 2280 autoHide: false, 2281 containment: false, 2282 ghost: false, 2283 grid: false, 2284 handles: "e,s,se", 2285 helper: false, 2286 maxHeight: null, 2287 maxWidth: null, 2288 minHeight: 10, 2289 minWidth: 10, 2290 // See #7960 2291 zIndex: 90, 2292 2293 // callbacks 2294 resize: null, 2295 start: null, 2296 stop: null 2297 }, 2298 _create: function() { 2299 2300 var n, i, handle, axis, hname, 2301 that = this, 2302 o = this.options; 2303 this.element.addClass("ui-resizable"); 2304 2305 $.extend(this, { 2306 _aspectRatio: !!(o.aspectRatio), 2307 aspectRatio: o.aspectRatio, 2308 originalElement: this.element, 2309 _proportionallyResizeElements: [], 2310 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 2311 }); 2312 2313 //Wrap the element if it cannot hold child nodes 2314 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 2315 2316 //Create a wrapper element and set the wrapper to the new current internal element 2317 this.element.wrap( 2318 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 2319 position: this.element.css("position"), 2320 width: this.element.outerWidth(), 2321 height: this.element.outerHeight(), 2322 top: this.element.css("top"), 2323 left: this.element.css("left") 2324 }) 2325 ); 2326 2327 //Overwrite the original this.element 2328 this.element = this.element.parent().data( 2329 "ui-resizable", this.element.data("ui-resizable") 2330 ); 2331 2332 this.elementIsWrapper = true; 2333 2334 //Move margins to the wrapper 2335 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 2336 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 2337 2338 //Prevent Safari textarea resize 2339 this.originalResizeStyle = this.originalElement.css("resize"); 2340 this.originalElement.css("resize", "none"); 2341 2342 //Push the actual element to our proportionallyResize internal array 2343 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 2344 2345 // avoid IE jump (hard set the margin) 2346 this.originalElement.css({ margin: this.originalElement.css("margin") }); 2347 2348 // fix handlers offset 2349 this._proportionallyResize(); 2350 2351 } 2352 2353 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" }); 2354 if(this.handles.constructor === String) { 2355 2356 if ( this.handles === "all") { 2357 this.handles = "n,e,s,w,se,sw,ne,nw"; 2358 } 2359 2360 n = this.handles.split(","); 2361 this.handles = {}; 2362 2363 for(i = 0; i < n.length; i++) { 2364 2365 handle = $.trim(n[i]); 2366 hname = "ui-resizable-"+handle; 2367 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 2368 2369 // Apply zIndex to all handles - see #7960 2370 axis.css({ zIndex: o.zIndex }); 2371 2372 //TODO : What's going on here? 2373 if ("se" === handle) { 2374 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 2375 } 2376 2377 //Insert into internal handles object and append to element 2378 this.handles[handle] = ".ui-resizable-"+handle; 2379 this.element.append(axis); 2380 } 2381 2382 } 2383 2384 this._renderAxis = function(target) { 2385 2386 var i, axis, padPos, padWrapper; 2387 2388 target = target || this.element; 2389 2390 for(i in this.handles) { 2391 2392 if(this.handles[i].constructor === String) { 2393 this.handles[i] = $(this.handles[i], this.element).show(); 2394 } 2395 2396 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 2397 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 2398 2399 axis = $(this.handles[i], this.element); 2400 2401 //Checking the correct pad and border 2402 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 2403 2404 //The padding type i have to apply... 2405 padPos = [ "padding", 2406 /ne|nw|n/.test(i) ? "Top" : 2407 /se|sw|s/.test(i) ? "Bottom" : 2408 /^e$/.test(i) ? "Right" : "Left" ].join(""); 2409 2410 target.css(padPos, padWrapper); 2411 2412 this._proportionallyResize(); 2413 2414 } 2415 2416 //TODO: What's that good for? There's not anything to be executed left 2417 if(!$(this.handles[i]).length) { 2418 continue; 2419 } 2420 } 2421 }; 2422 2423 //TODO: make renderAxis a prototype function 2424 this._renderAxis(this.element); 2425 2426 this._handles = $(".ui-resizable-handle", this.element) 2427 .disableSelection(); 2428 2429 //Matching axis name 2430 this._handles.mouseover(function() { 2431 if (!that.resizing) { 2432 if (this.className) { 2433 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 2434 } 2435 //Axis, default = se 2436 that.axis = axis && axis[1] ? axis[1] : "se"; 2437 } 2438 }); 2439 2440 //If we want to auto hide the elements 2441 if (o.autoHide) { 2442 this._handles.hide(); 2443 $(this.element) 2444 .addClass("ui-resizable-autohide") 2445 .mouseenter(function() { 2446 if (o.disabled) { 2447 return; 2448 } 2449 $(this).removeClass("ui-resizable-autohide"); 2450 that._handles.show(); 2451 }) 2452 .mouseleave(function(){ 2453 if (o.disabled) { 2454 return; 2455 } 2456 if (!that.resizing) { 2457 $(this).addClass("ui-resizable-autohide"); 2458 that._handles.hide(); 2459 } 2460 }); 2461 } 2462 2463 //Initialize the mouse interaction 2464 this._mouseInit(); 2465 2466 }, 2467 2468 _destroy: function() { 2469 2470 this._mouseDestroy(); 2471 2472 var wrapper, 2473 _destroy = function(exp) { 2474 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 2475 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 2476 }; 2477 2478 //TODO: Unwrap at same DOM position 2479 if (this.elementIsWrapper) { 2480 _destroy(this.element); 2481 wrapper = this.element; 2482 this.originalElement.css({ 2483 position: wrapper.css("position"), 2484 width: wrapper.outerWidth(), 2485 height: wrapper.outerHeight(), 2486 top: wrapper.css("top"), 2487 left: wrapper.css("left") 2488 }).insertAfter( wrapper ); 2489 wrapper.remove(); 2490 } 2491 2492 this.originalElement.css("resize", this.originalResizeStyle); 2493 _destroy(this.originalElement); 2494 2495 return this; 2496 }, 2497 2498 _mouseCapture: function(event) { 2499 var i, handle, 2500 capture = false; 2501 2502 for (i in this.handles) { 2503 handle = $(this.handles[i])[0]; 2504 if (handle === event.target || $.contains(handle, event.target)) { 2505 capture = true; 2506 } 2507 } 2508 2509 return !this.options.disabled && capture; 2510 }, 2511 2512 _mouseStart: function(event) { 2513 2514 var curleft, curtop, cursor, 2515 o = this.options, 2516 iniPos = this.element.position(), 2517 el = this.element; 2518 2519 this.resizing = true; 2520 2521 // bugfix for http://dev.jquery.com/ticket/1749 2522 if ( (/absolute/).test( el.css("position") ) ) { 2523 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 2524 } else if (el.is(".ui-draggable")) { 2525 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 2526 } 2527 2528 this._renderProxy(); 2529 2530 curleft = num(this.helper.css("left")); 2531 curtop = num(this.helper.css("top")); 2532 2533 if (o.containment) { 2534 curleft += $(o.containment).scrollLeft() || 0; 2535 curtop += $(o.containment).scrollTop() || 0; 2536 } 2537 2538 //Store needed variables 2539 this.offset = this.helper.offset(); 2540 this.position = { left: curleft, top: curtop }; 2541 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2542 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 2543 this.originalPosition = { left: curleft, top: curtop }; 2544 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 2545 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 2546 2547 //Aspect Ratio 2548 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 2549 2550 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 2551 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 2552 2553 el.addClass("ui-resizable-resizing"); 2554 this._propagate("start", event); 2555 return true; 2556 }, 2557 2558 _mouseDrag: function(event) { 2559 2560 //Increase performance, avoid regex 2561 var data, 2562 el = this.helper, props = {}, 2563 smp = this.originalMousePosition, 2564 a = this.axis, 2565 prevTop = this.position.top, 2566 prevLeft = this.position.left, 2567 prevWidth = this.size.width, 2568 prevHeight = this.size.height, 2569 dx = (event.pageX-smp.left)||0, 2570 dy = (event.pageY-smp.top)||0, 2571 trigger = this._change[a]; 2572 2573 if (!trigger) { 2574 return false; 2575 } 2576 2577 // Calculate the attrs that will be change 2578 data = trigger.apply(this, [event, dx, dy]); 2579 2580 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 2581 this._updateVirtualBoundaries(event.shiftKey); 2582 if (this._aspectRatio || event.shiftKey) { 2583 data = this._updateRatio(data, event); 2584 } 2585 2586 data = this._respectSize(data, event); 2587 2588 this._updateCache(data); 2589 2590 // plugins callbacks need to be called first 2591 this._propagate("resize", event); 2592 2593 if (this.position.top !== prevTop) { 2594 props.top = this.position.top + "px"; 2595 } 2596 if (this.position.left !== prevLeft) { 2597 props.left = this.position.left + "px"; 2598 } 2599 if (this.size.width !== prevWidth) { 2600 props.width = this.size.width + "px"; 2601 } 2602 if (this.size.height !== prevHeight) { 2603 props.height = this.size.height + "px"; 2604 } 2605 el.css(props); 2606 2607 if (!this._helper && this._proportionallyResizeElements.length) { 2608 this._proportionallyResize(); 2609 } 2610 2611 // Call the user callback if the element was resized 2612 if ( ! $.isEmptyObject(props) ) { 2613 this._trigger("resize", event, this.ui()); 2614 } 2615 2616 return false; 2617 }, 2618 2619 _mouseStop: function(event) { 2620 2621 this.resizing = false; 2622 var pr, ista, soffseth, soffsetw, s, left, top, 2623 o = this.options, that = this; 2624 2625 if(this._helper) { 2626 2627 pr = this._proportionallyResizeElements; 2628 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 2629 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 2630 soffsetw = ista ? 0 : that.sizeDiff.width; 2631 2632 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 2633 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 2634 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2635 2636 if (!o.animate) { 2637 this.element.css($.extend(s, { top: top, left: left })); 2638 } 2639 2640 that.helper.height(that.size.height); 2641 that.helper.width(that.size.width); 2642 2643 if (this._helper && !o.animate) { 2644 this._proportionallyResize(); 2645 } 2646 } 2647 2648 $("body").css("cursor", "auto"); 2649 2650 this.element.removeClass("ui-resizable-resizing"); 2651 2652 this._propagate("stop", event); 2653 2654 if (this._helper) { 2655 this.helper.remove(); 2656 } 2657 2658 return false; 2659 2660 }, 2661 2662 _updateVirtualBoundaries: function(forceAspectRatio) { 2663 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 2664 o = this.options; 2665 2666 b = { 2667 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 2668 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 2669 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 2670 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 2671 }; 2672 2673 if(this._aspectRatio || forceAspectRatio) { 2674 // We want to create an enclosing box whose aspect ration is the requested one 2675 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 2676 pMinWidth = b.minHeight * this.aspectRatio; 2677 pMinHeight = b.minWidth / this.aspectRatio; 2678 pMaxWidth = b.maxHeight * this.aspectRatio; 2679 pMaxHeight = b.maxWidth / this.aspectRatio; 2680 2681 if(pMinWidth > b.minWidth) { 2682 b.minWidth = pMinWidth; 2683 } 2684 if(pMinHeight > b.minHeight) { 2685 b.minHeight = pMinHeight; 2686 } 2687 if(pMaxWidth < b.maxWidth) { 2688 b.maxWidth = pMaxWidth; 2689 } 2690 if(pMaxHeight < b.maxHeight) { 2691 b.maxHeight = pMaxHeight; 2692 } 2693 } 2694 this._vBoundaries = b; 2695 }, 2696 2697 _updateCache: function(data) { 2698 this.offset = this.helper.offset(); 2699 if (isNumber(data.left)) { 2700 this.position.left = data.left; 2701 } 2702 if (isNumber(data.top)) { 2703 this.position.top = data.top; 2704 } 2705 if (isNumber(data.height)) { 2706 this.size.height = data.height; 2707 } 2708 if (isNumber(data.width)) { 2709 this.size.width = data.width; 2710 } 2711 }, 2712 2713 _updateRatio: function( data ) { 2714 2715 var cpos = this.position, 2716 csize = this.size, 2717 a = this.axis; 2718 2719 if (isNumber(data.height)) { 2720 data.width = (data.height * this.aspectRatio); 2721 } else if (isNumber(data.width)) { 2722 data.height = (data.width / this.aspectRatio); 2723 } 2724 2725 if (a === "sw") { 2726 data.left = cpos.left + (csize.width - data.width); 2727 data.top = null; 2728 } 2729 if (a === "nw") { 2730 data.top = cpos.top + (csize.height - data.height); 2731 data.left = cpos.left + (csize.width - data.width); 2732 } 2733 2734 return data; 2735 }, 2736 2737 _respectSize: function( data ) { 2738 2739 var o = this._vBoundaries, 2740 a = this.axis, 2741 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 2742 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 2743 dw = this.originalPosition.left + this.originalSize.width, 2744 dh = this.position.top + this.size.height, 2745 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 2746 if (isminw) { 2747 data.width = o.minWidth; 2748 } 2749 if (isminh) { 2750 data.height = o.minHeight; 2751 } 2752 if (ismaxw) { 2753 data.width = o.maxWidth; 2754 } 2755 if (ismaxh) { 2756 data.height = o.maxHeight; 2757 } 2758 2759 if (isminw && cw) { 2760 data.left = dw - o.minWidth; 2761 } 2762 if (ismaxw && cw) { 2763 data.left = dw - o.maxWidth; 2764 } 2765 if (isminh && ch) { 2766 data.top = dh - o.minHeight; 2767 } 2768 if (ismaxh && ch) { 2769 data.top = dh - o.maxHeight; 2770 } 2771 2772 // fixing jump error on top/left - bug #2330 2773 if (!data.width && !data.height && !data.left && data.top) { 2774 data.top = null; 2775 } else if (!data.width && !data.height && !data.top && data.left) { 2776 data.left = null; 2777 } 2778 2779 return data; 2780 }, 2781 2782 _proportionallyResize: function() { 2783 2784 if (!this._proportionallyResizeElements.length) { 2785 return; 2786 } 2787 2788 var i, j, borders, paddings, prel, 2789 element = this.helper || this.element; 2790 2791 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 2792 2793 prel = this._proportionallyResizeElements[i]; 2794 2795 if (!this.borderDif) { 2796 this.borderDif = []; 2797 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 2798 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 2799 2800 for ( j = 0; j < borders.length; j++ ) { 2801 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 2802 } 2803 } 2804 2805 prel.css({ 2806 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 2807 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 2808 }); 2809 2810 } 2811 2812 }, 2813 2814 _renderProxy: function() { 2815 2816 var el = this.element, o = this.options; 2817 this.elementOffset = el.offset(); 2818 2819 if(this._helper) { 2820 2821 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 2822 2823 this.helper.addClass(this._helper).css({ 2824 width: this.element.outerWidth() - 1, 2825 height: this.element.outerHeight() - 1, 2826 position: "absolute", 2827 left: this.elementOffset.left +"px", 2828 top: this.elementOffset.top +"px", 2829 zIndex: ++o.zIndex //TODO: Don't modify option 2830 }); 2831 2832 this.helper 2833 .appendTo("body") 2834 .disableSelection(); 2835 2836 } else { 2837 this.helper = this.element; 2838 } 2839 2840 }, 2841 2842 _change: { 2843 e: function(event, dx) { 2844 return { width: this.originalSize.width + dx }; 2845 }, 2846 w: function(event, dx) { 2847 var cs = this.originalSize, sp = this.originalPosition; 2848 return { left: sp.left + dx, width: cs.width - dx }; 2849 }, 2850 n: function(event, dx, dy) { 2851 var cs = this.originalSize, sp = this.originalPosition; 2852 return { top: sp.top + dy, height: cs.height - dy }; 2853 }, 2854 s: function(event, dx, dy) { 2855 return { height: this.originalSize.height + dy }; 2856 }, 2857 se: function(event, dx, dy) { 2858 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2859 }, 2860 sw: function(event, dx, dy) { 2861 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2862 }, 2863 ne: function(event, dx, dy) { 2864 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 2865 }, 2866 nw: function(event, dx, dy) { 2867 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 2868 } 2869 }, 2870 2871 _propagate: function(n, event) { 2872 $.ui.plugin.call(this, n, [event, this.ui()]); 2873 (n !== "resize" && this._trigger(n, event, this.ui())); 2874 }, 2875 2876 plugins: {}, 2877 2878 ui: function() { 2879 return { 2880 originalElement: this.originalElement, 2881 element: this.element, 2882 helper: this.helper, 2883 position: this.position, 2884 size: this.size, 2885 originalSize: this.originalSize, 2886 originalPosition: this.originalPosition 2887 }; 2888 } 2889 2890 }); 2891 2892 /* 2893 * Resizable Extensions 2894 */ 2895 2896 $.ui.plugin.add("resizable", "animate", { 2897 2898 stop: function( event ) { 2899 var that = $(this).data("ui-resizable"), 2900 o = that.options, 2901 pr = that._proportionallyResizeElements, 2902 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 2903 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 2904 soffsetw = ista ? 0 : that.sizeDiff.width, 2905 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 2906 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 2907 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 2908 2909 that.element.animate( 2910 $.extend(style, top && left ? { top: top, left: left } : {}), { 2911 duration: o.animateDuration, 2912 easing: o.animateEasing, 2913 step: function() { 2914 2915 var data = { 2916 width: parseInt(that.element.css("width"), 10), 2917 height: parseInt(that.element.css("height"), 10), 2918 top: parseInt(that.element.css("top"), 10), 2919 left: parseInt(that.element.css("left"), 10) 2920 }; 2921 2922 if (pr && pr.length) { 2923 $(pr[0]).css({ width: data.width, height: data.height }); 2924 } 2925 2926 // propagating resize, and updating values for each animation step 2927 that._updateCache(data); 2928 that._propagate("resize", event); 2929 2930 } 2931 } 2932 ); 2933 } 2934 2935 });
vendor: 4,977 bytes, lines 2936-3051
2936 2937 $.ui.plugin.add("resizable", "containment", { 2938 2939 start: function() { 2940 var element, p, co, ch, cw, width, height, 2941 that = $(this).data("ui-resizable"), 2942 o = that.options, 2943 el = that.element, 2944 oc = o.containment, 2945 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 2946 2947 if (!ce) { 2948 return; 2949 } 2950 2951 that.containerElement = $(ce); 2952 2953 if (/document/.test(oc) || oc === document) { 2954 that.containerOffset = { left: 0, top: 0 }; 2955 that.containerPosition = { left: 0, top: 0 }; 2956 2957 that.parentData = { 2958 element: $(document), left: 0, top: 0, 2959 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 2960 }; 2961 } 2962 2963 // i'm a node, so compute top, left, right, bottom 2964 else { 2965 element = $(ce); 2966 p = []; 2967 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 2968 2969 that.containerOffset = element.offset(); 2970 that.containerPosition = element.position(); 2971 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 2972 2973 co = that.containerOffset; 2974 ch = that.containerSize.height; 2975 cw = that.containerSize.width; 2976 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 2977 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 2978 2979 that.parentData = { 2980 element: ce, left: co.left, top: co.top, width: width, height: height 2981 }; 2982 } 2983 }, 2984 2985 resize: function( event ) { 2986 var woset, hoset, isParent, isOffsetRelative, 2987 that = $(this).data("ui-resizable"), 2988 o = that.options, 2989 co = that.containerOffset, cp = that.position, 2990 pRatio = that._aspectRatio || event.shiftKey, 2991 cop = { top:0, left:0 }, ce = that.containerElement; 2992 2993 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 2994 cop = co; 2995 } 2996 2997 if (cp.left < (that._helper ? co.left : 0)) { 2998 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 2999 if (pRatio) { 3000 that.size.height = that.size.width / that.aspectRatio; 3001 } 3002 that.position.left = o.helper ? co.left : 0; 3003 } 3004 3005 if (cp.top < (that._helper ? co.top : 0)) { 3006 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 3007 if (pRatio) { 3008 that.size.width = that.size.height * that.aspectRatio; 3009 } 3010 that.position.top = that._helper ? co.top : 0; 3011 } 3012 3013 that.offset.left = that.parentData.left+that.position.left; 3014 that.offset.top = that.parentData.top+that.position.top; 3015 3016 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 3017 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 3018 3019 isParent = that.containerElement.get(0) === that.element.parent().get(0); 3020 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 3021 3022 if(isParent && isOffsetRelative) { 3023 woset -= that.parentData.left; 3024 } 3025 3026 if (woset + that.size.width >= that.parentData.width) { 3027 that.size.width = that.parentData.width - woset; 3028 if (pRatio) { 3029 that.size.height = that.size.width / that.aspectRatio; 3030 } 3031 } 3032 3033 if (hoset + that.size.height >= that.parentData.height) { 3034 that.size.height = that.parentData.height - hoset; 3035 if (pRatio) { 3036 that.size.width = that.size.height * that.aspectRatio; 3037 } 3038 } 3039 }, 3040 3041 stop: function(){ 3042 var that = $(this).data("ui-resizable"), 3043 o = that.options, 3044 co = that.containerOffset, 3045 cop = that.containerPosition, 3046 ce = that.containerElement, 3047 helper = $(that.helper), 3048 ho = helper.offset(), 3049 w = helper.outerWidth() - that.sizeDiff.width, 3050 h = helper.outerHeight() - that.sizeDiff.height; 3051
vendor: 47,557 bytes, lines 3052-4254
3052 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 3053 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3054 } 3055 3056 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 3057 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 3058 } 3059 3060 } 3061 }); 3062 3063 $.ui.plugin.add("resizable", "alsoResize", { 3064 3065 start: function () { 3066 var that = $(this).data("ui-resizable"), 3067 o = that.options, 3068 _store = function (exp) { 3069 $(exp).each(function() { 3070 var el = $(this); 3071 el.data("ui-resizable-alsoresize", { 3072 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 3073 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 3074 }); 3075 }); 3076 }; 3077 3078 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 3079 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 3080 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 3081 }else{ 3082 _store(o.alsoResize); 3083 } 3084 }, 3085 3086 resize: function (event, ui) { 3087 var that = $(this).data("ui-resizable"), 3088 o = that.options, 3089 os = that.originalSize, 3090 op = that.originalPosition, 3091 delta = { 3092 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 3093 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 3094 }, 3095 3096 _alsoResize = function (exp, c) { 3097 $(exp).each(function() { 3098 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 3099 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 3100 3101 $.each(css, function (i, prop) { 3102 var sum = (start[prop]||0) + (delta[prop]||0); 3103 if (sum && sum >= 0) { 3104 style[prop] = sum || null; 3105 } 3106 }); 3107 3108 el.css(style); 3109 }); 3110 }; 3111 3112 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 3113 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 3114 }else{ 3115 _alsoResize(o.alsoResize); 3116 } 3117 }, 3118 3119 stop: function () { 3120 $(this).removeData("resizable-alsoresize"); 3121 } 3122 }); 3123 3124 $.ui.plugin.add("resizable", "ghost", { 3125 3126 start: function() { 3127 3128 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 3129 3130 that.ghost = that.originalElement.clone(); 3131 that.ghost 3132 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 3133 .addClass("ui-resizable-ghost") 3134 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 3135 3136 that.ghost.appendTo(that.helper); 3137 3138 }, 3139 3140 resize: function(){ 3141 var that = $(this).data("ui-resizable"); 3142 if (that.ghost) { 3143 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 3144 } 3145 }, 3146 3147 stop: function() { 3148 var that = $(this).data("ui-resizable"); 3149 if (that.ghost && that.helper) { 3150 that.helper.get(0).removeChild(that.ghost.get(0)); 3151 } 3152 } 3153 3154 }); 3155 3156 $.ui.plugin.add("resizable", "grid", { 3157 3158 resize: function() { 3159 var that = $(this).data("ui-resizable"), 3160 o = that.options, 3161 cs = that.size, 3162 os = that.originalSize, 3163 op = that.originalPosition, 3164 a = that.axis, 3165 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 3166 gridX = (grid[0]||1), 3167 gridY = (grid[1]||1), 3168 ox = Math.round((cs.width - os.width) / gridX) * gridX, 3169 oy = Math.round((cs.height - os.height) / gridY) * gridY, 3170 newWidth = os.width + ox, 3171 newHeight = os.height + oy, 3172 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 3173 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 3174 isMinWidth = o.minWidth && (o.minWidth > newWidth), 3175 isMinHeight = o.minHeight && (o.minHeight > newHeight); 3176 3177 o.grid = grid; 3178 3179 if (isMinWidth) { 3180 newWidth = newWidth + gridX; 3181 } 3182 if (isMinHeight) { 3183 newHeight = newHeight + gridY; 3184 } 3185 if (isMaxWidth) { 3186 newWidth = newWidth - gridX; 3187 } 3188 if (isMaxHeight) { 3189 newHeight = newHeight - gridY; 3190 } 3191 3192 if (/^(se|s|e)$/.test(a)) { 3193 that.size.width = newWidth; 3194 that.size.height = newHeight; 3195 } else if (/^(ne)$/.test(a)) { 3196 that.size.width = newWidth; 3197 that.size.height = newHeight; 3198 that.position.top = op.top - oy; 3199 } else if (/^(sw)$/.test(a)) { 3200 that.size.width = newWidth; 3201 that.size.height = newHeight; 3202 that.position.left = op.left - ox; 3203 } else { 3204 that.size.width = newWidth; 3205 that.size.height = newHeight; 3206 that.position.top = op.top - oy; 3207 that.position.left = op.left - ox; 3208 } 3209 } 3210 3211 }); 3212 3213})(jQuery); 3214 3215(function( $, undefined ) { 3216 3217 $.widget("ui.selectable", $.ui.mouse, { 3218 version: "1.10.2", 3219 options: { 3220 appendTo: "body", 3221 autoRefresh: true, 3222 distance: 0, 3223 filter: "*", 3224 tolerance: "touch", 3225 3226 // callbacks 3227 selected: null, 3228 selecting: null, 3229 start: null, 3230 stop: null, 3231 unselected: null, 3232 unselecting: null 3233 }, 3234 _create: function() { 3235 var selectees, 3236 that = this; 3237 3238 this.element.addClass("ui-selectable"); 3239 3240 this.dragged = false; 3241 3242 // cache selectee children based on filter 3243 this.refresh = function() { 3244 selectees = $(that.options.filter, that.element[0]); 3245 selectees.addClass("ui-selectee"); 3246 selectees.each(function() { 3247 var $this = $(this), 3248 pos = $this.offset(); 3249 $.data(this, "selectable-item", { 3250 element: this, 3251 $element: $this, 3252 left: pos.left, 3253 top: pos.top, 3254 right: pos.left + $this.outerWidth(), 3255 bottom: pos.top + $this.outerHeight(), 3256 startselected: false, 3257 selected: $this.hasClass("ui-selected"), 3258 selecting: $this.hasClass("ui-selecting"), 3259 unselecting: $this.hasClass("ui-unselecting") 3260 }); 3261 }); 3262 }; 3263 this.refresh(); 3264 3265 this.selectees = selectees.addClass("ui-selectee"); 3266 3267 this._mouseInit(); 3268 3269 this.helper = $("<div class='ui-selectable-helper'></div>"); 3270 }, 3271 3272 _destroy: function() { 3273 this.selectees 3274 .removeClass("ui-selectee") 3275 .removeData("selectable-item"); 3276 this.element 3277 .removeClass("ui-selectable ui-selectable-disabled"); 3278 this._mouseDestroy(); 3279 }, 3280 3281 _mouseStart: function(event) { 3282 var that = this, 3283 options = this.options; 3284 3285 this.opos = [event.pageX, event.pageY]; 3286 3287 if (this.options.disabled) { 3288 return; 3289 } 3290 3291 this.selectees = $(options.filter, this.element[0]); 3292 3293 this._trigger("start", event); 3294 3295 $(options.appendTo).append(this.helper); 3296 // position helper (lasso) 3297 this.helper.css({ 3298 "left": event.pageX, 3299 "top": event.pageY, 3300 "width": 0, 3301 "height": 0 3302 }); 3303 3304 if (options.autoRefresh) { 3305 this.refresh(); 3306 } 3307 3308 this.selectees.filter(".ui-selected").each(function() { 3309 var selectee = $.data(this, "selectable-item"); 3310 selectee.startselected = true; 3311 if (!event.metaKey && !event.ctrlKey) { 3312 selectee.$element.removeClass("ui-selected"); 3313 selectee.selected = false; 3314 selectee.$element.addClass("ui-unselecting"); 3315 selectee.unselecting = true; 3316 // selectable UNSELECTING callback 3317 that._trigger("unselecting", event, { 3318 unselecting: selectee.element 3319 }); 3320 } 3321 }); 3322 3323 $(event.target).parents().addBack().each(function() { 3324 var doSelect, 3325 selectee = $.data(this, "selectable-item"); 3326 if (selectee) { 3327 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 3328 selectee.$element 3329 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 3330 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 3331 selectee.unselecting = !doSelect; 3332 selectee.selecting = doSelect; 3333 selectee.selected = doSelect; 3334 // selectable (UN)SELECTING callback 3335 if (doSelect) { 3336 that._trigger("selecting", event, { 3337 selecting: selectee.element 3338 }); 3339 } else { 3340 that._trigger("unselecting", event, { 3341 unselecting: selectee.element 3342 }); 3343 } 3344 return false; 3345 } 3346 }); 3347 3348 }, 3349 3350 _mouseDrag: function(event) { 3351 3352 this.dragged = true; 3353 3354 if (this.options.disabled) { 3355 return; 3356 } 3357 3358 var tmp, 3359 that = this, 3360 options = this.options, 3361 x1 = this.opos[0], 3362 y1 = this.opos[1], 3363 x2 = event.pageX, 3364 y2 = event.pageY; 3365 3366 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 3367 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 3368 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 3369 3370 this.selectees.each(function() { 3371 var selectee = $.data(this, "selectable-item"), 3372 hit = false; 3373 3374 //prevent helper from being selected if appendTo: selectable 3375 if (!selectee || selectee.element === that.element[0]) { 3376 return; 3377 } 3378 3379 if (options.tolerance === "touch") { 3380 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 3381 } else if (options.tolerance === "fit") { 3382 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 3383 } 3384 3385 if (hit) { 3386 // SELECT 3387 if (selectee.selected) { 3388 selectee.$element.removeClass("ui-selected"); 3389 selectee.selected = false; 3390 } 3391 if (selectee.unselecting) { 3392 selectee.$element.removeClass("ui-unselecting"); 3393 selectee.unselecting = false; 3394 } 3395 if (!selectee.selecting) { 3396 selectee.$element.addClass("ui-selecting"); 3397 selectee.selecting = true; 3398 // selectable SELECTING callback 3399 that._trigger("selecting", event, { 3400 selecting: selectee.element 3401 }); 3402 } 3403 } else { 3404 // UNSELECT 3405 if (selectee.selecting) { 3406 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 3407 selectee.$element.removeClass("ui-selecting"); 3408 selectee.selecting = false; 3409 selectee.$element.addClass("ui-selected"); 3410 selectee.selected = true; 3411 } else { 3412 selectee.$element.removeClass("ui-selecting"); 3413 selectee.selecting = false; 3414 if (selectee.startselected) { 3415 selectee.$element.addClass("ui-unselecting"); 3416 selectee.unselecting = true; 3417 } 3418 // selectable UNSELECTING callback 3419 that._trigger("unselecting", event, { 3420 unselecting: selectee.element 3421 }); 3422 } 3423 } 3424 if (selectee.selected) { 3425 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 3426 selectee.$element.removeClass("ui-selected"); 3427 selectee.selected = false; 3428 3429 selectee.$element.addClass("ui-unselecting"); 3430 selectee.unselecting = true; 3431 // selectable UNSELECTING callback 3432 that._trigger("unselecting", event, { 3433 unselecting: selectee.element 3434 }); 3435 } 3436 } 3437 } 3438 }); 3439 3440 return false; 3441 }, 3442 3443 _mouseStop: function(event) { 3444 var that = this; 3445 3446 this.dragged = false; 3447 3448 $(".ui-unselecting", this.element[0]).each(function() { 3449 var selectee = $.data(this, "selectable-item"); 3450 selectee.$element.removeClass("ui-unselecting"); 3451 selectee.unselecting = false; 3452 selectee.startselected = false; 3453 that._trigger("unselected", event, { 3454 unselected: selectee.element 3455 }); 3456 }); 3457 $(".ui-selecting", this.element[0]).each(function() { 3458 var selectee = $.data(this, "selectable-item"); 3459 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 3460 selectee.selecting = false; 3461 selectee.selected = true; 3462 selectee.startselected = true; 3463 that._trigger("selected", event, { 3464 selected: selectee.element 3465 }); 3466 }); 3467 this._trigger("stop", event); 3468 3469 this.helper.remove(); 3470 3471 return false; 3472 } 3473 3474 }); 3475 3476})(jQuery); 3477 3478(function( $, undefined ) { 3479 3480 /*jshint loopfunc: true */ 3481 3482 function isOverAxis( x, reference, size ) { 3483 return ( x > reference ) && ( x < ( reference + size ) ); 3484 } 3485 3486 function isFloating(item) { 3487 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 3488 } 3489 3490 $.widget("ui.sortable", $.ui.mouse, { 3491 version: "1.10.2", 3492 widgetEventPrefix: "sort", 3493 ready: false, 3494 options: { 3495 appendTo: "parent", 3496 axis: false, 3497 connectWith: false, 3498 containment: false, 3499 cursor: "auto", 3500 cursorAt: false, 3501 dropOnEmpty: true, 3502 forcePlaceholderSize: false, 3503 forceHelperSize: false, 3504 grid: false, 3505 handle: false, 3506 helper: "original", 3507 items: "> *", 3508 opacity: false, 3509 placeholder: false, 3510 revert: false, 3511 scroll: true, 3512 scrollSensitivity: 20, 3513 scrollSpeed: 20, 3514 scope: "default", 3515 tolerance: "intersect", 3516 zIndex: 1000, 3517 3518 // callbacks 3519 activate: null, 3520 beforeStop: null, 3521 change: null, 3522 deactivate: null, 3523 out: null, 3524 over: null, 3525 receive: null, 3526 remove: null, 3527 sort: null, 3528 start: null, 3529 stop: null, 3530 update: null 3531 }, 3532 _create: function() { 3533 3534 var o = this.options; 3535 this.containerCache = {}; 3536 this.element.addClass("ui-sortable"); 3537 3538 //Get the items 3539 this.refresh(); 3540 3541 //Let's determine if the items are being displayed horizontally 3542 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 3543 3544 //Let's determine the parent's offset 3545 this.offset = this.element.offset(); 3546 3547 //Initialize mouse events for interaction 3548 this._mouseInit(); 3549 3550 //We're ready to go 3551 this.ready = true; 3552 3553 }, 3554 3555 _destroy: function() { 3556 this.element 3557 .removeClass("ui-sortable ui-sortable-disabled"); 3558 this._mouseDestroy(); 3559 3560 for ( var i = this.items.length - 1; i >= 0; i-- ) { 3561 this.items[i].item.removeData(this.widgetName + "-item"); 3562 } 3563 3564 return this; 3565 }, 3566 3567 _setOption: function(key, value){ 3568 if ( key === "disabled" ) { 3569 this.options[ key ] = value; 3570 3571 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 3572 } else { 3573 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 3574 $.Widget.prototype._setOption.apply(this, arguments); 3575 } 3576 }, 3577 3578 _mouseCapture: function(event, overrideHandle) { 3579 var currentItem = null, 3580 validHandle = false, 3581 that = this; 3582 3583 if (this.reverting) { 3584 return false; 3585 } 3586 3587 if(this.options.disabled || this.options.type === "static") { 3588 return false; 3589 } 3590 3591 //We have to refresh the items data once first 3592 this._refreshItems(event); 3593 3594 //Find out if the clicked node (or one of its parents) is a actual item in this.items 3595 $(event.target).parents().each(function() { 3596 if($.data(this, that.widgetName + "-item") === that) { 3597 currentItem = $(this); 3598 return false; 3599 } 3600 }); 3601 if($.data(event.target, that.widgetName + "-item") === that) { 3602 currentItem = $(event.target); 3603 } 3604 3605 if(!currentItem) { 3606 return false; 3607 } 3608 if(this.options.handle && !overrideHandle) { 3609 $(this.options.handle, currentItem).find("*").addBack().each(function() { 3610 if(this === event.target) { 3611 validHandle = true; 3612 } 3613 }); 3614 if(!validHandle) { 3615 return false; 3616 } 3617 } 3618 3619 this.currentItem = currentItem; 3620 this._removeCurrentsFromItems(); 3621 return true; 3622 3623 }, 3624 3625 _mouseStart: function(event, overrideHandle, noActivation) { 3626 3627 var i, body, 3628 o = this.options; 3629 3630 this.currentContainer = this; 3631 3632 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 3633 this.refreshPositions(); 3634 3635 //Create and append the visible helper 3636 this.helper = this._createHelper(event); 3637 3638 //Cache the helper size 3639 this._cacheHelperProportions(); 3640 3641 /* 3642 * - Position generation - 3643 * This block generates everything position related - it's the core of draggables. 3644 */ 3645 3646 //Cache the margins of the original element 3647 this._cacheMargins(); 3648 3649 //Get the next scrolling parent 3650 this.scrollParent = this.helper.scrollParent(); 3651 3652 //The element's absolute position on the page minus margins 3653 this.offset = this.currentItem.offset(); 3654 this.offset = { 3655 top: this.offset.top - this.margins.top, 3656 left: this.offset.left - this.margins.left 3657 }; 3658 3659 $.extend(this.offset, { 3660 click: { //Where the click happened, relative to the element 3661 left: event.pageX - this.offset.left, 3662 top: event.pageY - this.offset.top 3663 }, 3664 parent: this._getParentOffset(), 3665 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3666 }); 3667 3668 // Only after we got the offset, we can change the helper's position to absolute 3669 // TODO: Still need to figure out a way to make relative sorting possible 3670 this.helper.css("position", "absolute"); 3671 this.cssPosition = this.helper.css("position"); 3672 3673 //Generate the original position 3674 this.originalPosition = this._generatePosition(event); 3675 this.originalPageX = event.pageX; 3676 this.originalPageY = event.pageY; 3677 3678 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 3679 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3680 3681 //Cache the former DOM position 3682 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 3683 3684 //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 3685 if(this.helper[0] !== this.currentItem[0]) { 3686 this.currentItem.hide(); 3687 } 3688 3689 //Create the placeholder 3690 this._createPlaceholder(); 3691 3692 //Set a containment if given in the options 3693 if(o.containment) { 3694 this._setContainment(); 3695 } 3696 3697 if( o.cursor && o.cursor !== "auto" ) { // cursor option 3698 body = this.document.find( "body" ); 3699 3700 // support: IE 3701 this.storedCursor = body.css( "cursor" ); 3702 body.css( "cursor", o.cursor ); 3703 3704 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 3705 } 3706 3707 if(o.opacity) { // opacity option 3708 if (this.helper.css("opacity")) { 3709 this._storedOpacity = this.helper.css("opacity"); 3710 } 3711 this.helper.css("opacity", o.opacity); 3712 } 3713 3714 if(o.zIndex) { // zIndex option 3715 if (this.helper.css("zIndex")) { 3716 this._storedZIndex = this.helper.css("zIndex"); 3717 } 3718 this.helper.css("zIndex", o.zIndex); 3719 } 3720 3721 //Prepare scrolling 3722 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3723 this.overflowOffset = this.scrollParent.offset(); 3724 } 3725 3726 //Call callbacks 3727 this._trigger("start", event, this._uiHash()); 3728 3729 //Recache the helper size 3730 if(!this._preserveHelperProportions) { 3731 this._cacheHelperProportions(); 3732 } 3733 3734 3735 //Post "activate" events to possible containers 3736 if( !noActivation ) { 3737 for ( i = this.containers.length - 1; i >= 0; i-- ) { 3738 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 3739 } 3740 } 3741 3742 //Prepare possible droppables 3743 if($.ui.ddmanager) { 3744 $.ui.ddmanager.current = this; 3745 } 3746 3747 if ($.ui.ddmanager && !o.dropBehaviour) { 3748 $.ui.ddmanager.prepareOffsets(this, event); 3749 } 3750 3751 this.dragging = true; 3752 3753 this.helper.addClass("ui-sortable-helper"); 3754 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3755 return true; 3756 3757 }, 3758 3759 _mouseDrag: function(event) { 3760 var i, item, itemElement, intersection, 3761 o = this.options, 3762 scrolled = false; 3763 3764 //Compute the helpers position 3765 this.position = this._generatePosition(event); 3766 this.positionAbs = this._convertPositionTo("absolute"); 3767 3768 if (!this.lastPositionAbs) { 3769 this.lastPositionAbs = this.positionAbs; 3770 } 3771 3772 //Do scrolling 3773 if(this.options.scroll) { 3774 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 3775 3776 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 3777 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 3778 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 3779 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 3780 } 3781 3782 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 3783 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 3784 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 3785 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 3786 } 3787 3788 } else { 3789 3790 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 3791 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 3792 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 3793 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 3794 } 3795 3796 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 3797 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 3798 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 3799 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 3800 } 3801 3802 } 3803 3804 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 3805 $.ui.ddmanager.prepareOffsets(this, event); 3806 } 3807 } 3808 3809 //Regenerate the absolute position used for position checks 3810 this.positionAbs = this._convertPositionTo("absolute"); 3811 3812 //Set the helper position 3813 if(!this.options.axis || this.options.axis !== "y") { 3814 this.helper[0].style.left = this.position.left+"px"; 3815 } 3816 if(!this.options.axis || this.options.axis !== "x") { 3817 this.helper[0].style.top = this.position.top+"px"; 3818 } 3819 3820 //Rearrange 3821 for (i = this.items.length - 1; i >= 0; i--) { 3822 3823 //Cache variables and intersection, continue if no intersection 3824 item = this.items[i]; 3825 itemElement = item.item[0]; 3826 intersection = this._intersectsWithPointer(item); 3827 if (!intersection) { 3828 continue; 3829 } 3830 3831 // Only put the placeholder inside the current Container, skip all 3832 // items form other containers. This works because when moving 3833 // an item from one container to another the 3834 // currentContainer is switched before the placeholder is moved. 3835 // 3836 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 3837 // beetween the outer and inner container. 3838 if (item.instance !== this.currentContainer) { 3839 continue; 3840 } 3841 3842 // cannot intersect with itself 3843 // no useless actions that have been done before 3844 // no action if the item moved is the parent of the item checked 3845 if (itemElement !== this.currentItem[0] && 3846 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 3847 !$.contains(this.placeholder[0], itemElement) && 3848 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 3849 ) { 3850 3851 this.direction = intersection === 1 ? "down" : "up"; 3852 3853 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 3854 this._rearrange(event, item); 3855 } else { 3856 break; 3857 } 3858 3859 this._trigger("change", event, this._uiHash()); 3860 break; 3861 } 3862 } 3863 3864 //Post events to containers 3865 this._contactContainers(event); 3866 3867 //Interconnect with droppables 3868 if($.ui.ddmanager) { 3869 $.ui.ddmanager.drag(this, event); 3870 } 3871 3872 //Call callbacks 3873 this._trigger("sort", event, this._uiHash()); 3874 3875 this.lastPositionAbs = this.positionAbs; 3876 return false; 3877 3878 }, 3879 3880 _mouseStop: function(event, noPropagation) { 3881 3882 if(!event) { 3883 return; 3884 } 3885 3886 //If we are using droppables, inform the manager about the drop 3887 if ($.ui.ddmanager && !this.options.dropBehaviour) { 3888 $.ui.ddmanager.drop(this, event); 3889 } 3890 3891 if(this.options.revert) { 3892 var that = this, 3893 cur = this.placeholder.offset(), 3894 axis = this.options.axis, 3895 animation = {}; 3896 3897 if ( !axis || axis === "x" ) { 3898 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 3899 } 3900 if ( !axis || axis === "y" ) { 3901 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 3902 } 3903 this.reverting = true; 3904 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 3905 that._clear(event); 3906 }); 3907 } else { 3908 this._clear(event, noPropagation); 3909 } 3910 3911 return false; 3912 3913 }, 3914 3915 cancel: function() { 3916 3917 if(this.dragging) { 3918 3919 this._mouseUp({ target: null }); 3920 3921 if(this.options.helper === "original") { 3922 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 3923 } else { 3924 this.currentItem.show(); 3925 } 3926 3927 //Post deactivating events to containers 3928 for (var i = this.containers.length - 1; i >= 0; i--){ 3929 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 3930 if(this.containers[i].containerCache.over) { 3931 this.containers[i]._trigger("out", null, this._uiHash(this)); 3932 this.containers[i].containerCache.over = 0; 3933 } 3934 } 3935 3936 } 3937 3938 if (this.placeholder) { 3939 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 3940 if(this.placeholder[0].parentNode) { 3941 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 3942 } 3943 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 3944 this.helper.remove(); 3945 } 3946 3947 $.extend(this, { 3948 helper: null, 3949 dragging: false, 3950 reverting: false, 3951 _noFinalSort: null 3952 }); 3953 3954 if(this.domPosition.prev) { 3955 $(this.domPosition.prev).after(this.currentItem); 3956 } else { 3957 $(this.domPosition.parent).prepend(this.currentItem); 3958 } 3959 } 3960 3961 return this; 3962 3963 }, 3964 3965 serialize: function(o) { 3966 3967 var items = this._getItemsAsjQuery(o && o.connected), 3968 str = []; 3969 o = o || {}; 3970 3971 $(items).each(function() { 3972 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 3973 if (res) { 3974 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 3975 } 3976 }); 3977 3978 if(!str.length && o.key) { 3979 str.push(o.key + "="); 3980 } 3981 3982 return str.join("&"); 3983 3984 }, 3985 3986 toArray: function(o) { 3987 3988 var items = this._getItemsAsjQuery(o && o.connected), 3989 ret = []; 3990 3991 o = o || {}; 3992 3993 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 3994 return ret; 3995 3996 }, 3997 3998 /* Be careful with the following core functions */ 3999 _intersectsWith: function(item) { 4000 4001 var x1 = this.positionAbs.left, 4002 x2 = x1 + this.helperProportions.width, 4003 y1 = this.positionAbs.top, 4004 y2 = y1 + this.helperProportions.height, 4005 l = item.left, 4006 r = l + item.width, 4007 t = item.top, 4008 b = t + item.height, 4009 dyClick = this.offset.click.top, 4010 dxClick = this.offset.click.left, 4011 isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 4012 4013 if ( this.options.tolerance === "pointer" || 4014 this.options.forcePointerForContainers || 4015 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 4016 ) { 4017 return isOverElement; 4018 } else { 4019 4020 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 4021 x2 - (this.helperProportions.width / 2) < r && // Left Half 4022 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 4023 y2 - (this.helperProportions.height / 2) < b ); // Top Half 4024 4025 } 4026 }, 4027 4028 _intersectsWithPointer: function(item) { 4029 4030 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 4031 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 4032 isOverElement = isOverElementHeight && isOverElementWidth, 4033 verticalDirection = this._getDragVerticalDirection(), 4034 horizontalDirection = this._getDragHorizontalDirection(); 4035 4036 if (!isOverElement) { 4037 return false; 4038 } 4039 4040 return this.floating ? 4041 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 4042 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 4043 4044 }, 4045 4046 _intersectsWithSides: function(item) { 4047 4048 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 4049 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 4050 verticalDirection = this._getDragVerticalDirection(), 4051 horizontalDirection = this._getDragHorizontalDirection(); 4052 4053 if (this.floating && horizontalDirection) { 4054 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 4055 } else { 4056 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 4057 } 4058 4059 }, 4060 4061 _getDragVerticalDirection: function() { 4062 var delta = this.positionAbs.top - this.lastPositionAbs.top; 4063 return delta !== 0 && (delta > 0 ? "down" : "up"); 4064 }, 4065 4066 _getDragHorizontalDirection: function() { 4067 var delta = this.positionAbs.left - this.lastPositionAbs.left; 4068 return delta !== 0 && (delta > 0 ? "right" : "left"); 4069 }, 4070 4071 refresh: function(event) { 4072 this._refreshItems(event); 4073 this.refreshPositions(); 4074 return this; 4075 }, 4076 4077 _connectWith: function() { 4078 var options = this.options; 4079 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 4080 }, 4081 4082 _getItemsAsjQuery: function(connected) { 4083 4084 var i, j, cur, inst, 4085 items = [], 4086 queries = [], 4087 connectWith = this._connectWith(); 4088 4089 if(connectWith && connected) { 4090 for (i = connectWith.length - 1; i >= 0; i--){ 4091 cur = $(connectWith[i]); 4092 for ( j = cur.length - 1; j >= 0; j--){ 4093 inst = $.data(cur[j], this.widgetFullName); 4094 if(inst && inst !== this && !inst.options.disabled) { 4095 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]); 4096 } 4097 } 4098 } 4099 } 4100 4101 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]); 4102 4103 for (i = queries.length - 1; i >= 0; i--){ 4104 queries[i][0].each(function() { 4105 items.push(this); 4106 }); 4107 } 4108 4109 return $(items); 4110 4111 }, 4112 4113 _removeCurrentsFromItems: function() { 4114 4115 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 4116 4117 this.items = $.grep(this.items, function (item) { 4118 for (var j=0; j < list.length; j++) { 4119 if(list[j] === item.item[0]) { 4120 return false; 4121 } 4122 } 4123 return true; 4124 }); 4125 4126 }, 4127 4128 _refreshItems: function(event) { 4129 4130 this.items = []; 4131 this.containers = [this]; 4132 4133 var i, j, cur, inst, targetData, _queries, item, queriesLength, 4134 items = this.items, 4135 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 4136 connectWith = this._connectWith(); 4137 4138 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 4139 for (i = connectWith.length - 1; i >= 0; i--){ 4140 cur = $(connectWith[i]); 4141 for (j = cur.length - 1; j >= 0; j--){ 4142 inst = $.data(cur[j], this.widgetFullName); 4143 if(inst && inst !== this && !inst.options.disabled) { 4144 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 4145 this.containers.push(inst); 4146 } 4147 } 4148 } 4149 } 4150 4151 for (i = queries.length - 1; i >= 0; i--) { 4152 targetData = queries[i][1]; 4153 _queries = queries[i][0]; 4154 4155 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 4156 item = $(_queries[j]); 4157 4158 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 4159 4160 items.push({ 4161 item: item, 4162 instance: targetData, 4163 width: 0, height: 0, 4164 left: 0, top: 0 4165 }); 4166 } 4167 } 4168 4169 }, 4170 4171 refreshPositions: function(fast) { 4172 4173 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 4174 if(this.offsetParent && this.helper) { 4175 this.offset.parent = this._getParentOffset(); 4176 } 4177 4178 var i, item, t, p; 4179 4180 for (i = this.items.length - 1; i >= 0; i--){ 4181 item = this.items[i]; 4182 4183 //We ignore calculating positions of all connected containers when we're not over them 4184 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 4185 continue; 4186 } 4187 4188 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 4189 4190 if (!fast) { 4191 item.width = t.outerWidth(); 4192 item.height = t.outerHeight(); 4193 } 4194 4195 p = t.offset(); 4196 item.left = p.left; 4197 item.top = p.top; 4198 } 4199 4200 if(this.options.custom && this.options.custom.refreshContainers) { 4201 this.options.custom.refreshContainers.call(this); 4202 } else { 4203 for (i = this.containers.length - 1; i >= 0; i--){ 4204 p = this.containers[i].element.offset(); 4205 this.containers[i].containerCache.left = p.left; 4206 this.containers[i].containerCache.top = p.top; 4207 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 4208 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 4209 } 4210 } 4211 4212 return this; 4213 }, 4214 4215 _createPlaceholder: function(that) { 4216 that = that || this; 4217 var className, 4218 o = that.options; 4219 4220 if(!o.placeholder || o.placeholder.constructor === String) { 4221 className = o.placeholder; 4222 o.placeholder = { 4223 element: function() { 4224 4225 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 4226 element = $( that.document[0].createElement( nodeName ) ) 4227 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 4228 .removeClass("ui-sortable-helper"); 4229 4230 if ( nodeName === "tr" ) { 4231 // Use a high colspan to force the td to expand the full 4232 // width of the table (browsers are smart enough to 4233 // handle this properly) 4234 element.append( "<td colspan='99'> </td>" ); 4235 } else if ( nodeName === "img" ) { 4236 element.attr( "src", that.currentItem.attr( "src" ) ); 4237 } 4238 4239 if ( !className ) { 4240 element.css( "visibility", "hidden" ); 4241 } 4242 4243 return element; 4244 }, 4245 update: function(container, p) { 4246 4247 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 4248 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 4249 if(className && !o.forcePlaceholderSize) { 4250 return; 4251 } 4252 4253 //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 4254 if(!p.height()) { p.height(that.currentItem.innerHe
4254ight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 4255 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 4256 } 4257 }; 4258 } 4259 4260 //Create the placeholder 4261 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 4262 4263 //Append it after the actual current item 4264 that.currentItem.after(that.placeholder); 4265 4266 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 4267 o.placeholder.update(that, that.placeholder); 4268 4269 }, 4270 4271 _contactContainers: function(event) { 4272 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 4273 innermostContainer = null, 4274 innermostIndex = null; 4275 4276 // get innermost container that intersects with item 4277 for (i = this.containers.length - 1; i >= 0; i--) { 4278 4279 // never consider a container that's located within the item itself 4280 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 4281 continue; 4282 } 4283 4284 if(this._intersectsWith(this.containers[i].containerCache)) { 4285 4286 // if we've already found a container and it's more "inner" than this, then continue 4287 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 4288 continue; 4289 } 4290 4291 innermostContainer = this.containers[i]; 4292 innermostIndex = i; 4293 4294 } else { 4295 // container doesn't intersect. trigger "out" event if necessary 4296 if(this.containers[i].containerCache.over) { 4297 this.containers[i]._trigger("out", event, this._uiHash(this)); 4298 this.containers[i].containerCache.over = 0; 4299 } 4300 } 4301 4302 } 4303 4304 // if no intersecting containers found, return 4305 if(!innermostContainer) { 4306 return; 4307 } 4308 4309 // move the item into the container if it's not there already 4310 if(this.containers.length === 1) { 4311 if (!this.containers[innermostIndex].containerCache.over) { 4312 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4313 this.containers[innermostIndex].containerCache.over = 1; 4314 } 4315 } else { 4316 4317 //When entering a new container, we will find the item with the least distance and append our item near it 4318 dist = 10000; 4319 itemWithLeastDistance = null; 4320 floating = innermostContainer.floating || isFloating(this.currentItem); 4321 posProperty = floating ? "left" : "top"; 4322 sizeProperty = floating ? "width" : "height"; 4323 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 4324 for (j = this.items.length - 1; j >= 0; j--) { 4325 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 4326 continue; 4327 } 4328 if(this.items[j].item[0] === this.currentItem[0]) { 4329 continue; 4330 } 4331 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 4332 continue; 4333 } 4334 cur = this.items[j].item.offset()[posProperty]; 4335 nearBottom = false; 4336 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 4337 nearBottom = true; 4338 cur += this.items[j][sizeProperty]; 4339 } 4340 4341 if(Math.abs(cur - base) < dist) { 4342 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
vendor: 106,930 bytes, lines 4343-6957
4343 this.direction = nearBottom ? "up": "down"; 4344 } 4345 } 4346 4347 //Check if dropOnEmpty is enabled 4348 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 4349 return; 4350 } 4351 4352 if(this.currentContainer === this.containers[innermostIndex]) { 4353 return; 4354 } 4355 4356 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 4357 this._trigger("change", event, this._uiHash()); 4358 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 4359 this.currentContainer = this.containers[innermostIndex]; 4360 4361 //Update the placeholder 4362 this.options.placeholder.update(this.currentContainer, this.placeholder); 4363 4364 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 4365 this.containers[innermostIndex].containerCache.over = 1; 4366 } 4367 4368 4369 }, 4370 4371 _createHelper: function(event) { 4372 4373 var o = this.options, 4374 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 4375 4376 //Add the helper to the DOM if that didn't happen already 4377 if(!helper.parents("body").length) { 4378 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 4379 } 4380 4381 if(helper[0] === this.currentItem[0]) { 4382 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") }; 4383 } 4384 4385 if(!helper[0].style.width || o.forceHelperSize) { 4386 helper.width(this.currentItem.width()); 4387 } 4388 if(!helper[0].style.height || o.forceHelperSize) { 4389 helper.height(this.currentItem.height()); 4390 } 4391 4392 return helper; 4393 4394 }, 4395 4396 _adjustOffsetFromHelper: function(obj) { 4397 if (typeof obj === "string") { 4398 obj = obj.split(" "); 4399 } 4400 if ($.isArray(obj)) { 4401 obj = {left: +obj[0], top: +obj[1] || 0}; 4402 } 4403 if ("left" in obj) { 4404 this.offset.click.left = obj.left + this.margins.left; 4405 } 4406 if ("right" in obj) { 4407 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4408 } 4409 if ("top" in obj) { 4410 this.offset.click.top = obj.top + this.margins.top; 4411 } 4412 if ("bottom" in obj) { 4413 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4414 } 4415 }, 4416 4417 _getParentOffset: function() { 4418 4419 4420 //Get the offsetParent and cache its position 4421 this.offsetParent = this.helper.offsetParent(); 4422 var po = this.offsetParent.offset(); 4423 4424 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4425 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4426 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4427 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4428 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4429 po.left += this.scrollParent.scrollLeft(); 4430 po.top += this.scrollParent.scrollTop(); 4431 } 4432 4433 // This needs to be actually done for all browsers, since pageX/pageY includes this information 4434 // with an ugly IE fix 4435 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 4436 po = { top: 0, left: 0 }; 4437 } 4438 4439 return { 4440 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4441 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4442 }; 4443 4444 }, 4445 4446 _getRelativeOffset: function() { 4447 4448 if(this.cssPosition === "relative") { 4449 var p = this.currentItem.position(); 4450 return { 4451 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4452 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4453 }; 4454 } else { 4455 return { top: 0, left: 0 }; 4456 } 4457 4458 }, 4459 4460 _cacheMargins: function() { 4461 this.margins = { 4462 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 4463 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 4464 }; 4465 }, 4466 4467 _cacheHelperProportions: function() { 4468 this.helperProportions = { 4469 width: this.helper.outerWidth(), 4470 height: this.helper.outerHeight() 4471 }; 4472 }, 4473 4474 _setContainment: function() { 4475 4476 var ce, co, over, 4477 o = this.options; 4478 if(o.containment === "parent") { 4479 o.containment = this.helper[0].parentNode; 4480 } 4481 if(o.containment === "document" || o.containment === "window") { 4482 this.containment = [ 4483 0 - this.offset.relative.left - this.offset.parent.left, 4484 0 - this.offset.relative.top - this.offset.parent.top, 4485 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 4486 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4487 ]; 4488 } 4489 4490 if(!(/^(document|window|parent)$/).test(o.containment)) { 4491 ce = $(o.containment)[0]; 4492 co = $(o.containment).offset(); 4493 over = ($(ce).css("overflow") !== "hidden"); 4494 4495 this.containment = [ 4496 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 4497 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 4498 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, 4499 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 4500 ]; 4501 } 4502 4503 }, 4504 4505 _convertPositionTo: function(d, pos) { 4506 4507 if(!pos) { 4508 pos = this.position; 4509 } 4510 var mod = d === "absolute" ? 1 : -1, 4511 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 4512 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 4513 4514 return { 4515 top: ( 4516 pos.top + // The absolute mouse position 4517 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4518 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 4519 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4520 ), 4521 left: ( 4522 pos.left + // The absolute mouse position 4523 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 4524 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 4525 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4526 ) 4527 }; 4528 4529 }, 4530 4531 _generatePosition: function(event) { 4532 4533 var top, left, 4534 o = this.options, 4535 pageX = event.pageX, 4536 pageY = event.pageY, 4537 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); 4538 4539 // This is another very weird special case that only happens for relative elements: 4540 // 1. If the css position is relative 4541 // 2. and the scroll parent is the document or similar to the offset parent 4542 // we have to refresh the relative offset during the scroll so there are no jumps 4543 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 4544 this.offset.relative = this._getRelativeOffset(); 4545 } 4546 4547 /* 4548 * - Position constraining - 4549 * Constrain the position to a mix of grid, containment. 4550 */ 4551 4552 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4553 4554 if(this.containment) { 4555 if(event.pageX - this.offset.click.left < this.containment[0]) { 4556 pageX = this.containment[0] + this.offset.click.left; 4557 } 4558 if(event.pageY - this.offset.click.top < this.containment[1]) { 4559 pageY = this.containment[1] + this.offset.click.top; 4560 } 4561 if(event.pageX - this.offset.click.left > this.containment[2]) { 4562 pageX = this.containment[2] + this.offset.click.left; 4563 } 4564 if(event.pageY - this.offset.click.top > this.containment[3]) { 4565 pageY = this.containment[3] + this.offset.click.top; 4566 } 4567 } 4568 4569 if(o.grid) { 4570 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 4571 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; 4572 4573 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 4574 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; 4575 } 4576 4577 } 4578 4579 return { 4580 top: ( 4581 pageY - // The absolute mouse position 4582 this.offset.click.top - // Click offset (relative to the element) 4583 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 4584 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 4585 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4586 ), 4587 left: ( 4588 pageX - // The absolute mouse position 4589 this.offset.click.left - // Click offset (relative to the element) 4590 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 4591 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 4592 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4593 ) 4594 }; 4595 4596 }, 4597 4598 _rearrange: function(event, i, a, hardRefresh) { 4599 4600 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)); 4601 4602 //Various things done here to improve the performance: 4603 // 1. we create a setTimeout, that calls refreshPositions 4604 // 2. on the instance, we have a counter variable, that get's higher after every append 4605 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 4606 // 4. this lets only the last addition to the timeout stack through 4607 this.counter = this.counter ? ++this.counter : 1; 4608 var counter = this.counter; 4609 4610 this._delay(function() { 4611 if(counter === this.counter) { 4612 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 4613 } 4614 }); 4615 4616 }, 4617 4618 _clear: function(event, noPropagation) { 4619 4620 this.reverting = false; 4621 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 4622 // everything else normalized again 4623 var i, 4624 delayedTriggers = []; 4625 4626 // We first have to update the dom position of the actual currentItem 4627 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 4628 if(!this._noFinalSort && this.currentItem.parent().length) { 4629 this.placeholder.before(this.currentItem); 4630 } 4631 this._noFinalSort = null; 4632 4633 if(this.helper[0] === this.currentItem[0]) { 4634 for(i in this._storedCSS) { 4635 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 4636 this._storedCSS[i] = ""; 4637 } 4638 } 4639 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 4640 } else { 4641 this.currentItem.show(); 4642 } 4643 4644 if(this.fromOutside && !noPropagation) { 4645 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 4646 } 4647 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 4648 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 4649 } 4650 4651 // Check if the items Container has Changed and trigger appropriate 4652 // events. 4653 if (this !== this.currentContainer) { 4654 if(!noPropagation) { 4655 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 4656 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4657 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 4658 } 4659 } 4660 4661 4662 //Post events to containers 4663 for (i = this.containers.length - 1; i >= 0; i--){ 4664 if(!noPropagation) { 4665 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4666 } 4667 if(this.containers[i].containerCache.over) { 4668 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 4669 this.containers[i].containerCache.over = 0; 4670 } 4671 } 4672 4673 //Do what was originally in plugins 4674 if ( this.storedCursor ) { 4675 this.document.find( "body" ).css( "cursor", this.storedCursor ); 4676 this.storedStylesheet.remove(); 4677 } 4678 if(this._storedOpacity) { 4679 this.helper.css("opacity", this._storedOpacity); 4680 } 4681 if(this._storedZIndex) { 4682 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 4683 } 4684 4685 this.dragging = false; 4686 if(this.cancelHelperRemoval) { 4687 if(!noPropagation) { 4688 this._trigger("beforeStop", event, this._uiHash()); 4689 for (i=0; i < delayedTriggers.length; i++) { 4690 delayedTriggers[i].call(this, event); 4691 } //Trigger all delayed events 4692 this._trigger("stop", event, this._uiHash()); 4693 } 4694 4695 this.fromOutside = false; 4696 return false; 4697 } 4698 4699 if(!noPropagation) { 4700 this._trigger("beforeStop", event, this._uiHash()); 4701 } 4702 4703 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 4704 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 4705 4706 if(this.helper[0] !== this.currentItem[0]) { 4707 this.helper.remove(); 4708 } 4709 this.helper = null; 4710 4711 if(!noPropagation) { 4712 for (i=0; i < delayedTriggers.length; i++) { 4713 delayedTriggers[i].call(this, event); 4714 } //Trigger all delayed events 4715 this._trigger("stop", event, this._uiHash()); 4716 } 4717 4718 this.fromOutside = false; 4719 return true; 4720 4721 }, 4722 4723 _trigger: function() { 4724 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 4725 this.cancel(); 4726 } 4727 }, 4728 4729 _uiHash: function(_inst) { 4730 var inst = _inst || this; 4731 return { 4732 helper: inst.helper, 4733 placeholder: inst.placeholder || $([]), 4734 position: inst.position, 4735 originalPosition: inst.originalPosition, 4736 offset: inst.positionAbs, 4737 item: inst.currentItem, 4738 sender: _inst ? _inst.element : null 4739 }; 4740 } 4741 4742 }); 4743 4744})(jQuery); 4745 4746(function($, undefined) { 4747 4748 var dataSpace = "ui-effects-"; 4749 4750 $.effects = { 4751 effect: {} 4752 }; 4753 4754 /*! 4755 * jQuery Color Animations v2.1.2 4756 * https://github.com/jquery/jquery-color 4757 * 4758 * Copyright 2013 jQuery Foundation and other contributors 4759 * Released under the MIT license. 4760 * http://jquery.org/license 4761 * 4762 * Date: Wed Jan 16 08:47:09 2013 -0600 4763 */ 4764 (function( jQuery, undefined ) { 4765 4766 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 4767 4768 // plusequals test for += 100 -= 100 4769 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 4770 // a set of RE's that can match strings and generate color tuples. 4771 stringParsers = [{ 4772 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4773 parse: function( execResult ) { 4774 return [ 4775 execResult[ 1 ], 4776 execResult[ 2 ], 4777 execResult[ 3 ], 4778 execResult[ 4 ] 4779 ]; 4780 } 4781 }, { 4782 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4783 parse: function( execResult ) { 4784 return [ 4785 execResult[ 1 ] * 2.55, 4786 execResult[ 2 ] * 2.55, 4787 execResult[ 3 ] * 2.55, 4788 execResult[ 4 ] 4789 ]; 4790 } 4791 }, { 4792 // this regex ignores A-F because it's compared against an already lowercased string 4793 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 4794 parse: function( execResult ) { 4795 return [ 4796 parseInt( execResult[ 1 ], 16 ), 4797 parseInt( execResult[ 2 ], 16 ), 4798 parseInt( execResult[ 3 ], 16 ) 4799 ]; 4800 } 4801 }, { 4802 // this regex ignores A-F because it's compared against an already lowercased string 4803 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 4804 parse: function( execResult ) { 4805 return [ 4806 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 4807 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 4808 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 4809 ]; 4810 } 4811 }, { 4812 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 4813 space: "hsla", 4814 parse: function( execResult ) { 4815 return [ 4816 execResult[ 1 ], 4817 execResult[ 2 ] / 100, 4818 execResult[ 3 ] / 100, 4819 execResult[ 4 ] 4820 ]; 4821 } 4822 }], 4823 4824 // jQuery.Color( ) 4825 color = jQuery.Color = function( color, green, blue, alpha ) { 4826 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 4827 }, 4828 spaces = { 4829 rgba: { 4830 props: { 4831 red: { 4832 idx: 0, 4833 type: "byte" 4834 }, 4835 green: { 4836 idx: 1, 4837 type: "byte" 4838 }, 4839 blue: { 4840 idx: 2, 4841 type: "byte" 4842 } 4843 } 4844 }, 4845 4846 hsla: { 4847 props: { 4848 hue: { 4849 idx: 0, 4850 type: "degrees" 4851 }, 4852 saturation: { 4853 idx: 1, 4854 type: "percent" 4855 }, 4856 lightness: { 4857 idx: 2, 4858 type: "percent" 4859 } 4860 } 4861 } 4862 }, 4863 propTypes = { 4864 "byte": { 4865 floor: true, 4866 max: 255 4867 }, 4868 "percent": { 4869 max: 1 4870 }, 4871 "degrees": { 4872 mod: 360, 4873 floor: true 4874 } 4875 }, 4876 support = color.support = {}, 4877 4878 // element for support tests 4879 supportElem = jQuery( "<p>" )[ 0 ], 4880 4881 // colors = jQuery.Color.names 4882 colors, 4883 4884 // local aliases of functions called often 4885 each = jQuery.each; 4886 4887// determine rgba support immediately 4888 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 4889 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 4890 4891// define cache name and alpha properties 4892// for rgba and hsla spaces 4893 each( spaces, function( spaceName, space ) { 4894 space.cache = "_" + spaceName; 4895 space.props.alpha = { 4896 idx: 3, 4897 type: "percent", 4898 def: 1 4899 }; 4900 }); 4901 4902 function clamp( value, prop, allowEmpty ) { 4903 var type = propTypes[ prop.type ] || {}; 4904 4905 if ( value == null ) { 4906 return (allowEmpty || !prop.def) ? null : prop.def; 4907 } 4908 4909 // ~~ is an short way of doing floor for positive numbers 4910 value = type.floor ? ~~value : parseFloat( value ); 4911 4912 // IE will pass in empty strings as value for alpha, 4913 // which will hit this case 4914 if ( isNaN( value ) ) { 4915 return prop.def; 4916 } 4917 4918 if ( type.mod ) { 4919 // we add mod before modding to make sure that negatives values 4920 // get converted properly: -10 -> 350 4921 return (value + type.mod) % type.mod; 4922 } 4923 4924 // for now all property types without mod have min and max 4925 return 0 > value ? 0 : type.max < value ? type.max : value; 4926 } 4927 4928 function stringParse( string ) { 4929 var inst = color(), 4930 rgba = inst._rgba = []; 4931 4932 string = string.toLowerCase(); 4933 4934 each( stringParsers, function( i, parser ) { 4935 var parsed, 4936 match = parser.re.exec( string ), 4937 values = match && parser.parse( match ), 4938 spaceName = parser.space || "rgba"; 4939 4940 if ( values ) { 4941 parsed = inst[ spaceName ]( values ); 4942 4943 // if this was an rgba parse the assignment might happen twice 4944 // oh well.... 4945 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 4946 rgba = inst._rgba = parsed._rgba; 4947 4948 // exit each( stringParsers ) here because we matched 4949 return false; 4950 } 4951 }); 4952 4953 // Found a stringParser that handled it 4954 if ( rgba.length ) { 4955 4956 // if this came from a parsed string, force "transparent" when alpha is 0 4957 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 4958 if ( rgba.join() === "0,0,0,0" ) { 4959 jQuery.extend( rgba, colors.transparent ); 4960 } 4961 return inst; 4962 } 4963 4964 // named colors 4965 return colors[ string ]; 4966 } 4967 4968 color.fn = jQuery.extend( color.prototype, { 4969 parse: function( red, green, blue, alpha ) { 4970 if ( red === undefined ) { 4971 this._rgba = [ null, null, null, null ]; 4972 return this; 4973 } 4974 if ( red.jquery || red.nodeType ) { 4975 red = jQuery( red ).css( green ); 4976 green = undefined; 4977 } 4978 4979 var inst = this, 4980 type = jQuery.type( red ), 4981 rgba = this._rgba = []; 4982 4983 // more than 1 argument specified - assume ( red, green, blue, alpha ) 4984 if ( green !== undefined ) { 4985 red = [ red, green, blue, alpha ]; 4986 type = "array"; 4987 } 4988 4989 if ( type === "string" ) { 4990 return this.parse( stringParse( red ) || colors._default ); 4991 } 4992 4993 if ( type === "array" ) { 4994 each( spaces.rgba.props, function( key, prop ) { 4995 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 4996 }); 4997 return this; 4998 } 4999 5000 if ( type === "object" ) { 5001 if ( red instanceof color ) { 5002 each( spaces, function( spaceName, space ) { 5003 if ( red[ space.cache ] ) { 5004 inst[ space.cache ] = red[ space.cache ].slice(); 5005 } 5006 }); 5007 } else { 5008 each( spaces, function( spaceName, space ) { 5009 var cache = space.cache; 5010 each( space.props, function( key, prop ) { 5011 5012 // if the cache doesn't exist, and we know how to convert 5013 if ( !inst[ cache ] && space.to ) { 5014 5015 // if the value was null, we don't need to copy it 5016 // if the key was alpha, we don't need to copy it either 5017 if ( key === "alpha" || red[ key ] == null ) { 5018 return; 5019 } 5020 inst[ cache ] = space.to( inst._rgba ); 5021 } 5022 5023 // this is the only case where we allow nulls for ALL properties. 5024 // call clamp with alwaysAllowEmpty 5025 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 5026 }); 5027 5028 // everything defined but alpha? 5029 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 5030 // use the default of 1 5031 inst[ cache ][ 3 ] = 1; 5032 if ( space.from ) { 5033 inst._rgba = space.from( inst[ cache ] ); 5034 } 5035 } 5036 }); 5037 } 5038 return this; 5039 } 5040 }, 5041 is: function( compare ) { 5042 var is = color( compare ), 5043 same = true, 5044 inst = this; 5045 5046 each( spaces, function( _, space ) { 5047 var localCache, 5048 isCache = is[ space.cache ]; 5049 if (isCache) { 5050 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 5051 each( space.props, function( _, prop ) { 5052 if ( isCache[ prop.idx ] != null ) { 5053 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 5054 return same; 5055 } 5056 }); 5057 } 5058 return same; 5059 }); 5060 return same; 5061 }, 5062 _space: function() { 5063 var used = [], 5064 inst = this; 5065 each( spaces, function( spaceName, space ) { 5066 if ( inst[ space.cache ] ) { 5067 used.push( spaceName ); 5068 } 5069 }); 5070 return used.pop(); 5071 }, 5072 transition: function( other, distance ) { 5073 var end = color( other ), 5074 spaceName = end._space(), 5075 space = spaces[ spaceName ], 5076 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 5077 start = startColor[ space.cache ] || space.to( startColor._rgba ), 5078 result = start.slice(); 5079 5080 end = end[ space.cache ]; 5081 each( space.props, function( key, prop ) { 5082 var index = prop.idx, 5083 startValue = start[ index ], 5084 endValue = end[ index ], 5085 type = propTypes[ prop.type ] || {}; 5086 5087 // if null, don't override start value 5088 if ( endValue === null ) { 5089 return; 5090 } 5091 // if null - use end 5092 if ( startValue === null ) { 5093 result[ index ] = endValue; 5094 } else { 5095 if ( type.mod ) { 5096 if ( endValue - startValue > type.mod / 2 ) { 5097 startValue += type.mod; 5098 } else if ( startValue - endValue > type.mod / 2 ) { 5099 startValue -= type.mod; 5100 } 5101 } 5102 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 5103 } 5104 }); 5105 return this[ spaceName ]( result ); 5106 }, 5107 blend: function( opaque ) { 5108 // if we are already opaque - return ourself 5109 if ( this._rgba[ 3 ] === 1 ) { 5110 return this; 5111 } 5112 5113 var rgb = this._rgba.slice(), 5114 a = rgb.pop(), 5115 blend = color( opaque )._rgba; 5116 5117 return color( jQuery.map( rgb, function( v, i ) { 5118 return ( 1 - a ) * blend[ i ] + a * v; 5119 })); 5120 }, 5121 toRgbaString: function() { 5122 var prefix = "rgba(", 5123 rgba = jQuery.map( this._rgba, function( v, i ) { 5124 return v == null ? ( i > 2 ? 1 : 0 ) : v; 5125 }); 5126 5127 if ( rgba[ 3 ] === 1 ) { 5128 rgba.pop(); 5129 prefix = "rgb("; 5130 } 5131 5132 return prefix + rgba.join() + ")"; 5133 }, 5134 toHslaString: function() { 5135 var prefix = "hsla(", 5136 hsla = jQuery.map( this.hsla(), function( v, i ) { 5137 if ( v == null ) { 5138 v = i > 2 ? 1 : 0; 5139 } 5140 5141 // catch 1 and 2 5142 if ( i && i < 3 ) { 5143 v = Math.round( v * 100 ) + "%"; 5144 } 5145 return v; 5146 }); 5147 5148 if ( hsla[ 3 ] === 1 ) { 5149 hsla.pop(); 5150 prefix = "hsl("; 5151 } 5152 return prefix + hsla.join() + ")"; 5153 }, 5154 toHexString: function( includeAlpha ) { 5155 var rgba = this._rgba.slice(), 5156 alpha = rgba.pop(); 5157 5158 if ( includeAlpha ) { 5159 rgba.push( ~~( alpha * 255 ) ); 5160 } 5161 5162 return "#" + jQuery.map( rgba, function( v ) { 5163 5164 // default to 0 when nulls exist 5165 v = ( v || 0 ).toString( 16 ); 5166 return v.length === 1 ? "0" + v : v; 5167 }).join(""); 5168 }, 5169 toString: function() { 5170 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 5171 } 5172 }); 5173 color.fn.parse.prototype = color.fn; 5174 5175// hsla conversions adapted from: 5176// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 5177 5178 function hue2rgb( p, q, h ) { 5179 h = ( h + 1 ) % 1; 5180 if ( h * 6 < 1 ) { 5181 return p + (q - p) * h * 6; 5182 } 5183 if ( h * 2 < 1) { 5184 return q; 5185 } 5186 if ( h * 3 < 2 ) { 5187 return p + (q - p) * ((2/3) - h) * 6; 5188 } 5189 return p; 5190 } 5191 5192 spaces.hsla.to = function ( rgba ) { 5193 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 5194 return [ null, null, null, rgba[ 3 ] ]; 5195 } 5196 var r = rgba[ 0 ] / 255, 5197 g = rgba[ 1 ] / 255, 5198 b = rgba[ 2 ] / 255, 5199 a = rgba[ 3 ], 5200 max = Math.max( r, g, b ), 5201 min = Math.min( r, g, b ), 5202 diff = max - min, 5203 add = max + min, 5204 l = add * 0.5, 5205 h, s; 5206 5207 if ( min === max ) { 5208 h = 0; 5209 } else if ( r === max ) { 5210 h = ( 60 * ( g - b ) / diff ) + 360; 5211 } else if ( g === max ) { 5212 h = ( 60 * ( b - r ) / diff ) + 120; 5213 } else { 5214 h = ( 60 * ( r - g ) / diff ) + 240; 5215 } 5216 5217 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 5218 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 5219 if ( diff === 0 ) { 5220 s = 0; 5221 } else if ( l <= 0.5 ) { 5222 s = diff / add; 5223 } else { 5224 s = diff / ( 2 - add ); 5225 } 5226 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 5227 }; 5228 5229 spaces.hsla.from = function ( hsla ) { 5230 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 5231 return [ null, null, null, hsla[ 3 ] ]; 5232 } 5233 var h = hsla[ 0 ] / 360, 5234 s = hsla[ 1 ], 5235 l = hsla[ 2 ], 5236 a = hsla[ 3 ], 5237 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 5238 p = 2 * l - q; 5239 5240 return [ 5241 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 5242 Math.round( hue2rgb( p, q, h ) * 255 ), 5243 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 5244 a 5245 ]; 5246 }; 5247 5248 5249 each( spaces, function( spaceName, space ) { 5250 var props = space.props, 5251 cache = space.cache, 5252 to = space.to, 5253 from = space.from; 5254 5255 // makes rgba() and hsla() 5256 color.fn[ spaceName ] = function( value ) { 5257 5258 // generate a cache for this space if it doesn't exist 5259 if ( to && !this[ cache ] ) { 5260 this[ cache ] = to( this._rgba ); 5261 } 5262 if ( value === undefined ) { 5263 return this[ cache ].slice(); 5264 } 5265 5266 var ret, 5267 type = jQuery.type( value ), 5268 arr = ( type === "array" || type === "object" ) ? value : arguments, 5269 local = this[ cache ].slice(); 5270 5271 each( props, function( key, prop ) { 5272 var val = arr[ type === "object" ? key : prop.idx ]; 5273 if ( val == null ) { 5274 val = local[ prop.idx ]; 5275 } 5276 local[ prop.idx ] = clamp( val, prop ); 5277 }); 5278 5279 if ( from ) { 5280 ret = color( from( local ) ); 5281 ret[ cache ] = local; 5282 return ret; 5283 } else { 5284 return color( local ); 5285 } 5286 }; 5287 5288 // makes red() green() blue() alpha() hue() saturation() lightness() 5289 each( props, function( key, prop ) { 5290 // alpha is included in more than one space 5291 if ( color.fn[ key ] ) { 5292 return; 5293 } 5294 color.fn[ key ] = function( value ) { 5295 var vtype = jQuery.type( value ), 5296 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 5297 local = this[ fn ](), 5298 cur = local[ prop.idx ], 5299 match; 5300 5301 if ( vtype === "undefined" ) { 5302 return cur; 5303 } 5304 5305 if ( vtype === "function" ) { 5306 value = value.call( this, cur ); 5307 vtype = jQuery.type( value ); 5308 } 5309 if ( value == null && prop.empty ) { 5310 return this; 5311 } 5312 if ( vtype === "string" ) { 5313 match = rplusequals.exec( value ); 5314 if ( match ) { 5315 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 5316 } 5317 } 5318 local[ prop.idx ] = value; 5319 return this[ fn ]( local ); 5320 }; 5321 }); 5322 }); 5323 5324// add cssHook and .fx.step function for each named hook. 5325// accept a space separated string of properties 5326 color.hook = function( hook ) { 5327 var hooks = hook.split( " " ); 5328 each( hooks, function( i, hook ) { 5329 jQuery.cssHooks[ hook ] = { 5330 set: function( elem, value ) { 5331 var parsed, curElem, 5332 backgroundColor = ""; 5333 5334 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 5335 value = color( parsed || value ); 5336 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 5337 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 5338 while ( 5339 (backgroundColor === "" || backgroundColor === "transparent") && 5340 curElem && curElem.style 5341 ) { 5342 try { 5343 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 5344 curElem = curElem.parentNode; 5345 } catch ( e ) { 5346 } 5347 } 5348 5349 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 5350 backgroundColor : 5351 "_default" ); 5352 } 5353 5354 value = value.toRgbaString(); 5355 } 5356 try { 5357 elem.style[ hook ] = value; 5358 } catch( e ) { 5359 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 5360 } 5361 } 5362 }; 5363 jQuery.fx.step[ hook ] = function( fx ) { 5364 if ( !fx.colorInit ) { 5365 fx.start = color( fx.elem, hook ); 5366 fx.end = color( fx.end ); 5367 fx.colorInit = true; 5368 } 5369 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 5370 }; 5371 }); 5372 5373 }; 5374 5375 color.hook( stepHooks ); 5376 5377 jQuery.cssHooks.borderColor = { 5378 expand: function( value ) { 5379 var expanded = {}; 5380 5381 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 5382 expanded[ "border" + part + "Color" ] = value; 5383 }); 5384 return expanded; 5385 } 5386 }; 5387 5388// Basic color names only. 5389// Usage of any of the other color names requires adding yourself or including 5390// jquery.color.svg-names.js. 5391 colors = jQuery.Color.names = { 5392 // 4.1. Basic color keywords 5393 aqua: "#00ffff", 5394 black: "#000000", 5395 blue: "#0000ff", 5396 fuchsia: "#ff00ff", 5397 gray: "#808080", 5398 green: "#008000", 5399 lime: "#00ff00", 5400 maroon: "#800000", 5401 navy: "#000080", 5402 olive: "#808000", 5403 purple: "#800080", 5404 red: "#ff0000", 5405 silver: "#c0c0c0", 5406 teal: "#008080", 5407 white: "#ffffff", 5408 yellow: "#ffff00", 5409 5410 // 4.2.3. "transparent" color keyword 5411 transparent: [ null, null, null, 0 ], 5412 5413 _default: "#ffffff" 5414 }; 5415 5416 })( jQuery ); 5417 5418 5419 /******************************************************************************/ 5420 /****************************** CLASS ANIMATIONS ******************************/ 5421 /******************************************************************************/ 5422 (function() { 5423 5424 var classAnimationActions = [ "add", "remove", "toggle" ], 5425 shorthandStyles = { 5426 border: 1, 5427 borderBottom: 1, 5428 borderColor: 1, 5429 borderLeft: 1, 5430 borderRight: 1, 5431 borderTop: 1, 5432 borderWidth: 1, 5433 margin: 1, 5434 padding: 1 5435 }; 5436 5437 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 5438 $.fx.step[ prop ] = function( fx ) { 5439 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 5440 jQuery.style( fx.elem, prop, fx.end ); 5441 fx.setAttr = true; 5442 } 5443 }; 5444 }); 5445 5446 function getElementStyles( elem ) { 5447 var key, len, 5448 style = elem.ownerDocument.defaultView ? 5449 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 5450 elem.currentStyle, 5451 styles = {}; 5452 5453 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 5454 len = style.length; 5455 while ( len-- ) { 5456 key = style[ len ]; 5457 if ( typeof style[ key ] === "string" ) { 5458 styles[ $.camelCase( key ) ] = style[ key ]; 5459 } 5460 } 5461 // support: Opera, IE <9 5462 } else { 5463 for ( key in style ) { 5464 if ( typeof style[ key ] === "string" ) { 5465 styles[ key ] = style[ key ]; 5466 } 5467 } 5468 } 5469 5470 return styles; 5471 } 5472 5473 5474 function styleDifference( oldStyle, newStyle ) { 5475 var diff = {}, 5476 name, value; 5477 5478 for ( name in newStyle ) { 5479 value = newStyle[ name ]; 5480 if ( oldStyle[ name ] !== value ) { 5481 if ( !shorthandStyles[ name ] ) { 5482 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 5483 diff[ name ] = value; 5484 } 5485 } 5486 } 5487 } 5488 5489 return diff; 5490 } 5491 5492// support: jQuery <1.8 5493 if ( !$.fn.addBack ) { 5494 $.fn.addBack = function( selector ) { 5495 return this.add( selector == null ? 5496 this.prevObject : this.prevObject.filter( selector ) 5497 ); 5498 }; 5499 } 5500 5501 $.effects.animateClass = function( value, duration, easing, callback ) { 5502 var o = $.speed( duration, easing, callback ); 5503 5504 return this.queue( function() { 5505 var animated = $( this ), 5506 baseClass = animated.attr( "class" ) || "", 5507 applyClassChange, 5508 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 5509 5510 // map the animated objects to store the original styles. 5511 allAnimations = allAnimations.map(function() { 5512 var el = $( this ); 5513 return { 5514 el: el, 5515 start: getElementStyles( this ) 5516 }; 5517 }); 5518 5519 // apply class change 5520 applyClassChange = function() { 5521 $.each( classAnimationActions, function(i, action) { 5522 if ( value[ action ] ) { 5523 animated[ action + "Class" ]( value[ action ] ); 5524 } 5525 }); 5526 }; 5527 applyClassChange(); 5528 5529 // map all animated objects again - calculate new styles and diff 5530 allAnimations = allAnimations.map(function() { 5531 this.end = getElementStyles( this.el[ 0 ] ); 5532 this.diff = styleDifference( this.start, this.end ); 5533 return this; 5534 }); 5535 5536 // apply original class 5537 animated.attr( "class", baseClass ); 5538 5539 // map all animated objects again - this time collecting a promise 5540 allAnimations = allAnimations.map(function() { 5541 var styleInfo = this, 5542 dfd = $.Deferred(), 5543 opts = $.extend({}, o, { 5544 queue: false, 5545 complete: function() { 5546 dfd.resolve( styleInfo ); 5547 } 5548 }); 5549 5550 this.el.animate( this.diff, opts ); 5551 return dfd.promise(); 5552 }); 5553 5554 // once all animations have completed: 5555 $.when.apply( $, allAnimations.get() ).done(function() { 5556 5557 // set the final class 5558 applyClassChange(); 5559 5560 // for each animated element, 5561 // clear all css properties that were animated 5562 $.each( arguments, function() { 5563 var el = this.el; 5564 $.each( this.diff, function(key) { 5565 el.css( key, "" ); 5566 }); 5567 }); 5568 5569 // this is guarnteed to be there if you use jQuery.speed() 5570 // it also handles dequeuing the next anim... 5571 o.complete.call( animated[ 0 ] ); 5572 }); 5573 }); 5574 }; 5575 5576 $.fn.extend({ 5577 addClass: (function( orig ) { 5578 return function( classNames, speed, easing, callback ) { 5579 return speed ? 5580 $.effects.animateClass.call( this, 5581 { add: classNames }, speed, easing, callback ) : 5582 orig.apply( this, arguments ); 5583 }; 5584 })( $.fn.addClass ), 5585 5586 removeClass: (function( orig ) { 5587 return function( classNames, speed, easing, callback ) { 5588 return arguments.length > 1 ? 5589 $.effects.animateClass.call( this, 5590 { remove: classNames }, speed, easing, callback ) : 5591 orig.apply( this, arguments ); 5592 }; 5593 })( $.fn.removeClass ), 5594 5595 toggleClass: (function( orig ) { 5596 return function( classNames, force, speed, easing, callback ) { 5597 if ( typeof force === "boolean" || force === undefined ) { 5598 if ( !speed ) { 5599 // without speed parameter 5600 return orig.apply( this, arguments ); 5601 } else { 5602 return $.effects.animateClass.call( this, 5603 (force ? { add: classNames } : { remove: classNames }), 5604 speed, easing, callback ); 5605 } 5606 } else { 5607 // without force parameter 5608 return $.effects.animateClass.call( this, 5609 { toggle: classNames }, force, speed, easing ); 5610 } 5611 }; 5612 })( $.fn.toggleClass ), 5613 5614 switchClass: function( remove, add, speed, easing, callback) { 5615 return $.effects.animateClass.call( this, { 5616 add: add, 5617 remove: remove 5618 }, speed, easing, callback ); 5619 } 5620 }); 5621 5622 })(); 5623 5624 /******************************************************************************/ 5625 /*********************************** EFFECTS **********************************/ 5626 /******************************************************************************/ 5627 5628 (function() { 5629 5630 $.extend( $.effects, { 5631 version: "1.10.2", 5632 5633 // Saves a set of properties in a data storage 5634 save: function( element, set ) { 5635 for( var i=0; i < set.length; i++ ) { 5636 if ( set[ i ] !== null ) { 5637 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 5638 } 5639 } 5640 }, 5641 5642 // Restores a set of previously saved properties from a data storage 5643 restore: function( element, set ) { 5644 var val, i; 5645 for( i=0; i < set.length; i++ ) { 5646 if ( set[ i ] !== null ) { 5647 val = element.data( dataSpace + set[ i ] ); 5648 // support: jQuery 1.6.2 5649 // http://bugs.jquery.com/ticket/9917 5650 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 5651 // We can't differentiate between "" and 0 here, so we just assume 5652 // empty string since it's likely to be a more common value... 5653 if ( val === undefined ) { 5654 val = ""; 5655 } 5656 element.css( set[ i ], val ); 5657 } 5658 } 5659 }, 5660 5661 setMode: function( el, mode ) { 5662 if (mode === "toggle") { 5663 mode = el.is( ":hidden" ) ? "show" : "hide"; 5664 } 5665 return mode; 5666 }, 5667 5668 // Translates a [top,left] array into a baseline value 5669 // this should be a little more flexible in the future to handle a string & hash 5670 getBaseline: function( origin, original ) { 5671 var y, x; 5672 switch ( origin[ 0 ] ) { 5673 case "top": y = 0; break; 5674 case "middle": y = 0.5; break; 5675 case "bottom": y = 1; break; 5676 default: y = origin[ 0 ] / original.height; 5677 } 5678 switch ( origin[ 1 ] ) { 5679 case "left": x = 0; break; 5680 case "center": x = 0.5; break; 5681 case "right": x = 1; break; 5682 default: x = origin[ 1 ] / original.width; 5683 } 5684 return { 5685 x: x, 5686 y: y 5687 }; 5688 }, 5689 5690 // Wraps the element around a wrapper that copies position properties 5691 createWrapper: function( element ) { 5692 5693 // if the element is already wrapped, return it 5694 if ( element.parent().is( ".ui-effects-wrapper" )) { 5695 return element.parent(); 5696 } 5697 5698 // wrap the element 5699 var props = { 5700 width: element.outerWidth(true), 5701 height: element.outerHeight(true), 5702 "float": element.css( "float" ) 5703 }, 5704 wrapper = $( "<div></div>" ) 5705 .addClass( "ui-effects-wrapper" ) 5706 .css({ 5707 fontSize: "100%", 5708 background: "transparent", 5709 border: "none", 5710 margin: 0, 5711 padding: 0 5712 }), 5713 // Store the size in case width/height are defined in % - Fixes #5245 5714 size = { 5715 width: element.width(), 5716 height: element.height() 5717 }, 5718 active = document.activeElement; 5719 5720 // support: Firefox 5721 // Firefox incorrectly exposes anonymous content 5722 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 5723 try { 5724 active.id; 5725 } catch( e ) { 5726 active = document.body; 5727 } 5728 5729 element.wrap( wrapper ); 5730 5731 // Fixes #7595 - Elements lose focus when wrapped. 5732 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5733 $( active ).focus(); 5734 } 5735 5736 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 5737 5738 // transfer positioning properties to the wrapper 5739 if ( element.css( "position" ) === "static" ) { 5740 wrapper.css({ position: "relative" }); 5741 element.css({ position: "relative" }); 5742 } else { 5743 $.extend( props, { 5744 position: element.css( "position" ), 5745 zIndex: element.css( "z-index" ) 5746 }); 5747 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 5748 props[ pos ] = element.css( pos ); 5749 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 5750 props[ pos ] = "auto"; 5751 } 5752 }); 5753 element.css({ 5754 position: "relative", 5755 top: 0, 5756 left: 0, 5757 right: "auto", 5758 bottom: "auto" 5759 }); 5760 } 5761 element.css(size); 5762 5763 return wrapper.css( props ).show(); 5764 }, 5765 5766 removeWrapper: function( element ) { 5767 var active = document.activeElement; 5768 5769 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 5770 element.parent().replaceWith( element ); 5771 5772 // Fixes #7595 - Elements lose focus when wrapped. 5773 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 5774 $( active ).focus(); 5775 } 5776 } 5777 5778 5779 return element; 5780 }, 5781 5782 setTransition: function( element, list, factor, value ) { 5783 value = value || {}; 5784 $.each( list, function( i, x ) { 5785 var unit = element.cssUnit( x ); 5786 if ( unit[ 0 ] > 0 ) { 5787 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 5788 } 5789 }); 5790 return value; 5791 } 5792 }); 5793 5794// return an effect options object for the given parameters: 5795 function _normalizeArguments( effect, options, speed, callback ) { 5796 5797 // allow passing all options as the first parameter 5798 if ( $.isPlainObject( effect ) ) { 5799 options = effect; 5800 effect = effect.effect; 5801 } 5802 5803 // convert to an object 5804 effect = { effect: effect }; 5805 5806 // catch (effect, null, ...) 5807 if ( options == null ) { 5808 options = {}; 5809 } 5810 5811 // catch (effect, callback) 5812 if ( $.isFunction( options ) ) { 5813 callback = options; 5814 speed = null; 5815 options = {}; 5816 } 5817 5818 // catch (effect, speed, ?) 5819 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 5820 callback = speed; 5821 speed = options; 5822 options = {}; 5823 } 5824 5825 // catch (effect, options, callback) 5826 if ( $.isFunction( speed ) ) { 5827 callback = speed; 5828 speed = null; 5829 } 5830 5831 // add options to effect 5832 if ( options ) { 5833 $.extend( effect, options ); 5834 } 5835 5836 speed = speed || options.duration; 5837 effect.duration = $.fx.off ? 0 : 5838 typeof speed === "number" ? speed : 5839 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 5840 $.fx.speeds._default; 5841 5842 effect.complete = callback || options.complete; 5843 5844 return effect; 5845 } 5846 5847 function standardAnimationOption( option ) { 5848 // Valid standard speeds (nothing, number, named speed) 5849 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 5850 return true; 5851 } 5852 5853 // Invalid strings - treat as "normal" speed 5854 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 5855 return true; 5856 } 5857 5858 // Complete callback 5859 if ( $.isFunction( option ) ) { 5860 return true; 5861 } 5862 5863 // Options hash (but not naming an effect) 5864 if ( typeof option === "object" && !option.effect ) { 5865 return true; 5866 } 5867 5868 // Didn't match any standard API 5869 return false; 5870 } 5871 5872 $.fn.extend({ 5873 effect: function( /* effect, options, speed, callback */ ) { 5874 var args = _normalizeArguments.apply( this, arguments ), 5875 mode = args.mode, 5876 queue = args.queue, 5877 effectMethod = $.effects.effect[ args.effect ]; 5878 5879 if ( $.fx.off || !effectMethod ) { 5880 // delegate to the original method (e.g., .show()) if possible 5881 if ( mode ) { 5882 return this[ mode ]( args.duration, args.complete ); 5883 } else { 5884 return this.each( function() { 5885 if ( args.complete ) { 5886 args.complete.call( this ); 5887 } 5888 }); 5889 } 5890 } 5891 5892 function run( next ) { 5893 var elem = $( this ), 5894 complete = args.complete, 5895 mode = args.mode; 5896 5897 function done() { 5898 if ( $.isFunction( complete ) ) { 5899 complete.call( elem[0] ); 5900 } 5901 if ( $.isFunction( next ) ) { 5902 next(); 5903 } 5904 } 5905 5906 // If the element already has the correct final state, delegate to 5907 // the core methods so the internal tracking of "olddisplay" works. 5908 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 5909 elem[ mode ](); 5910 done(); 5911 } else { 5912 effectMethod.call( elem[0], args, done ); 5913 } 5914 } 5915 5916 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 5917 }, 5918 5919 show: (function( orig ) { 5920 return function( option ) { 5921 if ( standardAnimationOption( option ) ) { 5922 return orig.apply( this, arguments ); 5923 } else { 5924 var args = _normalizeArguments.apply( this, arguments ); 5925 args.mode = "show"; 5926 return this.effect.call( this, args ); 5927 } 5928 }; 5929 })( $.fn.show ), 5930 5931 hide: (function( orig ) { 5932 return function( option ) { 5933 if ( standardAnimationOption( option ) ) { 5934 return orig.apply( this, arguments ); 5935 } else { 5936 var args = _normalizeArguments.apply( this, arguments ); 5937 args.mode = "hide"; 5938 return this.effect.call( this, args ); 5939 } 5940 }; 5941 })( $.fn.hide ), 5942 5943 toggle: (function( orig ) { 5944 return function( option ) { 5945 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 5946 return orig.apply( this, arguments ); 5947 } else { 5948 var args = _normalizeArguments.apply( this, arguments ); 5949 args.mode = "toggle"; 5950 return this.effect.call( this, args ); 5951 } 5952 }; 5953 })( $.fn.toggle ), 5954 5955 // helper functions 5956 cssUnit: function(key) { 5957 var style = this.css( key ), 5958 val = []; 5959 5960 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 5961 if ( style.indexOf( unit ) > 0 ) { 5962 val = [ parseFloat( style ), unit ]; 5963 } 5964 }); 5965 return val; 5966 } 5967 }); 5968 5969 })(); 5970 5971 /******************************************************************************/ 5972 /*********************************** EASING ***********************************/ 5973 /******************************************************************************/ 5974 5975 (function() { 5976 5977// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 5978 5979 var baseEasings = {}; 5980 5981 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 5982 baseEasings[ name ] = function( p ) { 5983 return Math.pow( p, i + 2 ); 5984 }; 5985 }); 5986 5987 $.extend( baseEasings, { 5988 Sine: function ( p ) { 5989 return 1 - Math.cos( p * Math.PI / 2 ); 5990 }, 5991 Circ: function ( p ) { 5992 return 1 - Math.sqrt( 1 - p * p ); 5993 }, 5994 Elastic: function( p ) { 5995 return p === 0 || p === 1 ? p : 5996 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 5997 }, 5998 Back: function( p ) { 5999 return p * p * ( 3 * p - 2 ); 6000 }, 6001 Bounce: function ( p ) { 6002 var pow2, 6003 bounce = 4; 6004 6005 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 6006 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 6007 } 6008 }); 6009 6010 $.each( baseEasings, function( name, easeIn ) { 6011 $.easing[ "easeIn" + name ] = easeIn; 6012 $.easing[ "easeOut" + name ] = function( p ) { 6013 return 1 - easeIn( 1 - p ); 6014 }; 6015 $.easing[ "easeInOut" + name ] = function( p ) { 6016 return p < 0.5 ? 6017 easeIn( p * 2 ) / 2 : 6018 1 - easeIn( p * -2 + 2 ) / 2; 6019 }; 6020 }); 6021 6022 })(); 6023 6024})(jQuery); 6025 6026(function( $, undefined ) { 6027 6028 var uid = 0, 6029 hideProps = {}, 6030 showProps = {}; 6031 6032 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 6033 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 6034 showProps.height = showProps.paddingTop = showProps.paddingBottom = 6035 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 6036 6037 $.widget( "ui.accordion", { 6038 version: "1.10.2", 6039 options: { 6040 active: 0, 6041 animate: {}, 6042 collapsible: false, 6043 event: "click", 6044 header: "> li > :first-child,> :not(li):even", 6045 heightStyle: "auto", 6046 icons: { 6047 activeHeader: "ui-icon-triangle-1-s", 6048 header: "ui-icon-triangle-1-e" 6049 }, 6050 6051 // callbacks 6052 activate: null, 6053 beforeActivate: null 6054 }, 6055 6056 _create: function() { 6057 var options = this.options; 6058 this.prevShow = this.prevHide = $(); 6059 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 6060 // ARIA 6061 .attr( "role", "tablist" ); 6062 6063 // don't allow collapsible: false and active: false / null 6064 if ( !options.collapsible && (options.active === false || options.active == null) ) { 6065 options.active = 0; 6066 } 6067 6068 this._processPanels(); 6069 // handle negative values 6070 if ( options.active < 0 ) { 6071 options.active += this.headers.length; 6072 } 6073 this._refresh(); 6074 }, 6075 6076 _getCreateEventData: function() { 6077 return { 6078 header: this.active, 6079 panel: !this.active.length ? $() : this.active.next(), 6080 content: !this.active.length ? $() : this.active.next() 6081 }; 6082 }, 6083 6084 _createIcons: function() { 6085 var icons = this.options.icons; 6086 if ( icons ) { 6087 $( "<span>" ) 6088 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 6089 .prependTo( this.headers ); 6090 this.active.children( ".ui-accordion-header-icon" ) 6091 .removeClass( icons.header ) 6092 .addClass( icons.activeHeader ); 6093 this.headers.addClass( "ui-accordion-icons" ); 6094 } 6095 }, 6096 6097 _destroyIcons: function() { 6098 this.headers 6099 .removeClass( "ui-accordion-icons" ) 6100 .children( ".ui-accordion-header-icon" ) 6101 .remove(); 6102 }, 6103 6104 _destroy: function() { 6105 var contents; 6106 6107 // clean up main element 6108 this.element 6109 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 6110 .removeAttr( "role" ); 6111 6112 // clean up headers 6113 this.headers 6114 .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" ) 6115 .removeAttr( "role" ) 6116 .removeAttr( "aria-selected" ) 6117 .removeAttr( "aria-controls" ) 6118 .removeAttr( "tabIndex" ) 6119 .each(function() { 6120 if ( /^ui-accordion/.test( this.id ) ) { 6121 this.removeAttribute( "id" ); 6122 } 6123 }); 6124 this._destroyIcons(); 6125 6126 // clean up content panels 6127 contents = this.headers.next() 6128 .css( "display", "" ) 6129 .removeAttr( "role" ) 6130 .removeAttr( "aria-expanded" ) 6131 .removeAttr( "aria-hidden" ) 6132 .removeAttr( "aria-labelledby" ) 6133 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 6134 .each(function() { 6135 if ( /^ui-accordion/.test( this.id ) ) { 6136 this.removeAttribute( "id" ); 6137 } 6138 }); 6139 if ( this.options.heightStyle !== "content" ) { 6140 contents.css( "height", "" ); 6141 } 6142 }, 6143 6144 _setOption: function( key, value ) { 6145 if ( key === "active" ) { 6146 // _activate() will handle invalid values and update this.options 6147 this._activate( value ); 6148 return; 6149 } 6150 6151 if ( key === "event" ) { 6152 if ( this.options.event ) { 6153 this._off( this.headers, this.options.event ); 6154 } 6155 this._setupEvents( value ); 6156 } 6157 6158 this._super( key, value ); 6159 6160 // setting collapsible: false while collapsed; open first panel 6161 if ( key === "collapsible" && !value && this.options.active === false ) { 6162 this._activate( 0 ); 6163 } 6164 6165 if ( key === "icons" ) { 6166 this._destroyIcons(); 6167 if ( value ) { 6168 this._createIcons(); 6169 } 6170 } 6171 6172 // #5332 - opacity doesn't cascade to positioned elements in IE 6173 // so we need to add the disabled class to the headers and panels 6174 if ( key === "disabled" ) { 6175 this.headers.add( this.headers.next() ) 6176 .toggleClass( "ui-state-disabled", !!value ); 6177 } 6178 }, 6179 6180 _keydown: function( event ) { 6181 /*jshint maxcomplexity:15*/ 6182 if ( event.altKey || event.ctrlKey ) { 6183 return; 6184 } 6185 6186 var keyCode = $.ui.keyCode, 6187 length = this.headers.length, 6188 currentIndex = this.headers.index( event.target ), 6189 toFocus = false; 6190 6191 switch ( event.keyCode ) { 6192 case keyCode.RIGHT: 6193 case keyCode.DOWN: 6194 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 6195 break; 6196 case keyCode.LEFT: 6197 case keyCode.UP: 6198 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 6199 break; 6200 case keyCode.SPACE: 6201 case keyCode.ENTER: 6202 this._eventHandler( event ); 6203 break; 6204 case keyCode.HOME: 6205 toFocus = this.headers[ 0 ]; 6206 break; 6207 case keyCode.END: 6208 toFocus = this.headers[ length - 1 ]; 6209 break; 6210 } 6211 6212 if ( toFocus ) { 6213 $( event.target ).attr( "tabIndex", -1 ); 6214 $( toFocus ).attr( "tabIndex", 0 ); 6215 toFocus.focus(); 6216 event.preventDefault(); 6217 } 6218 }, 6219 6220 _panelKeyDown : function( event ) { 6221 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 6222 $( event.currentTarget ).prev().focus(); 6223 } 6224 }, 6225 6226 refresh: function() { 6227 var options = this.options; 6228 this._processPanels(); 6229 6230 // was collapsed or no panel 6231 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 6232 options.active = false; 6233 this.active = $(); 6234 // active false only when collapsible is true 6235 } if ( options.active === false ) { 6236 this._activate( 0 ); 6237 // was active, but active panel is gone 6238 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 6239 // all remaining panel are disabled 6240 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 6241 options.active = false; 6242 this.active = $(); 6243 // activate previous panel 6244 } else { 6245 this._activate( Math.max( 0, options.active - 1 ) ); 6246 } 6247 // was active, active panel still exists 6248 } else { 6249 // make sure active index is correct 6250 options.active = this.headers.index( this.active ); 6251 } 6252 6253 this._destroyIcons(); 6254 6255 this._refresh(); 6256 }, 6257 6258 _processPanels: function() { 6259 this.headers = this.element.find( this.options.header ) 6260 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 6261 6262 this.headers.next() 6263 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 6264 .filter(":not(.ui-accordion-content-active)") 6265 .hide(); 6266 }, 6267 6268 _refresh: function() { 6269 var maxHeight, 6270 options = this.options, 6271 heightStyle = options.heightStyle, 6272 parent = this.element.parent(), 6273 accordionId = this.accordionId = "ui-accordion-" + 6274 (this.element.attr( "id" ) || ++uid); 6275 6276 this.active = this._findActive( options.active ) 6277 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 6278 .removeClass( "ui-corner-all" ); 6279 this.active.next() 6280 .addClass( "ui-accordion-content-active" ) 6281 .show(); 6282 6283 this.headers 6284 .attr( "role", "tab" ) 6285 .each(function( i ) { 6286 var header = $( this ), 6287 headerId = header.attr( "id" ), 6288 panel = header.next(), 6289 panelId = panel.attr( "id" ); 6290 if ( !headerId ) { 6291 headerId = accordionId + "-header-" + i; 6292 header.attr( "id", headerId ); 6293 } 6294 if ( !panelId ) { 6295 panelId = accordionId + "-panel-" + i; 6296 panel.attr( "id", panelId ); 6297 } 6298 header.attr( "aria-controls", panelId ); 6299 panel.attr( "aria-labelledby", headerId ); 6300 }) 6301 .next() 6302 .attr( "role", "tabpanel" ); 6303 6304 this.headers 6305 .not( this.active ) 6306 .attr({ 6307 "aria-selected": "false", 6308 tabIndex: -1 6309 }) 6310 .next() 6311 .attr({ 6312 "aria-expanded": "false", 6313 "aria-hidden": "true" 6314 }) 6315 .hide(); 6316 6317 // make sure at least one header is in the tab order 6318 if ( !this.active.length ) { 6319 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 6320 } else { 6321 this.active.attr({ 6322 "aria-selected": "true", 6323 tabIndex: 0 6324 }) 6325 .next() 6326 .attr({ 6327 "aria-expanded": "true", 6328 "aria-hidden": "false" 6329 }); 6330 } 6331 6332 this._createIcons(); 6333 6334 this._setupEvents( options.event ); 6335 6336 if ( heightStyle === "fill" ) { 6337 maxHeight = parent.height(); 6338 this.element.siblings( ":visible" ).each(function() { 6339 var elem = $( this ), 6340 position = elem.css( "position" ); 6341 6342 if ( position === "absolute" || position === "fixed" ) { 6343 return; 6344 } 6345 maxHeight -= elem.outerHeight( true ); 6346 }); 6347 6348 this.headers.each(function() { 6349 maxHeight -= $( this ).outerHeight( true ); 6350 }); 6351 6352 this.headers.next() 6353 .each(function() { 6354 $( this ).height( Math.max( 0, maxHeight - 6355 $( this ).innerHeight() + $( this ).height() ) ); 6356 }) 6357 .css( "overflow", "auto" ); 6358 } else if ( heightStyle === "auto" ) { 6359 maxHeight = 0; 6360 this.headers.next() 6361 .each(function() { 6362 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 6363 }) 6364 .height( maxHeight ); 6365 } 6366 }, 6367 6368 _activate: function( index ) { 6369 var active = this._findActive( index )[ 0 ]; 6370 6371 // trying to activate the already active panel 6372 if ( active === this.active[ 0 ] ) { 6373 return; 6374 } 6375 6376 // trying to collapse, simulate a click on the currently active header 6377 active = active || this.active[ 0 ]; 6378 6379 this._eventHandler({ 6380 target: active, 6381 currentTarget: active, 6382 preventDefault: $.noop 6383 }); 6384 }, 6385 6386 _findActive: function( selector ) { 6387 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 6388 }, 6389 6390 _setupEvents: function( event ) { 6391 var events = { 6392 keydown: "_keydown" 6393 }; 6394 if ( event ) { 6395 $.each( event.split(" "), function( index, eventName ) { 6396 events[ eventName ] = "_eventHandler"; 6397 }); 6398 } 6399 6400 this._off( this.headers.add( this.headers.next() ) ); 6401 this._on( this.headers, events ); 6402 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 6403 this._hoverable( this.headers ); 6404 this._focusable( this.headers ); 6405 }, 6406 6407 _eventHandler: function( event ) { 6408 var options = this.options, 6409 active = this.active, 6410 clicked = $( event.currentTarget ), 6411 clickedIsActive = clicked[ 0 ] === active[ 0 ], 6412 collapsing = clickedIsActive && options.collapsible, 6413 toShow = collapsing ? $() : clicked.next(), 6414 toHide = active.next(), 6415 eventData = { 6416 oldHeader: active, 6417 oldPanel: toHide, 6418 newHeader: collapsing ? $() : clicked, 6419 newPanel: toShow 6420 }; 6421 6422 event.preventDefault(); 6423 6424 if ( 6425 // click on active header, but not collapsible 6426 ( clickedIsActive && !options.collapsible ) || 6427 // allow canceling activation 6428 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 6429 return; 6430 } 6431 6432 options.active = collapsing ? false : this.headers.index( clicked ); 6433 6434 // when the call to ._toggle() comes after the class changes 6435 // it causes a very odd bug in IE 8 (see #6720) 6436 this.active = clickedIsActive ? $() : clicked; 6437 this._toggle( eventData ); 6438 6439 // switch classes 6440 // corner classes on the previously active header stay after the animation 6441 active.removeClass( "ui-accordion-header-active ui-state-active" ); 6442 if ( options.icons ) { 6443 active.children( ".ui-accordion-header-icon" ) 6444 .removeClass( options.icons.activeHeader ) 6445 .addClass( options.icons.header ); 6446 } 6447 6448 if ( !clickedIsActive ) { 6449 clicked 6450 .removeClass( "ui-corner-all" ) 6451 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 6452 if ( options.icons ) { 6453 clicked.children( ".ui-accordion-header-icon" ) 6454 .removeClass( options.icons.header ) 6455 .addClass( options.icons.activeHeader ); 6456 } 6457 6458 clicked 6459 .next() 6460 .addClass( "ui-accordion-content-active" ); 6461 } 6462 }, 6463 6464 _toggle: function( data ) { 6465 var toShow = data.newPanel, 6466 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 6467 6468 // handle activating a panel during the animation for another activation 6469 this.prevShow.add( this.prevHide ).stop( true, true ); 6470 this.prevShow = toShow; 6471 this.prevHide = toHide; 6472 6473 if ( this.options.animate ) { 6474 this._animate( toShow, toHide, data ); 6475 } else { 6476 toHide.hide(); 6477 toShow.show(); 6478 this._toggleComplete( data ); 6479 } 6480 6481 toHide.attr({ 6482 "aria-expanded": "false", 6483 "aria-hidden": "true" 6484 }); 6485 toHide.prev().attr( "aria-selected", "false" ); 6486 // if we're switching panels, remove the old header from the tab order 6487 // if we're opening from collapsed state, remove the previous header from the tab order 6488 // if we're collapsing, then keep the collapsing header in the tab order 6489 if ( toShow.length && toHide.length ) { 6490 toHide.prev().attr( "tabIndex", -1 ); 6491 } else if ( toShow.length ) { 6492 this.headers.filter(function() { 6493 return $( this ).attr( "tabIndex" ) === 0; 6494 }) 6495 .attr( "tabIndex", -1 ); 6496 } 6497 6498 toShow 6499 .attr({ 6500 "aria-expanded": "true", 6501 "aria-hidden": "false" 6502 }) 6503 .prev() 6504 .attr({ 6505 "aria-selected": "true", 6506 tabIndex: 0 6507 }); 6508 }, 6509 6510 _animate: function( toShow, toHide, data ) { 6511 var total, easing, duration, 6512 that = this, 6513 adjust = 0, 6514 down = toShow.length && 6515 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 6516 animate = this.options.animate || {}, 6517 options = down && animate.down || animate, 6518 complete = function() { 6519 that._toggleComplete( data ); 6520 }; 6521 6522 if ( typeof options === "number" ) { 6523 duration = options; 6524 } 6525 if ( typeof options === "string" ) { 6526 easing = options; 6527 } 6528 // fall back from options to animation in case of partial down settings 6529 easing = easing || options.easing || animate.easing; 6530 duration = duration || options.duration || animate.duration; 6531 6532 if ( !toHide.length ) { 6533 return toShow.animate( showProps, duration, easing, complete ); 6534 } 6535 if ( !toShow.length ) { 6536 return toHide.animate( hideProps, duration, easing, complete ); 6537 } 6538 6539 total = toShow.show().outerHeight(); 6540 toHide.animate( hideProps, { 6541 duration: duration, 6542 easing: easing, 6543 step: function( now, fx ) { 6544 fx.now = Math.round( now ); 6545 } 6546 }); 6547 toShow 6548 .hide() 6549 .animate( showProps, { 6550 duration: duration, 6551 easing: easing, 6552 complete: complete, 6553 step: function( now, fx ) { 6554 fx.now = Math.round( now ); 6555 if ( fx.prop !== "height" ) { 6556 adjust += fx.now; 6557 } else if ( that.options.heightStyle !== "content" ) { 6558 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 6559 adjust = 0; 6560 } 6561 } 6562 }); 6563 }, 6564 6565 _toggleComplete: function( data ) { 6566 var toHide = data.oldPanel; 6567 6568 toHide 6569 .removeClass( "ui-accordion-content-active" ) 6570 .prev() 6571 .removeClass( "ui-corner-top" ) 6572 .addClass( "ui-corner-all" ); 6573 6574 // Work around for rendering bug in IE (#5421) 6575 if ( toHide.length ) { 6576 toHide.parent()[0].className = toHide.parent()[0].className; 6577 } 6578 6579 this._trigger( "activate", null, data ); 6580 } 6581 }); 6582 6583})( jQuery ); 6584 6585(function( $, undefined ) { 6586 6587// used to prevent race conditions with remote data sources 6588 var requestIndex = 0; 6589 6590 $.widget( "ui.autocomplete", { 6591 version: "1.10.2", 6592 defaultElement: "<input>", 6593 options: { 6594 appendTo: null, 6595 autoFocus: false, 6596 delay: 300, 6597 minLength: 1, 6598 position: { 6599 my: "left top", 6600 at: "left bottom", 6601 collision: "none" 6602 }, 6603 source: null, 6604 6605 // callbacks 6606 change: null, 6607 close: null, 6608 focus: null, 6609 open: null, 6610 response: null, 6611 search: null, 6612 select: null 6613 }, 6614 6615 pending: 0, 6616 6617 _create: function() { 6618 // Some browsers only repeat keydown events, not keypress events, 6619 // so we use the suppressKeyPress flag to determine if we've already 6620 // handled the keydown event. #7269 6621 // Unfortunately the code for & in keypress is the same as the up arrow, 6622 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6623 // events when we know the keydown event was used to modify the 6624 // search term. #7799 6625 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6626 nodeName = this.element[0].nodeName.toLowerCase(), 6627 isTextarea = nodeName === "textarea", 6628 isInput = nodeName === "input"; 6629 6630 this.isMultiLine = 6631 // Textareas are always multi-line 6632 isTextarea ? true : 6633 // Inputs are always single-line, even if inside a contentEditable element 6634 // IE also treats inputs as contentEditable 6635 isInput ? false : 6636 // All other element types are determined by whether or not they're contentEditable 6637 this.element.prop( "isContentEditable" ); 6638 6639 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6640 this.isNewMenu = true; 6641 6642 this.element 6643 .addClass( "ui-autocomplete-input" ) 6644 .attr( "autocomplete", "off" ); 6645 6646 this._on( this.element, { 6647 keydown: function( event ) { 6648 /*jshint maxcomplexity:15*/ 6649 if ( this.element.prop( "readOnly" ) ) { 6650 suppressKeyPress = true; 6651 suppressInput = true; 6652 suppressKeyPressRepeat = true; 6653 return; 6654 } 6655 6656 suppressKeyPress = false; 6657 suppressInput = false; 6658 suppressKeyPressRepeat = false; 6659 var keyCode = $.ui.keyCode; 6660 switch( event.keyCode ) { 6661 case keyCode.PAGE_UP: 6662 suppressKeyPress = true; 6663 this._move( "previousPage", event ); 6664 break; 6665 case keyCode.PAGE_DOWN: 6666 suppressKeyPress = true; 6667 this._move( "nextPage", event ); 6668 break; 6669 case keyCode.UP: 6670 suppressKeyPress = true; 6671 this._keyEvent( "previous", event ); 6672 break; 6673 case keyCode.DOWN: 6674 suppressKeyPress = true; 6675 this._keyEvent( "next", event ); 6676 break; 6677 case keyCode.ENTER: 6678 case keyCode.NUMPAD_ENTER: 6679 // when menu is open and has focus 6680 if ( this.menu.active ) { 6681 // #6055 - Opera still allows the keypress to occur 6682 // which causes forms to submit 6683 suppressKeyPress = true; 6684 event.preventDefault(); 6685 this.menu.select( event ); 6686 } 6687 break; 6688 case keyCode.TAB: 6689 if ( this.menu.active ) { 6690 this.menu.select( event ); 6691 } 6692 break; 6693 case keyCode.ESCAPE: 6694 if ( this.menu.element.is( ":visible" ) ) { 6695 this._value( this.term ); 6696 this.close( event ); 6697 // Different browsers have different default behavior for escape 6698 // Single press can mean undo or clear 6699 // Double press in IE means clear the whole form 6700 event.preventDefault(); 6701 } 6702 break; 6703 default: 6704 suppressKeyPressRepeat = true; 6705 // search timeout should be triggered before the input value is changed 6706 this._searchTimeout( event ); 6707 break; 6708 } 6709 }, 6710 keypress: function( event ) { 6711 if ( suppressKeyPress ) { 6712 suppressKeyPress = false; 6713 event.preventDefault(); 6714 return; 6715 } 6716 if ( suppressKeyPressRepeat ) { 6717 return; 6718 } 6719 6720 // replicate some key handlers to allow them to repeat in Firefox and Opera 6721 var keyCode = $.ui.keyCode; 6722 switch( event.keyCode ) { 6723 case keyCode.PAGE_UP: 6724 this._move( "previousPage", event ); 6725 break; 6726 case keyCode.PAGE_DOWN: 6727 this._move( "nextPage", event ); 6728 break; 6729 case keyCode.UP: 6730 this._keyEvent( "previous", event ); 6731 break; 6732 case keyCode.DOWN: 6733 this._keyEvent( "next", event ); 6734 break; 6735 } 6736 }, 6737 input: function( event ) { 6738 if ( suppressInput ) { 6739 suppressInput = false; 6740 event.preventDefault(); 6741 return; 6742 } 6743 this._searchTimeout( event ); 6744 }, 6745 focus: function() { 6746 this.selectedItem = null; 6747 this.previous = this._value(); 6748 }, 6749 blur: function( event ) { 6750 if ( this.cancelBlur ) { 6751 delete this.cancelBlur; 6752 return; 6753 } 6754 6755 clearTimeout( this.searching ); 6756 this.close( event ); 6757 this._change( event ); 6758 } 6759 }); 6760 6761 this._initSource(); 6762 this.menu = $( "<ul>" ) 6763 .addClass( "ui-autocomplete ui-front" ) 6764 .appendTo( this._appendTo() ) 6765 .menu({ 6766 // custom key handling for now 6767 input: $(), 6768 // disable ARIA support, the live region takes care of that 6769 role: null 6770 }) 6771 .hide() 6772 .data( "ui-menu" ); 6773 6774 this._on( this.menu.element, { 6775 mousedown: function( event ) { 6776 // prevent moving focus out of the text field 6777 event.preventDefault(); 6778 6779 // IE doesn't prevent moving focus even with event.preventDefault() 6780 // so we set a flag to know when we should ignore the blur event 6781 this.cancelBlur = true; 6782 this._delay(function() { 6783 delete this.cancelBlur; 6784 }); 6785 6786 // clicking on the scrollbar causes focus to shift to the body 6787 // but we can't detect a mouseup or a click immediately afterward 6788 // so we have to track the next mousedown and close the menu if 6789 // the user clicks somewhere outside of the autocomplete 6790 var menuElement = this.menu.element[ 0 ]; 6791 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 6792 this._delay(function() { 6793 var that = this; 6794 this.document.one( "mousedown", function( event ) { 6795 if ( event.target !== that.element[ 0 ] && 6796 event.target !== menuElement && 6797 !$.contains( menuElement, event.target ) ) { 6798 that.close(); 6799 } 6800 }); 6801 }); 6802 } 6803 }, 6804 menufocus: function( event, ui ) { 6805 // support: Firefox 6806 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6807 if ( this.isNewMenu ) { 6808 this.isNewMenu = false; 6809 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6810 this.menu.blur(); 6811 6812 this.document.one( "mousemove", function() { 6813 $( event.target ).trigger( event.originalEvent ); 6814 }); 6815 6816 return; 6817 } 6818 } 6819 6820 var item = ui.item.data( "ui-autocomplete-item" ); 6821 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6822 // use value to match what will end up in the input, if it was a key event 6823 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6824 this._value( item.value ); 6825 } 6826 } else { 6827 // Normally the input is populated with the item's value as the 6828 // menu is navigated, causing screen readers to notice a change and 6829 // announce the item. Since the focus event was canceled, this doesn't 6830 // happen, so we update the live region so that screen readers can 6831 // still notice the change and announce it. 6832 this.liveRegion.text( item.value ); 6833 } 6834 }, 6835 menuselect: function( event, ui ) { 6836 var item = ui.item.data( "ui-autocomplete-item" ), 6837 previous = this.previous; 6838 6839 // only trigger when focus was lost (click on menu) 6840 if ( this.element[0] !== this.document[0].activeElement ) { 6841 this.element.focus(); 6842 this.previous = previous; 6843 // #6109 - IE triggers two focus events and the second 6844 // is asynchronous, so we need to reset the previous 6845 // term synchronously and asynchronously :-( 6846 this._delay(function() { 6847 this.previous = previous; 6848 this.selectedItem = item; 6849 }); 6850 } 6851 6852 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6853 this._value( item.value ); 6854 } 6855 // reset the term after the select event 6856 // this allows custom select handling to work properly 6857 this.term = this._value(); 6858 6859 this.close( event ); 6860 this.selectedItem = item; 6861 } 6862 }); 6863 6864 this.liveRegion = $( "<span>", { 6865 role: "status", 6866 "aria-live": "polite" 6867 }) 6868 .addClass( "ui-helper-hidden-accessible" ) 6869 .insertAfter( this.element ); 6870 6871 // turning off autocomplete prevents the browser from remembering the 6872 // value when navigating through history, so we re-enable autocomplete 6873 // if the page is unloaded before the widget is destroyed. #7790 6874 this._on( this.window, { 6875 beforeunload: function() { 6876 this.element.removeAttr( "autocomplete" ); 6877 } 6878 }); 6879 }, 6880 6881 _destroy: function() { 6882 clearTimeout( this.searching ); 6883 this.element 6884 .removeClass( "ui-autocomplete-input" ) 6885 .removeAttr( "autocomplete" ); 6886 this.menu.element.remove(); 6887 this.liveRegion.remove(); 6888 }, 6889 6890 _setOption: function( key, value ) { 6891 this._super( key, value ); 6892 if ( key === "source" ) { 6893 this._initSource(); 6894 } 6895 if ( key === "appendTo" ) { 6896 this.menu.element.appendTo( this._appendTo() ); 6897 } 6898 if ( key === "disabled" && value && this.xhr ) { 6899 this.xhr.abort(); 6900 } 6901 }, 6902 6903 _appendTo: function() { 6904 var element = this.options.appendTo; 6905 6906 if ( element ) { 6907 element = element.jquery || element.nodeType ? 6908 $( element ) : 6909 this.document.find( element ).eq( 0 ); 6910 } 6911 6912 if ( !element ) { 6913 element = this.element.closest( ".ui-front" ); 6914 } 6915 6916 if ( !element.length ) { 6917 element = this.document[0].body; 6918 } 6919 6920 return element; 6921 }, 6922 6923 _initSource: function() { 6924 var array, url, 6925 that = this; 6926 if ( $.isArray(this.options.source) ) { 6927 array = this.options.source; 6928 this.source = function( request, response ) { 6929 response( $.ui.autocomplete.filter( array, request.term ) ); 6930 }; 6931 } else if ( typeof this.options.source === "string" ) { 6932 url = this.options.source; 6933 this.source = function( request, response ) { 6934 if ( that.xhr ) { 6935 that.xhr.abort(); 6936 } 6937 that.xhr = $.ajax({ 6938 url: url, 6939 data: request, 6940 dataType: "json", 6941 success: function( data ) { 6942 response( data ); 6943 }, 6944 error: function() { 6945 response( [] ); 6946 } 6947 }); 6948 }; 6949 } else { 6950 this.source = this.options.source; 6951 } 6952 }, 6953 6954 _searchTimeout: function( event ) { 6955 clearTimeout( this.searching ); 6956 this.searching = this._delay(function() { 6957 // only search if the value has changed
vendor: 5,839 bytes, lines 6958-7134
6958 if ( this.term !== this._value() ) { 6959 this.selectedItem = null; 6960 this.search( null, event ); 6961 } 6962 }, this.options.delay ); 6963 }, 6964 6965 search: function( value, event ) { 6966 value = value != null ? value : this._value(); 6967 6968 // always save the actual value, not the one passed as an argument 6969 this.term = this._value(); 6970 6971 if ( value.length < this.options.minLength ) { 6972 return this.close( event ); 6973 } 6974 6975 if ( this._trigger( "search", event ) === false ) { 6976 return; 6977 } 6978 6979 return this._search( value ); 6980 }, 6981 6982 _search: function( value ) { 6983 this.pending++; 6984 this.element.addClass( "ui-autocomplete-loading" ); 6985 this.cancelSearch = false; 6986 6987 this.source( { term: value }, this._response() ); 6988 }, 6989 6990 _response: function() { 6991 var that = this, 6992 index = ++requestIndex; 6993 6994 return function( content ) { 6995 if ( index === requestIndex ) { 6996 that.__response( content ); 6997 } 6998 6999 that.pending--; 7000 if ( !that.pending ) { 7001 that.element.removeClass( "ui-autocomplete-loading" ); 7002 } 7003 }; 7004 }, 7005 7006 __response: function( content ) { 7007 if ( content ) { 7008 content = this._normalize( content ); 7009 } 7010 this._trigger( "response", null, { content: content } ); 7011 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 7012 this._suggest( content ); 7013 this._trigger( "open" ); 7014 } else { 7015 // use ._close() instead of .close() so we don't cancel future searches 7016 this._close(); 7017 } 7018 }, 7019 7020 close: function( event ) { 7021 this.cancelSearch = true; 7022 this._close( event ); 7023 }, 7024 7025 _close: function( event ) { 7026 if ( this.menu.element.is( ":visible" ) ) { 7027 this.menu.element.hide(); 7028 this.menu.blur(); 7029 this.isNewMenu = true; 7030 this._trigger( "close", event ); 7031 } 7032 }, 7033 7034 _change: function( event ) { 7035 if ( this.previous !== this._value() ) { 7036 this._trigger( "change", event, { item: this.selectedItem } ); 7037 } 7038 }, 7039 7040 _normalize: function( items ) { 7041 // assume all items have the right format when the first item is complete 7042 if ( items.length && items[0].label && items[0].value ) { 7043 return items; 7044 } 7045 return $.map( items, function( item ) { 7046 if ( typeof item === "string" ) { 7047 return { 7048 label: item, 7049 value: item 7050 }; 7051 } 7052 return $.extend({ 7053 label: item.label || item.value, 7054 value: item.value || item.label 7055 }, item ); 7056 }); 7057 }, 7058 7059 _suggest: function( items ) { 7060 var ul = this.menu.element.empty(); 7061 this._renderMenu( ul, items ); 7062 this.isNewMenu = true; 7063 this.menu.refresh(); 7064 7065 // size and position menu 7066 ul.show(); 7067 this._resizeMenu(); 7068 ul.position( $.extend({ 7069 of: this.element 7070 }, this.options.position )); 7071 7072 if ( this.options.autoFocus ) { 7073 this.menu.next(); 7074 } 7075 }, 7076 7077 _resizeMenu: function() { 7078 var ul = this.menu.element; 7079 ul.outerWidth( Math.max( 7080 // Firefox wraps long text (possibly a rounding bug) 7081 // so we add 1px to avoid the wrapping (#7513) 7082 ul.width( "" ).outerWidth() + 1, 7083 this.element.outerWidth() 7084 ) ); 7085 }, 7086 7087 _renderMenu: function( ul, items ) { 7088 var that = this; 7089 $.each( items, function( index, item ) { 7090 that._renderItemData( ul, item ); 7091 }); 7092 }, 7093 7094 _renderItemData: function( ul, item ) { 7095 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 7096 }, 7097 7098 _renderItem: function( ul, item ) { 7099 return $( "<li>" ) 7100 .append( $( "<a>" ).text( item.label ) ) 7101 .appendTo( ul ); 7102 }, 7103 7104 _move: function( direction, event ) { 7105 if ( !this.menu.element.is( ":visible" ) ) { 7106 this.search( null, event ); 7107 return; 7108 } 7109 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 7110 this.menu.isLastItem() && /^next/.test( direction ) ) { 7111 this._value( this.term ); 7112 this.menu.blur(); 7113 return; 7114 } 7115 this.menu[ direction ]( event ); 7116 }, 7117 7118 widget: function() { 7119 return this.menu.element; 7120 }, 7121 7122 _value: function() { 7123 return this.valueMethod.apply( this.element, arguments ); 7124 }, 7125 7126 _keyEvent: function( keyEvent, event ) { 7127 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 7128 this._move( keyEvent, event ); 7129 7130 // prevents moving cursor to beginning/end of the text field in some browsers 7131 event.preventDefault(); 7132 } 7133 } 7134 });
vendor: 21,969 bytes, lines 7135-7635
7135 7136 $.extend( $.ui.autocomplete, { 7137 escapeRegex: function( value ) { 7138 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 7139 }, 7140 filter: function(array, term) { 7141 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 7142 return $.grep( array, function(value) { 7143 return matcher.test( value.label || value.value || value ); 7144 }); 7145 } 7146 }); 7147 7148 7149// live region extension, adding a `messages` option 7150// NOTE: This is an experimental API. We are still investigating 7151// a full solution for string manipulation and internationalization. 7152 $.widget( "ui.autocomplete", $.ui.autocomplete, { 7153 options: { 7154 messages: { 7155 noResults: "No search results.", 7156 results: function( amount ) { 7157 return amount + ( amount > 1 ? " results are" : " result is" ) + 7158 " available, use up and down arrow keys to navigate."; 7159 } 7160 } 7161 }, 7162 7163 __response: function( content ) { 7164 var message; 7165 this._superApply( arguments ); 7166 if ( this.options.disabled || this.cancelSearch ) { 7167 return; 7168 } 7169 if ( content && content.length ) { 7170 message = this.options.messages.results( content.length ); 7171 } else { 7172 message = this.options.messages.noResults; 7173 } 7174 this.liveRegion.text( message ); 7175 } 7176 }); 7177 7178}( jQuery )); 7179 7180(function( $, undefined ) { 7181 7182 var lastActive, startXPos, startYPos, clickDragged, 7183 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 7184 stateClasses = "ui-state-hover ui-state-active ", 7185 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", 7186 formResetHandler = function() { 7187 var buttons = $( this ).find( ":ui-button" ); 7188 setTimeout(function() { 7189 buttons.button( "refresh" ); 7190 }, 1 ); 7191 }, 7192 radioGroup = function( radio ) { 7193 var name = radio.name, 7194 form = radio.form, 7195 radios = $( [] ); 7196 if ( name ) { 7197 name = name.replace( /'/g, "\\'" ); 7198 if ( form ) { 7199 radios = $( form ).find( "[name='" + name + "']" ); 7200 } else { 7201 radios = $( "[name='" + name + "']", radio.ownerDocument ) 7202 .filter(function() { 7203 return !this.form; 7204 }); 7205 } 7206 } 7207 return radios; 7208 }; 7209 7210 $.widget( "ui.button", { 7211 version: "1.10.2", 7212 defaultElement: "<button>", 7213 options: { 7214 disabled: null, 7215 text: true, 7216 label: null, 7217 icons: { 7218 primary: null, 7219 secondary: null 7220 } 7221 }, 7222 _create: function() { 7223 this.element.closest( "form" ) 7224 .unbind( "reset" + this.eventNamespace ) 7225 .bind( "reset" + this.eventNamespace, formResetHandler ); 7226 7227 if ( typeof this.options.disabled !== "boolean" ) { 7228 this.options.disabled = !!this.element.prop( "disabled" ); 7229 } else { 7230 this.element.prop( "disabled", this.options.disabled ); 7231 } 7232 7233 this._determineButtonType(); 7234 this.hasTitle = !!this.buttonElement.attr( "title" ); 7235 7236 var that = this, 7237 options = this.options, 7238 toggleButton = this.type === "checkbox" || this.type === "radio", 7239 activeClass = !toggleButton ? "ui-state-active" : "", 7240 focusClass = "ui-state-focus"; 7241 7242 if ( options.label === null ) { 7243 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 7244 } 7245 7246 this._hoverable( this.buttonElement ); 7247 7248 this.buttonElement 7249 .addClass( baseClasses ) 7250 .attr( "role", "button" ) 7251 .bind( "mouseenter" + this.eventNamespace, function() { 7252 if ( options.disabled ) { 7253 return; 7254 } 7255 if ( this === lastActive ) { 7256 $( this ).addClass( "ui-state-active" ); 7257 } 7258 }) 7259 .bind( "mouseleave" + this.eventNamespace, function() { 7260 if ( options.disabled ) { 7261 return; 7262 } 7263 $( this ).removeClass( activeClass ); 7264 }) 7265 .bind( "click" + this.eventNamespace, function( event ) { 7266 if ( options.disabled ) { 7267 event.preventDefault(); 7268 event.stopImmediatePropagation(); 7269 } 7270 }); 7271 7272 this.element 7273 .bind( "focus" + this.eventNamespace, function() { 7274 // no need to check disabled, focus won't be triggered anyway 7275 that.buttonElement.addClass( focusClass ); 7276 }) 7277 .bind( "blur" + this.eventNamespace, function() { 7278 that.buttonElement.removeClass( focusClass ); 7279 }); 7280 7281 if ( toggleButton ) { 7282 this.element.bind( "change" + this.eventNamespace, function() { 7283 if ( clickDragged ) { 7284 return; 7285 } 7286 that.refresh(); 7287 }); 7288 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 7289 // prevents issue where button state changes but checkbox/radio checked state 7290 // does not in Firefox (see ticket #6970) 7291 this.buttonElement 7292 .bind( "mousedown" + this.eventNamespace, function( event ) { 7293 if ( options.disabled ) { 7294 return; 7295 } 7296 clickDragged = false; 7297 startXPos = event.pageX; 7298 startYPos = event.pageY; 7299 }) 7300 .bind( "mouseup" + this.eventNamespace, function( event ) { 7301 if ( options.disabled ) { 7302 return; 7303 } 7304 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 7305 clickDragged = true; 7306 } 7307 }); 7308 } 7309 7310 if ( this.type === "checkbox" ) { 7311 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7312 if ( options.disabled || clickDragged ) { 7313 return false; 7314 } 7315 }); 7316 } else if ( this.type === "radio" ) { 7317 this.buttonElement.bind( "click" + this.eventNamespace, function() { 7318 if ( options.disabled || clickDragged ) { 7319 return false; 7320 } 7321 $( this ).addClass( "ui-state-active" ); 7322 that.buttonElement.attr( "aria-pressed", "true" ); 7323 7324 var radio = that.element[ 0 ]; 7325 radioGroup( radio ) 7326 .not( radio ) 7327 .map(function() { 7328 return $( this ).button( "widget" )[ 0 ]; 7329 }) 7330 .removeClass( "ui-state-active" ) 7331 .attr( "aria-pressed", "false" ); 7332 }); 7333 } else { 7334 this.buttonElement 7335 .bind( "mousedown" + this.eventNamespace, function() { 7336 if ( options.disabled ) { 7337 return false; 7338 } 7339 $( this ).addClass( "ui-state-active" ); 7340 lastActive = this; 7341 that.document.one( "mouseup", function() { 7342 lastActive = null; 7343 }); 7344 }) 7345 .bind( "mouseup" + this.eventNamespace, function() { 7346 if ( options.disabled ) { 7347 return false; 7348 } 7349 $( this ).removeClass( "ui-state-active" ); 7350 }) 7351 .bind( "keydown" + this.eventNamespace, function(event) { 7352 if ( options.disabled ) { 7353 return false; 7354 } 7355 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 7356 $( this ).addClass( "ui-state-active" ); 7357 } 7358 }) 7359 // see #8559, we bind to blur here in case the button element loses 7360 // focus between keydown and keyup, it would be left in an "active" state 7361 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 7362 $( this ).removeClass( "ui-state-active" ); 7363 }); 7364 7365 if ( this.buttonElement.is("a") ) { 7366 this.buttonElement.keyup(function(event) { 7367 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7368 // TODO pass through original event correctly (just as 2nd argument doesn't work) 7369 $( this ).click(); 7370 } 7371 }); 7372 } 7373 } 7374 7375 // TODO: pull out $.Widget's handling for the disabled option into 7376 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 7377 // be overridden by individual plugins 7378 this._setOption( "disabled", options.disabled ); 7379 this._resetButton(); 7380 }, 7381 7382 _determineButtonType: function() { 7383 var ancestor, labelSelector, checked; 7384 7385 if ( this.element.is("[type=checkbox]") ) { 7386 this.type = "checkbox"; 7387 } else if ( this.element.is("[type=radio]") ) { 7388 this.type = "radio"; 7389 } else if ( this.element.is("input") ) { 7390 this.type = "input"; 7391 } else { 7392 this.type = "button"; 7393 } 7394 7395 if ( this.type === "checkbox" || this.type === "radio" ) { 7396 // we don't search against the document in case the element 7397 // is disconnected from the DOM 7398 ancestor = this.element.parents().last(); 7399 labelSelector = "label[for='" + this.element.attr("id") + "']"; 7400 this.buttonElement = ancestor.find( labelSelector ); 7401 if ( !this.buttonElement.length ) { 7402 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 7403 this.buttonElement = ancestor.filter( labelSelector ); 7404 if ( !this.buttonElement.length ) { 7405 this.buttonElement = ancestor.find( labelSelector ); 7406 } 7407 } 7408 this.element.addClass( "ui-helper-hidden-accessible" ); 7409 7410 checked = this.element.is( ":checked" ); 7411 if ( checked ) { 7412 this.buttonElement.addClass( "ui-state-active" ); 7413 } 7414 this.buttonElement.prop( "aria-pressed", checked ); 7415 } else { 7416 this.buttonElement = this.element; 7417 } 7418 }, 7419 7420 widget: function() { 7421 return this.buttonElement; 7422 }, 7423 7424 _destroy: function() { 7425 this.element 7426 .removeClass( "ui-helper-hidden-accessible" ); 7427 this.buttonElement 7428 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 7429 .removeAttr( "role" ) 7430 .removeAttr( "aria-pressed" ) 7431 .html( this.buttonElement.find(".ui-button-text").html() ); 7432 7433 if ( !this.hasTitle ) { 7434 this.buttonElement.removeAttr( "title" ); 7435 } 7436 }, 7437 7438 _setOption: function( key, value ) { 7439 this._super( key, value ); 7440 if ( key === "disabled" ) { 7441 if ( value ) { 7442 this.element.prop( "disabled", true ); 7443 } else { 7444 this.element.prop( "disabled", false ); 7445 } 7446 return; 7447 } 7448 this._resetButton(); 7449 }, 7450 7451 refresh: function() { 7452 //See #8237 & #8828 7453 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 7454 7455 if ( isDisabled !== this.options.disabled ) { 7456 this._setOption( "disabled", isDisabled ); 7457 } 7458 if ( this.type === "radio" ) { 7459 radioGroup( this.element[0] ).each(function() { 7460 if ( $( this ).is( ":checked" ) ) { 7461 $( this ).button( "widget" ) 7462 .addClass( "ui-state-active" ) 7463 .attr( "aria-pressed", "true" ); 7464 } else { 7465 $( this ).button( "widget" ) 7466 .removeClass( "ui-state-active" ) 7467 .attr( "aria-pressed", "false" ); 7468 } 7469 }); 7470 } else if ( this.type === "checkbox" ) { 7471 if ( this.element.is( ":checked" ) ) { 7472 this.buttonElement 7473 .addClass( "ui-state-active" ) 7474 .attr( "aria-pressed", "true" ); 7475 } else { 7476 this.buttonElement 7477 .removeClass( "ui-state-active" ) 7478 .attr( "aria-pressed", "false" ); 7479 } 7480 } 7481 }, 7482 7483 _resetButton: function() { 7484 if ( this.type === "input" ) { 7485 if ( this.options.label ) { 7486 this.element.val( this.options.label ); 7487 } 7488 return; 7489 } 7490 var buttonElement = this.buttonElement.removeClass( typeClasses ), 7491 buttonText = $( "<span></span>", this.document[0] ) 7492 .addClass( "ui-button-text" ) 7493 .html( this.options.label ) 7494 .appendTo( buttonElement.empty() ) 7495 .text(), 7496 icons = this.options.icons, 7497 multipleIcons = icons.primary && icons.secondary, 7498 buttonClasses = []; 7499 7500 if ( icons.primary || icons.secondary ) { 7501 if ( this.options.text ) { 7502 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 7503 } 7504 7505 if ( icons.primary ) { 7506 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 7507 } 7508 7509 if ( icons.secondary ) { 7510 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 7511 } 7512 7513 if ( !this.options.text ) { 7514 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 7515 7516 if ( !this.hasTitle ) { 7517 buttonElement.attr( "title", $.trim( buttonText ) ); 7518 } 7519 } 7520 } else { 7521 buttonClasses.push( "ui-button-text-only" ); 7522 } 7523 buttonElement.addClass( buttonClasses.join( " " ) ); 7524 } 7525 }); 7526 7527 $.widget( "ui.buttonset", { 7528 version: "1.10.2", 7529 options: { 7530 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 7531 }, 7532 7533 _create: function() { 7534 this.element.addClass( "ui-buttonset" ); 7535 }, 7536 7537 _init: function() { 7538 this.refresh(); 7539 }, 7540 7541 _setOption: function( key, value ) { 7542 if ( key === "disabled" ) { 7543 this.buttons.button( "option", key, value ); 7544 } 7545 7546 this._super( key, value ); 7547 }, 7548 7549 refresh: function() { 7550 var rtl = this.element.css( "direction" ) === "rtl"; 7551 7552 this.buttons = this.element.find( this.options.items ) 7553 .filter( ":ui-button" ) 7554 .button( "refresh" ) 7555 .end() 7556 .not( ":ui-button" ) 7557 .button() 7558 .end() 7559 .map(function() { 7560 return $( this ).button( "widget" )[ 0 ]; 7561 }) 7562 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 7563 .filter( ":first" ) 7564 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 7565 .end() 7566 .filter( ":last" ) 7567 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 7568 .end() 7569 .end(); 7570 }, 7571 7572 _destroy: function() { 7573 this.element.removeClass( "ui-buttonset" ); 7574 this.buttons 7575 .map(function() { 7576 return $( this ).button( "widget" )[ 0 ]; 7577 }) 7578 .removeClass( "ui-corner-left ui-corner-right" ) 7579 .end() 7580 .button( "destroy" ); 7581 } 7582 }); 7583 7584}( jQuery ) ); 7585 7586(function( $, undefined ) { 7587 7588 $.extend($.ui, { datepicker: { version: "1.10.2" } }); 7589 7590 var PROP_NAME = "datepicker", 7591 dpuuid = new Date().getTime(), 7592 instActive; 7593 7594 /* Date picker manager. 7595 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7596 Settings for (groups of) date pickers are maintained in an instance object, 7597 allowing multiple different settings on the same page. */ 7598 7599 function Datepicker() { 7600 this._curInst = null; // The current instance in use 7601 this._keyEvent = false; // If the last event was a key event 7602 this._disabledInputs = []; // List of date picker inputs that have been disabled 7603 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7604 this._inDialog = false; // True if showing within a "dialog", false if not 7605 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7606 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7607 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7608 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7609 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7610 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7611 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7612 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7613 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7614 this.regional = []; // Available regional settings, indexed by language code 7615 this.regional[""] = { // Default regional settings 7616 closeText: "Done", // Display text for close link 7617 prevText: "Prev", // Display text for previous month link 7618 nextText: "Next", // Display text for next month link 7619 currentText: "Today", // Display text for current month link 7620 monthNames: ["January","February","March","April","May","June", 7621 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 7622 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 7623 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 7624 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 7625 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 7626 weekHeader: "Wk", // Column header for week of the year 7627 dateFormat: "mm/dd/yy", // See format options on parseDate 7628 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7629 isRTL: false, // True if right-to-left language, false if left-to-right 7630 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7631 yearSuffix: "" // Additional text to append to the year in the month headers 7632 }; 7633 this._defaults = { // Global defaults for all the date picker instances 7634 showOn: "focus", // "focus" for popup on focus, 7635 // "button" for trigger button, or "both" for either
vendor: 7,673 bytes, lines 7636-7768
7636 showAnim: "fadeIn", // Name of jQuery animation for popup 7637 showOptions: {}, // Options for enhanced animations 7638 defaultDate: null, // Used when field is blank: actual date, 7639 // +/-number for offset from today, null for today 7640 appendText: "", // Display text following the input box, e.g. showing the format 7641 buttonText: "...", // Text for trigger button 7642 buttonImage: "", // URL for trigger button image 7643 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7644 hideIfNoPrevNext: false, // True to hide next/previous month links 7645 // if not applicable, false to just disable them 7646 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7647 gotoCurrent: false, // True if today link goes back to current selection instead 7648 changeMonth: false, // True if month can be selected directly, false if only prev/next 7649 changeYear: false, // True if year can be selected directly, false if only prev/next 7650 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7651 // either relative to today's year (-nn:+nn), relative to currently displayed year 7652 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7653 showOtherMonths: false, // True to show dates in other months, false to leave blank 7654 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7655 showWeek: false, // True to show week of the year, false to not show it 7656 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7657 // takes a Date and returns the number of the week for it 7658 shortYearCutoff: "+10", // Short year values < this are in the current century, 7659 // > this are in the previous century, 7660 // string value starting with "+" for current year + value 7661 minDate: null, // The earliest selectable date, or null for no limit 7662 maxDate: null, // The latest selectable date, or null for no limit 7663 duration: "fast", // Duration of display/closure 7664 beforeShowDay: null, // Function that takes a date and returns an array with 7665 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7666 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7667 beforeShow: null, // Function that takes an input field and 7668 // returns a set of custom settings for the date picker 7669 onSelect: null, // Define a callback function when a date is selected 7670 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7671 onClose: null, // Define a callback function when the datepicker is closed 7672 numberOfMonths: 1, // Number of months to show at a time 7673 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7674 stepMonths: 1, // Number of months to step back/forward 7675 stepBigMonths: 12, // Number of months to step back/forward for the big links 7676 altField: "", // Selector for an alternate field to store selected dates into 7677 altFormat: "", // The date format to use for the alternate field 7678 constrainInput: true, // The input is constrained by the current date format 7679 showButtonPanel: false, // True to show button panel, false to not show it 7680 autoSize: false, // True to size the input for the date format, false to leave as is 7681 disabled: false // The initial disabled state 7682 }; 7683 $.extend(this._defaults, this.regional[""]); 7684 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 7685 } 7686 7687 $.extend(Datepicker.prototype, { 7688 /* Class name added to elements to indicate already configured with a date picker. */ 7689 markerClassName: "hasDatepicker", 7690 7691 //Keep track of the maximum number of rows displayed (see #7043) 7692 maxRows: 4, 7693 7694 // TODO rename to "widget" when switching to widget factory 7695 _widgetDatepicker: function() { 7696 return this.dpDiv; 7697 }, 7698 7699 /* Override the default settings for all instances of the date picker. 7700 * @param settings object - the new settings to use as defaults (anonymous object) 7701 * @return the manager object 7702 */ 7703 setDefaults: function(settings) { 7704 extendRemove(this._defaults, settings || {}); 7705 return this; 7706 }, 7707 7708 /* Attach the date picker to a jQuery selection. 7709 * @param target element - the target input field or division or span 7710 * @param settings object - the new settings to use for this date picker instance (anonymous) 7711 */ 7712 _attachDatepicker: function(target, settings) { 7713 var nodeName, inline, inst; 7714 nodeName = target.nodeName.toLowerCase(); 7715 inline = (nodeName === "div" || nodeName === "span"); 7716 if (!target.id) { 7717 this.uuid += 1; 7718 target.id = "dp" + this.uuid; 7719 } 7720 inst = this._newInst($(target), inline); 7721 inst.settings = $.extend({}, settings || {}); 7722 if (nodeName === "input") { 7723 this._connectDatepicker(target, inst); 7724 } else if (inline) { 7725 this._inlineDatepicker(target, inst); 7726 } 7727 }, 7728 7729 /* Create a new instance object. */ 7730 _newInst: function(target, inline) { 7731 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 7732 return {id: id, input: target, // associated target 7733 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 7734 drawMonth: 0, drawYear: 0, // month being drawn 7735 inline: inline, // is datepicker inline or not 7736 dpDiv: (!inline ? this.dpDiv : // presentation div 7737 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 7738 }, 7739 7740 /* Attach the date picker to an input field. */ 7741 _connectDatepicker: function(target, inst) { 7742 var input = $(target); 7743 inst.append = $([]); 7744 inst.trigger = $([]); 7745 if (input.hasClass(this.markerClassName)) { 7746 return; 7747 } 7748 this._attachments(input, inst); 7749 input.addClass(this.markerClassName).keydown(this._doKeyDown). 7750 keypress(this._doKeyPress).keyup(this._doKeyUp); 7751 this._autoSize(inst); 7752 $.data(target, PROP_NAME, inst); 7753 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 7754 if( inst.settings.disabled ) { 7755 this._disableDatepicker( target ); 7756 } 7757 }, 7758 7759 /* Make attachments based on settings. */ 7760 _attachments: function(input, inst) { 7761 var showOn, buttonText, buttonImage, 7762 appendText = this._get(inst, "appendText"), 7763 isRTL = this._get(inst, "isRTL"); 7764 7765 if (inst.append) { 7766 inst.append.remove(); 7767 } 7768 if (appendText) {
vendor: 7,499 bytes, lines 7769-7921
7769 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 7770 input[isRTL ? "before" : "after"](inst.append); 7771 } 7772 7773 input.unbind("focus", this._showDatepicker); 7774 7775 if (inst.trigger) { 7776 inst.trigger.remove(); 7777 } 7778 7779 showOn = this._get(inst, "showOn"); 7780 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 7781 input.focus(this._showDatepicker); 7782 } 7783 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 7784 buttonText = this._get(inst, "buttonText"); 7785 buttonImage = this._get(inst, "buttonImage"); 7786 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 7787 $("<img/>").addClass(this._triggerClass). 7788 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 7789 $("<button type='button'></button>").addClass(this._triggerClass). 7790 html(!buttonImage ? buttonText : $("<img/>").attr( 7791 { src:buttonImage, alt:buttonText, title:buttonText }))); 7792 input[isRTL ? "before" : "after"](inst.trigger); 7793 inst.trigger.click(function() { 7794 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 7795 $.datepicker._hideDatepicker(); 7796 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 7797 $.datepicker._hideDatepicker(); 7798 $.datepicker._showDatepicker(input[0]); 7799 } else { 7800 $.datepicker._showDatepicker(input[0]); 7801 } 7802 return false; 7803 }); 7804 } 7805 }, 7806 7807 /* Apply the maximum length for the date format. */ 7808 _autoSize: function(inst) { 7809 if (this._get(inst, "autoSize") && !inst.inline) { 7810 var findMax, max, maxI, i, 7811 date = new Date(2009, 12 - 1, 20), // Ensure double digits 7812 dateFormat = this._get(inst, "dateFormat"); 7813 7814 if (dateFormat.match(/[DM]/)) { 7815 findMax = function(names) { 7816 max = 0; 7817 maxI = 0; 7818 for (i = 0; i < names.length; i++) { 7819 if (names[i].length > max) { 7820 max = names[i].length; 7821 maxI = i; 7822 } 7823 } 7824 return maxI; 7825 }; 7826 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 7827 "monthNames" : "monthNamesShort")))); 7828 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 7829 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 7830 } 7831 inst.input.attr("size", this._formatDate(inst, date).length); 7832 } 7833 }, 7834 7835 /* Attach an inline date picker to a div. */ 7836 _inlineDatepicker: function(target, inst) { 7837 var divSpan = $(target); 7838 if (divSpan.hasClass(this.markerClassName)) { 7839 return; 7840 } 7841 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 7842 $.data(target, PROP_NAME, inst); 7843 this._setDate(inst, this._getDefaultDate(inst), true); 7844 this._updateDatepicker(inst); 7845 this._updateAlternate(inst); 7846 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 7847 if( inst.settings.disabled ) { 7848 this._disableDatepicker( target ); 7849 } 7850 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 7851 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 7852 inst.dpDiv.css( "display", "block" ); 7853 }, 7854 7855 /* Pop-up the date picker in a "dialog" box. 7856 * @param input element - ignored 7857 * @param date string or Date - the initial date to display 7858 * @param onSelect function - the function to call when a date is selected 7859 * @param settings object - update the dialog date picker instance's settings (anonymous object) 7860 * @param pos int[2] - coordinates for the dialog's position within the screen or 7861 * event - with x/y coordinates or 7862 * leave empty for default (screen centre) 7863 * @return the manager object 7864 */ 7865 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 7866 var id, browserWidth, browserHeight, scrollX, scrollY, 7867 inst = this._dialogInst; // internal instance 7868 7869 if (!inst) { 7870 this.uuid += 1; 7871 id = "dp" + this.uuid; 7872 this._dialogInput = $("<input type='text' id='" + id + 7873 "' style='position: absolute; top: -100px; width: 0px;'/>"); 7874 this._dialogInput.keydown(this._doKeyDown); 7875 $("body").append(this._dialogInput); 7876 inst = this._dialogInst = this._newInst(this._dialogInput, false); 7877 inst.settings = {}; 7878 $.data(this._dialogInput[0], PROP_NAME, inst); 7879 } 7880 extendRemove(inst.settings, settings || {}); 7881 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 7882 this._dialogInput.val(date); 7883 7884 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 7885 if (!this._pos) { 7886 browserWidth = document.documentElement.clientWidth; 7887 browserHeight = document.documentElement.clientHeight; 7888 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 7889 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 7890 this._pos = // should use actual width/height below 7891 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 7892 } 7893 7894 // move input on screen for focus, but hidden behind dialog 7895 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 7896 inst.settings.onSelect = onSelect; 7897 this._inDialog = true; 7898 this.dpDiv.addClass(this._dialogClass); 7899 this._showDatepicker(this._dialogInput[0]); 7900 if ($.blockUI) { 7901 $.blockUI(this.dpDiv); 7902 } 7903 $.data(this._dialogInput[0], PROP_NAME, inst); 7904 return this; 7905 }, 7906 7907 /* Detach a datepicker from its control. 7908 * @param target element - the target input field or division or span 7909 */ 7910 _destroyDatepicker: function(target) { 7911 var nodeName, 7912 $target = $(target), 7913 inst = $.data(target, PROP_NAME); 7914 7915 if (!$target.hasClass(this.markerClassName)) { 7916 return; 7917 } 7918 7919 nodeName = target.nodeName.toLowerCase(); 7920 $.removeData(target, PROP_NAME); 7921 if (nodeName === "input") {
vendor: 15,212 bytes, lines 7922-8253
7922 inst.append.remove(); 7923 inst.trigger.remove(); 7924 $target.removeClass(this.markerClassName). 7925 unbind("focus", this._showDatepicker). 7926 unbind("keydown", this._doKeyDown). 7927 unbind("keypress", this._doKeyPress). 7928 unbind("keyup", this._doKeyUp); 7929 } else if (nodeName === "div" || nodeName === "span") { 7930 $target.removeClass(this.markerClassName).empty(); 7931 } 7932 }, 7933 7934 /* Enable the date picker to a jQuery selection. 7935 * @param target element - the target input field or division or span 7936 */ 7937 _enableDatepicker: function(target) { 7938 var nodeName, inline, 7939 $target = $(target), 7940 inst = $.data(target, PROP_NAME); 7941 7942 if (!$target.hasClass(this.markerClassName)) { 7943 return; 7944 } 7945 7946 nodeName = target.nodeName.toLowerCase(); 7947 if (nodeName === "input") { 7948 target.disabled = false; 7949 inst.trigger.filter("button"). 7950 each(function() { this.disabled = false; }).end(). 7951 filter("img").css({opacity: "1.0", cursor: ""}); 7952 } else if (nodeName === "div" || nodeName === "span") { 7953 inline = $target.children("." + this._inlineClass); 7954 inline.children().removeClass("ui-state-disabled"); 7955 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7956 prop("disabled", false); 7957 } 7958 this._disabledInputs = $.map(this._disabledInputs, 7959 function(value) { return (value === target ? null : value); }); // delete entry 7960 }, 7961 7962 /* Disable the date picker to a jQuery selection. 7963 * @param target element - the target input field or division or span 7964 */ 7965 _disableDatepicker: function(target) { 7966 var nodeName, inline, 7967 $target = $(target), 7968 inst = $.data(target, PROP_NAME); 7969 7970 if (!$target.hasClass(this.markerClassName)) { 7971 return; 7972 } 7973 7974 nodeName = target.nodeName.toLowerCase(); 7975 if (nodeName === "input") { 7976 target.disabled = true; 7977 inst.trigger.filter("button"). 7978 each(function() { this.disabled = true; }).end(). 7979 filter("img").css({opacity: "0.5", cursor: "default"}); 7980 } else if (nodeName === "div" || nodeName === "span") { 7981 inline = $target.children("." + this._inlineClass); 7982 inline.children().addClass("ui-state-disabled"); 7983 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 7984 prop("disabled", true); 7985 } 7986 this._disabledInputs = $.map(this._disabledInputs, 7987 function(value) { return (value === target ? null : value); }); // delete entry 7988 this._disabledInputs[this._disabledInputs.length] = target; 7989 }, 7990 7991 /* Is the first field in a jQuery collection disabled as a datepicker? 7992 * @param target element - the target input field or division or span 7993 * @return boolean - true if disabled, false if enabled 7994 */ 7995 _isDisabledDatepicker: function(target) { 7996 if (!target) { 7997 return false; 7998 } 7999 for (var i = 0; i < this._disabledInputs.length; i++) { 8000 if (this._disabledInputs[i] === target) { 8001 return true; 8002 } 8003 } 8004 return false; 8005 }, 8006 8007 /* Retrieve the instance data for the target control. 8008 * @param target element - the target input field or division or span 8009 * @return object - the associated instance data 8010 * @throws error if a jQuery problem getting data 8011 */ 8012 _getInst: function(target) { 8013 try { 8014 return $.data(target, PROP_NAME); 8015 } 8016 catch (err) { 8017 throw "Missing instance data for this datepicker"; 8018 } 8019 }, 8020 8021 /* Update or retrieve the settings for a date picker attached to an input field or division. 8022 * @param target element - the target input field or division or span 8023 * @param name object - the new settings to update or 8024 * string - the name of the setting to change or retrieve, 8025 * when retrieving also "all" for all instance settings or 8026 * "defaults" for all global defaults 8027 * @param value any - the new value for the setting 8028 * (omit if above is an object or to retrieve a value) 8029 */ 8030 _optionDatepicker: function(target, name, value) { 8031 var settings, date, minDate, maxDate, 8032 inst = this._getInst(target); 8033 8034 if (arguments.length === 2 && typeof name === "string") { 8035 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 8036 (inst ? (name === "all" ? $.extend({}, inst.settings) : 8037 this._get(inst, name)) : null)); 8038 } 8039 8040 settings = name || {}; 8041 if (typeof name === "string") { 8042 settings = {}; 8043 settings[name] = value; 8044 } 8045 8046 if (inst) { 8047 if (this._curInst === inst) { 8048 this._hideDatepicker(); 8049 } 8050 8051 date = this._getDateDatepicker(target, true); 8052 minDate = this._getMinMaxDate(inst, "min"); 8053 maxDate = this._getMinMaxDate(inst, "max"); 8054 extendRemove(inst.settings, settings); 8055 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8056 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 8057 inst.settings.minDate = this._formatDate(inst, minDate); 8058 } 8059 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 8060 inst.settings.maxDate = this._formatDate(inst, maxDate); 8061 } 8062 if ( "disabled" in settings ) { 8063 if ( settings.disabled ) { 8064 this._disableDatepicker(target); 8065 } else { 8066 this._enableDatepicker(target); 8067 } 8068 } 8069 this._attachments($(target), inst); 8070 this._autoSize(inst); 8071 this._setDate(inst, date); 8072 this._updateAlternate(inst); 8073 this._updateDatepicker(inst); 8074 } 8075 }, 8076 8077 // change method deprecated 8078 _changeDatepicker: function(target, name, value) { 8079 this._optionDatepicker(target, name, value); 8080 }, 8081 8082 /* Redraw the date picker attached to an input field or division. 8083 * @param target element - the target input field or division or span 8084 */ 8085 _refreshDatepicker: function(target) { 8086 var inst = this._getInst(target); 8087 if (inst) { 8088 this._updateDatepicker(inst); 8089 } 8090 }, 8091 8092 /* Set the dates for a jQuery selection. 8093 * @param target element - the target input field or division or span 8094 * @param date Date - the new date 8095 */ 8096 _setDateDatepicker: function(target, date) { 8097 var inst = this._getInst(target); 8098 if (inst) { 8099 this._setDate(inst, date); 8100 this._updateDatepicker(inst); 8101 this._updateAlternate(inst); 8102 } 8103 }, 8104 8105 /* Get the date(s) for the first entry in a jQuery selection. 8106 * @param target element - the target input field or division or span 8107 * @param noDefault boolean - true if no default date is to be used 8108 * @return Date - the current date 8109 */ 8110 _getDateDatepicker: function(target, noDefault) { 8111 var inst = this._getInst(target); 8112 if (inst && !inst.inline) { 8113 this._setDateFromField(inst, noDefault); 8114 } 8115 return (inst ? this._getDate(inst) : null); 8116 }, 8117 8118 /* Handle keystrokes. */ 8119 _doKeyDown: function(event) { 8120 var onSelect, dateStr, sel, 8121 inst = $.datepicker._getInst(event.target), 8122 handled = true, 8123 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 8124 8125 inst._keyEvent = true; 8126 if ($.datepicker._datepickerShowing) { 8127 switch (event.keyCode) { 8128 case 9: $.datepicker._hideDatepicker(); 8129 handled = false; 8130 break; // hide on tab out 8131 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 8132 $.datepicker._currentClass + ")", inst.dpDiv); 8133 if (sel[0]) { 8134 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 8135 } 8136 8137 onSelect = $.datepicker._get(inst, "onSelect"); 8138 if (onSelect) { 8139 dateStr = $.datepicker._formatDate(inst); 8140 8141 // trigger custom callback 8142 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 8143 } else { 8144 $.datepicker._hideDatepicker(); 8145 } 8146 8147 return false; // don't submit the form 8148 case 27: $.datepicker._hideDatepicker(); 8149 break; // hide on escape 8150 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8151 -$.datepicker._get(inst, "stepBigMonths") : 8152 -$.datepicker._get(inst, "stepMonths")), "M"); 8153 break; // previous month/year on page up/+ ctrl 8154 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8155 +$.datepicker._get(inst, "stepBigMonths") : 8156 +$.datepicker._get(inst, "stepMonths")), "M"); 8157 break; // next month/year on page down/+ ctrl 8158 case 35: if (event.ctrlKey || event.metaKey) { 8159 $.datepicker._clearDate(event.target); 8160 } 8161 handled = event.ctrlKey || event.metaKey; 8162 break; // clear on ctrl or command +end 8163 case 36: if (event.ctrlKey || event.metaKey) { 8164 $.datepicker._gotoToday(event.target); 8165 } 8166 handled = event.ctrlKey || event.metaKey; 8167 break; // current on ctrl or command +home 8168 case 37: if (event.ctrlKey || event.metaKey) { 8169 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 8170 } 8171 handled = event.ctrlKey || event.metaKey; 8172 // -1 day on ctrl or command +left 8173 if (event.originalEvent.altKey) { 8174 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8175 -$.datepicker._get(inst, "stepBigMonths") : 8176 -$.datepicker._get(inst, "stepMonths")), "M"); 8177 } 8178 // next month/year on alt +left on Mac 8179 break; 8180 case 38: if (event.ctrlKey || event.metaKey) { 8181 $.datepicker._adjustDate(event.target, -7, "D"); 8182 } 8183 handled = event.ctrlKey || event.metaKey; 8184 break; // -1 week on ctrl or command +up 8185 case 39: if (event.ctrlKey || event.metaKey) { 8186 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 8187 } 8188 handled = event.ctrlKey || event.metaKey; 8189 // +1 day on ctrl or command +right 8190 if (event.originalEvent.altKey) { 8191 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 8192 +$.datepicker._get(inst, "stepBigMonths") : 8193 +$.datepicker._get(inst, "stepMonths")), "M"); 8194 } 8195 // next month/year on alt +right 8196 break; 8197 case 40: if (event.ctrlKey || event.metaKey) { 8198 $.datepicker._adjustDate(event.target, +7, "D"); 8199 } 8200 handled = event.ctrlKey || event.metaKey; 8201 break; // +1 week on ctrl or command +down 8202 default: handled = false; 8203 } 8204 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 8205 $.datepicker._showDatepicker(this); 8206 } else { 8207 handled = false; 8208 } 8209 8210 if (handled) { 8211 event.preventDefault(); 8212 event.stopPropagation(); 8213 } 8214 }, 8215 8216 /* Filter entered characters - based on date format. */ 8217 _doKeyPress: function(event) { 8218 var chars, chr, 8219 inst = $.datepicker._getInst(event.target); 8220 8221 if ($.datepicker._get(inst, "constrainInput")) { 8222 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 8223 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 8224 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 8225 } 8226 }, 8227 8228 /* Synchronise manual entry and field/alternate field. */ 8229 _doKeyUp: function(event) { 8230 var date, 8231 inst = $.datepicker._getInst(event.target); 8232 8233 if (inst.input.val() !== inst.lastVal) { 8234 try { 8235 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 8236 (inst.input ? inst.input.val() : null), 8237 $.datepicker._getFormatConfig(inst)); 8238 8239 if (date) { // only if valid 8240 $.datepicker._setDateFromField(inst); 8241 $.datepicker._updateAlternate(inst); 8242 $.datepicker._updateDatepicker(inst); 8243 } 8244 } 8245 catch (err) { 8246 } 8247 } 8248 return true; 8249 }, 8250 8251 /* Pop-up the date picker for a given input field. 8252 * If false returned from beforeShow event handler do not show. 8253 * @param input element - the input field attached to the date picker or
vendor: 16,744 bytes, lines 8254-8639
8254 * event - if triggered by focus 8255 */ 8256 _showDatepicker: function(input) { 8257 input = input.target || input; 8258 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 8259 input = $("input", input.parentNode)[0]; 8260 } 8261 8262 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 8263 return; 8264 } 8265 8266 var inst, beforeShow, beforeShowSettings, isFixed, 8267 offset, showAnim, duration; 8268 8269 inst = $.datepicker._getInst(input); 8270 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 8271 $.datepicker._curInst.dpDiv.stop(true, true); 8272 if ( inst && $.datepicker._datepickerShowing ) { 8273 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 8274 } 8275 } 8276 8277 beforeShow = $.datepicker._get(inst, "beforeShow"); 8278 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 8279 if(beforeShowSettings === false){ 8280 return; 8281 } 8282 extendRemove(inst.settings, beforeShowSettings); 8283 8284 inst.lastVal = null; 8285 $.datepicker._lastInput = input; 8286 $.datepicker._setDateFromField(inst); 8287 8288 if ($.datepicker._inDialog) { // hide cursor 8289 input.value = ""; 8290 } 8291 if (!$.datepicker._pos) { // position below input 8292 $.datepicker._pos = $.datepicker._findPos(input); 8293 $.datepicker._pos[1] += input.offsetHeight; // add the height 8294 } 8295 8296 isFixed = false; 8297 $(input).parents().each(function() { 8298 isFixed |= $(this).css("position") === "fixed"; 8299 return !isFixed; 8300 }); 8301 8302 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 8303 $.datepicker._pos = null; 8304 //to avoid flashes on Firefox 8305 inst.dpDiv.empty(); 8306 // determine sizing offscreen 8307 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 8308 $.datepicker._updateDatepicker(inst); 8309 // fix width for dynamic number of date pickers 8310 // and adjust position before showing 8311 offset = $.datepicker._checkOffset(inst, offset, isFixed); 8312 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 8313 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 8314 left: offset.left + "px", top: offset.top + "px"}); 8315 8316 if (!inst.inline) { 8317 showAnim = $.datepicker._get(inst, "showAnim"); 8318 duration = $.datepicker._get(inst, "duration"); 8319 inst.dpDiv.zIndex($(input).zIndex()+1); 8320 $.datepicker._datepickerShowing = true; 8321 8322 if ( $.effects && $.effects.effect[ showAnim ] ) { 8323 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 8324 } else { 8325 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 8326 } 8327 8328 if (inst.input.is(":visible") && !inst.input.is(":disabled")) { 8329 inst.input.focus(); 8330 } 8331 $.datepicker._curInst = inst; 8332 } 8333 }, 8334 8335 /* Generate the date picker content. */ 8336 _updateDatepicker: function(inst) { 8337 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8338 instActive = inst; // for delegate hover events 8339 inst.dpDiv.empty().append(this._generateHTML(inst)); 8340 this._attachHandlers(inst); 8341 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 8342 8343 var origyearshtml, 8344 numMonths = this._getNumberOfMonths(inst), 8345 cols = numMonths[1], 8346 width = 17; 8347 8348 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 8349 if (cols > 1) { 8350 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 8351 } 8352 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 8353 "Class"]("ui-datepicker-multi"); 8354 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 8355 "Class"]("ui-datepicker-rtl"); 8356 8357 // #6694 - don't focus the input if it's already focused 8358 // this breaks the change event in IE 8359 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 8360 inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) { 8361 inst.input.focus(); 8362 } 8363 8364 // deffered render of the years select (to avoid flashes on Firefox) 8365 if( inst.yearshtml ){ 8366 origyearshtml = inst.yearshtml; 8367 setTimeout(function(){ 8368 //assure that inst.yearshtml didn't change. 8369 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 8370 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 8371 } 8372 origyearshtml = inst.yearshtml = null; 8373 }, 0); 8374 } 8375 }, 8376 8377 /* Retrieve the size of left and top borders for an element. 8378 * @param elem (jQuery object) the element of interest 8379 * @return (number[2]) the left and top borders 8380 */ 8381 _getBorders: function(elem) { 8382 var convert = function(value) { 8383 return {thin: 1, medium: 2, thick: 3}[value] || value; 8384 }; 8385 return [parseFloat(convert(elem.css("border-left-width"))), 8386 parseFloat(convert(elem.css("border-top-width")))]; 8387 }, 8388 8389 /* Check positioning to remain on screen. */ 8390 _checkOffset: function(inst, offset, isFixed) { 8391 var dpWidth = inst.dpDiv.outerWidth(), 8392 dpHeight = inst.dpDiv.outerHeight(), 8393 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8394 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8395 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 8396 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 8397 8398 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 8399 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 8400 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 8401 8402 // now check if datepicker is showing outside window viewport - move to a better place if so. 8403 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 8404 Math.abs(offset.left + dpWidth - viewWidth) : 0); 8405 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 8406 Math.abs(dpHeight + inputHeight) : 0); 8407 8408 return offset; 8409 }, 8410 8411 /* Find an object's position on the screen. */ 8412 _findPos: function(obj) { 8413 var position, 8414 inst = this._getInst(obj), 8415 isRTL = this._get(inst, "isRTL"); 8416 8417 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 8418 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 8419 } 8420 8421 position = $(obj).offset(); 8422 return [position.left, position.top]; 8423 }, 8424 8425 /* Hide the date picker from view. 8426 * @param input element - the input field attached to the date picker 8427 */ 8428 _hideDatepicker: function(input) { 8429 var showAnim, duration, postProcess, onClose, 8430 inst = this._curInst; 8431 8432 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 8433 return; 8434 } 8435 8436 if (this._datepickerShowing) { 8437 showAnim = this._get(inst, "showAnim"); 8438 duration = this._get(inst, "duration"); 8439 postProcess = function() { 8440 $.datepicker._tidyDialog(inst); 8441 }; 8442 8443 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 8444 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 8445 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 8446 } else { 8447 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 8448 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 8449 } 8450 8451 if (!showAnim) { 8452 postProcess(); 8453 } 8454 this._datepickerShowing = false; 8455 8456 onClose = this._get(inst, "onClose"); 8457 if (onClose) { 8458 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 8459 } 8460 8461 this._lastInput = null; 8462 if (this._inDialog) { 8463 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 8464 if ($.blockUI) { 8465 $.unblockUI(); 8466 $("body").append(this.dpDiv); 8467 } 8468 } 8469 this._inDialog = false; 8470 } 8471 }, 8472 8473 /* Tidy up after a dialog display. */ 8474 _tidyDialog: function(inst) { 8475 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 8476 }, 8477 8478 /* Close date picker if clicked elsewhere. */ 8479 _checkExternalClick: function(event) { 8480 if (!$.datepicker._curInst) { 8481 return; 8482 } 8483 8484 var $target = $(event.target), 8485 inst = $.datepicker._getInst($target[0]); 8486 8487 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 8488 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 8489 !$target.hasClass($.datepicker.markerClassName) && 8490 !$target.closest("." + $.datepicker._triggerClass).length && 8491 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 8492 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 8493 $.datepicker._hideDatepicker(); 8494 } 8495 }, 8496 8497 /* Adjust one of the date sub-fields. */ 8498 _adjustDate: function(id, offset, period) { 8499 var target = $(id), 8500 inst = this._getInst(target[0]); 8501 8502 if (this._isDisabledDatepicker(target[0])) { 8503 return; 8504 } 8505 this._adjustInstDate(inst, offset + 8506 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 8507 period); 8508 this._updateDatepicker(inst); 8509 }, 8510 8511 /* Action for current link. */ 8512 _gotoToday: function(id) { 8513 var date, 8514 target = $(id), 8515 inst = this._getInst(target[0]); 8516 8517 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 8518 inst.selectedDay = inst.currentDay; 8519 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8520 inst.drawYear = inst.selectedYear = inst.currentYear; 8521 } else { 8522 date = new Date(); 8523 inst.selectedDay = date.getDate(); 8524 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8525 inst.drawYear = inst.selectedYear = date.getFullYear(); 8526 } 8527 this._notifyChange(inst); 8528 this._adjustDate(target); 8529 }, 8530 8531 /* Action for selecting a new month/year. */ 8532 _selectMonthYear: function(id, select, period) { 8533 var target = $(id), 8534 inst = this._getInst(target[0]); 8535 8536 inst["selected" + (period === "M" ? "Month" : "Year")] = 8537 inst["draw" + (period === "M" ? "Month" : "Year")] = 8538 parseInt(select.options[select.selectedIndex].value,10); 8539 8540 this._notifyChange(inst); 8541 this._adjustDate(target); 8542 }, 8543 8544 /* Action for selecting a day. */ 8545 _selectDay: function(id, month, year, td) { 8546 var inst, 8547 target = $(id); 8548 8549 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 8550 return; 8551 } 8552 8553 inst = this._getInst(target[0]); 8554 inst.selectedDay = inst.currentDay = $("a", td).html(); 8555 inst.selectedMonth = inst.currentMonth = month; 8556 inst.selectedYear = inst.currentYear = year; 8557 this._selectDate(id, this._formatDate(inst, 8558 inst.currentDay, inst.currentMonth, inst.currentYear)); 8559 }, 8560 8561 /* Erase the input field and hide the date picker. */ 8562 _clearDate: function(id) { 8563 var target = $(id); 8564 this._selectDate(target, ""); 8565 }, 8566 8567 /* Update the input field with the selected date. */ 8568 _selectDate: function(id, dateStr) { 8569 var onSelect, 8570 target = $(id), 8571 inst = this._getInst(target[0]); 8572 8573 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 8574 if (inst.input) { 8575 inst.input.val(dateStr); 8576 } 8577 this._updateAlternate(inst); 8578 8579 onSelect = this._get(inst, "onSelect"); 8580 if (onSelect) { 8581 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 8582 } else if (inst.input) { 8583 inst.input.trigger("change"); // fire the change event 8584 } 8585 8586 if (inst.inline){ 8587 this._updateDatepicker(inst); 8588 } else { 8589 this._hideDatepicker(); 8590 this._lastInput = inst.input[0]; 8591 if (typeof(inst.input[0]) !== "object") { 8592 inst.input.focus(); // restore focus 8593 } 8594 this._lastInput = null; 8595 } 8596 }, 8597 8598 /* Update any alternate field to synchronise with the main field. */ 8599 _updateAlternate: function(inst) { 8600 var altFormat, date, dateStr, 8601 altField = this._get(inst, "altField"); 8602 8603 if (altField) { // update alternate field too 8604 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 8605 date = this._getDate(inst); 8606 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 8607 $(altField).each(function() { $(this).val(dateStr); }); 8608 } 8609 }, 8610 8611 /* Set as beforeShowDay function to prevent selection of weekends. 8612 * @param date Date - the date to customise 8613 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8614 */ 8615 noWeekends: function(date) { 8616 var day = date.getDay(); 8617 return [(day > 0 && day < 6), ""]; 8618 }, 8619 8620 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8621 * @param date Date - the date to get the week for 8622 * @return number - the number of the week within the year that contains this date 8623 */ 8624 iso8601Week: function(date) { 8625 var time, 8626 checkDate = new Date(date.getTime()); 8627 8628 // Find Thursday of this week starting on Monday 8629 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 8630 8631 time = checkDate.getTime(); 8632 checkDate.setMonth(0); // Compare with Jan 1 8633 checkDate.setDate(1); 8634 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 8635 }, 8636 8637 /* Parse a string value into a date object. 8638 * See formatDate below for the possible formats. 8639 *
vendor: 20,316 bytes, lines 8640-9085
8640 * @param format string - the expected format of the date 8641 * @param value string - the date in the above format 8642 * @param settings Object - attributes include: 8643 * shortYearCutoff number - the cutoff year for determining the century (optional) 8644 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8645 * dayNames string[7] - names of the days from Sunday (optional) 8646 * monthNamesShort string[12] - abbreviated names of the months (optional) 8647 * monthNames string[12] - names of the months (optional) 8648 * @return Date - the extracted date value or null if value is blank 8649 */ 8650 parseDate: function (format, value, settings) { 8651 if (format == null || value == null) { 8652 throw "Invalid arguments"; 8653 } 8654 8655 value = (typeof value === "object" ? value.toString() : value + ""); 8656 if (value === "") { 8657 return null; 8658 } 8659 8660 var iFormat, dim, extra, 8661 iValue = 0, 8662 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 8663 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 8664 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 8665 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8666 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8667 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8668 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8669 year = -1, 8670 month = -1, 8671 day = -1, 8672 doy = -1, 8673 literal = false, 8674 date, 8675 // Check whether a format character is doubled 8676 lookAhead = function(match) { 8677 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8678 if (matches) { 8679 iFormat++; 8680 } 8681 return matches; 8682 }, 8683 // Extract a number from the string value 8684 getNumber = function(match) { 8685 var isDoubled = lookAhead(match), 8686 size = (match === "@" ? 14 : (match === "!" ? 20 : 8687 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 8688 digits = new RegExp("^\\d{1," + size + "}"), 8689 num = value.substring(iValue).match(digits); 8690 if (!num) { 8691 throw "Missing number at position " + iValue; 8692 } 8693 iValue += num[0].length; 8694 return parseInt(num[0], 10); 8695 }, 8696 // Extract a name from the string value and convert to an index 8697 getName = function(match, shortNames, longNames) { 8698 var index = -1, 8699 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 8700 return [ [k, v] ]; 8701 }).sort(function (a, b) { 8702 return -(a[1].length - b[1].length); 8703 }); 8704 8705 $.each(names, function (i, pair) { 8706 var name = pair[1]; 8707 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 8708 index = pair[0]; 8709 iValue += name.length; 8710 return false; 8711 } 8712 }); 8713 if (index !== -1) { 8714 return index + 1; 8715 } else { 8716 throw "Unknown name at position " + iValue; 8717 } 8718 }, 8719 // Confirm that a literal character matches the string value 8720 checkLiteral = function() { 8721 if (value.charAt(iValue) !== format.charAt(iFormat)) { 8722 throw "Unexpected literal at position " + iValue; 8723 } 8724 iValue++; 8725 }; 8726 8727 for (iFormat = 0; iFormat < format.length; iFormat++) { 8728 if (literal) { 8729 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8730 literal = false; 8731 } else { 8732 checkLiteral(); 8733 } 8734 } else { 8735 switch (format.charAt(iFormat)) { 8736 case "d": 8737 day = getNumber("d"); 8738 break; 8739 case "D": 8740 getName("D", dayNamesShort, dayNames); 8741 break; 8742 case "o": 8743 doy = getNumber("o"); 8744 break; 8745 case "m": 8746 month = getNumber("m"); 8747 break; 8748 case "M": 8749 month = getName("M", monthNamesShort, monthNames); 8750 break; 8751 case "y": 8752 year = getNumber("y"); 8753 break; 8754 case "@": 8755 date = new Date(getNumber("@")); 8756 year = date.getFullYear(); 8757 month = date.getMonth() + 1; 8758 day = date.getDate(); 8759 break; 8760 case "!": 8761 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 8762 year = date.getFullYear(); 8763 month = date.getMonth() + 1; 8764 day = date.getDate(); 8765 break; 8766 case "'": 8767 if (lookAhead("'")){ 8768 checkLiteral(); 8769 } else { 8770 literal = true; 8771 } 8772 break; 8773 default: 8774 checkLiteral(); 8775 } 8776 } 8777 } 8778 8779 if (iValue < value.length){ 8780 extra = value.substr(iValue); 8781 if (!/^\s+/.test(extra)) { 8782 throw "Extra/unparsed characters found in date: " + extra; 8783 } 8784 } 8785 8786 if (year === -1) { 8787 year = new Date().getFullYear(); 8788 } else if (year < 100) { 8789 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 8790 (year <= shortYearCutoff ? 0 : -100); 8791 } 8792 8793 if (doy > -1) { 8794 month = 1; 8795 day = doy; 8796 do { 8797 dim = this._getDaysInMonth(year, month - 1); 8798 if (day <= dim) { 8799 break; 8800 } 8801 month++; 8802 day -= dim; 8803 } while (true); 8804 } 8805 8806 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 8807 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 8808 throw "Invalid date"; // E.g. 31/02/00 8809 } 8810 return date; 8811 }, 8812 8813 /* Standard date formats. */ 8814 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 8815 COOKIE: "D, dd M yy", 8816 ISO_8601: "yy-mm-dd", 8817 RFC_822: "D, d M y", 8818 RFC_850: "DD, dd-M-y", 8819 RFC_1036: "D, d M y", 8820 RFC_1123: "D, d M yy", 8821 RFC_2822: "D, d M yy", 8822 RSS: "D, d M y", // RFC 822 8823 TICKS: "!", 8824 TIMESTAMP: "@", 8825 W3C: "yy-mm-dd", // ISO 8601 8826 8827 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 8828 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 8829 8830 /* Format a date object into a string value. 8831 * The format can be combinations of the following: 8832 * d - day of month (no leading zero) 8833 * dd - day of month (two digit) 8834 * o - day of year (no leading zeros) 8835 * oo - day of year (three digit) 8836 * D - day name short 8837 * DD - day name long 8838 * m - month of year (no leading zero) 8839 * mm - month of year (two digit) 8840 * M - month name short 8841 * MM - month name long 8842 * y - year (two digit) 8843 * yy - year (four digit) 8844 * @ - Unix timestamp (ms since 01/01/1970) 8845 * ! - Windows ticks (100ns since 01/01/0001) 8846 * "..." - literal text 8847 * '' - single quote 8848 * 8849 * @param format string - the desired format of the date 8850 * @param date Date - the date value to format 8851 * @param settings Object - attributes include: 8852 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8853 * dayNames string[7] - names of the days from Sunday (optional) 8854 * monthNamesShort string[12] - abbreviated names of the months (optional) 8855 * monthNames string[12] - names of the months (optional) 8856 * @return string - the date in the above format 8857 */ 8858 formatDate: function (format, date, settings) { 8859 if (!date) { 8860 return ""; 8861 } 8862 8863 var iFormat, 8864 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 8865 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 8866 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 8867 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 8868 // Check whether a format character is doubled 8869 lookAhead = function(match) { 8870 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8871 if (matches) { 8872 iFormat++; 8873 } 8874 return matches; 8875 }, 8876 // Format a number, with leading zero if necessary 8877 formatNumber = function(match, value, len) { 8878 var num = "" + value; 8879 if (lookAhead(match)) { 8880 while (num.length < len) { 8881 num = "0" + num; 8882 } 8883 } 8884 return num; 8885 }, 8886 // Format a name, short or long as requested 8887 formatName = function(match, value, shortNames, longNames) { 8888 return (lookAhead(match) ? longNames[value] : shortNames[value]); 8889 }, 8890 output = "", 8891 literal = false; 8892 8893 if (date) { 8894 for (iFormat = 0; iFormat < format.length; iFormat++) { 8895 if (literal) { 8896 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8897 literal = false; 8898 } else { 8899 output += format.charAt(iFormat); 8900 } 8901 } else { 8902 switch (format.charAt(iFormat)) { 8903 case "d": 8904 output += formatNumber("d", date.getDate(), 2); 8905 break; 8906 case "D": 8907 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 8908 break; 8909 case "o": 8910 output += formatNumber("o", 8911 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 8912 break; 8913 case "m": 8914 output += formatNumber("m", date.getMonth() + 1, 2); 8915 break; 8916 case "M": 8917 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 8918 break; 8919 case "y": 8920 output += (lookAhead("y") ? date.getFullYear() : 8921 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 8922 break; 8923 case "@": 8924 output += date.getTime(); 8925 break; 8926 case "!": 8927 output += date.getTime() * 10000 + this._ticksTo1970; 8928 break; 8929 case "'": 8930 if (lookAhead("'")) { 8931 output += "'"; 8932 } else { 8933 literal = true; 8934 } 8935 break; 8936 default: 8937 output += format.charAt(iFormat); 8938 } 8939 } 8940 } 8941 } 8942 return output; 8943 }, 8944 8945 /* Extract all possible characters from the date format. */ 8946 _possibleChars: function (format) { 8947 var iFormat, 8948 chars = "", 8949 literal = false, 8950 // Check whether a format character is doubled 8951 lookAhead = function(match) { 8952 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 8953 if (matches) { 8954 iFormat++; 8955 } 8956 return matches; 8957 }; 8958 8959 for (iFormat = 0; iFormat < format.length; iFormat++) { 8960 if (literal) { 8961 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 8962 literal = false; 8963 } else { 8964 chars += format.charAt(iFormat); 8965 } 8966 } else { 8967 switch (format.charAt(iFormat)) { 8968 case "d": case "m": case "y": case "@": 8969 chars += "0123456789"; 8970 break; 8971 case "D": case "M": 8972 return null; // Accept anything 8973 case "'": 8974 if (lookAhead("'")) { 8975 chars += "'"; 8976 } else { 8977 literal = true; 8978 } 8979 break; 8980 default: 8981 chars += format.charAt(iFormat); 8982 } 8983 } 8984 } 8985 return chars; 8986 }, 8987 8988 /* Get a setting value, defaulting if necessary. */ 8989 _get: function(inst, name) { 8990 return inst.settings[name] !== undefined ? 8991 inst.settings[name] : this._defaults[name]; 8992 }, 8993 8994 /* Parse existing date and initialise date picker. */ 8995 _setDateFromField: function(inst, noDefault) { 8996 if (inst.input.val() === inst.lastVal) { 8997 return; 8998 } 8999 9000 var dateFormat = this._get(inst, "dateFormat"), 9001 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9002 defaultDate = this._getDefaultDate(inst), 9003 date = defaultDate, 9004 settings = this._getFormatConfig(inst); 9005 9006 try { 9007 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 9008 } catch (event) { 9009 dates = (noDefault ? "" : dates); 9010 } 9011 inst.selectedDay = date.getDate(); 9012 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9013 inst.drawYear = inst.selectedYear = date.getFullYear(); 9014 inst.currentDay = (dates ? date.getDate() : 0); 9015 inst.currentMonth = (dates ? date.getMonth() : 0); 9016 inst.currentYear = (dates ? date.getFullYear() : 0); 9017 this._adjustInstDate(inst); 9018 }, 9019 9020 /* Retrieve the default date shown on opening. */ 9021 _getDefaultDate: function(inst) { 9022 return this._restrictMinMax(inst, 9023 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 9024 }, 9025 9026 /* A date may be specified as an exact value or a relative one. */ 9027 _determineDate: function(inst, date, defaultDate) { 9028 var offsetNumeric = function(offset) { 9029 var date = new Date(); 9030 date.setDate(date.getDate() + offset); 9031 return date; 9032 }, 9033 offsetString = function(offset) { 9034 try { 9035 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 9036 offset, $.datepicker._getFormatConfig(inst)); 9037 } 9038 catch (e) { 9039 // Ignore 9040 } 9041 9042 var date = (offset.toLowerCase().match(/^c/) ? 9043 $.datepicker._getDate(inst) : null) || new Date(), 9044 year = date.getFullYear(), 9045 month = date.getMonth(), 9046 day = date.getDate(), 9047 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9048 matches = pattern.exec(offset); 9049 9050 while (matches) { 9051 switch (matches[2] || "d") { 9052 case "d" : case "D" : 9053 day += parseInt(matches[1],10); break; 9054 case "w" : case "W" : 9055 day += parseInt(matches[1],10) * 7; break; 9056 case "m" : case "M" : 9057 month += parseInt(matches[1],10); 9058 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9059 break; 9060 case "y": case "Y" : 9061 year += parseInt(matches[1],10); 9062 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 9063 break; 9064 } 9065 matches = pattern.exec(offset); 9066 } 9067 return new Date(year, month, day); 9068 }, 9069 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 9070 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 9071 9072 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 9073 if (newDate) { 9074 newDate.setHours(0); 9075 newDate.setMinutes(0); 9076 newDate.setSeconds(0); 9077 newDate.setMilliseconds(0); 9078 } 9079 return this._daylightSavingAdjust(newDate); 9080 }, 9081 9082 /* Handle switch to/from daylight saving. 9083 * Hours may be non-zero on daylight saving cut-over: 9084 * > 12 when midnight changeover, but then cannot generate 9085 * midnight datetime, so jump to 1AM, otherwise reset.
vendor: 20,924 bytes, lines 9086-9419
9086 * @param date (Date) the date to check 9087 * @return (Date) the corrected date 9088 */ 9089 _daylightSavingAdjust: function(date) { 9090 if (!date) { 9091 return null; 9092 } 9093 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 9094 return date; 9095 }, 9096 9097 /* Set the date(s) directly. */ 9098 _setDate: function(inst, date, noChange) { 9099 var clear = !date, 9100 origMonth = inst.selectedMonth, 9101 origYear = inst.selectedYear, 9102 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 9103 9104 inst.selectedDay = inst.currentDay = newDate.getDate(); 9105 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9106 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9107 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 9108 this._notifyChange(inst); 9109 } 9110 this._adjustInstDate(inst); 9111 if (inst.input) { 9112 inst.input.val(clear ? "" : this._formatDate(inst)); 9113 } 9114 }, 9115 9116 /* Retrieve the date(s) directly. */ 9117 _getDate: function(inst) { 9118 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 9119 this._daylightSavingAdjust(new Date( 9120 inst.currentYear, inst.currentMonth, inst.currentDay))); 9121 return startDate; 9122 }, 9123 9124 /* Attach the onxxx handlers. These are declared statically so 9125 * they work with static code transformers like Caja. 9126 */ 9127 _attachHandlers: function(inst) { 9128 var stepMonths = this._get(inst, "stepMonths"), 9129 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9130 inst.dpDiv.find("[data-handler]").map(function () { 9131 var handler = { 9132 prev: function () { 9133 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M"); 9134 }, 9135 next: function () { 9136 window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M"); 9137 }, 9138 hide: function () { 9139 window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker(); 9140 }, 9141 today: function () { 9142 window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id); 9143 }, 9144 selectDay: function () { 9145 window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 9146 return false; 9147 }, 9148 selectMonth: function () { 9149 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M"); 9150 return false; 9151 }, 9152 selectYear: function () { 9153 window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y"); 9154 return false; 9155 } 9156 }; 9157 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 9158 }); 9159 }, 9160 9161 /* Generate the HTML for the current state of the date picker. */ 9162 _generateHTML: function(inst) { 9163 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 9164 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9165 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9166 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9167 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9168 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9169 tempDate = new Date(), 9170 today = this._daylightSavingAdjust( 9171 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 9172 isRTL = this._get(inst, "isRTL"), 9173 showButtonPanel = this._get(inst, "showButtonPanel"), 9174 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 9175 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 9176 numMonths = this._getNumberOfMonths(inst), 9177 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 9178 stepMonths = this._get(inst, "stepMonths"), 9179 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 9180 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 9181 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 9182 minDate = this._getMinMaxDate(inst, "min"), 9183 maxDate = this._getMinMaxDate(inst, "max"), 9184 drawMonth = inst.drawMonth - showCurrentAtPos, 9185 drawYear = inst.drawYear; 9186 9187 if (drawMonth < 0) { 9188 drawMonth += 12; 9189 drawYear--; 9190 } 9191 if (maxDate) { 9192 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 9193 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 9194 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 9195 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 9196 drawMonth--; 9197 if (drawMonth < 0) { 9198 drawMonth = 11; 9199 drawYear--; 9200 } 9201 } 9202 } 9203 inst.drawMonth = drawMonth; 9204 inst.drawYear = drawYear; 9205 9206 prevText = this._get(inst, "prevText"); 9207 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 9208 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 9209 this._getFormatConfig(inst))); 9210 9211 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 9212 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 9213 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 9214 (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>")); 9215 9216 nextText = this._get(inst, "nextText"); 9217 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 9218 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 9219 this._getFormatConfig(inst))); 9220 9221 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 9222 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 9223 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 9224 (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>")); 9225 9226 currentText = this._get(inst, "currentText"); 9227 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 9228 currentText = (!navigationAsDateFormat ? currentText : 9229 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 9230 9231 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'>" + 9232 this._get(inst, "closeText") + "</button>" : ""); 9233 9234 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 9235 (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'" + 9236 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 9237 9238 firstDay = parseInt(this._get(inst, "firstDay"),10); 9239 firstDay = (isNaN(firstDay) ? 0 : firstDay); 9240 9241 showWeek = this._get(inst, "showWeek"); 9242 dayNames = this._get(inst, "dayNames"); 9243 dayNamesMin = this._get(inst, "dayNamesMin"); 9244 monthNames = this._get(inst, "monthNames"); 9245 monthNamesShort = this._get(inst, "monthNamesShort"); 9246 beforeShowDay = this._get(inst, "beforeShowDay"); 9247 showOtherMonths = this._get(inst, "showOtherMonths"); 9248 selectOtherMonths = this._get(inst, "selectOtherMonths"); 9249 defaultDate = this._getDefaultDate(inst); 9250 html = ""; 9251 dow; 9252 for (row = 0; row < numMonths[0]; row++) { 9253 group = ""; 9254 this.maxRows = 4; 9255 for (col = 0; col < numMonths[1]; col++) { 9256 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 9257 cornerClass = " ui-corner-all"; 9258 calender = ""; 9259 if (isMultiMonth) { 9260 calender += "<div class='ui-datepicker-group"; 9261 if (numMonths[1] > 1) { 9262 switch (col) { 9263 case 0: calender += " ui-datepicker-group-first"; 9264 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 9265 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 9266 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 9267 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9268 } 9269 } 9270 calender += "'>"; 9271 } 9272 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9273 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 9274 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 9275 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 9276 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 9277 "</div><table class='ui-datepicker-calendar'><thead>" + 9278 "<tr>"; 9279 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 9280 for (dow = 0; dow < 7; dow++) { // days of the week 9281 day = (dow + firstDay) % 7; 9282 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 9283 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 9284 } 9285 calender += thead + "</tr></thead><tbody>"; 9286 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 9287 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 9288 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 9289 } 9290 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 9291 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 9292 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 9293 this.maxRows = numRows; 9294 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 9295 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 9296 calender += "<tr>"; 9297 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9298 this._get(inst, "calculateWeek")(printDate) + "</td>"); 9299 for (dow = 0; dow < 7; dow++) { // create date picker days 9300 daySettings = (beforeShowDay ? 9301 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 9302 otherMonth = (printDate.getMonth() !== drawMonth); 9303 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 9304 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 9305 tbody += "<td class='" + 9306 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 9307 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 9308 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 9309 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 9310 // or defaultDate is current printedDate and defaultDate is selectedDate 9311 " " + this._dayOverClass : "") + // highlight selected day 9312 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 9313 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 9314 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 9315 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 9316 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 9317 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 9318 (otherMonth && !showOtherMonths ? " " : // display for other months 9319 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9320 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 9321 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 9322 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 9323 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 9324 printDate.setDate(printDate.getDate() + 1); 9325 printDate = this._daylightSavingAdjust(printDate); 9326 } 9327 calender += tbody + "</tr>"; 9328 } 9329 drawMonth++; 9330 if (drawMonth > 11) { 9331 drawMonth = 0; 9332 drawYear++; 9333 } 9334 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 9335 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 9336 group += calender; 9337 } 9338 html += group; 9339 } 9340 html += buttonPanel; 9341 inst._keyEvent = false; 9342 return html; 9343 }, 9344 9345 /* Generate the month and year header. */ 9346 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 9347 secondary, monthNames, monthNamesShort) { 9348 9349 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9350 changeMonth = this._get(inst, "changeMonth"), 9351 changeYear = this._get(inst, "changeYear"), 9352 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 9353 html = "<div class='ui-datepicker-title'>", 9354 monthHtml = ""; 9355 9356 // month selection 9357 if (secondary || !changeMonth) { 9358 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 9359 } else { 9360 inMinYear = (minDate && minDate.getFullYear() === drawYear); 9361 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 9362 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 9363 for ( month = 0; month < 12; month++) { 9364 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 9365 monthHtml += "<option value='" + month + "'" + 9366 (month === drawMonth ? " selected='selected'" : "") + 9367 ">" + monthNamesShort[month] + "</option>"; 9368 } 9369 } 9370 monthHtml += "</select>"; 9371 } 9372 9373 if (!showMonthAfterYear) { 9374 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 9375 } 9376 9377 // year selection 9378 if ( !inst.yearshtml ) { 9379 inst.yearshtml = ""; 9380 if (secondary || !changeYear) { 9381 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9382 } else { 9383 // determine range of years to display 9384 years = this._get(inst, "yearRange").split(":"); 9385 thisYear = new Date().getFullYear(); 9386 determineYear = function(value) { 9387 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 9388 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 9389 parseInt(value, 10))); 9390 return (isNaN(year) ? thisYear : year); 9391 }; 9392 year = determineYear(years[0]); 9393 endYear = Math.max(year, determineYear(years[1] || "")); 9394 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 9395 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 9396 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 9397 for (; year <= endYear; year++) { 9398 inst.yearshtml += "<option value='" + year + "'" + 9399 (year === drawYear ? " selected='selected'" : "") + 9400 ">" + year + "</option>"; 9401 } 9402 inst.yearshtml += "</select>"; 9403 9404 html += inst.yearshtml; 9405 inst.yearshtml = null; 9406 } 9407 } 9408 9409 html += this._get(inst, "yearSuffix"); 9410 if (showMonthAfterYear) { 9411 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 9412 } 9413 html += "</div>"; // Close datepicker_header 9414 return html; 9415 }, 9416 9417 /* Adjust one of the date sub-fields. */ 9418 _adjustInstDate: function(inst, offset, period) { 9419 var year = inst.drawYear + (period === "Y" ? offset : 0),
vendor: 5,347 bytes, lines 9420-9531
9420 month = inst.drawMonth + (period === "M" ? offset : 0), 9421 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 9422 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 9423 9424 inst.selectedDay = date.getDate(); 9425 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9426 inst.drawYear = inst.selectedYear = date.getFullYear(); 9427 if (period === "M" || period === "Y") { 9428 this._notifyChange(inst); 9429 } 9430 }, 9431 9432 /* Ensure a date is within any min/max bounds. */ 9433 _restrictMinMax: function(inst, date) { 9434 var minDate = this._getMinMaxDate(inst, "min"), 9435 maxDate = this._getMinMaxDate(inst, "max"), 9436 newDate = (minDate && date < minDate ? minDate : date); 9437 return (maxDate && newDate > maxDate ? maxDate : newDate); 9438 }, 9439 9440 /* Notify change of month/year. */ 9441 _notifyChange: function(inst) { 9442 var onChange = this._get(inst, "onChangeMonthYear"); 9443 if (onChange) { 9444 onChange.apply((inst.input ? inst.input[0] : null), 9445 [inst.selectedYear, inst.selectedMonth + 1, inst]); 9446 } 9447 }, 9448 9449 /* Determine the number of months to show. */ 9450 _getNumberOfMonths: function(inst) { 9451 var numMonths = this._get(inst, "numberOfMonths"); 9452 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 9453 }, 9454 9455 /* Determine the current maximum date - ensure no time components are set. */ 9456 _getMinMaxDate: function(inst, minMax) { 9457 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 9458 }, 9459 9460 /* Find the number of days in a given month. */ 9461 _getDaysInMonth: function(year, month) { 9462 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 9463 }, 9464 9465 /* Find the day of the week of the first of a month. */ 9466 _getFirstDayOfMonth: function(year, month) { 9467 return new Date(year, month, 1).getDay(); 9468 }, 9469 9470 /* Determines if we should allow a "next/prev" month display change. */ 9471 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 9472 var numMonths = this._getNumberOfMonths(inst), 9473 date = this._daylightSavingAdjust(new Date(curYear, 9474 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 9475 9476 if (offset < 0) { 9477 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 9478 } 9479 return this._isInRange(inst, date); 9480 }, 9481 9482 /* Is the given date in the accepted range? */ 9483 _isInRange: function(inst, date) { 9484 var yearSplit, currentYear, 9485 minDate = this._getMinMaxDate(inst, "min"), 9486 maxDate = this._getMinMaxDate(inst, "max"), 9487 minYear = null, 9488 maxYear = null, 9489 years = this._get(inst, "yearRange"); 9490 if (years){ 9491 yearSplit = years.split(":"); 9492 currentYear = new Date().getFullYear(); 9493 minYear = parseInt(yearSplit[0], 10); 9494 maxYear = parseInt(yearSplit[1], 10); 9495 if ( yearSplit[0].match(/[+\-].*/) ) { 9496 minYear += currentYear; 9497 } 9498 if ( yearSplit[1].match(/[+\-].*/) ) { 9499 maxYear += currentYear; 9500 } 9501 } 9502 9503 return ((!minDate || date.getTime() >= minDate.getTime()) && 9504 (!maxDate || date.getTime() <= maxDate.getTime()) && 9505 (!minYear || date.getFullYear() >= minYear) && 9506 (!maxYear || date.getFullYear() <= maxYear)); 9507 }, 9508 9509 /* Provide the configuration settings for formatting/parsing. */ 9510 _getFormatConfig: function(inst) { 9511 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 9512 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 9513 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 9514 return {shortYearCutoff: shortYearCutoff, 9515 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 9516 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 9517 }, 9518 9519 /* Format the given date for display. */ 9520 _formatDate: function(inst, day, month, year) { 9521 if (!day) { 9522 inst.currentDay = inst.selectedDay; 9523 inst.currentMonth = inst.selectedMonth; 9524 inst.currentYear = inst.selectedYear; 9525 } 9526 var date = (day ? (typeof day === "object" ? day : 9527 this._daylightSavingAdjust(new Date(year, month, day))) : 9528 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 9529 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 9530 } 9531 });
vendor: 204,402 bytes, lines 9532-14985
9532 9533 /* 9534 * Bind hover events for datepicker elements. 9535 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9536 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9537 */ 9538 function bindHover(dpDiv) { 9539 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9540 return dpDiv.delegate(selector, "mouseout", function() { 9541 $(this).removeClass("ui-state-hover"); 9542 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9543 $(this).removeClass("ui-datepicker-prev-hover"); 9544 } 9545 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9546 $(this).removeClass("ui-datepicker-next-hover"); 9547 } 9548 }) 9549 .delegate(selector, "mouseover", function(){ 9550 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 9551 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 9552 $(this).addClass("ui-state-hover"); 9553 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 9554 $(this).addClass("ui-datepicker-prev-hover"); 9555 } 9556 if (this.className.indexOf("ui-datepicker-next") !== -1) { 9557 $(this).addClass("ui-datepicker-next-hover"); 9558 } 9559 } 9560 }); 9561 } 9562 9563 /* jQuery extend now ignores nulls! */ 9564 function extendRemove(target, props) { 9565 $.extend(target, props); 9566 for (var name in props) { 9567 if (props[name] == null) { 9568 target[name] = props[name]; 9569 } 9570 } 9571 return target; 9572 } 9573 9574 /* Invoke the datepicker functionality. 9575 @param options string - a command, optionally followed by additional parameters or 9576 Object - settings for attaching new datepicker functionality 9577 @return jQuery object */ 9578 $.fn.datepicker = function(options){ 9579 9580 /* Verify an empty collection wasn't passed - Fixes #6976 */ 9581 if ( !this.length ) { 9582 return this; 9583 } 9584 9585 /* Initialise the date picker. */ 9586 if (!$.datepicker.initialized) { 9587 $(document).mousedown($.datepicker._checkExternalClick); 9588 $.datepicker.initialized = true; 9589 } 9590 9591 /* Append datepicker main container to body if not exist. */ 9592 if ($("#"+$.datepicker._mainDivId).length === 0) { 9593 $("body").append($.datepicker.dpDiv); 9594 } 9595 9596 var otherArgs = Array.prototype.slice.call(arguments, 1); 9597 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 9598 return $.datepicker["_" + options + "Datepicker"]. 9599 apply($.datepicker, [this[0]].concat(otherArgs)); 9600 } 9601 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 9602 return $.datepicker["_" + options + "Datepicker"]. 9603 apply($.datepicker, [this[0]].concat(otherArgs)); 9604 } 9605 return this.each(function() { 9606 typeof options === "string" ? 9607 $.datepicker["_" + options + "Datepicker"]. 9608 apply($.datepicker, [this].concat(otherArgs)) : 9609 $.datepicker._attachDatepicker(this, options); 9610 }); 9611 }; 9612 9613 $.datepicker = new Datepicker(); // singleton instance 9614 $.datepicker.initialized = false; 9615 $.datepicker.uuid = new Date().getTime(); 9616 $.datepicker.version = "1.10.2"; 9617 9618// Workaround for #4055 9619// Add another global to avoid noConflict issues with inline event handlers 9620 window["DP_jQuery_" + dpuuid] = $; 9621 9622})(jQuery); 9623 9624(function( $, undefined ) { 9625 9626 var sizeRelatedOptions = { 9627 buttons: true, 9628 height: true, 9629 maxHeight: true, 9630 maxWidth: true, 9631 minHeight: true, 9632 minWidth: true, 9633 width: true 9634 }, 9635 resizableRelatedOptions = { 9636 maxHeight: true, 9637 maxWidth: true, 9638 minHeight: true, 9639 minWidth: true 9640 }; 9641 9642 $.widget( "ui.dialog", { 9643 version: "1.10.2", 9644 options: { 9645 appendTo: "body", 9646 autoOpen: true, 9647 buttons: [], 9648 closeOnEscape: true, 9649 closeText: "close", 9650 dialogClass: "", 9651 draggable: true, 9652 hide: null, 9653 height: "auto", 9654 maxHeight: null, 9655 maxWidth: null, 9656 minHeight: 150, 9657 minWidth: 150, 9658 modal: false, 9659 position: { 9660 my: "center", 9661 at: "center", 9662 of: window, 9663 collision: "fit", 9664 // Ensure the titlebar is always visible 9665 using: function( pos ) { 9666 var topOffset = $( this ).css( pos ).offset().top; 9667 if ( topOffset < 0 ) { 9668 $( this ).css( "top", pos.top - topOffset ); 9669 } 9670 } 9671 }, 9672 resizable: true, 9673 show: null, 9674 title: null, 9675 width: 300, 9676 9677 // callbacks 9678 beforeClose: null, 9679 close: null, 9680 drag: null, 9681 dragStart: null, 9682 dragStop: null, 9683 focus: null, 9684 open: null, 9685 resize: null, 9686 resizeStart: null, 9687 resizeStop: null 9688 }, 9689 9690 _create: function() { 9691 this.originalCss = { 9692 display: this.element[0].style.display, 9693 width: this.element[0].style.width, 9694 minHeight: this.element[0].style.minHeight, 9695 maxHeight: this.element[0].style.maxHeight, 9696 height: this.element[0].style.height 9697 }; 9698 this.originalPosition = { 9699 parent: this.element.parent(), 9700 index: this.element.parent().children().index( this.element ) 9701 }; 9702 this.originalTitle = this.element.attr("title"); 9703 this.options.title = this.options.title || this.originalTitle; 9704 9705 this._createWrapper(); 9706 9707 this.element 9708 .show() 9709 .removeAttr("title") 9710 .addClass("ui-dialog-content ui-widget-content") 9711 .appendTo( this.uiDialog ); 9712 9713 this._createTitlebar(); 9714 this._createButtonPane(); 9715 9716 if ( this.options.draggable && $.fn.draggable ) { 9717 this._makeDraggable(); 9718 } 9719 if ( this.options.resizable && $.fn.resizable ) { 9720 this._makeResizable(); 9721 } 9722 9723 this._isOpen = false; 9724 }, 9725 9726 _init: function() { 9727 if ( this.options.autoOpen ) { 9728 this.open(); 9729 } 9730 }, 9731 9732 _appendTo: function() { 9733 var element = this.options.appendTo; 9734 if ( element && (element.jquery || element.nodeType) ) { 9735 return $( element ); 9736 } 9737 return this.document.find( element || "body" ).eq( 0 ); 9738 }, 9739 9740 _destroy: function() { 9741 var next, 9742 originalPosition = this.originalPosition; 9743 9744 this._destroyOverlay(); 9745 9746 this.element 9747 .removeUniqueId() 9748 .removeClass("ui-dialog-content ui-widget-content") 9749 .css( this.originalCss ) 9750 // Without detaching first, the following becomes really slow 9751 .detach(); 9752 9753 this.uiDialog.stop( true, true ).remove(); 9754 9755 if ( this.originalTitle ) { 9756 this.element.attr( "title", this.originalTitle ); 9757 } 9758 9759 next = originalPosition.parent.children().eq( originalPosition.index ); 9760 // Don't try to place the dialog next to itself (#8613) 9761 if ( next.length && next[0] !== this.element[0] ) { 9762 next.before( this.element ); 9763 } else { 9764 originalPosition.parent.append( this.element ); 9765 } 9766 }, 9767 9768 widget: function() { 9769 return this.uiDialog; 9770 }, 9771 9772 disable: $.noop, 9773 enable: $.noop, 9774 9775 close: function( event ) { 9776 var that = this; 9777 9778 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 9779 return; 9780 } 9781 9782 this._isOpen = false; 9783 this._destroyOverlay(); 9784 9785 if ( !this.opener.filter(":focusable").focus().length ) { 9786 // Hiding a focused element doesn't trigger blur in WebKit 9787 // so in case we have nothing to focus on, explicitly blur the active element 9788 // https://bugs.webkit.org/show_bug.cgi?id=47182 9789 $( this.document[0].activeElement ).blur(); 9790 } 9791 9792 this._hide( this.uiDialog, this.options.hide, function() { 9793 that._trigger( "close", event ); 9794 }); 9795 }, 9796 9797 isOpen: function() { 9798 return this._isOpen; 9799 }, 9800 9801 moveToTop: function() { 9802 this._moveToTop(); 9803 }, 9804 9805 _moveToTop: function( event, silent ) { 9806 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; 9807 if ( moved && !silent ) { 9808 this._trigger( "focus", event ); 9809 } 9810 return moved; 9811 }, 9812 9813 open: function() { 9814 var that = this; 9815 if ( this._isOpen ) { 9816 if ( this._moveToTop() ) { 9817 this._focusTabbable(); 9818 } 9819 return; 9820 } 9821 9822 this._isOpen = true; 9823 this.opener = $( this.document[0].activeElement ); 9824 9825 this._size(); 9826 this._position(); 9827 this._createOverlay(); 9828 this._moveToTop( null, true ); 9829 this._show( this.uiDialog, this.options.show, function() { 9830 that._focusTabbable(); 9831 that._trigger("focus"); 9832 }); 9833 9834 this._trigger("open"); 9835 }, 9836 9837 _focusTabbable: function() { 9838 // Set focus to the first match: 9839 // 1. First element inside the dialog matching [autofocus] 9840 // 2. Tabbable element inside the content element 9841 // 3. Tabbable element inside the buttonpane 9842 // 4. The close button 9843 // 5. The dialog itself 9844 var hasFocus = this.element.find("[autofocus]"); 9845 if ( !hasFocus.length ) { 9846 hasFocus = this.element.find(":tabbable"); 9847 } 9848 if ( !hasFocus.length ) { 9849 hasFocus = this.uiDialogButtonPane.find(":tabbable"); 9850 } 9851 if ( !hasFocus.length ) { 9852 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); 9853 } 9854 if ( !hasFocus.length ) { 9855 hasFocus = this.uiDialog; 9856 } 9857 hasFocus.eq( 0 ).focus(); 9858 }, 9859 9860 _keepFocus: function( event ) { 9861 function checkFocus() { 9862 var activeElement = this.document[0].activeElement, 9863 isActive = this.uiDialog[0] === activeElement || 9864 $.contains( this.uiDialog[0], activeElement ); 9865 if ( !isActive ) { 9866 this._focusTabbable(); 9867 } 9868 } 9869 event.preventDefault(); 9870 checkFocus.call( this ); 9871 // support: IE 9872 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 9873 // so we check again later 9874 this._delay( checkFocus ); 9875 }, 9876 9877 _createWrapper: function() { 9878 this.uiDialog = $("<div>") 9879 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 9880 this.options.dialogClass ) 9881 .hide() 9882 .attr({ 9883 // Setting tabIndex makes the div focusable 9884 tabIndex: -1, 9885 role: "dialog" 9886 }) 9887 .appendTo( this._appendTo() ); 9888 9889 this._on( this.uiDialog, { 9890 keydown: function( event ) { 9891 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 9892 event.keyCode === $.ui.keyCode.ESCAPE ) { 9893 event.preventDefault(); 9894 this.close( event ); 9895 return; 9896 } 9897 9898 // prevent tabbing out of dialogs 9899 if ( event.keyCode !== $.ui.keyCode.TAB ) { 9900 return; 9901 } 9902 var tabbables = this.uiDialog.find(":tabbable"), 9903 first = tabbables.filter(":first"), 9904 last = tabbables.filter(":last"); 9905 9906 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 9907 first.focus( 1 ); 9908 event.preventDefault(); 9909 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 9910 last.focus( 1 ); 9911 event.preventDefault(); 9912 } 9913 }, 9914 mousedown: function( event ) { 9915 if ( this._moveToTop( event ) ) { 9916 this._focusTabbable(); 9917 } 9918 } 9919 }); 9920 9921 // We assume that any existing aria-describedby attribute means 9922 // that the dialog content is marked up properly 9923 // otherwise we brute force the content as the description 9924 if ( !this.element.find("[aria-describedby]").length ) { 9925 this.uiDialog.attr({ 9926 "aria-describedby": this.element.uniqueId().attr("id") 9927 }); 9928 } 9929 }, 9930 9931 _createTitlebar: function() { 9932 var uiDialogTitle; 9933 9934 this.uiDialogTitlebar = $("<div>") 9935 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") 9936 .prependTo( this.uiDialog ); 9937 this._on( this.uiDialogTitlebar, { 9938 mousedown: function( event ) { 9939 // Don't prevent click on close button (#8838) 9940 // Focusing a dialog that is partially scrolled out of view 9941 // causes the browser to scroll it into view, preventing the click event 9942 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { 9943 // Dialog isn't getting focus when dragging (#8063) 9944 this.uiDialog.focus(); 9945 } 9946 } 9947 }); 9948 9949 this.uiDialogTitlebarClose = $("<button></button>") 9950 .button({ 9951 label: this.options.closeText, 9952 icons: { 9953 primary: "ui-icon-closethick" 9954 }, 9955 text: false 9956 }) 9957 .addClass("ui-dialog-titlebar-close") 9958 .appendTo( this.uiDialogTitlebar ); 9959 this._on( this.uiDialogTitlebarClose, { 9960 click: function( event ) { 9961 event.preventDefault(); 9962 this.close( event ); 9963 } 9964 }); 9965 9966 uiDialogTitle = $("<span>") 9967 .uniqueId() 9968 .addClass("ui-dialog-title") 9969 .prependTo( this.uiDialogTitlebar ); 9970 this._title( uiDialogTitle ); 9971 9972 this.uiDialog.attr({ 9973 "aria-labelledby": uiDialogTitle.attr("id") 9974 }); 9975 }, 9976 9977 _title: function( title ) { 9978 if ( !this.options.title ) { 9979 title.html(" "); 9980 } 9981 title.text( this.options.title ); 9982 }, 9983 9984 _createButtonPane: function() { 9985 this.uiDialogButtonPane = $("<div>") 9986 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); 9987 9988 this.uiButtonSet = $("<div>") 9989 .addClass("ui-dialog-buttonset") 9990 .appendTo( this.uiDialogButtonPane ); 9991 9992 this._createButtons(); 9993 }, 9994 9995 _createButtons: function() { 9996 var that = this, 9997 buttons = this.options.buttons; 9998 9999 // if we already have a button pane, remove it 10000 this.uiDialogButtonPane.remove(); 10001 this.uiButtonSet.empty(); 10002 10003 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 10004 this.uiDialog.removeClass("ui-dialog-buttons"); 10005 return; 10006 } 10007 10008 $.each( buttons, function( name, props ) { 10009 var click, buttonOptions; 10010 props = $.isFunction( props ) ? 10011 { click: props, text: name } : 10012 props; 10013 // Default to a non-submitting button 10014 props = $.extend( { type: "button" }, props ); 10015 // Change the context for the click callback to be the main element 10016 click = props.click; 10017 props.click = function() { 10018 click.apply( that.element[0], arguments ); 10019 }; 10020 buttonOptions = { 10021 icons: props.icons, 10022 text: props.showText 10023 }; 10024 delete props.icons; 10025 delete props.showText; 10026 $( "<button></button>", props ) 10027 .button( buttonOptions ) 10028 .appendTo( that.uiButtonSet ); 10029 }); 10030 this.uiDialog.addClass("ui-dialog-buttons"); 10031 this.uiDialogButtonPane.appendTo( this.uiDialog ); 10032 }, 10033 10034 _makeDraggable: function() { 10035 var that = this, 10036 options = this.options; 10037 10038 function filteredUi( ui ) { 10039 return { 10040 position: ui.position, 10041 offset: ui.offset 10042 }; 10043 } 10044 10045 this.uiDialog.draggable({ 10046 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 10047 handle: ".ui-dialog-titlebar", 10048 containment: "document", 10049 start: function( event, ui ) { 10050 $( this ).addClass("ui-dialog-dragging"); 10051 that._blockFrames(); 10052 that._trigger( "dragStart", event, filteredUi( ui ) ); 10053 }, 10054 drag: function( event, ui ) { 10055 that._trigger( "drag", event, filteredUi( ui ) ); 10056 }, 10057 stop: function( event, ui ) { 10058 options.position = [ 10059 ui.position.left - that.document.scrollLeft(), 10060 ui.position.top - that.document.scrollTop() 10061 ]; 10062 $( this ).removeClass("ui-dialog-dragging"); 10063 that._unblockFrames(); 10064 that._trigger( "dragStop", event, filteredUi( ui ) ); 10065 } 10066 }); 10067 }, 10068 10069 _makeResizable: function() { 10070 var that = this, 10071 options = this.options, 10072 handles = options.resizable, 10073 // .ui-resizable has position: relative defined in the stylesheet 10074 // but dialogs have to use absolute or fixed positioning 10075 position = this.uiDialog.css("position"), 10076 resizeHandles = typeof handles === "string" ? 10077 handles : 10078 "n,e,s,w,se,sw,ne,nw"; 10079 10080 function filteredUi( ui ) { 10081 return { 10082 originalPosition: ui.originalPosition, 10083 originalSize: ui.originalSize, 10084 position: ui.position, 10085 size: ui.size 10086 }; 10087 } 10088 10089 this.uiDialog.resizable({ 10090 cancel: ".ui-dialog-content", 10091 containment: "document", 10092 alsoResize: this.element, 10093 maxWidth: options.maxWidth, 10094 maxHeight: options.maxHeight, 10095 minWidth: options.minWidth, 10096 minHeight: this._minHeight(), 10097 handles: resizeHandles, 10098 start: function( event, ui ) { 10099 $( this ).addClass("ui-dialog-resizing"); 10100 that._blockFrames(); 10101 that._trigger( "resizeStart", event, filteredUi( ui ) ); 10102 }, 10103 resize: function( event, ui ) { 10104 that._trigger( "resize", event, filteredUi( ui ) ); 10105 }, 10106 stop: function( event, ui ) { 10107 options.height = $( this ).height(); 10108 options.width = $( this ).width(); 10109 $( this ).removeClass("ui-dialog-resizing"); 10110 that._unblockFrames(); 10111 that._trigger( "resizeStop", event, filteredUi( ui ) ); 10112 } 10113 }) 10114 .css( "position", position ); 10115 }, 10116 10117 _minHeight: function() { 10118 var options = this.options; 10119 10120 return options.height === "auto" ? 10121 options.minHeight : 10122 Math.min( options.minHeight, options.height ); 10123 }, 10124 10125 _position: function() { 10126 // Need to show the dialog to get the actual offset in the position plugin 10127 var isVisible = this.uiDialog.is(":visible"); 10128 if ( !isVisible ) { 10129 this.uiDialog.show(); 10130 } 10131 this.uiDialog.position( this.options.position ); 10132 if ( !isVisible ) { 10133 this.uiDialog.hide(); 10134 } 10135 }, 10136 10137 _setOptions: function( options ) { 10138 var that = this, 10139 resize = false, 10140 resizableOptions = {}; 10141 10142 $.each( options, function( key, value ) { 10143 that._setOption( key, value ); 10144 10145 if ( key in sizeRelatedOptions ) { 10146 resize = true; 10147 } 10148 if ( key in resizableRelatedOptions ) { 10149 resizableOptions[ key ] = value; 10150 } 10151 }); 10152 10153 if ( resize ) { 10154 this._size(); 10155 this._position(); 10156 } 10157 if ( this.uiDialog.is(":data(ui-resizable)") ) { 10158 this.uiDialog.resizable( "option", resizableOptions ); 10159 } 10160 }, 10161 10162 _setOption: function( key, value ) { 10163 /*jshint maxcomplexity:15*/ 10164 var isDraggable, isResizable, 10165 uiDialog = this.uiDialog; 10166 10167 if ( key === "dialogClass" ) { 10168 uiDialog 10169 .removeClass( this.options.dialogClass ) 10170 .addClass( value ); 10171 } 10172 10173 if ( key === "disabled" ) { 10174 return; 10175 } 10176 10177 this._super( key, value ); 10178 10179 if ( key === "appendTo" ) { 10180 this.uiDialog.appendTo( this._appendTo() ); 10181 } 10182 10183 if ( key === "buttons" ) { 10184 this._createButtons(); 10185 } 10186 10187 if ( key === "closeText" ) { 10188 this.uiDialogTitlebarClose.button({ 10189 // Ensure that we always pass a string 10190 label: "" + value 10191 }); 10192 } 10193 10194 if ( key === "draggable" ) { 10195 isDraggable = uiDialog.is(":data(ui-draggable)"); 10196 if ( isDraggable && !value ) { 10197 uiDialog.draggable("destroy"); 10198 } 10199 10200 if ( !isDraggable && value ) { 10201 this._makeDraggable(); 10202 } 10203 } 10204 10205 if ( key === "position" ) { 10206 this._position(); 10207 } 10208 10209 if ( key === "resizable" ) { 10210 // currently resizable, becoming non-resizable 10211 isResizable = uiDialog.is(":data(ui-resizable)"); 10212 if ( isResizable && !value ) { 10213 uiDialog.resizable("destroy"); 10214 } 10215 10216 // currently resizable, changing handles 10217 if ( isResizable && typeof value === "string" ) { 10218 uiDialog.resizable( "option", "handles", value ); 10219 } 10220 10221 // currently non-resizable, becoming resizable 10222 if ( !isResizable && value !== false ) { 10223 this._makeResizable(); 10224 } 10225 } 10226 10227 if ( key === "title" ) { 10228 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); 10229 } 10230 }, 10231 10232 _size: function() { 10233 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 10234 // divs will both have width and height set, so we need to reset them 10235 var nonContentHeight, minContentHeight, maxContentHeight, 10236 options = this.options; 10237 10238 // Reset content sizing 10239 this.element.show().css({ 10240 width: "auto", 10241 minHeight: 0, 10242 maxHeight: "none", 10243 height: 0 10244 }); 10245 10246 if ( options.minWidth > options.width ) { 10247 options.width = options.minWidth; 10248 } 10249 10250 // reset wrapper sizing 10251 // determine the height of all the non-content elements 10252 nonContentHeight = this.uiDialog.css({ 10253 height: "auto", 10254 width: options.width 10255 }) 10256 .outerHeight(); 10257 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 10258 maxContentHeight = typeof options.maxHeight === "number" ? 10259 Math.max( 0, options.maxHeight - nonContentHeight ) : 10260 "none"; 10261 10262 if ( options.height === "auto" ) { 10263 this.element.css({ 10264 minHeight: minContentHeight, 10265 maxHeight: maxContentHeight, 10266 height: "auto" 10267 }); 10268 } else { 10269 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 10270 } 10271 10272 if (this.uiDialog.is(":data(ui-resizable)") ) { 10273 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 10274 } 10275 }, 10276 10277 _blockFrames: function() { 10278 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 10279 var iframe = $( this ); 10280 10281 return $( "<div>" ) 10282 .css({ 10283 position: "absolute", 10284 width: iframe.outerWidth(), 10285 height: iframe.outerHeight() 10286 }) 10287 .appendTo( iframe.parent() ) 10288 .offset( iframe.offset() )[0]; 10289 }); 10290 }, 10291 10292 _unblockFrames: function() { 10293 if ( this.iframeBlocks ) { 10294 this.iframeBlocks.remove(); 10295 delete this.iframeBlocks; 10296 } 10297 }, 10298 10299 _allowInteraction: function( event ) { 10300 if ( $( event.target ).closest(".ui-dialog").length ) { 10301 return true; 10302 } 10303 10304 // TODO: Remove hack when datepicker implements 10305 // the .ui-front logic (#8989) 10306 return !!$( event.target ).closest(".ui-datepicker").length; 10307 }, 10308 10309 _createOverlay: function() { 10310 if ( !this.options.modal ) { 10311 return; 10312 } 10313 10314 var that = this, 10315 widgetFullName = this.widgetFullName; 10316 if ( !$.ui.dialog.overlayInstances ) { 10317 // Prevent use of anchors and inputs. 10318 // We use a delay in case the overlay is created from an 10319 // event that we're going to be cancelling. (#2804) 10320 this._delay(function() { 10321 // Handle .dialog().dialog("close") (#4065) 10322 if ( $.ui.dialog.overlayInstances ) { 10323 this.document.bind( "focusin.dialog", function( event ) { 10324 if ( !that._allowInteraction( event ) ) { 10325 event.preventDefault(); 10326 $(".ui-dialog:visible:last .ui-dialog-content") 10327 .data( widgetFullName )._focusTabbable(); 10328 } 10329 }); 10330 } 10331 }); 10332 } 10333 10334 this.overlay = $("<div>") 10335 .addClass("ui-widget-overlay ui-front") 10336 .appendTo( this._appendTo() ); 10337 this._on( this.overlay, { 10338 mousedown: "_keepFocus" 10339 }); 10340 $.ui.dialog.overlayInstances++; 10341 }, 10342 10343 _destroyOverlay: function() { 10344 if ( !this.options.modal ) { 10345 return; 10346 } 10347 10348 if ( this.overlay ) { 10349 $.ui.dialog.overlayInstances--; 10350 10351 if ( !$.ui.dialog.overlayInstances ) { 10352 this.document.unbind( "focusin.dialog" ); 10353 } 10354 this.overlay.remove(); 10355 this.overlay = null; 10356 } 10357 } 10358 }); 10359 10360 $.ui.dialog.overlayInstances = 0; 10361 10362// DEPRECATED 10363 if ( $.uiBackCompat !== false ) { 10364 // position option with array notation 10365 // just override with old implementation 10366 $.widget( "ui.dialog", $.ui.dialog, { 10367 _position: function() { 10368 var position = this.options.position, 10369 myAt = [], 10370 offset = [ 0, 0 ], 10371 isVisible; 10372 10373 if ( position ) { 10374 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 10375 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; 10376 if ( myAt.length === 1 ) { 10377 myAt[1] = myAt[0]; 10378 } 10379 10380 $.each( [ "left", "top" ], function( i, offsetPosition ) { 10381 if ( +myAt[ i ] === myAt[ i ] ) { 10382 offset[ i ] = myAt[ i ]; 10383 myAt[ i ] = offsetPosition; 10384 } 10385 }); 10386 10387 position = { 10388 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 10389 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 10390 at: myAt.join(" ") 10391 }; 10392 } 10393 10394 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 10395 } else { 10396 position = $.ui.dialog.prototype.options.position; 10397 } 10398 10399 // need to show the dialog to get the actual offset in the position plugin 10400 isVisible = this.uiDialog.is(":visible"); 10401 if ( !isVisible ) { 10402 this.uiDialog.show(); 10403 } 10404 this.uiDialog.position( position ); 10405 if ( !isVisible ) { 10406 this.uiDialog.hide(); 10407 } 10408 } 10409 }); 10410 } 10411 10412}( jQuery ) ); 10413 10414(function( $, undefined ) { 10415 10416 var rvertical = /up|down|vertical/, 10417 rpositivemotion = /up|left|vertical|horizontal/; 10418 10419 $.effects.effect.blind = function( o, done ) { 10420 // Create element 10421 var el = $( this ), 10422 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10423 mode = $.effects.setMode( el, o.mode || "hide" ), 10424 direction = o.direction || "up", 10425 vertical = rvertical.test( direction ), 10426 ref = vertical ? "height" : "width", 10427 ref2 = vertical ? "top" : "left", 10428 motion = rpositivemotion.test( direction ), 10429 animation = {}, 10430 show = mode === "show", 10431 wrapper, distance, margin; 10432 10433 // if already wrapped, the wrapper's properties are my property. #6245 10434 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10435 $.effects.save( el.parent(), props ); 10436 } else { 10437 $.effects.save( el, props ); 10438 } 10439 el.show(); 10440 wrapper = $.effects.createWrapper( el ).css({ 10441 overflow: "hidden" 10442 }); 10443 10444 distance = wrapper[ ref ](); 10445 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10446 10447 animation[ ref ] = show ? distance : 0; 10448 if ( !motion ) { 10449 el 10450 .css( vertical ? "bottom" : "right", 0 ) 10451 .css( vertical ? "top" : "left", "auto" ) 10452 .css({ position: "absolute" }); 10453 10454 animation[ ref2 ] = show ? margin : distance + margin; 10455 } 10456 10457 // start at 0 if we are showing 10458 if ( show ) { 10459 wrapper.css( ref, 0 ); 10460 if ( ! motion ) { 10461 wrapper.css( ref2, margin + distance ); 10462 } 10463 } 10464 10465 // Animate 10466 wrapper.animate( animation, { 10467 duration: o.duration, 10468 easing: o.easing, 10469 queue: false, 10470 complete: function() { 10471 if ( mode === "hide" ) { 10472 el.hide(); 10473 } 10474 $.effects.restore( el, props ); 10475 $.effects.removeWrapper( el ); 10476 done(); 10477 } 10478 }); 10479 10480 }; 10481 10482})(jQuery); 10483 10484(function( $, undefined ) { 10485 10486 $.effects.effect.bounce = function( o, done ) { 10487 var el = $( this ), 10488 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10489 10490 // defaults: 10491 mode = $.effects.setMode( el, o.mode || "effect" ), 10492 hide = mode === "hide", 10493 show = mode === "show", 10494 direction = o.direction || "up", 10495 distance = o.distance, 10496 times = o.times || 5, 10497 10498 // number of internal animations 10499 anims = times * 2 + ( show || hide ? 1 : 0 ), 10500 speed = o.duration / anims, 10501 easing = o.easing, 10502 10503 // utility: 10504 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10505 motion = ( direction === "up" || direction === "left" ), 10506 i, 10507 upAnim, 10508 downAnim, 10509 10510 // we will need to re-assemble the queue to stack our animations in place 10511 queue = el.queue(), 10512 queuelen = queue.length; 10513 10514 // Avoid touching opacity to prevent clearType and PNG issues in IE 10515 if ( show || hide ) { 10516 props.push( "opacity" ); 10517 } 10518 10519 $.effects.save( el, props ); 10520 el.show(); 10521 $.effects.createWrapper( el ); // Create Wrapper 10522 10523 // default distance for the BIGGEST bounce is the outer Distance / 3 10524 if ( !distance ) { 10525 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 10526 } 10527 10528 if ( show ) { 10529 downAnim = { opacity: 1 }; 10530 downAnim[ ref ] = 0; 10531 10532 // if we are showing, force opacity 0 and set the initial position 10533 // then do the "first" animation 10534 el.css( "opacity", 0 ) 10535 .css( ref, motion ? -distance * 2 : distance * 2 ) 10536 .animate( downAnim, speed, easing ); 10537 } 10538 10539 // start at the smallest distance if we are hiding 10540 if ( hide ) { 10541 distance = distance / Math.pow( 2, times - 1 ); 10542 } 10543 10544 downAnim = {}; 10545 downAnim[ ref ] = 0; 10546 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 10547 for ( i = 0; i < times; i++ ) { 10548 upAnim = {}; 10549 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10550 10551 el.animate( upAnim, speed, easing ) 10552 .animate( downAnim, speed, easing ); 10553 10554 distance = hide ? distance * 2 : distance / 2; 10555 } 10556 10557 // Last Bounce when Hiding 10558 if ( hide ) { 10559 upAnim = { opacity: 0 }; 10560 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 10561 10562 el.animate( upAnim, speed, easing ); 10563 } 10564 10565 el.queue(function() { 10566 if ( hide ) { 10567 el.hide(); 10568 } 10569 $.effects.restore( el, props ); 10570 $.effects.removeWrapper( el ); 10571 done(); 10572 }); 10573 10574 // inject all the animations we just queued to be first in line (after "inprogress") 10575 if ( queuelen > 1) { 10576 queue.splice.apply( queue, 10577 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10578 } 10579 el.dequeue(); 10580 10581 }; 10582 10583})(jQuery); 10584 10585(function( $, undefined ) { 10586 10587 $.effects.effect.clip = function( o, done ) { 10588 // Create element 10589 var el = $( this ), 10590 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10591 mode = $.effects.setMode( el, o.mode || "hide" ), 10592 show = mode === "show", 10593 direction = o.direction || "vertical", 10594 vert = direction === "vertical", 10595 size = vert ? "height" : "width", 10596 position = vert ? "top" : "left", 10597 animation = {}, 10598 wrapper, animate, distance; 10599 10600 // Save & Show 10601 $.effects.save( el, props ); 10602 el.show(); 10603 10604 // Create Wrapper 10605 wrapper = $.effects.createWrapper( el ).css({ 10606 overflow: "hidden" 10607 }); 10608 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 10609 distance = animate[ size ](); 10610 10611 // Shift 10612 if ( show ) { 10613 animate.css( size, 0 ); 10614 animate.css( position, distance / 2 ); 10615 } 10616 10617 // Create Animation Object: 10618 animation[ size ] = show ? distance : 0; 10619 animation[ position ] = show ? 0 : distance / 2; 10620 10621 // Animate 10622 animate.animate( animation, { 10623 queue: false, 10624 duration: o.duration, 10625 easing: o.easing, 10626 complete: function() { 10627 if ( !show ) { 10628 el.hide(); 10629 } 10630 $.effects.restore( el, props ); 10631 $.effects.removeWrapper( el ); 10632 done(); 10633 } 10634 }); 10635 10636 }; 10637 10638})(jQuery); 10639 10640(function( $, undefined ) { 10641 10642 $.effects.effect.drop = function( o, done ) { 10643 10644 var el = $( this ), 10645 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 10646 mode = $.effects.setMode( el, o.mode || "hide" ), 10647 show = mode === "show", 10648 direction = o.direction || "left", 10649 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10650 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 10651 animation = { 10652 opacity: show ? 1 : 0 10653 }, 10654 distance; 10655 10656 // Adjust 10657 $.effects.save( el, props ); 10658 el.show(); 10659 $.effects.createWrapper( el ); 10660 10661 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 10662 10663 if ( show ) { 10664 el 10665 .css( "opacity", 0 ) 10666 .css( ref, motion === "pos" ? -distance : distance ); 10667 } 10668 10669 // Animation 10670 animation[ ref ] = ( show ? 10671 ( motion === "pos" ? "+=" : "-=" ) : 10672 ( motion === "pos" ? "-=" : "+=" ) ) + 10673 distance; 10674 10675 // Animate 10676 el.animate( animation, { 10677 queue: false, 10678 duration: o.duration, 10679 easing: o.easing, 10680 complete: function() { 10681 if ( mode === "hide" ) { 10682 el.hide(); 10683 } 10684 $.effects.restore( el, props ); 10685 $.effects.removeWrapper( el ); 10686 done(); 10687 } 10688 }); 10689 }; 10690 10691})(jQuery); 10692 10693(function( $, undefined ) { 10694 10695 $.effects.effect.explode = function( o, done ) { 10696 10697 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 10698 cells = rows, 10699 el = $( this ), 10700 mode = $.effects.setMode( el, o.mode || "hide" ), 10701 show = mode === "show", 10702 10703 // show and then visibility:hidden the element before calculating offset 10704 offset = el.show().css( "visibility", "hidden" ).offset(), 10705 10706 // width and height of a piece 10707 width = Math.ceil( el.outerWidth() / cells ), 10708 height = Math.ceil( el.outerHeight() / rows ), 10709 pieces = [], 10710 10711 // loop 10712 i, j, left, top, mx, my; 10713 10714 // children animate complete: 10715 function childComplete() { 10716 pieces.push( this ); 10717 if ( pieces.length === rows * cells ) { 10718 animComplete(); 10719 } 10720 } 10721 10722 // clone the element for each row and cell. 10723 for( i = 0; i < rows ; i++ ) { // ===> 10724 top = offset.top + i * height; 10725 my = i - ( rows - 1 ) / 2 ; 10726 10727 for( j = 0; j < cells ; j++ ) { // ||| 10728 left = offset.left + j * width; 10729 mx = j - ( cells - 1 ) / 2 ; 10730 10731 // Create a clone of the now hidden main element that will be absolute positioned 10732 // within a wrapper div off the -left and -top equal to size of our pieces 10733 el 10734 .clone() 10735 .appendTo( "body" ) 10736 .wrap( "<div></div>" ) 10737 .css({ 10738 position: "absolute", 10739 visibility: "visible", 10740 left: -j * width, 10741 top: -i * height 10742 }) 10743 10744 // select the wrapper - make it overflow: hidden and absolute positioned based on 10745 // where the original was located +left and +top equal to the size of pieces 10746 .parent() 10747 .addClass( "ui-effects-explode" ) 10748 .css({ 10749 position: "absolute", 10750 overflow: "hidden", 10751 width: width, 10752 height: height, 10753 left: left + ( show ? mx * width : 0 ), 10754 top: top + ( show ? my * height : 0 ), 10755 opacity: show ? 0 : 1 10756 }).animate({ 10757 left: left + ( show ? 0 : mx * width ), 10758 top: top + ( show ? 0 : my * height ), 10759 opacity: show ? 1 : 0 10760 }, o.duration || 500, o.easing, childComplete ); 10761 } 10762 } 10763 10764 function animComplete() { 10765 el.css({ 10766 visibility: "visible" 10767 }); 10768 $( pieces ).remove(); 10769 if ( !show ) { 10770 el.hide(); 10771 } 10772 done(); 10773 } 10774 }; 10775 10776})(jQuery); 10777 10778(function( $, undefined ) { 10779 10780 $.effects.effect.fade = function( o, done ) { 10781 var el = $( this ), 10782 mode = $.effects.setMode( el, o.mode || "toggle" ); 10783 10784 el.animate({ 10785 opacity: mode 10786 }, { 10787 queue: false, 10788 duration: o.duration, 10789 easing: o.easing, 10790 complete: done 10791 }); 10792 }; 10793 10794})( jQuery ); 10795 10796(function( $, undefined ) { 10797 10798 $.effects.effect.fold = function( o, done ) { 10799 10800 // Create element 10801 var el = $( this ), 10802 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10803 mode = $.effects.setMode( el, o.mode || "hide" ), 10804 show = mode === "show", 10805 hide = mode === "hide", 10806 size = o.size || 15, 10807 percent = /([0-9]+)%/.exec( size ), 10808 horizFirst = !!o.horizFirst, 10809 widthFirst = show !== horizFirst, 10810 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 10811 duration = o.duration / 2, 10812 wrapper, distance, 10813 animation1 = {}, 10814 animation2 = {}; 10815 10816 $.effects.save( el, props ); 10817 el.show(); 10818 10819 // Create Wrapper 10820 wrapper = $.effects.createWrapper( el ).css({ 10821 overflow: "hidden" 10822 }); 10823 distance = widthFirst ? 10824 [ wrapper.width(), wrapper.height() ] : 10825 [ wrapper.height(), wrapper.width() ]; 10826 10827 if ( percent ) { 10828 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 10829 } 10830 if ( show ) { 10831 wrapper.css( horizFirst ? { 10832 height: 0, 10833 width: size 10834 } : { 10835 height: size, 10836 width: 0 10837 }); 10838 } 10839 10840 // Animation 10841 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 10842 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 10843 10844 // Animate 10845 wrapper 10846 .animate( animation1, duration, o.easing ) 10847 .animate( animation2, duration, o.easing, function() { 10848 if ( hide ) { 10849 el.hide(); 10850 } 10851 $.effects.restore( el, props ); 10852 $.effects.removeWrapper( el ); 10853 done(); 10854 }); 10855 10856 }; 10857 10858})(jQuery); 10859 10860(function( $, undefined ) { 10861 10862 $.effects.effect.highlight = function( o, done ) { 10863 var elem = $( this ), 10864 props = [ "backgroundImage", "backgroundColor", "opacity" ], 10865 mode = $.effects.setMode( elem, o.mode || "show" ), 10866 animation = { 10867 backgroundColor: elem.css( "backgroundColor" ) 10868 }; 10869 10870 if (mode === "hide") { 10871 animation.opacity = 0; 10872 } 10873 10874 $.effects.save( elem, props ); 10875 10876 elem 10877 .show() 10878 .css({ 10879 backgroundImage: "none", 10880 backgroundColor: o.color || "#ffff99" 10881 }) 10882 .animate( animation, { 10883 queue: false, 10884 duration: o.duration, 10885 easing: o.easing, 10886 complete: function() { 10887 if ( mode === "hide" ) { 10888 elem.hide(); 10889 } 10890 $.effects.restore( elem, props ); 10891 done(); 10892 } 10893 }); 10894 }; 10895 10896})(jQuery); 10897 10898(function( $, undefined ) { 10899 10900 $.effects.effect.pulsate = function( o, done ) { 10901 var elem = $( this ), 10902 mode = $.effects.setMode( elem, o.mode || "show" ), 10903 show = mode === "show", 10904 hide = mode === "hide", 10905 showhide = ( show || mode === "hide" ), 10906 10907 // showing or hiding leaves of the "last" animation 10908 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 10909 duration = o.duration / anims, 10910 animateTo = 0, 10911 queue = elem.queue(), 10912 queuelen = queue.length, 10913 i; 10914 10915 if ( show || !elem.is(":visible")) { 10916 elem.css( "opacity", 0 ).show(); 10917 animateTo = 1; 10918 } 10919 10920 // anims - 1 opacity "toggles" 10921 for ( i = 1; i < anims; i++ ) { 10922 elem.animate({ 10923 opacity: animateTo 10924 }, duration, o.easing ); 10925 animateTo = 1 - animateTo; 10926 } 10927 10928 elem.animate({ 10929 opacity: animateTo 10930 }, duration, o.easing); 10931 10932 elem.queue(function() { 10933 if ( hide ) { 10934 elem.hide(); 10935 } 10936 done(); 10937 }); 10938 10939 // We just queued up "anims" animations, we need to put them next in the queue 10940 if ( queuelen > 1 ) { 10941 queue.splice.apply( queue, 10942 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 10943 } 10944 elem.dequeue(); 10945 }; 10946 10947})(jQuery); 10948 10949(function( $, undefined ) { 10950 10951 $.effects.effect.puff = function( o, done ) { 10952 var elem = $( this ), 10953 mode = $.effects.setMode( elem, o.mode || "hide" ), 10954 hide = mode === "hide", 10955 percent = parseInt( o.percent, 10 ) || 150, 10956 factor = percent / 100, 10957 original = { 10958 height: elem.height(), 10959 width: elem.width(), 10960 outerHeight: elem.outerHeight(), 10961 outerWidth: elem.outerWidth() 10962 }; 10963 10964 $.extend( o, { 10965 effect: "scale", 10966 queue: false, 10967 fade: true, 10968 mode: mode, 10969 complete: done, 10970 percent: hide ? percent : 100, 10971 from: hide ? 10972 original : 10973 { 10974 height: original.height * factor, 10975 width: original.width * factor, 10976 outerHeight: original.outerHeight * factor, 10977 outerWidth: original.outerWidth * factor 10978 } 10979 }); 10980 10981 elem.effect( o ); 10982 }; 10983 10984 $.effects.effect.scale = function( o, done ) { 10985 10986 // Create element 10987 var el = $( this ), 10988 options = $.extend( true, {}, o ), 10989 mode = $.effects.setMode( el, o.mode || "effect" ), 10990 percent = parseInt( o.percent, 10 ) || 10991 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 10992 direction = o.direction || "both", 10993 origin = o.origin, 10994 original = { 10995 height: el.height(), 10996 width: el.width(), 10997 outerHeight: el.outerHeight(), 10998 outerWidth: el.outerWidth() 10999 }, 11000 factor = { 11001 y: direction !== "horizontal" ? (percent / 100) : 1, 11002 x: direction !== "vertical" ? (percent / 100) : 1 11003 }; 11004 11005 // We are going to pass this effect to the size effect: 11006 options.effect = "size"; 11007 options.queue = false; 11008 options.complete = done; 11009 11010 // Set default origin and restore for show/hide 11011 if ( mode !== "effect" ) { 11012 options.origin = origin || ["middle","center"]; 11013 options.restore = true; 11014 } 11015 11016 options.from = o.from || ( mode === "show" ? { 11017 height: 0, 11018 width: 0, 11019 outerHeight: 0, 11020 outerWidth: 0 11021 } : original ); 11022 options.to = { 11023 height: original.height * factor.y, 11024 width: original.width * factor.x, 11025 outerHeight: original.outerHeight * factor.y, 11026 outerWidth: original.outerWidth * factor.x 11027 }; 11028 11029 // Fade option to support puff 11030 if ( options.fade ) { 11031 if ( mode === "show" ) { 11032 options.from.opacity = 0; 11033 options.to.opacity = 1; 11034 } 11035 if ( mode === "hide" ) { 11036 options.from.opacity = 1; 11037 options.to.opacity = 0; 11038 } 11039 } 11040 11041 // Animate 11042 el.effect( options ); 11043 11044 }; 11045 11046 $.effects.effect.size = function( o, done ) { 11047 11048 // Create element 11049 var original, baseline, factor, 11050 el = $( this ), 11051 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11052 11053 // Always restore 11054 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11055 11056 // Copy for children 11057 props2 = [ "width", "height", "overflow" ], 11058 cProps = [ "fontSize" ], 11059 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11060 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11061 11062 // Set options 11063 mode = $.effects.setMode( el, o.mode || "effect" ), 11064 restore = o.restore || mode !== "effect", 11065 scale = o.scale || "both", 11066 origin = o.origin || [ "middle", "center" ], 11067 position = el.css( "position" ), 11068 props = restore ? props0 : props1, 11069 zero = { 11070 height: 0, 11071 width: 0, 11072 outerHeight: 0, 11073 outerWidth: 0 11074 }; 11075 11076 if ( mode === "show" ) { 11077 el.show(); 11078 } 11079 original = { 11080 height: el.height(), 11081 width: el.width(), 11082 outerHeight: el.outerHeight(), 11083 outerWidth: el.outerWidth() 11084 }; 11085 11086 if ( o.mode === "toggle" && mode === "show" ) { 11087 el.from = o.to || zero; 11088 el.to = o.from || original; 11089 } else { 11090 el.from = o.from || ( mode === "show" ? zero : original ); 11091 el.to = o.to || ( mode === "hide" ? zero : original ); 11092 } 11093 11094 // Set scaling factor 11095 factor = { 11096 from: { 11097 y: el.from.height / original.height, 11098 x: el.from.width / original.width 11099 }, 11100 to: { 11101 y: el.to.height / original.height, 11102 x: el.to.width / original.width 11103 } 11104 }; 11105 11106 // Scale the css box 11107 if ( scale === "box" || scale === "both" ) { 11108 11109 // Vertical props scaling 11110 if ( factor.from.y !== factor.to.y ) { 11111 props = props.concat( vProps ); 11112 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11113 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11114 } 11115 11116 // Horizontal props scaling 11117 if ( factor.from.x !== factor.to.x ) { 11118 props = props.concat( hProps ); 11119 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11120 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11121 } 11122 } 11123 11124 // Scale the content 11125 if ( scale === "content" || scale === "both" ) { 11126 11127 // Vertical props scaling 11128 if ( factor.from.y !== factor.to.y ) { 11129 props = props.concat( cProps ).concat( props2 ); 11130 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11131 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11132 } 11133 } 11134 11135 $.effects.save( el, props ); 11136 el.show(); 11137 $.effects.createWrapper( el ); 11138 el.css( "overflow", "hidden" ).css( el.from ); 11139 11140 // Adjust 11141 if (origin) { // Calculate baseline shifts 11142 baseline = $.effects.getBaseline( origin, original ); 11143 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11144 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11145 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11146 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11147 } 11148 el.css( el.from ); // set top & left 11149 11150 // Animate 11151 if ( scale === "content" || scale === "both" ) { // Scale the children 11152 11153 // Add margins/font-size 11154 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11155 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11156 props2 = props0.concat(vProps).concat(hProps); 11157 11158 el.find( "*[width]" ).each( function(){ 11159 var child = $( this ), 11160 c_original = { 11161 height: child.height(), 11162 width: child.width(), 11163 outerHeight: child.outerHeight(), 11164 outerWidth: child.outerWidth() 11165 }; 11166 if (restore) { 11167 $.effects.save(child, props2); 11168 } 11169 11170 child.from = { 11171 height: c_original.height * factor.from.y, 11172 width: c_original.width * factor.from.x, 11173 outerHeight: c_original.outerHeight * factor.from.y, 11174 outerWidth: c_original.outerWidth * factor.from.x 11175 }; 11176 child.to = { 11177 height: c_original.height * factor.to.y, 11178 width: c_original.width * factor.to.x, 11179 outerHeight: c_original.height * factor.to.y, 11180 outerWidth: c_original.width * factor.to.x 11181 }; 11182 11183 // Vertical props scaling 11184 if ( factor.from.y !== factor.to.y ) { 11185 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11186 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11187 } 11188 11189 // Horizontal props scaling 11190 if ( factor.from.x !== factor.to.x ) { 11191 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11192 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11193 } 11194 11195 // Animate children 11196 child.css( child.from ); 11197 child.animate( child.to, o.duration, o.easing, function() { 11198 11199 // Restore children 11200 if ( restore ) { 11201 $.effects.restore( child, props2 ); 11202 } 11203 }); 11204 }); 11205 } 11206 11207 // Animate 11208 el.animate( el.to, { 11209 queue: false, 11210 duration: o.duration, 11211 easing: o.easing, 11212 complete: function() { 11213 if ( el.to.opacity === 0 ) { 11214 el.css( "opacity", el.from.opacity ); 11215 } 11216 if( mode === "hide" ) { 11217 el.hide(); 11218 } 11219 $.effects.restore( el, props ); 11220 if ( !restore ) { 11221 11222 // we need to calculate our new positioning based on the scaling 11223 if ( position === "static" ) { 11224 el.css({ 11225 position: "relative", 11226 top: el.to.top, 11227 left: el.to.left 11228 }); 11229 } else { 11230 $.each([ "top", "left" ], function( idx, pos ) { 11231 el.css( pos, function( _, str ) { 11232 var val = parseInt( str, 10 ), 11233 toRef = idx ? el.to.left : el.to.top; 11234 11235 // if original was "auto", recalculate the new value from wrapper 11236 if ( str === "auto" ) { 11237 return toRef + "px"; 11238 } 11239 11240 return val + toRef + "px"; 11241 }); 11242 }); 11243 } 11244 } 11245 11246 $.effects.removeWrapper( el ); 11247 done(); 11248 } 11249 }); 11250 11251 }; 11252 11253})(jQuery); 11254 11255(function( $, undefined ) { 11256 11257 $.effects.effect.shake = function( o, done ) { 11258 11259 var el = $( this ), 11260 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11261 mode = $.effects.setMode( el, o.mode || "effect" ), 11262 direction = o.direction || "left", 11263 distance = o.distance || 20, 11264 times = o.times || 3, 11265 anims = times * 2 + 1, 11266 speed = Math.round(o.duration/anims), 11267 ref = (direction === "up" || direction === "down") ? "top" : "left", 11268 positiveMotion = (direction === "up" || direction === "left"), 11269 animation = {}, 11270 animation1 = {}, 11271 animation2 = {}, 11272 i, 11273 11274 // we will need to re-assemble the queue to stack our animations in place 11275 queue = el.queue(), 11276 queuelen = queue.length; 11277 11278 $.effects.save( el, props ); 11279 el.show(); 11280 $.effects.createWrapper( el ); 11281 11282 // Animation 11283 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11284 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11285 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11286 11287 // Animate 11288 el.animate( animation, speed, o.easing ); 11289 11290 // Shakes 11291 for ( i = 1; i < times; i++ ) { 11292 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11293 } 11294 el 11295 .animate( animation1, speed, o.easing ) 11296 .animate( animation, speed / 2, o.easing ) 11297 .queue(function() { 11298 if ( mode === "hide" ) { 11299 el.hide(); 11300 } 11301 $.effects.restore( el, props ); 11302 $.effects.removeWrapper( el ); 11303 done(); 11304 }); 11305 11306 // inject all the animations we just queued to be first in line (after "inprogress") 11307 if ( queuelen > 1) { 11308 queue.splice.apply( queue, 11309 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11310 } 11311 el.dequeue(); 11312 11313 }; 11314 11315})(jQuery); 11316 11317(function( $, undefined ) { 11318 11319 $.effects.effect.slide = function( o, done ) { 11320 11321 // Create element 11322 var el = $( this ), 11323 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11324 mode = $.effects.setMode( el, o.mode || "show" ), 11325 show = mode === "show", 11326 direction = o.direction || "left", 11327 ref = (direction === "up" || direction === "down") ? "top" : "left", 11328 positiveMotion = (direction === "up" || direction === "left"), 11329 distance, 11330 animation = {}; 11331 11332 // Adjust 11333 $.effects.save( el, props ); 11334 el.show(); 11335 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11336 11337 $.effects.createWrapper( el ).css({ 11338 overflow: "hidden" 11339 }); 11340 11341 if ( show ) { 11342 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11343 } 11344 11345 // Animation 11346 animation[ ref ] = ( show ? 11347 ( positiveMotion ? "+=" : "-=") : 11348 ( positiveMotion ? "-=" : "+=")) + 11349 distance; 11350 11351 // Animate 11352 el.animate( animation, { 11353 queue: false, 11354 duration: o.duration, 11355 easing: o.easing, 11356 complete: function() { 11357 if ( mode === "hide" ) { 11358 el.hide(); 11359 } 11360 $.effects.restore( el, props ); 11361 $.effects.removeWrapper( el ); 11362 done(); 11363 } 11364 }); 11365 }; 11366 11367})(jQuery); 11368 11369(function( $, undefined ) { 11370 11371 $.effects.effect.transfer = function( o, done ) { 11372 var elem = $( this ), 11373 target = $( o.to ), 11374 targetFixed = target.css( "position" ) === "fixed", 11375 body = $("body"), 11376 fixTop = targetFixed ? body.scrollTop() : 0, 11377 fixLeft = targetFixed ? body.scrollLeft() : 0, 11378 endPosition = target.offset(), 11379 animation = { 11380 top: endPosition.top - fixTop , 11381 left: endPosition.left - fixLeft , 11382 height: target.innerHeight(), 11383 width: target.innerWidth() 11384 }, 11385 startPosition = elem.offset(), 11386 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11387 .appendTo( document.body ) 11388 .addClass( o.className ) 11389 .css({ 11390 top: startPosition.top - fixTop , 11391 left: startPosition.left - fixLeft , 11392 height: elem.innerHeight(), 11393 width: elem.innerWidth(), 11394 position: targetFixed ? "fixed" : "absolute" 11395 }) 11396 .animate( animation, o.duration, o.easing, function() { 11397 transfer.remove(); 11398 done(); 11399 }); 11400 }; 11401 11402})(jQuery); 11403 11404(function( $, undefined ) { 11405 11406 $.widget( "ui.menu", { 11407 version: "1.10.2", 11408 defaultElement: "<ul>", 11409 delay: 300, 11410 options: { 11411 icons: { 11412 submenu: "ui-icon-carat-1-e" 11413 }, 11414 menus: "ul", 11415 position: { 11416 my: "left top", 11417 at: "right top" 11418 }, 11419 role: "menu", 11420 11421 // callbacks 11422 blur: null, 11423 focus: null, 11424 select: null 11425 }, 11426 11427 _create: function() { 11428 this.activeMenu = this.element; 11429 // flag used to prevent firing of the click handler 11430 // as the event bubbles up through nested menus 11431 this.mouseHandled = false; 11432 this.element 11433 .uniqueId() 11434 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11435 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 11436 .attr({ 11437 role: this.options.role, 11438 tabIndex: 0 11439 }) 11440 // need to catch all clicks on disabled menu 11441 // not possible through _on 11442 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 11443 if ( this.options.disabled ) { 11444 event.preventDefault(); 11445 } 11446 }, this )); 11447 11448 if ( this.options.disabled ) { 11449 this.element 11450 .addClass( "ui-state-disabled" ) 11451 .attr( "aria-disabled", "true" ); 11452 } 11453 11454 this._on({ 11455 // Prevent focus from sticking to links inside menu after clicking 11456 // them (focus should always stay on UL during navigation). 11457 "mousedown .ui-menu-item > a": function( event ) { 11458 event.preventDefault(); 11459 }, 11460 "click .ui-state-disabled > a": function( event ) { 11461 event.preventDefault(); 11462 }, 11463 "click .ui-menu-item:has(a)": function( event ) { 11464 var target = $( event.target ).closest( ".ui-menu-item" ); 11465 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 11466 this.mouseHandled = true; 11467 11468 this.select( event ); 11469 // Open submenu on click 11470 if ( target.has( ".ui-menu" ).length ) { 11471 this.expand( event ); 11472 } else if ( !this.element.is( ":focus" ) ) { 11473 // Redirect focus to the menu 11474 this.element.trigger( "focus", [ true ] ); 11475 11476 // If the active item is on the top level, let it stay active. 11477 // Otherwise, blur the active item since it is no longer visible. 11478 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 11479 clearTimeout( this.timer ); 11480 } 11481 } 11482 } 11483 }, 11484 "mouseenter .ui-menu-item": function( event ) { 11485 var target = $( event.currentTarget ); 11486 // Remove ui-state-active class from siblings of the newly focused menu item 11487 // to avoid a jump caused by adjacent elements both having a class with a border 11488 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 11489 this.focus( event, target ); 11490 }, 11491 mouseleave: "collapseAll", 11492 "mouseleave .ui-menu": "collapseAll", 11493 focus: function( event, keepActiveItem ) { 11494 // If there's already an active item, keep it active 11495 // If not, activate the first item 11496 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 11497 11498 if ( !keepActiveItem ) { 11499 this.focus( event, item ); 11500 } 11501 }, 11502 blur: function( event ) { 11503 this._delay(function() { 11504 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 11505 this.collapseAll( event ); 11506 } 11507 }); 11508 }, 11509 keydown: "_keydown" 11510 }); 11511 11512 this.refresh(); 11513 11514 // Clicks outside of a menu collapse any open menus 11515 this._on( this.document, { 11516 click: function( event ) { 11517 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 11518 this.collapseAll( event ); 11519 } 11520 11521 // Reset the mouseHandled flag 11522 this.mouseHandled = false; 11523 } 11524 }); 11525 }, 11526 11527 _destroy: function() { 11528 // Destroy (sub)menus 11529 this.element 11530 .removeAttr( "aria-activedescendant" ) 11531 .find( ".ui-menu" ).addBack() 11532 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 11533 .removeAttr( "role" ) 11534 .removeAttr( "tabIndex" ) 11535 .removeAttr( "aria-labelledby" ) 11536 .removeAttr( "aria-expanded" ) 11537 .removeAttr( "aria-hidden" ) 11538 .removeAttr( "aria-disabled" ) 11539 .removeUniqueId() 11540 .show(); 11541 11542 // Destroy menu items 11543 this.element.find( ".ui-menu-item" ) 11544 .removeClass( "ui-menu-item" ) 11545 .removeAttr( "role" ) 11546 .removeAttr( "aria-disabled" ) 11547 .children( "a" ) 11548 .removeUniqueId() 11549 .removeClass( "ui-corner-all ui-state-hover" ) 11550 .removeAttr( "tabIndex" ) 11551 .removeAttr( "role" ) 11552 .removeAttr( "aria-haspopup" ) 11553 .children().each( function() { 11554 var elem = $( this ); 11555 if ( elem.data( "ui-menu-submenu-carat" ) ) { 11556 elem.remove(); 11557 } 11558 }); 11559 11560 // Destroy menu dividers 11561 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 11562 }, 11563 11564 _keydown: function( event ) { 11565 /*jshint maxcomplexity:20*/ 11566 var match, prev, character, skip, regex, 11567 preventDefault = true; 11568 11569 function escape( value ) { 11570 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 11571 } 11572 11573 switch ( event.keyCode ) { 11574 case $.ui.keyCode.PAGE_UP: 11575 this.previousPage( event ); 11576 break; 11577 case $.ui.keyCode.PAGE_DOWN: 11578 this.nextPage( event ); 11579 break; 11580 case $.ui.keyCode.HOME: 11581 this._move( "first", "first", event ); 11582 break; 11583 case $.ui.keyCode.END: 11584 this._move( "last", "last", event ); 11585 break; 11586 case $.ui.keyCode.UP: 11587 this.previous( event ); 11588 break; 11589 case $.ui.keyCode.DOWN: 11590 this.next( event ); 11591 break; 11592 case $.ui.keyCode.LEFT: 11593 this.collapse( event ); 11594 break; 11595 case $.ui.keyCode.RIGHT: 11596 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 11597 this.expand( event ); 11598 } 11599 break; 11600 case $.ui.keyCode.ENTER: 11601 case $.ui.keyCode.SPACE: 11602 this._activate( event ); 11603 break; 11604 case $.ui.keyCode.ESCAPE: 11605 this.collapse( event ); 11606 break; 11607 default: 11608 preventDefault = false; 11609 prev = this.previousFilter || ""; 11610 character = String.fromCharCode( event.keyCode ); 11611 skip = false; 11612 11613 clearTimeout( this.filterTimer ); 11614 11615 if ( character === prev ) { 11616 skip = true; 11617 } else { 11618 character = prev + character; 11619 } 11620 11621 regex = new RegExp( "^" + escape( character ), "i" ); 11622 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11623 return regex.test( $( this ).children( "a" ).text() ); 11624 }); 11625 match = skip && match.index( this.active.next() ) !== -1 ? 11626 this.active.nextAll( ".ui-menu-item" ) : 11627 match; 11628 11629 // If no matches on the current filter, reset to the last character pressed 11630 // to move down the menu to the first item that starts with that character 11631 if ( !match.length ) { 11632 character = String.fromCharCode( event.keyCode ); 11633 regex = new RegExp( "^" + escape( character ), "i" ); 11634 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 11635 return regex.test( $( this ).children( "a" ).text() ); 11636 }); 11637 } 11638 11639 if ( match.length ) { 11640 this.focus( event, match ); 11641 if ( match.length > 1 ) { 11642 this.previousFilter = character; 11643 this.filterTimer = this._delay(function() { 11644 delete this.previousFilter; 11645 }, 1000 ); 11646 } else { 11647 delete this.previousFilter; 11648 } 11649 } else { 11650 delete this.previousFilter; 11651 } 11652 } 11653 11654 if ( preventDefault ) { 11655 event.preventDefault(); 11656 } 11657 }, 11658 11659 _activate: function( event ) { 11660 if ( !this.active.is( ".ui-state-disabled" ) ) { 11661 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 11662 this.expand( event ); 11663 } else { 11664 this.select( event ); 11665 } 11666 } 11667 }, 11668 11669 refresh: function() { 11670 var menus, 11671 icon = this.options.icons.submenu, 11672 submenus = this.element.find( this.options.menus ); 11673 11674 // Initialize nested menus 11675 submenus.filter( ":not(.ui-menu)" ) 11676 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 11677 .hide() 11678 .attr({ 11679 role: this.options.role, 11680 "aria-hidden": "true", 11681 "aria-expanded": "false" 11682 }) 11683 .each(function() { 11684 var menu = $( this ), 11685 item = menu.prev( "a" ), 11686 submenuCarat = $( "<span>" ) 11687 .addClass( "ui-menu-icon ui-icon " + icon ) 11688 .data( "ui-menu-submenu-carat", true ); 11689 11690 item 11691 .attr( "aria-haspopup", "true" ) 11692 .prepend( submenuCarat ); 11693 menu.attr( "aria-labelledby", item.attr( "id" ) ); 11694 }); 11695 11696 menus = submenus.add( this.element ); 11697 11698 // Don't refresh list items that are already adapted 11699 menus.children( ":not(.ui-menu-item):has(a)" ) 11700 .addClass( "ui-menu-item" ) 11701 .attr( "role", "presentation" ) 11702 .children( "a" ) 11703 .uniqueId() 11704 .addClass( "ui-corner-all" ) 11705 .attr({ 11706 tabIndex: -1, 11707 role: this._itemRole() 11708 }); 11709 11710 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 11711 menus.children( ":not(.ui-menu-item)" ).each(function() { 11712 var item = $( this ); 11713 // hyphen, em dash, en dash 11714 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 11715 item.addClass( "ui-widget-content ui-menu-divider" ); 11716 } 11717 }); 11718 11719 // Add aria-disabled attribute to any disabled menu item 11720 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 11721 11722 // If the active item has been removed, blur the menu 11723 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 11724 this.blur(); 11725 } 11726 }, 11727 11728 _itemRole: function() { 11729 return { 11730 menu: "menuitem", 11731 listbox: "option" 11732 }[ this.options.role ]; 11733 }, 11734 11735 _setOption: function( key, value ) { 11736 if ( key === "icons" ) { 11737 this.element.find( ".ui-menu-icon" ) 11738 .removeClass( this.options.icons.submenu ) 11739 .addClass( value.submenu ); 11740 } 11741 this._super( key, value ); 11742 }, 11743 11744 focus: function( event, item ) { 11745 var nested, focused; 11746 this.blur( event, event && event.type === "focus" ); 11747 11748 this._scrollIntoView( item ); 11749 11750 this.active = item.first(); 11751 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 11752 // Only update aria-activedescendant if there's a role 11753 // otherwise we assume focus is managed elsewhere 11754 if ( this.options.role ) { 11755 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 11756 } 11757 11758 // Highlight active parent menu item, if any 11759 this.active 11760 .parent() 11761 .closest( ".ui-menu-item" ) 11762 .children( "a:first" ) 11763 .addClass( "ui-state-active" ); 11764 11765 if ( event && event.type === "keydown" ) { 11766 this._close(); 11767 } else { 11768 this.timer = this._delay(function() { 11769 this._close(); 11770 }, this.delay ); 11771 } 11772 11773 nested = item.children( ".ui-menu" ); 11774 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 11775 this._startOpening(nested); 11776 } 11777 this.activeMenu = item.parent(); 11778 11779 this._trigger( "focus", event, { item: item } ); 11780 }, 11781 11782 _scrollIntoView: function( item ) { 11783 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 11784 if ( this._hasScroll() ) { 11785 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 11786 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 11787 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 11788 scroll = this.activeMenu.scrollTop(); 11789 elementHeight = this.activeMenu.height(); 11790 itemHeight = item.height(); 11791 11792 if ( offset < 0 ) { 11793 this.activeMenu.scrollTop( scroll + offset ); 11794 } else if ( offset + itemHeight > elementHeight ) { 11795 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 11796 } 11797 } 11798 }, 11799 11800 blur: function( event, fromFocus ) { 11801 if ( !fromFocus ) { 11802 clearTimeout( this.timer ); 11803 } 11804 11805 if ( !this.active ) { 11806 return; 11807 } 11808 11809 this.active.children( "a" ).removeClass( "ui-state-focus" ); 11810 this.active = null; 11811 11812 this._trigger( "blur", event, { item: this.active } ); 11813 }, 11814 11815 _startOpening: function( submenu ) { 11816 clearTimeout( this.timer ); 11817 11818 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 11819 // shift in the submenu position when mousing over the carat icon 11820 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 11821 return; 11822 } 11823 11824 this.timer = this._delay(function() { 11825 this._close(); 11826 this._open( submenu ); 11827 }, this.delay ); 11828 }, 11829 11830 _open: function( submenu ) { 11831 var position = $.extend({ 11832 of: this.active 11833 }, this.options.position ); 11834 11835 clearTimeout( this.timer ); 11836 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 11837 .hide() 11838 .attr( "aria-hidden", "true" ); 11839 11840 submenu 11841 .show() 11842 .removeAttr( "aria-hidden" ) 11843 .attr( "aria-expanded", "true" ) 11844 .position( position ); 11845 }, 11846 11847 collapseAll: function( event, all ) { 11848 clearTimeout( this.timer ); 11849 this.timer = this._delay(function() { 11850 // If we were passed an event, look for the submenu that contains the event 11851 var currentMenu = all ? this.element : 11852 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 11853 11854 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 11855 if ( !currentMenu.length ) { 11856 currentMenu = this.element; 11857 } 11858 11859 this._close( currentMenu ); 11860 11861 this.blur( event ); 11862 this.activeMenu = currentMenu; 11863 }, this.delay ); 11864 }, 11865 11866 // With no arguments, closes the currently active menu - if nothing is active 11867 // it closes all menus. If passed an argument, it will search for menus BELOW 11868 _close: function( startMenu ) { 11869 if ( !startMenu ) { 11870 startMenu = this.active ? this.active.parent() : this.element; 11871 } 11872 11873 startMenu 11874 .find( ".ui-menu" ) 11875 .hide() 11876 .attr( "aria-hidden", "true" ) 11877 .attr( "aria-expanded", "false" ) 11878 .end() 11879 .find( "a.ui-state-active" ) 11880 .removeClass( "ui-state-active" ); 11881 }, 11882 11883 collapse: function( event ) { 11884 var newItem = this.active && 11885 this.active.parent().closest( ".ui-menu-item", this.element ); 11886 if ( newItem && newItem.length ) { 11887 this._close(); 11888 this.focus( event, newItem ); 11889 } 11890 }, 11891 11892 expand: function( event ) { 11893 var newItem = this.active && 11894 this.active 11895 .children( ".ui-menu " ) 11896 .children( ".ui-menu-item" ) 11897 .first(); 11898 11899 if ( newItem && newItem.length ) { 11900 this._open( newItem.parent() ); 11901 11902 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 11903 this._delay(function() { 11904 this.focus( event, newItem ); 11905 }); 11906 } 11907 }, 11908 11909 next: function( event ) { 11910 this._move( "next", "first", event ); 11911 }, 11912 11913 previous: function( event ) { 11914 this._move( "prev", "last", event ); 11915 }, 11916 11917 isFirstItem: function() { 11918 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 11919 }, 11920 11921 isLastItem: function() { 11922 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 11923 }, 11924 11925 _move: function( direction, filter, event ) { 11926 var next; 11927 if ( this.active ) { 11928 if ( direction === "first" || direction === "last" ) { 11929 next = this.active 11930 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 11931 .eq( -1 ); 11932 } else { 11933 next = this.active 11934 [ direction + "All" ]( ".ui-menu-item" ) 11935 .eq( 0 ); 11936 } 11937 } 11938 if ( !next || !next.length || !this.active ) { 11939 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 11940 } 11941 11942 this.focus( event, next ); 11943 }, 11944 11945 nextPage: function( event ) { 11946 var item, base, height; 11947 11948 if ( !this.active ) { 11949 this.next( event ); 11950 return; 11951 } 11952 if ( this.isLastItem() ) { 11953 return; 11954 } 11955 if ( this._hasScroll() ) { 11956 base = this.active.offset().top; 11957 height = this.element.height(); 11958 this.active.nextAll( ".ui-menu-item" ).each(function() { 11959 item = $( this ); 11960 return item.offset().top - base - height < 0; 11961 }); 11962 11963 this.focus( event, item ); 11964 } else { 11965 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 11966 [ !this.active ? "first" : "last" ]() ); 11967 } 11968 }, 11969 11970 previousPage: function( event ) { 11971 var item, base, height; 11972 if ( !this.active ) { 11973 this.next( event ); 11974 return; 11975 } 11976 if ( this.isFirstItem() ) { 11977 return; 11978 } 11979 if ( this._hasScroll() ) { 11980 base = this.active.offset().top; 11981 height = this.element.height(); 11982 this.active.prevAll( ".ui-menu-item" ).each(function() { 11983 item = $( this ); 11984 return item.offset().top - base + height > 0; 11985 }); 11986 11987 this.focus( event, item ); 11988 } else { 11989 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 11990 } 11991 }, 11992 11993 _hasScroll: function() { 11994 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 11995 }, 11996 11997 select: function( event ) { 11998 // TODO: It should never be possible to not have an active item at this 11999 // point, but the tests don't trigger mouseenter before click. 12000 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 12001 var ui = { item: this.active }; 12002 if ( !this.active.has( ".ui-menu" ).length ) { 12003 this.collapseAll( event, true ); 12004 } 12005 this._trigger( "select", event, ui ); 12006 } 12007 }); 12008 12009}( jQuery )); 12010 12011(function( $, undefined ) { 12012 12013 $.ui = $.ui || {}; 12014 12015 var cachedScrollbarWidth, 12016 max = Math.max, 12017 abs = Math.abs, 12018 round = Math.round, 12019 rhorizontal = /left|center|right/, 12020 rvertical = /top|center|bottom/, 12021 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 12022 rposition = /^\w+/, 12023 rpercent = /%$/, 12024 _position = $.fn.position; 12025 12026 function getOffsets( offsets, width, height ) { 12027 return [ 12028 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 12029 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 12030 ]; 12031 } 12032 12033 function parseCss( element, property ) { 12034 return parseInt( $.css( element, property ), 10 ) || 0; 12035 } 12036 12037 function getDimensions( elem ) { 12038 var raw = elem[0]; 12039 if ( raw.nodeType === 9 ) { 12040 return { 12041 width: elem.width(), 12042 height: elem.height(), 12043 offset: { top: 0, left: 0 } 12044 }; 12045 } 12046 if ( $.isWindow( raw ) ) { 12047 return { 12048 width: elem.width(), 12049 height: elem.height(), 12050 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 12051 }; 12052 } 12053 if ( raw.preventDefault ) { 12054 return { 12055 width: 0, 12056 height: 0, 12057 offset: { top: raw.pageY, left: raw.pageX } 12058 }; 12059 } 12060 return { 12061 width: elem.outerWidth(), 12062 height: elem.outerHeight(), 12063 offset: elem.offset() 12064 }; 12065 } 12066 12067 $.position = { 12068 scrollbarWidth: function() { 12069 if ( cachedScrollbarWidth !== undefined ) { 12070 return cachedScrollbarWidth; 12071 } 12072 var w1, w2, 12073 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 12074 innerDiv = div.children()[0]; 12075 12076 $( "body" ).append( div ); 12077 w1 = innerDiv.offsetWidth; 12078 div.css( "overflow", "scroll" ); 12079 12080 w2 = innerDiv.offsetWidth; 12081 12082 if ( w1 === w2 ) { 12083 w2 = div[0].clientWidth; 12084 } 12085 12086 div.remove(); 12087 12088 return (cachedScrollbarWidth = w1 - w2); 12089 }, 12090 getScrollInfo: function( within ) { 12091 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 12092 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 12093 hasOverflowX = overflowX === "scroll" || 12094 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 12095 hasOverflowY = overflowY === "scroll" || 12096 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 12097 return { 12098 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 12099 height: hasOverflowX ? $.position.scrollbarWidth() : 0 12100 }; 12101 }, 12102 getWithinInfo: function( element ) { 12103 var withinElement = $( element || window ), 12104 isWindow = $.isWindow( withinElement[0] ); 12105 return { 12106 element: withinElement, 12107 isWindow: isWindow, 12108 offset: withinElement.offset() || { left: 0, top: 0 }, 12109 scrollLeft: withinElement.scrollLeft(), 12110 scrollTop: withinElement.scrollTop(), 12111 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 12112 height: isWindow ? withinElement.height() : withinElement.outerHeight() 12113 }; 12114 } 12115 }; 12116 12117 $.fn.position = function( options ) { 12118 if ( !options || !options.of ) { 12119 return _position.apply( this, arguments ); 12120 } 12121 12122 // make a copy, we don't want to modify arguments 12123 options = $.extend( {}, options ); 12124 12125 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 12126 target = $( options.of ), 12127 within = $.position.getWithinInfo( options.within ), 12128 scrollInfo = $.position.getScrollInfo( within ), 12129 collision = ( options.collision || "flip" ).split( " " ), 12130 offsets = {}; 12131 12132 dimensions = getDimensions( target ); 12133 if ( target[0].preventDefault ) { 12134 // force left top to allow flipping 12135 options.at = "left top"; 12136 } 12137 targetWidth = dimensions.width; 12138 targetHeight = dimensions.height; 12139 targetOffset = dimensions.offset; 12140 // clone to reuse original targetOffset later 12141 basePosition = $.extend( {}, targetOffset ); 12142 12143 // force my and at to have valid horizontal and vertical positions 12144 // if a value is missing or invalid, it will be converted to center 12145 $.each( [ "my", "at" ], function() { 12146 var pos = ( options[ this ] || "" ).split( " " ), 12147 horizontalOffset, 12148 verticalOffset; 12149 12150 if ( pos.length === 1) { 12151 pos = rhorizontal.test( pos[ 0 ] ) ? 12152 pos.concat( [ "center" ] ) : 12153 rvertical.test( pos[ 0 ] ) ? 12154 [ "center" ].concat( pos ) : 12155 [ "center", "center" ]; 12156 } 12157 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 12158 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 12159 12160 // calculate offsets 12161 horizontalOffset = roffset.exec( pos[ 0 ] ); 12162 verticalOffset = roffset.exec( pos[ 1 ] ); 12163 offsets[ this ] = [ 12164 horizontalOffset ? horizontalOffset[ 0 ] : 0, 12165 verticalOffset ? verticalOffset[ 0 ] : 0 12166 ]; 12167 12168 // reduce to just the positions without the offsets 12169 options[ this ] = [ 12170 rposition.exec( pos[ 0 ] )[ 0 ], 12171 rposition.exec( pos[ 1 ] )[ 0 ] 12172 ]; 12173 }); 12174 12175 // normalize collision option 12176 if ( collision.length === 1 ) { 12177 collision[ 1 ] = collision[ 0 ]; 12178 } 12179 12180 if ( options.at[ 0 ] === "right" ) { 12181 basePosition.left += targetWidth; 12182 } else if ( options.at[ 0 ] === "center" ) { 12183 basePosition.left += targetWidth / 2; 12184 } 12185 12186 if ( options.at[ 1 ] === "bottom" ) { 12187 basePosition.top += targetHeight; 12188 } else if ( options.at[ 1 ] === "center" ) { 12189 basePosition.top += targetHeight / 2; 12190 } 12191 12192 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 12193 basePosition.left += atOffset[ 0 ]; 12194 basePosition.top += atOffset[ 1 ]; 12195 12196 return this.each(function() { 12197 var collisionPosition, using, 12198 elem = $( this ), 12199 elemWidth = elem.outerWidth(), 12200 elemHeight = elem.outerHeight(), 12201 marginLeft = parseCss( this, "marginLeft" ), 12202 marginTop = parseCss( this, "marginTop" ), 12203 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 12204 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 12205 position = $.extend( {}, basePosition ), 12206 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 12207 12208 if ( options.my[ 0 ] === "right" ) { 12209 position.left -= elemWidth; 12210 } else if ( options.my[ 0 ] === "center" ) { 12211 position.left -= elemWidth / 2; 12212 } 12213 12214 if ( options.my[ 1 ] === "bottom" ) { 12215 position.top -= elemHeight; 12216 } else if ( options.my[ 1 ] === "center" ) { 12217 position.top -= elemHeight / 2; 12218 } 12219 12220 position.left += myOffset[ 0 ]; 12221 position.top += myOffset[ 1 ]; 12222 12223 // if the browser doesn't support fractions, then round for consistent results 12224 if ( !$.support.offsetFractions ) { 12225 position.left = round( position.left ); 12226 position.top = round( position.top ); 12227 } 12228 12229 collisionPosition = { 12230 marginLeft: marginLeft, 12231 marginTop: marginTop 12232 }; 12233 12234 $.each( [ "left", "top" ], function( i, dir ) { 12235 if ( $.ui.position[ collision[ i ] ] ) { 12236 $.ui.position[ collision[ i ] ][ dir ]( position, { 12237 targetWidth: targetWidth, 12238 targetHeight: targetHeight, 12239 elemWidth: elemWidth, 12240 elemHeight: elemHeight, 12241 collisionPosition: collisionPosition, 12242 collisionWidth: collisionWidth, 12243 collisionHeight: collisionHeight, 12244 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 12245 my: options.my, 12246 at: options.at, 12247 within: within, 12248 elem : elem 12249 }); 12250 } 12251 }); 12252 12253 if ( options.using ) { 12254 // adds feedback as second argument to using callback, if present 12255 using = function( props ) { 12256 var left = targetOffset.left - position.left, 12257 right = left + targetWidth - elemWidth, 12258 top = targetOffset.top - position.top, 12259 bottom = top + targetHeight - elemHeight, 12260 feedback = { 12261 target: { 12262 element: target, 12263 left: targetOffset.left, 12264 top: targetOffset.top, 12265 width: targetWidth, 12266 height: targetHeight 12267 }, 12268 element: { 12269 element: elem, 12270 left: position.left, 12271 top: position.top, 12272 width: elemWidth, 12273 height: elemHeight 12274 }, 12275 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 12276 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 12277 }; 12278 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 12279 feedback.horizontal = "center"; 12280 } 12281 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 12282 feedback.vertical = "middle"; 12283 } 12284 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 12285 feedback.important = "horizontal"; 12286 } else { 12287 feedback.important = "vertical"; 12288 } 12289 options.using.call( this, props, feedback ); 12290 }; 12291 } 12292 12293 elem.offset( $.extend( position, { using: using } ) ); 12294 }); 12295 }; 12296 12297 $.ui.position = { 12298 fit: { 12299 left: function( position, data ) { 12300 var within = data.within, 12301 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 12302 outerWidth = within.width, 12303 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12304 overLeft = withinOffset - collisionPosLeft, 12305 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 12306 newOverRight; 12307 12308 // element is wider than within 12309 if ( data.collisionWidth > outerWidth ) { 12310 // element is initially over the left side of within 12311 if ( overLeft > 0 && overRight <= 0 ) { 12312 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 12313 position.left += overLeft - newOverRight; 12314 // element is initially over right side of within 12315 } else if ( overRight > 0 && overLeft <= 0 ) { 12316 position.left = withinOffset; 12317 // element is initially over both left and right sides of within 12318 } else { 12319 if ( overLeft > overRight ) { 12320 position.left = withinOffset + outerWidth - data.collisionWidth; 12321 } else { 12322 position.left = withinOffset; 12323 } 12324 } 12325 // too far left -> align with left edge 12326 } else if ( overLeft > 0 ) { 12327 position.left += overLeft; 12328 // too far right -> align with right edge 12329 } else if ( overRight > 0 ) { 12330 position.left -= overRight; 12331 // adjust based on position and margin 12332 } else { 12333 position.left = max( position.left - collisionPosLeft, position.left ); 12334 } 12335 }, 12336 top: function( position, data ) { 12337 var within = data.within, 12338 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 12339 outerHeight = data.within.height, 12340 collisionPosTop = position.top - data.collisionPosition.marginTop, 12341 overTop = withinOffset - collisionPosTop, 12342 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 12343 newOverBottom; 12344 12345 // element is taller than within 12346 if ( data.collisionHeight > outerHeight ) { 12347 // element is initially over the top of within 12348 if ( overTop > 0 && overBottom <= 0 ) { 12349 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 12350 position.top += overTop - newOverBottom; 12351 // element is initially over bottom of within 12352 } else if ( overBottom > 0 && overTop <= 0 ) { 12353 position.top = withinOffset; 12354 // element is initially over both top and bottom of within 12355 } else { 12356 if ( overTop > overBottom ) { 12357 position.top = withinOffset + outerHeight - data.collisionHeight; 12358 } else { 12359 position.top = withinOffset; 12360 } 12361 } 12362 // too far up -> align with top 12363 } else if ( overTop > 0 ) { 12364 position.top += overTop; 12365 // too far down -> align with bottom edge 12366 } else if ( overBottom > 0 ) { 12367 position.top -= overBottom; 12368 // adjust based on position and margin 12369 } else { 12370 position.top = max( position.top - collisionPosTop, position.top ); 12371 } 12372 } 12373 }, 12374 flip: { 12375 left: function( position, data ) { 12376 var within = data.within, 12377 withinOffset = within.offset.left + within.scrollLeft, 12378 outerWidth = within.width, 12379 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12380 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12381 overLeft = collisionPosLeft - offsetLeft, 12382 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12383 myOffset = data.my[ 0 ] === "left" ? 12384 -data.elemWidth : 12385 data.my[ 0 ] === "right" ? 12386 data.elemWidth : 12387 0, 12388 atOffset = data.at[ 0 ] === "left" ? 12389 data.targetWidth : 12390 data.at[ 0 ] === "right" ? 12391 -data.targetWidth : 12392 0, 12393 offset = -2 * data.offset[ 0 ], 12394 newOverRight, 12395 newOverLeft; 12396 12397 if ( overLeft < 0 ) { 12398 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 12399 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12400 position.left += myOffset + atOffset + offset; 12401 } 12402 } 12403 else if ( overRight > 0 ) { 12404 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 12405 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12406 position.left += myOffset + atOffset + offset; 12407 } 12408 } 12409 }, 12410 top: function( position, data ) { 12411 var within = data.within, 12412 withinOffset = within.offset.top + within.scrollTop, 12413 outerHeight = within.height, 12414 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12415 collisionPosTop = position.top - data.collisionPosition.marginTop, 12416 overTop = collisionPosTop - offsetTop, 12417 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12418 top = data.my[ 1 ] === "top", 12419 myOffset = top ? 12420 -data.elemHeight : 12421 data.my[ 1 ] === "bottom" ? 12422 data.elemHeight : 12423 0, 12424 atOffset = data.at[ 1 ] === "top" ? 12425 data.targetHeight : 12426 data.at[ 1 ] === "bottom" ? 12427 -data.targetHeight : 12428 0, 12429 offset = -2 * data.offset[ 1 ], 12430 newOverTop, 12431 newOverBottom; 12432 if ( overTop < 0 ) { 12433 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 12434 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 12435 position.top += myOffset + atOffset + offset; 12436 } 12437 } 12438 else if ( overBottom > 0 ) { 12439 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 12440 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 12441 position.top += myOffset + atOffset + offset; 12442 } 12443 } 12444 } 12445 }, 12446 flipfit: { 12447 left: function() { 12448 $.ui.position.flip.left.apply( this, arguments ); 12449 $.ui.position.fit.left.apply( this, arguments ); 12450 }, 12451 top: function() { 12452 $.ui.position.flip.top.apply( this, arguments ); 12453 $.ui.position.fit.top.apply( this, arguments ); 12454 } 12455 } 12456 }; 12457 12458// fraction support test 12459 (function () { 12460 var testElement, testElementParent, testElementStyle, offsetLeft, i, 12461 body = document.getElementsByTagName( "body" )[ 0 ], 12462 div = document.createElement( "div" ); 12463 12464 //Create a "fake body" for testing based on method used in jQuery.support 12465 testElement = document.createElement( body ? "div" : "body" ); 12466 testElementStyle = { 12467 visibility: "hidden", 12468 width: 0, 12469 height: 0, 12470 border: 0, 12471 margin: 0, 12472 background: "none" 12473 }; 12474 if ( body ) { 12475 $.extend( testElementStyle, { 12476 position: "absolute", 12477 left: "-1000px", 12478 top: "-1000px" 12479 }); 12480 } 12481 for ( i in testElementStyle ) { 12482 testElement.style[ i ] = testElementStyle[ i ]; 12483 } 12484 testElement.appendChild( div ); 12485 testElementParent = body || document.documentElement; 12486 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 12487 12488 div.style.cssText = "position: absolute; left: 10.7432222px;"; 12489 12490 offsetLeft = $( div ).offset().left; 12491 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 12492 12493 testElement.innerHTML = ""; 12494 testElementParent.removeChild( testElement ); 12495 })(); 12496 12497}( jQuery ) ); 12498 12499(function( $, undefined ) { 12500 12501 $.widget( "ui.progressbar", { 12502 version: "1.10.2", 12503 options: { 12504 max: 100, 12505 value: 0, 12506 12507 change: null, 12508 complete: null 12509 }, 12510 12511 min: 0, 12512 12513 _create: function() { 12514 // Constrain initial value 12515 this.oldValue = this.options.value = this._constrainedValue(); 12516 12517 this.element 12518 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12519 .attr({ 12520 // Only set static values, aria-valuenow and aria-valuemax are 12521 // set inside _refreshValue() 12522 role: "progressbar", 12523 "aria-valuemin": this.min 12524 }); 12525 12526 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12527 .appendTo( this.element ); 12528 12529 this._refreshValue(); 12530 }, 12531 12532 _destroy: function() { 12533 this.element 12534 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12535 .removeAttr( "role" ) 12536 .removeAttr( "aria-valuemin" ) 12537 .removeAttr( "aria-valuemax" ) 12538 .removeAttr( "aria-valuenow" ); 12539 12540 this.valueDiv.remove(); 12541 }, 12542 12543 value: function( newValue ) { 12544 if ( newValue === undefined ) { 12545 return this.options.value; 12546 } 12547 12548 this.options.value = this._constrainedValue( newValue ); 12549 this._refreshValue(); 12550 }, 12551 12552 _constrainedValue: function( newValue ) { 12553 if ( newValue === undefined ) { 12554 newValue = this.options.value; 12555 } 12556 12557 this.indeterminate = newValue === false; 12558 12559 // sanitize value 12560 if ( typeof newValue !== "number" ) { 12561 newValue = 0; 12562 } 12563 12564 return this.indeterminate ? false : 12565 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12566 }, 12567 12568 _setOptions: function( options ) { 12569 // Ensure "value" option is set after other values (like max) 12570 var value = options.value; 12571 delete options.value; 12572 12573 this._super( options ); 12574 12575 this.options.value = this._constrainedValue( value ); 12576 this._refreshValue(); 12577 }, 12578 12579 _setOption: function( key, value ) { 12580 if ( key === "max" ) { 12581 // Don't allow a max less than min 12582 value = Math.max( this.min, value ); 12583 } 12584 12585 this._super( key, value ); 12586 }, 12587 12588 _percentage: function() { 12589 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12590 }, 12591 12592 _refreshValue: function() { 12593 var value = this.options.value, 12594 percentage = this._percentage(); 12595 12596 this.valueDiv 12597 .toggle( this.indeterminate || value > this.min ) 12598 .toggleClass( "ui-corner-right", value === this.options.max ) 12599 .width( percentage.toFixed(0) + "%" ); 12600 12601 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12602 12603 if ( this.indeterminate ) { 12604 this.element.removeAttr( "aria-valuenow" ); 12605 if ( !this.overlayDiv ) { 12606 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12607 } 12608 } else { 12609 this.element.attr({ 12610 "aria-valuemax": this.options.max, 12611 "aria-valuenow": value 12612 }); 12613 if ( this.overlayDiv ) { 12614 this.overlayDiv.remove(); 12615 this.overlayDiv = null; 12616 } 12617 } 12618 12619 if ( this.oldValue !== value ) { 12620 this.oldValue = value; 12621 this._trigger( "change" ); 12622 } 12623 if ( value === this.options.max ) { 12624 this._trigger( "complete" ); 12625 } 12626 } 12627 }); 12628 12629})( jQuery ); 12630 12631(function( $, undefined ) { 12632 12633// number of pages in a slider 12634// (how many times can you page up/down to go through the whole range) 12635 var numPages = 5; 12636 12637 $.widget( "ui.slider", $.ui.mouse, { 12638 version: "1.10.2", 12639 widgetEventPrefix: "slide", 12640 12641 options: { 12642 animate: false, 12643 distance: 0, 12644 max: 100, 12645 min: 0, 12646 orientation: "horizontal", 12647 range: false, 12648 step: 1, 12649 value: 0, 12650 values: null, 12651 12652 // callbacks 12653 change: null, 12654 slide: null, 12655 start: null, 12656 stop: null 12657 }, 12658 12659 _create: function() { 12660 this._keySliding = false; 12661 this._mouseSliding = false; 12662 this._animateOff = true; 12663 this._handleIndex = null; 12664 this._detectOrientation(); 12665 this._mouseInit(); 12666 12667 this.element 12668 .addClass( "ui-slider" + 12669 " ui-slider-" + this.orientation + 12670 " ui-widget" + 12671 " ui-widget-content" + 12672 " ui-corner-all"); 12673 12674 this._refresh(); 12675 this._setOption( "disabled", this.options.disabled ); 12676 12677 this._animateOff = false; 12678 }, 12679 12680 _refresh: function() { 12681 this._createRange(); 12682 this._createHandles(); 12683 this._setupEvents(); 12684 this._refreshValue(); 12685 }, 12686 12687 _createHandles: function() { 12688 var i, handleCount, 12689 options = this.options, 12690 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 12691 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 12692 handles = []; 12693 12694 handleCount = ( options.values && options.values.length ) || 1; 12695 12696 if ( existingHandles.length > handleCount ) { 12697 existingHandles.slice( handleCount ).remove(); 12698 existingHandles = existingHandles.slice( 0, handleCount ); 12699 } 12700 12701 for ( i = existingHandles.length; i < handleCount; i++ ) { 12702 handles.push( handle ); 12703 } 12704 12705 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 12706 12707 this.handle = this.handles.eq( 0 ); 12708 12709 this.handles.each(function( i ) { 12710 $( this ).data( "ui-slider-handle-index", i ); 12711 }); 12712 }, 12713 12714 _createRange: function() { 12715 var options = this.options, 12716 classes = ""; 12717 12718 if ( options.range ) { 12719 if ( options.range === true ) { 12720 if ( !options.values ) { 12721 options.values = [ this._valueMin(), this._valueMin() ]; 12722 } else if ( options.values.length && options.values.length !== 2 ) { 12723 options.values = [ options.values[0], options.values[0] ]; 12724 } else if ( $.isArray( options.values ) ) { 12725 options.values = options.values.slice(0); 12726 } 12727 } 12728 12729 if ( !this.range || !this.range.length ) { 12730 this.range = $( "<div></div>" ) 12731 .appendTo( this.element ); 12732 12733 classes = "ui-slider-range" + 12734 // note: this isn't the most fittingly semantic framework class for this element, 12735 // but worked best visually with a variety of themes 12736 " ui-widget-header ui-corner-all"; 12737 } else { 12738 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 12739 // Handle range switching from true to min/max 12740 .css({ 12741 "left": "", 12742 "bottom": "" 12743 }); 12744 } 12745 12746 this.range.addClass( classes + 12747 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 12748 } else { 12749 this.range = $([]); 12750 } 12751 }, 12752 12753 _setupEvents: function() { 12754 var elements = this.handles.add( this.range ).filter( "a" ); 12755 this._off( elements ); 12756 this._on( elements, this._handleEvents ); 12757 this._hoverable( elements ); 12758 this._focusable( elements ); 12759 }, 12760 12761 _destroy: function() { 12762 this.handles.remove(); 12763 this.range.remove(); 12764 12765 this.element 12766 .removeClass( "ui-slider" + 12767 " ui-slider-horizontal" + 12768 " ui-slider-vertical" + 12769 " ui-widget" + 12770 " ui-widget-content" + 12771 " ui-corner-all" ); 12772 12773 this._mouseDestroy(); 12774 }, 12775 12776 _mouseCapture: function( event ) { 12777 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 12778 that = this, 12779 o = this.options; 12780 12781 if ( o.disabled ) { 12782 return false; 12783 } 12784 12785 this.elementSize = { 12786 width: this.element.outerWidth(), 12787 height: this.element.outerHeight() 12788 }; 12789 this.elementOffset = this.element.offset(); 12790 12791 position = { x: event.pageX, y: event.pageY }; 12792 normValue = this._normValueFromMouse( position ); 12793 distance = this._valueMax() - this._valueMin() + 1; 12794 this.handles.each(function( i ) { 12795 var thisDistance = Math.abs( normValue - that.values(i) ); 12796 if (( distance > thisDistance ) || 12797 ( distance === thisDistance && 12798 (i === that._lastChangedValue || that.values(i) === o.min ))) { 12799 distance = thisDistance; 12800 closestHandle = $( this ); 12801 index = i; 12802 } 12803 }); 12804 12805 allowed = this._start( event, index ); 12806 if ( allowed === false ) { 12807 return false; 12808 } 12809 this._mouseSliding = true; 12810 12811 this._handleIndex = index; 12812 12813 closestHandle 12814 .addClass( "ui-state-active" ) 12815 .focus(); 12816 12817 offset = closestHandle.offset(); 12818 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 12819 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 12820 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 12821 top: event.pageY - offset.top - 12822 ( closestHandle.height() / 2 ) - 12823 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 12824 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 12825 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 12826 }; 12827 12828 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 12829 this._slide( event, index, normValue ); 12830 } 12831 this._animateOff = true; 12832 return true; 12833 }, 12834 12835 _mouseStart: function() { 12836 return true; 12837 }, 12838 12839 _mouseDrag: function( event ) { 12840 var position = { x: event.pageX, y: event.pageY }, 12841 normValue = this._normValueFromMouse( position ); 12842 12843 this._slide( event, this._handleIndex, normValue ); 12844 12845 return false; 12846 }, 12847 12848 _mouseStop: function( event ) { 12849 this.handles.removeClass( "ui-state-active" ); 12850 this._mouseSliding = false; 12851 12852 this._stop( event, this._handleIndex ); 12853 this._change( event, this._handleIndex ); 12854 12855 this._handleIndex = null; 12856 this._clickOffset = null; 12857 this._animateOff = false; 12858 12859 return false; 12860 }, 12861 12862 _detectOrientation: function() { 12863 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 12864 }, 12865 12866 _normValueFromMouse: function( position ) { 12867 var pixelTotal, 12868 pixelMouse, 12869 percentMouse, 12870 valueTotal, 12871 valueMouse; 12872 12873 if ( this.orientation === "horizontal" ) { 12874 pixelTotal = this.elementSize.width; 12875 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 12876 } else { 12877 pixelTotal = this.elementSize.height; 12878 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 12879 } 12880 12881 percentMouse = ( pixelMouse / pixelTotal ); 12882 if ( percentMouse > 1 ) { 12883 percentMouse = 1; 12884 } 12885 if ( percentMouse < 0 ) { 12886 percentMouse = 0; 12887 } 12888 if ( this.orientation === "vertical" ) { 12889 percentMouse = 1 - percentMouse; 12890 } 12891 12892 valueTotal = this._valueMax() - this._valueMin(); 12893 valueMouse = this._valueMin() + percentMouse * valueTotal; 12894 12895 return this._trimAlignValue( valueMouse ); 12896 }, 12897 12898 _start: function( event, index ) { 12899 var uiHash = { 12900 handle: this.handles[ index ], 12901 value: this.value() 12902 }; 12903 if ( this.options.values && this.options.values.length ) { 12904 uiHash.value = this.values( index ); 12905 uiHash.values = this.values(); 12906 } 12907 return this._trigger( "start", event, uiHash ); 12908 }, 12909 12910 _slide: function( event, index, newVal ) { 12911 var otherVal, 12912 newValues, 12913 allowed; 12914 12915 if ( this.options.values && this.options.values.length ) { 12916 otherVal = this.values( index ? 0 : 1 ); 12917 12918 if ( ( this.options.values.length === 2 && this.options.range === true ) && 12919 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 12920 ) { 12921 newVal = otherVal; 12922 } 12923 12924 if ( newVal !== this.values( index ) ) { 12925 newValues = this.values(); 12926 newValues[ index ] = newVal; 12927 // A slide can be canceled by returning false from the slide callback 12928 allowed = this._trigger( "slide", event, { 12929 handle: this.handles[ index ], 12930 value: newVal, 12931 values: newValues 12932 } ); 12933 otherVal = this.values( index ? 0 : 1 ); 12934 if ( allowed !== false ) { 12935 this.values( index, newVal, true ); 12936 } 12937 } 12938 } else { 12939 if ( newVal !== this.value() ) { 12940 // A slide can be canceled by returning false from the slide callback 12941 allowed = this._trigger( "slide", event, { 12942 handle: this.handles[ index ], 12943 value: newVal 12944 } ); 12945 if ( allowed !== false ) { 12946 this.value( newVal ); 12947 } 12948 } 12949 } 12950 }, 12951 12952 _stop: function( event, index ) { 12953 var uiHash = { 12954 handle: this.handles[ index ], 12955 value: this.value() 12956 }; 12957 if ( this.options.values && this.options.values.length ) { 12958 uiHash.value = this.values( index ); 12959 uiHash.values = this.values(); 12960 } 12961 12962 this._trigger( "stop", event, uiHash ); 12963 }, 12964 12965 _change: function( event, index ) { 12966 if ( !this._keySliding && !this._mouseSliding ) { 12967 var uiHash = { 12968 handle: this.handles[ index ], 12969 value: this.value() 12970 }; 12971 if ( this.options.values && this.options.values.length ) { 12972 uiHash.value = this.values( index ); 12973 uiHash.values = this.values(); 12974 } 12975 12976 //store the last changed value index for reference when handles overlap 12977 this._lastChangedValue = index; 12978 12979 this._trigger( "change", event, uiHash ); 12980 } 12981 }, 12982 12983 value: function( newValue ) { 12984 if ( arguments.length ) { 12985 this.options.value = this._trimAlignValue( newValue ); 12986 this._refreshValue(); 12987 this._change( null, 0 ); 12988 return; 12989 } 12990 12991 return this._value(); 12992 }, 12993 12994 values: function( index, newValue ) { 12995 var vals, 12996 newValues, 12997 i; 12998 12999 if ( arguments.length > 1 ) { 13000 this.options.values[ index ] = this._trimAlignValue( newValue ); 13001 this._refreshValue(); 13002 this._change( null, index ); 13003 return; 13004 } 13005 13006 if ( arguments.length ) { 13007 if ( $.isArray( arguments[ 0 ] ) ) { 13008 vals = this.options.values; 13009 newValues = arguments[ 0 ]; 13010 for ( i = 0; i < vals.length; i += 1 ) { 13011 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13012 this._change( null, i ); 13013 } 13014 this._refreshValue(); 13015 } else { 13016 if ( this.options.values && this.options.values.length ) { 13017 return this._values( index ); 13018 } else { 13019 return this.value(); 13020 } 13021 } 13022 } else { 13023 return this._values(); 13024 } 13025 }, 13026 13027 _setOption: function( key, value ) { 13028 var i, 13029 valsLength = 0; 13030 13031 if ( key === "range" && this.options.range === true ) { 13032 if ( value === "min" ) { 13033 this.options.value = this._values( 0 ); 13034 this.options.values = null; 13035 } else if ( value === "max" ) { 13036 this.options.value = this._values( this.options.values.length-1 ); 13037 this.options.values = null; 13038 } 13039 } 13040 13041 if ( $.isArray( this.options.values ) ) { 13042 valsLength = this.options.values.length; 13043 } 13044 13045 $.Widget.prototype._setOption.apply( this, arguments ); 13046 13047 switch ( key ) { 13048 case "orientation": 13049 this._detectOrientation(); 13050 this.element 13051 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13052 .addClass( "ui-slider-" + this.orientation ); 13053 this._refreshValue(); 13054 break; 13055 case "value": 13056 this._animateOff = true; 13057 this._refreshValue(); 13058 this._change( null, 0 ); 13059 this._animateOff = false; 13060 break; 13061 case "values": 13062 this._animateOff = true; 13063 this._refreshValue(); 13064 for ( i = 0; i < valsLength; i += 1 ) { 13065 this._change( null, i ); 13066 } 13067 this._animateOff = false; 13068 break; 13069 case "min": 13070 case "max": 13071 this._animateOff = true; 13072 this._refreshValue(); 13073 this._animateOff = false; 13074 break; 13075 case "range": 13076 this._animateOff = true; 13077 this._refresh(); 13078 this._animateOff = false; 13079 break; 13080 } 13081 }, 13082 13083 //internal value getter 13084 // _value() returns value trimmed by min and max, aligned by step 13085 _value: function() { 13086 var val = this.options.value; 13087 val = this._trimAlignValue( val ); 13088 13089 return val; 13090 }, 13091 13092 //internal values getter 13093 // _values() returns array of values trimmed by min and max, aligned by step 13094 // _values( index ) returns single value trimmed by min and max, aligned by step 13095 _values: function( index ) { 13096 var val, 13097 vals, 13098 i; 13099 13100 if ( arguments.length ) { 13101 val = this.options.values[ index ]; 13102 val = this._trimAlignValue( val ); 13103 13104 return val; 13105 } else if ( this.options.values && this.options.values.length ) { 13106 // .slice() creates a copy of the array 13107 // this copy gets trimmed by min and max and then returned 13108 vals = this.options.values.slice(); 13109 for ( i = 0; i < vals.length; i+= 1) { 13110 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13111 } 13112 13113 return vals; 13114 } else { 13115 return []; 13116 } 13117 }, 13118 13119 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13120 _trimAlignValue: function( val ) { 13121 if ( val <= this._valueMin() ) { 13122 return this._valueMin(); 13123 } 13124 if ( val >= this._valueMax() ) { 13125 return this._valueMax(); 13126 } 13127 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13128 valModStep = (val - this._valueMin()) % step, 13129 alignValue = val - valModStep; 13130 13131 if ( Math.abs(valModStep) * 2 >= step ) { 13132 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13133 } 13134 13135 // Since JavaScript has problems with large floats, round 13136 // the final value to 5 digits after the decimal point (see #4124) 13137 return parseFloat( alignValue.toFixed(5) ); 13138 }, 13139 13140 _valueMin: function() { 13141 return this.options.min; 13142 }, 13143 13144 _valueMax: function() { 13145 return this.options.max; 13146 }, 13147 13148 _refreshValue: function() { 13149 var lastValPercent, valPercent, value, valueMin, valueMax, 13150 oRange = this.options.range, 13151 o = this.options, 13152 that = this, 13153 animate = ( !this._animateOff ) ? o.animate : false, 13154 _set = {}; 13155 13156 if ( this.options.values && this.options.values.length ) { 13157 this.handles.each(function( i ) { 13158 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13159 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13160 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13161 if ( that.options.range === true ) { 13162 if ( that.orientation === "horizontal" ) { 13163 if ( i === 0 ) { 13164 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13165 } 13166 if ( i === 1 ) { 13167 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13168 } 13169 } else { 13170 if ( i === 0 ) { 13171 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13172 } 13173 if ( i === 1 ) { 13174 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13175 } 13176 } 13177 } 13178 lastValPercent = valPercent; 13179 }); 13180 } else { 13181 value = this.value(); 13182 valueMin = this._valueMin(); 13183 valueMax = this._valueMax(); 13184 valPercent = ( valueMax !== valueMin ) ? 13185 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13186 0; 13187 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13188 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13189 13190 if ( oRange === "min" && this.orientation === "horizontal" ) { 13191 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13192 } 13193 if ( oRange === "max" && this.orientation === "horizontal" ) { 13194 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13195 } 13196 if ( oRange === "min" && this.orientation === "vertical" ) { 13197 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13198 } 13199 if ( oRange === "max" && this.orientation === "vertical" ) { 13200 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13201 } 13202 } 13203 }, 13204 13205 _handleEvents: { 13206 keydown: function( event ) { 13207 /*jshint maxcomplexity:25*/ 13208 var allowed, curVal, newVal, step, 13209 index = $( event.target ).data( "ui-slider-handle-index" ); 13210 13211 switch ( event.keyCode ) { 13212 case $.ui.keyCode.HOME: 13213 case $.ui.keyCode.END: 13214 case $.ui.keyCode.PAGE_UP: 13215 case $.ui.keyCode.PAGE_DOWN: 13216 case $.ui.keyCode.UP: 13217 case $.ui.keyCode.RIGHT: 13218 case $.ui.keyCode.DOWN: 13219 case $.ui.keyCode.LEFT: 13220 event.preventDefault(); 13221 if ( !this._keySliding ) { 13222 this._keySliding = true; 13223 $( event.target ).addClass( "ui-state-active" ); 13224 allowed = this._start( event, index ); 13225 if ( allowed === false ) { 13226 return; 13227 } 13228 } 13229 break; 13230 } 13231 13232 step = this.options.step; 13233 if ( this.options.values && this.options.values.length ) { 13234 curVal = newVal = this.values( index ); 13235 } else { 13236 curVal = newVal = this.value(); 13237 } 13238 13239 switch ( event.keyCode ) { 13240 case $.ui.keyCode.HOME: 13241 newVal = this._valueMin(); 13242 break; 13243 case $.ui.keyCode.END: 13244 newVal = this._valueMax(); 13245 break; 13246 case $.ui.keyCode.PAGE_UP: 13247 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13248 break; 13249 case $.ui.keyCode.PAGE_DOWN: 13250 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13251 break; 13252 case $.ui.keyCode.UP: 13253 case $.ui.keyCode.RIGHT: 13254 if ( curVal === this._valueMax() ) { 13255 return; 13256 } 13257 newVal = this._trimAlignValue( curVal + step ); 13258 break; 13259 case $.ui.keyCode.DOWN: 13260 case $.ui.keyCode.LEFT: 13261 if ( curVal === this._valueMin() ) { 13262 return; 13263 } 13264 newVal = this._trimAlignValue( curVal - step ); 13265 break; 13266 } 13267 13268 this._slide( event, index, newVal ); 13269 }, 13270 click: function( event ) { 13271 event.preventDefault(); 13272 }, 13273 keyup: function( event ) { 13274 var index = $( event.target ).data( "ui-slider-handle-index" ); 13275 13276 if ( this._keySliding ) { 13277 this._keySliding = false; 13278 this._stop( event, index ); 13279 this._change( event, index ); 13280 $( event.target ).removeClass( "ui-state-active" ); 13281 } 13282 } 13283 } 13284 13285 }); 13286 13287}(jQuery)); 13288 13289(function( $ ) { 13290 13291 function modifier( fn ) { 13292 return function() { 13293 var previous = this.element.val(); 13294 fn.apply( this, arguments ); 13295 this._refresh(); 13296 if ( previous !== this.element.val() ) { 13297 this._trigger( "change" ); 13298 } 13299 }; 13300 } 13301 13302 $.widget( "ui.spinner", { 13303 version: "1.10.2", 13304 defaultElement: "<input>", 13305 widgetEventPrefix: "spin", 13306 options: { 13307 culture: null, 13308 icons: { 13309 down: "ui-icon-triangle-1-s", 13310 up: "ui-icon-triangle-1-n" 13311 }, 13312 incremental: true, 13313 max: null, 13314 min: null, 13315 numberFormat: null, 13316 page: 10, 13317 step: 1, 13318 13319 change: null, 13320 spin: null, 13321 start: null, 13322 stop: null 13323 }, 13324 13325 _create: function() { 13326 // handle string values that need to be parsed 13327 this._setOption( "max", this.options.max ); 13328 this._setOption( "min", this.options.min ); 13329 this._setOption( "step", this.options.step ); 13330 13331 // format the value, but don't constrain 13332 this._value( this.element.val(), true ); 13333 13334 this._draw(); 13335 this._on( this._events ); 13336 this._refresh(); 13337 13338 // turning off autocomplete prevents the browser from remembering the 13339 // value when navigating through history, so we re-enable autocomplete 13340 // if the page is unloaded before the widget is destroyed. #7790 13341 this._on( this.window, { 13342 beforeunload: function() { 13343 this.element.removeAttr( "autocomplete" ); 13344 } 13345 }); 13346 }, 13347 13348 _getCreateOptions: function() { 13349 var options = {}, 13350 element = this.element; 13351 13352 $.each( [ "min", "max", "step" ], function( i, option ) { 13353 var value = element.attr( option ); 13354 if ( value !== undefined && value.length ) { 13355 options[ option ] = value; 13356 } 13357 }); 13358 13359 return options; 13360 }, 13361 13362 _events: { 13363 keydown: function( event ) { 13364 if ( this._start( event ) && this._keydown( event ) ) { 13365 event.preventDefault(); 13366 } 13367 }, 13368 keyup: "_stop", 13369 focus: function() { 13370 this.previous = this.element.val(); 13371 }, 13372 blur: function( event ) { 13373 if ( this.cancelBlur ) { 13374 delete this.cancelBlur; 13375 return; 13376 } 13377 13378 this._stop(); 13379 this._refresh(); 13380 if ( this.previous !== this.element.val() ) { 13381 this._trigger( "change", event ); 13382 } 13383 }, 13384 mousewheel: function( event, delta ) { 13385 if ( !delta ) { 13386 return; 13387 } 13388 if ( !this.spinning && !this._start( event ) ) { 13389 return false; 13390 } 13391 13392 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13393 clearTimeout( this.mousewheelTimer ); 13394 this.mousewheelTimer = this._delay(function() { 13395 if ( this.spinning ) { 13396 this._stop( event ); 13397 } 13398 }, 100 ); 13399 event.preventDefault(); 13400 }, 13401 "mousedown .ui-spinner-button": function( event ) { 13402 var previous; 13403 13404 // We never want the buttons to have focus; whenever the user is 13405 // interacting with the spinner, the focus should be on the input. 13406 // If the input is focused then this.previous is properly set from 13407 // when the input first received focus. If the input is not focused 13408 // then we need to set this.previous based on the value before spinning. 13409 previous = this.element[0] === this.document[0].activeElement ? 13410 this.previous : this.element.val(); 13411 function checkFocus() { 13412 var isActive = this.element[0] === this.document[0].activeElement; 13413 if ( !isActive ) { 13414 this.element.focus(); 13415 this.previous = previous; 13416 // support: IE 13417 // IE sets focus asynchronously, so we need to check if focus 13418 // moved off of the input because the user clicked on the button. 13419 this._delay(function() { 13420 this.previous = previous; 13421 }); 13422 } 13423 } 13424 13425 // ensure focus is on (or stays on) the text field 13426 event.preventDefault(); 13427 checkFocus.call( this ); 13428 13429 // support: IE 13430 // IE doesn't prevent moving focus even with event.preventDefault() 13431 // so we set a flag to know when we should ignore the blur event 13432 // and check (again) if focus moved off of the input. 13433 this.cancelBlur = true; 13434 this._delay(function() { 13435 delete this.cancelBlur; 13436 checkFocus.call( this ); 13437 }); 13438 13439 if ( this._start( event ) === false ) { 13440 return; 13441 } 13442 13443 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13444 }, 13445 "mouseup .ui-spinner-button": "_stop", 13446 "mouseenter .ui-spinner-button": function( event ) { 13447 // button will add ui-state-active if mouse was down while mouseleave and kept down 13448 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13449 return; 13450 } 13451 13452 if ( this._start( event ) === false ) { 13453 return false; 13454 } 13455 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13456 }, 13457 // TODO: do we really want to consider this a stop? 13458 // shouldn't we just stop the repeater and wait until mouseup before 13459 // we trigger the stop event? 13460 "mouseleave .ui-spinner-button": "_stop" 13461 }, 13462 13463 _draw: function() { 13464 var uiSpinner = this.uiSpinner = this.element 13465 .addClass( "ui-spinner-input" ) 13466 .attr( "autocomplete", "off" ) 13467 .wrap( this._uiSpinnerHtml() ) 13468 .parent() 13469 // add buttons 13470 .append( this._buttonHtml() ); 13471 13472 this.element.attr( "role", "spinbutton" ); 13473 13474 // button bindings 13475 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13476 .attr( "tabIndex", -1 ) 13477 .button() 13478 .removeClass( "ui-corner-all" ); 13479 13480 // IE 6 doesn't understand height: 50% for the buttons 13481 // unless the wrapper has an explicit height 13482 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13483 uiSpinner.height() > 0 ) { 13484 uiSpinner.height( uiSpinner.height() ); 13485 } 13486 13487 // disable spinner if element was already disabled 13488 if ( this.options.disabled ) { 13489 this.disable(); 13490 } 13491 }, 13492 13493 _keydown: function( event ) { 13494 var options = this.options, 13495 keyCode = $.ui.keyCode; 13496 13497 switch ( event.keyCode ) { 13498 case keyCode.UP: 13499 this._repeat( null, 1, event ); 13500 return true; 13501 case keyCode.DOWN: 13502 this._repeat( null, -1, event ); 13503 return true; 13504 case keyCode.PAGE_UP: 13505 this._repeat( null, options.page, event ); 13506 return true; 13507 case keyCode.PAGE_DOWN: 13508 this._repeat( null, -options.page, event ); 13509 return true; 13510 } 13511 13512 return false; 13513 }, 13514 13515 _uiSpinnerHtml: function() { 13516 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13517 }, 13518 13519 _buttonHtml: function() { 13520 return "" + 13521 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13522 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13523 "</a>" + 13524 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13525 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13526 "</a>"; 13527 }, 13528 13529 _start: function( event ) { 13530 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13531 return false; 13532 } 13533 13534 if ( !this.counter ) { 13535 this.counter = 1; 13536 } 13537 this.spinning = true; 13538 return true; 13539 }, 13540 13541 _repeat: function( i, steps, event ) { 13542 i = i || 500; 13543 13544 clearTimeout( this.timer ); 13545 this.timer = this._delay(function() { 13546 this._repeat( 40, steps, event ); 13547 }, i ); 13548 13549 this._spin( steps * this.options.step, event ); 13550 }, 13551 13552 _spin: function( step, event ) { 13553 var value = this.value() || 0; 13554 13555 if ( !this.counter ) { 13556 this.counter = 1; 13557 } 13558 13559 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13560 13561 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13562 this._value( value ); 13563 this.counter++; 13564 } 13565 }, 13566 13567 _increment: function( i ) { 13568 var incremental = this.options.incremental; 13569 13570 if ( incremental ) { 13571 return $.isFunction( incremental ) ? 13572 incremental( i ) : 13573 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13574 } 13575 13576 return 1; 13577 }, 13578 13579 _precision: function() { 13580 var precision = this._precisionOf( this.options.step ); 13581 if ( this.options.min !== null ) { 13582 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13583 } 13584 return precision; 13585 }, 13586 13587 _precisionOf: function( num ) { 13588 var str = num.toString(), 13589 decimal = str.indexOf( "." ); 13590 return decimal === -1 ? 0 : str.length - decimal - 1; 13591 }, 13592 13593 _adjustValue: function( value ) { 13594 var base, aboveMin, 13595 options = this.options; 13596 13597 // make sure we're at a valid step 13598 // - find out where we are relative to the base (min or 0) 13599 base = options.min !== null ? options.min : 0; 13600 aboveMin = value - base; 13601 // - round to the nearest step 13602 aboveMin = Math.round(aboveMin / options.step) * options.step; 13603 // - rounding is based on 0, so adjust back to our base 13604 value = base + aboveMin; 13605 13606 // fix precision from bad JS floating point math 13607 value = parseFloat( value.toFixed( this._precision() ) ); 13608 13609 // clamp the value 13610 if ( options.max !== null && value > options.max) { 13611 return options.max; 13612 } 13613 if ( options.min !== null && value < options.min ) { 13614 return options.min; 13615 } 13616 13617 return value; 13618 }, 13619 13620 _stop: function( event ) { 13621 if ( !this.spinning ) { 13622 return; 13623 } 13624 13625 clearTimeout( this.timer ); 13626 clearTimeout( this.mousewheelTimer ); 13627 this.counter = 0; 13628 this.spinning = false; 13629 this._trigger( "stop", event ); 13630 }, 13631 13632 _setOption: function( key, value ) { 13633 if ( key === "culture" || key === "numberFormat" ) { 13634 var prevValue = this._parse( this.element.val() ); 13635 this.options[ key ] = value; 13636 this.element.val( this._format( prevValue ) ); 13637 return; 13638 } 13639 13640 if ( key === "max" || key === "min" || key === "step" ) { 13641 if ( typeof value === "string" ) { 13642 value = this._parse( value ); 13643 } 13644 } 13645 if ( key === "icons" ) { 13646 this.buttons.first().find( ".ui-icon" ) 13647 .removeClass( this.options.icons.up ) 13648 .addClass( value.up ); 13649 this.buttons.last().find( ".ui-icon" ) 13650 .removeClass( this.options.icons.down ) 13651 .addClass( value.down ); 13652 } 13653 13654 this._super( key, value ); 13655 13656 if ( key === "disabled" ) { 13657 if ( value ) { 13658 this.element.prop( "disabled", true ); 13659 this.buttons.button( "disable" ); 13660 } else { 13661 this.element.prop( "disabled", false ); 13662 this.buttons.button( "enable" ); 13663 } 13664 } 13665 }, 13666 13667 _setOptions: modifier(function( options ) { 13668 this._super( options ); 13669 this._value( this.element.val() ); 13670 }), 13671 13672 _parse: function( val ) { 13673 if ( typeof val === "string" && val !== "" ) { 13674 val = window.Globalize && this.options.numberFormat ? 13675 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 13676 } 13677 return val === "" || isNaN( val ) ? null : val; 13678 }, 13679 13680 _format: function( value ) { 13681 if ( value === "" ) { 13682 return ""; 13683 } 13684 return window.Globalize && this.options.numberFormat ? 13685 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 13686 value; 13687 }, 13688 13689 _refresh: function() { 13690 this.element.attr({ 13691 "aria-valuemin": this.options.min, 13692 "aria-valuemax": this.options.max, 13693 // TODO: what should we do with values that can't be parsed? 13694 "aria-valuenow": this._parse( this.element.val() ) 13695 }); 13696 }, 13697 13698 // update the value without triggering change 13699 _value: function( value, allowAny ) { 13700 var parsed; 13701 if ( value !== "" ) { 13702 parsed = this._parse( value ); 13703 if ( parsed !== null ) { 13704 if ( !allowAny ) { 13705 parsed = this._adjustValue( parsed ); 13706 } 13707 value = this._format( parsed ); 13708 } 13709 } 13710 this.element.val( value ); 13711 this._refresh(); 13712 }, 13713 13714 _destroy: function() { 13715 this.element 13716 .removeClass( "ui-spinner-input" ) 13717 .prop( "disabled", false ) 13718 .removeAttr( "autocomplete" ) 13719 .removeAttr( "role" ) 13720 .removeAttr( "aria-valuemin" ) 13721 .removeAttr( "aria-valuemax" ) 13722 .removeAttr( "aria-valuenow" ); 13723 this.uiSpinner.replaceWith( this.element ); 13724 }, 13725 13726 stepUp: modifier(function( steps ) { 13727 this._stepUp( steps ); 13728 }), 13729 _stepUp: function( steps ) { 13730 if ( this._start() ) { 13731 this._spin( (steps || 1) * this.options.step ); 13732 this._stop(); 13733 } 13734 }, 13735 13736 stepDown: modifier(function( steps ) { 13737 this._stepDown( steps ); 13738 }), 13739 _stepDown: function( steps ) { 13740 if ( this._start() ) { 13741 this._spin( (steps || 1) * -this.options.step ); 13742 this._stop(); 13743 } 13744 }, 13745 13746 pageUp: modifier(function( pages ) { 13747 this._stepUp( (pages || 1) * this.options.page ); 13748 }), 13749 13750 pageDown: modifier(function( pages ) { 13751 this._stepDown( (pages || 1) * this.options.page ); 13752 }), 13753 13754 value: function( newVal ) { 13755 if ( !arguments.length ) { 13756 return this._parse( this.element.val() ); 13757 } 13758 modifier( this._value ).call( this, newVal ); 13759 }, 13760 13761 widget: function() { 13762 return this.uiSpinner; 13763 } 13764 }); 13765 13766}( jQuery ) ); 13767 13768(function( $, undefined ) { 13769 13770 var tabId = 0, 13771 rhash = /#.*$/; 13772 13773 function getNextTabId() { 13774 return ++tabId; 13775 } 13776 13777 function isLocal( anchor ) { 13778 return anchor.hash.length > 1 && 13779 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 13780 decodeURIComponent( location.href.replace( rhash, "" ) ); 13781 } 13782 13783 $.widget( "ui.tabs", { 13784 version: "1.10.2", 13785 delay: 300, 13786 options: { 13787 active: null, 13788 collapsible: false, 13789 event: "click", 13790 heightStyle: "content", 13791 hide: null, 13792 show: null, 13793 13794 // callbacks 13795 activate: null, 13796 beforeActivate: null, 13797 beforeLoad: null, 13798 load: null 13799 }, 13800 13801 _create: function() { 13802 var that = this, 13803 options = this.options; 13804 13805 this.running = false; 13806 13807 this.element 13808 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 13809 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 13810 // Prevent users from focusing disabled tabs via click 13811 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 13812 if ( $( this ).is( ".ui-state-disabled" ) ) { 13813 event.preventDefault(); 13814 } 13815 }) 13816 // support: IE <9 13817 // Preventing the default action in mousedown doesn't prevent IE 13818 // from focusing the element, so if the anchor gets focused, blur. 13819 // We don't have to worry about focusing the previously focused 13820 // element since clicking on a non-focusable element should focus 13821 // the body anyway. 13822 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 13823 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 13824 this.blur(); 13825 } 13826 }); 13827 13828 this._processTabs(); 13829 options.active = this._initialActive(); 13830 13831 // Take disabling tabs via class attribute from HTML 13832 // into account and update option properly. 13833 if ( $.isArray( options.disabled ) ) { 13834 options.disabled = $.unique( options.disabled.concat( 13835 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 13836 return that.tabs.index( li ); 13837 }) 13838 ) ).sort(); 13839 } 13840 13841 // check for length avoids error when initializing empty list 13842 if ( this.options.active !== false && this.anchors.length ) { 13843 this.active = this._findActive( options.active ); 13844 } else { 13845 this.active = $(); 13846 } 13847 13848 this._refresh(); 13849 13850 if ( this.active.length ) { 13851 this.load( options.active ); 13852 } 13853 }, 13854 13855 _initialActive: function() { 13856 var active = this.options.active, 13857 collapsible = this.options.collapsible, 13858 locationHash = location.hash.substring( 1 ); 13859 13860 if ( active === null ) { 13861 // check the fragment identifier in the URL 13862 if ( locationHash ) { 13863 this.tabs.each(function( i, tab ) { 13864 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 13865 active = i; 13866 return false; 13867 } 13868 }); 13869 } 13870 13871 // check for a tab marked active via a class 13872 if ( active === null ) { 13873 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 13874 } 13875 13876 // no active tab, set to false 13877 if ( active === null || active === -1 ) { 13878 active = this.tabs.length ? 0 : false; 13879 } 13880 } 13881 13882 // handle numbers: negative, out of range 13883 if ( active !== false ) { 13884 active = this.tabs.index( this.tabs.eq( active ) ); 13885 if ( active === -1 ) { 13886 active = collapsible ? false : 0; 13887 } 13888 } 13889 13890 // don't allow collapsible: false and active: false 13891 if ( !collapsible && active === false && this.anchors.length ) { 13892 active = 0; 13893 } 13894 13895 return active; 13896 }, 13897 13898 _getCreateEventData: function() { 13899 return { 13900 tab: this.active, 13901 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 13902 }; 13903 }, 13904 13905 _tabKeydown: function( event ) { 13906 /*jshint maxcomplexity:15*/ 13907 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 13908 selectedIndex = this.tabs.index( focusedTab ), 13909 goingForward = true; 13910 13911 if ( this._handlePageNav( event ) ) { 13912 return; 13913 } 13914 13915 switch ( event.keyCode ) { 13916 case $.ui.keyCode.RIGHT: 13917 case $.ui.keyCode.DOWN: 13918 selectedIndex++; 13919 break; 13920 case $.ui.keyCode.UP: 13921 case $.ui.keyCode.LEFT: 13922 goingForward = false; 13923 selectedIndex--; 13924 break; 13925 case $.ui.keyCode.END: 13926 selectedIndex = this.anchors.length - 1; 13927 break; 13928 case $.ui.keyCode.HOME: 13929 selectedIndex = 0; 13930 break; 13931 case $.ui.keyCode.SPACE: 13932 // Activate only, no collapsing 13933 event.preventDefault(); 13934 clearTimeout( this.activating ); 13935 this._activate( selectedIndex ); 13936 return; 13937 case $.ui.keyCode.ENTER: 13938 // Toggle (cancel delayed activation, allow collapsing) 13939 event.preventDefault(); 13940 clearTimeout( this.activating ); 13941 // Determine if we should collapse or activate 13942 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 13943 return; 13944 default: 13945 return; 13946 } 13947 13948 // Focus the appropriate tab, based on which key was pressed 13949 event.preventDefault(); 13950 clearTimeout( this.activating ); 13951 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 13952 13953 // Navigating with control key will prevent automatic activation 13954 if ( !event.ctrlKey ) { 13955 // Update aria-selected immediately so that AT think the tab is already selected. 13956 // Otherwise AT may confuse the user by stating that they need to activate the tab, 13957 // but the tab will already be activated by the time the announcement finishes. 13958 focusedTab.attr( "aria-selected", "false" ); 13959 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 13960 13961 this.activating = this._delay(function() { 13962 this.option( "active", selectedIndex ); 13963 }, this.delay ); 13964 } 13965 }, 13966 13967 _panelKeydown: function( event ) { 13968 if ( this._handlePageNav( event ) ) { 13969 return; 13970 } 13971 13972 // Ctrl+up moves focus to the current tab 13973 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 13974 event.preventDefault(); 13975 this.active.focus(); 13976 } 13977 }, 13978 13979 // Alt+page up/down moves focus to the previous/next tab (and activates) 13980 _handlePageNav: function( event ) { 13981 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 13982 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 13983 return true; 13984 } 13985 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 13986 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 13987 return true; 13988 } 13989 }, 13990 13991 _findNextTab: function( index, goingForward ) { 13992 var lastTabIndex = this.tabs.length - 1; 13993 13994 function constrain() { 13995 if ( index > lastTabIndex ) { 13996 index = 0; 13997 } 13998 if ( index < 0 ) { 13999 index = lastTabIndex; 14000 } 14001 return index; 14002 } 14003 14004 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14005 index = goingForward ? index + 1 : index - 1; 14006 } 14007 14008 return index; 14009 }, 14010 14011 _focusNextTab: function( index, goingForward ) { 14012 index = this._findNextTab( index, goingForward ); 14013 this.tabs.eq( index ).focus(); 14014 return index; 14015 }, 14016 14017 _setOption: function( key, value ) { 14018 if ( key === "active" ) { 14019 // _activate() will handle invalid values and update this.options 14020 this._activate( value ); 14021 return; 14022 } 14023 14024 if ( key === "disabled" ) { 14025 // don't use the widget factory's disabled handling 14026 this._setupDisabled( value ); 14027 return; 14028 } 14029 14030 this._super( key, value); 14031 14032 if ( key === "collapsible" ) { 14033 this.element.toggleClass( "ui-tabs-collapsible", value ); 14034 // Setting collapsible: false while collapsed; open first panel 14035 if ( !value && this.options.active === false ) { 14036 this._activate( 0 ); 14037 } 14038 } 14039 14040 if ( key === "event" ) { 14041 this._setupEvents( value ); 14042 } 14043 14044 if ( key === "heightStyle" ) { 14045 this._setupHeightStyle( value ); 14046 } 14047 }, 14048 14049 _tabId: function( tab ) { 14050 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14051 }, 14052 14053 _sanitizeSelector: function( hash ) { 14054 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14055 }, 14056 14057 refresh: function() { 14058 var options = this.options, 14059 lis = this.tablist.children( ":has(a[href])" ); 14060 14061 // get disabled tabs from class attribute from HTML 14062 // this will get converted to a boolean if needed in _refresh() 14063 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14064 return lis.index( tab ); 14065 }); 14066 14067 this._processTabs(); 14068 14069 // was collapsed or no tabs 14070 if ( options.active === false || !this.anchors.length ) { 14071 options.active = false; 14072 this.active = $(); 14073 // was active, but active tab is gone 14074 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14075 // all remaining tabs are disabled 14076 if ( this.tabs.length === options.disabled.length ) { 14077 options.active = false; 14078 this.active = $(); 14079 // activate previous tab 14080 } else { 14081 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14082 } 14083 // was active, active tab still exists 14084 } else { 14085 // make sure active index is correct 14086 options.active = this.tabs.index( this.active ); 14087 } 14088 14089 this._refresh(); 14090 }, 14091 14092 _refresh: function() { 14093 this._setupDisabled( this.options.disabled ); 14094 this._setupEvents( this.options.event ); 14095 this._setupHeightStyle( this.options.heightStyle ); 14096 14097 this.tabs.not( this.active ).attr({ 14098 "aria-selected": "false", 14099 tabIndex: -1 14100 }); 14101 this.panels.not( this._getPanelForTab( this.active ) ) 14102 .hide() 14103 .attr({ 14104 "aria-expanded": "false", 14105 "aria-hidden": "true" 14106 }); 14107 14108 // Make sure one tab is in the tab order 14109 if ( !this.active.length ) { 14110 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14111 } else { 14112 this.active 14113 .addClass( "ui-tabs-active ui-state-active" ) 14114 .attr({ 14115 "aria-selected": "true", 14116 tabIndex: 0 14117 }); 14118 this._getPanelForTab( this.active ) 14119 .show() 14120 .attr({ 14121 "aria-expanded": "true", 14122 "aria-hidden": "false" 14123 }); 14124 } 14125 }, 14126 14127 _processTabs: function() { 14128 var that = this; 14129 14130 this.tablist = this._getList() 14131 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14132 .attr( "role", "tablist" ); 14133 14134 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14135 .addClass( "ui-state-default ui-corner-top" ) 14136 .attr({ 14137 role: "tab", 14138 tabIndex: -1 14139 }); 14140 14141 this.anchors = this.tabs.map(function() { 14142 return $( "a", this )[ 0 ]; 14143 }) 14144 .addClass( "ui-tabs-anchor" ) 14145 .attr({ 14146 role: "presentation", 14147 tabIndex: -1 14148 }); 14149 14150 this.panels = $(); 14151 14152 this.anchors.each(function( i, anchor ) { 14153 var selector, panel, panelId, 14154 anchorId = $( anchor ).uniqueId().attr( "id" ), 14155 tab = $( anchor ).closest( "li" ), 14156 originalAriaControls = tab.attr( "aria-controls" ); 14157 14158 // inline tab 14159 if ( isLocal( anchor ) ) { 14160 selector = anchor.hash; 14161 panel = that.element.find( that._sanitizeSelector( selector ) ); 14162 // remote tab 14163 } else { 14164 panelId = that._tabId( tab ); 14165 selector = "#" + panelId; 14166 panel = that.element.find( selector ); 14167 if ( !panel.length ) { 14168 panel = that._createPanel( panelId ); 14169 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14170 } 14171 panel.attr( "aria-live", "polite" ); 14172 } 14173 14174 if ( panel.length) { 14175 that.panels = that.panels.add( panel ); 14176 } 14177 if ( originalAriaControls ) { 14178 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14179 } 14180 tab.attr({ 14181 "aria-controls": selector.substring( 1 ), 14182 "aria-labelledby": anchorId 14183 }); 14184 panel.attr( "aria-labelledby", anchorId ); 14185 }); 14186 14187 this.panels 14188 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14189 .attr( "role", "tabpanel" ); 14190 }, 14191 14192 // allow overriding how to find the list for rare usage scenarios (#7715) 14193 _getList: function() { 14194 return this.element.find( "ol,ul" ).eq( 0 ); 14195 }, 14196 14197 _createPanel: function( id ) { 14198 return $( "<div>" ) 14199 .attr( "id", id ) 14200 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14201 .data( "ui-tabs-destroy", true ); 14202 }, 14203 14204 _setupDisabled: function( disabled ) { 14205 if ( $.isArray( disabled ) ) { 14206 if ( !disabled.length ) { 14207 disabled = false; 14208 } else if ( disabled.length === this.anchors.length ) { 14209 disabled = true; 14210 } 14211 } 14212 14213 // disable tabs 14214 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14215 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14216 $( li ) 14217 .addClass( "ui-state-disabled" ) 14218 .attr( "aria-disabled", "true" ); 14219 } else { 14220 $( li ) 14221 .removeClass( "ui-state-disabled" ) 14222 .removeAttr( "aria-disabled" ); 14223 } 14224 } 14225 14226 this.options.disabled = disabled; 14227 }, 14228 14229 _setupEvents: function( event ) { 14230 var events = { 14231 click: function( event ) { 14232 event.preventDefault(); 14233 } 14234 }; 14235 if ( event ) { 14236 $.each( event.split(" "), function( index, eventName ) { 14237 events[ eventName ] = "_eventHandler"; 14238 }); 14239 } 14240 14241 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14242 this._on( this.anchors, events ); 14243 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14244 this._on( this.panels, { keydown: "_panelKeydown" } ); 14245 14246 this._focusable( this.tabs ); 14247 this._hoverable( this.tabs ); 14248 }, 14249 14250 _setupHeightStyle: function( heightStyle ) { 14251 var maxHeight, 14252 parent = this.element.parent(); 14253 14254 if ( heightStyle === "fill" ) { 14255 maxHeight = parent.height(); 14256 maxHeight -= this.element.outerHeight() - this.element.height(); 14257 14258 this.element.siblings( ":visible" ).each(function() { 14259 var elem = $( this ), 14260 position = elem.css( "position" ); 14261 14262 if ( position === "absolute" || position === "fixed" ) { 14263 return; 14264 } 14265 maxHeight -= elem.outerHeight( true ); 14266 }); 14267 14268 this.element.children().not( this.panels ).each(function() { 14269 maxHeight -= $( this ).outerHeight( true ); 14270 }); 14271 14272 this.panels.each(function() { 14273 $( this ).height( Math.max( 0, maxHeight - 14274 $( this ).innerHeight() + $( this ).height() ) ); 14275 }) 14276 .css( "overflow", "auto" ); 14277 } else if ( heightStyle === "auto" ) { 14278 maxHeight = 0; 14279 this.panels.each(function() { 14280 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14281 }).height( maxHeight ); 14282 } 14283 }, 14284 14285 _eventHandler: function( event ) { 14286 var options = this.options, 14287 active = this.active, 14288 anchor = $( event.currentTarget ), 14289 tab = anchor.closest( "li" ), 14290 clickedIsActive = tab[ 0 ] === active[ 0 ], 14291 collapsing = clickedIsActive && options.collapsible, 14292 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14293 toHide = !active.length ? $() : this._getPanelForTab( active ), 14294 eventData = { 14295 oldTab: active, 14296 oldPanel: toHide, 14297 newTab: collapsing ? $() : tab, 14298 newPanel: toShow 14299 }; 14300 14301 event.preventDefault(); 14302 14303 if ( tab.hasClass( "ui-state-disabled" ) || 14304 // tab is already loading 14305 tab.hasClass( "ui-tabs-loading" ) || 14306 // can't switch durning an animation 14307 this.running || 14308 // click on active header, but not collapsible 14309 ( clickedIsActive && !options.collapsible ) || 14310 // allow canceling activation 14311 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14312 return; 14313 } 14314 14315 options.active = collapsing ? false : this.tabs.index( tab ); 14316 14317 this.active = clickedIsActive ? $() : tab; 14318 if ( this.xhr ) { 14319 this.xhr.abort(); 14320 } 14321 14322 if ( !toHide.length && !toShow.length ) { 14323 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14324 } 14325 14326 if ( toShow.length ) { 14327 this.load( this.tabs.index( tab ), event ); 14328 } 14329 this._toggle( event, eventData ); 14330 }, 14331 14332 // handles show/hide for selecting tabs 14333 _toggle: function( event, eventData ) { 14334 var that = this, 14335 toShow = eventData.newPanel, 14336 toHide = eventData.oldPanel; 14337 14338 this.running = true; 14339 14340 function complete() { 14341 that.running = false; 14342 that._trigger( "activate", event, eventData ); 14343 } 14344 14345 function show() { 14346 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14347 14348 if ( toShow.length && that.options.show ) { 14349 that._show( toShow, that.options.show, complete ); 14350 } else { 14351 toShow.show(); 14352 complete(); 14353 } 14354 } 14355 14356 // start out by hiding, then showing, then completing 14357 if ( toHide.length && this.options.hide ) { 14358 this._hide( toHide, this.options.hide, function() { 14359 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14360 show(); 14361 }); 14362 } else { 14363 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14364 toHide.hide(); 14365 show(); 14366 } 14367 14368 toHide.attr({ 14369 "aria-expanded": "false", 14370 "aria-hidden": "true" 14371 }); 14372 eventData.oldTab.attr( "aria-selected", "false" ); 14373 // If we're switching tabs, remove the old tab from the tab order. 14374 // If we're opening from collapsed state, remove the previous tab from the tab order. 14375 // If we're collapsing, then keep the collapsing tab in the tab order. 14376 if ( toShow.length && toHide.length ) { 14377 eventData.oldTab.attr( "tabIndex", -1 ); 14378 } else if ( toShow.length ) { 14379 this.tabs.filter(function() { 14380 return $( this ).attr( "tabIndex" ) === 0; 14381 }) 14382 .attr( "tabIndex", -1 ); 14383 } 14384 14385 toShow.attr({ 14386 "aria-expanded": "true", 14387 "aria-hidden": "false" 14388 }); 14389 eventData.newTab.attr({ 14390 "aria-selected": "true", 14391 tabIndex: 0 14392 }); 14393 }, 14394 14395 _activate: function( index ) { 14396 var anchor, 14397 active = this._findActive( index ); 14398 14399 // trying to activate the already active panel 14400 if ( active[ 0 ] === this.active[ 0 ] ) { 14401 return; 14402 } 14403 14404 // trying to collapse, simulate a click on the current active header 14405 if ( !active.length ) { 14406 active = this.active; 14407 } 14408 14409 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14410 this._eventHandler({ 14411 target: anchor, 14412 currentTarget: anchor, 14413 preventDefault: $.noop 14414 }); 14415 }, 14416 14417 _findActive: function( index ) { 14418 return index === false ? $() : this.tabs.eq( index ); 14419 }, 14420 14421 _getIndex: function( index ) { 14422 // meta-function to give users option to provide a href string instead of a numerical index. 14423 if ( typeof index === "string" ) { 14424 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14425 } 14426 14427 return index; 14428 }, 14429 14430 _destroy: function() { 14431 if ( this.xhr ) { 14432 this.xhr.abort(); 14433 } 14434 14435 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14436 14437 this.tablist 14438 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14439 .removeAttr( "role" ); 14440 14441 this.anchors 14442 .removeClass( "ui-tabs-anchor" ) 14443 .removeAttr( "role" ) 14444 .removeAttr( "tabIndex" ) 14445 .removeUniqueId(); 14446 14447 this.tabs.add( this.panels ).each(function() { 14448 if ( $.data( this, "ui-tabs-destroy" ) ) { 14449 $( this ).remove(); 14450 } else { 14451 $( this ) 14452 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14453 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14454 .removeAttr( "tabIndex" ) 14455 .removeAttr( "aria-live" ) 14456 .removeAttr( "aria-busy" ) 14457 .removeAttr( "aria-selected" ) 14458 .removeAttr( "aria-labelledby" ) 14459 .removeAttr( "aria-hidden" ) 14460 .removeAttr( "aria-expanded" ) 14461 .removeAttr( "role" ); 14462 } 14463 }); 14464 14465 this.tabs.each(function() { 14466 var li = $( this ), 14467 prev = li.data( "ui-tabs-aria-controls" ); 14468 if ( prev ) { 14469 li 14470 .attr( "aria-controls", prev ) 14471 .removeData( "ui-tabs-aria-controls" ); 14472 } else { 14473 li.removeAttr( "aria-controls" ); 14474 } 14475 }); 14476 14477 this.panels.show(); 14478 14479 if ( this.options.heightStyle !== "content" ) { 14480 this.panels.css( "height", "" ); 14481 } 14482 }, 14483 14484 enable: function( index ) { 14485 var disabled = this.options.disabled; 14486 if ( disabled === false ) { 14487 return; 14488 } 14489 14490 if ( index === undefined ) { 14491 disabled = false; 14492 } else { 14493 index = this._getIndex( index ); 14494 if ( $.isArray( disabled ) ) { 14495 disabled = $.map( disabled, function( num ) { 14496 return num !== index ? num : null; 14497 }); 14498 } else { 14499 disabled = $.map( this.tabs, function( li, num ) { 14500 return num !== index ? num : null; 14501 }); 14502 } 14503 } 14504 this._setupDisabled( disabled ); 14505 }, 14506 14507 disable: function( index ) { 14508 var disabled = this.options.disabled; 14509 if ( disabled === true ) { 14510 return; 14511 } 14512 14513 if ( index === undefined ) { 14514 disabled = true; 14515 } else { 14516 index = this._getIndex( index ); 14517 if ( $.inArray( index, disabled ) !== -1 ) { 14518 return; 14519 } 14520 if ( $.isArray( disabled ) ) { 14521 disabled = $.merge( [ index ], disabled ).sort(); 14522 } else { 14523 disabled = [ index ]; 14524 } 14525 } 14526 this._setupDisabled( disabled ); 14527 }, 14528 14529 load: function( index, event ) { 14530 index = this._getIndex( index ); 14531 var that = this, 14532 tab = this.tabs.eq( index ), 14533 anchor = tab.find( ".ui-tabs-anchor" ), 14534 panel = this._getPanelForTab( tab ), 14535 eventData = { 14536 tab: tab, 14537 panel: panel 14538 }; 14539 14540 // not remote 14541 if ( isLocal( anchor[ 0 ] ) ) { 14542 return; 14543 } 14544 14545 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14546 14547 // support: jQuery <1.8 14548 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14549 // but as of 1.8, $.ajax() always returns a jqXHR object. 14550 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14551 tab.addClass( "ui-tabs-loading" ); 14552 panel.attr( "aria-busy", "true" ); 14553 14554 this.xhr 14555 .success(function( response ) { 14556 // support: jQuery <1.8 14557 // http://bugs.jquery.com/ticket/11778 14558 setTimeout(function() { 14559 panel.html( response ); 14560 that._trigger( "load", event, eventData ); 14561 }, 1 ); 14562 }) 14563 .complete(function( jqXHR, status ) { 14564 // support: jQuery <1.8 14565 // http://bugs.jquery.com/ticket/11778 14566 setTimeout(function() { 14567 if ( status === "abort" ) { 14568 that.panels.stop( false, true ); 14569 } 14570 14571 tab.removeClass( "ui-tabs-loading" ); 14572 panel.removeAttr( "aria-busy" ); 14573 14574 if ( jqXHR === that.xhr ) { 14575 delete that.xhr; 14576 } 14577 }, 1 ); 14578 }); 14579 } 14580 }, 14581 14582 _ajaxSettings: function( anchor, event, eventData ) { 14583 var that = this; 14584 return { 14585 url: anchor.attr( "href" ), 14586 beforeSend: function( jqXHR, settings ) { 14587 return that._trigger( "beforeLoad", event, 14588 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 14589 } 14590 }; 14591 }, 14592 14593 _getPanelForTab: function( tab ) { 14594 var id = $( tab ).attr( "aria-controls" ); 14595 return this.element.find( this._sanitizeSelector( "#" + id ) ); 14596 } 14597 }); 14598 14599})( jQuery ); 14600 14601(function( $ ) { 14602 14603 var increments = 0; 14604 14605 function addDescribedBy( elem, id ) { 14606 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 14607 describedby.push( id ); 14608 elem 14609 .data( "ui-tooltip-id", id ) 14610 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 14611 } 14612 14613 function removeDescribedBy( elem ) { 14614 var id = elem.data( "ui-tooltip-id" ), 14615 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 14616 index = $.inArray( id, describedby ); 14617 if ( index !== -1 ) { 14618 describedby.splice( index, 1 ); 14619 } 14620 14621 elem.removeData( "ui-tooltip-id" ); 14622 describedby = $.trim( describedby.join( " " ) ); 14623 if ( describedby ) { 14624 elem.attr( "aria-describedby", describedby ); 14625 } else { 14626 elem.removeAttr( "aria-describedby" ); 14627 } 14628 } 14629 14630 $.widget( "ui.tooltip", { 14631 version: "1.10.2", 14632 options: { 14633 content: function() { 14634 // support: IE<9, Opera in jQuery <1.7 14635 // .text() can't accept undefined, so coerce to a string 14636 var title = $( this ).attr( "title" ) || ""; 14637 // Escape title, since we're going from an attribute to raw HTML 14638 return $( "<a>" ).text( title ).html(); 14639 }, 14640 hide: true, 14641 // Disabled elements have inconsistent behavior across browsers (#8661) 14642 items: "[title]:not([disabled])", 14643 position: { 14644 my: "left top+15", 14645 at: "left bottom", 14646 collision: "flipfit flip" 14647 }, 14648 show: true, 14649 tooltipClass: null, 14650 track: false, 14651 14652 // callbacks 14653 close: null, 14654 open: null 14655 }, 14656 14657 _create: function() { 14658 this._on({ 14659 mouseover: "open", 14660 focusin: "open" 14661 }); 14662 14663 // IDs of generated tooltips, needed for destroy 14664 this.tooltips = {}; 14665 // IDs of parent tooltips where we removed the title attribute 14666 this.parents = {}; 14667 14668 if ( this.options.disabled ) { 14669 this._disable(); 14670 } 14671 }, 14672 14673 _setOption: function( key, value ) { 14674 var that = this; 14675 14676 if ( key === "disabled" ) { 14677 this[ value ? "_disable" : "_enable" ](); 14678 this.options[ key ] = value; 14679 // disable element style changes 14680 return; 14681 } 14682 14683 this._super( key, value ); 14684 14685 if ( key === "content" ) { 14686 $.each( this.tooltips, function( id, element ) { 14687 that._updateContent( element ); 14688 }); 14689 } 14690 }, 14691 14692 _disable: function() { 14693 var that = this; 14694 14695 // close open tooltips 14696 $.each( this.tooltips, function( id, element ) { 14697 var event = $.Event( "blur" ); 14698 event.target = event.currentTarget = element[0]; 14699 that.close( event, true ); 14700 }); 14701 14702 // remove title attributes to prevent native tooltips 14703 this.element.find( this.options.items ).addBack().each(function() { 14704 var element = $( this ); 14705 if ( element.is( "[title]" ) ) { 14706 element 14707 .data( "ui-tooltip-title", element.attr( "title" ) ) 14708 .attr( "title", "" ); 14709 } 14710 }); 14711 }, 14712 14713 _enable: function() { 14714 // restore title attributes 14715 this.element.find( this.options.items ).addBack().each(function() { 14716 var element = $( this ); 14717 if ( element.data( "ui-tooltip-title" ) ) { 14718 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14719 } 14720 }); 14721 }, 14722 14723 open: function( event ) { 14724 var that = this, 14725 target = $( event ? event.target : this.element ) 14726 // we need closest here due to mouseover bubbling, 14727 // but always pointing at the same event target 14728 .closest( this.options.items ); 14729 14730 // No element to show a tooltip for or the tooltip is already open 14731 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 14732 return; 14733 } 14734 14735 if ( target.attr( "title" ) ) { 14736 target.data( "ui-tooltip-title", target.attr( "title" ) ); 14737 } 14738 14739 target.data( "ui-tooltip-open", true ); 14740 14741 // kill parent tooltips, custom or native, for hover 14742 if ( event && event.type === "mouseover" ) { 14743 target.parents().each(function() { 14744 var parent = $( this ), 14745 blurEvent; 14746 if ( parent.data( "ui-tooltip-open" ) ) { 14747 blurEvent = $.Event( "blur" ); 14748 blurEvent.target = blurEvent.currentTarget = this; 14749 that.close( blurEvent, true ); 14750 } 14751 if ( parent.attr( "title" ) ) { 14752 parent.uniqueId(); 14753 that.parents[ this.id ] = { 14754 element: this, 14755 title: parent.attr( "title" ) 14756 }; 14757 parent.attr( "title", "" ); 14758 } 14759 }); 14760 } 14761 14762 this._updateContent( target, event ); 14763 }, 14764 14765 _updateContent: function( target, event ) { 14766 var content, 14767 contentOption = this.options.content, 14768 that = this, 14769 eventType = event ? event.type : null; 14770 14771 if ( typeof contentOption === "string" ) { 14772 return this._open( event, target, contentOption ); 14773 } 14774 14775 content = contentOption.call( target[0], function( response ) { 14776 // ignore async response if tooltip was closed already 14777 if ( !target.data( "ui-tooltip-open" ) ) { 14778 return; 14779 } 14780 // IE may instantly serve a cached response for ajax requests 14781 // delay this call to _open so the other call to _open runs first 14782 that._delay(function() { 14783 // jQuery creates a special event for focusin when it doesn't 14784 // exist natively. To improve performance, the native event 14785 // object is reused and the type is changed. Therefore, we can't 14786 // rely on the type being correct after the event finished 14787 // bubbling, so we set it back to the previous value. (#8740) 14788 if ( event ) { 14789 event.type = eventType; 14790 } 14791 this._open( event, target, response ); 14792 }); 14793 }); 14794 if ( content ) { 14795 this._open( event, target, content ); 14796 } 14797 }, 14798 14799 _open: function( event, target, content ) { 14800 var tooltip, events, delayedShow, 14801 positionOption = $.extend( {}, this.options.position ); 14802 14803 if ( !content ) { 14804 return; 14805 } 14806 14807 // Content can be updated multiple times. If the tooltip already 14808 // exists, then just update the content and bail. 14809 tooltip = this._find( target ); 14810 if ( tooltip.length ) { 14811 tooltip.find( ".ui-tooltip-content" ).html( content ); 14812 return; 14813 } 14814 14815 // if we have a title, clear it to prevent the native tooltip 14816 // we have to check first to avoid defining a title if none exists 14817 // (we don't want to cause an element to start matching [title]) 14818 // 14819 // We use removeAttr only for key events, to allow IE to export the correct 14820 // accessible attributes. For mouse events, set to empty string to avoid 14821 // native tooltip showing up (happens only when removing inside mouseover). 14822 if ( target.is( "[title]" ) ) { 14823 if ( event && event.type === "mouseover" ) { 14824 target.attr( "title", "" ); 14825 } else { 14826 target.removeAttr( "title" ); 14827 } 14828 } 14829 14830 tooltip = this._tooltip( target ); 14831 addDescribedBy( target, tooltip.attr( "id" ) ); 14832 tooltip.find( ".ui-tooltip-content" ).html( content ); 14833 14834 function position( event ) { 14835 positionOption.of = event; 14836 if ( tooltip.is( ":hidden" ) ) { 14837 return; 14838 } 14839 tooltip.position( positionOption ); 14840 } 14841 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 14842 this._on( this.document, { 14843 mousemove: position 14844 }); 14845 // trigger once to override element-relative positioning 14846 position( event ); 14847 } else { 14848 tooltip.position( $.extend({ 14849 of: target 14850 }, this.options.position ) ); 14851 } 14852 14853 tooltip.hide(); 14854 14855 this._show( tooltip, this.options.show ); 14856 // Handle tracking tooltips that are shown with a delay (#8644). As soon 14857 // as the tooltip is visible, position the tooltip using the most recent 14858 // event. 14859 if ( this.options.show && this.options.show.delay ) { 14860 delayedShow = this.delayedShow = setInterval(function() { 14861 if ( tooltip.is( ":visible" ) ) { 14862 position( positionOption.of ); 14863 clearInterval( delayedShow ); 14864 } 14865 }, $.fx.interval ); 14866 } 14867 14868 this._trigger( "open", event, { tooltip: tooltip } ); 14869 14870 events = { 14871 keyup: function( event ) { 14872 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 14873 var fakeEvent = $.Event(event); 14874 fakeEvent.currentTarget = target[0]; 14875 this.close( fakeEvent, true ); 14876 } 14877 }, 14878 remove: function() { 14879 this._removeTooltip( tooltip ); 14880 } 14881 }; 14882 if ( !event || event.type === "mouseover" ) { 14883 events.mouseleave = "close"; 14884 } 14885 if ( !event || event.type === "focusin" ) { 14886 events.focusout = "close"; 14887 } 14888 this._on( true, target, events ); 14889 }, 14890 14891 close: function( event ) { 14892 var that = this, 14893 target = $( event ? event.currentTarget : this.element ), 14894 tooltip = this._find( target ); 14895 14896 // disabling closes the tooltip, so we need to track when we're closing 14897 // to avoid an infinite loop in case the tooltip becomes disabled on close 14898 if ( this.closing ) { 14899 return; 14900 } 14901 14902 // Clear the interval for delayed tracking tooltips 14903 clearInterval( this.delayedShow ); 14904 14905 // only set title if we had one before (see comment in _open()) 14906 if ( target.data( "ui-tooltip-title" ) ) { 14907 target.attr( "title", target.data( "ui-tooltip-title" ) ); 14908 } 14909 14910 removeDescribedBy( target ); 14911 14912 tooltip.stop( true ); 14913 this._hide( tooltip, this.options.hide, function() { 14914 that._removeTooltip( $( this ) ); 14915 }); 14916 14917 target.removeData( "ui-tooltip-open" ); 14918 this._off( target, "mouseleave focusout keyup" ); 14919 // Remove 'remove' binding only on delegated targets 14920 if ( target[0] !== this.element[0] ) { 14921 this._off( target, "remove" ); 14922 } 14923 this._off( this.document, "mousemove" ); 14924 14925 if ( event && event.type === "mouseleave" ) { 14926 $.each( this.parents, function( id, parent ) { 14927 $( parent.element ).attr( "title", parent.title ); 14928 delete that.parents[ id ]; 14929 }); 14930 } 14931 14932 this.closing = true; 14933 this._trigger( "close", event, { tooltip: tooltip } ); 14934 this.closing = false; 14935 }, 14936 14937 _tooltip: function( element ) { 14938 var id = "ui-tooltip-" + increments++, 14939 tooltip = $( "<div>" ) 14940 .attr({ 14941 id: id, 14942 role: "tooltip" 14943 }) 14944 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 14945 ( this.options.tooltipClass || "" ) ); 14946 $( "<div>" ) 14947 .addClass( "ui-tooltip-content" ) 14948 .appendTo( tooltip ); 14949 tooltip.appendTo( this.document[0].body ); 14950 this.tooltips[ id ] = element; 14951 return tooltip; 14952 }, 14953 14954 _find: function( target ) { 14955 var id = target.data( "ui-tooltip-id" ); 14956 return id ? $( "#" + id ) : $(); 14957 }, 14958 14959 _removeTooltip: function( tooltip ) { 14960 tooltip.remove(); 14961 delete this.tooltips[ tooltip.attr( "id" ) ]; 14962 }, 14963 14964 _destroy: function() { 14965 var that = this; 14966 14967 // close open tooltips 14968 $.each( this.tooltips, function( id, element ) { 14969 // Delegate to close method to handle common cleanup 14970 var event = $.Event( "blur" ); 14971 event.target = event.currentTarget = element[0]; 14972 that.close( event, true ); 14973 14974 // Remove immediately; destroying an open tooltip doesn't use the 14975 // hide animation 14976 $( "#" + id ).remove(); 14977 14978 // Restore the title 14979 if ( element.data( "ui-tooltip-title" ) ) { 14980 element.attr( "title", element.data( "ui-tooltip-title" ) ); 14981 element.removeData( "ui-tooltip-title" ); 14982 } 14983 }); 14984 } 14985 });
14986 14987}( 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.