Make WordPress Core

Changeset 29847


Ignore:
Timestamp:
10/07/2014 03:27:56 PM (10 years ago)
Author:
ocean90
Message:

Update jQuery UI to 1.11.1.

Because jQUI's build process no longer provides individual minified files we need some additional changes:

  • Rename all files, remove the "jquery.ui." prefix. Add old files to $_old_files.
  • Add and use non-minified files in /src.
  • Add grunt task to minify jQuery UI files.
  • (Non-minified files will not be shipped.)

Changelogs:

props Fab1en, ocean90.
fixes #29833.

Location:
trunk
Files:
3 added
3 edited
34 moved

Legend:

Unmodified
Added
Removed
  • trunk/Gruntfile.js

    r29795 r29847  
    5959                            '!wp-includes/js/underscore.js',
    6060                            '!wp-includes/js/jquery/jquery.masonry.js',
     61                            '!wp-includes/js/jquery/ui/*.js',
    6162                            '!wp-includes/js/tinymce/tinymce.js',
    6263                            '!wp-includes/version.php' // Exclude version.php
     
    352353                    '!wp-includes/js/zxcvbn.min.js'
    353354                ]
     355            },
     356            jqueryui: {
     357                options: {
     358                    preserveComments: 'some'
     359                },
     360                expand: true,
     361                cwd: SOURCE_DIR,
     362                dest: BUILD_DIR,
     363                ext: '.min.js',
     364                src: ['wp-includes/js/jquery/ui/*.js']
    354365            }
    355366        },
     
    468479    // Build task.
    469480    grunt.registerTask('build', ['clean:all', 'copy:all', 'cssmin:core', 'colors', 'rtl', 'cssmin:rtl', 'cssmin:colors',
    470         'uglify:core', 'concat:tinymce', 'compress:tinymce', 'clean:tinymce', 'jsvalidate:build']);
     481        'uglify:core', 'uglify:jqueryui', 'concat:tinymce', 'compress:tinymce', 'clean:tinymce', 'jsvalidate:build']);
    471482
    472483    // Testing tasks.
  • trunk/src/wp-admin/includes/update-core.php

    r29206 r29847  
    660660'wp-includes/js/tinymce/plugins/paste/pastetext.htm',
    661661'wp-includes/js/tinymce/langs/wp-langs.php',
     662// 4.1
     663'wp-includes/js/jquery/ui/jquery.ui.accordion.min.js',
     664'wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js',
     665'wp-includes/js/jquery/ui/jquery.ui.button.min.js',
     666'wp-includes/js/jquery/ui/jquery.ui.core.min.js',
     667'wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js',
     668'wp-includes/js/jquery/ui/jquery.ui.dialog.min.js',
     669'wp-includes/js/jquery/ui/jquery.ui.draggable.min.js',
     670'wp-includes/js/jquery/ui/jquery.ui.droppable.min.js',
     671'wp-includes/js/jquery/ui/jquery.ui.effect-blind.min.js',
     672'wp-includes/js/jquery/ui/jquery.ui.effect-bounce.min.js',
     673'wp-includes/js/jquery/ui/jquery.ui.effect-clip.min.js',
     674'wp-includes/js/jquery/ui/jquery.ui.effect-drop.min.js',
     675'wp-includes/js/jquery/ui/jquery.ui.effect-explode.min.js',
     676'wp-includes/js/jquery/ui/jquery.ui.effect-fade.min.js',
     677'wp-includes/js/jquery/ui/jquery.ui.effect-fold.min.js',
     678'wp-includes/js/jquery/ui/jquery.ui.effect-highlight.min.js',
     679'wp-includes/js/jquery/ui/jquery.ui.effect-pulsate.min.js',
     680'wp-includes/js/jquery/ui/jquery.ui.effect-scale.min.js',
     681'wp-includes/js/jquery/ui/jquery.ui.effect-shake.min.js',
     682'wp-includes/js/jquery/ui/jquery.ui.effect-slide.min.js',
     683'wp-includes/js/jquery/ui/jquery.ui.effect-transfer.min.js',
     684'wp-includes/js/jquery/ui/jquery.ui.effect.min.js',
     685'wp-includes/js/jquery/ui/jquery.ui.menu.min.js',
     686'wp-includes/js/jquery/ui/jquery.ui.mouse.min.js',
     687'wp-includes/js/jquery/ui/jquery.ui.position.min.js',
     688'wp-includes/js/jquery/ui/jquery.ui.progressbar.min.js',
     689'wp-includes/js/jquery/ui/jquery.ui.resizable.min.js',
     690'wp-includes/js/jquery/ui/jquery.ui.selectable.min.js',
     691'wp-includes/js/jquery/ui/jquery.ui.slider.min.js',
     692'wp-includes/js/jquery/ui/jquery.ui.sortable.min.js',
     693'wp-includes/js/jquery/ui/jquery.ui.spinner.min.js',
     694'wp-includes/js/jquery/ui/jquery.ui.tabs.min.js',
     695'wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js',
     696'wp-includes/js/jquery/ui/jquery.ui.widget.min.js',
    662697);
    663698
  • trunk/src/wp-includes/js/jquery/ui/accordion.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(t){var e=0,i={},s={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",s.height=s.paddingTop=s.paddingBottom=s.borderTopWidth=s.borderBottomWidth="show",t.widget("ui.accordion",{version:"1.10.4",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t(),content:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("<span>").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),undefined):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),"disabled"===t&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e),undefined)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),a=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(t(e.target).attr("tabIndex",-1),t(a).attr("tabIndex",0),a.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,s=this.options,n=s.heightStyle,a=this.element.parent(),o=this.accordionId="ui-accordion-"+(this.element.attr("id")||++e);this.active=this._findActive(s.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(e){var i=t(this),s=i.attr("id"),n=i.next(),a=n.attr("id");s||(s=o+"-header-"+e,i.attr("id",s)),a||(a=o+"-panel-"+e,n.attr("id",a)),i.attr("aria-controls",a),n.attr("aria-labelledby",s)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(s.event),"fill"===n?(i=a.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.headers.each(function(){i-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===n&&(i=0,this.headers.next().each(function(){i=Math.max(i,t(this).css("height","").height())}).height(i))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n[0]===s[0],o=a&&i.collapsible,r=o?t():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:o?t():n,newPanel:r};e.preventDefault(),a&&!i.collapsible||this._trigger("beforeActivate",e,l)===!1||(i.active=o?!1:this.headers.index(n),this.active=a?t():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),a||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true",tabIndex:0,"aria-expanded":"true"})},_animate:function(t,e,n){var a,o,r,h=this,l=0,c=t.length&&(!e.length||t.index()<e.index()),u=this.options.animate||{},d=c&&u.down||u,p=function(){h._toggleComplete(n)};return"number"==typeof d&&(r=d),"string"==typeof d&&(o=d),o=o||d.easing||u.easing,r=r||d.duration||u.duration,e.length?t.length?(a=t.show().outerHeight(),e.animate(i,{duration:r,easing:o,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(s,{duration:r,easing:o,complete:p,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(a-e.outerHeight()-l),l=0)}}),undefined):e.animate(i,r,o,p):t.animate(s,r,o,p)},_toggleComplete:function(t){var e=t.oldPanel;e.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}})})(jQuery);
     1/*!
     2 * jQuery UI Accordion 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/accordion/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define([
     16            "jquery",
     17            "./core",
     18            "./widget"
     19        ], factory );
     20    } else {
     21
     22        // Browser globals
     23        factory( jQuery );
     24    }
     25}(function( $ ) {
     26
     27return $.widget( "ui.accordion", {
     28    version: "1.11.1",
     29    options: {
     30        active: 0,
     31        animate: {},
     32        collapsible: false,
     33        event: "click",
     34        header: "> li > :first-child,> :not(li):even",
     35        heightStyle: "auto",
     36        icons: {
     37            activeHeader: "ui-icon-triangle-1-s",
     38            header: "ui-icon-triangle-1-e"
     39        },
     40
     41        // callbacks
     42        activate: null,
     43        beforeActivate: null
     44    },
     45
     46    hideProps: {
     47        borderTopWidth: "hide",
     48        borderBottomWidth: "hide",
     49        paddingTop: "hide",
     50        paddingBottom: "hide",
     51        height: "hide"
     52    },
     53
     54    showProps: {
     55        borderTopWidth: "show",
     56        borderBottomWidth: "show",
     57        paddingTop: "show",
     58        paddingBottom: "show",
     59        height: "show"
     60    },
     61
     62    _create: function() {
     63        var options = this.options;
     64        this.prevShow = this.prevHide = $();
     65        this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
     66            // ARIA
     67            .attr( "role", "tablist" );
     68
     69        // don't allow collapsible: false and active: false / null
     70        if ( !options.collapsible && (options.active === false || options.active == null) ) {
     71            options.active = 0;
     72        }
     73
     74        this._processPanels();
     75        // handle negative values
     76        if ( options.active < 0 ) {
     77            options.active += this.headers.length;
     78        }
     79        this._refresh();
     80    },
     81
     82    _getCreateEventData: function() {
     83        return {
     84            header: this.active,
     85            panel: !this.active.length ? $() : this.active.next()
     86        };
     87    },
     88
     89    _createIcons: function() {
     90        var icons = this.options.icons;
     91        if ( icons ) {
     92            $( "<span>" )
     93                .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
     94                .prependTo( this.headers );
     95            this.active.children( ".ui-accordion-header-icon" )
     96                .removeClass( icons.header )
     97                .addClass( icons.activeHeader );
     98            this.headers.addClass( "ui-accordion-icons" );
     99        }
     100    },
     101
     102    _destroyIcons: function() {
     103        this.headers
     104            .removeClass( "ui-accordion-icons" )
     105            .children( ".ui-accordion-header-icon" )
     106                .remove();
     107    },
     108
     109    _destroy: function() {
     110        var contents;
     111
     112        // clean up main element
     113        this.element
     114            .removeClass( "ui-accordion ui-widget ui-helper-reset" )
     115            .removeAttr( "role" );
     116
     117        // clean up headers
     118        this.headers
     119            .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
     120                "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
     121            .removeAttr( "role" )
     122            .removeAttr( "aria-expanded" )
     123            .removeAttr( "aria-selected" )
     124            .removeAttr( "aria-controls" )
     125            .removeAttr( "tabIndex" )
     126            .removeUniqueId();
     127
     128        this._destroyIcons();
     129
     130        // clean up content panels
     131        contents = this.headers.next()
     132            .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
     133                "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
     134            .css( "display", "" )
     135            .removeAttr( "role" )
     136            .removeAttr( "aria-hidden" )
     137            .removeAttr( "aria-labelledby" )
     138            .removeUniqueId();
     139
     140        if ( this.options.heightStyle !== "content" ) {
     141            contents.css( "height", "" );
     142        }
     143    },
     144
     145    _setOption: function( key, value ) {
     146        if ( key === "active" ) {
     147            // _activate() will handle invalid values and update this.options
     148            this._activate( value );
     149            return;
     150        }
     151
     152        if ( key === "event" ) {
     153            if ( this.options.event ) {
     154                this._off( this.headers, this.options.event );
     155            }
     156            this._setupEvents( value );
     157        }
     158
     159        this._super( key, value );
     160
     161        // setting collapsible: false while collapsed; open first panel
     162        if ( key === "collapsible" && !value && this.options.active === false ) {
     163            this._activate( 0 );
     164        }
     165
     166        if ( key === "icons" ) {
     167            this._destroyIcons();
     168            if ( value ) {
     169                this._createIcons();
     170            }
     171        }
     172
     173        // #5332 - opacity doesn't cascade to positioned elements in IE
     174        // so we need to add the disabled class to the headers and panels
     175        if ( key === "disabled" ) {
     176            this.element
     177                .toggleClass( "ui-state-disabled", !!value )
     178                .attr( "aria-disabled", value );
     179            this.headers.add( this.headers.next() )
     180                .toggleClass( "ui-state-disabled", !!value );
     181        }
     182    },
     183
     184    _keydown: function( event ) {
     185        if ( event.altKey || event.ctrlKey ) {
     186            return;
     187        }
     188
     189        var keyCode = $.ui.keyCode,
     190            length = this.headers.length,
     191            currentIndex = this.headers.index( event.target ),
     192            toFocus = false;
     193
     194        switch ( event.keyCode ) {
     195            case keyCode.RIGHT:
     196            case keyCode.DOWN:
     197                toFocus = this.headers[ ( currentIndex + 1 ) % length ];
     198                break;
     199            case keyCode.LEFT:
     200            case keyCode.UP:
     201                toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
     202                break;
     203            case keyCode.SPACE:
     204            case keyCode.ENTER:
     205                this._eventHandler( event );
     206                break;
     207            case keyCode.HOME:
     208                toFocus = this.headers[ 0 ];
     209                break;
     210            case keyCode.END:
     211                toFocus = this.headers[ length - 1 ];
     212                break;
     213        }
     214
     215        if ( toFocus ) {
     216            $( event.target ).attr( "tabIndex", -1 );
     217            $( toFocus ).attr( "tabIndex", 0 );
     218            toFocus.focus();
     219            event.preventDefault();
     220        }
     221    },
     222
     223    _panelKeyDown: function( event ) {
     224        if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
     225            $( event.currentTarget ).prev().focus();
     226        }
     227    },
     228
     229    refresh: function() {
     230        var options = this.options;
     231        this._processPanels();
     232
     233        // was collapsed or no panel
     234        if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
     235            options.active = false;
     236            this.active = $();
     237        // active false only when collapsible is true
     238        } else if ( options.active === false ) {
     239            this._activate( 0 );
     240        // was active, but active panel is gone
     241        } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
     242            // all remaining panel are disabled
     243            if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
     244                options.active = false;
     245                this.active = $();
     246            // activate previous panel
     247            } else {
     248                this._activate( Math.max( 0, options.active - 1 ) );
     249            }
     250        // was active, active panel still exists
     251        } else {
     252            // make sure active index is correct
     253            options.active = this.headers.index( this.active );
     254        }
     255
     256        this._destroyIcons();
     257
     258        this._refresh();
     259    },
     260
     261    _processPanels: function() {
     262        this.headers = this.element.find( this.options.header )
     263            .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
     264
     265        this.headers.next()
     266            .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
     267            .filter( ":not(.ui-accordion-content-active)" )
     268            .hide();
     269    },
     270
     271    _refresh: function() {
     272        var maxHeight,
     273            options = this.options,
     274            heightStyle = options.heightStyle,
     275            parent = this.element.parent();
     276
     277        this.active = this._findActive( options.active )
     278            .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
     279            .removeClass( "ui-corner-all" );
     280        this.active.next()
     281            .addClass( "ui-accordion-content-active" )
     282            .show();
     283
     284        this.headers
     285            .attr( "role", "tab" )
     286            .each(function() {
     287                var header = $( this ),
     288                    headerId = header.uniqueId().attr( "id" ),
     289                    panel = header.next(),
     290                    panelId = panel.uniqueId().attr( "id" );
     291                header.attr( "aria-controls", panelId );
     292                panel.attr( "aria-labelledby", headerId );
     293            })
     294            .next()
     295                .attr( "role", "tabpanel" );
     296
     297        this.headers
     298            .not( this.active )
     299            .attr({
     300                "aria-selected": "false",
     301                "aria-expanded": "false",
     302                tabIndex: -1
     303            })
     304            .next()
     305                .attr({
     306                    "aria-hidden": "true"
     307                })
     308                .hide();
     309
     310        // make sure at least one header is in the tab order
     311        if ( !this.active.length ) {
     312            this.headers.eq( 0 ).attr( "tabIndex", 0 );
     313        } else {
     314            this.active.attr({
     315                "aria-selected": "true",
     316                "aria-expanded": "true",
     317                tabIndex: 0
     318            })
     319            .next()
     320                .attr({
     321                    "aria-hidden": "false"
     322                });
     323        }
     324
     325        this._createIcons();
     326
     327        this._setupEvents( options.event );
     328
     329        if ( heightStyle === "fill" ) {
     330            maxHeight = parent.height();
     331            this.element.siblings( ":visible" ).each(function() {
     332                var elem = $( this ),
     333                    position = elem.css( "position" );
     334
     335                if ( position === "absolute" || position === "fixed" ) {
     336                    return;
     337                }
     338                maxHeight -= elem.outerHeight( true );
     339            });
     340
     341            this.headers.each(function() {
     342                maxHeight -= $( this ).outerHeight( true );
     343            });
     344
     345            this.headers.next()
     346                .each(function() {
     347                    $( this ).height( Math.max( 0, maxHeight -
     348                        $( this ).innerHeight() + $( this ).height() ) );
     349                })
     350                .css( "overflow", "auto" );
     351        } else if ( heightStyle === "auto" ) {
     352            maxHeight = 0;
     353            this.headers.next()
     354                .each(function() {
     355                    maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
     356                })
     357                .height( maxHeight );
     358        }
     359    },
     360
     361    _activate: function( index ) {
     362        var active = this._findActive( index )[ 0 ];
     363
     364        // trying to activate the already active panel
     365        if ( active === this.active[ 0 ] ) {
     366            return;
     367        }
     368
     369        // trying to collapse, simulate a click on the currently active header
     370        active = active || this.active[ 0 ];
     371
     372        this._eventHandler({
     373            target: active,
     374            currentTarget: active,
     375            preventDefault: $.noop
     376        });
     377    },
     378
     379    _findActive: function( selector ) {
     380        return typeof selector === "number" ? this.headers.eq( selector ) : $();
     381    },
     382
     383    _setupEvents: function( event ) {
     384        var events = {
     385            keydown: "_keydown"
     386        };
     387        if ( event ) {
     388            $.each( event.split( " " ), function( index, eventName ) {
     389                events[ eventName ] = "_eventHandler";
     390            });
     391        }
     392
     393        this._off( this.headers.add( this.headers.next() ) );
     394        this._on( this.headers, events );
     395        this._on( this.headers.next(), { keydown: "_panelKeyDown" });
     396        this._hoverable( this.headers );
     397        this._focusable( this.headers );
     398    },
     399
     400    _eventHandler: function( event ) {
     401        var options = this.options,
     402            active = this.active,
     403            clicked = $( event.currentTarget ),
     404            clickedIsActive = clicked[ 0 ] === active[ 0 ],
     405            collapsing = clickedIsActive && options.collapsible,
     406            toShow = collapsing ? $() : clicked.next(),
     407            toHide = active.next(),
     408            eventData = {
     409                oldHeader: active,
     410                oldPanel: toHide,
     411                newHeader: collapsing ? $() : clicked,
     412                newPanel: toShow
     413            };
     414
     415        event.preventDefault();
     416
     417        if (
     418                // click on active header, but not collapsible
     419                ( clickedIsActive && !options.collapsible ) ||
     420                // allow canceling activation
     421                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
     422            return;
     423        }
     424
     425        options.active = collapsing ? false : this.headers.index( clicked );
     426
     427        // when the call to ._toggle() comes after the class changes
     428        // it causes a very odd bug in IE 8 (see #6720)
     429        this.active = clickedIsActive ? $() : clicked;
     430        this._toggle( eventData );
     431
     432        // switch classes
     433        // corner classes on the previously active header stay after the animation
     434        active.removeClass( "ui-accordion-header-active ui-state-active" );
     435        if ( options.icons ) {
     436            active.children( ".ui-accordion-header-icon" )
     437                .removeClass( options.icons.activeHeader )
     438                .addClass( options.icons.header );
     439        }
     440
     441        if ( !clickedIsActive ) {
     442            clicked
     443                .removeClass( "ui-corner-all" )
     444                .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
     445            if ( options.icons ) {
     446                clicked.children( ".ui-accordion-header-icon" )
     447                    .removeClass( options.icons.header )
     448                    .addClass( options.icons.activeHeader );
     449            }
     450
     451            clicked
     452                .next()
     453                .addClass( "ui-accordion-content-active" );
     454        }
     455    },
     456
     457    _toggle: function( data ) {
     458        var toShow = data.newPanel,
     459            toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
     460
     461        // handle activating a panel during the animation for another activation
     462        this.prevShow.add( this.prevHide ).stop( true, true );
     463        this.prevShow = toShow;
     464        this.prevHide = toHide;
     465
     466        if ( this.options.animate ) {
     467            this._animate( toShow, toHide, data );
     468        } else {
     469            toHide.hide();
     470            toShow.show();
     471            this._toggleComplete( data );
     472        }
     473
     474        toHide.attr({
     475            "aria-hidden": "true"
     476        });
     477        toHide.prev().attr( "aria-selected", "false" );
     478        // if we're switching panels, remove the old header from the tab order
     479        // if we're opening from collapsed state, remove the previous header from the tab order
     480        // if we're collapsing, then keep the collapsing header in the tab order
     481        if ( toShow.length && toHide.length ) {
     482            toHide.prev().attr({
     483                "tabIndex": -1,
     484                "aria-expanded": "false"
     485            });
     486        } else if ( toShow.length ) {
     487            this.headers.filter(function() {
     488                return $( this ).attr( "tabIndex" ) === 0;
     489            })
     490            .attr( "tabIndex", -1 );
     491        }
     492
     493        toShow
     494            .attr( "aria-hidden", "false" )
     495            .prev()
     496                .attr({
     497                    "aria-selected": "true",
     498                    tabIndex: 0,
     499                    "aria-expanded": "true"
     500                });
     501    },
     502
     503    _animate: function( toShow, toHide, data ) {
     504        var total, easing, duration,
     505            that = this,
     506            adjust = 0,
     507            down = toShow.length &&
     508                ( !toHide.length || ( toShow.index() < toHide.index() ) ),
     509            animate = this.options.animate || {},
     510            options = down && animate.down || animate,
     511            complete = function() {
     512                that._toggleComplete( data );
     513            };
     514
     515        if ( typeof options === "number" ) {
     516            duration = options;
     517        }
     518        if ( typeof options === "string" ) {
     519            easing = options;
     520        }
     521        // fall back from options to animation in case of partial down settings
     522        easing = easing || options.easing || animate.easing;
     523        duration = duration || options.duration || animate.duration;
     524
     525        if ( !toHide.length ) {
     526            return toShow.animate( this.showProps, duration, easing, complete );
     527        }
     528        if ( !toShow.length ) {
     529            return toHide.animate( this.hideProps, duration, easing, complete );
     530        }
     531
     532        total = toShow.show().outerHeight();
     533        toHide.animate( this.hideProps, {
     534            duration: duration,
     535            easing: easing,
     536            step: function( now, fx ) {
     537                fx.now = Math.round( now );
     538            }
     539        });
     540        toShow
     541            .hide()
     542            .animate( this.showProps, {
     543                duration: duration,
     544                easing: easing,
     545                complete: complete,
     546                step: function( now, fx ) {
     547                    fx.now = Math.round( now );
     548                    if ( fx.prop !== "height" ) {
     549                        adjust += fx.now;
     550                    } else if ( that.options.heightStyle !== "content" ) {
     551                        fx.now = Math.round( total - toHide.outerHeight() - adjust );
     552                        adjust = 0;
     553                    }
     554                }
     555            });
     556    },
     557
     558    _toggleComplete: function( data ) {
     559        var toHide = data.oldPanel;
     560
     561        toHide
     562            .removeClass( "ui-accordion-content-active" )
     563            .prev()
     564                .removeClass( "ui-corner-top" )
     565                .addClass( "ui-corner-all" );
     566
     567        // Work around for rendering bug in IE (#5421)
     568        if ( toHide.length ) {
     569            toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
     570        }
     571        this._trigger( "activate", null, data );
     572    }
     573});
     574
     575}));
  • trunk/src/wp-includes/js/jquery/ui/autocomplete.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(t){t.widget("ui.autocomplete",{version:"1.10.4",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,undefined;e=!1,s=!1,i=!1;var a=t.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:e=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case a.UP:e=!0,this._keyEvent("previous",n);break;case a.DOWN:e=!0,this._keyEvent("next",n);break;case a.ENTER:case a.NUMPAD_ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),undefined;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),undefined):(this._searchTimeout(t),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(t),this._change(t),undefined)}}),this._initSource(),this.menu=t("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];t(e.target).closest(".ui-menu-item").length||this._delay(function(){var e=this;this.document.one("mousedown",function(s){s.target===e.element[0]||s.target===i||t.contains(i,s.target)||e.close()})})},menufocus:function(e,i){if(this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",e,{item:s})?e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=t("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e||(e=this.element.closest(".ui-front")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):undefined},_search:function(t){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return t.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({label:e.label||e.value,value:e.value||e.label},e)})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<a>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[t](e),undefined):(this.search(null,e),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.text(e))}})})(jQuery);
     1/*!
     2 * jQuery UI Autocomplete 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/autocomplete/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define([
     16            "jquery",
     17            "./core",
     18            "./widget",
     19            "./position",
     20            "./menu"
     21        ], factory );
     22    } else {
     23
     24        // Browser globals
     25        factory( jQuery );
     26    }
     27}(function( $ ) {
     28
     29$.widget( "ui.autocomplete", {
     30    version: "1.11.1",
     31    defaultElement: "<input>",
     32    options: {
     33        appendTo: null,
     34        autoFocus: false,
     35        delay: 300,
     36        minLength: 1,
     37        position: {
     38            my: "left top",
     39            at: "left bottom",
     40            collision: "none"
     41        },
     42        source: null,
     43
     44        // callbacks
     45        change: null,
     46        close: null,
     47        focus: null,
     48        open: null,
     49        response: null,
     50        search: null,
     51        select: null
     52    },
     53
     54    requestIndex: 0,
     55    pending: 0,
     56
     57    _create: function() {
     58        // Some browsers only repeat keydown events, not keypress events,
     59        // so we use the suppressKeyPress flag to determine if we've already
     60        // handled the keydown event. #7269
     61        // Unfortunately the code for & in keypress is the same as the up arrow,
     62        // so we use the suppressKeyPressRepeat flag to avoid handling keypress
     63        // events when we know the keydown event was used to modify the
     64        // search term. #7799
     65        var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
     66            nodeName = this.element[ 0 ].nodeName.toLowerCase(),
     67            isTextarea = nodeName === "textarea",
     68            isInput = nodeName === "input";
     69
     70        this.isMultiLine =
     71            // Textareas are always multi-line
     72            isTextarea ? true :
     73            // Inputs are always single-line, even if inside a contentEditable element
     74            // IE also treats inputs as contentEditable
     75            isInput ? false :
     76            // All other element types are determined by whether or not they're contentEditable
     77            this.element.prop( "isContentEditable" );
     78
     79        this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
     80        this.isNewMenu = true;
     81
     82        this.element
     83            .addClass( "ui-autocomplete-input" )
     84            .attr( "autocomplete", "off" );
     85
     86        this._on( this.element, {
     87            keydown: function( event ) {
     88                if ( this.element.prop( "readOnly" ) ) {
     89                    suppressKeyPress = true;
     90                    suppressInput = true;
     91                    suppressKeyPressRepeat = true;
     92                    return;
     93                }
     94
     95                suppressKeyPress = false;
     96                suppressInput = false;
     97                suppressKeyPressRepeat = false;
     98                var keyCode = $.ui.keyCode;
     99                switch ( event.keyCode ) {
     100                case keyCode.PAGE_UP:
     101                    suppressKeyPress = true;
     102                    this._move( "previousPage", event );
     103                    break;
     104                case keyCode.PAGE_DOWN:
     105                    suppressKeyPress = true;
     106                    this._move( "nextPage", event );
     107                    break;
     108                case keyCode.UP:
     109                    suppressKeyPress = true;
     110                    this._keyEvent( "previous", event );
     111                    break;
     112                case keyCode.DOWN:
     113                    suppressKeyPress = true;
     114                    this._keyEvent( "next", event );
     115                    break;
     116                case keyCode.ENTER:
     117                    // when menu is open and has focus
     118                    if ( this.menu.active ) {
     119                        // #6055 - Opera still allows the keypress to occur
     120                        // which causes forms to submit
     121                        suppressKeyPress = true;
     122                        event.preventDefault();
     123                        this.menu.select( event );
     124                    }
     125                    break;
     126                case keyCode.TAB:
     127                    if ( this.menu.active ) {
     128                        this.menu.select( event );
     129                    }
     130                    break;
     131                case keyCode.ESCAPE:
     132                    if ( this.menu.element.is( ":visible" ) ) {
     133                        if ( !this.isMultiLine ) {
     134                            this._value( this.term );
     135                        }
     136                        this.close( event );
     137                        // Different browsers have different default behavior for escape
     138                        // Single press can mean undo or clear
     139                        // Double press in IE means clear the whole form
     140                        event.preventDefault();
     141                    }
     142                    break;
     143                default:
     144                    suppressKeyPressRepeat = true;
     145                    // search timeout should be triggered before the input value is changed
     146                    this._searchTimeout( event );
     147                    break;
     148                }
     149            },
     150            keypress: function( event ) {
     151                if ( suppressKeyPress ) {
     152                    suppressKeyPress = false;
     153                    if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
     154                        event.preventDefault();
     155                    }
     156                    return;
     157                }
     158                if ( suppressKeyPressRepeat ) {
     159                    return;
     160                }
     161
     162                // replicate some key handlers to allow them to repeat in Firefox and Opera
     163                var keyCode = $.ui.keyCode;
     164                switch ( event.keyCode ) {
     165                case keyCode.PAGE_UP:
     166                    this._move( "previousPage", event );
     167                    break;
     168                case keyCode.PAGE_DOWN:
     169                    this._move( "nextPage", event );
     170                    break;
     171                case keyCode.UP:
     172                    this._keyEvent( "previous", event );
     173                    break;
     174                case keyCode.DOWN:
     175                    this._keyEvent( "next", event );
     176                    break;
     177                }
     178            },
     179            input: function( event ) {
     180                if ( suppressInput ) {
     181                    suppressInput = false;
     182                    event.preventDefault();
     183                    return;
     184                }
     185                this._searchTimeout( event );
     186            },
     187            focus: function() {
     188                this.selectedItem = null;
     189                this.previous = this._value();
     190            },
     191            blur: function( event ) {
     192                if ( this.cancelBlur ) {
     193                    delete this.cancelBlur;
     194                    return;
     195                }
     196
     197                clearTimeout( this.searching );
     198                this.close( event );
     199                this._change( event );
     200            }
     201        });
     202
     203        this._initSource();
     204        this.menu = $( "<ul>" )
     205            .addClass( "ui-autocomplete ui-front" )
     206            .appendTo( this._appendTo() )
     207            .menu({
     208                // disable ARIA support, the live region takes care of that
     209                role: null
     210            })
     211            .hide()
     212            .menu( "instance" );
     213
     214        this._on( this.menu.element, {
     215            mousedown: function( event ) {
     216                // prevent moving focus out of the text field
     217                event.preventDefault();
     218
     219                // IE doesn't prevent moving focus even with event.preventDefault()
     220                // so we set a flag to know when we should ignore the blur event
     221                this.cancelBlur = true;
     222                this._delay(function() {
     223                    delete this.cancelBlur;
     224                });
     225
     226                // clicking on the scrollbar causes focus to shift to the body
     227                // but we can't detect a mouseup or a click immediately afterward
     228                // so we have to track the next mousedown and close the menu if
     229                // the user clicks somewhere outside of the autocomplete
     230                var menuElement = this.menu.element[ 0 ];
     231                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
     232                    this._delay(function() {
     233                        var that = this;
     234                        this.document.one( "mousedown", function( event ) {
     235                            if ( event.target !== that.element[ 0 ] &&
     236                                    event.target !== menuElement &&
     237                                    !$.contains( menuElement, event.target ) ) {
     238                                that.close();
     239                            }
     240                        });
     241                    });
     242                }
     243            },
     244            menufocus: function( event, ui ) {
     245                var label, item;
     246                // support: Firefox
     247                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
     248                if ( this.isNewMenu ) {
     249                    this.isNewMenu = false;
     250                    if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
     251                        this.menu.blur();
     252
     253                        this.document.one( "mousemove", function() {
     254                            $( event.target ).trigger( event.originalEvent );
     255                        });
     256
     257                        return;
     258                    }
     259                }
     260
     261                item = ui.item.data( "ui-autocomplete-item" );
     262                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
     263                    // use value to match what will end up in the input, if it was a key event
     264                    if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
     265                        this._value( item.value );
     266                    }
     267                }
     268
     269                // Announce the value in the liveRegion
     270                label = ui.item.attr( "aria-label" ) || item.value;
     271                if ( label && $.trim( label ).length ) {
     272                    this.liveRegion.children().hide();
     273                    $( "<div>" ).text( label ).appendTo( this.liveRegion );
     274                }
     275            },
     276            menuselect: function( event, ui ) {
     277                var item = ui.item.data( "ui-autocomplete-item" ),
     278                    previous = this.previous;
     279
     280                // only trigger when focus was lost (click on menu)
     281                if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
     282                    this.element.focus();
     283                    this.previous = previous;
     284                    // #6109 - IE triggers two focus events and the second
     285                    // is asynchronous, so we need to reset the previous
     286                    // term synchronously and asynchronously :-(
     287                    this._delay(function() {
     288                        this.previous = previous;
     289                        this.selectedItem = item;
     290                    });
     291                }
     292
     293                if ( false !== this._trigger( "select", event, { item: item } ) ) {
     294                    this._value( item.value );
     295                }
     296                // reset the term after the select event
     297                // this allows custom select handling to work properly
     298                this.term = this._value();
     299
     300                this.close( event );
     301                this.selectedItem = item;
     302            }
     303        });
     304
     305        this.liveRegion = $( "<span>", {
     306                role: "status",
     307                "aria-live": "assertive",
     308                "aria-relevant": "additions"
     309            })
     310            .addClass( "ui-helper-hidden-accessible" )
     311            .appendTo( this.document[ 0 ].body );
     312
     313        // turning off autocomplete prevents the browser from remembering the
     314        // value when navigating through history, so we re-enable autocomplete
     315        // if the page is unloaded before the widget is destroyed. #7790
     316        this._on( this.window, {
     317            beforeunload: function() {
     318                this.element.removeAttr( "autocomplete" );
     319            }
     320        });
     321    },
     322
     323    _destroy: function() {
     324        clearTimeout( this.searching );
     325        this.element
     326            .removeClass( "ui-autocomplete-input" )
     327            .removeAttr( "autocomplete" );
     328        this.menu.element.remove();
     329        this.liveRegion.remove();
     330    },
     331
     332    _setOption: function( key, value ) {
     333        this._super( key, value );
     334        if ( key === "source" ) {
     335            this._initSource();
     336        }
     337        if ( key === "appendTo" ) {
     338            this.menu.element.appendTo( this._appendTo() );
     339        }
     340        if ( key === "disabled" && value && this.xhr ) {
     341            this.xhr.abort();
     342        }
     343    },
     344
     345    _appendTo: function() {
     346        var element = this.options.appendTo;
     347
     348        if ( element ) {
     349            element = element.jquery || element.nodeType ?
     350                $( element ) :
     351                this.document.find( element ).eq( 0 );
     352        }
     353
     354        if ( !element || !element[ 0 ] ) {
     355            element = this.element.closest( ".ui-front" );
     356        }
     357
     358        if ( !element.length ) {
     359            element = this.document[ 0 ].body;
     360        }
     361
     362        return element;
     363    },
     364
     365    _initSource: function() {
     366        var array, url,
     367            that = this;
     368        if ( $.isArray( this.options.source ) ) {
     369            array = this.options.source;
     370            this.source = function( request, response ) {
     371                response( $.ui.autocomplete.filter( array, request.term ) );
     372            };
     373        } else if ( typeof this.options.source === "string" ) {
     374            url = this.options.source;
     375            this.source = function( request, response ) {
     376                if ( that.xhr ) {
     377                    that.xhr.abort();
     378                }
     379                that.xhr = $.ajax({
     380                    url: url,
     381                    data: request,
     382                    dataType: "json",
     383                    success: function( data ) {
     384                        response( data );
     385                    },
     386                    error: function() {
     387                        response([]);
     388                    }
     389                });
     390            };
     391        } else {
     392            this.source = this.options.source;
     393        }
     394    },
     395
     396    _searchTimeout: function( event ) {
     397        clearTimeout( this.searching );
     398        this.searching = this._delay(function() {
     399
     400            // Search if the value has changed, or if the user retypes the same value (see #7434)
     401            var equalValues = this.term === this._value(),
     402                menuVisible = this.menu.element.is( ":visible" ),
     403                modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
     404
     405            if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
     406                this.selectedItem = null;
     407                this.search( null, event );
     408            }
     409        }, this.options.delay );
     410    },
     411
     412    search: function( value, event ) {
     413        value = value != null ? value : this._value();
     414
     415        // always save the actual value, not the one passed as an argument
     416        this.term = this._value();
     417
     418        if ( value.length < this.options.minLength ) {
     419            return this.close( event );
     420        }
     421
     422        if ( this._trigger( "search", event ) === false ) {
     423            return;
     424        }
     425
     426        return this._search( value );
     427    },
     428
     429    _search: function( value ) {
     430        this.pending++;
     431        this.element.addClass( "ui-autocomplete-loading" );
     432        this.cancelSearch = false;
     433
     434        this.source( { term: value }, this._response() );
     435    },
     436
     437    _response: function() {
     438        var index = ++this.requestIndex;
     439
     440        return $.proxy(function( content ) {
     441            if ( index === this.requestIndex ) {
     442                this.__response( content );
     443            }
     444
     445            this.pending--;
     446            if ( !this.pending ) {
     447                this.element.removeClass( "ui-autocomplete-loading" );
     448            }
     449        }, this );
     450    },
     451
     452    __response: function( content ) {
     453        if ( content ) {
     454            content = this._normalize( content );
     455        }
     456        this._trigger( "response", null, { content: content } );
     457        if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
     458            this._suggest( content );
     459            this._trigger( "open" );
     460        } else {
     461            // use ._close() instead of .close() so we don't cancel future searches
     462            this._close();
     463        }
     464    },
     465
     466    close: function( event ) {
     467        this.cancelSearch = true;
     468        this._close( event );
     469    },
     470
     471    _close: function( event ) {
     472        if ( this.menu.element.is( ":visible" ) ) {
     473            this.menu.element.hide();
     474            this.menu.blur();
     475            this.isNewMenu = true;
     476            this._trigger( "close", event );
     477        }
     478    },
     479
     480    _change: function( event ) {
     481        if ( this.previous !== this._value() ) {
     482            this._trigger( "change", event, { item: this.selectedItem } );
     483        }
     484    },
     485
     486    _normalize: function( items ) {
     487        // assume all items have the right format when the first item is complete
     488        if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
     489            return items;
     490        }
     491        return $.map( items, function( item ) {
     492            if ( typeof item === "string" ) {
     493                return {
     494                    label: item,
     495                    value: item
     496                };
     497            }
     498            return $.extend( {}, item, {
     499                label: item.label || item.value,
     500                value: item.value || item.label
     501            });
     502        });
     503    },
     504
     505    _suggest: function( items ) {
     506        var ul = this.menu.element.empty();
     507        this._renderMenu( ul, items );
     508        this.isNewMenu = true;
     509        this.menu.refresh();
     510
     511        // size and position menu
     512        ul.show();
     513        this._resizeMenu();
     514        ul.position( $.extend({
     515            of: this.element
     516        }, this.options.position ) );
     517
     518        if ( this.options.autoFocus ) {
     519            this.menu.next();
     520        }
     521    },
     522
     523    _resizeMenu: function() {
     524        var ul = this.menu.element;
     525        ul.outerWidth( Math.max(
     526            // Firefox wraps long text (possibly a rounding bug)
     527            // so we add 1px to avoid the wrapping (#7513)
     528            ul.width( "" ).outerWidth() + 1,
     529            this.element.outerWidth()
     530        ) );
     531    },
     532
     533    _renderMenu: function( ul, items ) {
     534        var that = this;
     535        $.each( items, function( index, item ) {
     536            that._renderItemData( ul, item );
     537        });
     538    },
     539
     540    _renderItemData: function( ul, item ) {
     541        return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
     542    },
     543
     544    _renderItem: function( ul, item ) {
     545        return $( "<li>" ).text( item.label ).appendTo( ul );
     546    },
     547
     548    _move: function( direction, event ) {
     549        if ( !this.menu.element.is( ":visible" ) ) {
     550            this.search( null, event );
     551            return;
     552        }
     553        if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
     554                this.menu.isLastItem() && /^next/.test( direction ) ) {
     555
     556            if ( !this.isMultiLine ) {
     557                this._value( this.term );
     558            }
     559
     560            this.menu.blur();
     561            return;
     562        }
     563        this.menu[ direction ]( event );
     564    },
     565
     566    widget: function() {
     567        return this.menu.element;
     568    },
     569
     570    _value: function() {
     571        return this.valueMethod.apply( this.element, arguments );
     572    },
     573
     574    _keyEvent: function( keyEvent, event ) {
     575        if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
     576            this._move( keyEvent, event );
     577
     578            // prevents moving cursor to beginning/end of the text field in some browsers
     579            event.preventDefault();
     580        }
     581    }
     582});
     583
     584$.extend( $.ui.autocomplete, {
     585    escapeRegex: function( value ) {
     586        return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
     587    },
     588    filter: function( array, term ) {
     589        var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
     590        return $.grep( array, function( value ) {
     591            return matcher.test( value.label || value.value || value );
     592        });
     593    }
     594});
     595
     596// live region extension, adding a `messages` option
     597// NOTE: This is an experimental API. We are still investigating
     598// a full solution for string manipulation and internationalization.
     599$.widget( "ui.autocomplete", $.ui.autocomplete, {
     600    options: {
     601        messages: {
     602            noResults: "No search results.",
     603            results: function( amount ) {
     604                return amount + ( amount > 1 ? " results are" : " result is" ) +
     605                    " available, use up and down arrow keys to navigate.";
     606            }
     607        }
     608    },
     609
     610    __response: function( content ) {
     611        var message;
     612        this._superApply( arguments );
     613        if ( this.options.disabled || this.cancelSearch ) {
     614            return;
     615        }
     616        if ( content && content.length ) {
     617            message = this.options.messages.results( content.length );
     618        } else {
     619            message = this.options.messages.noResults;
     620        }
     621        this.liveRegion.children().hide();
     622        $( "<div>" ).text( message ).appendTo( this.liveRegion );
     623    }
     624});
     625
     626return $.ui.autocomplete;
     627
     628}));
  • trunk/src/wp-includes/js/jquery/ui/button.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(t){var e,i="ui-button ui-widget ui-state-default ui-corner-all",s="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",n=function(){var e=t(this);setTimeout(function(){e.find(":ui-button").button("refresh")},1)},a=function(e){var i=e.name,s=e.form,n=t([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?t(s).find("[name='"+i+"']"):t("[name='"+i+"']",e.ownerDocument).filter(function(){return!this.form})),n};t.widget("ui.button",{version:"1.10.4",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,n),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var s=this,o=this.options,r="checkbox"===this.type||"radio"===this.type,h=r?"":"ui-state-active";null===o.label&&(o.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(i).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){o.disabled||this===e&&t(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){o.disabled||t(this).removeClass(h)}).bind("click"+this.eventNamespace,function(t){o.disabled&&(t.preventDefault(),t.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),r&&this.element.bind("change"+this.eventNamespace,function(){s.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return o.disabled?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(o.disabled)return!1;t(this).addClass("ui-state-active"),s.buttonElement.attr("aria-pressed","true");var e=s.element[0];a(e).not(e).map(function(){return t(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return o.disabled?!1:(t(this).addClass("ui-state-active"),e=this,s.document.one("mouseup",function(){e=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return o.disabled?!1:(t(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(e){return o.disabled?!1:((e.keyCode===t.ui.keyCode.SPACE||e.keyCode===t.ui.keyCode.ENTER)&&t(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){t(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(e){e.keyCode===t.ui.keyCode.SPACE&&t(this).click()})),this._setOption("disabled",o.disabled),this._resetButton()},_determineButtonType:function(){var t,e,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(t=this.element.parents().last(),e="label[for='"+this.element.attr("id")+"']",this.buttonElement=t.find(e),this.buttonElement.length||(t=t.length?t.siblings():this.element.siblings(),this.buttonElement=t.filter(e),this.buttonElement.length||(this.buttonElement=t.find(e))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(i+" ui-state-active "+s).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(t,e){return this._super(t,e),"disabled"===t?(this.element.prop("disabled",!!e),e&&this.buttonElement.removeClass("ui-state-focus"),undefined):(this._resetButton(),undefined)},refresh:function(){var e=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");e!==this.options.disabled&&this._setOption("disabled",e),"radio"===this.type?a(this.element[0]).each(function(){t(this).is(":checked")?t(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):t(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var e=this.buttonElement.removeClass(s),i=t("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(e.empty()).text(),n=this.options.icons,a=n.primary&&n.secondary,o=[];n.primary||n.secondary?(this.options.text&&o.push("ui-button-text-icon"+(a?"s":n.primary?"-primary":"-secondary")),n.primary&&e.prepend("<span class='ui-button-icon-primary ui-icon "+n.primary+"'></span>"),n.secondary&&e.append("<span class='ui-button-icon-secondary ui-icon "+n.secondary+"'></span>"),this.options.text||(o.push(a?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||e.attr("title",t.trim(i)))):o.push("ui-button-text-only"),e.addClass(o.join(" "))}}),t.widget("ui.buttonset",{version:"1.10.4",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(t,e){"disabled"===t&&this.buttons.button("option",t,e),this._super(t,e)},refresh:function(){var e="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(e?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(e?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);
     1/*!
     2 * jQuery UI Button 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/button/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define([
     16            "jquery",
     17            "./core",
     18            "./widget"
     19        ], factory );
     20    } else {
     21
     22        // Browser globals
     23        factory( jQuery );
     24    }
     25}(function( $ ) {
     26
     27var lastActive,
     28    baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
     29    typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
     30    formResetHandler = function() {
     31        var form = $( this );
     32        setTimeout(function() {
     33            form.find( ":ui-button" ).button( "refresh" );
     34        }, 1 );
     35    },
     36    radioGroup = function( radio ) {
     37        var name = radio.name,
     38            form = radio.form,
     39            radios = $( [] );
     40        if ( name ) {
     41            name = name.replace( /'/g, "\\'" );
     42            if ( form ) {
     43                radios = $( form ).find( "[name='" + name + "'][type=radio]" );
     44            } else {
     45                radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
     46                    .filter(function() {
     47                        return !this.form;
     48                    });
     49            }
     50        }
     51        return radios;
     52    };
     53
     54$.widget( "ui.button", {
     55    version: "1.11.1",
     56    defaultElement: "<button>",
     57    options: {
     58        disabled: null,
     59        text: true,
     60        label: null,
     61        icons: {
     62            primary: null,
     63            secondary: null
     64        }
     65    },
     66    _create: function() {
     67        this.element.closest( "form" )
     68            .unbind( "reset" + this.eventNamespace )
     69            .bind( "reset" + this.eventNamespace, formResetHandler );
     70
     71        if ( typeof this.options.disabled !== "boolean" ) {
     72            this.options.disabled = !!this.element.prop( "disabled" );
     73        } else {
     74            this.element.prop( "disabled", this.options.disabled );
     75        }
     76
     77        this._determineButtonType();
     78        this.hasTitle = !!this.buttonElement.attr( "title" );
     79
     80        var that = this,
     81            options = this.options,
     82            toggleButton = this.type === "checkbox" || this.type === "radio",
     83            activeClass = !toggleButton ? "ui-state-active" : "";
     84
     85        if ( options.label === null ) {
     86            options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
     87        }
     88
     89        this._hoverable( this.buttonElement );
     90
     91        this.buttonElement
     92            .addClass( baseClasses )
     93            .attr( "role", "button" )
     94            .bind( "mouseenter" + this.eventNamespace, function() {
     95                if ( options.disabled ) {
     96                    return;
     97                }
     98                if ( this === lastActive ) {
     99                    $( this ).addClass( "ui-state-active" );
     100                }
     101            })
     102            .bind( "mouseleave" + this.eventNamespace, function() {
     103                if ( options.disabled ) {
     104                    return;
     105                }
     106                $( this ).removeClass( activeClass );
     107            })
     108            .bind( "click" + this.eventNamespace, function( event ) {
     109                if ( options.disabled ) {
     110                    event.preventDefault();
     111                    event.stopImmediatePropagation();
     112                }
     113            });
     114
     115        // Can't use _focusable() because the element that receives focus
     116        // and the element that gets the ui-state-focus class are different
     117        this._on({
     118            focus: function() {
     119                this.buttonElement.addClass( "ui-state-focus" );
     120            },
     121            blur: function() {
     122                this.buttonElement.removeClass( "ui-state-focus" );
     123            }
     124        });
     125
     126        if ( toggleButton ) {
     127            this.element.bind( "change" + this.eventNamespace, function() {
     128                that.refresh();
     129            });
     130        }
     131
     132        if ( this.type === "checkbox" ) {
     133            this.buttonElement.bind( "click" + this.eventNamespace, function() {
     134                if ( options.disabled ) {
     135                    return false;
     136                }
     137            });
     138        } else if ( this.type === "radio" ) {
     139            this.buttonElement.bind( "click" + this.eventNamespace, function() {
     140                if ( options.disabled ) {
     141                    return false;
     142                }
     143                $( this ).addClass( "ui-state-active" );
     144                that.buttonElement.attr( "aria-pressed", "true" );
     145
     146                var radio = that.element[ 0 ];
     147                radioGroup( radio )
     148                    .not( radio )
     149                    .map(function() {
     150                        return $( this ).button( "widget" )[ 0 ];
     151                    })
     152                    .removeClass( "ui-state-active" )
     153                    .attr( "aria-pressed", "false" );
     154            });
     155        } else {
     156            this.buttonElement
     157                .bind( "mousedown" + this.eventNamespace, function() {
     158                    if ( options.disabled ) {
     159                        return false;
     160                    }
     161                    $( this ).addClass( "ui-state-active" );
     162                    lastActive = this;
     163                    that.document.one( "mouseup", function() {
     164                        lastActive = null;
     165                    });
     166                })
     167                .bind( "mouseup" + this.eventNamespace, function() {
     168                    if ( options.disabled ) {
     169                        return false;
     170                    }
     171                    $( this ).removeClass( "ui-state-active" );
     172                })
     173                .bind( "keydown" + this.eventNamespace, function(event) {
     174                    if ( options.disabled ) {
     175                        return false;
     176                    }
     177                    if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
     178                        $( this ).addClass( "ui-state-active" );
     179                    }
     180                })
     181                // see #8559, we bind to blur here in case the button element loses
     182                // focus between keydown and keyup, it would be left in an "active" state
     183                .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
     184                    $( this ).removeClass( "ui-state-active" );
     185                });
     186
     187            if ( this.buttonElement.is("a") ) {
     188                this.buttonElement.keyup(function(event) {
     189                    if ( event.keyCode === $.ui.keyCode.SPACE ) {
     190                        // TODO pass through original event correctly (just as 2nd argument doesn't work)
     191                        $( this ).click();
     192                    }
     193                });
     194            }
     195        }
     196
     197        this._setOption( "disabled", options.disabled );
     198        this._resetButton();
     199    },
     200
     201    _determineButtonType: function() {
     202        var ancestor, labelSelector, checked;
     203
     204        if ( this.element.is("[type=checkbox]") ) {
     205            this.type = "checkbox";
     206        } else if ( this.element.is("[type=radio]") ) {
     207            this.type = "radio";
     208        } else if ( this.element.is("input") ) {
     209            this.type = "input";
     210        } else {
     211            this.type = "button";
     212        }
     213
     214        if ( this.type === "checkbox" || this.type === "radio" ) {
     215            // we don't search against the document in case the element
     216            // is disconnected from the DOM
     217            ancestor = this.element.parents().last();
     218            labelSelector = "label[for='" + this.element.attr("id") + "']";
     219            this.buttonElement = ancestor.find( labelSelector );
     220            if ( !this.buttonElement.length ) {
     221                ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
     222                this.buttonElement = ancestor.filter( labelSelector );
     223                if ( !this.buttonElement.length ) {
     224                    this.buttonElement = ancestor.find( labelSelector );
     225                }
     226            }
     227            this.element.addClass( "ui-helper-hidden-accessible" );
     228
     229            checked = this.element.is( ":checked" );
     230            if ( checked ) {
     231                this.buttonElement.addClass( "ui-state-active" );
     232            }
     233            this.buttonElement.prop( "aria-pressed", checked );
     234        } else {
     235            this.buttonElement = this.element;
     236        }
     237    },
     238
     239    widget: function() {
     240        return this.buttonElement;
     241    },
     242
     243    _destroy: function() {
     244        this.element
     245            .removeClass( "ui-helper-hidden-accessible" );
     246        this.buttonElement
     247            .removeClass( baseClasses + " ui-state-active " + typeClasses )
     248            .removeAttr( "role" )
     249            .removeAttr( "aria-pressed" )
     250            .html( this.buttonElement.find(".ui-button-text").html() );
     251
     252        if ( !this.hasTitle ) {
     253            this.buttonElement.removeAttr( "title" );
     254        }
     255    },
     256
     257    _setOption: function( key, value ) {
     258        this._super( key, value );
     259        if ( key === "disabled" ) {
     260            this.widget().toggleClass( "ui-state-disabled", !!value );
     261            this.element.prop( "disabled", !!value );
     262            if ( value ) {
     263                if ( this.type === "checkbox" || this.type === "radio" ) {
     264                    this.buttonElement.removeClass( "ui-state-focus" );
     265                } else {
     266                    this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
     267                }
     268            }
     269            return;
     270        }
     271        this._resetButton();
     272    },
     273
     274    refresh: function() {
     275        //See #8237 & #8828
     276        var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
     277
     278        if ( isDisabled !== this.options.disabled ) {
     279            this._setOption( "disabled", isDisabled );
     280        }
     281        if ( this.type === "radio" ) {
     282            radioGroup( this.element[0] ).each(function() {
     283                if ( $( this ).is( ":checked" ) ) {
     284                    $( this ).button( "widget" )
     285                        .addClass( "ui-state-active" )
     286                        .attr( "aria-pressed", "true" );
     287                } else {
     288                    $( this ).button( "widget" )
     289                        .removeClass( "ui-state-active" )
     290                        .attr( "aria-pressed", "false" );
     291                }
     292            });
     293        } else if ( this.type === "checkbox" ) {
     294            if ( this.element.is( ":checked" ) ) {
     295                this.buttonElement
     296                    .addClass( "ui-state-active" )
     297                    .attr( "aria-pressed", "true" );
     298            } else {
     299                this.buttonElement
     300                    .removeClass( "ui-state-active" )
     301                    .attr( "aria-pressed", "false" );
     302            }
     303        }
     304    },
     305
     306    _resetButton: function() {
     307        if ( this.type === "input" ) {
     308            if ( this.options.label ) {
     309                this.element.val( this.options.label );
     310            }
     311            return;
     312        }
     313        var buttonElement = this.buttonElement.removeClass( typeClasses ),
     314            buttonText = $( "<span></span>", this.document[0] )
     315                .addClass( "ui-button-text" )
     316                .html( this.options.label )
     317                .appendTo( buttonElement.empty() )
     318                .text(),
     319            icons = this.options.icons,
     320            multipleIcons = icons.primary && icons.secondary,
     321            buttonClasses = [];
     322
     323        if ( icons.primary || icons.secondary ) {
     324            if ( this.options.text ) {
     325                buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
     326            }
     327
     328            if ( icons.primary ) {
     329                buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
     330            }
     331
     332            if ( icons.secondary ) {
     333                buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
     334            }
     335
     336            if ( !this.options.text ) {
     337                buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
     338
     339                if ( !this.hasTitle ) {
     340                    buttonElement.attr( "title", $.trim( buttonText ) );
     341                }
     342            }
     343        } else {
     344            buttonClasses.push( "ui-button-text-only" );
     345        }
     346        buttonElement.addClass( buttonClasses.join( " " ) );
     347    }
     348});
     349
     350$.widget( "ui.buttonset", {
     351    version: "1.11.1",
     352    options: {
     353        items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
     354    },
     355
     356    _create: function() {
     357        this.element.addClass( "ui-buttonset" );
     358    },
     359
     360    _init: function() {
     361        this.refresh();
     362    },
     363
     364    _setOption: function( key, value ) {
     365        if ( key === "disabled" ) {
     366            this.buttons.button( "option", key, value );
     367        }
     368
     369        this._super( key, value );
     370    },
     371
     372    refresh: function() {
     373        var rtl = this.element.css( "direction" ) === "rtl",
     374            allButtons = this.element.find( this.options.items ),
     375            existingButtons = allButtons.filter( ":ui-button" );
     376
     377        // Initialize new buttons
     378        allButtons.not( ":ui-button" ).button();
     379
     380        // Refresh existing buttons
     381        existingButtons.button( "refresh" );
     382
     383        this.buttons = allButtons
     384            .map(function() {
     385                return $( this ).button( "widget" )[ 0 ];
     386            })
     387                .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
     388                .filter( ":first" )
     389                    .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
     390                .end()
     391                .filter( ":last" )
     392                    .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
     393                .end()
     394            .end();
     395    },
     396
     397    _destroy: function() {
     398        this.element.removeClass( "ui-buttonset" );
     399        this.buttons
     400            .map(function() {
     401                return $( this ).button( "widget" )[ 0 ];
     402            })
     403                .removeClass( "ui-corner-left ui-corner-right" )
     404            .end()
     405            .button( "destroy" );
     406    }
     407});
     408
     409return $.ui.button;
     410
     411}));
  • trunk/src/wp-includes/js/jquery/ui/core.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(e,t){function i(t,i){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&s(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],r=s.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?o["inner"+s].call(this):this.each(function(){e(this).css(r,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?o["outer"+s].call(this,t):this.each(function(){e(this).css(r,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);
     1/*!
     2 * jQuery UI Core 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/category/ui-core/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define( [ "jquery" ], factory );
     16    } else {
     17
     18        // Browser globals
     19        factory( jQuery );
     20    }
     21}(function( $ ) {
     22
     23// $.ui might exist from components with no dependencies, e.g., $.ui.position
     24$.ui = $.ui || {};
     25
     26$.extend( $.ui, {
     27    version: "1.11.1",
     28
     29    keyCode: {
     30        BACKSPACE: 8,
     31        COMMA: 188,
     32        DELETE: 46,
     33        DOWN: 40,
     34        END: 35,
     35        ENTER: 13,
     36        ESCAPE: 27,
     37        HOME: 36,
     38        LEFT: 37,
     39        PAGE_DOWN: 34,
     40        PAGE_UP: 33,
     41        PERIOD: 190,
     42        RIGHT: 39,
     43        SPACE: 32,
     44        TAB: 9,
     45        UP: 38
     46    }
     47});
     48
     49// plugins
     50$.fn.extend({
     51    scrollParent: function( includeHidden ) {
     52        var position = this.css( "position" ),
     53            excludeStaticParent = position === "absolute",
     54            overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
     55            scrollParent = this.parents().filter( function() {
     56                var parent = $( this );
     57                if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
     58                    return false;
     59                }
     60                return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
     61            }).eq( 0 );
     62
     63        return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
     64    },
     65
     66    uniqueId: (function() {
     67        var uuid = 0;
     68
     69        return function() {
     70            return this.each(function() {
     71                if ( !this.id ) {
     72                    this.id = "ui-id-" + ( ++uuid );
     73                }
     74            });
     75        };
     76    })(),
     77
     78    removeUniqueId: function() {
     79        return this.each(function() {
     80            if ( /^ui-id-\d+$/.test( this.id ) ) {
     81                $( this ).removeAttr( "id" );
     82            }
     83        });
     84    }
     85});
     86
     87// selectors
     88function focusable( element, isTabIndexNotNaN ) {
     89    var map, mapName, img,
     90        nodeName = element.nodeName.toLowerCase();
     91    if ( "area" === nodeName ) {
     92        map = element.parentNode;
     93        mapName = map.name;
     94        if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
     95            return false;
     96        }
     97        img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
     98        return !!img && visible( img );
     99    }
     100    return ( /input|select|textarea|button|object/.test( nodeName ) ?
     101        !element.disabled :
     102        "a" === nodeName ?
     103            element.href || isTabIndexNotNaN :
     104            isTabIndexNotNaN) &&
     105        // the element and all of its ancestors must be visible
     106        visible( element );
     107}
     108
     109function visible( element ) {
     110    return $.expr.filters.visible( element ) &&
     111        !$( element ).parents().addBack().filter(function() {
     112            return $.css( this, "visibility" ) === "hidden";
     113        }).length;
     114}
     115
     116$.extend( $.expr[ ":" ], {
     117    data: $.expr.createPseudo ?
     118        $.expr.createPseudo(function( dataName ) {
     119            return function( elem ) {
     120                return !!$.data( elem, dataName );
     121            };
     122        }) :
     123        // support: jQuery <1.8
     124        function( elem, i, match ) {
     125            return !!$.data( elem, match[ 3 ] );
     126        },
     127
     128    focusable: function( element ) {
     129        return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
     130    },
     131
     132    tabbable: function( element ) {
     133        var tabIndex = $.attr( element, "tabindex" ),
     134            isTabIndexNaN = isNaN( tabIndex );
     135        return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
     136    }
     137});
     138
     139// support: jQuery <1.8
     140if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
     141    $.each( [ "Width", "Height" ], function( i, name ) {
     142        var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
     143            type = name.toLowerCase(),
     144            orig = {
     145                innerWidth: $.fn.innerWidth,
     146                innerHeight: $.fn.innerHeight,
     147                outerWidth: $.fn.outerWidth,
     148                outerHeight: $.fn.outerHeight
     149            };
     150
     151        function reduce( elem, size, border, margin ) {
     152            $.each( side, function() {
     153                size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
     154                if ( border ) {
     155                    size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
     156                }
     157                if ( margin ) {
     158                    size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
     159                }
     160            });
     161            return size;
     162        }
     163
     164        $.fn[ "inner" + name ] = function( size ) {
     165            if ( size === undefined ) {
     166                return orig[ "inner" + name ].call( this );
     167            }
     168
     169            return this.each(function() {
     170                $( this ).css( type, reduce( this, size ) + "px" );
     171            });
     172        };
     173
     174        $.fn[ "outer" + name] = function( size, margin ) {
     175            if ( typeof size !== "number" ) {
     176                return orig[ "outer" + name ].call( this, size );
     177            }
     178
     179            return this.each(function() {
     180                $( this).css( type, reduce( this, size, true, margin ) + "px" );
     181            });
     182        };
     183    });
     184}
     185
     186// support: jQuery <1.8
     187if ( !$.fn.addBack ) {
     188    $.fn.addBack = function( selector ) {
     189        return this.add( selector == null ?
     190            this.prevObject : this.prevObject.filter( selector )
     191        );
     192    };
     193}
     194
     195// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
     196if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
     197    $.fn.removeData = (function( removeData ) {
     198        return function( key ) {
     199            if ( arguments.length ) {
     200                return removeData.call( this, $.camelCase( key ) );
     201            } else {
     202                return removeData.call( this );
     203            }
     204        };
     205    })( $.fn.removeData );
     206}
     207
     208// deprecated
     209$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
     210
     211$.fn.extend({
     212    focus: (function( orig ) {
     213        return function( delay, fn ) {
     214            return typeof delay === "number" ?
     215                this.each(function() {
     216                    var elem = this;
     217                    setTimeout(function() {
     218                        $( elem ).focus();
     219                        if ( fn ) {
     220                            fn.call( elem );
     221                        }
     222                    }, delay );
     223                }) :
     224                orig.apply( this, arguments );
     225        };
     226    })( $.fn.focus ),
     227
     228    disableSelection: (function() {
     229        var eventType = "onselectstart" in document.createElement( "div" ) ?
     230            "selectstart" :
     231            "mousedown";
     232
     233        return function() {
     234            return this.bind( eventType + ".ui-disableSelection", function( event ) {
     235                event.preventDefault();
     236            });
     237        };
     238    })(),
     239
     240    enableSelection: function() {
     241        return this.unbind( ".ui-disableSelection" );
     242    },
     243
     244    zIndex: function( zIndex ) {
     245        if ( zIndex !== undefined ) {
     246            return this.css( "zIndex", zIndex );
     247        }
     248
     249        if ( this.length ) {
     250            var elem = $( this[ 0 ] ), position, value;
     251            while ( elem.length && elem[ 0 ] !== document ) {
     252                // Ignore z-index if position is set to a value where z-index is ignored by the browser
     253                // This makes behavior of this function consistent across browsers
     254                // WebKit always returns auto if the element is positioned
     255                position = elem.css( "position" );
     256                if ( position === "absolute" || position === "relative" || position === "fixed" ) {
     257                    // IE returns 0 when zIndex is not specified
     258                    // other browsers return a string
     259                    // we ignore the case of nested elements with an explicit value of 0
     260                    // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
     261                    value = parseInt( elem.css( "zIndex" ), 10 );
     262                    if ( !isNaN( value ) && value !== 0 ) {
     263                        return value;
     264                    }
     265                }
     266                elem = elem.parent();
     267            }
     268        }
     269
     270        return 0;
     271    }
     272});
     273
     274// $.ui.plugin is deprecated. Use $.widget() extensions instead.
     275$.ui.plugin = {
     276    add: function( module, option, set ) {
     277        var i,
     278            proto = $.ui[ module ].prototype;
     279        for ( i in set ) {
     280            proto.plugins[ i ] = proto.plugins[ i ] || [];
     281            proto.plugins[ i ].push( [ option, set[ i ] ] );
     282        }
     283    },
     284    call: function( instance, name, args, allowDisconnected ) {
     285        var i,
     286            set = instance.plugins[ name ];
     287
     288        if ( !set ) {
     289            return;
     290        }
     291
     292        if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
     293            return;
     294        }
     295
     296        for ( i = 0; i < set.length; i++ ) {
     297            if ( instance.options[ set[ i ][ 0 ] ] ) {
     298                set[ i ][ 1 ].apply( instance.element, args );
     299            }
     300        }
     301    }
     302};
     303
     304}));
  • trunk/src/wp-includes/js/jquery/ui/datepicker.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(t,e){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.dpDiv=s(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function s(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(i,"mouseout",function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){t.datepicker._isDisabledDatepicker(a.inline?e.parent()[0]:a.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))})}function n(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}t.extend(t.ui,{datepicker:{version:"1.10.4"}});var a,r="datepicker";t.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return n(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,a;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),a=this._newInst(t(e),n),a.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,a):n&&this._inlineDatepicker(e,a)},_newInst:function(e,i){var n=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?s(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),t.data(e,r,i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,a,r=this._get(i,"appendText"),o=this._get(i,"isRTL");i.append&&i.append.remove(),r&&(i.append=t("<span class='"+this._appendClass+"'>"+r+"</span>"),e[o?"before":"after"](i.append)),e.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),a=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:a,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(a?t("<img/>").attr({src:a,alt:n,title:n}):n)),e[o?"before":"after"](i.trigger),i.trigger.click(function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,a=new Date(2009,11,20),r=this._get(t,"dateFormat");r.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},a.setMonth(e(this._get(t,r.match(/MM/)?"monthNames":"monthNamesShort"))),a.setDate(e(this._get(t,r.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())),t.input.attr("size",this._formatDate(t,a).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,r,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,a,o){var h,l,c,u,d,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),t("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},t.data(this._dialogInput[0],r,p)),n(p.settings,a||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(l=document.documentElement.clientWidth,c=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+u,c/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],r,p),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,r);s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,r),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())},_enableDatepicker:function(e){var i,s,n=t(e),a=t.data(e,r);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,a.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),a=t.data(e,r);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,a.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,r)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,s,a){var r,o,h,l,c=this._getInst(i);return 2===arguments.length&&"string"==typeof s?"defaults"===s?t.extend({},t.datepicker._defaults):c?"all"===s?t.extend({},c.settings):this._get(c,s):null:(r=s||{},"string"==typeof s&&(r={},r[s]=a),c&&(this._curInst===c&&this._hideDatepicker(),o=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(c,"min"),l=this._getMinMaxDate(c,"max"),n(c.settings,r),null!==h&&r.dateFormat!==e&&r.minDate===e&&(c.settings.minDate=this._formatDate(c,h)),null!==l&&r.dateFormat!==e&&r.maxDate===e&&(c.settings.maxDate=this._formatDate(c,l)),"disabled"in r&&(r.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(t(i),c),this._autoSize(c),this._setDate(c,o),this._updateAlternate(c),this._updateDatepicker(c)),e)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,a=t.datepicker._getInst(e.target),r=!0,o=a.dpDiv.is(".ui-datepicker-rtl");if(a._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),r=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",a.dpDiv),n[0]&&t.datepicker._selectDay(e.target,a.selectedMonth,a.selectedYear,n[0]),i=t.datepicker._get(a,"onSelect"),i?(s=t.datepicker._formatDate(a),i.apply(a.input?a.input[0]:null,[s,a])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(a,"stepBigMonths"):-t.datepicker._get(a,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(a,"stepBigMonths"):+t.datepicker._get(a,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),r=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),r=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,o?1:-1,"D"),r=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(a,"stepBigMonths"):-t.datepicker._get(a,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),r=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,o?-1:1,"D"),r=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(a,"stepBigMonths"):+t.datepicker._get(a,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),r=e.ctrlKey||e.metaKey;break;default:r=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):r=!1;r&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(i){var s,n,a=t.datepicker._getInst(i.target);return t.datepicker._get(a,"constrainInput")?(s=t.datepicker._possibleChars(t.datepicker._get(a,"dateFormat")),n=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">n||!s||s.indexOf(n)>-1):e},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var i,s,a,r,o,h,l;i=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==i&&(t.datepicker._curInst.dpDiv.stop(!0,!0),i&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),s=t.datepicker._get(i,"beforeShow"),a=s?s.apply(e,[e,i]):{},a!==!1&&(n(i.settings,a),i.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(i),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),o={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(i),o=t.datepicker._checkOffset(i,o,r),i.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:o.left+"px",top:o.top+"px"}),i.inline||(h=t.datepicker._get(i,"showAnim"),l=t.datepicker._get(i,"duration"),i.dpDiv.zIndex(t(e).zIndex()+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[h]?i.dpDiv.show(h,t.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),t.datepicker._shouldFocusInput(i)&&i.input.focus(),t.datepicker._curInst=i))}},_updateDatepicker:function(e){this.maxRows=4,a=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,s=this._getNumberOfMonths(e),n=s[1],r=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",r*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.focus(),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),a=e.dpDiv.outerHeight(),r=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-r:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+o?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+a>l&&l>a?Math.abs(a+o):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,a,o=this._curInst;!o||e&&o!==t.data(e,r)||this._datepickerShowing&&(i=this._get(o,"showAnim"),s=this._get(o,"duration"),n=function(){t.datepicker._tidyDialog(o)},t.effects&&(t.effects.effect[i]||t.effects[i])?o.dpDiv.hide(i,t.datepicker._get(o,"showOptions"),s,n):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,a=this._get(o,"onClose"),a&&a.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),a=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(a,i+("M"===s?this._get(a,"showCurrentAtPos"):0),s),this._updateDatepicker(a))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),a=this._getInst(n[0]);a["selected"+("M"===s?"Month":"Year")]=a["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(a),this._adjustDate(n)},_selectDay:function(e,i,s,n){var a,r=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(r[0])||(a=this._getInst(r[0]),a.selectedDay=a.currentDay=t("a",n).html(),a.selectedMonth=a.currentMonth=i,a.selectedYear=a.currentYear=s,this._selectDate(e,this._formatDate(a,a.currentDay,a.currentMonth,a.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),a=this._getInst(n[0]);i=null!=i?i:this._formatDate(a),a.input&&a.input.val(i),this._updateAlternate(a),s=this._get(a,"onSelect"),s?s.apply(a.input?a.input[0]:null,[i,a]):a.input&&a.input.trigger("change"),a.inline?this._updateDatepicker(a):(this._hideDatepicker(),this._lastInput=a.input[0],"object"!=typeof a.input[0]&&a.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,a=this._get(e,"altField");a&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(a).each(function(){t(this).val(n)}))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(i,s,n){if(null==i||null==s)throw"Invalid arguments";if(s="object"==typeof s?""+s:s+"",""===s)return null;var a,r,o,h,l=0,c=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof c?c:(new Date).getFullYear()%100+parseInt(c,10),d=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,p=(n?n.dayNames:null)||this._defaults.dayNames,f=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,m=(n?n.monthNames:null)||this._defaults.monthNames,g=-1,v=-1,_=-1,b=-1,y=!1,x=function(t){var e=i.length>a+1&&i.charAt(a+1)===t;return e&&a++,e},k=function(t){var e=x(t),i="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n=RegExp("^\\d{1,"+i+"}"),a=s.substring(l).match(n);if(!a)throw"Missing number at position "+l;return l+=a[0].length,parseInt(a[0],10)},w=function(i,n,a){var r=-1,o=t.map(x(i)?a:n,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(o,function(t,i){var n=i[1];return s.substr(l,n.length).toLowerCase()===n.toLowerCase()?(r=i[0],l+=n.length,!1):e}),-1!==r)return r+1;throw"Unknown name at position "+l},D=function(){if(s.charAt(l)!==i.charAt(a))throw"Unexpected literal at position "+l;l++};for(a=0;i.length>a;a++)if(y)"'"!==i.charAt(a)||x("'")?D():y=!1;else switch(i.charAt(a)){case"d":_=k("d");break;case"D":w("D",d,p);break;case"o":b=k("o");break;case"m":v=k("m");break;case"M":v=w("M",f,m);break;case"y":g=k("y");break;case"@":h=new Date(k("@")),g=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"!":h=new Date((k("!")-this._ticksTo1970)/1e4),g=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"'":x("'")?D():y=!0;break;default:D()}if(s.length>l&&(o=s.substr(l),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=g?0:-100)),b>-1)for(v=1,_=b;;){if(r=this._getDaysInMonth(g,v-1),r>=_)break;v++,_-=r}if(h=this._daylightSavingAdjust(new Date(g,v-1,_)),h.getFullYear()!==g||h.getMonth()+1!==v||h.getDate()!==_)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,a=(i?i.dayNames:null)||this._defaults.dayNames,r=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,o=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,a);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),r,o);break;case"y":u+=h("y")?e.getFullYear():(10>e.getYear()%100?"0":"")+e.getYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,i){return t.settings[i]!==e?t.settings[i]:this._defaults[i]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),a=n,r=this._getFormatConfig(t);try{a=this.parseDate(i,s,r)||n}catch(o){s=e?"":s}t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),t.currentDay=s?a.getDate():0,t.currentMonth=s?a.getMonth():0,t.currentYear=s?a.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},a=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,a=n.getFullYear(),r=n.getMonth(),o=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":o+=parseInt(l[1],10);break;case"w":case"W":o+=7*parseInt(l[1],10);break;case"m":case"M":r+=parseInt(l[1],10),o=Math.min(o,t.datepicker._getDaysInMonth(a,r));break;case"y":case"Y":a+=parseInt(l[1],10),o=Math.min(o,t.datepicker._getDaysInMonth(a,r))}l=h.exec(i)}return new Date(a,r,o)},r=null==i||""===i?s:"string"==typeof i?a(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return r=r&&"Invalid Date"==""+r?s:r,r&&(r.setHours(0),r.setMinutes(0),r.setSeconds(0),r.setMilliseconds(0)),this._daylightSavingAdjust(r)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,a=t.selectedYear,r=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=r.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=r.getMonth(),t.drawYear=t.selectedYear=t.currentYear=r.getFullYear(),n===t.selectedMonth&&a===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,a,r,o,h,l,c,u,d,p,f,m,g,v,_,b,y,x,k,w,D,T,C,S,M,N,I,P,A,z,H,E,F,O,j,W,R=new Date,L=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),B=this._get(t,"showButtonPanel"),K=this._get(t,"hideIfNoPrevNext"),J=this._get(t,"navigationAsDateFormat"),Q=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),U=this._get(t,"stepMonths"),q=1!==Q[0]||1!==Q[1],X=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),G=this._getMinMaxDate(t,"min"),$=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),$)for(e=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-Q[0]*Q[1]+1,$.getDate())),e=G&&G>e?G:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=J?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-U,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":K?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=J?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+U,1)),this._getFormatConfig(t)):n,a=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":K?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",r=this._get(t,"currentText"),o=this._get(t,"gotoCurrent")&&t.currentDay?X:L,r=J?this.formatDate(r,o,this._getFormatConfig(t)):r,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,o)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+r+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),m=this._get(t,"monthNamesShort"),g=this._get(t,"beforeShowDay"),v=this._get(t,"showOtherMonths"),_=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;Q[0]>k;k++){for(w="",this.maxRows=4,D=0;Q[1]>D;D++){if(T=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),C=" ui-corner-all",S="",q){if(S+="<div class='ui-datepicker-group",Q[1]>1)switch(D){case 0:S+=" ui-datepicker-group-first",C=" ui-corner-"+(Y?"right":"left");break;case Q[1]-1:S+=" ui-datepicker-group-last",C=" ui-corner-"+(Y?"left":"right");break;default:S+=" ui-datepicker-group-middle",C=""}S+="'>"}for(S+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+C+"'>"+(/all|left/.test(C)&&0===k?Y?a:s:"")+(/all|right/.test(C)&&0===k?Y?s:a:"")+this._generateMonthYearHeader(t,Z,te,G,$,k>0||D>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",M=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",x=0;7>x;x++)N=(x+c)%7,M+="<th"+((x+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[N]+"'>"+p[N]+"</span></th>";for(S+=M+"</tr></thead><tbody>",I=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,I)),P=(this._getFirstDayOfMonth(te,Z)-c+7)%7,A=Math.ceil((P+I)/7),z=q?this.maxRows>A?this.maxRows:A:A,this.maxRows=z,H=this._daylightSavingAdjust(new Date(te,Z,1-P)),E=0;z>E;E++){for(S+="<tr>",F=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(H)+"</td>":"",x=0;7>x;x++)O=g?g.apply(t.input?t.input[0]:null,[H]):[!0,""],j=H.getMonth()!==Z,W=j&&!_||!O[0]||G&&G>H||$&&H>$,F+="<td class='"+((x+c+6)%7>=5?" ui-datepicker-week-end":"")+(j?" ui-datepicker-other-month":"")+(H.getTime()===T.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===H.getTime()&&b.getTime()===T.getTime()?" "+this._dayOverClass:"")+(W?" "+this._unselectableClass+" ui-state-disabled":"")+(j&&!v?"":" "+O[1]+(H.getTime()===X.getTime()?" "+this._currentClass:"")+(H.getTime()===L.getTime()?" ui-datepicker-today":""))+"'"+(j&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(W?"":" data-handler='selectDay' data-event='click' data-month='"+H.getMonth()+"' data-year='"+H.getFullYear()+"'")+">"+(j&&!v?"&#xa0;":W?"<span class='ui-state-default'>"+H.getDate()+"</span>":"<a class='ui-state-default"+(H.getTime()===L.getTime()?" ui-state-highlight":"")+(H.getTime()===X.getTime()?" ui-state-active":"")+(j?" ui-priority-secondary":"")+"' href='#'>"+H.getDate()+"</a>")+"</td>",H.setDate(H.getDate()+1),H=this._daylightSavingAdjust(H);S+=F+"</tr>"}Z++,Z>11&&(Z=0,te++),S+="</tbody></table>"+(q?"</div>"+(Q[0]>0&&D===Q[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),w+=S}y+=w}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,a,r,o){var h,l,c,u,d,p,f,m,g=this._get(t,"changeMonth"),v=this._get(t,"changeYear"),_=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(a||!g)y+="<span class='ui-datepicker-month'>"+r[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+o[c]+"</option>");y+="</select>"}if(_||(b+=y+(!a&&g&&v?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",a||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);
    5 return isNaN(e)?d:e},f=p(u[0]),m=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=n?Math.min(m,n.getFullYear()):m,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),_&&(b+=(!a&&g&&v?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.drawYear+("Y"===i?e:0),n=t.drawMonth+("M"===i?e:0),a=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),r=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,a)));t.selectedDay=r.getDate(),t.drawMonth=t.selectedMonth=r.getMonth(),t.drawYear=t.selectedYear=r.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),a=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&a.setDate(this._getDaysInMonth(a.getFullYear(),a.getMonth())),this._isInRange(t,a)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),a=this._getMinMaxDate(t,"max"),r=null,o=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),r=parseInt(i[0],10),o=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(r+=s),i[1].match(/[+\-].*/)&&(o+=s)),(!n||e.getTime()>=n.getTime())&&(!a||e.getTime()<=a.getTime())&&(!r||e.getFullYear()>=r)&&(!o||o>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).mousedown(t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new i,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.10.4"})(jQuery);
     1/*!
     2 * jQuery UI Datepicker 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/datepicker/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define([
     16            "jquery",
     17            "./core"
     18        ], factory );
     19    } else {
     20
     21        // Browser globals
     22        factory( jQuery );
     23    }
     24}(function( $ ) {
     25
     26$.extend($.ui, { datepicker: { version: "1.11.1" } });
     27
     28var datepicker_instActive;
     29
     30function datepicker_getZindex( elem ) {
     31    var position, value;
     32    while ( elem.length && elem[ 0 ] !== document ) {
     33        // Ignore z-index if position is set to a value where z-index is ignored by the browser
     34        // This makes behavior of this function consistent across browsers
     35        // WebKit always returns auto if the element is positioned
     36        position = elem.css( "position" );
     37        if ( position === "absolute" || position === "relative" || position === "fixed" ) {
     38            // IE returns 0 when zIndex is not specified
     39            // other browsers return a string
     40            // we ignore the case of nested elements with an explicit value of 0
     41            // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
     42            value = parseInt( elem.css( "zIndex" ), 10 );
     43            if ( !isNaN( value ) && value !== 0 ) {
     44                return value;
     45            }
     46        }
     47        elem = elem.parent();
     48    }
     49
     50    return 0;
     51}
     52/* Date picker manager.
     53   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
     54   Settings for (groups of) date pickers are maintained in an instance object,
     55   allowing multiple different settings on the same page. */
     56
     57function Datepicker() {
     58    this._curInst = null; // The current instance in use
     59    this._keyEvent = false; // If the last event was a key event
     60    this._disabledInputs = []; // List of date picker inputs that have been disabled
     61    this._datepickerShowing = false; // True if the popup picker is showing , false if not
     62    this._inDialog = false; // True if showing within a "dialog", false if not
     63    this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
     64    this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
     65    this._appendClass = "ui-datepicker-append"; // The name of the append marker class
     66    this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
     67    this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
     68    this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
     69    this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
     70    this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
     71    this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
     72    this.regional = []; // Available regional settings, indexed by language code
     73    this.regional[""] = { // Default regional settings
     74        closeText: "Done", // Display text for close link
     75        prevText: "Prev", // Display text for previous month link
     76        nextText: "Next", // Display text for next month link
     77        currentText: "Today", // Display text for current month link
     78        monthNames: ["January","February","March","April","May","June",
     79            "July","August","September","October","November","December"], // Names of months for drop-down and formatting
     80        monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
     81        dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
     82        dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
     83        dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
     84        weekHeader: "Wk", // Column header for week of the year
     85        dateFormat: "mm/dd/yy", // See format options on parseDate
     86        firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
     87        isRTL: false, // True if right-to-left language, false if left-to-right
     88        showMonthAfterYear: false, // True if the year select precedes month, false for month then year
     89        yearSuffix: "" // Additional text to append to the year in the month headers
     90    };
     91    this._defaults = { // Global defaults for all the date picker instances
     92        showOn: "focus", // "focus" for popup on focus,
     93            // "button" for trigger button, or "both" for either
     94        showAnim: "fadeIn", // Name of jQuery animation for popup
     95        showOptions: {}, // Options for enhanced animations
     96        defaultDate: null, // Used when field is blank: actual date,
     97            // +/-number for offset from today, null for today
     98        appendText: "", // Display text following the input box, e.g. showing the format
     99        buttonText: "...", // Text for trigger button
     100        buttonImage: "", // URL for trigger button image
     101        buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
     102        hideIfNoPrevNext: false, // True to hide next/previous month links
     103            // if not applicable, false to just disable them
     104        navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
     105        gotoCurrent: false, // True if today link goes back to current selection instead
     106        changeMonth: false, // True if month can be selected directly, false if only prev/next
     107        changeYear: false, // True if year can be selected directly, false if only prev/next
     108        yearRange: "c-10:c+10", // Range of years to display in drop-down,
     109            // either relative to today's year (-nn:+nn), relative to currently displayed year
     110            // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
     111        showOtherMonths: false, // True to show dates in other months, false to leave blank
     112        selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
     113        showWeek: false, // True to show week of the year, false to not show it
     114        calculateWeek: this.iso8601Week, // How to calculate the week of the year,
     115            // takes a Date and returns the number of the week for it
     116        shortYearCutoff: "+10", // Short year values < this are in the current century,
     117            // > this are in the previous century,
     118            // string value starting with "+" for current year + value
     119        minDate: null, // The earliest selectable date, or null for no limit
     120        maxDate: null, // The latest selectable date, or null for no limit
     121        duration: "fast", // Duration of display/closure
     122        beforeShowDay: null, // Function that takes a date and returns an array with
     123            // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
     124            // [2] = cell title (optional), e.g. $.datepicker.noWeekends
     125        beforeShow: null, // Function that takes an input field and
     126            // returns a set of custom settings for the date picker
     127        onSelect: null, // Define a callback function when a date is selected
     128        onChangeMonthYear: null, // Define a callback function when the month or year is changed
     129        onClose: null, // Define a callback function when the datepicker is closed
     130        numberOfMonths: 1, // Number of months to show at a time
     131        showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
     132        stepMonths: 1, // Number of months to step back/forward
     133        stepBigMonths: 12, // Number of months to step back/forward for the big links
     134        altField: "", // Selector for an alternate field to store selected dates into
     135        altFormat: "", // The date format to use for the alternate field
     136        constrainInput: true, // The input is constrained by the current date format
     137        showButtonPanel: false, // True to show button panel, false to not show it
     138        autoSize: false, // True to size the input for the date format, false to leave as is
     139        disabled: false // The initial disabled state
     140    };
     141    $.extend(this._defaults, this.regional[""]);
     142    this.regional.en = $.extend( true, {}, this.regional[ "" ]);
     143    this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
     144    this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
     145}
     146
     147$.extend(Datepicker.prototype, {
     148    /* Class name added to elements to indicate already configured with a date picker. */
     149    markerClassName: "hasDatepicker",
     150
     151    //Keep track of the maximum number of rows displayed (see #7043)
     152    maxRows: 4,
     153
     154    // TODO rename to "widget" when switching to widget factory
     155    _widgetDatepicker: function() {
     156        return this.dpDiv;
     157    },
     158
     159    /* Override the default settings for all instances of the date picker.
     160     * @param  settings  object - the new settings to use as defaults (anonymous object)
     161     * @return the manager object
     162     */
     163    setDefaults: function(settings) {
     164        datepicker_extendRemove(this._defaults, settings || {});
     165        return this;
     166    },
     167
     168    /* Attach the date picker to a jQuery selection.
     169     * @param  target   element - the target input field or division or span
     170     * @param  settings  object - the new settings to use for this date picker instance (anonymous)
     171     */
     172    _attachDatepicker: function(target, settings) {
     173        var nodeName, inline, inst;
     174        nodeName = target.nodeName.toLowerCase();
     175        inline = (nodeName === "div" || nodeName === "span");
     176        if (!target.id) {
     177            this.uuid += 1;
     178            target.id = "dp" + this.uuid;
     179        }
     180        inst = this._newInst($(target), inline);
     181        inst.settings = $.extend({}, settings || {});
     182        if (nodeName === "input") {
     183            this._connectDatepicker(target, inst);
     184        } else if (inline) {
     185            this._inlineDatepicker(target, inst);
     186        }
     187    },
     188
     189    /* Create a new instance object. */
     190    _newInst: function(target, inline) {
     191        var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
     192        return {id: id, input: target, // associated target
     193            selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
     194            drawMonth: 0, drawYear: 0, // month being drawn
     195            inline: inline, // is datepicker inline or not
     196            dpDiv: (!inline ? this.dpDiv : // presentation div
     197            datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
     198    },
     199
     200    /* Attach the date picker to an input field. */
     201    _connectDatepicker: function(target, inst) {
     202        var input = $(target);
     203        inst.append = $([]);
     204        inst.trigger = $([]);
     205        if (input.hasClass(this.markerClassName)) {
     206            return;
     207        }
     208        this._attachments(input, inst);
     209        input.addClass(this.markerClassName).keydown(this._doKeyDown).
     210            keypress(this._doKeyPress).keyup(this._doKeyUp);
     211        this._autoSize(inst);
     212        $.data(target, "datepicker", inst);
     213        //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
     214        if( inst.settings.disabled ) {
     215            this._disableDatepicker( target );
     216        }
     217    },
     218
     219    /* Make attachments based on settings. */
     220    _attachments: function(input, inst) {
     221        var showOn, buttonText, buttonImage,
     222            appendText = this._get(inst, "appendText"),
     223            isRTL = this._get(inst, "isRTL");
     224
     225        if (inst.append) {
     226            inst.append.remove();
     227        }
     228        if (appendText) {
     229            inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
     230            input[isRTL ? "before" : "after"](inst.append);
     231        }
     232
     233        input.unbind("focus", this._showDatepicker);
     234
     235        if (inst.trigger) {
     236            inst.trigger.remove();
     237        }
     238
     239        showOn = this._get(inst, "showOn");
     240        if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
     241            input.focus(this._showDatepicker);
     242        }
     243        if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
     244            buttonText = this._get(inst, "buttonText");
     245            buttonImage = this._get(inst, "buttonImage");
     246            inst.trigger = $(this._get(inst, "buttonImageOnly") ?
     247                $("<img/>").addClass(this._triggerClass).
     248                    attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
     249                $("<button type='button'></button>").addClass(this._triggerClass).
     250                    html(!buttonImage ? buttonText : $("<img/>").attr(
     251                    { src:buttonImage, alt:buttonText, title:buttonText })));
     252            input[isRTL ? "before" : "after"](inst.trigger);
     253            inst.trigger.click(function() {
     254                if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
     255                    $.datepicker._hideDatepicker();
     256                } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
     257                    $.datepicker._hideDatepicker();
     258                    $.datepicker._showDatepicker(input[0]);
     259                } else {
     260                    $.datepicker._showDatepicker(input[0]);
     261                }
     262                return false;
     263            });
     264        }
     265    },
     266
     267    /* Apply the maximum length for the date format. */
     268    _autoSize: function(inst) {
     269        if (this._get(inst, "autoSize") && !inst.inline) {
     270            var findMax, max, maxI, i,
     271                date = new Date(2009, 12 - 1, 20), // Ensure double digits
     272                dateFormat = this._get(inst, "dateFormat");
     273
     274            if (dateFormat.match(/[DM]/)) {
     275                findMax = function(names) {
     276                    max = 0;
     277                    maxI = 0;
     278                    for (i = 0; i < names.length; i++) {
     279                        if (names[i].length > max) {
     280                            max = names[i].length;
     281                            maxI = i;
     282                        }
     283                    }
     284                    return maxI;
     285                };
     286                date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
     287                    "monthNames" : "monthNamesShort"))));
     288                date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
     289                    "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
     290            }
     291            inst.input.attr("size", this._formatDate(inst, date).length);
     292        }
     293    },
     294
     295    /* Attach an inline date picker to a div. */
     296    _inlineDatepicker: function(target, inst) {
     297        var divSpan = $(target);
     298        if (divSpan.hasClass(this.markerClassName)) {
     299            return;
     300        }
     301        divSpan.addClass(this.markerClassName).append(inst.dpDiv);
     302        $.data(target, "datepicker", inst);
     303        this._setDate(inst, this._getDefaultDate(inst), true);
     304        this._updateDatepicker(inst);
     305        this._updateAlternate(inst);
     306        //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
     307        if( inst.settings.disabled ) {
     308            this._disableDatepicker( target );
     309        }
     310        // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
     311        // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
     312        inst.dpDiv.css( "display", "block" );
     313    },
     314
     315    /* Pop-up the date picker in a "dialog" box.
     316     * @param  input element - ignored
     317     * @param  date string or Date - the initial date to display
     318     * @param  onSelect  function - the function to call when a date is selected
     319     * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
     320     * @param  pos int[2] - coordinates for the dialog's position within the screen or
     321     *                  event - with x/y coordinates or
     322     *                  leave empty for default (screen centre)
     323     * @return the manager object
     324     */
     325    _dialogDatepicker: function(input, date, onSelect, settings, pos) {
     326        var id, browserWidth, browserHeight, scrollX, scrollY,
     327            inst = this._dialogInst; // internal instance
     328
     329        if (!inst) {
     330            this.uuid += 1;
     331            id = "dp" + this.uuid;
     332            this._dialogInput = $("<input type='text' id='" + id +
     333                "' style='position: absolute; top: -100px; width: 0px;'/>");
     334            this._dialogInput.keydown(this._doKeyDown);
     335            $("body").append(this._dialogInput);
     336            inst = this._dialogInst = this._newInst(this._dialogInput, false);
     337            inst.settings = {};
     338            $.data(this._dialogInput[0], "datepicker", inst);
     339        }
     340        datepicker_extendRemove(inst.settings, settings || {});
     341        date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
     342        this._dialogInput.val(date);
     343
     344        this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
     345        if (!this._pos) {
     346            browserWidth = document.documentElement.clientWidth;
     347            browserHeight = document.documentElement.clientHeight;
     348            scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
     349            scrollY = document.documentElement.scrollTop || document.body.scrollTop;
     350            this._pos = // should use actual width/height below
     351                [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
     352        }
     353
     354        // move input on screen for focus, but hidden behind dialog
     355        this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
     356        inst.settings.onSelect = onSelect;
     357        this._inDialog = true;
     358        this.dpDiv.addClass(this._dialogClass);
     359        this._showDatepicker(this._dialogInput[0]);
     360        if ($.blockUI) {
     361            $.blockUI(this.dpDiv);
     362        }
     363        $.data(this._dialogInput[0], "datepicker", inst);
     364        return this;
     365    },
     366
     367    /* Detach a datepicker from its control.
     368     * @param  target   element - the target input field or division or span
     369     */
     370    _destroyDatepicker: function(target) {
     371        var nodeName,
     372            $target = $(target),
     373            inst = $.data(target, "datepicker");
     374
     375        if (!$target.hasClass(this.markerClassName)) {
     376            return;
     377        }
     378
     379        nodeName = target.nodeName.toLowerCase();
     380        $.removeData(target, "datepicker");
     381        if (nodeName === "input") {
     382            inst.append.remove();
     383            inst.trigger.remove();
     384            $target.removeClass(this.markerClassName).
     385                unbind("focus", this._showDatepicker).
     386                unbind("keydown", this._doKeyDown).
     387                unbind("keypress", this._doKeyPress).
     388                unbind("keyup", this._doKeyUp);
     389        } else if (nodeName === "div" || nodeName === "span") {
     390            $target.removeClass(this.markerClassName).empty();
     391        }
     392    },
     393
     394    /* Enable the date picker to a jQuery selection.
     395     * @param  target   element - the target input field or division or span
     396     */
     397    _enableDatepicker: function(target) {
     398        var nodeName, inline,
     399            $target = $(target),
     400            inst = $.data(target, "datepicker");
     401
     402        if (!$target.hasClass(this.markerClassName)) {
     403            return;
     404        }
     405
     406        nodeName = target.nodeName.toLowerCase();
     407        if (nodeName === "input") {
     408            target.disabled = false;
     409            inst.trigger.filter("button").
     410                each(function() { this.disabled = false; }).end().
     411                filter("img").css({opacity: "1.0", cursor: ""});
     412        } else if (nodeName === "div" || nodeName === "span") {
     413            inline = $target.children("." + this._inlineClass);
     414            inline.children().removeClass("ui-state-disabled");
     415            inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
     416                prop("disabled", false);
     417        }
     418        this._disabledInputs = $.map(this._disabledInputs,
     419            function(value) { return (value === target ? null : value); }); // delete entry
     420    },
     421
     422    /* Disable the date picker to a jQuery selection.
     423     * @param  target   element - the target input field or division or span
     424     */
     425    _disableDatepicker: function(target) {
     426        var nodeName, inline,
     427            $target = $(target),
     428            inst = $.data(target, "datepicker");
     429
     430        if (!$target.hasClass(this.markerClassName)) {
     431            return;
     432        }
     433
     434        nodeName = target.nodeName.toLowerCase();
     435        if (nodeName === "input") {
     436            target.disabled = true;
     437            inst.trigger.filter("button").
     438                each(function() { this.disabled = true; }).end().
     439                filter("img").css({opacity: "0.5", cursor: "default"});
     440        } else if (nodeName === "div" || nodeName === "span") {
     441            inline = $target.children("." + this._inlineClass);
     442            inline.children().addClass("ui-state-disabled");
     443            inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
     444                prop("disabled", true);
     445        }
     446        this._disabledInputs = $.map(this._disabledInputs,
     447            function(value) { return (value === target ? null : value); }); // delete entry
     448        this._disabledInputs[this._disabledInputs.length] = target;
     449    },
     450
     451    /* Is the first field in a jQuery collection disabled as a datepicker?
     452     * @param  target   element - the target input field or division or span
     453     * @return boolean - true if disabled, false if enabled
     454     */
     455    _isDisabledDatepicker: function(target) {
     456        if (!target) {
     457            return false;
     458        }
     459        for (var i = 0; i < this._disabledInputs.length; i++) {
     460            if (this._disabledInputs[i] === target) {
     461                return true;
     462            }
     463        }
     464        return false;
     465    },
     466
     467    /* Retrieve the instance data for the target control.
     468     * @param  target  element - the target input field or division or span
     469     * @return  object - the associated instance data
     470     * @throws  error if a jQuery problem getting data
     471     */
     472    _getInst: function(target) {
     473        try {
     474            return $.data(target, "datepicker");
     475        }
     476        catch (err) {
     477            throw "Missing instance data for this datepicker";
     478        }
     479    },
     480
     481    /* Update or retrieve the settings for a date picker attached to an input field or division.
     482     * @param  target  element - the target input field or division or span
     483     * @param  name object - the new settings to update or
     484     *              string - the name of the setting to change or retrieve,
     485     *              when retrieving also "all" for all instance settings or
     486     *              "defaults" for all global defaults
     487     * @param  value   any - the new value for the setting
     488     *              (omit if above is an object or to retrieve a value)
     489     */
     490    _optionDatepicker: function(target, name, value) {
     491        var settings, date, minDate, maxDate,
     492            inst = this._getInst(target);
     493
     494        if (arguments.length === 2 && typeof name === "string") {
     495            return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
     496                (inst ? (name === "all" ? $.extend({}, inst.settings) :
     497                this._get(inst, name)) : null));
     498        }
     499
     500        settings = name || {};
     501        if (typeof name === "string") {
     502            settings = {};
     503            settings[name] = value;
     504        }
     505
     506        if (inst) {
     507            if (this._curInst === inst) {
     508                this._hideDatepicker();
     509            }
     510
     511            date = this._getDateDatepicker(target, true);
     512            minDate = this._getMinMaxDate(inst, "min");
     513            maxDate = this._getMinMaxDate(inst, "max");
     514            datepicker_extendRemove(inst.settings, settings);
     515            // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
     516            if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
     517                inst.settings.minDate = this._formatDate(inst, minDate);
     518            }
     519            if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
     520                inst.settings.maxDate = this._formatDate(inst, maxDate);
     521            }
     522            if ( "disabled" in settings ) {
     523                if ( settings.disabled ) {
     524                    this._disableDatepicker(target);
     525                } else {
     526                    this._enableDatepicker(target);
     527                }
     528            }
     529            this._attachments($(target), inst);
     530            this._autoSize(inst);
     531            this._setDate(inst, date);
     532            this._updateAlternate(inst);
     533            this._updateDatepicker(inst);
     534        }
     535    },
     536
     537    // change method deprecated
     538    _changeDatepicker: function(target, name, value) {
     539        this._optionDatepicker(target, name, value);
     540    },
     541
     542    /* Redraw the date picker attached to an input field or division.
     543     * @param  target  element - the target input field or division or span
     544     */
     545    _refreshDatepicker: function(target) {
     546        var inst = this._getInst(target);
     547        if (inst) {
     548            this._updateDatepicker(inst);
     549        }
     550    },
     551
     552    /* Set the dates for a jQuery selection.
     553     * @param  target element - the target input field or division or span
     554     * @param  date Date - the new date
     555     */
     556    _setDateDatepicker: function(target, date) {
     557        var inst = this._getInst(target);
     558        if (inst) {
     559            this._setDate(inst, date);
     560            this._updateDatepicker(inst);
     561            this._updateAlternate(inst);
     562        }
     563    },
     564
     565    /* Get the date(s) for the first entry in a jQuery selection.
     566     * @param  target element - the target input field or division or span
     567     * @param  noDefault boolean - true if no default date is to be used
     568     * @return Date - the current date
     569     */
     570    _getDateDatepicker: function(target, noDefault) {
     571        var inst = this._getInst(target);
     572        if (inst && !inst.inline) {
     573            this._setDateFromField(inst, noDefault);
     574        }
     575        return (inst ? this._getDate(inst) : null);
     576    },
     577
     578    /* Handle keystrokes. */
     579    _doKeyDown: function(event) {
     580        var onSelect, dateStr, sel,
     581            inst = $.datepicker._getInst(event.target),
     582            handled = true,
     583            isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
     584
     585        inst._keyEvent = true;
     586        if ($.datepicker._datepickerShowing) {
     587            switch (event.keyCode) {
     588                case 9: $.datepicker._hideDatepicker();
     589                        handled = false;
     590                        break; // hide on tab out
     591                case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
     592                                    $.datepicker._currentClass + ")", inst.dpDiv);
     593                        if (sel[0]) {
     594                            $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
     595                        }
     596
     597                        onSelect = $.datepicker._get(inst, "onSelect");
     598                        if (onSelect) {
     599                            dateStr = $.datepicker._formatDate(inst);
     600
     601                            // trigger custom callback
     602                            onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
     603                        } else {
     604                            $.datepicker._hideDatepicker();
     605                        }
     606
     607                        return false; // don't submit the form
     608                case 27: $.datepicker._hideDatepicker();
     609                        break; // hide on escape
     610                case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
     611                            -$.datepicker._get(inst, "stepBigMonths") :
     612                            -$.datepicker._get(inst, "stepMonths")), "M");
     613                        break; // previous month/year on page up/+ ctrl
     614                case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
     615                            +$.datepicker._get(inst, "stepBigMonths") :
     616                            +$.datepicker._get(inst, "stepMonths")), "M");
     617                        break; // next month/year on page down/+ ctrl
     618                case 35: if (event.ctrlKey || event.metaKey) {
     619                            $.datepicker._clearDate(event.target);
     620                        }
     621                        handled = event.ctrlKey || event.metaKey;
     622                        break; // clear on ctrl or command +end
     623                case 36: if (event.ctrlKey || event.metaKey) {
     624                            $.datepicker._gotoToday(event.target);
     625                        }
     626                        handled = event.ctrlKey || event.metaKey;
     627                        break; // current on ctrl or command +home
     628                case 37: if (event.ctrlKey || event.metaKey) {
     629                            $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
     630                        }
     631                        handled = event.ctrlKey || event.metaKey;
     632                        // -1 day on ctrl or command +left
     633                        if (event.originalEvent.altKey) {
     634                            $.datepicker._adjustDate(event.target, (event.ctrlKey ?
     635                                -$.datepicker._get(inst, "stepBigMonths") :
     636                                -$.datepicker._get(inst, "stepMonths")), "M");
     637                        }
     638                        // next month/year on alt +left on Mac
     639                        break;
     640                case 38: if (event.ctrlKey || event.metaKey) {
     641                            $.datepicker._adjustDate(event.target, -7, "D");
     642                        }
     643                        handled = event.ctrlKey || event.metaKey;
     644                        break; // -1 week on ctrl or command +up
     645                case 39: if (event.ctrlKey || event.metaKey) {
     646                            $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
     647                        }
     648                        handled = event.ctrlKey || event.metaKey;
     649                        // +1 day on ctrl or command +right
     650                        if (event.originalEvent.altKey) {
     651                            $.datepicker._adjustDate(event.target, (event.ctrlKey ?
     652                                +$.datepicker._get(inst, "stepBigMonths") :
     653                                +$.datepicker._get(inst, "stepMonths")), "M");
     654                        }
     655                        // next month/year on alt +right
     656                        break;
     657                case 40: if (event.ctrlKey || event.metaKey) {
     658                            $.datepicker._adjustDate(event.target, +7, "D");
     659                        }
     660                        handled = event.ctrlKey || event.metaKey;
     661                        break; // +1 week on ctrl or command +down
     662                default: handled = false;
     663            }
     664        } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
     665            $.datepicker._showDatepicker(this);
     666        } else {
     667            handled = false;
     668        }
     669
     670        if (handled) {
     671            event.preventDefault();
     672            event.stopPropagation();
     673        }
     674    },
     675
     676    /* Filter entered characters - based on date format. */
     677    _doKeyPress: function(event) {
     678        var chars, chr,
     679            inst = $.datepicker._getInst(event.target);
     680
     681        if ($.datepicker._get(inst, "constrainInput")) {
     682            chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
     683            chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
     684            return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
     685        }
     686    },
     687
     688    /* Synchronise manual entry and field/alternate field. */
     689    _doKeyUp: function(event) {
     690        var date,
     691            inst = $.datepicker._getInst(event.target);
     692
     693        if (inst.input.val() !== inst.lastVal) {
     694            try {
     695                date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
     696                    (inst.input ? inst.input.val() : null),
     697                    $.datepicker._getFormatConfig(inst));
     698
     699                if (date) { // only if valid
     700                    $.datepicker._setDateFromField(inst);
     701                    $.datepicker._updateAlternate(inst);
     702                    $.datepicker._updateDatepicker(inst);
     703                }
     704            }
     705            catch (err) {
     706            }
     707        }
     708        return true;
     709    },
     710
     711    /* Pop-up the date picker for a given input field.
     712     * If false returned from beforeShow event handler do not show.
     713     * @param  input  element - the input field attached to the date picker or
     714     *                  event - if triggered by focus
     715     */
     716    _showDatepicker: function(input) {
     717        input = input.target || input;
     718        if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
     719            input = $("input", input.parentNode)[0];
     720        }
     721
     722        if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
     723            return;
     724        }
     725
     726        var inst, beforeShow, beforeShowSettings, isFixed,
     727            offset, showAnim, duration;
     728
     729        inst = $.datepicker._getInst(input);
     730        if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
     731            $.datepicker._curInst.dpDiv.stop(true, true);
     732            if ( inst && $.datepicker._datepickerShowing ) {
     733                $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
     734            }
     735        }
     736
     737        beforeShow = $.datepicker._get(inst, "beforeShow");
     738        beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
     739        if(beforeShowSettings === false){
     740            return;
     741        }
     742        datepicker_extendRemove(inst.settings, beforeShowSettings);
     743
     744        inst.lastVal = null;
     745        $.datepicker._lastInput = input;
     746        $.datepicker._setDateFromField(inst);
     747
     748        if ($.datepicker._inDialog) { // hide cursor
     749            input.value = "";
     750        }
     751        if (!$.datepicker._pos) { // position below input
     752            $.datepicker._pos = $.datepicker._findPos(input);
     753            $.datepicker._pos[1] += input.offsetHeight; // add the height
     754        }
     755
     756        isFixed = false;
     757        $(input).parents().each(function() {
     758            isFixed |= $(this).css("position") === "fixed";
     759            return !isFixed;
     760        });
     761
     762        offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
     763        $.datepicker._pos = null;
     764        //to avoid flashes on Firefox
     765        inst.dpDiv.empty();
     766        // determine sizing offscreen
     767        inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
     768        $.datepicker._updateDatepicker(inst);
     769        // fix width for dynamic number of date pickers
     770        // and adjust position before showing
     771        offset = $.datepicker._checkOffset(inst, offset, isFixed);
     772        inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
     773            "static" : (isFixed ? "fixed" : "absolute")), display: "none",
     774            left: offset.left + "px", top: offset.top + "px"});
     775
     776        if (!inst.inline) {
     777            showAnim = $.datepicker._get(inst, "showAnim");
     778            duration = $.datepicker._get(inst, "duration");
     779            inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
     780            $.datepicker._datepickerShowing = true;
     781
     782            if ( $.effects && $.effects.effect[ showAnim ] ) {
     783                inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
     784            } else {
     785                inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
     786            }
     787
     788            if ( $.datepicker._shouldFocusInput( inst ) ) {
     789                inst.input.focus();
     790            }
     791
     792            $.datepicker._curInst = inst;
     793        }
     794    },
     795
     796    /* Generate the date picker content. */
     797    _updateDatepicker: function(inst) {
     798        this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
     799        datepicker_instActive = inst; // for delegate hover events
     800        inst.dpDiv.empty().append(this._generateHTML(inst));
     801        this._attachHandlers(inst);
     802
     803        var origyearshtml,
     804            numMonths = this._getNumberOfMonths(inst),
     805            cols = numMonths[1],
     806            width = 17,
     807            activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
     808
     809        if ( activeCell.length > 0 ) {
     810            datepicker_handleMouseover.apply( activeCell.get( 0 ) );
     811        }
     812
     813        inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
     814        if (cols > 1) {
     815            inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
     816        }
     817        inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
     818            "Class"]("ui-datepicker-multi");
     819        inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
     820            "Class"]("ui-datepicker-rtl");
     821
     822        if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
     823            inst.input.focus();
     824        }
     825
     826        // deffered render of the years select (to avoid flashes on Firefox)
     827        if( inst.yearshtml ){
     828            origyearshtml = inst.yearshtml;
     829            setTimeout(function(){
     830                //assure that inst.yearshtml didn't change.
     831                if( origyearshtml === inst.yearshtml && inst.yearshtml ){
     832                    inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
     833                }
     834                origyearshtml = inst.yearshtml = null;
     835            }, 0);
     836        }
     837    },
     838
     839    // #6694 - don't focus the input if it's already focused
     840    // this breaks the change event in IE
     841    // Support: IE and jQuery <1.9
     842    _shouldFocusInput: function( inst ) {
     843        return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
     844    },
     845
     846    /* Check positioning to remain on screen. */
     847    _checkOffset: function(inst, offset, isFixed) {
     848        var dpWidth = inst.dpDiv.outerWidth(),
     849            dpHeight = inst.dpDiv.outerHeight(),
     850            inputWidth = inst.input ? inst.input.outerWidth() : 0,
     851            inputHeight = inst.input ? inst.input.outerHeight() : 0,
     852            viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
     853            viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
     854
     855        offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
     856        offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
     857        offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
     858
     859        // now check if datepicker is showing outside window viewport - move to a better place if so.
     860        offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
     861            Math.abs(offset.left + dpWidth - viewWidth) : 0);
     862        offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
     863            Math.abs(dpHeight + inputHeight) : 0);
     864
     865        return offset;
     866    },
     867
     868    /* Find an object's position on the screen. */
     869    _findPos: function(obj) {
     870        var position,
     871            inst = this._getInst(obj),
     872            isRTL = this._get(inst, "isRTL");
     873
     874        while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
     875            obj = obj[isRTL ? "previousSibling" : "nextSibling"];
     876        }
     877
     878        position = $(obj).offset();
     879        return [position.left, position.top];
     880    },
     881
     882    /* Hide the date picker from view.
     883     * @param  input  element - the input field attached to the date picker
     884     */
     885    _hideDatepicker: function(input) {
     886        var showAnim, duration, postProcess, onClose,
     887            inst = this._curInst;
     888
     889        if (!inst || (input && inst !== $.data(input, "datepicker"))) {
     890            return;
     891        }
     892
     893        if (this._datepickerShowing) {
     894            showAnim = this._get(inst, "showAnim");
     895            duration = this._get(inst, "duration");
     896            postProcess = function() {
     897                $.datepicker._tidyDialog(inst);
     898            };
     899
     900            // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
     901            if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
     902                inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
     903            } else {
     904                inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
     905                    (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
     906            }
     907
     908            if (!showAnim) {
     909                postProcess();
     910            }
     911            this._datepickerShowing = false;
     912
     913            onClose = this._get(inst, "onClose");
     914            if (onClose) {
     915                onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
     916            }
     917
     918            this._lastInput = null;
     919            if (this._inDialog) {
     920                this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
     921                if ($.blockUI) {
     922                    $.unblockUI();
     923                    $("body").append(this.dpDiv);
     924                }
     925            }
     926            this._inDialog = false;
     927        }
     928    },
     929
     930    /* Tidy up after a dialog display. */
     931    _tidyDialog: function(inst) {
     932        inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
     933    },
     934
     935    /* Close date picker if clicked elsewhere. */
     936    _checkExternalClick: function(event) {
     937        if (!$.datepicker._curInst) {
     938            return;
     939        }
     940
     941        var $target = $(event.target),
     942            inst = $.datepicker._getInst($target[0]);
     943
     944        if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
     945                $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
     946                !$target.hasClass($.datepicker.markerClassName) &&
     947                !$target.closest("." + $.datepicker._triggerClass).length &&
     948                $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
     949            ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
     950                $.datepicker._hideDatepicker();
     951        }
     952    },
     953
     954    /* Adjust one of the date sub-fields. */
     955    _adjustDate: function(id, offset, period) {
     956        var target = $(id),
     957            inst = this._getInst(target[0]);
     958
     959        if (this._isDisabledDatepicker(target[0])) {
     960            return;
     961        }
     962        this._adjustInstDate(inst, offset +
     963            (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
     964            period);
     965        this._updateDatepicker(inst);
     966    },
     967
     968    /* Action for current link. */
     969    _gotoToday: function(id) {
     970        var date,
     971            target = $(id),
     972            inst = this._getInst(target[0]);
     973
     974        if (this._get(inst, "gotoCurrent") && inst.currentDay) {
     975            inst.selectedDay = inst.currentDay;
     976            inst.drawMonth = inst.selectedMonth = inst.currentMonth;
     977            inst.drawYear = inst.selectedYear = inst.currentYear;
     978        } else {
     979            date = new Date();
     980            inst.selectedDay = date.getDate();
     981            inst.drawMonth = inst.selectedMonth = date.getMonth();
     982            inst.drawYear = inst.selectedYear = date.getFullYear();
     983        }
     984        this._notifyChange(inst);
     985        this._adjustDate(target);
     986    },
     987
     988    /* Action for selecting a new month/year. */
     989    _selectMonthYear: function(id, select, period) {
     990        var target = $(id),
     991            inst = this._getInst(target[0]);
     992
     993        inst["selected" + (period === "M" ? "Month" : "Year")] =
     994        inst["draw" + (period === "M" ? "Month" : "Year")] =
     995            parseInt(select.options[select.selectedIndex].value,10);
     996
     997        this._notifyChange(inst);
     998        this._adjustDate(target);
     999    },
     1000
     1001    /* Action for selecting a day. */
     1002    _selectDay: function(id, month, year, td) {
     1003        var inst,
     1004            target = $(id);
     1005
     1006        if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
     1007            return;
     1008        }
     1009
     1010        inst = this._getInst(target[0]);
     1011        inst.selectedDay = inst.currentDay = $("a", td).html();
     1012        inst.selectedMonth = inst.currentMonth = month;
     1013        inst.selectedYear = inst.currentYear = year;
     1014        this._selectDate(id, this._formatDate(inst,
     1015            inst.currentDay, inst.currentMonth, inst.currentYear));
     1016    },
     1017
     1018    /* Erase the input field and hide the date picker. */
     1019    _clearDate: function(id) {
     1020        var target = $(id);
     1021        this._selectDate(target, "");
     1022    },
     1023
     1024    /* Update the input field with the selected date. */
     1025    _selectDate: function(id, dateStr) {
     1026        var onSelect,
     1027            target = $(id),
     1028            inst = this._getInst(target[0]);
     1029
     1030        dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
     1031        if (inst.input) {
     1032            inst.input.val(dateStr);
     1033        }
     1034        this._updateAlternate(inst);
     1035
     1036        onSelect = this._get(inst, "onSelect");
     1037        if (onSelect) {
     1038            onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
     1039        } else if (inst.input) {
     1040            inst.input.trigger("change"); // fire the change event
     1041        }
     1042
     1043        if (inst.inline){
     1044            this._updateDatepicker(inst);
     1045        } else {
     1046            this._hideDatepicker();
     1047            this._lastInput = inst.input[0];
     1048            if (typeof(inst.input[0]) !== "object") {
     1049                inst.input.focus(); // restore focus
     1050            }
     1051            this._lastInput = null;
     1052        }
     1053    },
     1054
     1055    /* Update any alternate field to synchronise with the main field. */
     1056    _updateAlternate: function(inst) {
     1057        var altFormat, date, dateStr,
     1058            altField = this._get(inst, "altField");
     1059
     1060        if (altField) { // update alternate field too
     1061            altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
     1062            date = this._getDate(inst);
     1063            dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
     1064            $(altField).each(function() { $(this).val(dateStr); });
     1065        }
     1066    },
     1067
     1068    /* Set as beforeShowDay function to prevent selection of weekends.
     1069     * @param  date  Date - the date to customise
     1070     * @return [boolean, string] - is this date selectable?, what is its CSS class?
     1071     */
     1072    noWeekends: function(date) {
     1073        var day = date.getDay();
     1074        return [(day > 0 && day < 6), ""];
     1075    },
     1076
     1077    /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
     1078     * @param  date  Date - the date to get the week for
     1079     * @return  number - the number of the week within the year that contains this date
     1080     */
     1081    iso8601Week: function(date) {
     1082        var time,
     1083            checkDate = new Date(date.getTime());
     1084
     1085        // Find Thursday of this week starting on Monday
     1086        checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
     1087
     1088        time = checkDate.getTime();
     1089        checkDate.setMonth(0); // Compare with Jan 1
     1090        checkDate.setDate(1);
     1091        return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
     1092    },
     1093
     1094    /* Parse a string value into a date object.
     1095     * See formatDate below for the possible formats.
     1096     *
     1097     * @param  format string - the expected format of the date
     1098     * @param  value string - the date in the above format
     1099     * @param  settings Object - attributes include:
     1100     *                  shortYearCutoff  number - the cutoff year for determining the century (optional)
     1101     *                  dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
     1102     *                  dayNames        string[7] - names of the days from Sunday (optional)
     1103     *                  monthNamesShort string[12] - abbreviated names of the months (optional)
     1104     *                  monthNames      string[12] - names of the months (optional)
     1105     * @return  Date - the extracted date value or null if value is blank
     1106     */
     1107    parseDate: function (format, value, settings) {
     1108        if (format == null || value == null) {
     1109            throw "Invalid arguments";
     1110        }
     1111
     1112        value = (typeof value === "object" ? value.toString() : value + "");
     1113        if (value === "") {
     1114            return null;
     1115        }
     1116
     1117        var iFormat, dim, extra,
     1118            iValue = 0,
     1119            shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
     1120            shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
     1121                new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
     1122            dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
     1123            dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
     1124            monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
     1125            monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
     1126            year = -1,
     1127            month = -1,
     1128            day = -1,
     1129            doy = -1,
     1130            literal = false,
     1131            date,
     1132            // Check whether a format character is doubled
     1133            lookAhead = function(match) {
     1134                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
     1135                if (matches) {
     1136                    iFormat++;
     1137                }
     1138                return matches;
     1139            },
     1140            // Extract a number from the string value
     1141            getNumber = function(match) {
     1142                var isDoubled = lookAhead(match),
     1143                    size = (match === "@" ? 14 : (match === "!" ? 20 :
     1144                    (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
     1145                    minSize = (match === "y" ? size : 1),
     1146                    digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
     1147                    num = value.substring(iValue).match(digits);
     1148                if (!num) {
     1149                    throw "Missing number at position " + iValue;
     1150                }
     1151                iValue += num[0].length;
     1152                return parseInt(num[0], 10);
     1153            },
     1154            // Extract a name from the string value and convert to an index
     1155            getName = function(match, shortNames, longNames) {
     1156                var index = -1,
     1157                    names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
     1158                        return [ [k, v] ];
     1159                    }).sort(function (a, b) {
     1160                        return -(a[1].length - b[1].length);
     1161                    });
     1162
     1163                $.each(names, function (i, pair) {
     1164                    var name = pair[1];
     1165                    if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
     1166                        index = pair[0];
     1167                        iValue += name.length;
     1168                        return false;
     1169                    }
     1170                });
     1171                if (index !== -1) {
     1172                    return index + 1;
     1173                } else {
     1174                    throw "Unknown name at position " + iValue;
     1175                }
     1176            },
     1177            // Confirm that a literal character matches the string value
     1178            checkLiteral = function() {
     1179                if (value.charAt(iValue) !== format.charAt(iFormat)) {
     1180                    throw "Unexpected literal at position " + iValue;
     1181                }
     1182                iValue++;
     1183            };
     1184
     1185        for (iFormat = 0; iFormat < format.length; iFormat++) {
     1186            if (literal) {
     1187                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
     1188                    literal = false;
     1189                } else {
     1190                    checkLiteral();
     1191                }
     1192            } else {
     1193                switch (format.charAt(iFormat)) {
     1194                    case "d":
     1195                        day = getNumber("d");
     1196                        break;
     1197                    case "D":
     1198                        getName("D", dayNamesShort, dayNames);
     1199                        break;
     1200                    case "o":
     1201                        doy = getNumber("o");
     1202                        break;
     1203                    case "m":
     1204                        month = getNumber("m");
     1205                        break;
     1206                    case "M":
     1207                        month = getName("M", monthNamesShort, monthNames);
     1208                        break;
     1209                    case "y":
     1210                        year = getNumber("y");
     1211                        break;
     1212                    case "@":
     1213                        date = new Date(getNumber("@"));
     1214                        year = date.getFullYear();
     1215                        month = date.getMonth() + 1;
     1216                        day = date.getDate();
     1217                        break;
     1218                    case "!":
     1219                        date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
     1220                        year = date.getFullYear();
     1221                        month = date.getMonth() + 1;
     1222                        day = date.getDate();
     1223                        break;
     1224                    case "'":
     1225                        if (lookAhead("'")){
     1226                            checkLiteral();
     1227                        } else {
     1228                            literal = true;
     1229                        }
     1230                        break;
     1231                    default:
     1232                        checkLiteral();
     1233                }
     1234            }
     1235        }
     1236
     1237        if (iValue < value.length){
     1238            extra = value.substr(iValue);
     1239            if (!/^\s+/.test(extra)) {
     1240                throw "Extra/unparsed characters found in date: " + extra;
     1241            }
     1242        }
     1243
     1244        if (year === -1) {
     1245            year = new Date().getFullYear();
     1246        } else if (year < 100) {
     1247            year += new Date().getFullYear() - new Date().getFullYear() % 100 +
     1248                (year <= shortYearCutoff ? 0 : -100);
     1249        }
     1250
     1251        if (doy > -1) {
     1252            month = 1;
     1253            day = doy;
     1254            do {
     1255                dim = this._getDaysInMonth(year, month - 1);
     1256                if (day <= dim) {
     1257                    break;
     1258                }
     1259                month++;
     1260                day -= dim;
     1261            } while (true);
     1262        }
     1263
     1264        date = this._daylightSavingAdjust(new Date(year, month - 1, day));
     1265        if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
     1266            throw "Invalid date"; // E.g. 31/02/00
     1267        }
     1268        return date;
     1269    },
     1270
     1271    /* Standard date formats. */
     1272    ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
     1273    COOKIE: "D, dd M yy",
     1274    ISO_8601: "yy-mm-dd",
     1275    RFC_822: "D, d M y",
     1276    RFC_850: "DD, dd-M-y",
     1277    RFC_1036: "D, d M y",
     1278    RFC_1123: "D, d M yy",
     1279    RFC_2822: "D, d M yy",
     1280    RSS: "D, d M y", // RFC 822
     1281    TICKS: "!",
     1282    TIMESTAMP: "@",
     1283    W3C: "yy-mm-dd", // ISO 8601
     1284
     1285    _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
     1286        Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
     1287
     1288    /* Format a date object into a string value.
     1289     * The format can be combinations of the following:
     1290     * d  - day of month (no leading zero)
     1291     * dd - day of month (two digit)
     1292     * o  - day of year (no leading zeros)
     1293     * oo - day of year (three digit)
     1294     * D  - day name short
     1295     * DD - day name long
     1296     * m  - month of year (no leading zero)
     1297     * mm - month of year (two digit)
     1298     * M  - month name short
     1299     * MM - month name long
     1300     * y  - year (two digit)
     1301     * yy - year (four digit)
     1302     * @ - Unix timestamp (ms since 01/01/1970)
     1303     * ! - Windows ticks (100ns since 01/01/0001)
     1304     * "..." - literal text
     1305     * '' - single quote
     1306     *
     1307     * @param  format string - the desired format of the date
     1308     * @param  date Date - the date value to format
     1309     * @param  settings Object - attributes include:
     1310     *                  dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
     1311     *                  dayNames        string[7] - names of the days from Sunday (optional)
     1312     *                  monthNamesShort string[12] - abbreviated names of the months (optional)
     1313     *                  monthNames      string[12] - names of the months (optional)
     1314     * @return  string - the date in the above format
     1315     */
     1316    formatDate: function (format, date, settings) {
     1317        if (!date) {
     1318            return "";
     1319        }
     1320
     1321        var iFormat,
     1322            dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
     1323            dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
     1324            monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
     1325            monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
     1326            // Check whether a format character is doubled
     1327            lookAhead = function(match) {
     1328                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
     1329                if (matches) {
     1330                    iFormat++;
     1331                }
     1332                return matches;
     1333            },
     1334            // Format a number, with leading zero if necessary
     1335            formatNumber = function(match, value, len) {
     1336                var num = "" + value;
     1337                if (lookAhead(match)) {
     1338                    while (num.length < len) {
     1339                        num = "0" + num;
     1340                    }
     1341                }
     1342                return num;
     1343            },
     1344            // Format a name, short or long as requested
     1345            formatName = function(match, value, shortNames, longNames) {
     1346                return (lookAhead(match) ? longNames[value] : shortNames[value]);
     1347            },
     1348            output = "",
     1349            literal = false;
     1350
     1351        if (date) {
     1352            for (iFormat = 0; iFormat < format.length; iFormat++) {
     1353                if (literal) {
     1354                    if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
     1355                        literal = false;
     1356                    } else {
     1357                        output += format.charAt(iFormat);
     1358                    }
     1359                } else {
     1360                    switch (format.charAt(iFormat)) {
     1361                        case "d":
     1362                            output += formatNumber("d", date.getDate(), 2);
     1363                            break;
     1364                        case "D":
     1365                            output += formatName("D", date.getDay(), dayNamesShort, dayNames);
     1366                            break;
     1367                        case "o":
     1368                            output += formatNumber("o",
     1369                                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
     1370                            break;
     1371                        case "m":
     1372                            output += formatNumber("m", date.getMonth() + 1, 2);
     1373                            break;
     1374                        case "M":
     1375                            output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
     1376                            break;
     1377                        case "y":
     1378                            output += (lookAhead("y") ? date.getFullYear() :
     1379                                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
     1380                            break;
     1381                        case "@":
     1382                            output += date.getTime();
     1383                            break;
     1384                        case "!":
     1385                            output += date.getTime() * 10000 + this._ticksTo1970;
     1386                            break;
     1387                        case "'":
     1388                            if (lookAhead("'")) {
     1389                                output += "'";
     1390                            } else {
     1391                                literal = true;
     1392                            }
     1393                            break;
     1394                        default:
     1395                            output += format.charAt(iFormat);
     1396                    }
     1397                }
     1398            }
     1399        }
     1400        return output;
     1401    },
     1402
     1403    /* Extract all possible characters from the date format. */
     1404    _possibleChars: function (format) {
     1405        var iFormat,
     1406            chars = "",
     1407            literal = false,
     1408            // Check whether a format character is doubled
     1409            lookAhead = function(match) {
     1410                var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
     1411                if (matches) {
     1412                    iFormat++;
     1413                }
     1414                return matches;
     1415            };
     1416
     1417        for (iFormat = 0; iFormat < format.length; iFormat++) {
     1418            if (literal) {
     1419                if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
     1420                    literal = false;
     1421                } else {
     1422                    chars += format.charAt(iFormat);
     1423                }
     1424            } else {
     1425                switch (format.charAt(iFormat)) {
     1426                    case "d": case "m": case "y": case "@":
     1427                        chars += "0123456789";
     1428                        break;
     1429                    case "D": case "M":
     1430                        return null; // Accept anything
     1431                    case "'":
     1432                        if (lookAhead("'")) {
     1433                            chars += "'";
     1434                        } else {
     1435                            literal = true;
     1436                        }
     1437                        break;
     1438                    default:
     1439                        chars += format.charAt(iFormat);
     1440                }
     1441            }
     1442        }
     1443        return chars;
     1444    },
     1445
     1446    /* Get a setting value, defaulting if necessary. */
     1447    _get: function(inst, name) {
     1448        return inst.settings[name] !== undefined ?
     1449            inst.settings[name] : this._defaults[name];
     1450    },
     1451
     1452    /* Parse existing date and initialise date picker. */
     1453    _setDateFromField: function(inst, noDefault) {
     1454        if (inst.input.val() === inst.lastVal) {
     1455            return;
     1456        }
     1457
     1458        var dateFormat = this._get(inst, "dateFormat"),
     1459            dates = inst.lastVal = inst.input ? inst.input.val() : null,
     1460            defaultDate = this._getDefaultDate(inst),
     1461            date = defaultDate,
     1462            settings = this._getFormatConfig(inst);
     1463
     1464        try {
     1465            date = this.parseDate(dateFormat, dates, settings) || defaultDate;
     1466        } catch (event) {
     1467            dates = (noDefault ? "" : dates);
     1468        }
     1469        inst.selectedDay = date.getDate();
     1470        inst.drawMonth = inst.selectedMonth = date.getMonth();
     1471        inst.drawYear = inst.selectedYear = date.getFullYear();
     1472        inst.currentDay = (dates ? date.getDate() : 0);
     1473        inst.currentMonth = (dates ? date.getMonth() : 0);
     1474        inst.currentYear = (dates ? date.getFullYear() : 0);
     1475        this._adjustInstDate(inst);
     1476    },
     1477
     1478    /* Retrieve the default date shown on opening. */
     1479    _getDefaultDate: function(inst) {
     1480        return this._restrictMinMax(inst,
     1481            this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
     1482    },
     1483
     1484    /* A date may be specified as an exact value or a relative one. */
     1485    _determineDate: function(inst, date, defaultDate) {
     1486        var offsetNumeric = function(offset) {
     1487                var date = new Date();
     1488                date.setDate(date.getDate() + offset);
     1489                return date;
     1490            },
     1491            offsetString = function(offset) {
     1492                try {
     1493                    return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
     1494                        offset, $.datepicker._getFormatConfig(inst));
     1495                }
     1496                catch (e) {
     1497                    // Ignore
     1498                }
     1499
     1500                var date = (offset.toLowerCase().match(/^c/) ?
     1501                    $.datepicker._getDate(inst) : null) || new Date(),
     1502                    year = date.getFullYear(),
     1503                    month = date.getMonth(),
     1504                    day = date.getDate(),
     1505                    pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
     1506                    matches = pattern.exec(offset);
     1507
     1508                while (matches) {
     1509                    switch (matches[2] || "d") {
     1510                        case "d" : case "D" :
     1511                            day += parseInt(matches[1],10); break;
     1512                        case "w" : case "W" :
     1513                            day += parseInt(matches[1],10) * 7; break;
     1514                        case "m" : case "M" :
     1515                            month += parseInt(matches[1],10);
     1516                            day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
     1517                            break;
     1518                        case "y": case "Y" :
     1519                            year += parseInt(matches[1],10);
     1520                            day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
     1521                            break;
     1522                    }
     1523                    matches = pattern.exec(offset);
     1524                }
     1525                return new Date(year, month, day);
     1526            },
     1527            newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
     1528                (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
     1529
     1530        newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
     1531        if (newDate) {
     1532            newDate.setHours(0);
     1533            newDate.setMinutes(0);
     1534            newDate.setSeconds(0);
     1535            newDate.setMilliseconds(0);
     1536        }
     1537        return this._daylightSavingAdjust(newDate);
     1538    },
     1539
     1540    /* Handle switch to/from daylight saving.
     1541     * Hours may be non-zero on daylight saving cut-over:
     1542     * > 12 when midnight changeover, but then cannot generate
     1543     * midnight datetime, so jump to 1AM, otherwise reset.
     1544     * @param  date  (Date) the date to check
     1545     * @return  (Date) the corrected date
     1546     */
     1547    _daylightSavingAdjust: function(date) {
     1548        if (!date) {
     1549            return null;
     1550        }
     1551        date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
     1552        return date;
     1553    },
     1554
     1555    /* Set the date(s) directly. */
     1556    _setDate: function(inst, date, noChange) {
     1557        var clear = !date,
     1558            origMonth = inst.selectedMonth,
     1559            origYear = inst.selectedYear,
     1560            newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
     1561
     1562        inst.selectedDay = inst.currentDay = newDate.getDate();
     1563        inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
     1564        inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
     1565        if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
     1566            this._notifyChange(inst);
     1567        }
     1568        this._adjustInstDate(inst);
     1569        if (inst.input) {
     1570            inst.input.val(clear ? "" : this._formatDate(inst));
     1571        }
     1572    },
     1573
     1574    /* Retrieve the date(s) directly. */
     1575    _getDate: function(inst) {
     1576        var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
     1577            this._daylightSavingAdjust(new Date(
     1578            inst.currentYear, inst.currentMonth, inst.currentDay)));
     1579            return startDate;
     1580    },
     1581
     1582    /* Attach the onxxx handlers.  These are declared statically so
     1583     * they work with static code transformers like Caja.
     1584     */
     1585    _attachHandlers: function(inst) {
     1586        var stepMonths = this._get(inst, "stepMonths"),
     1587            id = "#" + inst.id.replace( /\\\\/g, "\\" );
     1588        inst.dpDiv.find("[data-handler]").map(function () {
     1589            var handler = {
     1590                prev: function () {
     1591                    $.datepicker._adjustDate(id, -stepMonths, "M");
     1592                },
     1593                next: function () {
     1594                    $.datepicker._adjustDate(id, +stepMonths, "M");
     1595                },
     1596                hide: function () {
     1597                    $.datepicker._hideDatepicker();
     1598                },
     1599                today: function () {
     1600                    $.datepicker._gotoToday(id);
     1601                },
     1602                selectDay: function () {
     1603                    $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
     1604                    return false;
     1605                },
     1606                selectMonth: function () {
     1607                    $.datepicker._selectMonthYear(id, this, "M");
     1608                    return false;
     1609                },
     1610                selectYear: function () {
     1611                    $.datepicker._selectMonthYear(id, this, "Y");
     1612                    return false;
     1613                }
     1614            };
     1615            $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
     1616        });
     1617    },
     1618
     1619    /* Generate the HTML for the current state of the date picker. */
     1620    _generateHTML: function(inst) {
     1621        var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
     1622            controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
     1623            monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
     1624            selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
     1625            cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
     1626            printDate, dRow, tbody, daySettings, otherMonth, unselectable,
     1627            tempDate = new Date(),
     1628            today = this._daylightSavingAdjust(
     1629                new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
     1630            isRTL = this._get(inst, "isRTL"),
     1631            showButtonPanel = this._get(inst, "showButtonPanel"),
     1632            hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
     1633            navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
     1634            numMonths = this._getNumberOfMonths(inst),
     1635            showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
     1636            stepMonths = this._get(inst, "stepMonths"),
     1637            isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
     1638            currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
     1639                new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
     1640            minDate = this._getMinMaxDate(inst, "min"),
     1641            maxDate = this._getMinMaxDate(inst, "max"),
     1642            drawMonth = inst.drawMonth - showCurrentAtPos,
     1643            drawYear = inst.drawYear;
     1644
     1645        if (drawMonth < 0) {
     1646            drawMonth += 12;
     1647            drawYear--;
     1648        }
     1649        if (maxDate) {
     1650            maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
     1651                maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
     1652            maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
     1653            while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
     1654                drawMonth--;
     1655                if (drawMonth < 0) {
     1656                    drawMonth = 11;
     1657                    drawYear--;
     1658                }
     1659            }
     1660        }
     1661        inst.drawMonth = drawMonth;
     1662        inst.drawYear = drawYear;
     1663
     1664        prevText = this._get(inst, "prevText");
     1665        prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
     1666            this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
     1667            this._getFormatConfig(inst)));
     1668
     1669        prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
     1670            "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
     1671            " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
     1672            (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>"));
     1673
     1674        nextText = this._get(inst, "nextText");
     1675        nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
     1676            this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
     1677            this._getFormatConfig(inst)));
     1678
     1679        next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
     1680            "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
     1681            " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
     1682            (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>"));
     1683
     1684        currentText = this._get(inst, "currentText");
     1685        gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
     1686        currentText = (!navigationAsDateFormat ? currentText :
     1687            this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
     1688
     1689        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'>" +
     1690            this._get(inst, "closeText") + "</button>" : "");
     1691
     1692        buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
     1693            (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'" +
     1694            ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
     1695
     1696        firstDay = parseInt(this._get(inst, "firstDay"),10);
     1697        firstDay = (isNaN(firstDay) ? 0 : firstDay);
     1698
     1699        showWeek = this._get(inst, "showWeek");
     1700        dayNames = this._get(inst, "dayNames");
     1701        dayNamesMin = this._get(inst, "dayNamesMin");
     1702        monthNames = this._get(inst, "monthNames");
     1703        monthNamesShort = this._get(inst, "monthNamesShort");
     1704        beforeShowDay = this._get(inst, "beforeShowDay");
     1705        showOtherMonths = this._get(inst, "showOtherMonths");
     1706        selectOtherMonths = this._get(inst, "selectOtherMonths");
     1707        defaultDate = this._getDefaultDate(inst);
     1708        html = "";
     1709        dow;
     1710        for (row = 0; row < numMonths[0]; row++) {
     1711            group = "";
     1712            this.maxRows = 4;
     1713            for (col = 0; col < numMonths[1]; col++) {
     1714                selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
     1715                cornerClass = " ui-corner-all";
     1716                calender = "";
     1717                if (isMultiMonth) {
     1718                    calender += "<div class='ui-datepicker-group";
     1719                    if (numMonths[1] > 1) {
     1720                        switch (col) {
     1721                            case 0: calender += " ui-datepicker-group-first";
     1722                                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
     1723                            case numMonths[1]-1: calender += " ui-datepicker-group-last";
     1724                                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
     1725                            default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
     1726                        }
     1727                    }
     1728                    calender += "'>";
     1729                }
     1730                calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
     1731                    (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
     1732                    (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
     1733                    this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
     1734                    row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
     1735                    "</div><table class='ui-datepicker-calendar'><thead>" +
     1736                    "<tr>";
     1737                thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
     1738                for (dow = 0; dow < 7; dow++) { // days of the week
     1739                    day = (dow + firstDay) % 7;
     1740                    thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
     1741                        "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
     1742                }
     1743                calender += thead + "</tr></thead><tbody>";
     1744                daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
     1745                if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
     1746                    inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
     1747                }
     1748                leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
     1749                curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
     1750                numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
     1751                this.maxRows = numRows;
     1752                printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
     1753                for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
     1754                    calender += "<tr>";
     1755                    tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
     1756                        this._get(inst, "calculateWeek")(printDate) + "</td>");
     1757                    for (dow = 0; dow < 7; dow++) { // create date picker days
     1758                        daySettings = (beforeShowDay ?
     1759                            beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
     1760                        otherMonth = (printDate.getMonth() !== drawMonth);
     1761                        unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
     1762                            (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
     1763                        tbody += "<td class='" +
     1764                            ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
     1765                            (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
     1766                            ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
     1767                            (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
     1768                            // or defaultDate is current printedDate and defaultDate is selectedDate
     1769                            " " + this._dayOverClass : "") + // highlight selected day
     1770                            (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
     1771                            (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
     1772                            (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
     1773                            (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
     1774                            ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
     1775                            (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
     1776                            (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
     1777                            (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
     1778                            (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
     1779                            (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
     1780                            (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
     1781                            "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
     1782                        printDate.setDate(printDate.getDate() + 1);
     1783                        printDate = this._daylightSavingAdjust(printDate);
     1784                    }
     1785                    calender += tbody + "</tr>";
     1786                }
     1787                drawMonth++;
     1788                if (drawMonth > 11) {
     1789                    drawMonth = 0;
     1790                    drawYear++;
     1791                }
     1792                calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
     1793                            ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
     1794                group += calender;
     1795            }
     1796            html += group;
     1797        }
     1798        html += buttonPanel;
     1799        inst._keyEvent = false;
     1800        return html;
     1801    },
     1802
     1803    /* Generate the month and year header. */
     1804    _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
     1805            secondary, monthNames, monthNamesShort) {
     1806
     1807        var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
     1808            changeMonth = this._get(inst, "changeMonth"),
     1809            changeYear = this._get(inst, "changeYear"),
     1810            showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
     1811            html = "<div class='ui-datepicker-title'>",
     1812            monthHtml = "";
     1813
     1814        // month selection
     1815        if (secondary || !changeMonth) {
     1816            monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
     1817        } else {
     1818            inMinYear = (minDate && minDate.getFullYear() === drawYear);
     1819            inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
     1820            monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
     1821            for ( month = 0; month < 12; month++) {
     1822                if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
     1823                    monthHtml += "<option value='" + month + "'" +
     1824                        (month === drawMonth ? " selected='selected'" : "") +
     1825                        ">" + monthNamesShort[month] + "</option>";
     1826                }
     1827            }
     1828            monthHtml += "</select>";
     1829        }
     1830
     1831        if (!showMonthAfterYear) {
     1832            html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
     1833        }
     1834
     1835        // year selection
     1836        if ( !inst.yearshtml ) {
     1837            inst.yearshtml = "";
     1838            if (secondary || !changeYear) {
     1839                html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
     1840            } else {
     1841                // determine range of years to display
     1842                years = this._get(inst, "yearRange").split(":");
     1843                thisYear = new Date().getFullYear();
     1844                determineYear = function(value) {
     1845                    var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
     1846                        (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
     1847                        parseInt(value, 10)));
     1848                    return (isNaN(year) ? thisYear : year);
     1849                };
     1850                year = determineYear(years[0]);
     1851                endYear = Math.max(year, determineYear(years[1] || ""));
     1852                year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
     1853                endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
     1854                inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
     1855                for (; year <= endYear; year++) {
     1856                    inst.yearshtml += "<option value='" + year + "'" +
     1857                        (year === drawYear ? " selected='selected'" : "") +
     1858                        ">" + year + "</option>";
     1859                }
     1860                inst.yearshtml += "</select>";
     1861
     1862                html += inst.yearshtml;
     1863                inst.yearshtml = null;
     1864            }
     1865        }
     1866
     1867        html += this._get(inst, "yearSuffix");
     1868        if (showMonthAfterYear) {
     1869            html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
     1870        }
     1871        html += "</div>"; // Close datepicker_header
     1872        return html;
     1873    },
     1874
     1875    /* Adjust one of the date sub-fields. */
     1876    _adjustInstDate: function(inst, offset, period) {
     1877        var year = inst.drawYear + (period === "Y" ? offset : 0),
     1878            month = inst.drawMonth + (period === "M" ? offset : 0),
     1879            day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
     1880            date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
     1881
     1882        inst.selectedDay = date.getDate();
     1883        inst.drawMonth = inst.selectedMonth = date.getMonth();
     1884        inst.drawYear = inst.selectedYear = date.getFullYear();
     1885        if (period === "M" || period === "Y") {
     1886            this._notifyChange(inst);
     1887        }
     1888    },
     1889
     1890    /* Ensure a date is within any min/max bounds. */
     1891    _restrictMinMax: function(inst, date) {
     1892        var minDate = this._getMinMaxDate(inst, "min"),
     1893            maxDate = this._getMinMaxDate(inst, "max"),
     1894            newDate = (minDate && date < minDate ? minDate : date);
     1895        return (maxDate && newDate > maxDate ? maxDate : newDate);
     1896    },
     1897
     1898    /* Notify change of month/year. */
     1899    _notifyChange: function(inst) {
     1900        var onChange = this._get(inst, "onChangeMonthYear");
     1901        if (onChange) {
     1902            onChange.apply((inst.input ? inst.input[0] : null),
     1903                [inst.selectedYear, inst.selectedMonth + 1, inst]);
     1904        }
     1905    },
     1906
     1907    /* Determine the number of months to show. */
     1908    _getNumberOfMonths: function(inst) {
     1909        var numMonths = this._get(inst, "numberOfMonths");
     1910        return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
     1911    },
     1912
     1913    /* Determine the current maximum date - ensure no time components are set. */
     1914    _getMinMaxDate: function(inst, minMax) {
     1915        return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
     1916    },
     1917
     1918    /* Find the number of days in a given month. */
     1919    _getDaysInMonth: function(year, month) {
     1920        return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
     1921    },
     1922
     1923    /* Find the day of the week of the first of a month. */
     1924    _getFirstDayOfMonth: function(year, month) {
     1925        return new Date(year, month, 1).getDay();
     1926    },
     1927
     1928    /* Determines if we should allow a "next/prev" month display change. */
     1929    _canAdjustMonth: function(inst, offset, curYear, curMonth) {
     1930        var numMonths = this._getNumberOfMonths(inst),
     1931            date = this._daylightSavingAdjust(new Date(curYear,
     1932            curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
     1933
     1934        if (offset < 0) {
     1935            date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
     1936        }
     1937        return this._isInRange(inst, date);
     1938    },
     1939
     1940    /* Is the given date in the accepted range? */
     1941    _isInRange: function(inst, date) {
     1942        var yearSplit, currentYear,
     1943            minDate = this._getMinMaxDate(inst, "min"),
     1944            maxDate = this._getMinMaxDate(inst, "max"),
     1945            minYear = null,
     1946            maxYear = null,
     1947            years = this._get(inst, "yearRange");
     1948            if (years){
     1949                yearSplit = years.split(":");
     1950                currentYear = new Date().getFullYear();
     1951                minYear = parseInt(yearSplit[0], 10);
     1952                maxYear = parseInt(yearSplit[1], 10);
     1953                if ( yearSplit[0].match(/[+\-].*/) ) {
     1954                    minYear += currentYear;
     1955                }
     1956                if ( yearSplit[1].match(/[+\-].*/) ) {
     1957                    maxYear += currentYear;
     1958                }
     1959            }
     1960
     1961        return ((!minDate || date.getTime() >= minDate.getTime()) &&
     1962            (!maxDate || date.getTime() <= maxDate.getTime()) &&
     1963            (!minYear || date.getFullYear() >= minYear) &&
     1964            (!maxYear || date.getFullYear() <= maxYear));
     1965    },
     1966
     1967    /* Provide the configuration settings for formatting/parsing. */
     1968    _getFormatConfig: function(inst) {
     1969        var shortYearCutoff = this._get(inst, "shortYearCutoff");
     1970        shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
     1971            new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
     1972        return {shortYearCutoff: shortYearCutoff,
     1973            dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
     1974            monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
     1975    },
     1976
     1977    /* Format the given date for display. */
     1978    _formatDate: function(inst, day, month, year) {
     1979        if (!day) {
     1980            inst.currentDay = inst.selectedDay;
     1981            inst.currentMonth = inst.selectedMonth;
     1982            inst.currentYear = inst.selectedYear;
     1983        }
     1984        var date = (day ? (typeof day === "object" ? day :
     1985            this._daylightSavingAdjust(new Date(year, month, day))) :
     1986            this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
     1987        return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
     1988    }
     1989});
     1990
     1991/*
     1992 * Bind hover events for datepicker elements.
     1993 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
     1994 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
     1995 */
     1996function datepicker_bindHover(dpDiv) {
     1997    var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
     1998    return dpDiv.delegate(selector, "mouseout", function() {
     1999            $(this).removeClass("ui-state-hover");
     2000            if (this.className.indexOf("ui-datepicker-prev") !== -1) {
     2001                $(this).removeClass("ui-datepicker-prev-hover");
     2002            }
     2003            if (this.className.indexOf("ui-datepicker-next") !== -1) {
     2004                $(this).removeClass("ui-datepicker-next-hover");
     2005            }
     2006        })
     2007        .delegate( selector, "mouseover", datepicker_handleMouseover );
     2008}
     2009
     2010function datepicker_handleMouseover() {
     2011    if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
     2012        $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
     2013        $(this).addClass("ui-state-hover");
     2014        if (this.className.indexOf("ui-datepicker-prev") !== -1) {
     2015            $(this).addClass("ui-datepicker-prev-hover");
     2016        }
     2017        if (this.className.indexOf("ui-datepicker-next") !== -1) {
     2018            $(this).addClass("ui-datepicker-next-hover");
     2019        }
     2020    }
     2021}
     2022
     2023/* jQuery extend now ignores nulls! */
     2024function datepicker_extendRemove(target, props) {
     2025    $.extend(target, props);
     2026    for (var name in props) {
     2027        if (props[name] == null) {
     2028            target[name] = props[name];
     2029        }
     2030    }
     2031    return target;
     2032}
     2033
     2034/* Invoke the datepicker functionality.
     2035   @param  options  string - a command, optionally followed by additional parameters or
     2036                    Object - settings for attaching new datepicker functionality
     2037   @return  jQuery object */
     2038$.fn.datepicker = function(options){
     2039
     2040    /* Verify an empty collection wasn't passed - Fixes #6976 */
     2041    if ( !this.length ) {
     2042        return this;
     2043    }
     2044
     2045    /* Initialise the date picker. */
     2046    if (!$.datepicker.initialized) {
     2047        $(document).mousedown($.datepicker._checkExternalClick);
     2048        $.datepicker.initialized = true;
     2049    }
     2050
     2051    /* Append datepicker main container to body if not exist. */
     2052    if ($("#"+$.datepicker._mainDivId).length === 0) {
     2053        $("body").append($.datepicker.dpDiv);
     2054    }
     2055
     2056    var otherArgs = Array.prototype.slice.call(arguments, 1);
     2057    if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
     2058        return $.datepicker["_" + options + "Datepicker"].
     2059            apply($.datepicker, [this[0]].concat(otherArgs));
     2060    }
     2061    if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
     2062        return $.datepicker["_" + options + "Datepicker"].
     2063            apply($.datepicker, [this[0]].concat(otherArgs));
     2064    }
     2065    return this.each(function() {
     2066        typeof options === "string" ?
     2067            $.datepicker["_" + options + "Datepicker"].
     2068                apply($.datepicker, [this].concat(otherArgs)) :
     2069            $.datepicker._attachDatepicker(this, options);
     2070    });
     2071};
     2072
     2073$.datepicker = new Datepicker(); // singleton instance
     2074$.datepicker.initialized = false;
     2075$.datepicker.uuid = new Date().getTime();
     2076$.datepicker.version = "1.11.1";
     2077
     2078return $.datepicker;
     2079
     2080}));
  • trunk/src/wp-includes/js/jquery/ui/dialog.js

    r29846 r29847  
    1 /*! jQuery UI - v1.10.4 - 2014-01-17
    2 * http://jqueryui.com
    3 * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    4 (function(t){var e={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};t.widget("ui.dialog",{version:"1.10.4",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i,s=this;if(this._isOpen&&this._trigger("beforeClose",e)!==!1){if(this._isOpen=!1,this._destroyOverlay(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&t(i).blur()}catch(n){}this._hide(this.uiDialog,this.options.hide,function(){s._trigger("close",e)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!e&&this._trigger("focus",t),i},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var t=this.element.find("[autofocus]");t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function i(){var e=this.document[0].activeElement,i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),undefined;if(e.keyCode===t.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(n.focus(1),e.preventDefault()):(s.focus(1),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=t("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(e),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title||t.html("&#160;"),t.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(t.each(i,function(i,s){var n,a;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(e.element[0],arguments)},a={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,t("<button></button>",s).button(a).appendTo(e.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){t(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,a){s.position=[a.position.left-i.document.scrollLeft(),a.position.top-i.document.scrollTop()],t(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(a))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,a=this.uiDialog.css("position"),o="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:o,start:function(s,n){t(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,a){s.height=t(this).height(),s.width=t(this).width(),t(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(a))}}).css("position",a)},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(s){var n=this,a=!1,o={};t.each(s,function(t,s){n._setOption(t,s),t in e&&(a=!0),t in i&&(o[t]=s)}),a&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",o)},_setOption:function(t,e){var i,s,n=this.uiDialog;"dialogClass"===t&&n.removeClass(this.options.dialogClass).addClass(e),"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:""+e}),"draggable"===t&&(i=n.is(":data(ui-draggable)"),i&&!e&&n.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&(s=n.is(":data(ui-resizable)"),s&&!e&&n.resizable("destroy"),s&&"string"==typeof e&&n.resizable("option","handles",e),s||e===!1||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=this,i=this.widgetFullName;t.ui.dialog.overlayInstances||this._delay(function(){t.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(s){e._allowInteraction(s)||(s.preventDefault(),t(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=t("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),t.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(t.ui.dialog.overlayInstances--,t.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),t.ui.dialog.overlayInstances=0,t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{_position:function(){var e,i=this.options.position,s=[],n=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(s=i.split?i.split(" "):[i[0],i[1]],1===s.length&&(s[1]=s[0]),t.each(["left","top"],function(t,e){+s[t]===s[t]&&(n[t]=s[t],s[t]=e)}),i={my:s[0]+(0>n[0]?n[0]:"+"+n[0])+" "+s[1]+(0>n[1]?n[1]:"+"+n[1]),at:s.join(" ")}),i=t.extend({},t.ui.dialog.prototype.options.position,i)):i=t.ui.dialog.prototype.options.position,e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.position(i),e||this.uiDialog.hide()}})})(jQuery);
     1/*!
     2 * jQuery UI Dialog 1.11.1
     3 * http://jqueryui.com
     4 *
     5 * Copyright 2014 jQuery Foundation and other contributors
     6 * Released under the MIT license.
     7 * http://jquery.org/license
     8 *
     9 * http://api.jqueryui.com/dialog/
     10 */
     11(function( factory ) {
     12    if ( typeof define === "function" && define.amd ) {
     13
     14        // AMD. Register as an anonymous module.
     15        define([
     16            "jquery",
     17            "./core",
     18            "./widget",
     19            "./button",
     20            "./draggable",
     21            "./mouse",
     22            "./position",
     23            "./resizable"
     24        ], factory );
     25    } else {
     26
     27        // Browser globals
     28        factory( jQuery );
     29    }
     30}(function( $ ) {
     31
     32return $.widget( "ui.dialog", {
     33    version: "1.11.1",
     34    options: {
     35        appendTo: "body",
     36        autoOpen: true,
     37        buttons: [],
     38        closeOnEscape: true,
     39        closeText: "Close",
     40        dialogClass: "",
     41        draggable: true,
     42        hide: null,
     43        height: "auto",
     44        maxHeight: null,
     45        maxWidth: null,
     46        minHeight: 150,
     47        minWidth: 150,
     48        modal: false,
     49        position: {
     50            my: "center",
     51            at: "center",
     52            of: window,
     53            collision: "fit",
     54            // Ensure the titlebar is always visible
     55            using: function( pos ) {
     56                var topOffset = $( this ).css( pos ).offset().top;
     57                if ( topOffset < 0 ) {
     58                    $( this ).css( "top", pos.top - topOffset );
     59                }
     60            }
     61        },
     62        resizable: true,
     63        show: null,
     64        title: null,
     65        width: 300,
     66
     67        // callbacks
     68        beforeClose: null,
     69        close: null,
     70        drag: null,
     71        dragStart: null,
     72        dragStop: null,
     73        focus: null,
     74        open: null,
     75        resize: null,
     76        resizeStart: null,
     77        resizeStop: null
     78    },
     79
     80    sizeRelatedOptions: {
     81        buttons: true,
     82        height: true,
     83        maxHeight: true,
     84        maxWidth: true,
     85        minHeight: true,
     86        minWidth: true,
     87        width: true
     88    },
     89
     90    resizableRelatedOptions: {
     91        maxHeight: true,
     92        maxWidth: true,
     93        minHeight: true,
     94        minWidth: true
     95    },
     96
     97    _create: function() {
     98        this.originalCss = {
     99            display: this.element[ 0 ].style.display,
     100            width: this.element[ 0 ].style.width,
     101            minHeight: this.element[ 0 ].style.minHeight,
     102            maxHeight: this.element[ 0 ].style.maxHeight,
     103            height: this.element[ 0 ].style.height
     104        };
     105        this.originalPosition = {
     106            parent: this.element.parent(),
     107            index: this.element.parent().children().index( this.element )
     108        };
     109        this.originalTitle = this.element.attr( "title" );
     110        this.options.title = this.options.title || this.originalTitle;
     111
     112        this._createWrapper();
     113
     114        this.element
     115            .show()
     116            .removeAttr( "title" )
     117            .addClass( "ui-dialog-content ui-widget-content" )
     118            .appendTo( this.uiDialog );
     119
     120        this._createTitlebar();
     121        this._createButtonPane();
     122
     123        if ( this.options.draggable && $.fn.draggable ) {
     124            this._makeDraggable();
     125        }
     126        if ( this.options.resizable && $.fn.resizable ) {
     127            this._makeResizable();
     128        }
     129
     130        this._isOpen = false;
     131
     132        this._trackFocus();
     133    },
     134
     135    _init: function() {
     136        if ( this.options.autoOpen ) {
     137            this.open();
     138        }
     139    },
     140
     141    _appendTo: function() {
     142        var element = this.options.appendTo;
     143        if ( element && (element.jquery || element.nodeType) ) {
     144            return $( element );
     145        }
     146        return this.document.find( element || "body" ).eq( 0 );
     147    },
     148
     149    _destroy: function() {
     150        var next,
     151            originalPosition = this.originalPosition;
     152
     153        this._destroyOverlay();
     154
     155        this.element
     156            .removeUniqueId()
     157            .removeClass( "ui-dialog-content ui-widget-content" )
     158            .css( this.originalCss )
     159            // Without detaching first, the following becomes really slow
     160            .detach();
     161
     162        this.uiDialog.stop( true, true ).remove();
     163
     164        if ( this.originalTitle ) {
     165            this.element.attr( "title", this.originalTitle );
     166        }
     167
     168        next = originalPosition.parent.children().eq( originalPosition.index );
     169        // Don't try to place the dialog next to itself (#8613)
     170        if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
     171            next.before( this.element );
     172        } else {
     173            originalPosition.parent.append( this.element );
     174        }
     175    },
     176
     177    widget: function() {
     178        return this.uiDialog;
     179    },
     180
     181    disable: $.noop,
     182    enable: $.noop,
     183
     184    close: function( event ) {
     185        var activeElement,
     186            that = this;
     187
     188        if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
     189            return;
     190        }
     191
     192        this._isOpen = false;
     193        this._focusedElement = null;
     194        this._destroyOverlay();
     195        this._untrackInstance();
     196
     197        if ( !this.opener.filter( ":focusable" ).focus().length ) {
     198
     199            // support: IE9
     200            // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
     201            try {
     202                activeElement = this.document[ 0 ].activeElement;
     203
     204                // Support: IE9, IE10
     205                // If the <body> is blurred, IE will switch windows, see #4520
     206                if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
     207
     208                    // Hiding a focused element doesn't trigger blur in WebKit
     209                    // so in case we have nothing to focus on, explicitly blur the active element
     210                    // https://bugs.webkit.org/show_bug.cgi?id=47182
     211                    $( activeElement ).blur();
     212                }
     213            } catch ( error ) {}
     214        }
     215
     216        this._hide( this.uiDialog, this.options.hide, function() {
     217            that._trigger( "close", event );
     218        });
     219    },
     220
     221    isOpen: function() {
     222        return this._isOpen;
     223    },
     224
     225    moveToTop: function() {
     226        this._moveToTop();
     227    },
     228
     229    _moveToTop: function( event, silent ) {
     230        var moved = false,
     231            zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
     232                return +$( this ).css( "z-index" );
     233            }).get(),
     234            zIndexMax = Math.max.apply( null, zIndicies );
     235
     236        if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
     237            this.uiDialog.css( "z-index", zIndexMax + 1 );
     238            moved = true;
     239        }
     240
     241        if ( moved && !silent ) {
     242            this._trigger( "focus", event );
     243        }
     244        return moved;
     245    },
     246
     247    open: function() {
     248        var that = this;
     249        if ( this._isOpen ) {
     250            if ( this._moveToTop() ) {
     251                this._focusTabbable();
     252            }
     253            return;
     254        }
     255
     256        this._isOpen = true;
     257        this.opener = $( this.document[ 0 ].activeElement );
     258
     259        this._size();
     260        this._position();
     261        this._createOverlay();
     262        this._moveToTop( null, true );
     263
     264        // Ensure the overlay is moved to the top with the dialog, but only when
     265        // opening. The overlay shouldn't move after the dialog is open so that
     266        // modeless dialogs opened after the modal dialog stack properly.
     267        if ( this.overlay ) {
     268            this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
     269        }
     270
     271        this._show( this.uiDialog, this.options.show, function() {
     272            that._focusTabbable();
     273            that._trigger( "focus" );
     274        });
     275
     276        // Track the dialog immediately upon openening in case a focus event
     277        // somehow occurs outside of the dialog before an element inside the
     278        // dialog is focused (#10152)
     279        this._makeFocusTarget();
     280
     281        this._trigger( "open" );
     282    },
     283
     284    _focusTabbable: function() {
     285        // Set focus to the first match:
     286        // 1. An element that was focused previously
     287        // 2. First element inside the dialog matching [autofocus]
     288        // 3. Tabbable element inside the content element
     289        // 4. Tabbable element inside the buttonpane
     290        // 5. The close button
     291        // 6. The dialog itself
     292        var hasFocus = this._focusedElement;
     293        if ( !hasFocus ) {
     294            hasFocus = this.element.find( "[autofocus]" );
     295        }
     296        if ( !hasFocus.length ) {
     297            hasFocus = this.element.find( ":tabbable" );
     298        }
     299        if ( !hasFocus.length ) {
     300            hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
     301        }
     302        if ( !hasFocus.length ) {
     303            hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
     304        }
     305        if ( !hasFocus.length ) {
     306            hasFocus = this.uiDialog;
     307        }
     308        hasFocus.eq( 0 ).focus();
     309    },
     310
     311    _keepFocus: function( event ) {
     312        function checkFocus() {
     313            var activeElement = this.document[0].activeElement,
     314                isActive = this.uiDialog[0] === activeElement ||
     315                    $.contains( this.uiDialog[0], activeElement );
     316            if ( !isActive ) {
     317                this._focusTabbable();
     318            }
     319        }
     320        event.preventDefault();
     321        checkFocus.call( this );
     322        // support: IE
     323        // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
     324        // so we check again later
     325        this._delay( checkFocus );
     326    },
     327
     328    _createWrapper: function() {
     329        this.uiDialog = $("<div>")
     330            .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
     331                this.options.dialogClass )
     332            .hide()
     333            .attr({
     334                // Setting tabIndex makes the div focusable
     335                tabIndex: -1,
     336                role: "dialog"
     337            })
     338            .appendTo( this._appendTo() );
     339
     340        this._on( this.uiDialog, {
     341            keydown: function( event ) {
     342                if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
     343                        event.keyCode === $.ui.keyCode.ESCAPE ) {
     344                    event.preventDefault();
     345                    this.close( event );
     346                    return;
     347                }
     348
     349                // prevent tabbing out of dialogs
     350                if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
     351                    return;
     352                }
     353                var tabbables = this.uiDialog.find( ":tabbable" ),
     354                    first = tabbables.filter( ":first" ),
     355                    last = tabbables.filter( ":last" );
     356
     357                if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
     358                    this._delay(function() {
     359                        first.focus();
     360                    });
     361                    event.preventDefault();
     362                } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
     363                    this._delay(function() {
     364                        last.focus();
     365                    });
     366                    event.preventDefault();
     367                }
     368            },
     369            mousedown: function( event ) {
     370                if ( this._moveToTop( event ) ) {
     371                    this._focusTabbable();
     372                }
     373            }
     374        });
     375
     376        // We assume that any existing aria-describedby attribute means
     377        // that the dialog content is marked up properly
     378        // otherwise we brute force the content as the description
     379        if ( !this.element.find( "[aria-describedby]" ).length ) {
     380            this.uiDialog.attr({
     381                "aria-describedby": this.element.uniqueId().attr( "id" )
     382            });
     383        }
     384    },
     385
     386    _createTitlebar: function() {
     387        var uiDialogTitle;
     388
     389        this.uiDialogTitlebar = $( "<div>" )
     390            .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
     391            .prependTo( this.uiDialog );
     392        this._on( this.uiDialogTitlebar, {
     393            mousedown: function( event ) {
     394                // Don't prevent click on close button (#8838)
     395                // Focusing a dialog that is partially scrolled out of view
     396                // causes the browser to scroll it into view, preventing the click event
     397                if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
     398                    // Dialog isn't getting focus when dragging (#8063)
     399                    this.uiDialog.focus();
     400                }
     401            }
     402        });
     403
     404        // support: IE
     405        // Use type="button" to prevent enter keypresses in textboxes from closing the
     406        // dialog in IE (#9312)
     407        this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
     408            .button({
     409                label: this.options.closeText,
     410                icons: {
     411                    primary: "ui-icon-closethick"
     412                },
     413                text: false
     414            })
     415            .addClass( "ui-dialog-titlebar-close" )
     416            .appendTo( this.uiDialogTitlebar );
     417        this._on( this.uiDialogTitlebarClose, {
     418            click: function( event ) {
     419                event.preventDefault();
     420                this.close( event );
     421            }
     422        });
     423
     424        uiDialogTitle = $( "<span>" )
     425            .uniqueId()
     426            .addClass( "ui-dialog-title" )
     427            .prependTo( this.uiDialogTitlebar );
     428        this._title( uiDialogTitle );
     429
     430        this.uiDialog.attr({
     431            "aria-labelledby": uiDialogTitle.attr( "id" )
     432        });
     433    },
     434
     435    _title: function( title ) {
     436        if ( !this.options.title ) {
     437            title.html( "&#160;" );
     438        }
     439        title.text( this.options.title );
     440    },
     441
     442    _createButtonPane: function() {
     443        this.uiDialogButtonPane = $( "<div>" )
     444            .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
     445
     446        this.uiButtonSet = $( "<div>" )
     447            .addClass( "ui-dialog-buttonset" )
     448            .appendTo( this.uiDialogButtonPane );
     449
     450        this._createButtons();
     451    },
     452
     453    _createButtons: function() {
     454        var that = this,
     455            buttons = this.options.buttons;
     456
     457        // if we already have a button pane, remove it
     458        this.uiDialogButtonPane.remove();
     459        this.uiButtonSet.empty();
     460
     461        if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
     462            this.uiDialog.removeClass( "ui-dialog-buttons" );
     463            return;
     464        }
     465
     466        $.each( buttons, function( name, props ) {
     467            var click, buttonOptions;
     468            props = $.isFunction( props ) ?
     469                { click: props, text: name } :
     470                props;
     471            // Default to a non-submitting button
     472            props = $.extend( { type: "button" }, props );
     473            // Change the context for the click callback to be the main element
     474            click = props.click;
     475            props.click = function() {
     476                click.apply( that.element[ 0 ], arguments );
     477            };
     478            buttonOptions = {
     479                icons: props.icons,
     480                text: props.showText
     481            };
     482            delete props.icons;
     483            delete props.showText;
     484            $( "<button></button>", props )
     485                .button( buttonOptions )
     486                .appendTo( that.uiButtonSet );
     487        });
     488        this.uiDialog.addClass( "ui-dialog-buttons" );
     489        this.uiDialogButtonPane.appendTo( this.uiDialog );
     490    },
     491
     492    _makeDraggable: function() {
     493        var that = this,
     494            options = this.options;
     495
     496        function filteredUi( ui ) {
     497            return {
     498                position: ui.position,
     499                offset: ui.offset
     500            };
     501        }
     502
     503        this.uiDialog.draggable({
     504            cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
     505            handle: ".ui-dialog-titlebar",
     506            containment: "document",
     507            start: function( event, ui ) {
     508                $( this ).addClass( "ui-dialog-dragging" );
     509                that._blockFrames();
     510                that._trigger( "dragStart", event, filteredUi( ui ) );
     511            },
     512            drag: function( event, ui ) {
     513                that._trigger( "drag", event, filteredUi( ui ) );
     514            },
     515            stop: function( event, ui ) {
     516                var left = ui.offset.left - that.document.scrollLeft(),
     517                    top = ui.offset.top - that.document.scrollTop();
     518
     519                options.position = {
     520                    my: "left top",
     521                    at: "left" + (left >= 0 ? "+" : "") + left + " " +
     522                        "top" + (top >= 0 ? "+" : "") + top,
     523                    of: that.window
     524                };
     525                $( this ).removeClass( "ui-dialog-dragging" );
     526                that._unblockFrames();
     527                that._trigger( "dragStop", event, filteredUi( ui ) );
     528            }
     529        });
     530    },
     531
     532    _makeResizable: function() {
     533        var that = this,
     534            options = this.options,
     535            handles = options.resizable,
     536            // .ui-resizable has position: relative defined in the stylesheet
     537            // but dialogs have to use absolute or fixed positioning
     538            position = this.uiDialog.css("position"),
     539            resizeHandles = typeof handles === "string" ?
     540                handles :
     541                "n,e,s,w,se,sw,ne,nw";
     542
     543        function filteredUi( ui ) {
     544            return {
     545                originalPosition: ui.originalPosition,
     546                originalSize: ui.originalSize,
     547                position: ui.position,
     548                size: ui.size
     549            };
     550        }
     551
     552        this.uiDialog.resizable({
     553            cancel: ".ui-dialog-content",
     554            containment: "document",
     555            alsoResize: this.element,
     556            maxWidth: options.maxWidth,
     557            maxHeight: options.maxHeight,
     558            minWidth: options.minWidth,
     559            minHeight: this._minHeight(),
     560            handles: resizeHandles,
     561            start: function( event, ui ) {
     562                $( this ).addClass( "ui-dialog-resizing" );
     563                that._blockFrames();
     564                that._trigger( "resizeStart", event, filteredUi( ui ) );
     565            },
     566            resize: function( event, ui ) {
     567                that._trigger( "resize", event, filteredUi( ui ) );
     568            },
     569            stop: function( event, ui ) {
     570                var offset = that.uiDialog.offset(),
     571                    left = offset.left - that.document.scrollLeft(),
     572                    top = offset.top - that.document.scrollTop();
     573
     574                options.height = that.uiDialog.height();
     575                options.width = that.uiDialog.width();
     576                options.position = {
     577                    my: "left top",
     578                    at: "left" + (left >= 0 ? "+" : "") + left + " " +
     579                        "top" + (top >= 0 ? "+" : "") + top,
     580                    of: that.window
     581                };
     582                $( this ).removeClass( "ui-dialog-resizing" );
     583                that._unblockFrames();
     584                that._trigger( "resizeStop", event, filteredUi( ui ) );
     585            }
     586        })
     587        .css( "position", position );
     588    },
     589
     590    _trackFocus: function() {
     591        this._on( this.widget(), {
     592            focusin: function( event ) {
     593                this._makeFocusTarget();
     594                this._focusedElement = $( event.target );
     595            }
     596        });
     597    },
     598
     599    _makeFocusTarget: function() {
     600        this._untrackInstance();
     601        this._trackingInstances().unshift( this );
     602    },
     603
     604    _untrackInstance: function() {
     605        var instances = this._trackingInstances(),
     606            exists = $.inArray( this, instances );
     607        if ( exists !== -1 ) {
     608            instances.splice( exists, 1 );
     609        }
     610    },
     611
     612    _trackingInstances: function() {
     613        var instances = this.document.data( "ui-dialog-instances" );
     614        if ( !instances ) {
     615            instances = [];
     616            this.document.data( "ui-dialog-instances", instances );
     617        }
     618        return instances;
     619    },
     620
     621    _minHeight: function() {
     622        var options = this.options;
     623
     624        return options.height === "auto" ?
     625            options.minHeight :
     626            Math.min( options.minHeight, options.height );
     627    },
     628
     629    _position: function() {
     630        // Need to show the dialog to get the actual offset in the position plugin
     631        var isVisible = this.uiDialog.is( ":visible" );
     632        if ( !isVisible ) {
     633            this.uiDialog.show();
     634        }
     635        this.uiDialog.position( this.options.position );
     636        if ( !isVisible ) {
     637            this.uiDialog.hide();
     638        }
     639    },
     640
     641    _setOptions: function( options ) {
     642        var that = this,
     643            resize = false,
     644            resizableOptions = {};
     645
     646        $.each( options, function( key, value ) {
     647            that._setOption( key, value );
     648
     649            if ( key in that.sizeRelatedOptions ) {
     650                resize = true;
     651            }
     652            if ( key in that.resizableRelatedOptions ) {
     653                resizableOptions[ key ] = value;
     654            }
     655        });
     656
     657        if ( resize ) {
     658            this._size();
     659            this._position();
     660        }
     661        if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
     662            this.uiDialog.resizable( "option", resizableOptions );
     663        }
     664    },
     665
     666    _setOption: function( key, value ) {
     667        var isDraggable, isResizable,
     668            uiDialog = this.uiDialog;
     669
     670        if ( key === "dialogClass" ) {
     671            uiDialog
     672                .removeClass( this.options.dialogClass )
     673                .addClass( value );
     674        }
     675
     676        if ( key === "disabled" ) {
     677            return;
     678        }
     679
     680        this._super( key, value );
     681
     682        if ( key === "appendTo" ) {
     683            this.uiDialog.appendTo( this._appendTo() );
     684        }
     685
     686        if ( key === "buttons" ) {
     687            this._createButtons();
     688        }
     689
     690        if ( key === "closeText" ) {
     691            this.uiDialogTitlebarClose.button({
     692                // Ensure that we always pass a string
     693