vendor: 5,361 bytes, lines 1-198
1/*! jQuery UI - v1.10.4 - 2018-03-23 2* http://jqueryui.com 3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.datepicker.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6(function( $, undefined ) { 7 8var uuid = 0, 9 runiqueId = /^ui-id-\d+$/; 10 11// $.ui might exist from components with no dependencies, e.g., $.ui.position 12$.ui = $.ui || {}; 13 14$.extend( $.ui, { 15 version: "1.10.4", 16 17 keyCode: { 18 BACKSPACE: 8, 19 COMMA: 188, 20 DELETE: 46, 21 DOWN: 40, 22 END: 35, 23 ENTER: 13, 24 ESCAPE: 27, 25 HOME: 36, 26 LEFT: 37, 27 NUMPAD_ADD: 107, 28 NUMPAD_DECIMAL: 110, 29 NUMPAD_DIVIDE: 111, 30 NUMPAD_ENTER: 108, 31 NUMPAD_MULTIPLY: 106, 32 NUMPAD_SUBTRACT: 109, 33 PAGE_DOWN: 34, 34 PAGE_UP: 33, 35 PERIOD: 190, 36 RIGHT: 39, 37 SPACE: 32, 38 TAB: 9, 39 UP: 38 40 } 41}); 42 43// plugins 44$.fn.extend({ 45 focus: (function( orig ) { 46 return function( delay, fn ) { 47 return typeof delay === "number" ? 48 this.each(function() { 49 var elem = this; 50 setTimeout(function() { 51 $( elem ).focus(); 52 if ( fn ) { 53 fn.call( elem ); 54 } 55 }, delay ); 56 }) : 57 orig.apply( this, arguments ); 58 }; 59 })( $.fn.focus ), 60 61 scrollParent: function() { 62 var scrollParent; 63 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 64 scrollParent = this.parents().filter(function() { 65 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 66 }).eq(0); 67 } else { 68 scrollParent = this.parents().filter(function() { 69 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 70 }).eq(0); 71 } 72 73 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 74 }, 75 76 zIndex: function( zIndex ) { 77 if ( zIndex !== undefined ) { 78 return this.css( "zIndex", zIndex ); 79 } 80 81 if ( this.length ) { 82 var elem = $( this[ 0 ] ), position, value; 83 while ( elem.length && elem[ 0 ] !== document ) { 84 // Ignore z-index if position is set to a value where z-index is ignored by the browser 85 // This makes behavior of this function consistent across browsers 86 // WebKit always returns auto if the element is positioned 87 position = elem.css( "position" ); 88 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 89 // IE returns 0 when zIndex is not specified 90 // other browsers return a string 91 // we ignore the case of nested elements with an explicit value of 0 92 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 93 value = parseInt( elem.css( "zIndex" ), 10 ); 94 if ( !isNaN( value ) && value !== 0 ) { 95 return value; 96 } 97 } 98 elem = elem.parent(); 99 } 100 } 101 102 return 0; 103 }, 104 105 uniqueId: function() { 106 return this.each(function() { 107 if ( !this.id ) { 108 this.id = "ui-id-" + (++uuid); 109 } 110 }); 111 }, 112 113 removeUniqueId: function() { 114 return this.each(function() { 115 if ( runiqueId.test( this.id ) ) { 116 $( this ).removeAttr( "id" ); 117 } 118 }); 119 } 120}); 121 122// selectors 123function focusable( element, isTabIndexNotNaN ) { 124 var map, mapName, img, 125 nodeName = element.nodeName.toLowerCase(); 126 if ( "area" === nodeName ) { 127 map = element.parentNode; 128 mapName = map.name; 129 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 130 return false; 131 } 132 img = $( "img[usemap=#" + mapName + "]" )[0]; 133 return !!img && visible( img ); 134 } 135 return ( /input|select|textarea|button|object/.test( nodeName ) ? 136 !element.disabled : 137 "a" === nodeName ? 138 element.href || isTabIndexNotNaN : 139 isTabIndexNotNaN) && 140 // the element and all of its ancestors must be visible 141 visible( element ); 142} 143 144function visible( element ) { 145 return $.expr.filters.visible( element ) && 146 !$( element ).parents().addBack().filter(function() { 147 return $.css( this, "visibility" ) === "hidden"; 148 }).length; 149} 150 151$.extend( $.expr[ ":" ], { 152 data: $.expr.createPseudo ? 153 $.expr.createPseudo(function( dataName ) { 154 return function( elem ) { 155 return !!$.data( elem, dataName ); 156 }; 157 }) : 158 // support: jQuery <1.8 159 function( elem, i, match ) { 160 return !!$.data( elem, match[ 3 ] ); 161 }, 162 163 focusable: function( element ) { 164 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 165 }, 166 167 tabbable: function( element ) { 168 var tabIndex = $.attr( element, "tabindex" ), 169 isTabIndexNaN = isNaN( tabIndex ); 170 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 171 } 172}); 173 174// support: jQuery <1.8 175if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 176 $.each( [ "Width", "Height" ], function( i, name ) { 177 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 178 type = name.toLowerCase(), 179 orig = { 180 innerWidth: $.fn.innerWidth, 181 innerHeight: $.fn.innerHeight, 182 outerWidth: $.fn.outerWidth, 183 outerHeight: $.fn.outerHeight 184 }; 185 186 function reduce( elem, size, border, margin ) { 187 $.each( side, function() { 188 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 189 if ( border ) { 190 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 191 } 192 if ( margin ) { 193 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 194 } 195 }); 196 return size; 197 } 198
vendor: 5,527 bytes, lines 199-400
199 $.fn[ "inner" + name ] = function( size ) { 200 if ( size === undefined ) { 201 return orig[ "inner" + name ].call( this ); 202 } 203 204 return this.each(function() { 205 $( this ).css( type, reduce( this, size ) + "px" ); 206 }); 207 }; 208 209 $.fn[ "outer" + name] = function( size, margin ) { 210 if ( typeof size !== "number" ) { 211 return orig[ "outer" + name ].call( this, size ); 212 } 213 214 return this.each(function() { 215 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 216 }); 217 }; 218 }); 219} 220 221// support: jQuery <1.8 222if ( !$.fn.addBack ) { 223 $.fn.addBack = function( selector ) { 224 return this.add( selector == null ? 225 this.prevObject : this.prevObject.filter( selector ) 226 ); 227 }; 228} 229 230// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 231if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 232 $.fn.removeData = (function( removeData ) { 233 return function( key ) { 234 if ( arguments.length ) { 235 return removeData.call( this, $.camelCase( key ) ); 236 } else { 237 return removeData.call( this ); 238 } 239 }; 240 })( $.fn.removeData ); 241} 242 243 244 245 246 247// deprecated 248$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 249 250$.support.selectstart = "onselectstart" in document.createElement( "div" ); 251$.fn.extend({ 252 disableSelection: function() { 253 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 254 ".ui-disableSelection", function( event ) { 255 event.preventDefault(); 256 }); 257 }, 258 259 enableSelection: function() { 260 return this.unbind( ".ui-disableSelection" ); 261 } 262}); 263 264$.extend( $.ui, { 265 // $.ui.plugin is deprecated. Use $.widget() extensions instead. 266 plugin: { 267 add: function( module, option, set ) { 268 var i, 269 proto = $.ui[ module ].prototype; 270 for ( i in set ) { 271 proto.plugins[ i ] = proto.plugins[ i ] || []; 272 proto.plugins[ i ].push( [ option, set[ i ] ] ); 273 } 274 }, 275 call: function( instance, name, args ) { 276 var i, 277 set = instance.plugins[ name ]; 278 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 279 return; 280 } 281 282 for ( i = 0; i < set.length; i++ ) { 283 if ( instance.options[ set[ i ][ 0 ] ] ) { 284 set[ i ][ 1 ].apply( instance.element, args ); 285 } 286 } 287 } 288 }, 289 290 // only used by resizable 291 hasScroll: function( el, a ) { 292 293 //If overflow is hidden, the element might have extra content, but the user wants to hide it 294 if ( $( el ).css( "overflow" ) === "hidden") { 295 return false; 296 } 297 298 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 299 has = false; 300 301 if ( el[ scroll ] > 0 ) { 302 return true; 303 } 304 305 // TODO: determine which cases actually cause this to happen 306 // if the element doesn't have the scroll set, see if it's possible to 307 // set the scroll 308 el[ scroll ] = 1; 309 has = ( el[ scroll ] > 0 ); 310 el[ scroll ] = 0; 311 return has; 312 } 313}); 314 315})( jQuery ); 316(function( $, undefined ) { 317 318var 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
vendor: 11,929 bytes, lines 401-812
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) : 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 ( arguments.length === 1 ) { 624 return curOption[ key ] === undefined ? null : curOption[ key ]; 625 } 626 curOption[ key ] = value; 627 } else { 628 if ( arguments.length === 1 ) { 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 ] ) {
vendor: 20,254 bytes, lines 813-1476
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(function( $, undefined ) { 828 829var mouseHandled = false; 830$( document ).mouseup( function() { 831 mouseHandled = false; 832}); 833 834$.widget("ui.mouse", { 835 version: "1.10.4", 836 options: { 837 cancel: "input,textarea,button,select,option", 838 distance: 1, 839 delay: 0 840 }, 841 _mouseInit: function() { 842 var that = this; 843 844 this.element 845 .bind("mousedown."+this.widgetName, function(event) { 846 return that._mouseDown(event); 847 }) 848 .bind("click."+this.widgetName, function(event) { 849 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 850 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 851 event.stopImmediatePropagation(); 852 return false; 853 } 854 }); 855 856 this.started = false; 857 }, 858 859 // TODO: make sure destroying one instance of mouse doesn't mess with 860 // other instances of mouse 861 _mouseDestroy: function() { 862 this.element.unbind("."+this.widgetName); 863 if ( this._mouseMoveDelegate ) { 864 $(document) 865 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 866 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 867 } 868 }, 869 870 _mouseDown: function(event) { 871 // don't let more than one widget handle mouseStart 872 if( mouseHandled ) { return; } 873 874 // we may have missed mouseup (out of window) 875 (this._mouseStarted && this._mouseUp(event)); 876 877 this._mouseDownEvent = event; 878 879 var that = this, 880 btnIsLeft = (event.which === 1), 881 // event.target.nodeName works around a bug in IE 8 with 882 // disabled inputs (#7620) 883 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 884 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 885 return true; 886 } 887 888 this.mouseDelayMet = !this.options.delay; 889 if (!this.mouseDelayMet) { 890 this._mouseDelayTimer = setTimeout(function() { 891 that.mouseDelayMet = true; 892 }, this.options.delay); 893 } 894 895 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 896 this._mouseStarted = (this._mouseStart(event) !== false); 897 if (!this._mouseStarted) { 898 event.preventDefault(); 899 return true; 900 } 901 } 902 903 // Click event may never have fired (Gecko & Opera) 904 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 905 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 906 } 907 908 // these delegates are required to keep context 909 this._mouseMoveDelegate = function(event) { 910 return that._mouseMove(event); 911 }; 912 this._mouseUpDelegate = function(event) { 913 return that._mouseUp(event); 914 }; 915 $(document) 916 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 917 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 918 919 event.preventDefault(); 920 921 mouseHandled = true; 922 return true; 923 }, 924 925 _mouseMove: function(event) { 926 // IE mouseup check - mouseup happened when mouse was out of window 927 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 928 return this._mouseUp(event); 929 } 930 931 if (this._mouseStarted) { 932 this._mouseDrag(event); 933 return event.preventDefault(); 934 } 935 936 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 937 this._mouseStarted = 938 (this._mouseStart(this._mouseDownEvent, event) !== false); 939 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 940 } 941 942 return !this._mouseStarted; 943 }, 944 945 _mouseUp: function(event) { 946 $(document) 947 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 948 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 949 950 if (this._mouseStarted) { 951 this._mouseStarted = false; 952 953 if (event.target === this._mouseDownEvent.target) { 954 $.data(event.target, this.widgetName + ".preventClickEvent", true); 955 } 956 957 this._mouseStop(event); 958 } 959 960 return false; 961 }, 962 963 _mouseDistanceMet: function(event) { 964 return (Math.max( 965 Math.abs(this._mouseDownEvent.pageX - event.pageX), 966 Math.abs(this._mouseDownEvent.pageY - event.pageY) 967 ) >= this.options.distance 968 ); 969 }, 970 971 _mouseDelayMet: function(/* event */) { 972 return this.mouseDelayMet; 973 }, 974 975 // These are placeholder methods, to be overriden by extending plugin 976 _mouseStart: function(/* event */) {}, 977 _mouseDrag: function(/* event */) {}, 978 _mouseStop: function(/* event */) {}, 979 _mouseCapture: function(/* event */) { return true; } 980}); 981 982})(jQuery); 983(function( $, undefined ) { 984 985$.ui = $.ui || {}; 986 987var cachedScrollbarWidth, 988 max = Math.max, 989 abs = Math.abs, 990 round = Math.round, 991 rhorizontal = /left|center|right/, 992 rvertical = /top|center|bottom/, 993 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 994 rposition = /^\w+/, 995 rpercent = /%$/, 996 _position = $.fn.position; 997 998function getOffsets( offsets, width, height ) { 999 return [ 1000 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1001 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1002 ]; 1003} 1004 1005function parseCss( element, property ) { 1006 return parseInt( $.css( element, property ), 10 ) || 0; 1007} 1008 1009function getDimensions( elem ) { 1010 var raw = elem[0]; 1011 if ( raw.nodeType === 9 ) { 1012 return { 1013 width: elem.width(), 1014 height: elem.height(), 1015 offset: { top: 0, left: 0 } 1016 }; 1017 } 1018 if ( $.isWindow( raw ) ) { 1019 return { 1020 width: elem.width(), 1021 height: elem.height(), 1022 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1023 }; 1024 } 1025 if ( raw.preventDefault ) { 1026 return { 1027 width: 0, 1028 height: 0, 1029 offset: { top: raw.pageY, left: raw.pageX } 1030 }; 1031 } 1032 return { 1033 width: elem.outerWidth(), 1034 height: elem.outerHeight(), 1035 offset: elem.offset() 1036 }; 1037} 1038 1039$.position = { 1040 scrollbarWidth: function() { 1041 if ( cachedScrollbarWidth !== undefined ) { 1042 return cachedScrollbarWidth; 1043 } 1044 var w1, w2, 1045 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1046 innerDiv = div.children()[0]; 1047 1048 $( "body" ).append( div ); 1049 w1 = innerDiv.offsetWidth; 1050 div.css( "overflow", "scroll" ); 1051 1052 w2 = innerDiv.offsetWidth; 1053 1054 if ( w1 === w2 ) { 1055 w2 = div[0].clientWidth; 1056 } 1057 1058 div.remove(); 1059 1060 return (cachedScrollbarWidth = w1 - w2); 1061 }, 1062 getScrollInfo: function( within ) { 1063 var overflowX = within.isWindow || within.isDocument ? "" : 1064 within.element.css( "overflow-x" ), 1065 overflowY = within.isWindow || within.isDocument ? "" : 1066 within.element.css( "overflow-y" ), 1067 hasOverflowX = overflowX === "scroll" || 1068 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1069 hasOverflowY = overflowY === "scroll" || 1070 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1071 return { 1072 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1073 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1074 }; 1075 }, 1076 getWithinInfo: function( element ) { 1077 var withinElement = $( element || window ), 1078 isWindow = $.isWindow( withinElement[0] ), 1079 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1080 return { 1081 element: withinElement, 1082 isWindow: isWindow, 1083 isDocument: isDocument, 1084 offset: withinElement.offset() || { left: 0, top: 0 }, 1085 scrollLeft: withinElement.scrollLeft(), 1086 scrollTop: withinElement.scrollTop(), 1087 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 1088 height: isWindow ? withinElement.height() : withinElement.outerHeight() 1089 }; 1090 } 1091}; 1092 1093$.fn.position = function( options ) { 1094 if ( !options || !options.of ) { 1095 return _position.apply( this, arguments ); 1096 } 1097 1098 // make a copy, we don't want to modify arguments 1099 options = $.extend( {}, options ); 1100 1101 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1102 target = $( options.of ), 1103 within = $.position.getWithinInfo( options.within ), 1104 scrollInfo = $.position.getScrollInfo( within ), 1105 collision = ( options.collision || "flip" ).split( " " ), 1106 offsets = {}; 1107 1108 dimensions = getDimensions( target ); 1109 if ( target[0].preventDefault ) { 1110 // force left top to allow flipping 1111 options.at = "left top"; 1112 } 1113 targetWidth = dimensions.width; 1114 targetHeight = dimensions.height; 1115 targetOffset = dimensions.offset; 1116 // clone to reuse original targetOffset later 1117 basePosition = $.extend( {}, targetOffset ); 1118 1119 // force my and at to have valid horizontal and vertical positions 1120 // if a value is missing or invalid, it will be converted to center 1121 $.each( [ "my", "at" ], function() { 1122 var pos = ( options[ this ] || "" ).split( " " ), 1123 horizontalOffset, 1124 verticalOffset; 1125 1126 if ( pos.length === 1) { 1127 pos = rhorizontal.test( pos[ 0 ] ) ? 1128 pos.concat( [ "center" ] ) : 1129 rvertical.test( pos[ 0 ] ) ? 1130 [ "center" ].concat( pos ) : 1131 [ "center", "center" ]; 1132 } 1133 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1134 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1135 1136 // calculate offsets 1137 horizontalOffset = roffset.exec( pos[ 0 ] ); 1138 verticalOffset = roffset.exec( pos[ 1 ] ); 1139 offsets[ this ] = [ 1140 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1141 verticalOffset ? verticalOffset[ 0 ] : 0 1142 ]; 1143 1144 // reduce to just the positions without the offsets 1145 options[ this ] = [ 1146 rposition.exec( pos[ 0 ] )[ 0 ], 1147 rposition.exec( pos[ 1 ] )[ 0 ] 1148 ]; 1149 }); 1150 1151 // normalize collision option 1152 if ( collision.length === 1 ) { 1153 collision[ 1 ] = collision[ 0 ]; 1154 } 1155 1156 if ( options.at[ 0 ] === "right" ) { 1157 basePosition.left += targetWidth; 1158 } else if ( options.at[ 0 ] === "center" ) { 1159 basePosition.left += targetWidth / 2; 1160 } 1161 1162 if ( options.at[ 1 ] === "bottom" ) { 1163 basePosition.top += targetHeight; 1164 } else if ( options.at[ 1 ] === "center" ) { 1165 basePosition.top += targetHeight / 2; 1166 } 1167 1168 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1169 basePosition.left += atOffset[ 0 ]; 1170 basePosition.top += atOffset[ 1 ]; 1171 1172 return this.each(function() { 1173 var collisionPosition, using, 1174 elem = $( this ), 1175 elemWidth = elem.outerWidth(), 1176 elemHeight = elem.outerHeight(), 1177 marginLeft = parseCss( this, "marginLeft" ), 1178 marginTop = parseCss( this, "marginTop" ), 1179 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1180 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1181 position = $.extend( {}, basePosition ), 1182 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1183 1184 if ( options.my[ 0 ] === "right" ) { 1185 position.left -= elemWidth; 1186 } else if ( options.my[ 0 ] === "center" ) { 1187 position.left -= elemWidth / 2; 1188 } 1189 1190 if ( options.my[ 1 ] === "bottom" ) { 1191 position.top -= elemHeight; 1192 } else if ( options.my[ 1 ] === "center" ) { 1193 position.top -= elemHeight / 2; 1194 } 1195 1196 position.left += myOffset[ 0 ]; 1197 position.top += myOffset[ 1 ]; 1198 1199 // if the browser doesn't support fractions, then round for consistent results 1200 if ( !$.support.offsetFractions ) { 1201 position.left = round( position.left ); 1202 position.top = round( position.top ); 1203 } 1204 1205 collisionPosition = { 1206 marginLeft: marginLeft, 1207 marginTop: marginTop 1208 }; 1209 1210 $.each( [ "left", "top" ], function( i, dir ) { 1211 if ( $.ui.position[ collision[ i ] ] ) { 1212 $.ui.position[ collision[ i ] ][ dir ]( position, { 1213 targetWidth: targetWidth, 1214 targetHeight: targetHeight, 1215 elemWidth: elemWidth, 1216 elemHeight: elemHeight, 1217 collisionPosition: collisionPosition, 1218 collisionWidth: collisionWidth, 1219 collisionHeight: collisionHeight, 1220 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1221 my: options.my, 1222 at: options.at, 1223 within: within, 1224 elem : elem 1225 }); 1226 } 1227 }); 1228 1229 if ( options.using ) { 1230 // adds feedback as second argument to using callback, if present 1231 using = function( props ) { 1232 var left = targetOffset.left - position.left, 1233 right = left + targetWidth - elemWidth, 1234 top = targetOffset.top - position.top, 1235 bottom = top + targetHeight - elemHeight, 1236 feedback = { 1237 target: { 1238 element: target, 1239 left: targetOffset.left, 1240 top: targetOffset.top, 1241 width: targetWidth, 1242 height: targetHeight 1243 }, 1244 element: { 1245 element: elem, 1246 left: position.left, 1247 top: position.top, 1248 width: elemWidth, 1249 height: elemHeight 1250 }, 1251 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1252 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1253 }; 1254 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1255 feedback.horizontal = "center"; 1256 } 1257 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1258 feedback.vertical = "middle"; 1259 } 1260 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1261 feedback.important = "horizontal"; 1262 } else { 1263 feedback.important = "vertical"; 1264 } 1265 options.using.call( this, props, feedback ); 1266 }; 1267 } 1268 1269 elem.offset( $.extend( position, { using: using } ) ); 1270 }); 1271}; 1272 1273$.ui.position = { 1274 fit: { 1275 left: function( position, data ) { 1276 var within = data.within, 1277 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1278 outerWidth = within.width, 1279 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1280 overLeft = withinOffset - collisionPosLeft, 1281 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1282 newOverRight; 1283 1284 // element is wider than within 1285 if ( data.collisionWidth > outerWidth ) { 1286 // element is initially over the left side of within 1287 if ( overLeft > 0 && overRight <= 0 ) { 1288 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1289 position.left += overLeft - newOverRight; 1290 // element is initially over right side of within 1291 } else if ( overRight > 0 && overLeft <= 0 ) { 1292 position.left = withinOffset; 1293 // element is initially over both left and right sides of within 1294 } else { 1295 if ( overLeft > overRight ) { 1296 position.left = withinOffset + outerWidth - data.collisionWidth; 1297 } else { 1298 position.left = withinOffset; 1299 } 1300 } 1301 // too far left -> align with left edge 1302 } else if ( overLeft > 0 ) { 1303 position.left += overLeft; 1304 // too far right -> align with right edge 1305 } else if ( overRight > 0 ) { 1306 position.left -= overRight; 1307 // adjust based on position and margin 1308 } else { 1309 position.left = max( position.left - collisionPosLeft, position.left ); 1310 } 1311 }, 1312 top: function( position, data ) { 1313 var within = data.within, 1314 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1315 outerHeight = data.within.height, 1316 collisionPosTop = position.top - data.collisionPosition.marginTop, 1317 overTop = withinOffset - collisionPosTop, 1318 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1319 newOverBottom; 1320 1321 // element is taller than within 1322 if ( data.collisionHeight > outerHeight ) { 1323 // element is initially over the top of within 1324 if ( overTop > 0 && overBottom <= 0 ) { 1325 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1326 position.top += overTop - newOverBottom; 1327 // element is initially over bottom of within 1328 } else if ( overBottom > 0 && overTop <= 0 ) { 1329 position.top = withinOffset; 1330 // element is initially over both top and bottom of within 1331 } else { 1332 if ( overTop > overBottom ) { 1333 position.top = withinOffset + outerHeight - data.collisionHeight; 1334 } else { 1335 position.top = withinOffset; 1336 } 1337 } 1338 // too far up -> align with top 1339 } else if ( overTop > 0 ) { 1340 position.top += overTop; 1341 // too far down -> align with bottom edge 1342 } else if ( overBottom > 0 ) { 1343 position.top -= overBottom; 1344 // adjust based on position and margin 1345 } else { 1346 position.top = max( position.top - collisionPosTop, position.top ); 1347 } 1348 } 1349 }, 1350 flip: { 1351 left: function( position, data ) { 1352 var within = data.within, 1353 withinOffset = within.offset.left + within.scrollLeft, 1354 outerWidth = within.width, 1355 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1356 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1357 overLeft = collisionPosLeft - offsetLeft, 1358 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1359 myOffset = data.my[ 0 ] === "left" ? 1360 -data.elemWidth : 1361 data.my[ 0 ] === "right" ? 1362 data.elemWidth : 1363 0, 1364 atOffset = data.at[ 0 ] === "left" ? 1365 data.targetWidth : 1366 data.at[ 0 ] === "right" ? 1367 -data.targetWidth : 1368 0, 1369 offset = -2 * data.offset[ 0 ], 1370 newOverRight, 1371 newOverLeft; 1372 1373 if ( overLeft < 0 ) { 1374 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1375 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1376 position.left += myOffset + atOffset + offset; 1377 } 1378 } 1379 else if ( overRight > 0 ) { 1380 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1381 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1382 position.left += myOffset + atOffset + offset; 1383 } 1384 } 1385 }, 1386 top: function( position, data ) { 1387 var within = data.within, 1388 withinOffset = within.offset.top + within.scrollTop, 1389 outerHeight = within.height, 1390 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1391 collisionPosTop = position.top - data.collisionPosition.marginTop, 1392 overTop = collisionPosTop - offsetTop, 1393 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1394 top = data.my[ 1 ] === "top", 1395 myOffset = top ? 1396 -data.elemHeight : 1397 data.my[ 1 ] === "bottom" ? 1398 data.elemHeight : 1399 0, 1400 atOffset = data.at[ 1 ] === "top" ? 1401 data.targetHeight : 1402 data.at[ 1 ] === "bottom" ? 1403 -data.targetHeight : 1404 0, 1405 offset = -2 * data.offset[ 1 ], 1406 newOverTop, 1407 newOverBottom; 1408 if ( overTop < 0 ) { 1409 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1410 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1411 position.top += myOffset + atOffset + offset; 1412 } 1413 } 1414 else if ( overBottom > 0 ) { 1415 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1416 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1417 position.top += myOffset + atOffset + offset; 1418 } 1419 } 1420 } 1421 }, 1422 flipfit: { 1423 left: function() { 1424 $.ui.position.flip.left.apply( this, arguments ); 1425 $.ui.position.fit.left.apply( this, arguments ); 1426 }, 1427 top: function() { 1428 $.ui.position.flip.top.apply( this, arguments ); 1429 $.ui.position.fit.top.apply( this, arguments ); 1430 } 1431 } 1432}; 1433 1434// fraction support test 1435(function () { 1436 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1437 body = document.getElementsByTagName( "body" )[ 0 ], 1438 div = document.createElement( "div" ); 1439 1440 //Create a "fake body" for testing based on method used in jQuery.support 1441 testElement = document.createElement( body ? "div" : "body" ); 1442 testElementStyle = { 1443 visibility: "hidden", 1444 width: 0, 1445 height: 0, 1446 border: 0, 1447 margin: 0, 1448 background: "none" 1449 }; 1450 if ( body ) { 1451 $.extend( testElementStyle, { 1452 position: "absolute", 1453 left: "-1000px", 1454 top: "-1000px" 1455 }); 1456 } 1457 for ( i in testElementStyle ) { 1458 testElement.style[ i ] = testElementStyle[ i ]; 1459 } 1460 testElement.appendChild( div ); 1461 testElementParent = body || document.documentElement; 1462 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1463 1464 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1465 1466 offsetLeft = $( div ).offset().left; 1467 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 1468 1469 testElement.innerHTML = ""; 1470 testElementParent.removeChild( testElement ); 1471})(); 1472 1473}( jQuery ) ); 1474(function( $, undefined ) { 1475 1476$.extend($.ui, { datepicker: { version: "1.10.4
vendor: 75,965 bytes, lines 1476-3496
1476" } }); 1477 1478var PROP_NAME = "datepicker", 1479 instActive; 1480 1481/* Date picker manager. 1482 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 1483 Settings for (groups of) date pickers are maintained in an instance object, 1484 allowing multiple different settings on the same page. */ 1485 1486function Datepicker() { 1487 this._curInst = null; // The current instance in use 1488 this._keyEvent = false; // If the last event was a key event 1489 this._disabledInputs = []; // List of date picker inputs that have been disabled 1490 this._datepickerShowing = false; // True if the popup picker is showing , false if not 1491 this._inDialog = false; // True if showing within a "dialog", false if not 1492 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 1493 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 1494 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 1495 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 1496 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 1497 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 1498 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 1499 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 1500 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 1501 this.regional = []; // Available regional settings, indexed by language code 1502 this.regional[""] = { // Default regional settings 1503 closeText: "Done", // Display text for close link 1504 prevText: "Prev", // Display text for previous month link 1505 nextText: "Next", // Display text for next month link 1506 currentText: "Today", // Display text for current month link 1507 monthNames: ["January","February","March","April","May","June", 1508 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 1509 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 1510 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 1511 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 1512 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 1513 weekHeader: "Wk", // Column header for week of the year 1514 dateFormat: "mm/dd/yy", // See format options on parseDate 1515 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 1516 isRTL: false, // True if right-to-left language, false if left-to-right 1517 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 1518 yearSuffix: "" // Additional text to append to the year in the month headers 1519 }; 1520 this._defaults = { // Global defaults for all the date picker instances 1521 showOn: "focus", // "focus" for popup on focus, 1522 // "button" for trigger button, or "both" for either 1523 showAnim: "fadeIn", // Name of jQuery animation for popup 1524 showOptions: {}, // Options for enhanced animations 1525 defaultDate: null, // Used when field is blank: actual date, 1526 // +/-number for offset from today, null for today 1527 appendText: "", // Display text following the input box, e.g. showing the format 1528 buttonText: "...", // Text for trigger button 1529 buttonImage: "", // URL for trigger button image 1530 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 1531 hideIfNoPrevNext: false, // True to hide next/previous month links 1532 // if not applicable, false to just disable them 1533 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 1534 gotoCurrent: false, // True if today link goes back to current selection instead 1535 changeMonth: false, // True if month can be selected directly, false if only prev/next 1536 changeYear: false, // True if year can be selected directly, false if only prev/next 1537 yearRange: "c-10:c+10", // Range of years to display in drop-down, 1538 // either relative to today's year (-nn:+nn), relative to currently displayed year 1539 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 1540 showOtherMonths: false, // True to show dates in other months, false to leave blank 1541 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 1542 showWeek: false, // True to show week of the year, false to not show it 1543 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 1544 // takes a Date and returns the number of the week for it 1545 shortYearCutoff: "+10", // Short year values < this are in the current century, 1546 // > this are in the previous century, 1547 // string value starting with "+" for current year + value 1548 minDate: null, // The earliest selectable date, or null for no limit 1549 maxDate: null, // The latest selectable date, or null for no limit 1550 duration: "fast", // Duration of display/closure 1551 beforeShowDay: null, // Function that takes a date and returns an array with 1552 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 1553 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 1554 beforeShow: null, // Function that takes an input field and 1555 // returns a set of custom settings for the date picker 1556 onSelect: null, // Define a callback function when a date is selected 1557 onChangeMonthYear: null, // Define a callback function when the month or year is changed 1558 onClose: null, // Define a callback function when the datepicker is closed 1559 numberOfMonths: 1, // Number of months to show at a time 1560 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 1561 stepMonths: 1, // Number of months to step back/forward 1562 stepBigMonths: 12, // Number of months to step back/forward for the big links 1563 altField: "", // Selector for an alternate field to store selected dates into 1564 altFormat: "", // The date format to use for the alternate field 1565 constrainInput: true, // The input is constrained by the current date format 1566 showButtonPanel: false, // True to show button panel, false to not show it 1567 autoSize: false, // True to size the input for the date format, false to leave as is 1568 disabled: false // The initial disabled state 1569 }; 1570 $.extend(this._defaults, this.regional[""]); 1571 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 1572} 1573 1574$.extend(Datepicker.prototype, { 1575 /* Class name added to elements to indicate already configured with a date picker. */ 1576 markerClassName: "hasDatepicker", 1577 1578 //Keep track of the maximum number of rows displayed (see #7043) 1579 maxRows: 4, 1580 1581 // TODO rename to "widget" when switching to widget factory 1582 _widgetDatepicker: function() { 1583 return this.dpDiv; 1584 }, 1585 1586 /* Override the default settings for all instances of the date picker. 1587 * @param settings object - the new settings to use as defaults (anonymous object) 1588 * @return the manager object 1589 */ 1590 setDefaults: function(settings) { 1591 extendRemove(this._defaults, settings || {}); 1592 return this; 1593 }, 1594 1595 /* Attach the date picker to a jQuery selection. 1596 * @param target element - the target input field or division or span 1597 * @param settings object - the new settings to use for this date picker instance (anonymous) 1598 */ 1599 _attachDatepicker: function(target, settings) { 1600 var nodeName, inline, inst; 1601 nodeName = target.nodeName.toLowerCase(); 1602 inline = (nodeName === "div" || nodeName === "span"); 1603 if (!target.id) { 1604 this.uuid += 1; 1605 target.id = "dp" + this.uuid; 1606 } 1607 inst = this._newInst($(target), inline); 1608 inst.settings = $.extend({}, settings || {}); 1609 if (nodeName === "input") { 1610 this._connectDatepicker(target, inst); 1611 } else if (inline) { 1612 this._inlineDatepicker(target, inst); 1613 } 1614 }, 1615 1616 /* Create a new instance object. */ 1617 _newInst: function(target, inline) { 1618 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 1619 return {id: id, input: target, // associated target 1620 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 1621 drawMonth: 0, drawYear: 0, // month being drawn 1622 inline: inline, // is datepicker inline or not 1623 dpDiv: (!inline ? this.dpDiv : // presentation div 1624 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 1625 }, 1626 1627 /* Attach the date picker to an input field. */ 1628 _connectDatepicker: function(target, inst) { 1629 var input = $(target); 1630 inst.append = $([]); 1631 inst.trigger = $([]); 1632 if (input.hasClass(this.markerClassName)) { 1633 return; 1634 } 1635 this._attachments(input, inst); 1636 input.addClass(this.markerClassName).keydown(this._doKeyDown). 1637 keypress(this._doKeyPress).keyup(this._doKeyUp); 1638 this._autoSize(inst); 1639 $.data(target, PROP_NAME, inst); 1640 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 1641 if( inst.settings.disabled ) { 1642 this._disableDatepicker( target ); 1643 } 1644 }, 1645 1646 /* Make attachments based on settings. */ 1647 _attachments: function(input, inst) { 1648 var showOn, buttonText, buttonImage, 1649 appendText = this._get(inst, "appendText"), 1650 isRTL = this._get(inst, "isRTL"); 1651 1652 if (inst.append) { 1653 inst.append.remove(); 1654 } 1655 if (appendText) { 1656 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 1657 input[isRTL ? "before" : "after"](inst.append); 1658 } 1659 1660 input.unbind("focus", this._showDatepicker); 1661 1662 if (inst.trigger) { 1663 inst.trigger.remove(); 1664 } 1665 1666 showOn = this._get(inst, "showOn"); 1667 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 1668 input.focus(this._showDatepicker); 1669 } 1670 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 1671 buttonText = this._get(inst, "buttonText"); 1672 buttonImage = this._get(inst, "buttonImage"); 1673 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 1674 $("<img/>").addClass(this._triggerClass). 1675 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 1676 $("<button type='button'></button>").addClass(this._triggerClass). 1677 html(!buttonImage ? buttonText : $("<img/>").attr( 1678 { src:buttonImage, alt:buttonText, title:buttonText }))); 1679 input[isRTL ? "before" : "after"](inst.trigger); 1680 inst.trigger.click(function() { 1681 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 1682 $.datepicker._hideDatepicker(); 1683 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 1684 $.datepicker._hideDatepicker(); 1685 $.datepicker._showDatepicker(input[0]); 1686 } else { 1687 $.datepicker._showDatepicker(input[0]); 1688 } 1689 return false; 1690 }); 1691 } 1692 }, 1693 1694 /* Apply the maximum length for the date format. */ 1695 _autoSize: function(inst) { 1696 if (this._get(inst, "autoSize") && !inst.inline) { 1697 var findMax, max, maxI, i, 1698 date = new Date(2009, 12 - 1, 20), // Ensure double digits 1699 dateFormat = this._get(inst, "dateFormat"); 1700 1701 if (dateFormat.match(/[DM]/)) { 1702 findMax = function(names) { 1703 max = 0; 1704 maxI = 0; 1705 for (i = 0; i < names.length; i++) { 1706 if (names[i].length > max) { 1707 max = names[i].length; 1708 maxI = i; 1709 } 1710 } 1711 return maxI; 1712 }; 1713 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 1714 "monthNames" : "monthNamesShort")))); 1715 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 1716 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 1717 } 1718 inst.input.attr("size", this._formatDate(inst, date).length); 1719 } 1720 }, 1721 1722 /* Attach an inline date picker to a div. */ 1723 _inlineDatepicker: function(target, inst) { 1724 var divSpan = $(target); 1725 if (divSpan.hasClass(this.markerClassName)) { 1726 return; 1727 } 1728 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 1729 $.data(target, PROP_NAME, inst); 1730 this._setDate(inst, this._getDefaultDate(inst), true); 1731 this._updateDatepicker(inst); 1732 this._updateAlternate(inst); 1733 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 1734 if( inst.settings.disabled ) { 1735 this._disableDatepicker( target ); 1736 } 1737 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 1738 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 1739 inst.dpDiv.css( "display", "block" ); 1740 }, 1741 1742 /* Pop-up the date picker in a "dialog" box. 1743 * @param input element - ignored 1744 * @param date string or Date - the initial date to display 1745 * @param onSelect function - the function to call when a date is selected 1746 * @param settings object - update the dialog date picker instance's settings (anonymous object) 1747 * @param pos int[2] - coordinates for the dialog's position within the screen or 1748 * event - with x/y coordinates or 1749 * leave empty for default (screen centre) 1750 * @return the manager object 1751 */ 1752 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 1753 var id, browserWidth, browserHeight, scrollX, scrollY, 1754 inst = this._dialogInst; // internal instance 1755 1756 if (!inst) { 1757 this.uuid += 1; 1758 id = "dp" + this.uuid; 1759 this._dialogInput = $("<input type='text' id='" + id + 1760 "' style='position: absolute; top: -100px; width: 0px;'/>"); 1761 this._dialogInput.keydown(this._doKeyDown); 1762 $("body").append(this._dialogInput); 1763 inst = this._dialogInst = this._newInst(this._dialogInput, false); 1764 inst.settings = {}; 1765 $.data(this._dialogInput[0], PROP_NAME, inst); 1766 } 1767 extendRemove(inst.settings, settings || {}); 1768 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 1769 this._dialogInput.val(date); 1770 1771 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 1772 if (!this._pos) { 1773 browserWidth = document.documentElement.clientWidth; 1774 browserHeight = document.documentElement.clientHeight; 1775 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 1776 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 1777 this._pos = // should use actual width/height below 1778 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 1779 } 1780 1781 // move input on screen for focus, but hidden behind dialog 1782 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 1783 inst.settings.onSelect = onSelect; 1784 this._inDialog = true; 1785 this.dpDiv.addClass(this._dialogClass); 1786 this._showDatepicker(this._dialogInput[0]); 1787 if ($.blockUI) { 1788 $.blockUI(this.dpDiv); 1789 } 1790 $.data(this._dialogInput[0], PROP_NAME, inst); 1791 return this; 1792 }, 1793 1794 /* Detach a datepicker from its control. 1795 * @param target element - the target input field or division or span 1796 */ 1797 _destroyDatepicker: function(target) { 1798 var nodeName, 1799 $target = $(target), 1800 inst = $.data(target, PROP_NAME); 1801 1802 if (!$target.hasClass(this.markerClassName)) { 1803 return; 1804 } 1805 1806 nodeName = target.nodeName.toLowerCase(); 1807 $.removeData(target, PROP_NAME); 1808 if (nodeName === "input") { 1809 inst.append.remove(); 1810 inst.trigger.remove(); 1811 $target.removeClass(this.markerClassName). 1812 unbind("focus", this._showDatepicker). 1813 unbind("keydown", this._doKeyDown). 1814 unbind("keypress", this._doKeyPress). 1815 unbind("keyup", this._doKeyUp); 1816 } else if (nodeName === "div" || nodeName === "span") { 1817 $target.removeClass(this.markerClassName).empty(); 1818 } 1819 }, 1820 1821 /* Enable the date picker to a jQuery selection. 1822 * @param target element - the target input field or division or span 1823 */ 1824 _enableDatepicker: function(target) { 1825 var nodeName, inline, 1826 $target = $(target), 1827 inst = $.data(target, PROP_NAME); 1828 1829 if (!$target.hasClass(this.markerClassName)) { 1830 return; 1831 } 1832 1833 nodeName = target.nodeName.toLowerCase(); 1834 if (nodeName === "input") { 1835 target.disabled = false; 1836 inst.trigger.filter("button"). 1837 each(function() { this.disabled = false; }).end(). 1838 filter("img").css({opacity: "1.0", cursor: ""}); 1839 } else if (nodeName === "div" || nodeName === "span") { 1840 inline = $target.children("." + this._inlineClass); 1841 inline.children().removeClass("ui-state-disabled"); 1842 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 1843 prop("disabled", false); 1844 } 1845 this._disabledInputs = $.map(this._disabledInputs, 1846 function(value) { return (value === target ? null : value); }); // delete entry 1847 }, 1848 1849 /* Disable the date picker to a jQuery selection. 1850 * @param target element - the target input field or division or span 1851 */ 1852 _disableDatepicker: function(target) { 1853 var nodeName, inline, 1854 $target = $(target), 1855 inst = $.data(target, PROP_NAME); 1856 1857 if (!$target.hasClass(this.markerClassName)) { 1858 return; 1859 } 1860 1861 nodeName = target.nodeName.toLowerCase(); 1862 if (nodeName === "input") { 1863 target.disabled = true; 1864 inst.trigger.filter("button"). 1865 each(function() { this.disabled = true; }).end(). 1866 filter("img").css({opacity: "0.5", cursor: "default"}); 1867 } else if (nodeName === "div" || nodeName === "span") { 1868 inline = $target.children("." + this._inlineClass); 1869 inline.children().addClass("ui-state-disabled"); 1870 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 1871 prop("disabled", true); 1872 } 1873 this._disabledInputs = $.map(this._disabledInputs, 1874 function(value) { return (value === target ? null : value); }); // delete entry 1875 this._disabledInputs[this._disabledInputs.length] = target; 1876 }, 1877 1878 /* Is the first field in a jQuery collection disabled as a datepicker? 1879 * @param target element - the target input field or division or span 1880 * @return boolean - true if disabled, false if enabled 1881 */ 1882 _isDisabledDatepicker: function(target) { 1883 if (!target) { 1884 return false; 1885 } 1886 for (var i = 0; i < this._disabledInputs.length; i++) { 1887 if (this._disabledInputs[i] === target) { 1888 return true; 1889 } 1890 } 1891 return false; 1892 }, 1893 1894 /* Retrieve the instance data for the target control. 1895 * @param target element - the target input field or division or span 1896 * @return object - the associated instance data 1897 * @throws error if a jQuery problem getting data 1898 */ 1899 _getInst: function(target) { 1900 try { 1901 return $.data(target, PROP_NAME); 1902 } 1903 catch (err) { 1904 throw "Missing instance data for this datepicker"; 1905 } 1906 }, 1907 1908 /* Update or retrieve the settings for a date picker attached to an input field or division. 1909 * @param target element - the target input field or division or span 1910 * @param name object - the new settings to update or 1911 * string - the name of the setting to change or retrieve, 1912 * when retrieving also "all" for all instance settings or 1913 * "defaults" for all global defaults 1914 * @param value any - the new value for the setting 1915 * (omit if above is an object or to retrieve a value) 1916 */ 1917 _optionDatepicker: function(target, name, value) { 1918 var settings, date, minDate, maxDate, 1919 inst = this._getInst(target); 1920 1921 if (arguments.length === 2 && typeof name === "string") { 1922 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 1923 (inst ? (name === "all" ? $.extend({}, inst.settings) : 1924 this._get(inst, name)) : null)); 1925 } 1926 1927 settings = name || {}; 1928 if (typeof name === "string") { 1929 settings = {}; 1930 settings[name] = value; 1931 } 1932 1933 if (inst) { 1934 if (this._curInst === inst) { 1935 this._hideDatepicker(); 1936 } 1937 1938 date = this._getDateDatepicker(target, true); 1939 minDate = this._getMinMaxDate(inst, "min"); 1940 maxDate = this._getMinMaxDate(inst, "max"); 1941 extendRemove(inst.settings, settings); 1942 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 1943 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 1944 inst.settings.minDate = this._formatDate(inst, minDate); 1945 } 1946 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 1947 inst.settings.maxDate = this._formatDate(inst, maxDate); 1948 } 1949 if ( "disabled" in settings ) { 1950 if ( settings.disabled ) { 1951 this._disableDatepicker(target); 1952 } else { 1953 this._enableDatepicker(target); 1954 } 1955 } 1956 this._attachments($(target), inst); 1957 this._autoSize(inst); 1958 this._setDate(inst, date); 1959 this._updateAlternate(inst); 1960 this._updateDatepicker(inst); 1961 } 1962 }, 1963 1964 // change method deprecated 1965 _changeDatepicker: function(target, name, value) { 1966 this._optionDatepicker(target, name, value); 1967 }, 1968 1969 /* Redraw the date picker attached to an input field or division. 1970 * @param target element - the target input field or division or span 1971 */ 1972 _refreshDatepicker: function(target) { 1973 var inst = this._getInst(target); 1974 if (inst) { 1975 this._updateDatepicker(inst); 1976 } 1977 }, 1978 1979 /* Set the dates for a jQuery selection. 1980 * @param target element - the target input field or division or span 1981 * @param date Date - the new date 1982 */ 1983 _setDateDatepicker: function(target, date) { 1984 var inst = this._getInst(target); 1985 if (inst) { 1986 this._setDate(inst, date); 1987 this._updateDatepicker(inst); 1988 this._updateAlternate(inst); 1989 } 1990 }, 1991 1992 /* Get the date(s) for the first entry in a jQuery selection. 1993 * @param target element - the target input field or division or span 1994 * @param noDefault boolean - true if no default date is to be used 1995 * @return Date - the current date 1996 */ 1997 _getDateDatepicker: function(target, noDefault) { 1998 var inst = this._getInst(target); 1999 if (inst && !inst.inline) { 2000 this._setDateFromField(inst, noDefault); 2001 } 2002 return (inst ? this._getDate(inst) : null); 2003 }, 2004 2005 /* Handle keystrokes. */ 2006 _doKeyDown: function(event) { 2007 var onSelect, dateStr, sel, 2008 inst = $.datepicker._getInst(event.target), 2009 handled = true, 2010 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 2011 2012 inst._keyEvent = true; 2013 if ($.datepicker._datepickerShowing) { 2014 switch (event.keyCode) { 2015 case 9: $.datepicker._hideDatepicker(); 2016 handled = false; 2017 break; // hide on tab out 2018 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 2019 $.datepicker._currentClass + ")", inst.dpDiv); 2020 if (sel[0]) { 2021 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 2022 } 2023 2024 onSelect = $.datepicker._get(inst, "onSelect"); 2025 if (onSelect) { 2026 dateStr = $.datepicker._formatDate(inst); 2027 2028 // trigger custom callback 2029 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 2030 } else { 2031 $.datepicker._hideDatepicker(); 2032 } 2033 2034 return false; // don't submit the form 2035 case 27: $.datepicker._hideDatepicker(); 2036 break; // hide on escape 2037 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 2038 -$.datepicker._get(inst, "stepBigMonths") : 2039 -$.datepicker._get(inst, "stepMonths")), "M"); 2040 break; // previous month/year on page up/+ ctrl 2041 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 2042 +$.datepicker._get(inst, "stepBigMonths") : 2043 +$.datepicker._get(inst, "stepMonths")), "M"); 2044 break; // next month/year on page down/+ ctrl 2045 case 35: if (event.ctrlKey || event.metaKey) { 2046 $.datepicker._clearDate(event.target); 2047 } 2048 handled = event.ctrlKey || event.metaKey; 2049 break; // clear on ctrl or command +end 2050 case 36: if (event.ctrlKey || event.metaKey) { 2051 $.datepicker._gotoToday(event.target); 2052 } 2053 handled = event.ctrlKey || event.metaKey; 2054 break; // current on ctrl or command +home 2055 case 37: if (event.ctrlKey || event.metaKey) { 2056 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 2057 } 2058 handled = event.ctrlKey || event.metaKey; 2059 // -1 day on ctrl or command +left 2060 if (event.originalEvent.altKey) { 2061 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 2062 -$.datepicker._get(inst, "stepBigMonths") : 2063 -$.datepicker._get(inst, "stepMonths")), "M"); 2064 } 2065 // next month/year on alt +left on Mac 2066 break; 2067 case 38: if (event.ctrlKey || event.metaKey) { 2068 $.datepicker._adjustDate(event.target, -7, "D"); 2069 } 2070 handled = event.ctrlKey || event.metaKey; 2071 break; // -1 week on ctrl or command +up 2072 case 39: if (event.ctrlKey || event.metaKey) { 2073 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 2074 } 2075 handled = event.ctrlKey || event.metaKey; 2076 // +1 day on ctrl or command +right 2077 if (event.originalEvent.altKey) { 2078 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 2079 +$.datepicker._get(inst, "stepBigMonths") : 2080 +$.datepicker._get(inst, "stepMonths")), "M"); 2081 } 2082 // next month/year on alt +right 2083 break; 2084 case 40: if (event.ctrlKey || event.metaKey) { 2085 $.datepicker._adjustDate(event.target, +7, "D"); 2086 } 2087 handled = event.ctrlKey || event.metaKey; 2088 break; // +1 week on ctrl or command +down 2089 default: handled = false; 2090 } 2091 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 2092 $.datepicker._showDatepicker(this); 2093 } else { 2094 handled = false; 2095 } 2096 2097 if (handled) { 2098 event.preventDefault(); 2099 event.stopPropagation(); 2100 } 2101 }, 2102 2103 /* Filter entered characters - based on date format. */ 2104 _doKeyPress: function(event) { 2105 var chars, chr, 2106 inst = $.datepicker._getInst(event.target); 2107 2108 if ($.datepicker._get(inst, "constrainInput")) { 2109 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 2110 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 2111 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 2112 } 2113 }, 2114 2115 /* Synchronise manual entry and field/alternate field. */ 2116 _doKeyUp: function(event) { 2117 var date, 2118 inst = $.datepicker._getInst(event.target); 2119 2120 if (inst.input.val() !== inst.lastVal) { 2121 try { 2122 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 2123 (inst.input ? inst.input.val() : null), 2124 $.datepicker._getFormatConfig(inst)); 2125 2126 if (date) { // only if valid 2127 $.datepicker._setDateFromField(inst); 2128 $.datepicker._updateAlternate(inst); 2129 $.datepicker._updateDatepicker(inst); 2130 } 2131 } 2132 catch (err) { 2133 } 2134 } 2135 return true; 2136 }, 2137 2138 /* Pop-up the date picker for a given input field. 2139 * If false returned from beforeShow event handler do not show. 2140 * @param input element - the input field attached to the date picker or 2141 * event - if triggered by focus 2142 */ 2143 _showDatepicker: function(input) { 2144 input = input.target || input; 2145 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 2146 input = $("input", input.parentNode)[0]; 2147 } 2148 2149 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 2150 return; 2151 } 2152 2153 var inst, beforeShow, beforeShowSettings, isFixed, 2154 offset, showAnim, duration; 2155 2156 inst = $.datepicker._getInst(input); 2157 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 2158 $.datepicker._curInst.dpDiv.stop(true, true); 2159 if ( inst && $.datepicker._datepickerShowing ) { 2160 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 2161 } 2162 } 2163 2164 beforeShow = $.datepicker._get(inst, "beforeShow"); 2165 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 2166 if(beforeShowSettings === false){ 2167 return; 2168 } 2169 extendRemove(inst.settings, beforeShowSettings); 2170 2171 inst.lastVal = null; 2172 $.datepicker._lastInput = input; 2173 $.datepicker._setDateFromField(inst); 2174 2175 if ($.datepicker._inDialog) { // hide cursor 2176 input.value = ""; 2177 } 2178 if (!$.datepicker._pos) { // position below input 2179 $.datepicker._pos = $.datepicker._findPos(input); 2180 $.datepicker._pos[1] += input.offsetHeight; // add the height 2181 } 2182 2183 isFixed = false; 2184 $(input).parents().each(function() { 2185 isFixed |= $(this).css("position") === "fixed"; 2186 return !isFixed; 2187 }); 2188 2189 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 2190 $.datepicker._pos = null; 2191 //to avoid flashes on Firefox 2192 inst.dpDiv.empty(); 2193 // determine sizing offscreen 2194 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 2195 $.datepicker._updateDatepicker(inst); 2196 // fix width for dynamic number of date pickers 2197 // and adjust position before showing 2198 offset = $.datepicker._checkOffset(inst, offset, isFixed); 2199 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 2200 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 2201 left: offset.left + "px", top: offset.top + "px"}); 2202 2203 if (!inst.inline) { 2204 showAnim = $.datepicker._get(inst, "showAnim"); 2205 duration = $.datepicker._get(inst, "duration"); 2206 inst.dpDiv.zIndex($(input).zIndex()+1); 2207 $.datepicker._datepickerShowing = true; 2208 2209 if ( $.effects && $.effects.effect[ showAnim ] ) { 2210 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 2211 } else { 2212 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 2213 } 2214 2215 if ( $.datepicker._shouldFocusInput( inst ) ) { 2216 inst.input.focus(); 2217 } 2218 2219 $.datepicker._curInst = inst; 2220 } 2221 }, 2222 2223 /* Generate the date picker content. */ 2224 _updateDatepicker: function(inst) { 2225 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 2226 instActive = inst; // for delegate hover events 2227 inst.dpDiv.empty().append(this._generateHTML(inst)); 2228 this._attachHandlers(inst); 2229 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 2230 2231 var origyearshtml, 2232 numMonths = this._getNumberOfMonths(inst), 2233 cols = numMonths[1], 2234 width = 17; 2235 2236 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 2237 if (cols > 1) { 2238 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 2239 } 2240 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 2241 "Class"]("ui-datepicker-multi"); 2242 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 2243 "Class"]("ui-datepicker-rtl"); 2244 2245 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 2246 inst.input.focus(); 2247 } 2248 2249 // deffered render of the years select (to avoid flashes on Firefox) 2250 if( inst.yearshtml ){ 2251 origyearshtml = inst.yearshtml; 2252 setTimeout(function(){ 2253 //assure that inst.yearshtml didn't change. 2254 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 2255 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 2256 } 2257 origyearshtml = inst.yearshtml = null; 2258 }, 0); 2259 } 2260 }, 2261 2262 // #6694 - don't focus the input if it's already focused 2263 // this breaks the change event in IE 2264 // Support: IE and jQuery <1.9 2265 _shouldFocusInput: function( inst ) { 2266 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 2267 }, 2268 2269 /* Check positioning to remain on screen. */ 2270 _checkOffset: function(inst, offset, isFixed) { 2271 var dpWidth = inst.dpDiv.outerWidth(), 2272 dpHeight = inst.dpDiv.outerHeight(), 2273 inputWidth = inst.input ? inst.input.outerWidth() : 0, 2274 inputHeight = inst.input ? inst.input.outerHeight() : 0, 2275 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 2276 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 2277 2278 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 2279 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 2280 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 2281 2282 // now check if datepicker is showing outside window viewport - move to a better place if so. 2283 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 2284 Math.abs(offset.left + dpWidth - viewWidth) : 0); 2285 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 2286 Math.abs(dpHeight + inputHeight) : 0); 2287 2288 return offset; 2289 }, 2290 2291 /* Find an object's position on the screen. */ 2292 _findPos: function(obj) { 2293 var position, 2294 inst = this._getInst(obj), 2295 isRTL = this._get(inst, "isRTL"); 2296 2297 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 2298 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 2299 } 2300 2301 position = $(obj).offset(); 2302 return [position.left, position.top]; 2303 }, 2304 2305 /* Hide the date picker from view. 2306 * @param input element - the input field attached to the date picker 2307 */ 2308 _hideDatepicker: function(input) { 2309 var showAnim, duration, postProcess, onClose, 2310 inst = this._curInst; 2311 2312 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 2313 return; 2314 } 2315 2316 if (this._datepickerShowing) { 2317 showAnim = this._get(inst, "showAnim"); 2318 duration = this._get(inst, "duration"); 2319 postProcess = function() { 2320 $.datepicker._tidyDialog(inst); 2321 }; 2322 2323 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 2324 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 2325 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 2326 } else { 2327 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 2328 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 2329 } 2330 2331 if (!showAnim) { 2332 postProcess(); 2333 } 2334 this._datepickerShowing = false; 2335 2336 onClose = this._get(inst, "onClose"); 2337 if (onClose) { 2338 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 2339 } 2340 2341 this._lastInput = null; 2342 if (this._inDialog) { 2343 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 2344 if ($.blockUI) { 2345 $.unblockUI(); 2346 $("body").append(this.dpDiv); 2347 } 2348 } 2349 this._inDialog = false; 2350 } 2351 }, 2352 2353 /* Tidy up after a dialog display. */ 2354 _tidyDialog: function(inst) { 2355 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 2356 }, 2357 2358 /* Close date picker if clicked elsewhere. */ 2359 _checkExternalClick: function(event) { 2360 if (!$.datepicker._curInst) { 2361 return; 2362 } 2363 2364 var $target = $(event.target), 2365 inst = $.datepicker._getInst($target[0]); 2366 2367 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 2368 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 2369 !$target.hasClass($.datepicker.markerClassName) && 2370 !$target.closest("." + $.datepicker._triggerClass).length && 2371 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 2372 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 2373 $.datepicker._hideDatepicker(); 2374 } 2375 }, 2376 2377 /* Adjust one of the date sub-fields. */ 2378 _adjustDate: function(id, offset, period) { 2379 var target = $(id), 2380 inst = this._getInst(target[0]); 2381 2382 if (this._isDisabledDatepicker(target[0])) { 2383 return; 2384 } 2385 this._adjustInstDate(inst, offset + 2386 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 2387 period); 2388 this._updateDatepicker(inst); 2389 }, 2390 2391 /* Action for current link. */ 2392 _gotoToday: function(id) { 2393 var date, 2394 target = $(id), 2395 inst = this._getInst(target[0]); 2396 2397 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 2398 inst.selectedDay = inst.currentDay; 2399 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 2400 inst.drawYear = inst.selectedYear = inst.currentYear; 2401 } else { 2402 date = new Date(); 2403 inst.selectedDay = date.getDate(); 2404 inst.drawMonth = inst.selectedMonth = date.getMonth(); 2405 inst.drawYear = inst.selectedYear = date.getFullYear(); 2406 } 2407 this._notifyChange(inst); 2408 this._adjustDate(target); 2409 }, 2410 2411 /* Action for selecting a new month/year. */ 2412 _selectMonthYear: function(id, select, period) { 2413 var target = $(id), 2414 inst = this._getInst(target[0]); 2415 2416 inst["selected" + (period === "M" ? "Month" : "Year")] = 2417 inst["draw" + (period === "M" ? "Month" : "Year")] = 2418 parseInt(select.options[select.selectedIndex].value,10); 2419 2420 this._notifyChange(inst); 2421 this._adjustDate(target); 2422 }, 2423 2424 /* Action for selecting a day. */ 2425 _selectDay: function(id, month, year, td) { 2426 var inst, 2427 target = $(id); 2428 2429 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 2430 return; 2431 } 2432 2433 inst = this._getInst(target[0]); 2434 inst.selectedDay = inst.currentDay = $("a", td).html(); 2435 inst.selectedMonth = inst.currentMonth = month; 2436 inst.selectedYear = inst.currentYear = year; 2437 this._selectDate(id, this._formatDate(inst, 2438 inst.currentDay, inst.currentMonth, inst.currentYear)); 2439 }, 2440 2441 /* Erase the input field and hide the date picker. */ 2442 _clearDate: function(id) { 2443 var target = $(id); 2444 this._selectDate(target, ""); 2445 }, 2446 2447 /* Update the input field with the selected date. */ 2448 _selectDate: function(id, dateStr) { 2449 var onSelect, 2450 target = $(id), 2451 inst = this._getInst(target[0]); 2452 2453 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 2454 if (inst.input) { 2455 inst.input.val(dateStr); 2456 } 2457 this._updateAlternate(inst); 2458 2459 onSelect = this._get(inst, "onSelect"); 2460 if (onSelect) { 2461 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 2462 } else if (inst.input) { 2463 inst.input.trigger("change"); // fire the change event 2464 } 2465 2466 if (inst.inline){ 2467 this._updateDatepicker(inst); 2468 } else { 2469 this._hideDatepicker(); 2470 this._lastInput = inst.input[0]; 2471 if (typeof(inst.input[0]) !== "object") { 2472 inst.input.focus(); // restore focus 2473 } 2474 this._lastInput = null; 2475 } 2476 }, 2477 2478 /* Update any alternate field to synchronise with the main field. */ 2479 _updateAlternate: function(inst) { 2480 var altFormat, date, dateStr, 2481 altField = this._get(inst, "altField"); 2482 2483 if (altField) { // update alternate field too 2484 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 2485 date = this._getDate(inst); 2486 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 2487 $(altField).each(function() { $(this).val(dateStr); }); 2488 } 2489 }, 2490 2491 /* Set as beforeShowDay function to prevent selection of weekends. 2492 * @param date Date - the date to customise 2493 * @return [boolean, string] - is this date selectable?, what is its CSS class? 2494 */ 2495 noWeekends: function(date) { 2496 var day = date.getDay(); 2497 return [(day > 0 && day < 6), ""]; 2498 }, 2499 2500 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 2501 * @param date Date - the date to get the week for 2502 * @return number - the number of the week within the year that contains this date 2503 */ 2504 iso8601Week: function(date) { 2505 var time, 2506 checkDate = new Date(date.getTime()); 2507 2508 // Find Thursday of this week starting on Monday 2509 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 2510 2511 time = checkDate.getTime(); 2512 checkDate.setMonth(0); // Compare with Jan 1 2513 checkDate.setDate(1); 2514 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 2515 }, 2516 2517 /* Parse a string value into a date object. 2518 * See formatDate below for the possible formats. 2519 * 2520 * @param format string - the expected format of the date 2521 * @param value string - the date in the above format 2522 * @param settings Object - attributes include: 2523 * shortYearCutoff number - the cutoff year for determining the century (optional) 2524 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 2525 * dayNames string[7] - names of the days from Sunday (optional) 2526 * monthNamesShort string[12] - abbreviated names of the months (optional) 2527 * monthNames string[12] - names of the months (optional) 2528 * @return Date - the extracted date value or null if value is blank 2529 */ 2530 parseDate: function (format, value, settings) { 2531 if (format == null || value == null) { 2532 throw "Invalid arguments"; 2533 } 2534 2535 value = (typeof value === "object" ? value.toString() : value + ""); 2536 if (value === "") { 2537 return null; 2538 } 2539 2540 var iFormat, dim, extra, 2541 iValue = 0, 2542 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 2543 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 2544 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 2545 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 2546 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 2547 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 2548 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 2549 year = -1, 2550 month = -1, 2551 day = -1, 2552 doy = -1, 2553 literal = false, 2554 date, 2555 // Check whether a format character is doubled 2556 lookAhead = function(match) { 2557 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 2558 if (matches) { 2559 iFormat++; 2560 } 2561 return matches; 2562 }, 2563 // Extract a number from the string value 2564 getNumber = function(match) { 2565 var isDoubled = lookAhead(match), 2566 size = (match === "@" ? 14 : (match === "!" ? 20 : 2567 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 2568 digits = new RegExp("^\\d{1," + size + "}"), 2569 num = value.substring(iValue).match(digits); 2570 if (!num) { 2571 throw "Missing number at position " + iValue; 2572 } 2573 iValue += num[0].length; 2574 return parseInt(num[0], 10); 2575 }, 2576 // Extract a name from the string value and convert to an index 2577 getName = function(match, shortNames, longNames) { 2578 var index = -1, 2579 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 2580 return [ [k, v] ]; 2581 }).sort(function (a, b) { 2582 return -(a[1].length - b[1].length); 2583 }); 2584 2585 $.each(names, function (i, pair) { 2586 var name = pair[1]; 2587 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 2588 index = pair[0]; 2589 iValue += name.length; 2590 return false; 2591 } 2592 }); 2593 if (index !== -1) { 2594 return index + 1; 2595 } else { 2596 throw "Unknown name at position " + iValue; 2597 } 2598 }, 2599 // Confirm that a literal character matches the string value 2600 checkLiteral = function() { 2601 if (value.charAt(iValue) !== format.charAt(iFormat)) { 2602 throw "Unexpected literal at position " + iValue; 2603 } 2604 iValue++; 2605 }; 2606 2607 for (iFormat = 0; iFormat < format.length; iFormat++) { 2608 if (literal) { 2609 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 2610 literal = false; 2611 } else { 2612 checkLiteral(); 2613 } 2614 } else { 2615 switch (format.charAt(iFormat)) { 2616 case "d": 2617 day = getNumber("d"); 2618 break; 2619 case "D": 2620 getName("D", dayNamesShort, dayNames); 2621 break; 2622 case "o": 2623 doy = getNumber("o"); 2624 break; 2625 case "m": 2626 month = getNumber("m"); 2627 break; 2628 case "M": 2629 month = getName("M", monthNamesShort, monthNames); 2630 break; 2631 case "y": 2632 year = getNumber("y"); 2633 break; 2634 case "@": 2635 date = new Date(getNumber("@")); 2636 year = date.getFullYear(); 2637 month = date.getMonth() + 1; 2638 day = date.getDate(); 2639 break; 2640 case "!": 2641 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 2642 year = date.getFullYear(); 2643 month = date.getMonth() + 1; 2644 day = date.getDate(); 2645 break; 2646 case "'": 2647 if (lookAhead("'")){ 2648 checkLiteral(); 2649 } else { 2650 literal = true; 2651 } 2652 break; 2653 default: 2654 checkLiteral(); 2655 } 2656 } 2657 } 2658 2659 if (iValue < value.length){ 2660 extra = value.substr(iValue); 2661 if (!/^\s+/.test(extra)) { 2662 throw "Extra/unparsed characters found in date: " + extra; 2663 } 2664 } 2665 2666 if (year === -1) { 2667 year = new Date().getFullYear(); 2668 } else if (year < 100) { 2669 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 2670 (year <= shortYearCutoff ? 0 : -100); 2671 } 2672 2673 if (doy > -1) { 2674 month = 1; 2675 day = doy; 2676 do { 2677 dim = this._getDaysInMonth(year, month - 1); 2678 if (day <= dim) { 2679 break; 2680 } 2681 month++; 2682 day -= dim; 2683 } while (true); 2684 } 2685 2686 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 2687 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 2688 throw "Invalid date"; // E.g. 31/02/00 2689 } 2690 return date; 2691 }, 2692 2693 /* Standard date formats. */ 2694 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 2695 COOKIE: "D, dd M yy", 2696 ISO_8601: "yy-mm-dd", 2697 RFC_822: "D, d M y", 2698 RFC_850: "DD, dd-M-y", 2699 RFC_1036: "D, d M y", 2700 RFC_1123: "D, d M yy", 2701 RFC_2822: "D, d M yy", 2702 RSS: "D, d M y", // RFC 822 2703 TICKS: "!", 2704 TIMESTAMP: "@", 2705 W3C: "yy-mm-dd", // ISO 8601 2706 2707 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 2708 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 2709 2710 /* Format a date object into a string value. 2711 * The format can be combinations of the following: 2712 * d - day of month (no leading zero) 2713 * dd - day of month (two digit) 2714 * o - day of year (no leading zeros) 2715 * oo - day of year (three digit) 2716 * D - day name short 2717 * DD - day name long 2718 * m - month of year (no leading zero) 2719 * mm - month of year (two digit) 2720 * M - month name short 2721 * MM - month name long 2722 * y - year (two digit) 2723 * yy - year (four digit) 2724 * @ - Unix timestamp (ms since 01/01/1970) 2725 * ! - Windows ticks (100ns since 01/01/0001) 2726 * "..." - literal text 2727 * '' - single quote 2728 * 2729 * @param format string - the desired format of the date 2730 * @param date Date - the date value to format 2731 * @param settings Object - attributes include: 2732 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 2733 * dayNames string[7] - names of the days from Sunday (optional) 2734 * monthNamesShort string[12] - abbreviated names of the months (optional) 2735 * monthNames string[12] - names of the months (optional) 2736 * @return string - the date in the above format 2737 */ 2738 formatDate: function (format, date, settings) { 2739 if (!date) { 2740 return ""; 2741 } 2742 2743 var iFormat, 2744 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 2745 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 2746 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 2747 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 2748 // Check whether a format character is doubled 2749 lookAhead = function(match) { 2750 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 2751 if (matches) { 2752 iFormat++; 2753 } 2754 return matches; 2755 }, 2756 // Format a number, with leading zero if necessary 2757 formatNumber = function(match, value, len) { 2758 var num = "" + value; 2759 if (lookAhead(match)) { 2760 while (num.length < len) { 2761 num = "0" + num; 2762 } 2763 } 2764 return num; 2765 }, 2766 // Format a name, short or long as requested 2767 formatName = function(match, value, shortNames, longNames) { 2768 return (lookAhead(match) ? longNames[value] : shortNames[value]); 2769 }, 2770 output = "", 2771 literal = false; 2772 2773 if (date) { 2774 for (iFormat = 0; iFormat < format.length; iFormat++) { 2775 if (literal) { 2776 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 2777 literal = false; 2778 } else { 2779 output += format.charAt(iFormat); 2780 } 2781 } else { 2782 switch (format.charAt(iFormat)) { 2783 case "d": 2784 output += formatNumber("d", date.getDate(), 2); 2785 break; 2786 case "D": 2787 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 2788 break; 2789 case "o": 2790 output += formatNumber("o", 2791 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 2792 break; 2793 case "m": 2794 output += formatNumber("m", date.getMonth() + 1, 2); 2795 break; 2796 case "M": 2797 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 2798 break; 2799 case "y": 2800 output += (lookAhead("y") ? date.getFullYear() : 2801 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 2802 break; 2803 case "@": 2804 output += date.getTime(); 2805 break; 2806 case "!": 2807 output += date.getTime() * 10000 + this._ticksTo1970; 2808 break; 2809 case "'": 2810 if (lookAhead("'")) { 2811 output += "'"; 2812 } else { 2813 literal = true; 2814 } 2815 break; 2816 default: 2817 output += format.charAt(iFormat); 2818 } 2819 } 2820 } 2821 } 2822 return output; 2823 }, 2824 2825 /* Extract all possible characters from the date format. */ 2826 _possibleChars: function (format) { 2827 var iFormat, 2828 chars = "", 2829 literal = false, 2830 // Check whether a format character is doubled 2831 lookAhead = function(match) { 2832 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 2833 if (matches) { 2834 iFormat++; 2835 } 2836 return matches; 2837 }; 2838 2839 for (iFormat = 0; iFormat < format.length; iFormat++) { 2840 if (literal) { 2841 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 2842 literal = false; 2843 } else { 2844 chars += format.charAt(iFormat); 2845 } 2846 } else { 2847 switch (format.charAt(iFormat)) { 2848 case "d": case "m": case "y": case "@": 2849 chars += "0123456789"; 2850 break; 2851 case "D": case "M": 2852 return null; // Accept anything 2853 case "'": 2854 if (lookAhead("'")) { 2855 chars += "'"; 2856 } else { 2857 literal = true; 2858 } 2859 break; 2860 default: 2861 chars += format.charAt(iFormat); 2862 } 2863 } 2864 } 2865 return chars; 2866 }, 2867 2868 /* Get a setting value, defaulting if necessary. */ 2869 _get: function(inst, name) { 2870 return inst.settings[name] !== undefined ? 2871 inst.settings[name] : this._defaults[name]; 2872 }, 2873 2874 /* Parse existing date and initialise date picker. */ 2875 _setDateFromField: function(inst, noDefault) { 2876 if (inst.input.val() === inst.lastVal) { 2877 return; 2878 } 2879 2880 var dateFormat = this._get(inst, "dateFormat"), 2881 dates = inst.lastVal = inst.input ? inst.input.val() : null, 2882 defaultDate = this._getDefaultDate(inst), 2883 date = defaultDate, 2884 settings = this._getFormatConfig(inst); 2885 2886 try { 2887 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 2888 } catch (event) { 2889 dates = (noDefault ? "" : dates); 2890 } 2891 inst.selectedDay = date.getDate(); 2892 inst.drawMonth = inst.selectedMonth = date.getMonth(); 2893 inst.drawYear = inst.selectedYear = date.getFullYear(); 2894 inst.currentDay = (dates ? date.getDate() : 0); 2895 inst.currentMonth = (dates ? date.getMonth() : 0); 2896 inst.currentYear = (dates ? date.getFullYear() : 0); 2897 this._adjustInstDate(inst); 2898 }, 2899 2900 /* Retrieve the default date shown on opening. */ 2901 _getDefaultDate: function(inst) { 2902 return this._restrictMinMax(inst, 2903 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 2904 }, 2905 2906 /* A date may be specified as an exact value or a relative one. */ 2907 _determineDate: function(inst, date, defaultDate) { 2908 var offsetNumeric = function(offset) { 2909 var date = new Date(); 2910 date.setDate(date.getDate() + offset); 2911 return date; 2912 }, 2913 offsetString = function(offset) { 2914 try { 2915 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 2916 offset, $.datepicker._getFormatConfig(inst)); 2917 } 2918 catch (e) { 2919 // Ignore 2920 } 2921 2922 var date = (offset.toLowerCase().match(/^c/) ? 2923 $.datepicker._getDate(inst) : null) || new Date(), 2924 year = date.getFullYear(), 2925 month = date.getMonth(), 2926 day = date.getDate(), 2927 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 2928 matches = pattern.exec(offset); 2929 2930 while (matches) { 2931 switch (matches[2] || "d") { 2932 case "d" : case "D" : 2933 day += parseInt(matches[1],10); break; 2934 case "w" : case "W" : 2935 day += parseInt(matches[1],10) * 7; break; 2936 case "m" : case "M" : 2937 month += parseInt(matches[1],10); 2938 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 2939 break; 2940 case "y": case "Y" : 2941 year += parseInt(matches[1],10); 2942 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 2943 break; 2944 } 2945 matches = pattern.exec(offset); 2946 } 2947 return new Date(year, month, day); 2948 }, 2949 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 2950 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 2951 2952 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 2953 if (newDate) { 2954 newDate.setHours(0); 2955 newDate.setMinutes(0); 2956 newDate.setSeconds(0); 2957 newDate.setMilliseconds(0); 2958 } 2959 return this._daylightSavingAdjust(newDate); 2960 }, 2961 2962 /* Handle switch to/from daylight saving. 2963 * Hours may be non-zero on daylight saving cut-over: 2964 * > 12 when midnight changeover, but then cannot generate 2965 * midnight datetime, so jump to 1AM, otherwise reset. 2966 * @param date (Date) the date to check 2967 * @return (Date) the corrected date 2968 */ 2969 _daylightSavingAdjust: function(date) { 2970 if (!date) { 2971 return null; 2972 } 2973 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 2974 return date; 2975 }, 2976 2977 /* Set the date(s) directly. */ 2978 _setDate: function(inst, date, noChange) { 2979 var clear = !date, 2980 origMonth = inst.selectedMonth, 2981 origYear = inst.selectedYear, 2982 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 2983 2984 inst.selectedDay = inst.currentDay = newDate.getDate(); 2985 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 2986 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 2987 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 2988 this._notifyChange(inst); 2989 } 2990 this._adjustInstDate(inst); 2991 if (inst.input) { 2992 inst.input.val(clear ? "" : this._formatDate(inst)); 2993 } 2994 }, 2995 2996 /* Retrieve the date(s) directly. */ 2997 _getDate: function(inst) { 2998 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 2999 this._daylightSavingAdjust(new Date( 3000 inst.currentYear, inst.currentMonth, inst.currentDay))); 3001 return startDate; 3002 }, 3003 3004 /* Attach the onxxx handlers. These are declared statically so 3005 * they work with static code transformers like Caja. 3006 */ 3007 _attachHandlers: function(inst) { 3008 var stepMonths = this._get(inst, "stepMonths"), 3009 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 3010 inst.dpDiv.find("[data-handler]").map(function () { 3011 var handler = { 3012 prev: function () { 3013 $.datepicker._adjustDate(id, -stepMonths, "M"); 3014 }, 3015 next: function () { 3016 $.datepicker._adjustDate(id, +stepMonths, "M"); 3017 }, 3018 hide: function () { 3019 $.datepicker._hideDatepicker(); 3020 }, 3021 today: function () { 3022 $.datepicker._gotoToday(id); 3023 }, 3024 selectDay: function () { 3025 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 3026 return false; 3027 }, 3028 selectMonth: function () { 3029 $.datepicker._selectMonthYear(id, this, "M"); 3030 return false; 3031 }, 3032 selectYear: function () { 3033 $.datepicker._selectMonthYear(id, this, "Y"); 3034 return false; 3035 } 3036 }; 3037 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 3038 }); 3039 }, 3040 3041 /* Generate the HTML for the current state of the date picker. */ 3042 _generateHTML: function(inst) { 3043 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 3044 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 3045 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 3046 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 3047 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 3048 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 3049 tempDate = new Date(), 3050 today = this._daylightSavingAdjust( 3051 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 3052 isRTL = this._get(inst, "isRTL"), 3053 showButtonPanel = this._get(inst, "showButtonPanel"), 3054 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 3055 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 3056 numMonths = this._getNumberOfMonths(inst), 3057 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 3058 stepMonths = this._get(inst, "stepMonths"), 3059 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 3060 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 3061 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 3062 minDate = this._getMinMaxDate(inst, "min"), 3063 maxDate = this._getMinMaxDate(inst, "max"), 3064 drawMonth = inst.drawMonth - showCurrentAtPos, 3065 drawYear = inst.drawYear; 3066 3067 if (drawMonth < 0) { 3068 drawMonth += 12; 3069 drawYear--; 3070 } 3071 if (maxDate) { 3072 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 3073 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 3074 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 3075 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 3076 drawMonth--; 3077 if (drawMonth < 0) { 3078 drawMonth = 11; 3079 drawYear--; 3080 } 3081 } 3082 } 3083 inst.drawMonth = drawMonth; 3084 inst.drawYear = drawYear; 3085 3086 prevText = this._get(inst, "prevText"); 3087 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 3088 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 3089 this._getFormatConfig(inst))); 3090 3091 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 3092 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 3093 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 3094 (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>")); 3095 3096 nextText = this._get(inst, "nextText"); 3097 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 3098 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 3099 this._getFormatConfig(inst))); 3100 3101 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 3102 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 3103 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 3104 (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>")); 3105 3106 currentText = this._get(inst, "currentText"); 3107 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 3108 currentText = (!navigationAsDateFormat ? currentText : 3109 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 3110 3111 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'>" + 3112 this._get(inst, "closeText") + "</button>" : ""); 3113 3114 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 3115 (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'" + 3116 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 3117 3118 firstDay = parseInt(this._get(inst, "firstDay"),10); 3119 firstDay = (isNaN(firstDay) ? 0 : firstDay); 3120 3121 showWeek = this._get(inst, "showWeek"); 3122 dayNames = this._get(inst, "dayNames"); 3123 dayNamesMin = this._get(inst, "dayNamesMin"); 3124 monthNames = this._get(inst, "monthNames"); 3125 monthNamesShort = this._get(inst, "monthNamesShort"); 3126 beforeShowDay = this._get(inst, "beforeShowDay"); 3127 showOtherMonths = this._get(inst, "showOtherMonths"); 3128 selectOtherMonths = this._get(inst, "selectOtherMonths"); 3129 defaultDate = this._getDefaultDate(inst); 3130 html = ""; 3131 dow; 3132 for (row = 0; row < numMonths[0]; row++) { 3133 group = ""; 3134 this.maxRows = 4; 3135 for (col = 0; col < numMonths[1]; col++) { 3136 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 3137 cornerClass = " ui-corner-all"; 3138 calender = ""; 3139 if (isMultiMonth) { 3140 calender += "<div class='ui-datepicker-group"; 3141 if (numMonths[1] > 1) { 3142 switch (col) { 3143 case 0: calender += " ui-datepicker-group-first"; 3144 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 3145 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 3146 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 3147 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 3148 } 3149 } 3150 calender += "'>"; 3151 } 3152 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 3153 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 3154 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 3155 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 3156 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 3157 "</div><table class='ui-datepicker-calendar'><thead>" + 3158 "<tr>"; 3159 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 3160 for (dow = 0; dow < 7; dow++) { // days of the week 3161 day = (dow + firstDay) % 7; 3162 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 3163 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 3164 } 3165 calender += thead + "</tr></thead><tbody>"; 3166 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 3167 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 3168 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 3169 } 3170 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 3171 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 3172 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 3173 this.maxRows = numRows; 3174 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 3175 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 3176 calender += "<tr>"; 3177 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 3178 this._get(inst, "calculateWeek")(printDate) + "</td>"); 3179 for (dow = 0; dow < 7; dow++) { // create date picker days 3180 daySettings = (beforeShowDay ? 3181 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 3182 otherMonth = (printDate.getMonth() !== drawMonth); 3183 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 3184 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 3185 tbody += "<td class='" + 3186 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 3187 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 3188 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 3189 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 3190 // or defaultDate is current printedDate and defaultDate is selectedDate 3191 " " + this._dayOverClass : "") + // highlight selected day 3192 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 3193 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 3194 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 3195 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 3196 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 3197 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 3198 (otherMonth && !showOtherMonths ? " " : // display for other months 3199 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 3200 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 3201 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 3202 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 3203 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 3204 printDate.setDate(printDate.getDate() + 1); 3205 printDate = this._daylightSavingAdjust(printDate); 3206 } 3207 calender += tbody + "</tr>"; 3208 } 3209 drawMonth++; 3210 if (drawMonth > 11) { 3211 drawMonth = 0; 3212 drawYear++; 3213 } 3214 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 3215 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 3216 group += calender; 3217 } 3218 html += group; 3219 } 3220 html += buttonPanel; 3221 inst._keyEvent = false; 3222 return html; 3223 }, 3224 3225 /* Generate the month and year header. */ 3226 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 3227 secondary, monthNames, monthNamesShort) { 3228 3229 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 3230 changeMonth = this._get(inst, "changeMonth"), 3231 changeYear = this._get(inst, "changeYear"), 3232 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 3233 html = "<div class='ui-datepicker-title'>", 3234 monthHtml = ""; 3235 3236 // month selection 3237 if (secondary || !changeMonth) { 3238 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 3239 } else { 3240 inMinYear = (minDate && minDate.getFullYear() === drawYear); 3241 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 3242 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 3243 for ( month = 0; month < 12; month++) { 3244 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 3245 monthHtml += "<option value='" + month + "'" + 3246 (month === drawMonth ? " selected='selected'" : "") + 3247 ">" + monthNamesShort[month] + "</option>"; 3248 } 3249 } 3250 monthHtml += "</select>"; 3251 } 3252 3253 if (!showMonthAfterYear) { 3254 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 3255 } 3256 3257 // year selection 3258 if ( !inst.yearshtml ) { 3259 inst.yearshtml = ""; 3260 if (secondary || !changeYear) { 3261 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 3262 } else { 3263 // determine range of years to display 3264 years = this._get(inst, "yearRange").split(":"); 3265 thisYear = new Date().getFullYear(); 3266 determineYear = function(value) { 3267 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 3268 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 3269 parseInt(value, 10))); 3270 return (isNaN(year) ? thisYear : year); 3271 }; 3272 year = determineYear(years[0]); 3273 endYear = Math.max(year, determineYear(years[1] || "")); 3274 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 3275 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 3276 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 3277 for (; year <= endYear; year++) { 3278 inst.yearshtml += "<option value='" + year + "'" + 3279 (year === drawYear ? " selected='selected'" : "") + 3280 ">" + year + "</option>"; 3281 } 3282 inst.yearshtml += "</select>"; 3283 3284 html += inst.yearshtml; 3285 inst.yearshtml = null; 3286 } 3287 } 3288 3289 html += this._get(inst, "yearSuffix"); 3290 if (showMonthAfterYear) { 3291 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 3292 } 3293 html += "</div>"; // Close datepicker_header 3294 return html; 3295 }, 3296 3297 /* Adjust one of the date sub-fields. */ 3298 _adjustInstDate: function(inst, offset, period) { 3299 var year = inst.drawYear + (period === "Y" ? offset : 0), 3300 month = inst.drawMonth + (period === "M" ? offset : 0), 3301 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 3302 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 3303 3304 inst.selectedDay = date.getDate(); 3305 inst.drawMonth = inst.selectedMonth = date.getMonth(); 3306 inst.drawYear = inst.selectedYear = date.getFullYear(); 3307 if (period === "M" || period === "Y") { 3308 this._notifyChange(inst); 3309 } 3310 }, 3311 3312 /* Ensure a date is within any min/max bounds. */ 3313 _restrictMinMax: function(inst, date) { 3314 var minDate = this._getMinMaxDate(inst, "min"), 3315 maxDate = this._getMinMaxDate(inst, "max"), 3316 newDate = (minDate && date < minDate ? minDate : date); 3317 return (maxDate && newDate > maxDate ? maxDate : newDate); 3318 }, 3319 3320 /* Notify change of month/year. */ 3321 _notifyChange: function(inst) { 3322 var onChange = this._get(inst, "onChangeMonthYear"); 3323 if (onChange) { 3324 onChange.apply((inst.input ? inst.input[0] : null), 3325 [inst.selectedYear, inst.selectedMonth + 1, inst]); 3326 } 3327 }, 3328 3329 /* Determine the number of months to show. */ 3330 _getNumberOfMonths: function(inst) { 3331 var numMonths = this._get(inst, "numberOfMonths"); 3332 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 3333 }, 3334 3335 /* Determine the current maximum date - ensure no time components are set. */ 3336 _getMinMaxDate: function(inst, minMax) { 3337 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 3338 }, 3339 3340 /* Find the number of days in a given month. */ 3341 _getDaysInMonth: function(year, month) { 3342 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 3343 }, 3344 3345 /* Find the day of the week of the first of a month. */ 3346 _getFirstDayOfMonth: function(year, month) { 3347 return new Date(year, month, 1).getDay(); 3348 }, 3349 3350 /* Determines if we should allow a "next/prev" month display change. */ 3351 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 3352 var numMonths = this._getNumberOfMonths(inst), 3353 date = this._daylightSavingAdjust(new Date(curYear, 3354 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 3355 3356 if (offset < 0) { 3357 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 3358 } 3359 return this._isInRange(inst, date); 3360 }, 3361 3362 /* Is the given date in the accepted range? */ 3363 _isInRange: function(inst, date) { 3364 var yearSplit, currentYear, 3365 minDate = this._getMinMaxDate(inst, "min"), 3366 maxDate = this._getMinMaxDate(inst, "max"), 3367 minYear = null, 3368 maxYear = null, 3369 years = this._get(inst, "yearRange"); 3370 if (years){ 3371 yearSplit = years.split(":"); 3372 currentYear = new Date().getFullYear(); 3373 minYear = parseInt(yearSplit[0], 10); 3374 maxYear = parseInt(yearSplit[1], 10); 3375 if ( yearSplit[0].match(/[+\-].*/) ) { 3376 minYear += currentYear; 3377 } 3378 if ( yearSplit[1].match(/[+\-].*/) ) { 3379 maxYear += currentYear; 3380 } 3381 } 3382 3383 return ((!minDate || date.getTime() >= minDate.getTime()) && 3384 (!maxDate || date.getTime() <= maxDate.getTime()) && 3385 (!minYear || date.getFullYear() >= minYear) && 3386 (!maxYear || date.getFullYear() <= maxYear)); 3387 }, 3388 3389 /* Provide the configuration settings for formatting/parsing. */ 3390 _getFormatConfig: function(inst) { 3391 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 3392 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 3393 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 3394 return {shortYearCutoff: shortYearCutoff, 3395 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 3396 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 3397 }, 3398 3399 /* Format the given date for display. */ 3400 _formatDate: function(inst, day, month, year) { 3401 if (!day) { 3402 inst.currentDay = inst.selectedDay; 3403 inst.currentMonth = inst.selectedMonth; 3404 inst.currentYear = inst.selectedYear; 3405 } 3406 var date = (day ? (typeof day === "object" ? day : 3407 this._daylightSavingAdjust(new Date(year, month, day))) : 3408 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 3409 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 3410 } 3411}); 3412 3413/* 3414 * Bind hover events for datepicker elements. 3415 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 3416 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 3417 */ 3418function bindHover(dpDiv) { 3419 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 3420 return dpDiv.delegate(selector, "mouseout", function() { 3421 $(this).removeClass("ui-state-hover"); 3422 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 3423 $(this).removeClass("ui-datepicker-prev-hover"); 3424 } 3425 if (this.className.indexOf("ui-datepicker-next") !== -1) { 3426 $(this).removeClass("ui-datepicker-next-hover"); 3427 } 3428 }) 3429 .delegate(selector, "mouseover", function(){ 3430 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 3431 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 3432 $(this).addClass("ui-state-hover"); 3433 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 3434 $(this).addClass("ui-datepicker-prev-hover"); 3435 } 3436 if (this.className.indexOf("ui-datepicker-next") !== -1) { 3437 $(this).addClass("ui-datepicker-next-hover"); 3438 } 3439 } 3440 }); 3441} 3442 3443/* jQuery extend now ignores nulls! */ 3444function extendRemove(target, props) { 3445 $.extend(target, props); 3446 for (var name in props) { 3447 if (props[name] == null) { 3448 target[name] = props[name]; 3449 } 3450 } 3451 return target; 3452} 3453 3454/* Invoke the datepicker functionality. 3455 @param options string - a command, optionally followed by additional parameters or 3456 Object - settings for attaching new datepicker functionality 3457 @return jQuery object */ 3458$.fn.datepicker = function(options){ 3459 3460 /* Verify an empty collection wasn't passed - Fixes #6976 */ 3461 if ( !this.length ) { 3462 return this; 3463 } 3464 3465 /* Initialise the date picker. */ 3466 if (!$.datepicker.initialized) { 3467 $(document).mousedown($.datepicker._checkExternalClick); 3468 $.datepicker.initialized = true; 3469 } 3470 3471 /* Append datepicker main container to body if not exist. */ 3472 if ($("#"+$.datepicker._mainDivId).length === 0) { 3473 $("body").append($.datepicker.dpDiv); 3474 } 3475 3476 var otherArgs = Array.prototype.slice.call(arguments, 1); 3477 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 3478 return $.datepicker["_" + options + "Datepicker"]. 3479 apply($.datepicker, [this[0]].concat(otherArgs)); 3480 } 3481 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 3482 return $.datepicker["_" + options + "Datepicker"]. 3483 apply($.datepicker, [this[0]].concat(otherArgs)); 3484 } 3485 return this.each(function() { 3486 typeof options === "string" ? 3487 $.datepicker["_" + options + "Datepicker"]. 3488 apply($.datepicker, [this].concat(otherArgs)) : 3489 $.datepicker._attachDatepicker(this, options); 3490 }); 3491}; 3492 3493$.datepicker = new Datepicker(); // singleton instance 3494$.datepicker.initialized = false; 3495$.datepicker.uuid = new Date().getTime(); 3496$.datepicker.version = "1.10.
34964"; 3497 3498})(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.